diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java index d53f1280640..96d4cf17590 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java @@ -618,6 +618,8 @@ public class ScryfallImageSupportCards { add("ECL"); // Lorwyn Eclipsed add("TMT"); // Teenage Mutant Ninja Turtles add("TMC"); // Teenage Mutant Ninja Turtles Eternal + add("MSH"); // Marvel Super Heroes + add("MSC"); // Marvel Super Heroes Commander // Custom sets using Scryfall images - must provide a direct link for each card in directDownloadLinks add("CALC"); // Custom Alchemized versions of existing cards diff --git a/Mage.Sets/src/mage/cards/a/AbolisherOfBloodlines.java b/Mage.Sets/src/mage/cards/a/AbolisherOfBloodlines.java deleted file mode 100644 index 1cde0a968c6..00000000000 --- a/Mage.Sets/src/mage/cards/a/AbolisherOfBloodlines.java +++ /dev/null @@ -1,51 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.common.SacrificeEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.target.common.TargetOpponent; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class AbolisherOfBloodlines extends CardImpl { - - public AbolisherOfBloodlines(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(6); - this.toughness = new MageInt(5); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // When this creature transforms into Abolisher of Bloodlines, target opponent sacrifices three creatures. - Ability ability = new TransformIntoSourceTriggeredAbility(new SacrificeEffect( - StaticFilters.FILTER_PERMANENT_CREATURES, 3, "target opponent" - )); - ability.addTarget(new TargetOpponent()); - this.addAbility(ability); - } - - private AbolisherOfBloodlines(final AbolisherOfBloodlines card) { - super(card); - } - - @Override - public AbolisherOfBloodlines copy() { - return new AbolisherOfBloodlines(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AllOutAssault.java b/Mage.Sets/src/mage/cards/a/AllOutAssault.java index 1e25977cabb..6e230b7819e 100644 --- a/Mage.Sets/src/mage/cards/a/AllOutAssault.java +++ b/Mage.Sets/src/mage/cards/a/AllOutAssault.java @@ -42,7 +42,7 @@ public final class AllOutAssault extends CardImpl { extraCombatAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new WhenYouAttackDelayedTriggeredAbility( new UntapAllControllerEffect( StaticFilters.FILTER_CONTROLLED_CREATURE, "untap each creature you control"), Duration.EndOfTurn, true))); - this.addAbility(extraCombatAbility.withInterveningIf(IsMainPhaseCondition.YOUR)); + this.addAbility(extraCombatAbility.withInterveningIf(IsMainPhaseCondition.YOURS)); } diff --git a/Mage.Sets/src/mage/cards/a/AltarOfTheWretched.java b/Mage.Sets/src/mage/cards/a/AltarOfTheWretched.java index d17c4d340e1..0c7e34a60d2 100644 --- a/Mage.Sets/src/mage/cards/a/AltarOfTheWretched.java +++ b/Mage.Sets/src/mage/cards/a/AltarOfTheWretched.java @@ -117,7 +117,7 @@ enum WretchedBonemassDynamicValue implements DynamicValue { ExileZone exileZone = game .getExile() .getExileZone(CardUtil.getExileZoneId( - game, permanent.getId(), permanent.getZoneChangeCounter(game) - 2 + game, permanent.getMainCard().getId(), permanent.getZoneChangeCounter(game) - 1 )); if (exileZone == null) { return 0; @@ -167,7 +167,7 @@ class WretchedBonemassGainAbilityEffect extends ContinuousEffectImpl { ExileZone exileZone = game .getExile() .getExileZone(CardUtil.getExileZoneId( - game, wretchedBonemass.getId(), wretchedBonemass.getZoneChangeCounter(game) - 2 + game, wretchedBonemass.getMainCard().getId(), wretchedBonemass.getZoneChangeCounter(game) - 1 )); if (exileZone != null && !exileZone.isEmpty()) { diff --git a/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java b/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java deleted file mode 100644 index ec8de09da90..00000000000 --- a/Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java +++ /dev/null @@ -1,92 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.hint.Hint; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.StaticFilters; -import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.card.DefendingPlayerOwnsCardPredicate; -import mage.game.Game; - -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * @author TheElk801 - */ -public final class AnimusOfNightsReach extends CardImpl { - - private static final FilterCard filter - = new FilterCreatureCard("creature cards in defending player's graveyard"); - - static { - filter.add(DefendingPlayerOwnsCardPredicate.instance); - } - - private static final DynamicValue xValue = new CardsInAllGraveyardsCount(filter); - - public AnimusOfNightsReach(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(0); - this.toughness = new MageInt(4); - this.color.setBlack(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // Whenever Animus of Night's Reach attacks, it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard. - this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect( - xValue, StaticValue.get(0), Duration.EndOfTurn - ).setText("it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard")).addHint(AnimusOfNightsReachHint.instance)); - } - - private AnimusOfNightsReach(final AnimusOfNightsReach card) { - super(card); - } - - @Override - public AnimusOfNightsReach copy() { - return new AnimusOfNightsReach(this); - } -} - -enum AnimusOfNightsReachHint implements Hint { - instance; - - @Override - public String getText(Game game, Ability ability) { - return "Cards in each opponent's graveyard:
" - + game - .getOpponents(ability.getControllerId()) - .stream() - .map(game::getPlayer) - .filter(Objects::nonNull) - .map(player -> player - .getName() - + ": " + player - .getGraveyard() - .count(StaticFilters.FILTER_CARD_CREATURE, game)) - .collect(Collectors.joining("
")); - } - - @Override - public AnimusOfNightsReachHint copy() { - return instance; - } -} diff --git a/Mage.Sets/src/mage/cards/a/ArchitectOfRestoration.java b/Mage.Sets/src/mage/cards/a/ArchitectOfRestoration.java deleted file mode 100644 index 7796e0f603a..00000000000 --- a/Mage.Sets/src/mage/cards/a/ArchitectOfRestoration.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.AttacksOrBlocksTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.game.permanent.token.SpiritToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ArchitectOfRestoration extends CardImpl { - - public ArchitectOfRestoration(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.FOX); - this.subtype.add(SubType.MONK); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.color.setWhite(true); - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Whenever Architect of Restoration attacks or blocks, create a 1/1 colorless Spirit creature token. - this.addAbility(new AttacksOrBlocksTriggeredAbility(new CreateTokenEffect(new SpiritToken()), false)); - } - - private ArchitectOfRestoration(final ArchitectOfRestoration card) { - super(card); - } - - @Override - public ArchitectOfRestoration copy() { - return new ArchitectOfRestoration(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AshlingRekindled.java b/Mage.Sets/src/mage/cards/a/AshlingRekindled.java new file mode 100644 index 00000000000..aa3a0ebf23e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AshlingRekindled.java @@ -0,0 +1,76 @@ +package mage.cards.a; + +import mage.abilities.common.TransformIntoSourceTriggeredAbility; +import mage.abilities.common.TransformsOrEntersTriggeredAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.mana.AddConditionalManaOfAnyColorEffect; +import mage.abilities.mana.conditional.ConditionalSpellManaBuilder; +import mage.abilities.meta.OrTriggeredAbility; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; +import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.ManaValuePredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AshlingRekindled extends TransformingDoubleFacedCard { + + private static final FilterSpell filter = new FilterSpell("spells with mana value 4 or greater"); + + static { + filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 3)); + } + + public AshlingRekindled(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL, SubType.SORCERER}, "{1}{R}", + "Ashling, Rimebound", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL, SubType.WIZARD}, "U" + ); + this.getLeftHalfCard().setPT(1, 3); + this.getRightHalfCard().setPT(1, 3); + + // Whenever this creature enters or transforms into Ashling, Rekindled, you may discard a card. If you do, draw a card. + this.getLeftHalfCard().addAbility(new TransformsOrEntersTriggeredAbility( + new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()), false + )); + + // At the beginning of your first main phase, you may pay {U}. If you do, transform Ashling. + this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{U}")) + )); + + // Ashling, Rimebound + // Whenever this creature transforms into Ashling, Rimebound and at the beginning of your first main phase, add two mana of any one color. Spend this mana only to cast spells with mana value 4 or greater. + this.getRightHalfCard().addAbility(new OrTriggeredAbility( + Zone.BATTLEFIELD, + new AddConditionalManaOfAnyColorEffect(2, new ConditionalSpellManaBuilder(filter)), + new TransformIntoSourceTriggeredAbility(null), + new BeginningOfFirstMainTriggeredAbility(null) + )); + + // At the beginning of your first main phase, you may pay {R}. If you do, transform Ashling. + this.getRightHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{R}")) + )); + } + + private AshlingRekindled(final AshlingRekindled card) { + super(card); + } + + @Override + public AshlingRekindled copy() { + return new AshlingRekindled(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AshmouthDragon.java b/Mage.Sets/src/mage/cards/a/AshmouthDragon.java deleted file mode 100644 index f4c11eb6b55..00000000000 --- a/Mage.Sets/src/mage/cards/a/AshmouthDragon.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.target.common.TargetAnyTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AshmouthDragon extends CardImpl { - - public AshmouthDragon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.DRAGON); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setRed(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever you cast an instant or sorcery spell, Ashmouth Dragon deals 2 damage to any target. - Ability ability = new SpellCastControllerTriggeredAbility( - new DamageTargetEffect(2), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false - ); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); - } - - private AshmouthDragon(final AshmouthDragon card) { - super(card); - } - - @Override - public AshmouthDragon copy() { - return new AshmouthDragon(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AttumaAtlanteanWarlord.java b/Mage.Sets/src/mage/cards/a/AttumaAtlanteanWarlord.java new file mode 100644 index 00000000000..d5e001f324e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AttumaAtlanteanWarlord.java @@ -0,0 +1,51 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AttumaAtlanteanWarlord extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(SubType.MERFOLK); + + public AttumaAtlanteanWarlord(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WARRIOR); + this.subtype.add(SubType.VILLAIN); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Other Merfolk you control get +1/+1. + this.addAbility(new SimpleStaticAbility(new BoostAllEffect( + 1, 1, Duration.WhileOnBattlefield, filter, true + ))); + + // Whenever one or more Merfolk you control attack a player, draw a card. + this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility( + new DrawCardSourceControllerEffect(1), filter, SetTargetPointer.NONE + )); + } + + private AttumaAtlanteanWarlord(final AttumaAtlanteanWarlord card) { + super(card); + } + + @Override + public AttumaAtlanteanWarlord copy() { + return new AttumaAtlanteanWarlord(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AvatarKuruk.java b/Mage.Sets/src/mage/cards/a/AvatarKuruk.java deleted file mode 100644 index 94c2be30e65..00000000000 --- a/Mage.Sets/src/mage/cards/a/AvatarKuruk.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.costs.common.WaterbendCost; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; -import mage.abilities.keyword.ExhaustAbility; -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.game.permanent.token.SpiritWorldToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AvatarKuruk extends CardImpl { - - public AvatarKuruk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AVATAR); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - this.nightCard = true; - - // Whenever you cast a spell, create a 1/1 colorless Spirit creature token with "This token can't block or be blocked by non-Spirit creatures." - this.addAbility(new SpellCastControllerTriggeredAbility( - new CreateTokenEffect(new SpiritWorldToken()), StaticFilters.FILTER_SPELL_A, false - )); - - // Exhaust -- Waterbend {20}: Take an extra turn after this one. - this.addAbility(new ExhaustAbility(new AddExtraTurnControllerEffect(), new WaterbendCost(20))); - } - - private AvatarKuruk(final AvatarKuruk card) { - super(card); - } - - @Override - public AvatarKuruk copy() { - return new AvatarKuruk(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AvatarKyoshi.java b/Mage.Sets/src/mage/cards/a/AvatarKyoshi.java deleted file mode 100644 index c4c67099081..00000000000 --- a/Mage.Sets/src/mage/cards/a/AvatarKyoshi.java +++ /dev/null @@ -1,62 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.dynamicvalue.common.GreatestAmongPermanentsValue; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.HexproofAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.mana.DynamicManaAbility; -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.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AvatarKyoshi extends CardImpl { - - public AvatarKyoshi(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AVATAR); - this.power = new MageInt(5); - this.toughness = new MageInt(4); - this.nightCard = true; - - // Lands you control have trample and hexproof. - Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS - )); - ability.addEffect(new GainAbilityControlledEffect( - HexproofAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS - ).setText("and hexproof")); - this.addAbility(ability); - - // {T}: Add X mana of any one color, where X is the greatest power among creatures you control. - this.addAbility(new DynamicManaAbility( - Mana.AnyMana(1), GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES, - new TapSourceCost(), "add X mana of any one color, " + - "where X is the greatest power among creatures you control", true - ).addHint(GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES.getHint())); - } - - private AvatarKyoshi(final AvatarKyoshi card) { - super(card); - } - - @Override - public AvatarKyoshi copy() { - return new AvatarKyoshi(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AvatarRoku.java b/Mage.Sets/src/mage/cards/a/AvatarRoku.java deleted file mode 100644 index c5b970958a7..00000000000 --- a/Mage.Sets/src/mage/cards/a/AvatarRoku.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.FirebendingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.game.permanent.token.DragonFirebendingToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AvatarRoku extends CardImpl { - - public AvatarRoku(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AVATAR); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.nightCard = true; - - // Firebending 4 - this.addAbility(new FirebendingAbility(4)); - - // {8}: Create a 4/4 red Dragon creature token with flying and firebending 4. - this.addAbility(new SimpleActivatedAbility( - new CreateTokenEffect(new DragonFirebendingToken()), new GenericManaCost(8) - )); - } - - private AvatarRoku(final AvatarRoku card) { - super(card); - } - - @Override - public AvatarRoku copy() { - return new AvatarRoku(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AvatarYangchen.java b/Mage.Sets/src/mage/cards/a/AvatarYangchen.java deleted file mode 100644 index 558ecad122c..00000000000 --- a/Mage.Sets/src/mage/cards/a/AvatarYangchen.java +++ /dev/null @@ -1,57 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.CastSecondSpellTriggeredAbility; -import mage.abilities.effects.keyword.AirbendTargetEffect; -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.FilterPermanent; -import mage.filter.common.FilterNonlandPermanent; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AvatarYangchen extends CardImpl { - - private static final FilterPermanent filter = new FilterNonlandPermanent("other target nonland permanent"); - - static { - filter.add(AnotherPredicate.instance); - } - - public AvatarYangchen(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AVATAR); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever you cast your second spell each turn, airbend up to one other target nonland permanent. - Ability ability = new CastSecondSpellTriggeredAbility(new AirbendTargetEffect()); - ability.addTarget(new TargetPermanent(0, 1, filter)); - this.addAbility(ability); - } - - private AvatarYangchen(final AvatarYangchen card) { - super(card); - } - - @Override - public AvatarYangchen copy() { - return new AvatarYangchen(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AwokenHorror.java b/Mage.Sets/src/mage/cards/a/AwokenHorror.java deleted file mode 100644 index 1fab7bc271c..00000000000 --- a/Mage.Sets/src/mage/cards/a/AwokenHorror.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class AwokenHorror extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Horror creatures"); - - static { - filter.add(Predicates.not(SubType.HORROR.getPredicate())); - } - - public AwokenHorror(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.KRAKEN); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(7); - this.toughness = new MageInt(8); - this.color.setBlue(true); - - this.nightCard = true; - - // When this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands. - this.addAbility(new TransformIntoSourceTriggeredAbility(new ReturnToHandFromBattlefieldAllEffect(filter))); - } - - private AwokenHorror(final AwokenHorror card) { - super(card); - } - - @Override - public AwokenHorror copy() { - return new AwokenHorror(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java b/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java deleted file mode 100644 index 9be6a546534..00000000000 --- a/Mage.Sets/src/mage/cards/a/AzcantaTheSunkenRuin.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.a; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.mana.BlueManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.PutCards; -import mage.constants.SuperType; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; - -/** - * - * @author LevelX2 - */ -public final class AzcantaTheSunkenRuin extends CardImpl { - - private static final FilterCard filter = new FilterCard("a noncreature, nonland card"); - - static { - filter.add(Predicates.not(CardType.CREATURE.getPredicate())); - filter.add(Predicates.not(CardType.LAND.getPredicate())); - } - - public AzcantaTheSunkenRuin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - // this card is the second face of double-faced card - this.nightCard = true; - - // (Transforms from Search for Azcanta)/ - // {T} : Add {U}. - this.addAbility(new BlueManaAbility()); - - // {2}{U} , {T} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. - Ability ability = new SimpleActivatedAbility( - new LookLibraryAndPickControllerEffect(4, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY), - new ManaCostsImpl<>("{2}{U}") - ); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private AzcantaTheSunkenRuin(final AzcantaTheSunkenRuin card) { - super(card); - } - - @Override - public AzcantaTheSunkenRuin copy() { - return new AzcantaTheSunkenRuin(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BaradDur.java b/Mage.Sets/src/mage/cards/b/BaradDur.java index d51f2572517..0a448e697a4 100644 --- a/Mage.Sets/src/mage/cards/b/BaradDur.java +++ b/Mage.Sets/src/mage/cards/b/BaradDur.java @@ -4,7 +4,7 @@ import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.condition.common.MorbidCondition; -import mage.abilities.condition.common.YouControlPermanentCondition; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.GetXValue; @@ -16,8 +16,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; import java.util.UUID; @@ -26,21 +24,14 @@ import java.util.UUID; */ public final class BaradDur extends CardImpl { - private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter); - public BaradDur(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add(SuperType.LEGENDARY); // Barad-dur enters the battlefield tapped unless you control a legendary creature. - this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); + this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance) + .addHint(YouControlALegendaryCreatureCondition.getHint())); // {T}: Add {B}. this.addAbility(new BlackManaAbility()); diff --git a/Mage.Sets/src/mage/cards/b/BarracksOfTheThousand.java b/Mage.Sets/src/mage/cards/b/BarracksOfTheThousand.java deleted file mode 100644 index 5a462272b46..00000000000 --- a/Mage.Sets/src/mage/cards/b/BarracksOfTheThousand.java +++ /dev/null @@ -1,56 +0,0 @@ -package mage.cards.b; - -import mage.abilities.common.CastSpellPaidBySourceTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.mana.WhiteManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; -import mage.filter.FilterSpell; -import mage.filter.predicate.Predicates; -import mage.game.permanent.token.GnomeSoldierStarStarToken; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class BarracksOfTheThousand extends CardImpl { - - private static final FilterSpell filter = new FilterSpell("an artifact or creature spell"); - - static { - filter.add(Predicates.or( - CardType.ARTIFACT.getPredicate(), - CardType.CREATURE.getPredicate() - )); - } - - public BarracksOfTheThousand(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - // (Transforms from Thousand Moons Smithy.) - this.nightCard = true; - - // {T}: Add {W}. - this.addAbility(new WhiteManaAbility()); - - // Whenever you cast an artifact or creature spell using mana produced by Barracks of the Thousand, create a white Gnome Soldier artifact creature token with "This creature's power and toughness are each equal to the number of artifacts and/or creatures you control." - this.addAbility(new CastSpellPaidBySourceTriggeredAbility( - new CreateTokenEffect(new GnomeSoldierStarStarToken()), - filter, false - )); - } - - private BarracksOfTheThousand(final BarracksOfTheThousand card) { - super(card); - } - - @Override - public BarracksOfTheThousand copy() { - return new BarracksOfTheThousand(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BasaltGolem.java b/Mage.Sets/src/mage/cards/b/BasaltGolem.java index f13c6b69fe7..908e1eaeeb5 100644 --- a/Mage.Sets/src/mage/cards/b/BasaltGolem.java +++ b/Mage.Sets/src/mage/cards/b/BasaltGolem.java @@ -19,7 +19,7 @@ import mage.constants.SubType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.WallToken; +import mage.game.permanent.token.BasaltGolemToken; import mage.players.Player; /** @@ -30,7 +30,7 @@ public final class BasaltGolem extends CardImpl { public BasaltGolem(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); - + this.subtype.add(SubType.GOLEM); this.power = new MageInt(2); this.toughness = new MageInt(4); @@ -83,6 +83,6 @@ class BasaltGolemEffect extends OneShotEffect { if (!creature.sacrifice(source, game)) return false; - return new WallToken().putOntoBattlefield(1, game, source, player.getId()); + return new BasaltGolemToken().putOntoBattlefield(1, game, source, player.getId()); } } diff --git a/Mage.Sets/src/mage/cards/b/BlackChocobo.java b/Mage.Sets/src/mage/cards/b/BlackChocobo.java deleted file mode 100644 index 9b6dc77adfe..00000000000 --- a/Mage.Sets/src/mage/cards/b/BlackChocobo.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.common.LandfallAbility; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.target.common.TargetCardInLibrary; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BlackChocobo extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent(SubType.BIRD, "Birds"); - - public BlackChocobo(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.BIRD); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.nightCard = true; - this.color.setGreen(true); - - // When this permanent transforms into Black Chocobo, search your library for a land card, put it onto the battlefield tapped, then shuffle. - this.addAbility(new TransformIntoSourceTriggeredAbility( - new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_LAND_A), true) - )); - - // Landfall -- Whenever a land you control enters, Birds you control get +1/+0 until end of turn. - this.addAbility(new LandfallAbility(new BoostControlledEffect( - 1, 0, Duration.EndOfTurn, filter, false - ))); - } - - private BlackChocobo(final BlackChocobo card) { - super(card); - } - - @Override - public BlackChocobo copy() { - return new BlackChocobo(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BloodbatSummoner.java b/Mage.Sets/src/mage/cards/b/BloodbatSummoner.java deleted file mode 100644 index 4491fd40c12..00000000000 --- a/Mage.Sets/src/mage/cards/b/BloodbatSummoner.java +++ /dev/null @@ -1,68 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; -import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.permanent.token.custom.CreatureToken; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BloodbatSummoner extends CardImpl { - - private static final FilterPermanent filter - = new FilterControlledPermanent(SubType.BLOOD, "Blood token you control"); - - static { - filter.add(TokenPredicate.TRUE); - } - - public BloodbatSummoner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.VAMPIRE); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // At the beginning of combat on your turn, up to one target Blood token you control becomes a 2/2 black Bat creature with flying and haste in addition to its other types. - Ability ability = new BeginningOfCombatTriggeredAbility(new BecomesCreatureTargetEffect( - new CreatureToken(2, 2, "", SubType.BAT) - .withAbility(FlyingAbility.getInstance()) - .withAbility(HasteAbility.getInstance()) - .withColor("B"), - false, false, Duration.Custom - ).setText("up to one target Blood token you control becomes a " + - "2/2 black Bat creature with flying and haste in addition to its other types")); - ability.addTarget(new TargetPermanent(0, 1, filter)); - this.addAbility(ability); - } - - private BloodbatSummoner(final BloodbatSummoner card) { - super(card); - } - - @Override - public BloodbatSummoner copy() { - return new BloodbatSummoner(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BlossomCladWerewolf.java b/Mage.Sets/src/mage/cards/b/BlossomCladWerewolf.java deleted file mode 100644 index 39737df7b9d..00000000000 --- a/Mage.Sets/src/mage/cards/b/BlossomCladWerewolf.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.mana.AddManaOfAnyColorEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BlossomCladWerewolf extends CardImpl { - - public BlossomCladWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.color.setGreen(true); - this.nightCard = true; - - // {T}: Add two mana of any one color. - this.addAbility(new SimpleManaAbility( - Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost() - )); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private BlossomCladWerewolf(final BlossomCladWerewolf card) { - super(card); - } - - @Override - public BlossomCladWerewolf copy() { - return new BlossomCladWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BottomlessPoolLockerRoom.java b/Mage.Sets/src/mage/cards/b/BottomlessPoolLockerRoom.java index 24bbd2026fa..40ea7ba49ef 100644 --- a/Mage.Sets/src/mage/cards/b/BottomlessPoolLockerRoom.java +++ b/Mage.Sets/src/mage/cards/b/BottomlessPoolLockerRoom.java @@ -26,8 +26,7 @@ public final class BottomlessPoolLockerRoom extends RoomCard { // Enchantment -- Room // Whenever one or more creatures you control deal combat damage to a player, draw a card. super(ownerId, setInfo, - new CardType[] { CardType.ENCHANTMENT }, - "{U}", "{4}{U}", SpellAbilityType.SPLIT); + "{U}", "{4}{U}"); this.subtype.add(SubType.ROOM); // Left half ability - "When you unlock this door, return up to one target creature to its owner’s hand." @@ -52,4 +51,4 @@ public final class BottomlessPoolLockerRoom extends RoomCard { public BottomlessPoolLockerRoom copy() { return new BottomlessPoolLockerRoom(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/b/BruceBanner.java b/Mage.Sets/src/mage/cards/b/BruceBanner.java new file mode 100644 index 00000000000..406068aa95e --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BruceBanner.java @@ -0,0 +1,82 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.condition.common.SourceAttackingCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.common.AdditionalCombatPhaseEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardSetInfo; +import mage.cards.ModalDoubleFacedCard; +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 BruceBanner extends ModalDoubleFacedCard { + + public BruceBanner(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SCIENTIST, SubType.HERO}, "{U}", + "The Incredible Hulk", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GAMMA, SubType.BERSERKER, SubType.HERO}, "{2}{R}{R}{G}{G}" + ); + this.getLeftHalfCard().setPT(1, 1); + this.getRightHalfCard().setPT(8, 8); + + // {X}{X}, {T}: Draw X cards. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new DrawCardSourceControllerEffect(GetXValue.instance), new ManaCostsImpl<>("{X}{X}") + ); + ability.addCost(new TapSourceCost()); + this.getLeftHalfCard().addAbility(ability); + + // {2}{R}{R}{G}{G}: Transform Bruce Banner. Activate only as a sorcery. + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility( + new TransformSourceEffect(), new ManaCostsImpl<>("{2}{R}{R}{G}{G}") + )); + + // The Incredible Hulk + // Reach + this.getRightHalfCard().addAbility(ReachAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Enrage -- Whenever The Incredible Hulk is dealt damage, put a +1/+1 counter on him. If he's attacking, untap him and there is an additional combat phase after this phase. + ability = new DealtDamageToSourceTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + .setText("put a +1/+1 counter on him"), + false, true + ); + ability.addEffect(new ConditionalOneShotEffect( + new UntapSourceEffect(), SourceAttackingCondition.instance, "If he's attacking, " + + "untap him and there is an additional combat phase after this phase" + ).addEffect(new AdditionalCombatPhaseEffect())); + this.getRightHalfCard().addAbility(ability); + } + + private BruceBanner(final BruceBanner card) { + super(card); + } + + @Override + public BruceBanner copy() { + return new BruceBanner(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BurnishedDunestomper.java b/Mage.Sets/src/mage/cards/b/BurnishedDunestomper.java deleted file mode 100644 index ad484ef7305..00000000000 --- a/Mage.Sets/src/mage/cards/b/BurnishedDunestomper.java +++ /dev/null @@ -1,41 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.keyword.TrampleAbility; -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 BurnishedDunestomper extends CardImpl { - - public BurnishedDunestomper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.DOG); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.color.setGreen(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - } - - private BurnishedDunestomper(final BurnishedDunestomper card) { - super(card); - } - - @Override - public BurnishedDunestomper copy() { - return new BurnishedDunestomper(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CaptainAmericaSuperSoldier.java b/Mage.Sets/src/mage/cards/c/CaptainAmericaSuperSoldier.java new file mode 100644 index 00000000000..5f172a134a7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CaptainAmericaSuperSoldier.java @@ -0,0 +1,72 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControllerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.HexproofAbility; +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.FilterPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CaptainAmericaSuperSoldier extends CardImpl { + + private static final Condition condition = new SourceHasCounterCondition(CounterType.SHIELD); + private static final FilterPermanent filter = new FilterPermanent(SubType.HERO, "Heroes"); + + public CaptainAmericaSuperSoldier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.subtype.add(SubType.HERO); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // Captain America enters with a shield counter on him. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.SHIELD.createInstance()), + "with a shield counter on him" + )); + + // As long as Captain America has a shield counter on him, you and other Heroes you control have hexproof. + Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilityControllerEffect(HexproofAbility.getInstance()), + condition, "as long as {this} has a shield counter on him, you" + )); + ability.addEffect(new ConditionalContinuousEffect(new GainAbilityControlledEffect( + HexproofAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + ), condition, null).concatBy("and")); + this.addAbility(ability); + } + + private CaptainAmericaSuperSoldier(final CaptainAmericaSuperSoldier card) { + super(card); + } + + @Override + public CaptainAmericaSuperSoldier copy() { + return new CaptainAmericaSuperSoldier(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CasalLurkwoodPathfinder.java b/Mage.Sets/src/mage/cards/c/CasalLurkwoodPathfinder.java index 27e9538d02f..87a3d7580c7 100644 --- a/Mage.Sets/src/mage/cards/c/CasalLurkwoodPathfinder.java +++ b/Mage.Sets/src/mage/cards/c/CasalLurkwoodPathfinder.java @@ -1,19 +1,25 @@ package mage.cards.c; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.constants.SuperType; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterLandCard; import mage.target.common.TargetCardInLibrary; @@ -22,37 +28,59 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class CasalLurkwoodPathfinder extends CardImpl { +public final class CasalLurkwoodPathfinder extends TransformingDoubleFacedCard { private static final FilterLandCard filter = new FilterLandCard("Forest card"); + private static final FilterCreaturePermanent filterLegendary = new FilterCreaturePermanent(); static { filter.add(SubType.FOREST.getPredicate()); + filterLegendary.add(SuperType.LEGENDARY.getPredicate()); } public CasalLurkwoodPathfinder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.TIEFLING, SubType.DRUID}, "{3}{G}", + "Casal, Pathbreaker Owlbear", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BIRD, SubType.BEAR}, "G" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.TIEFLING); - this.subtype.add(SubType.DRUID); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = CasalPathbreakerOwlbear.class; + // Casal, Lurkwood Pathfinder + this.getLeftHalfCard().setPT(3, 3); // Vigilance - this.addAbility(VigilanceAbility.getInstance()); + this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance()); - // When Doric, Nature's Warden enters the battlefield, search your library for a Forest card, put it into the battlefield tapped, then shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility( + // When Casal, Lurkwood Pathfinder enters the battlefield, search your library for a Forest card, put it into the battlefield tapped, then shuffle. + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), true) )); - // Whenever Doric attacks, you may pay {1}{G}. If you do, transform her. - this.addAbility(new TransformAbility()); - this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( + // Whenever Casal attacks, you may pay {1}{G}. If you do, transform her. + this.getLeftHalfCard().addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( new TransformSourceEffect().setText("transform her"), new ManaCostsImpl<>("{1}{G}") ))); + + // Casal, Pathbreaker Owlbear + this.getRightHalfCard().setPT(6, 6); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // When this creature transforms into Casal, Pathbreaker Owlbear, other legendary creatures you control get +2/+2 and gain trample until end of turn. + Ability ability = new TransformIntoSourceTriggeredAbility(new BoostControlledEffect( + 2, 2, Duration.EndOfTurn, filterLegendary, true + ).setText("other legendary creatures you control get +2/+2")); + ability.addEffect(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn, filterLegendary, true + ).setText("and gain trample until end of turn")); + this.getRightHalfCard().addAbility(ability); + + // At the beginning of your upkeep, transform Casal. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect())); } private CasalLurkwoodPathfinder(final CasalLurkwoodPathfinder card) { diff --git a/Mage.Sets/src/mage/cards/c/CasalPathbreakerOwlbear.java b/Mage.Sets/src/mage/cards/c/CasalPathbreakerOwlbear.java deleted file mode 100644 index 6d62625d256..00000000000 --- a/Mage.Sets/src/mage/cards/c/CasalPathbreakerOwlbear.java +++ /dev/null @@ -1,68 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.common.FilterCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class CasalPathbreakerOwlbear extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - public CasalPathbreakerOwlbear(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.BIRD); - this.subtype.add(SubType.BEAR); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.color.setGreen(true); - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // When this creature transforms into Doric, Owlbear Avenger, other legendary creatures you control get +2/+2 and gain trample until end of turn. - Ability ability = new TransformIntoSourceTriggeredAbility(new BoostControlledEffect( - 2, 2, Duration.EndOfTurn, filter, true - ).setText("other legendary creatures you control get +2/+2")); - ability.addEffect(new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.EndOfTurn, filter, true - ).setText("and gain trample until end of turn")); - this.addAbility(ability); - - // At the beginning of your upkeep, transform Doric. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect())); - } - - private CasalPathbreakerOwlbear(final CasalPathbreakerOwlbear card) { - super(card); - } - - @Override - public CasalPathbreakerOwlbear copy() { - return new CasalPathbreakerOwlbear(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChocoboCamp.java b/Mage.Sets/src/mage/cards/c/ChocoboCamp.java new file mode 100644 index 00000000000..2c106ed9b3e --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChocoboCamp.java @@ -0,0 +1,62 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AddCounterNextSpellDelayedTriggeredAbility; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.mana.BasicManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.common.FilterCreatureSpell; +import mage.game.permanent.token.ChocoboToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ChocoboCamp extends CardImpl { + + private static final FilterSpell filter = new FilterCreatureSpell("a Bird creature spell"); + + static { + filter.add(SubType.BIRD.getPredicate()); + } + + public ChocoboCamp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // This land enters tapped unless you control a legendary creature. + this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance) + .addHint(YouControlALegendaryCreatureCondition.getHint())); + + // {T}: Add {G}. When you next cast a Bird creature spell this turn, it enters with an additional +1/+1 counter on it. + BasicManaAbility manaAbility = new GreenManaAbility(); + manaAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new AddCounterNextSpellDelayedTriggeredAbility(filter))); + manaAbility.setUndoPossible(false); + this.addAbility(manaAbility); + + // {2}{G}{G}, {T}: Create a 2/2 green Bird creature token with "Whenever a land you control enters, this token gets +1/+0 until end of turn." + Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new ChocoboToken()), new ManaCostsImpl<>("{2}{G}{G}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + private ChocoboCamp(final ChocoboCamp card) { + super(card); + } + + @Override + public ChocoboCamp copy() { + return new ChocoboCamp(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CipherboundSpirit.java b/Mage.Sets/src/mage/cards/c/CipherboundSpirit.java deleted file mode 100644 index 6046bb3bbfb..00000000000 --- a/Mage.Sets/src/mage/cards/c/CipherboundSpirit.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.common.CanBlockOnlyFlyingAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DrawDiscardControllerEffect; -import mage.abilities.keyword.FlyingAbility; -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 CipherboundSpirit extends CardImpl { - - public CipherboundSpirit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Cipherbound Spirit can block only creatures with flying. - this.addAbility(new CanBlockOnlyFlyingAbility()); - - // {3}{U}: Draw two cards, then discard a card. - this.addAbility(new SimpleActivatedAbility( - new DrawDiscardControllerEffect(2, 1), new ManaCostsImpl<>("{3}{U}") - )); - } - - private CipherboundSpirit(final CipherboundSpirit card) { - super(card); - } - - @Override - public CipherboundSpirit copy() { - return new CipherboundSpirit(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/ConsumingSepulcher.java b/Mage.Sets/src/mage/cards/c/ConsumingSepulcher.java deleted file mode 100644 index 7499d76d724..00000000000 --- a/Mage.Sets/src/mage/cards/c/ConsumingSepulcher.java +++ /dev/null @@ -1,39 +0,0 @@ -package mage.cards.c; - -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -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 java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ConsumingSepulcher extends CardImpl { - - public ConsumingSepulcher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - this.nightCard = true; - this.color.setBlack(true); - - // At the beginning of your upkeep, each opponent loses 1 life and you gain 1 life. - Ability ability = new BeginningOfUpkeepTriggeredAbility( - new LoseLifeOpponentsEffect(1) - ); - ability.addEffect(new GainLifeEffect(1).concatBy("and")); - this.addAbility(ability); - } - - private ConsumingSepulcher(final ConsumingSepulcher card) { - super(card); - } - - @Override - public ConsumingSepulcher copy() { - return new ConsumingSepulcher(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CookingCampsite.java b/Mage.Sets/src/mage/cards/c/CookingCampsite.java deleted file mode 100644 index a85066abeb2..00000000000 --- a/Mage.Sets/src/mage/cards/c/CookingCampsite.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.c; - -import java.util.UUID; - -import mage.abilities.Ability; -import mage.abilities.common.ActivateAsSorceryActivatedAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.abilities.mana.WhiteManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.counters.CounterType; -import mage.filter.StaticFilters; - -/** - * @author balazskristof - */ -public final class CookingCampsite extends CardImpl { - - public CookingCampsite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.nightCard = true; - - // {T}: Add {W}. - this.addAbility(new WhiteManaAbility()); - - // {3}, {T}, Sacrifice an artifact: Put a +1/+1 counter on each creature you control. Activate only as a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility( - new AddCountersAllEffect(CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE), new ManaCostsImpl<>("{3}") - ); - ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT_AN)); - this.addAbility(ability); - } - - private CookingCampsite(final CookingCampsite card) { - super(card); - } - - @Override - public CookingCampsite copy() { - return new CookingCampsite(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java b/Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java deleted file mode 100644 index 292bc3b8620..00000000000 --- a/Mage.Sets/src/mage/cards/c/CosmiumCatalyst.java +++ /dev/null @@ -1,98 +0,0 @@ -package mage.cards.c; - -import java.util.UUID; - -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInExile; -import mage.util.CardUtil; - -/** - * Cosmium Catalyst - * Artifact - * {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost. - * - * @author DominionSpy - */ -public class CosmiumCatalyst extends CardImpl { - - public CosmiumCatalyst(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.nightCard = true; - this.color.setRed(true); - - // {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost. - Ability ability = new SimpleActivatedAbility(new CosmiumCatalystEffect(), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private CosmiumCatalyst(CosmiumCatalyst card) { - super(card); - } - - @Override - public CosmiumCatalyst copy() { - return new CosmiumCatalyst(this); - } -} - -class CosmiumCatalystEffect extends OneShotEffect { - - CosmiumCatalystEffect() { - super(Outcome.PlayForFree); - this.staticText = "Choose an exiled card used to craft {this} at random." + - " You may cast that card without paying its mana cost."; - } - - private CosmiumCatalystEffect(CosmiumCatalystEffect effect) { - super(effect); - } - - @Override - public CosmiumCatalystEffect copy() { - return new CosmiumCatalystEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - MageObject sourceObject = game.getObject(source.getSourceId()); - if (sourceObject == null) { - return false; - } - - Target target = new TargetCardInExile(StaticFilters.FILTER_CARD, - CardUtil.getExileZoneId(game, source.getSourceId(), - game.getState().getZoneChangeCounter(source.getSourceId()) - 2 - )); - target.withNotTarget(true); - target.setRandom(true); - if (!target.canChoose(controller.getId(), source, game)) { - return true; - } - target.chooseTarget(outcome, controller.getId(), source, game); - Card chosenCard = game.getCard(target.getFirstTarget()); - if (chosenCard != null) { - CardUtil.castSpellWithAttributesForFree(controller, source, game, chosenCard); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/c/CrystallizedSerah.java b/Mage.Sets/src/mage/cards/c/CrystallizedSerah.java deleted file mode 100644 index a10acd8f683..00000000000 --- a/Mage.Sets/src/mage/cards/c/CrystallizedSerah.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.c; - -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.s.SerahFarron; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SuperType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class CrystallizedSerah extends CardImpl { - - public CrystallizedSerah(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - this.color.setGreen(true); - this.color.setWhite(true); - - // The first legendary creature spell you cast each turn costs {2} less to cast. - this.addAbility(SerahFarron.makeAbility()); - - // Legendary creatures you control get +2/+2. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( - 2, 2, Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURES_LEGENDARY - ))); - } - - private CrystallizedSerah(final CrystallizedSerah card) { - super(card); - } - - @Override - public CrystallizedSerah copy() { - return new CrystallizedSerah(this); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DazzlingTheaterPropRoom.java b/Mage.Sets/src/mage/cards/d/DazzlingTheaterPropRoom.java index 46d4dc6c385..beaa3eef13f 100644 --- a/Mage.Sets/src/mage/cards/d/DazzlingTheaterPropRoom.java +++ b/Mage.Sets/src/mage/cards/d/DazzlingTheaterPropRoom.java @@ -8,7 +8,6 @@ import mage.abilities.keyword.ConvokeAbility; import mage.cards.CardSetInfo; import mage.cards.RoomCard; import mage.constants.CardType; -import mage.constants.SpellAbilityType; import mage.constants.SubType; import mage.filter.StaticFilters; import mage.filter.common.FilterNonlandCard; @@ -30,7 +29,7 @@ public final class DazzlingTheaterPropRoom extends RoomCard { } public DazzlingTheaterPropRoom(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}", "{2}{W}", SpellAbilityType.SPLIT); + super(ownerId, setInfo, "{3}{W}", "{2}{W}"); this.subtype.add(SubType.ROOM); // Dazzling Theater: Creature spells you cast have convoke. diff --git a/Mage.Sets/src/mage/cards/d/DefiledCryptCadaverLab.java b/Mage.Sets/src/mage/cards/d/DefiledCryptCadaverLab.java new file mode 100644 index 00000000000..3029cc0fd6b --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DefiledCryptCadaverLab.java @@ -0,0 +1,45 @@ +package mage.cards.d; + +import mage.abilities.Ability; +import mage.abilities.common.CardsLeaveGraveyardTriggeredAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.filter.StaticFilters; +import mage.game.permanent.token.HorrorEnchantmentCreatureToken; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DefiledCryptCadaverLab extends RoomCard { + + public DefiledCryptCadaverLab(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{3}{B}", "{B}"); + + // Defiled Crypt + // Whenever one or more cards leave your graveyard, create a 2/2 black Horror enchantment creature token. This ability triggers only once each turn. + this.getLeftHalfCard().addAbility(new CardsLeaveGraveyardTriggeredAbility( + new CreateTokenEffect(new HorrorEnchantmentCreatureToken()) + ).setTriggersLimitEachTurn(1)); + + // Cadaver Lab + // When you unlock this door, return target creature card from your graveyard to your hand. + Ability ability = new UnlockThisDoorTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false, false); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getRightHalfCard().addAbility(ability); + } + + private DefiledCryptCadaverLab(final DefiledCryptCadaverLab card) { + super(card); + } + + @Override + public DefiledCryptCadaverLab copy() { + return new DefiledCryptCadaverLab(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DerelictAtticWidowsWalk.java b/Mage.Sets/src/mage/cards/d/DerelictAtticWidowsWalk.java new file mode 100644 index 00000000000..969eb49623f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DerelictAtticWidowsWalk.java @@ -0,0 +1,52 @@ +package mage.cards.d; + +import mage.abilities.Ability; +import mage.abilities.common.AttacksAloneControlledTriggeredAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DerelictAtticWidowsWalk extends RoomCard { + + public DerelictAtticWidowsWalk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{B}", "{3}{B}"); + + // Derelict Attic + // When you unlock this door, you draw two cards and you lose 2 life. + Ability ability = new UnlockThisDoorTriggeredAbility( + new DrawCardSourceControllerEffect(2, true), false, true + ); + ability.addEffect(new LoseLifeSourceControllerEffect(2).concatBy("and")); + this.getLeftHalfCard().addAbility(ability); + + // Widow's Walk + // Whenever a creature you control attacks alone, it gets +1/+0 and gains deathtouch until end of turn. + ability = new AttacksAloneControlledTriggeredAbility( + new BoostTargetEffect(1, 0).setText("it gets +1/+0"), + StaticFilters.FILTER_CONTROLLED_A_CREATURE, true, false + ); + ability.addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance()) + .setText("and gains deathtouch until end of turn")); + this.getRightHalfCard().addAbility(ability); + } + + private DerelictAtticWidowsWalk(final DerelictAtticWidowsWalk card) { + super(card); + } + + @Override + public DerelictAtticWidowsWalk copy() { + return new DerelictAtticWidowsWalk(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DireStrainAnarchist.java b/Mage.Sets/src/mage/cards/d/DireStrainAnarchist.java deleted file mode 100644 index a683736bce5..00000000000 --- a/Mage.Sets/src/mage/cards/d/DireStrainAnarchist.java +++ /dev/null @@ -1,59 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.target.TargetPlayer; -import mage.target.common.TargetCreaturePermanent; -import mage.target.common.TargetPlaneswalkerPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class DireStrainAnarchist extends CardImpl { - - public DireStrainAnarchist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.color.setRed(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // Whenever Dire-Strain Anarchist attacks, it deals 2 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker. - Ability ability = new AttacksTriggeredAbility(new DamageTargetEffect(2).setText("it deals 2 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker")); - ability.addTarget(new TargetCreaturePermanent(0, 1)); - ability.addTarget(new TargetPlayer(0, 1, false)); - ability.addTarget(new TargetPlaneswalkerPermanent(0, 1)); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private DireStrainAnarchist(final DireStrainAnarchist card) { - super(card); - } - - @Override - public DireStrainAnarchist copy() { - return new DireStrainAnarchist(this); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DireStrainBrawler.java b/Mage.Sets/src/mage/cards/d/DireStrainBrawler.java deleted file mode 100644 index b1ee9f52960..00000000000 --- a/Mage.Sets/src/mage/cards/d/DireStrainBrawler.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.abilities.keyword.NightboundAbility; -import mage.abilities.keyword.VigilanceAbility; -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 DireStrainBrawler extends CardImpl { - - public DireStrainBrawler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.color.setGreen(true); - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private DireStrainBrawler(final DireStrainBrawler card) { - super(card); - } - - @Override - public DireStrainBrawler copy() { - return new DireStrainBrawler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java b/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java index 129e98d02db..5c6d9e4a605 100644 --- a/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java +++ b/Mage.Sets/src/mage/cards/d/DocentOfPerfection.java @@ -1,7 +1,7 @@ package mage.cards.d; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; @@ -9,15 +9,18 @@ import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.ComparisonType; +import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.HumanWizardToken; @@ -27,7 +30,7 @@ import java.util.UUID; /** * @author fireshoes */ -public final class DocentOfPerfection extends CardImpl { +public final class DocentOfPerfection extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledPermanent(SubType.WIZARD), ComparisonType.MORE_THAN, 2 @@ -35,22 +38,27 @@ public final class DocentOfPerfection extends CardImpl { private static final Hint hint = new ValueHint( "Wizards you control", new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.WIZARD)) ); + private static final FilterPermanent filterWizard = new FilterPermanent("Wizards"); + + static { + filterWizard.add(SubType.WIZARD.getPredicate()); + } public DocentOfPerfection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); - this.subtype.add(SubType.INSECT); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(5); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.INSECT, SubType.HORROR}, "{3}{U}{U}", + "Final Iteration", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.INSECT}, "" + ); - this.secondSideCardClazz = mage.cards.f.FinalIteration.class; + // Docent of Perfection + this.getLeftHalfCard().setPT(5, 4); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Whenever you cast an instant or sorcery spell, create a 1/1 blue Human Wizard creature token. // Then if you control three or more Wizards, transform Docent of Perfection. - this.addAbility(new TransformAbility()); Ability ability = new SpellCastControllerTriggeredAbility( new CreateTokenEffect(new HumanWizardToken()), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false @@ -59,7 +67,28 @@ public final class DocentOfPerfection extends CardImpl { new TransformSourceEffect(), condition, "Then if you control three or more Wizards, transform {this}" )); - this.addAbility(ability.addHint(hint)); + this.getLeftHalfCard().addAbility(ability.addHint(hint)); + + // Final Iteration + this.getRightHalfCard().setPT(6, 5); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Wizards you control get +2/+1 and have flying. + Ability ability2 = new SimpleStaticAbility(new BoostControlledEffect( + 2, 1, Duration.WhileOnBattlefield, filterWizard, false + )); + ability2.addEffect(new GainAbilityControlledEffect( + FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filterWizard + ).setText("and have flying")); + this.getRightHalfCard().addAbility(ability2); + + // Whenever you cast an instant or sorcery spell, create a 1/1 blue Human Wizard creature token. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new CreateTokenEffect(new HumanWizardToken()), + StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false + )); } private DocentOfPerfection(final DocentOfPerfection card) { diff --git a/Mage.Sets/src/mage/cards/d/DoctorDoom.java b/Mage.Sets/src/mage/cards/d/DoctorDoom.java new file mode 100644 index 00000000000..1006beb5aad --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DoctorDoom.java @@ -0,0 +1,83 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.game.permanent.token.DoombotToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DoctorDoom extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent("you control an artifact creature or a Plan"); + + static { + filter.add(Predicates.or( + Predicates.and( + CardType.ARTIFACT.getPredicate(), + CardType.CREATURE.getPredicate() + ), + SubType.PLAN.getPredicate() + )); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); + private static final Hint hint = new ConditionHint(condition); + + public DoctorDoom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCIENTIST); + this.subtype.add(SubType.VILLAIN); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Doctor Doom enters, create two 3/3 colorless Robot Villain artifact creature tokens named Doombot. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new DoombotToken(), 2))); + + // As long as you control an artifact creature or a Plan, Doctor Doom has indestructible. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilitySourceEffect(IndestructibleAbility.getInstance()), condition, + "as long as you control an artifact creature or a Plan, {this} has indestructible" + )).addHint(hint)); + + // At the beginning of your end step, you draw a card and lose 1 life. + Ability ability = new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(1, true)); + ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); + this.addAbility(ability); + } + + private DoctorDoom(final DoctorDoom card) { + super(card); + } + + @Override + public DoctorDoom copy() { + return new DoctorDoom(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DollmakersShopPorcelainGallery.java b/Mage.Sets/src/mage/cards/d/DollmakersShopPorcelainGallery.java index 1566406118a..1f264b2ade7 100644 --- a/Mage.Sets/src/mage/cards/d/DollmakersShopPorcelainGallery.java +++ b/Mage.Sets/src/mage/cards/d/DollmakersShopPorcelainGallery.java @@ -9,7 +9,9 @@ import mage.abilities.effects.common.continuous.SetBasePowerToughnessAllEffect; import mage.abilities.hint.ValueHint; import mage.cards.CardSetInfo; import mage.cards.RoomCard; -import mage.constants.*; +import mage.constants.Duration; +import mage.constants.SetTargetPointer; +import mage.constants.SubType; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.Predicates; @@ -29,7 +31,7 @@ public final class DollmakersShopPorcelainGallery extends RoomCard { } public DollmakersShopPorcelainGallery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}", "{4}{W}{W}", SpellAbilityType.SPLIT); + super(ownerId, setInfo, "{1}{W}", "{4}{W}{W}"); this.subtype.add(SubType.ROOM); // Dollmaker's Shop: Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token. @@ -44,7 +46,7 @@ public final class DollmakersShopPorcelainGallery extends RoomCard { this.getRightHalfCard().addAbility(right); } - private DollmakersShopPorcelainGallery (final DollmakersShopPorcelainGallery card) { + private DollmakersShopPorcelainGallery(final DollmakersShopPorcelainGallery card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/d/DoseOfDawnglow.java b/Mage.Sets/src/mage/cards/d/DoseOfDawnglow.java new file mode 100644 index 00000000000..47b25ae0b6d --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DoseOfDawnglow.java @@ -0,0 +1,39 @@ +package mage.cards.d; + +import mage.abilities.condition.common.IsMainPhaseCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.effects.keyword.BlightControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DoseOfDawnglow extends CardImpl { + + public DoseOfDawnglow(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}"); + + // Return target creature card from your graveyard to the battlefield. Then if it isn't your main phase, blight 2. + this.getSpellAbility().addEffect(new ReturnFromGraveyardToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new BlightControllerEffect(2), IsMainPhaseCondition.NOT_YOURS + ).concatBy("Then")); + } + + private DoseOfDawnglow(final DoseOfDawnglow card) { + super(card); + } + + @Override + public DoseOfDawnglow copy() { + return new DoseOfDawnglow(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DovinsAcuity.java b/Mage.Sets/src/mage/cards/d/DovinsAcuity.java index 07386d65811..163eb593436 100644 --- a/Mage.Sets/src/mage/cards/d/DovinsAcuity.java +++ b/Mage.Sets/src/mage/cards/d/DovinsAcuity.java @@ -36,7 +36,7 @@ public final class DovinsAcuity extends CardImpl { // Whenever you cast an instant spell during your main phase, you may return Dovin's Acuity to its owner's hand. this.addAbility(new SpellCastControllerTriggeredAbility( new ReturnToHandSourceEffect(true), filter, true - ).withTriggerCondition(IsMainPhaseCondition.YOUR).setTriggerPhrase("Whenever you cast an instant spell during your main phase, ")); + ).withTriggerCondition(IsMainPhaseCondition.YOURS).setTriggerPhrase("Whenever you cast an instant spell during your main phase, ")); } private DovinsAcuity(final DovinsAcuity card) { diff --git a/Mage.Sets/src/mage/cards/d/DragonKamisEgg.java b/Mage.Sets/src/mage/cards/d/DragonKamisEgg.java deleted file mode 100644 index 3def1f2d789..00000000000 --- a/Mage.Sets/src/mage/cards/d/DragonKamisEgg.java +++ /dev/null @@ -1,91 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.counters.CounterType; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.players.Player; -import mage.util.CardUtil; - -import java.util.Objects; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class DragonKamisEgg extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DRAGON); - - public DragonKamisEgg(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.EGG); - this.power = new MageInt(0); - this.toughness = new MageInt(1); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever Dragon-Kami's Egg or a Dragon you control dies, you may cast a creature spell from among cards you own in exile with hatching counters on them without paying its mana cost. - this.addAbility(new DiesThisOrAnotherTriggeredAbility( - new DragonKamisEggEffect(), false, filter - ).setTriggerPhrase("Whenever {this} or a Dragon you control dies, ")); - } - - private DragonKamisEgg(final DragonKamisEgg card) { - super(card); - } - - @Override - public DragonKamisEgg copy() { - return new DragonKamisEgg(this); - } -} - -class DragonKamisEggEffect extends OneShotEffect { - - DragonKamisEggEffect() { - super(Outcome.Benefit); - staticText = "you may cast a creature spell from among cards you own in exile " + - "with hatching counters on them without paying its mana cost"; - } - - private DragonKamisEggEffect(final DragonKamisEggEffect effect) { - super(effect); - } - - @Override - public DragonKamisEggEffect copy() { - return new DragonKamisEggEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Cards cards = new CardsImpl(); - game.getExile() - .getCardsOwned(game, player.getId()) - .stream() - .filter(Objects::nonNull) - .filter(card -> card.getCounters(game).containsKey(CounterType.HATCHLING)) - .forEach(cards::add); - return !cards.isEmpty() && CardUtil.castSpellWithAttributesForFree( - player, source, game, cards, StaticFilters.FILTER_CARD_CREATURE - ); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DreadOsseosaur.java b/Mage.Sets/src/mage/cards/d/DreadOsseosaur.java deleted file mode 100644 index aea68c4293c..00000000000 --- a/Mage.Sets/src/mage/cards/d/DreadOsseosaur.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; -import mage.abilities.effects.common.MillCardsControllerEffect; -import mage.abilities.keyword.MenaceAbility; -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 DreadOsseosaur extends CardImpl { - - public DreadOsseosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.DINOSAUR); - this.subtype.add(SubType.SKELETON); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(5); - this.toughness = new MageInt(4); - this.nightCard = true; - this.color.setBlack(true); - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Whenever Dread Osseosaur enters the battlefield or attacks, you may mill two cards. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( - new MillCardsControllerEffect(2), true - )); - } - - private DreadOsseosaur(final DreadOsseosaur card) { - super(card); - } - - @Override - public DreadOsseosaur copy() { - return new DreadOsseosaur(this); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DronepackKindred.java b/Mage.Sets/src/mage/cards/d/DronepackKindred.java deleted file mode 100644 index 3b3e4b5b1a1..00000000000 --- a/Mage.Sets/src/mage/cards/d/DronepackKindred.java +++ /dev/null @@ -1,48 +0,0 @@ - -package mage.cards.d; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Zone; - -/** - * - * @author fireshoes - */ -public final class DronepackKindred extends CardImpl { - - public DronepackKindred(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(5); - this.toughness = new MageInt(7); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // {1}: Dronepack Kindred gets +1/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new GenericManaCost(1))); - } - - private DronepackKindred(final DronepackKindred card) { - super(card); - } - - @Override - public DronepackKindred copy() { - return new DronepackKindred(this); - } -} diff --git a/Mage.Sets/src/mage/cards/e/EchoOfDeathsWail.java b/Mage.Sets/src/mage/cards/e/EchoOfDeathsWail.java deleted file mode 100644 index 03883109463..00000000000 --- a/Mage.Sets/src/mage/cards/e/EchoOfDeathsWail.java +++ /dev/null @@ -1,67 +0,0 @@ -package mage.cards.e; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.continuous.GainControlAllEffect; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.predicate.permanent.TokenPredicate; - -/** - * - * @author weirddan455 - */ -public final class EchoOfDeathsWail extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent(SubType.RAT, "Rat tokens"); - - static { - filter.add(TokenPredicate.TRUE); - } - - public EchoOfDeathsWail(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // When Echo of Death's Wail enters the battlefield, gain control of all Rat tokens. - this.addAbility(new EntersBattlefieldTriggeredAbility(new GainControlAllEffect(Duration.Custom, filter))); - - // Whenever Echo of Death's Wail attacks, you may sacrifice another creature. If you do, draw a card. - this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( - new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - ))); - } - - private EchoOfDeathsWail(final EchoOfDeathsWail card) { - super(card); - } - - @Override - public EchoOfDeathsWail copy() { - return new EchoOfDeathsWail(this); - } -} diff --git a/Mage.Sets/src/mage/cards/e/EruptingDreadwolf.java b/Mage.Sets/src/mage/cards/e/EruptingDreadwolf.java deleted file mode 100644 index b713976e65f..00000000000 --- a/Mage.Sets/src/mage/cards/e/EruptingDreadwolf.java +++ /dev/null @@ -1,45 +0,0 @@ - -package mage.cards.e; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.target.common.TargetAnyTarget; - -/** - * - * @author fireshoes - */ -public final class EruptingDreadwolf extends CardImpl { - - public EruptingDreadwolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(6); - this.toughness = new MageInt(4); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Whenever Erupting Dreadwolf attacks, it deals 2 damage to any target. - Ability ability = new AttacksTriggeredAbility(new DamageTargetEffect(2, "it"), false); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); - } - - private EruptingDreadwolf(final EruptingDreadwolf card) { - super(card); - } - - @Override - public EruptingDreadwolf copy() { - return new EruptingDreadwolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/e/EsperTerra.java b/Mage.Sets/src/mage/cards/e/EsperTerra.java deleted file mode 100644 index fd4cde6c0f4..00000000000 --- a/Mage.Sets/src/mage/cards/e/EsperTerra.java +++ /dev/null @@ -1,125 +0,0 @@ -package mage.cards.e; - -import mage.MageInt; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenCopyTargetEffect; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.abilities.effects.mana.BasicManaEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledEnchantmentPermanent; -import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.TargetPermanent; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class EsperTerra extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent("nonlegendary enchantment you control"); - - static { - filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); - } - - public EsperTerra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.SAGA); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.nightCard = true; - this.color.setRed(true); - this.color.setGreen(true); - - // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_IV); - - // I, II, III -- Create a token that's a copy of target nonlegendary enchantment you control. It gains haste. If it's a Saga, put up to three lore counters on it. Sacrifice it at the beginning of your next end step. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_III, - new EsperTerraEffect(), new TargetPermanent(filter) - ); - - // IV -- Add {W}{W}, {U}{U}, {B}{B}, {R}{R}, and {G}{G}. Exile Esper Terra, then return it to the battlefield. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_IV, - new BasicManaEffect(new Mana( - 2, 2, 2, 2, 2, 0, 0, 0 - )).setText("add {W}{W}, {U}{U}, {B}{B}, {R}{R}, and {G}{G}"), - new ExileSourceAndReturnFaceUpEffect()); - this.addAbility(sagaAbility); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - } - - private EsperTerra(final EsperTerra card) { - super(card); - } - - @Override - public EsperTerra copy() { - return new EsperTerra(this); - } -} - -class EsperTerraEffect extends OneShotEffect { - - EsperTerraEffect() { - super(Outcome.Benefit); - staticText = "create a token that's a copy of target nonlegendary enchantment you control. " + - "It gains haste. If it's a Saga, put up to three lore counters on it. " + - "Sacrifice it at the beginning of your next end step"; - } - - private EsperTerraEffect(final EsperTerraEffect effect) { - super(effect); - } - - @Override - public EsperTerraEffect copy() { - return new EsperTerraEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent == null) { - return false; - } - CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); - effect.setSavedPermanent(permanent); - effect.addAdditionalAbilities(HasteAbility.getInstance()); - effect.apply(game, source); - for (Permanent token : effect.getAddedPermanents()) { - if (!token.hasSubtype(SubType.SAGA, game)) { - continue; - } - Optional.ofNullable(source.getControllerId()) - .map(game::getPlayer) - .map(player -> player.getAmount( - 0, 3, "Choose how many lore counters to put on " + token.getIdName(), source, game - )) - .filter(amount -> amount > 0) - .ifPresent(amount -> token.addCounters(CounterType.LORE.createInstance(amount), source, game)); - } - effect.removeTokensCreatedAt(game, source, false, PhaseStep.END_TURN, TargetController.YOU); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/e/EsquireOfTheKing.java b/Mage.Sets/src/mage/cards/e/EsquireOfTheKing.java index 86d81519f8d..4c0c1812a77 100644 --- a/Mage.Sets/src/mage/cards/e/EsquireOfTheKing.java +++ b/Mage.Sets/src/mage/cards/e/EsquireOfTheKing.java @@ -3,14 +3,12 @@ package mage.cards.e; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; import mage.abilities.costs.CostAdjuster; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.hint.ConditionHint; -import mage.abilities.hint.Hint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -27,11 +25,6 @@ import java.util.UUID; */ public final class EsquireOfTheKing extends CardImpl { - private static final Hint hint = new ConditionHint( - new PermanentsOnTheBattlefieldCondition(StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY), - "You control a legendary creature" - ); - public EsquireOfTheKing(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); @@ -47,7 +40,7 @@ public final class EsquireOfTheKing extends CardImpl { ability.addCost(new TapSourceCost()); ability.setCostAdjuster(EsquireOfTheKingAdjuster.instance); ability.addEffect(new InfoEffect("This ability costs {2} less to activate if you control a legendary creature.")); - this.addAbility(ability.addHint(hint)); + this.addAbility(ability.addHint(YouControlALegendaryCreatureCondition.getHint())); } private EsquireOfTheKing(final EsquireOfTheKing card) { diff --git a/Mage.Sets/src/mage/cards/e/ExperimentalLabStaffRoom.java b/Mage.Sets/src/mage/cards/e/ExperimentalLabStaffRoom.java new file mode 100644 index 00000000000..2c5783c44fb --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ExperimentalLabStaffRoom.java @@ -0,0 +1,80 @@ +package mage.cards.e; + +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.keyword.ManifestDreadEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.Outcome; +import mage.constants.SetTargetPointer; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ExperimentalLabStaffRoom extends RoomCard { + + public ExperimentalLabStaffRoom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{3}{G}", "{2}{G}"); + + // Experimental Lab + // When you unlock this door, manifest dread, then put two +1/+1 counters and a trample counter on that creature. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new ManifestDreadEffect( + CounterType.P1P1.createInstance(2), CounterType.TRAMPLE.createInstance() + ), false, true)); + + // Staff Room + // Whenever a creature you control deals combat damage to a player, turn that creature face up or put a +1/+1 counter on it. + this.getRightHalfCard().addAbility(new DealsDamageToAPlayerAllTriggeredAbility( + new StaffRoomEffect(), StaticFilters.FILTER_CONTROLLED_CREATURE, + false, SetTargetPointer.PERMANENT, true + )); + } + + private ExperimentalLabStaffRoom(final ExperimentalLabStaffRoom card) { + super(card); + } + + @Override + public ExperimentalLabStaffRoom copy() { + return new ExperimentalLabStaffRoom(this); + } +} + +class StaffRoomEffect extends OneShotEffect { + + StaffRoomEffect() { + super(Outcome.Benefit); + staticText = "turn that creature face up or put a +1/+1 counter on it"; + } + + private StaffRoomEffect(final StaffRoomEffect effect) { + super(effect); + } + + @Override + public StaffRoomEffect copy() { + return new StaffRoomEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (player == null || permanent == null) { + return false; + } + return permanent.isFaceDown(game) + && player.chooseUse(Outcome.BoostCreature, "Turn " + permanent.getIdName() + " creature face-up?", source, game) + && permanent.turnFaceUp(source, game, source.getControllerId()) + || permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EyeOfOjerTaq.java b/Mage.Sets/src/mage/cards/e/EyeOfOjerTaq.java index ccb404fca3e..a5934e9a2ff 100644 --- a/Mage.Sets/src/mage/cards/e/EyeOfOjerTaq.java +++ b/Mage.Sets/src/mage/cards/e/EyeOfOjerTaq.java @@ -2,14 +2,15 @@ package mage.cards.e; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.SpellAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TapSourceEffect; -import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.keyword.CraftAbility; import mage.abilities.mana.AnyColorManaAbility; import mage.cards.Card; @@ -27,6 +28,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInGraveyardBattlefieldOrStack; import mage.util.CardUtil; +import mage.watchers.common.SpellsCastWatcher; import java.util.*; import java.util.stream.Collectors; @@ -149,7 +151,10 @@ class ChooseCardTypeEffect extends OneShotEffect { if (permanent == null) { return false; } - ExileZone exileZone = game.getState().getExile().getExileZone(CardUtil.getExileZoneId(game, source, game.getState().getZoneChangeCounter(mageObject.getId()) - 1)); + ExileZone exileZone = game.getState() + .getExile() + .getExileZone(CardUtil + .getExileZoneId(game, permanent.getMainCard().getId(), permanent.getMainCard().getZoneChangeCounter(game))); if (exileZone == null) { return false; } @@ -232,63 +237,74 @@ class ApexObservatoryEffect extends OneShotEffect { } } -class ApexObservatoryCastWithoutManaEffect extends CostModificationEffectImpl { +class ApexObservatoryCastWithoutManaEffect extends ContinuousEffectImpl { + class ApexObservatoryCondition implements Condition { + private final int spellCastCount; + + private ApexObservatoryCondition(int spellCastCount) { + this.spellCastCount = spellCastCount; + } + + @Override + public boolean apply(Game game, Ability source) { + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (watcher != null) { + return watcher.getSpellsCastThisTurn(playerId).size() == spellCastCount; + } + return false; + } + } + + private final FilterCard filter; private final String chosenCardType; private final UUID playerId; - private boolean used = false; + private int spellCastCount; + private AlternativeCostSourceAbility alternativeCostSourceAbility; ApexObservatoryCastWithoutManaEffect(String chosenCardType, UUID playerId) { - super(Duration.EndOfTurn, Outcome.Benefit, CostModificationType.SET_COST); + super(Duration.EndOfTurn, Layer.RulesEffects, SubLayer.NA, Outcome.PlayForFree); this.chosenCardType = chosenCardType; this.playerId = playerId; + this.filter = new FilterCard("spell of the chosen type"); + filter.add(CardType.fromString(chosenCardType).getPredicate()); staticText = "The next spell you cast this turn of the chosen type can be cast without paying its mana cost"; } + @Override + public void init(Ability source, Game game) { + super.init(source, game); + SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); + if (watcher != null) { + spellCastCount = watcher.getSpellsCastThisTurn(playerId).size(); + Condition condition = new ApexObservatoryCondition(spellCastCount); + alternativeCostSourceAbility = new AlternativeCostSourceAbility( + null, condition, null, filter, true + ); + } + } + private ApexObservatoryCastWithoutManaEffect(final ApexObservatoryCastWithoutManaEffect effect) { super(effect); this.chosenCardType = effect.chosenCardType; this.playerId = effect.playerId; this.used = effect.used; + this.spellCastCount = effect.spellCastCount; + this.filter = effect.filter; + this.alternativeCostSourceAbility = effect.alternativeCostSourceAbility; } @Override - public boolean apply(Game game, Ability source, Ability abilityToModify) { + public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(playerId); - if (controller != null) { - MageObject spell = abilityToModify.getSourceObject(game); - if (spell != null && !game.isSimulation()) { - String message = "Cast " + spell.getIdName() + " without paying its mana cost?"; - if (controller.chooseUse(Outcome.Benefit, message, source, game)) { - abilityToModify.getManaCostsToPay().clear(); - used = true; - } - } + if (controller == null) { + return false; } + alternativeCostSourceAbility.setSourceId(source.getSourceId()); + controller.getAlternativeSourceCosts().add(alternativeCostSourceAbility); return true; } - @Override - public boolean isInactive(Ability source, Game game) { - return used || super.isInactive(source, game); - } - - @Override - public boolean applies(Ability ability, Ability source, Game game) { - if (used) { - return false; - } - if (!ability.isControlledBy(playerId)) { - return false; - } - if (!(ability instanceof SpellAbility)) { - return false; - } - MageObject object = game.getObject(ability.getSourceId()); - return object != null && object.getCardType(game).stream() - .anyMatch(cardType -> cardType.toString().equals(chosenCardType)); - } - @Override public ApexObservatoryCastWithoutManaEffect copy() { return new ApexObservatoryCastWithoutManaEffect(this); diff --git a/Mage.Sets/src/mage/cards/f/FibrousEntangler.java b/Mage.Sets/src/mage/cards/f/FibrousEntangler.java deleted file mode 100644 index ac64f9a2e07..00000000000 --- a/Mage.Sets/src/mage/cards/f/FibrousEntangler.java +++ /dev/null @@ -1,50 +0,0 @@ - -package mage.cards.f; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect; -import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect; -import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Zone; - -/** - * - * @author LevelX2 - */ -public final class FibrousEntangler extends CardImpl { - - public FibrousEntangler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(6); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - // Fibrous Entangler must be blocked if able. - this.addAbility(new SimpleStaticAbility(new MustBeBlockedByAtLeastOneSourceEffect(Duration.WhileOnBattlefield))); - - // Fibrous Entangler can block an additional creature each combat. - this.addAbility(new SimpleStaticAbility(new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1))); - } - - private FibrousEntangler(final FibrousEntangler card) { - super(card); - } - - @Override - public FibrousEntangler copy() { - return new FibrousEntangler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/FinalIteration.java b/Mage.Sets/src/mage/cards/f/FinalIteration.java deleted file mode 100644 index de5fab8d202..00000000000 --- a/Mage.Sets/src/mage/cards/f/FinalIteration.java +++ /dev/null @@ -1,70 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.game.permanent.token.HumanWizardToken; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class FinalIteration extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("Wizards"); - - static { - filter.add(SubType.WIZARD.getPredicate()); - } - - public FinalIteration(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.INSECT); - this.power = new MageInt(6); - this.toughness = new MageInt(5); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Wizards you control get +2/+1 and have flying. - Ability ability = new SimpleStaticAbility(new BoostControlledEffect( - 2, 1, Duration.WhileOnBattlefield, filter, false - )); - ability.addEffect(new GainAbilityControlledEffect( - FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter - ).setText("and have flying")); - this.addAbility(ability); - - // Whenever you cast an instant or sorcery spell, create a 1/1 blue Human Wizard creature token. - this.addAbility(new SpellCastControllerTriggeredAbility( - new CreateTokenEffect(new HumanWizardToken()), - StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false - )); - } - - private FinalIteration(final FinalIteration card) { - super(card); - } - - @Override - public FinalIteration copy() { - return new FinalIteration(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/FireLordSozin.java b/Mage.Sets/src/mage/cards/f/FireLordSozin.java deleted file mode 100644 index 5074b2310fa..00000000000 --- a/Mage.Sets/src/mage/cards/f/FireLordSozin.java +++ /dev/null @@ -1,158 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.delayed.ReflexiveTriggeredAbility; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.costs.mana.ManaCosts; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.keyword.FirebendingAbility; -import mage.abilities.keyword.MenaceAbility; -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.filter.FilterCard; -import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; -import mage.util.CardUtil; - -import java.util.Objects; -import java.util.Set; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class FireLordSozin extends CardImpl { - - public FireLordSozin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.color.setBlack(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // Firebending 3 - this.addAbility(new FirebendingAbility(3)); - - // Whenever Fire Lord Sozin deals combat damage to a player, you may pay {X}. When you do, put any number of target creature cards with total mana value X or less from that player's graveyard onto the battlefield under your control. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new FireLordSozinEffect())); - } - - private FireLordSozin(final FireLordSozin card) { - super(card); - } - - @Override - public FireLordSozin copy() { - return new FireLordSozin(this); - } -} - -class FireLordSozinEffect extends OneShotEffect { - - FireLordSozinEffect() { - super(Outcome.Benefit); - staticText = "you may pay {X}. When you do, put any number of target creature cards with " + - "total mana value X or less from that player's graveyard onto the battlefield under your control"; - } - - private FireLordSozinEffect(final FireLordSozinEffect effect) { - super(effect); - } - - @Override - public FireLordSozinEffect copy() { - return new FireLordSozinEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - if (controller == null || !controller.chooseUse(Outcome.BoostCreature, "Pay {X}?", source, game)) { - return false; - } - int xValue = controller.announceX(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source, true); - ManaCosts cost = new ManaCostsImpl<>("{X}"); - cost.add(new GenericManaCost(xValue)); - if (!cost.pay(source, game, source, source.getControllerId(), false, null)) { - return false; - } - ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), false); - ability.addTarget(new FireLordSozinTarget((UUID) getValue("damagedPlayer"), xValue)); - game.fireReflexiveTriggeredAbility(ability, source); - return true; - } -} - -class FireLordSozinTarget extends TargetCardInGraveyard { - - private final int xValue; - - private static final FilterCard makeFilter(UUID ownerId, int xValue) { - FilterCard filter = new FilterCreatureCard("creature cards with total mana value " + xValue + " or less from that player's graveyard"); - filter.add(new OwnerIdPredicate(ownerId)); - return filter; - } - - FireLordSozinTarget(UUID ownerId, int xValue) { - super(0, Integer.MAX_VALUE, makeFilter(ownerId, xValue), false); - this.xValue = xValue; - } - - private FireLordSozinTarget(final FireLordSozinTarget target) { - super(target); - this.xValue = target.xValue; - } - - @Override - public FireLordSozinTarget copy() { - return new FireLordSozinTarget(this); - } - - @Override - public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) { - return super.canTarget(playerId, id, source, game) - && CardUtil.checkCanTargetTotalValueLimit(this.getTargets(), id, MageObject::getManaValue, xValue, game); - } - - @Override - public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) { - return CardUtil.checkPossibleTargetsTotalValueLimit( - this.getTargets(), - super.possibleTargets(sourceControllerId, source, game), - MageObject::getManaValue, xValue, game - ); - } - - @Override - public String getMessage(Game game) { - // shows selected total - int selectedValue = this.getTargets().stream() - .map(game::getObject) - .filter(Objects::nonNull) - .mapToInt(MageObject::getManaValue) - .sum(); - return super.getMessage(game) + " (selected total mana value " + selectedValue + ")"; - } -} diff --git a/Mage.Sets/src/mage/cards/f/FragmentOfKonda.java b/Mage.Sets/src/mage/cards/f/FragmentOfKonda.java deleted file mode 100644 index 77b85acde32..00000000000 --- a/Mage.Sets/src/mage/cards/f/FragmentOfKonda.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.common.DiesSourceTriggeredAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.DefenderAbility; -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 FragmentOfKonda extends CardImpl { - - public FragmentOfKonda(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.nightCard = true; - - // Defender - this.addAbility(DefenderAbility.getInstance()); - - // When Fragment of Konda dies, draw a card. - this.addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1))); - } - - private FragmentOfKonda(final FragmentOfKonda card) { - super(card); - } - - @Override - public FragmentOfKonda copy() { - return new FragmentOfKonda(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/FullThrottle.java b/Mage.Sets/src/mage/cards/f/FullThrottle.java index 740867674f2..6783e96aca9 100644 --- a/Mage.Sets/src/mage/cards/f/FullThrottle.java +++ b/Mage.Sets/src/mage/cards/f/FullThrottle.java @@ -1,22 +1,25 @@ package mage.cards.f; -import java.util.UUID; - +import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; -import mage.abilities.condition.common.IsMainPhaseCondition; +import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.*; +import mage.abilities.effects.common.AdditionalCombatPhaseEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.UntapAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AttackedThisTurnPredicate; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.turn.Turn; + +import java.util.UUID; /** - * * @author Jmlundeen */ public final class FullThrottle extends CardImpl { @@ -24,16 +27,15 @@ public final class FullThrottle extends CardImpl { public FullThrottle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}"); - // After this main phase, there are two additional combat phases. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new AdditionalCombatPhaseEffect(2), - IsMainPhaseCondition.ANY, + new AdditionalCombatPhaseEffect(2), FullThrottleCondition.instance, "After this main phase, there are two additional combat phases." )); + // At the beginning of each combat this turn, untap all creatures that attacked this turn. - DelayedTriggeredAbility ability = new FullThrottleTriggeredAbility(); - this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(ability).concatBy("
")); + this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new FullThrottleTriggeredAbility()) + .concatBy("
")); } private FullThrottle(final FullThrottle card) { @@ -46,14 +48,25 @@ public final class FullThrottle extends CardImpl { } } +enum FullThrottleCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return game.getTurnPhaseType().isMain(); + } +} + class FullThrottleTriggeredAbility extends DelayedTriggeredAbility { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that attacked this turn"); + + private static final FilterPermanent filter = new FilterCreaturePermanent("creatures that attacked this turn"); static { filter.add(AttackedThisTurnPredicate.instance); } + public FullThrottleTriggeredAbility() { - super(new UntapAllEffect(filter), Duration.EndOfTurn, false); + super(new UntapAllEffect(filter), Duration.EndOfTurn, false, false); setTriggerPhrase("At the beginning of each combat this turn, "); } @@ -73,7 +86,6 @@ class FullThrottleTriggeredAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - Turn turn = game.getState().getTurn(); - return turn.getPhase().getType() == TurnPhase.COMBAT; + return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FuneralRoomAwakeningHall.java b/Mage.Sets/src/mage/cards/f/FuneralRoomAwakeningHall.java index a10d8b8f31e..23d75f79f87 100644 --- a/Mage.Sets/src/mage/cards/f/FuneralRoomAwakeningHall.java +++ b/Mage.Sets/src/mage/cards/f/FuneralRoomAwakeningHall.java @@ -8,8 +8,6 @@ import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.common.ReturnFromYourGraveyardToBattlefieldAllEffect; import mage.cards.CardSetInfo; import mage.cards.RoomCard; -import mage.constants.CardType; -import mage.constants.SpellAbilityType; import mage.constants.SubType; import mage.filter.StaticFilters; @@ -21,7 +19,7 @@ import java.util.UUID; public final class FuneralRoomAwakeningHall extends RoomCard { public FuneralRoomAwakeningHall(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}", "{6}{B}{B}", SpellAbilityType.SPLIT); + super(ownerId, setInfo, "{2}{B}", "{6}{B}{B}"); this.subtype.add(SubType.ROOM); // Funeral Room: Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life. diff --git a/Mage.Sets/src/mage/cards/f/FurnaceBlessedConqueror.java b/Mage.Sets/src/mage/cards/f/FurnaceBlessedConqueror.java deleted file mode 100644 index 3b69d44dcf8..00000000000 --- a/Mage.Sets/src/mage/cards/f/FurnaceBlessedConqueror.java +++ /dev/null @@ -1,88 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenCopyTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class FurnaceBlessedConqueror extends CardImpl { - - public FurnaceBlessedConqueror(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.color.setRed(true); - this.nightCard = true; - - // Whenever Furnace-Blessed Conqueror attacks, create a tapped and attacking token that's a copy of it. Put a +1/+1 counter on that token for each +1/+1 counter on Furnace-Blessed Conqueror. Sacrifice that token at the beginning of the next end step. - this.addAbility(new AttacksTriggeredAbility(new FurnaceBlessedConquerorEffect())); - } - - private FurnaceBlessedConqueror(final FurnaceBlessedConqueror card) { - super(card); - } - - @Override - public FurnaceBlessedConqueror copy() { - return new FurnaceBlessedConqueror(this); - } -} - -class FurnaceBlessedConquerorEffect extends OneShotEffect { - - FurnaceBlessedConquerorEffect() { - super(Outcome.Benefit); - staticText = "create a tapped and attacking token that's a copy of it. " + - "Put a +1/+1 counter on that token for each +1/+1 counter on {this}. " + - "Sacrifice that token at the beginning of the next end step"; - } - - private FurnaceBlessedConquerorEffect(final FurnaceBlessedConquerorEffect effect) { - super(effect); - } - - @Override - public FurnaceBlessedConquerorEffect copy() { - return new FurnaceBlessedConquerorEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = source.getSourcePermanentIfItStillExists(game); - if (permanent == null) { - return false; - } - CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect( - null, null, false, 1, true, true - ); - effect.setSavedPermanent(permanent); - effect.apply(game, source); - effect.sacrificeTokensCreatedAtNextEndStep(game, source); - int counters = permanent.getCounters(game).getCount(CounterType.P1P1); - if (counters < 1) { - return true; - } - for (Permanent token : effect.getAddedPermanents()) { - token.addCounters(CounterType.P1P1.createInstance(counters), source, game); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GalianBeast.java b/Mage.Sets/src/mage/cards/g/GalianBeast.java deleted file mode 100644 index 9ff6b2f8107..00000000000 --- a/Mage.Sets/src/mage/cards/g/GalianBeast.java +++ /dev/null @@ -1,51 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.common.DiesSourceTriggeredAbility; -import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; -import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TrampleAbility; -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 GalianBeast extends CardImpl { - - public GalianBeast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.BEAST); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.nightCard = true; - this.color.setBlack(true); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - - // When Galian Beast dies, return it to the battlefield tapped. - this.addAbility(new DiesSourceTriggeredAbility(new ReturnSourceFromGraveyardToBattlefieldEffect(true) - .setText("return it to the battlefield tapped"))); - } - - private GalianBeast(final GalianBeast card) { - super(card); - } - - @Override - public GalianBeast copy() { - return new GalianBeast(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GarlandRoyalKidnapper.java b/Mage.Sets/src/mage/cards/g/GarlandRoyalKidnapper.java new file mode 100644 index 00000000000..28d09f9e005 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GarlandRoyalKidnapper.java @@ -0,0 +1,173 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.BecomesMonarchTargetEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.hint.common.MonarchHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetOpponent; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GarlandRoyalKidnapper extends CardImpl { + + private static final FilterControlledCreaturePermanent filter + = new FilterControlledCreaturePermanent("creatures you control but don't own"); + + static { + filter.add(TargetController.NOT_YOU.getOwnerPredicate()); + } + + public GarlandRoyalKidnapper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // When Garland enters, target opponent becomes the monarch. + Ability ability = new EntersBattlefieldTriggeredAbility(new BecomesMonarchTargetEffect()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability.addHint(MonarchHint.instance)); + + // Whenever an opponent becomes the monarch, gain control of target creature that player controls for as long as they're the monarch. + this.addAbility(new GarlandRoyalKidnapperTriggeredAbility()); + + // Creatures you control but don't own get +2/+2 and can't be sacrificed. + ability = new SimpleStaticAbility(new BoostAllEffect( + 2, 2, Duration.WhileOnBattlefield, filter, false + )); + ability.addEffect(new GarlandRoyalKidnapperSacrificeEffect()); + this.addAbility(ability); + } + + private GarlandRoyalKidnapper(final GarlandRoyalKidnapper card) { + super(card); + } + + @Override + public GarlandRoyalKidnapper copy() { + return new GarlandRoyalKidnapper(this); + } +} + +class GarlandRoyalKidnapperTriggeredAbility extends TriggeredAbilityImpl { + + GarlandRoyalKidnapperTriggeredAbility() { + super(Zone.BATTLEFIELD, new GarlandRoyalKidnapperControlEffect()); + this.addTarget(new TargetOpponent()); + this.setTriggerPhrase("Whenever an opponent becomes the monarch, "); + } + + private GarlandRoyalKidnapperTriggeredAbility(final GarlandRoyalKidnapperTriggeredAbility ability) { + super(ability); + } + + @Override + public GarlandRoyalKidnapperTriggeredAbility copy() { + return new GarlandRoyalKidnapperTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.BECOMES_MONARCH; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Player player = game.getPlayer(event.getTargetId()); + if (player == null || !game.getOpponents(getControllerId()).contains(player.getId())) { + return false; + } + FilterPermanent filter = new FilterCreaturePermanent("creature controlled by " + player.getName()); + filter.add(new ControllerIdPredicate(player.getId())); + this.getTargets().clear(); + this.addTarget(new TargetPermanent(filter)); + this.getEffects().setValue("monarchId", player.getId()); + return true; + } +} + +class GarlandRoyalKidnapperControlEffect extends GainControlTargetEffect { + + GarlandRoyalKidnapperControlEffect() { + super(Duration.Custom, true); + staticText = "gain control of target creature that player controls for as long as they're the monarch"; + } + + private GarlandRoyalKidnapperControlEffect(final GarlandRoyalKidnapperControlEffect effect) { + super(effect); + } + + @Override + public GarlandRoyalKidnapperControlEffect copy() { + return new GarlandRoyalKidnapperControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null + && Optional + .ofNullable((UUID) getValue("monarchId")) + .filter(uuid -> uuid.equals(game.getMonarchId())) + .isPresent()) { + return super.apply(game, source); + } + discard(); + return false; + } +} + +class GarlandRoyalKidnapperSacrificeEffect extends ContinuousEffectImpl { + + GarlandRoyalKidnapperSacrificeEffect() { + super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); + staticText = "and can't be sacrificed"; + } + + private GarlandRoyalKidnapperSacrificeEffect(final GarlandRoyalKidnapperSacrificeEffect effect) { + super(effect); + } + + @Override + public GarlandRoyalKidnapperSacrificeEffect copy() { + return new GarlandRoyalKidnapperSacrificeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source, game + )) { + if (!permanent.isOwnedBy(source.getControllerId())) { + permanent.setCanBeSacrificed(true); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GhastlyHaunting.java b/Mage.Sets/src/mage/cards/g/GhastlyHaunting.java deleted file mode 100644 index 75e1bcf6701..00000000000 --- a/Mage.Sets/src/mage/cards/g/GhastlyHaunting.java +++ /dev/null @@ -1,47 +0,0 @@ - -package mage.cards.g; - -import java.util.UUID; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.ControlEnchantedEffect; -import mage.abilities.keyword.EnchantAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; - -/** - * - * @author BetaSteward - */ -public final class GhastlyHaunting extends CardImpl { - - public GhastlyHaunting(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},""); - this.subtype.add(SubType.AURA); - this.color.setBlue(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Enchant creature - TargetPermanent auraTarget = new TargetCreaturePermanent(); - this.getSpellAbility().addTarget(auraTarget); - this.addAbility(new EnchantAbility(auraTarget)); - - // You control enchanted creature. - this.addAbility(new SimpleStaticAbility(new ControlEnchantedEffect())); - } - - private GhastlyHaunting(final GhastlyHaunting card) { - super(card); - } - - @Override - public GhastlyHaunting copy() { - return new GhastlyHaunting(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GhostlyKeybearer.java b/Mage.Sets/src/mage/cards/g/GhostlyKeybearer.java new file mode 100644 index 00000000000..c387627e364 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GhostlyKeybearer.java @@ -0,0 +1,91 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GhostlyKeybearer extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ROOM); + + public GhostlyKeybearer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever this creature deals combat damage to a player, unlock a locked door of up to one target Room you control. + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new GhostlyKeybearerEffect()); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.addAbility(ability); + } + + private GhostlyKeybearer(final GhostlyKeybearer card) { + super(card); + } + + @Override + public GhostlyKeybearer copy() { + return new GhostlyKeybearer(this); + } +} + +class GhostlyKeybearerEffect extends OneShotEffect { + + GhostlyKeybearerEffect() { + super(Outcome.Benefit); + staticText = "unlock a locked door of up to one target Room you control"; + } + + private GhostlyKeybearerEffect(final GhostlyKeybearerEffect effect) { + super(effect); + } + + @Override + public GhostlyKeybearerEffect copy() { + return new GhostlyKeybearerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (player == null || permanent == null || !permanent.isLeftDoorUnlocked() && !permanent.isRightDoorUnlocked()) { + return false; + } + boolean unlockLeft; + if (!permanent.isLeftDoorUnlocked() && permanent.isRightDoorUnlocked()) { + unlockLeft = true; + } else if (permanent.isLeftDoorUnlocked() && !permanent.isRightDoorUnlocked()) { + unlockLeft = false; + } else { + unlockLeft = player.chooseUse( + Outcome.Neutral, "Unlock the left door or the right door?", + null, "Left", "Right", source, game + ); + } + return permanent.unlockDoor(game, source, unlockLeft); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GlassworksShatteredYard.java b/Mage.Sets/src/mage/cards/g/GlassworksShatteredYard.java new file mode 100644 index 00000000000..ad65477e7bd --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlassworksShatteredYard.java @@ -0,0 +1,42 @@ +package mage.cards.g; + +import mage.abilities.Ability; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.TargetController; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GlassworksShatteredYard extends RoomCard { + + public GlassworksShatteredYard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{R}", "{4}{R}"); + + // Glassworks + // When you unlock this door, this Room deals 4 damage to target creature an opponent controls. + Ability ability = new UnlockThisDoorTriggeredAbility(new DamageTargetEffect(4), false, true); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.getLeftHalfCard().addAbility(ability); + + // Shattered Yard + // At the beginning of your end step, this Room deals 1 damage to each opponent. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new DamagePlayersEffect(1, TargetController.OPPONENT))); + } + + private GlassworksShatteredYard(final GlassworksShatteredYard card) { + super(card); + } + + @Override + public GlassworksShatteredYard copy() { + return new GlassworksShatteredYard(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GoblinBlastRunner.java b/Mage.Sets/src/mage/cards/g/GoblinBlastRunner.java index b532381e56d..3371fa82418 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinBlastRunner.java +++ b/Mage.Sets/src/mage/cards/g/GoblinBlastRunner.java @@ -62,12 +62,9 @@ enum GoblinBlastRunnerCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - UUID player = source.getControllerId(); PermanentsSacrificedWatcher watcher = game.getState().getWatcher(PermanentsSacrificedWatcher.class); - if (watcher == null) { - return false; - } - return watcher.getThisTurnSacrificedPermanents(player) != null; + return watcher != null + && !watcher.getThisTurnSacrificedPermanents(source.getControllerId()).isEmpty(); } public static Hint getHint() { diff --git a/Mage.Sets/src/mage/cards/g/GornogTheRedReaper.java b/Mage.Sets/src/mage/cards/g/GornogTheRedReaper.java index 93f24e52fe4..7466457aa59 100644 --- a/Mage.Sets/src/mage/cards/g/GornogTheRedReaper.java +++ b/Mage.Sets/src/mage/cards/g/GornogTheRedReaper.java @@ -20,7 +20,7 @@ import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.AttackingPredicate; -import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster; import java.util.UUID; @@ -61,7 +61,7 @@ public final class GornogTheRedReaper extends CardImpl { Ability ability = new AttacksPlayerWithCreaturesTriggeredAbility( new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.COWARD).setText("target creature that player controls becomes a Coward"), filterWarrior, SetTargetPointer.PLAYER); - ability.addTarget(new TargetPermanent()); + ability.addTarget(new TargetCreaturePermanent()); ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GrandEntrywayElegantRotunda.java b/Mage.Sets/src/mage/cards/g/GrandEntrywayElegantRotunda.java new file mode 100644 index 00000000000..2df43f1745e --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrandEntrywayElegantRotunda.java @@ -0,0 +1,42 @@ +package mage.cards.g; + +import mage.abilities.Ability; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.counters.CounterType; +import mage.game.permanent.token.GlimmerToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GrandEntrywayElegantRotunda extends RoomCard { + + public GrandEntrywayElegantRotunda(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{1}{W}", "{2}{W}"); + + // Grand Entryway + // When you unlock this door, create a 1/1 white Glimmer enchantment creature token. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new CreateTokenEffect(new GlimmerToken()), false, true)); + + // Elegant Rotunda + // When you unlock this door, put a +1/+1 counter on each of up to two target creatures. + Ability ability = new UnlockThisDoorTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false, false); + ability.addTarget(new TargetCreaturePermanent(0, 2)); + this.getRightHalfCard().addAbility(ability); + } + + private GrandEntrywayElegantRotunda(final GrandEntrywayElegantRotunda card) { + super(card); + } + + @Override + public GrandEntrywayElegantRotunda copy() { + return new GrandEntrywayElegantRotunda(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GreenhouseRicketyGazebo.java b/Mage.Sets/src/mage/cards/g/GreenhouseRicketyGazebo.java new file mode 100644 index 00000000000..f91689a14c9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GreenhouseRicketyGazebo.java @@ -0,0 +1,48 @@ +package mage.cards.g; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.common.MillThenPutInHandEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.DependencyType; +import mage.constants.Duration; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GreenhouseRicketyGazebo extends RoomCard { + + public GreenhouseRicketyGazebo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{G}", "{3}{G}"); + + // Greenhouse + // Lands you control have "{T}: Add one mana of any color." + ContinuousEffect effect = new GainAbilityControlledEffect( + new AnyColorManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS, false + ); + effect.addDependedToType(DependencyType.BecomeNonbasicLand); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(effect)); + + // Rickety Gazebo + // When you unlock this door, mill four cards, then return up to two permanent cards from among them to your hand. + this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new MillThenPutInHandEffect( + 4, StaticFilters.FILTER_CARD_PERMANENTS, null, true, 2 + ), false, false)); + } + + private GreenhouseRicketyGazebo(final GreenhouseRicketyGazebo card) { + super(card); + } + + @Override + public GreenhouseRicketyGazebo copy() { + return new GreenhouseRicketyGazebo(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GrimReapersSprint.java b/Mage.Sets/src/mage/cards/g/GrimReapersSprint.java index 10efdaf4a85..d0f66b8037c 100644 --- a/Mage.Sets/src/mage/cards/g/GrimReapersSprint.java +++ b/Mage.Sets/src/mage/cards/g/GrimReapersSprint.java @@ -59,7 +59,7 @@ public final class GrimReapersSprint extends CardImpl { "untap each creature you control" ), false ); - triggeredAbility.addEffect(new ConditionalOneShotEffect(new AdditionalCombatPhaseEffect(), IsMainPhaseCondition.YOUR, "If it's your main phase, there is an additional combat phase after this phase.")); + triggeredAbility.addEffect(new ConditionalOneShotEffect(new AdditionalCombatPhaseEffect(), IsMainPhaseCondition.YOURS, "If it's your main phase, there is an additional combat phase after this phase.")); this.addAbility(triggeredAbility); // Enchanted creature gets +2/+2 and has haste. @@ -110,4 +110,4 @@ class GrimReapersSprintCostModificationEffect extends CostModificationEffectImpl public GrimReapersSprintCostModificationEffect copy() { return new GrimReapersSprintCostModificationEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GristThePlagueSwarm.java b/Mage.Sets/src/mage/cards/g/GristThePlagueSwarm.java deleted file mode 100644 index 41a53240019..00000000000 --- a/Mage.Sets/src/mage/cards/g/GristThePlagueSwarm.java +++ /dev/null @@ -1,163 +0,0 @@ -package mage.cards.g; - -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenCopyTargetEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.counters.CounterType; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentCard; -import mage.game.permanent.token.IzoniInsectToken; -import mage.players.Player; -import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTargets; - -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * @author Susucr - */ -public final class GristThePlagueSwarm extends CardImpl { - - public GristThePlagueSwarm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GRIST); - this.setStartingLoyalty(3); - - this.color.setBlack(true); - this.color.setGreen(true); - this.nightCard = true; - - // +1: Create a 1/1 black and green Insect creature token, then mill two cards. Put a deathtouch counter on the token if a black card was milled this way. - this.addAbility(new LoyaltyAbility(new GristThePlagueSwarmPlus1Effect(), 1)); - - // -2: Destroy target artifact or enchantment. - Ability ability = new LoyaltyAbility(new DestroyTargetEffect(), -2); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); - this.addAbility(ability); - - // -6: For each creature card in your graveyard, create a token that's a copy of it, except it's a 1/1 black and green Insect. - this.addAbility(new LoyaltyAbility(new GristThePlagueSwarmMinus6Effect(), -6)); - } - - private GristThePlagueSwarm(final GristThePlagueSwarm card) { - super(card); - } - - @Override - public GristThePlagueSwarm copy() { - return new GristThePlagueSwarm(this); - } -} - -class GristThePlagueSwarmPlus1Effect extends OneShotEffect { - - GristThePlagueSwarmPlus1Effect() { - super(Outcome.PutCreatureInPlay); - staticText = "Create a 1/1 black and green Insect creature token, then mill two cards. " - + "Put a deathtouch counter on the token if a black card was milled this way."; - } - - private GristThePlagueSwarmPlus1Effect(final GristThePlagueSwarmPlus1Effect effect) { - super(effect); - } - - @Override - public GristThePlagueSwarmPlus1Effect copy() { - return new GristThePlagueSwarmPlus1Effect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - - // Create a 1/1 black and green Insect creature token - CreateTokenEffect effect = new CreateTokenEffect(new IzoniInsectToken()); - effect.apply(game, source); - - // Then mill two cards - Cards cards = controller.millCards(2, source, game); - - // Put a deathtouch counter on the token if a black card was milled this way. - if (cards.getCards(game).stream().anyMatch(card -> card.getColor(game).isBlack())) { - List tokens = effect - .getLastAddedTokenIds() - .stream() - .map(game::getPermanent) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - if (!tokens.isEmpty()) { - Effect addEffect = new AddCountersTargetEffect(CounterType.DEATHTOUCH.createInstance()); - addEffect.setTargetPointer(new FixedTargets(tokens, game)); - addEffect.apply(game, source); - } - } - return true; - } -} - -class GristThePlagueSwarmMinus6Effect extends OneShotEffect { - - GristThePlagueSwarmMinus6Effect() { - super(Outcome.PutCreatureInPlay); - staticText = "For each creature card in your graveyard, create a token that's a copy of it, " - + "except it's a 1/1 black and green Insect."; - } - - private GristThePlagueSwarmMinus6Effect(final GristThePlagueSwarmMinus6Effect effect) { - super(effect); - } - - @Override - public GristThePlagueSwarmMinus6Effect copy() { - return new GristThePlagueSwarmMinus6Effect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Set cards = controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game); - if (cards.isEmpty()) { - return false; - } - for (Card card : cards) { - CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect( - null, null, false, 1, false, - false, null, 1, 1, false - ); - effect.setSavedPermanent(new PermanentCard(card, controller.getId(), game)); - effect.setOnlyColor(new ObjectColor("BG")); - effect.setOnlySubType(SubType.INSECT); - effect.apply(game, source); - } - return true; - } - -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/g/GristVoraciousLarva.java b/Mage.Sets/src/mage/cards/g/GristVoraciousLarva.java index e685b4684d1..0292cfb325f 100644 --- a/Mage.Sets/src/mage/cards/g/GristVoraciousLarva.java +++ b/Mage.Sets/src/mage/cards/g/GristVoraciousLarva.java @@ -1,46 +1,73 @@ package mage.cards.g; -import mage.MageInt; -import mage.constants.Pronoun; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.DeathtouchAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.counters.CounterType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentCard; +import mage.game.permanent.token.IzoniInsectToken; import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTargets; +import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; /** * @author Susucr */ -public final class GristVoraciousLarva extends CardImpl { +public final class GristVoraciousLarva extends TransformingDoubleFacedCard { public GristVoraciousLarva(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.INSECT}, "{G}", + "Grist, the Plague Swarm", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.GRIST}, "BG" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.INSECT); - this.power = new MageInt(1); - this.toughness = new MageInt(2); - - this.secondSideCardClazz = GristThePlagueSwarm.class; + // Grist, Voracious Larva + this.getLeftHalfCard().setPT(1, 2); // Deathtouch - this.addAbility(DeathtouchAbility.getInstance()); + this.getLeftHalfCard().addAbility(DeathtouchAbility.getInstance()); // Whenever Grist, Voracious Larva or another creature you control enters, if it entered from your graveyard or was cast from your graveyard, you may pay {G}. If you do, exile Grist, then return it to the battlefield transformed under its owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new GristVoraciousLarvaTriggeredAbility()); + this.getLeftHalfCard().addAbility(new GristVoraciousLarvaTriggeredAbility()); + + // Grist, the Plague Swarm + this.getRightHalfCard().setStartingLoyalty(3); + + // +1: Create a 1/1 black and green Insect creature token, then mill two cards. Put a deathtouch counter on the token if a black card was milled this way. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new GristThePlagueSwarmPlus1Effect(), 1)); + + // -2: Destroy target artifact or enchantment. + Ability ability = new LoyaltyAbility(new DestroyTargetEffect(), -2); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getRightHalfCard().addAbility(ability); + + // -6: For each creature card in your graveyard, create a token that's a copy of it, except it's a 1/1 black and green Insect. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new GristThePlagueSwarmMinus6Effect(), -6)); } private GristVoraciousLarva(final GristVoraciousLarva card) { @@ -100,3 +127,93 @@ class GristVoraciousLarvaTriggeredAbility extends EntersBattlefieldThisOrAnother return fromGraveyard && super.checkTrigger(event, game); } } + +class GristThePlagueSwarmPlus1Effect extends OneShotEffect { + + GristThePlagueSwarmPlus1Effect() { + super(Outcome.PutCreatureInPlay); + staticText = "Create a 1/1 black and green Insect creature token, then mill two cards. " + + "Put a deathtouch counter on the token if a black card was milled this way."; + } + + private GristThePlagueSwarmPlus1Effect(final GristThePlagueSwarmPlus1Effect effect) { + super(effect); + } + + @Override + public GristThePlagueSwarmPlus1Effect copy() { + return new GristThePlagueSwarmPlus1Effect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + + // Create a 1/1 black and green Insect creature token + CreateTokenEffect effect = new CreateTokenEffect(new IzoniInsectToken()); + effect.apply(game, source); + + // Then mill two cards + Cards cards = controller.millCards(2, source, game); + + // Put a deathtouch counter on the token if a black card was milled this way. + if (cards.getCards(game).stream().anyMatch(card -> card.getColor(game).isBlack())) { + List tokens = effect + .getLastAddedTokenIds() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (!tokens.isEmpty()) { + Effect addEffect = new AddCountersTargetEffect(CounterType.DEATHTOUCH.createInstance()); + addEffect.setTargetPointer(new FixedTargets(tokens, game)); + addEffect.apply(game, source); + } + } + return true; + } +} + +class GristThePlagueSwarmMinus6Effect extends OneShotEffect { + + GristThePlagueSwarmMinus6Effect() { + super(Outcome.PutCreatureInPlay); + staticText = "For each creature card in your graveyard, create a token that's a copy of it, " + + "except it's a 1/1 black and green Insect."; + } + + private GristThePlagueSwarmMinus6Effect(final GristThePlagueSwarmMinus6Effect effect) { + super(effect); + } + + @Override + public GristThePlagueSwarmMinus6Effect copy() { + return new GristThePlagueSwarmMinus6Effect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Set cards = controller.getGraveyard().getCards(StaticFilters.FILTER_CARD_CREATURE, game); + if (cards.isEmpty()) { + return false; + } + for (Card card : cards) { + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect( + null, null, false, 1, false, + false, null, 1, 1, false + ); + effect.setSavedPermanent(new PermanentCard(card, controller.getId(), game)); + effect.setOnlyColor(new ObjectColor("BG")); + effect.setOnlySubType(SubType.INSECT); + effect.apply(game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HauntOfTheDeadMarshes.java b/Mage.Sets/src/mage/cards/h/HauntOfTheDeadMarshes.java index f587b2cfd43..0d8337fffdd 100644 --- a/Mage.Sets/src/mage/cards/h/HauntOfTheDeadMarshes.java +++ b/Mage.Sets/src/mage/cards/h/HauntOfTheDeadMarshes.java @@ -1,23 +1,17 @@ package mage.cards.h; import mage.MageInt; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; import mage.abilities.effects.keyword.ScryEffect; -import mage.abilities.hint.ConditionHint; -import mage.abilities.hint.Hint; 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.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; import java.util.UUID; @@ -26,16 +20,6 @@ import java.util.UUID; */ public final class HauntOfTheDeadMarshes extends CardImpl { - private static final FilterPermanent filter - = new FilterControlledCreaturePermanent("you control a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); - private static final Hint hint = new ConditionHint(condition, "You control a legendary creature"); - public HauntOfTheDeadMarshes(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); @@ -50,8 +34,8 @@ public final class HauntOfTheDeadMarshes extends CardImpl { // {2}{B}: Return Haunt of the Dead Marshes from your graveyard to the battlefield tapped. Activate only if you control a legendary creature. this.addAbility(new ActivateIfConditionActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(true, false), - new ManaCostsImpl<>("{2}{B}"), condition - ).addHint(hint)); + new ManaCostsImpl<>("{2}{B}"), YouControlALegendaryCreatureCondition.instance + ).addHint(YouControlALegendaryCreatureCondition.getHint())); } private HauntOfTheDeadMarshes(final HauntOfTheDeadMarshes card) { diff --git a/Mage.Sets/src/mage/cards/h/HighPerfectMorcant.java b/Mage.Sets/src/mage/cards/h/HighPerfectMorcant.java new file mode 100644 index 00000000000..ce4a60cc452 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HighPerfectMorcant.java @@ -0,0 +1,92 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.ProliferateEffect; +import mage.abilities.effects.keyword.BlightControllerEffect; +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.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HighPerfectMorcant extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.ELF, "Elf"); + private static final FilterControlledPermanent filter2 + = new FilterControlledPermanent(SubType.ELF, "untapped Elves you control"); + + static { + filter2.add(TappedPredicate.UNTAPPED); + } + + public HighPerfectMorcant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.NOBLE); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Whenever High Perfect Morcant or another Elf you control enters, each opponent blights 1. + this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility( + new HighPerfectMorcantEffect(), filter, false, true + )); + + // Tap three untapped Elves you control: Proliferate. Activate only as a sorcery. + this.addAbility(new ActivateAsSorceryActivatedAbility( + new ProliferateEffect(), new TapTargetCost(3, filter2) + )); + } + + private HighPerfectMorcant(final HighPerfectMorcant card) { + super(card); + } + + @Override + public HighPerfectMorcant copy() { + return new HighPerfectMorcant(this); + } +} + +class HighPerfectMorcantEffect extends OneShotEffect { + + HighPerfectMorcantEffect() { + super(Outcome.Benefit); + staticText = "each opponent blights 1. (They each put a -1/-1 counter on a creature they control.)"; + } + + private HighPerfectMorcantEffect(final HighPerfectMorcantEffect effect) { + super(effect); + } + + @Override + public HighPerfectMorcantEffect copy() { + return new HighPerfectMorcantEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + BlightControllerEffect.doBlight(opponent, 1, game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HowlingChorus.java b/Mage.Sets/src/mage/cards/h/HowlingChorus.java deleted file mode 100644 index 5d0a033e27b..00000000000 --- a/Mage.Sets/src/mage/cards/h/HowlingChorus.java +++ /dev/null @@ -1,48 +0,0 @@ - -package mage.cards.h; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesWithLessPowerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.permanent.token.EldraziHorrorToken; - -/** - * - * @author LevelX2 - */ -public final class HowlingChorus extends CardImpl { - - public HowlingChorus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(5); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Creatures with power less than Howling Chorus's power can't block it. - this.addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesWithLessPowerEffect())); - - // Whenever Howling Chorus deals combat damage to a player, create a 3/2 colorless Eldrazi Horror creature token. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenEffect(new EldraziHorrorToken()), false)); - } - - private HowlingChorus(final HowlingChorus card) { - super(card); - } - - @Override - public HowlingChorus copy() { - return new HowlingChorus(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HowlpackOfEstwald.java b/Mage.Sets/src/mage/cards/h/HowlpackOfEstwald.java deleted file mode 100644 index 42f61342450..00000000000 --- a/Mage.Sets/src/mage/cards/h/HowlpackOfEstwald.java +++ /dev/null @@ -1,40 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class HowlpackOfEstwald extends CardImpl { - - public HowlpackOfEstwald(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.color.setGreen(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(4); - this.toughness = new MageInt(6); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Howlpack of Estwald. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private HowlpackOfEstwald(final HowlpackOfEstwald card) { - super(card); - } - - @Override - public HowlpackOfEstwald copy() { - return new HowlpackOfEstwald(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HumanTorch.java b/Mage.Sets/src/mage/cards/h/HumanTorch.java new file mode 100644 index 00000000000..27fef4bb874 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HumanTorch.java @@ -0,0 +1,140 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.events.DamagedBatchBySourceEvent; +import mage.game.events.GameEvent; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HumanTorch extends CardImpl { + + public HumanTorch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.HERO); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // At the beginning of combat on your turn, if you've cast a noncreature spell this turn, Human Torch gains flying, double strike, and haste until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility( + new GainAbilitySourceEffect( + FlyingAbility.getInstance(), Duration.EndOfTurn + ).setText("{this} gains flying") + ).withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance); + ability.addEffect(new GainAbilitySourceEffect( + DoubleStrikeAbility.getInstance(), Duration.EndOfTurn + ).setText(", double strike")); + ability.addEffect(new GainAbilitySourceEffect( + HasteAbility.getInstance(), Duration.EndOfTurn + ).setText(", and haste until end of turn.")); + this.addAbility(ability.addHint(CastNoncreatureSpellThisTurnCondition.getHint())); + + // Whenever Human Torch attacks, you may pay {R}{G}{W}{U}. If you do, until end of turn, whenever he deals combat damage to an opponent, he deals that much damage to each other opponent. + this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( + new CreateDelayedTriggeredAbilityEffect(new HumanTorchTriggeredAbility()) + .setText("until end of turn, whenever he deals combat damage to an opponent, " + + "he deals that much damage to each other opponent"), + new ManaCostsImpl<>("{R}{G}{W}{U}") + ))); + } + + private HumanTorch(final HumanTorch card) { + super(card); + } + + @Override + public HumanTorch copy() { + return new HumanTorch(this); + } +} + +class HumanTorchTriggeredAbility extends DelayedTriggeredAbility { + + HumanTorchTriggeredAbility() { + super(new HumanTorchEffect(), Duration.EndOfTurn, false, false); + setTriggerPhrase("Whenever {this} deals combat damage to an opponent, "); + } + + private HumanTorchTriggeredAbility(final HumanTorchTriggeredAbility ability) { + super(ability); + } + + @Override + public HumanTorchTriggeredAbility copy() { + return new HumanTorchTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_BATCH_BY_SOURCE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!event.getSourceId().equals(getSourceId()) + || !((DamagedBatchBySourceEvent) event).isCombatDamage() + || !game.getOpponents(getControllerId()).contains(event.getTargetId())) { + return false; + } + this.getEffects().setValue("playerId", event.getTargetId()); + this.getEffects().setValue("damage", event.getAmount()); + return true; + } +} + +class HumanTorchEffect extends OneShotEffect { + + HumanTorchEffect() { + super(Outcome.Benefit); + staticText = "he deals that much damage to each other opponent"; + } + + private HumanTorchEffect(final HumanTorchEffect effect) { + super(effect); + } + + @Override + public HumanTorchEffect copy() { + return new HumanTorchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID playerId = (UUID) getValue("playerId"); + int damage = (Integer) getValue("damage"); + if (damage < 1) { + return false; + } + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + if (!opponentId.equals(playerId)) { + Optional.ofNullable(opponentId) + .map(game::getPlayer) + .ifPresent(player -> player.damage(damage, source, game)); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HydaelynTheMothercrystal.java b/Mage.Sets/src/mage/cards/h/HydaelynTheMothercrystal.java deleted file mode 100644 index eee3edefdf4..00000000000 --- a/Mage.Sets/src/mage/cards/h/HydaelynTheMothercrystal.java +++ /dev/null @@ -1,89 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.IndestructibleAbility; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; -import mage.filter.StaticFilters; -import mage.game.Controllable; -import mage.game.Game; -import mage.target.TargetPermanent; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class HydaelynTheMothercrystal extends CardImpl { - - public HydaelynTheMothercrystal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GOD); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.nightCard = true; - this.color.setWhite(true); - - // Indestructible - this.addAbility(IndestructibleAbility.getInstance()); - - // Blessing of Light -- At the beginning of combat on your turn, put a +1/+1 counter on another target creature you control. Until your next turn, it gains indestructible. If that creature is legendary, draw a card. - Ability ability = new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); - ability.addEffect(new GainAbilityTargetEffect( - IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn - ).setText("Until your next turn, it gains indestructible")); - ability.addEffect(new HydaelynTheMothercrystalEffect()); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); - this.addAbility(ability.withFlavorWord("Blessing of Light")); - } - - private HydaelynTheMothercrystal(final HydaelynTheMothercrystal card) { - super(card); - } - - @Override - public HydaelynTheMothercrystal copy() { - return new HydaelynTheMothercrystal(this); - } -} - -class HydaelynTheMothercrystalEffect extends OneShotEffect { - - HydaelynTheMothercrystalEffect() { - super(Outcome.Benefit); - staticText = "If that creature is legendary, draw a card"; - } - - private HydaelynTheMothercrystalEffect(final HydaelynTheMothercrystalEffect effect) { - super(effect); - } - - @Override - public HydaelynTheMothercrystalEffect copy() { - return new HydaelynTheMothercrystalEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return Optional.ofNullable(getTargetPointer().getFirst(game, source)) - .map(game::getPermanent) - .filter(permanent -> permanent.isLegendary(game)) - .isPresent() - && Optional - .ofNullable(source) - .map(Controllable::getControllerId) - .map(game::getPlayer) - .filter(player -> player.drawCards(1, source, game) > 0) - .isPresent(); - } -} diff --git a/Mage.Sets/src/mage/cards/i/IncitedRabble.java b/Mage.Sets/src/mage/cards/i/IncitedRabble.java deleted file mode 100644 index 91003feeba6..00000000000 --- a/Mage.Sets/src/mage/cards/i/IncitedRabble.java +++ /dev/null @@ -1,48 +0,0 @@ - -package mage.cards.i; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.AttacksEachCombatStaticAbility; -import mage.abilities.common.SimpleActivatedAbility; -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.SubType; -import mage.constants.Duration; -import mage.constants.Zone; - -/** - * - * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) - */ -public final class IncitedRabble extends CardImpl { - - public IncitedRabble(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.HUMAN); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.color.setRed(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Incited Rabble attacks each combat if able. - this.addAbility(new AttacksEachCombatStaticAbility()); - - // {2}: Incited Rabble gets +1/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{2}"))); - } - - private IncitedRabble(final IncitedRabble card) { - super(card); - } - - @Override - public IncitedRabble copy() { - return new IncitedRabble(this); - } -} diff --git a/Mage.Sets/src/mage/cards/i/InvisibleWoman.java b/Mage.Sets/src/mage/cards/i/InvisibleWoman.java new file mode 100644 index 00000000000..a2939873956 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InvisibleWoman.java @@ -0,0 +1,63 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoWhenCostPaid; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.game.permanent.token.WallColorlessReachToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class InvisibleWoman extends CardImpl { + + public InvisibleWoman(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.HERO); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // At the beginning of combat on your turn, if you've cast a noncreature spell this turn, create a 0/3 colorless Wall creature token with defender and reach. + this.addAbility(new BeginningOfCombatTriggeredAbility(new CreateTokenEffect(new WallColorlessReachToken())) + .withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance) + .addHint(CastNoncreatureSpellThisTurnCondition.getHint())); + + // Whenever you attack, you may pay {R}{G}{W}{U}. When you do, target creature gets +1/+0 until end of turn for each creature you control and can't be blocked this turn. + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new BoostTargetEffect(CreaturesYouControlCount.SINGULAR, StaticValue.get(0)), false + ); + ability.addEffect(new CantBeBlockedTargetEffect().setText("and can't be blocked this turn")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(new AttacksWithCreaturesTriggeredAbility(new DoWhenCostPaid( + ability, new ManaCostsImpl<>("{R}{G}{W}{U}"), "Pay {R}{G}{W}{U}?" + ), 1)); + } + + private InvisibleWoman(final InvisibleWoman card) { + super(card); + } + + @Override + public InvisibleWoman copy() { + return new InvisibleWoman(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/Ironfang.java b/Mage.Sets/src/mage/cards/i/Ironfang.java deleted file mode 100644 index 500ad43411f..00000000000 --- a/Mage.Sets/src/mage/cards/i/Ironfang.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.i; - -import mage.MageInt; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.keyword.FirstStrikeAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class Ironfang extends CardImpl { - - public Ironfang(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.color.setRed(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(3); - this.toughness = new MageInt(1); - - this.addAbility(FirstStrikeAbility.getInstance()); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ironfang. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private Ironfang(final Ironfang card) { - super(card); - } - - @Override - public Ironfang copy() { - return new Ironfang(this); - } -} diff --git a/Mage.Sets/src/mage/cards/j/JadeSeedstones.java b/Mage.Sets/src/mage/cards/j/JadeSeedstones.java index 9fc5a8264fe..0d67cd34d26 100644 --- a/Mage.Sets/src/mage/cards/j/JadeSeedstones.java +++ b/Mage.Sets/src/mage/cards/j/JadeSeedstones.java @@ -8,6 +8,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.abilities.keyword.CraftAbility; +import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; @@ -66,9 +67,15 @@ enum JadeheartAttendantValue implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { + Card sourceCard = game.getCard(sourceAbility.getSourceId()); + if (sourceCard == null) { + return 0; + } ExileZone exileZone = game .getExile() - .getExileZone(CardUtil.getExileZoneId(game, sourceAbility, -2)); + .getExileZone(CardUtil.getExileZoneId(game, + sourceCard.getMainCard().getMainCard().getId(), + sourceCard.getMainCard().getZoneChangeCounter(game) - 1)); return exileZone != null ? exileZone .getCards(game) diff --git a/Mage.Sets/src/mage/cards/j/JaredCarthalionTrueHeir.java b/Mage.Sets/src/mage/cards/j/JaredCarthalionTrueHeir.java index f23761bd6e5..83c076a64c7 100644 --- a/Mage.Sets/src/mage/cards/j/JaredCarthalionTrueHeir.java +++ b/Mage.Sets/src/mage/cards/j/JaredCarthalionTrueHeir.java @@ -34,8 +34,7 @@ public final class JaredCarthalionTrueHeir extends CardImpl { this.toughness = new MageInt(3); // When Jared Carthalion, True Heir enters the battlefield, target opponent becomes the monarch. You can't become the monarch this turn. - Ability ability = new EntersBattlefieldTriggeredAbility(new BecomesMonarchTargetEffect() - .setText("target opponent becomes the monarch")); + Ability ability = new EntersBattlefieldTriggeredAbility(new BecomesMonarchTargetEffect()); ability.addEffect(new JaredCarthalionTrueHeirMonarchEffect()); ability.addTarget(new TargetOpponent()); ability.addHint(MonarchHint.instance); diff --git a/Mage.Sets/src/mage/cards/j/JurassicPark.java b/Mage.Sets/src/mage/cards/j/JurassicPark.java deleted file mode 100644 index 7024769e637..00000000000 --- a/Mage.Sets/src/mage/cards/j/JurassicPark.java +++ /dev/null @@ -1,107 +0,0 @@ -package mage.cards.j; - -import java.util.Objects; -import java.util.UUID; - -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.EscapeAbility; -import mage.abilities.mana.DynamicManaAbility; -import mage.constants.*; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.game.Game; -import mage.players.Player; - -/** - * - * @author jimga150 - */ -public final class JurassicPark extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledPermanent("Dinosaur you control"); - - static { - filter.add(SubType.DINOSAUR.getPredicate()); - } - - private static final Hint hint = new ValueHint( - "Number of Dinosaurs you control", new PermanentsOnBattlefieldCount(filter) - ); - - public JurassicPark(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - - // (Transforms from Welcome to ....) - // Each Dinosaur card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. - // Based on Underworld Breach - this.addAbility(new SimpleStaticAbility(new JurassicParkEffect())); - - // {T}: Add {G} for each Dinosaur you control. - // Based on Gaea's Cradle - DynamicManaAbility ability = new DynamicManaAbility( - Mana.GreenMana(1), - new PermanentsOnBattlefieldCount(filter) - ); - this.addAbility(ability.addHint(hint)); - } - - private JurassicPark(final JurassicPark card) { - super(card); - } - - @Override - public JurassicPark copy() { - return new JurassicPark(this); - } -} - -class JurassicParkEffect extends ContinuousEffectImpl { - - JurassicParkEffect() { - super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); - staticText = "Each Dinosaur card in your graveyard has escape. " + - "The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard."; - } - - private JurassicParkEffect(final JurassicParkEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - controller - .getGraveyard() - .getCards(game) - .stream() - .filter(Objects::nonNull) - .filter(card -> !card.getManaCost().getText().isEmpty()) // card must have a mana cost - .filter(card -> card.hasSubtype(SubType.DINOSAUR, game)) - .forEach(card -> { - Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3); - ability.setSourceId(card.getId()); - ability.setControllerId(card.getOwnerId()); - game.getState().addOtherAbility(card, ability); - }); - return true; - } - - @Override - public JurassicParkEffect copy() { - return new JurassicParkEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KirinTouchedOrochi.java b/Mage.Sets/src/mage/cards/k/KirinTouchedOrochi.java deleted file mode 100644 index 254d48fc2e5..00000000000 --- a/Mage.Sets/src/mage/cards/k/KirinTouchedOrochi.java +++ /dev/null @@ -1,137 +0,0 @@ -package mage.cards.k; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.Mode; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.delayed.ReflexiveTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.cards.Card; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.counters.CounterType; -import mage.filter.FilterCard; -import mage.filter.StaticFilters; -import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.game.permanent.token.SpiritToken; -import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; -import mage.target.common.TargetControlledCreaturePermanent; - -/** - * - * @author weirddan455 - */ -public final class KirinTouchedOrochi extends CardImpl { - - private static final FilterCard filter = new FilterCard("noncreature card from a graveyard"); - static { - filter.add(Predicates.not(CardType.CREATURE.getPredicate())); - } - - public KirinTouchedOrochi(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.SNAKE); - this.subtype.add(SubType.MONK); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever Kirin-Touched Orochi attacks, choose one — - // • Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token. - Ability ability = new AttacksTriggeredAbility(new KirinTouchedOrochiTokenEffect()); - ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_A_GRAVEYARD)); - - // • Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control. - Mode mode = new Mode(new KirinTouchedOrochiCounterEffect()); - mode.addTarget(new TargetCardInGraveyard(filter)); - ability.addMode(mode); - this.addAbility(ability); - } - - private KirinTouchedOrochi(final KirinTouchedOrochi card) { - super(card); - } - - @Override - public KirinTouchedOrochi copy() { - return new KirinTouchedOrochi(this); - } -} - -class KirinTouchedOrochiTokenEffect extends OneShotEffect { - - KirinTouchedOrochiTokenEffect() { - super(Outcome.Exile); - this.staticText = "Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token"; - } - - private KirinTouchedOrochiTokenEffect(final KirinTouchedOrochiTokenEffect effect) { - super(effect); - } - - @Override - public KirinTouchedOrochiTokenEffect copy() { - return new KirinTouchedOrochiTokenEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - UUID targetId = source.getFirstTarget(); - Card card = game.getCard(targetId); - if (controller == null || card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) { - return false; - } - if (!controller.moveCards(card, Zone.EXILED, source, game)) { - return false; - } - ReflexiveTriggeredAbility reflexiveTokenAbility = new ReflexiveTriggeredAbility(new CreateTokenEffect(new SpiritToken()), false); - game.fireReflexiveTriggeredAbility(reflexiveTokenAbility, source); - return true; - } -} - -class KirinTouchedOrochiCounterEffect extends OneShotEffect { - - KirinTouchedOrochiCounterEffect() { - super(Outcome.Exile); - this.staticText = "Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control"; - } - - private KirinTouchedOrochiCounterEffect(final KirinTouchedOrochiCounterEffect effect) { - super(effect); - } - - @Override - public KirinTouchedOrochiCounterEffect copy() { - return new KirinTouchedOrochiCounterEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - UUID targetId = source.getFirstTarget(); - Card card = game.getCard(targetId); - if (controller == null || card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) { - return false; - } - if (!controller.moveCards(card, Zone.EXILED, source, game)) { - return false; - } - ReflexiveTriggeredAbility reflexiveCounterAbility = new ReflexiveTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false); - reflexiveCounterAbility.addTarget(new TargetControlledCreaturePermanent()); - game.fireReflexiveTriggeredAbility(reflexiveCounterAbility, source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/k/KirolAttentiveFirstYear.java b/Mage.Sets/src/mage/cards/k/KirolAttentiveFirstYear.java new file mode 100644 index 00000000000..7d867994bc1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KirolAttentiveFirstYear.java @@ -0,0 +1,48 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.CopyTargetStackObjectEffect; +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.TargetStackObject; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KirolAttentiveFirstYear extends CardImpl { + + public KirolAttentiveFirstYear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R/W}{R/W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.VAMPIRE); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Tap two untapped creatures you control: Copy target triggered ability you control. You may choose new targets for the copy. Activate only once each turn. + Ability ability = new LimitedTimesPerTurnActivatedAbility( + new CopyTargetStackObjectEffect(), new TapTargetCost(2, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES) + ); + ability.addTarget(new TargetStackObject(StaticFilters.FILTER_CONTROLLED_TRIGGERED_ABILITY)); + this.addAbility(ability); + } + + private KirolAttentiveFirstYear(final KirolAttentiveFirstYear card) { + super(card); + } + + @Override + public KirolAttentiveFirstYear copy() { + return new KirolAttentiveFirstYear(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KrallenhordeKiller.java b/Mage.Sets/src/mage/cards/k/KrallenhordeKiller.java deleted file mode 100644 index 5c2fc9960cc..00000000000 --- a/Mage.Sets/src/mage/cards/k/KrallenhordeKiller.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.k; - -import mage.MageInt; -import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -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 mage.constants.Zone; - -import java.util.UUID; - -/** - * @author Loki - */ -public final class KrallenhordeKiller extends CardImpl { - - public KrallenhordeKiller(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.color.setGreen(true); - - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - this.nightCard = true; - - // {3}{G}: Krallenhorde Killer gets +4/+4 until end of turn. Activate this ability only once each turn. - this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(4, 4, Duration.EndOfTurn), new ManaCostsImpl<>("{3}{G}"))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Krallenhorde Killer. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private KrallenhordeKiller(final KrallenhordeKiller card) { - super(card); - } - - @Override - public KrallenhordeKiller copy() { - return new KrallenhordeKiller(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LocusOfEnlightenment.java b/Mage.Sets/src/mage/cards/l/LocusOfEnlightenment.java deleted file mode 100644 index 190c43c56fc..00000000000 --- a/Mage.Sets/src/mage/cards/l/LocusOfEnlightenment.java +++ /dev/null @@ -1,98 +0,0 @@ -package mage.cards.l; - -import mage.abilities.Ability; -import mage.abilities.ActivatedAbility; -import mage.abilities.common.ActivateAbilityTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.common.CopyStackObjectEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterStackObject; -import mage.filter.common.FilterActivatedOrTriggeredAbility; -import mage.filter.predicate.other.NotManaAbilityPredicate; -import mage.game.ExileZone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LocusOfEnlightenment extends CardImpl { - private static final FilterStackObject filter = new FilterActivatedOrTriggeredAbility("an ability that isn't a mana ability"); - - static { - filter.add(NotManaAbilityPredicate.instance); - } - public LocusOfEnlightenment(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - this.color.setBlue(true); - - // Locus of Enlightenment has each activated ability of the exiled cards used to craft it. You may activate each of those abilities only once each turn. - this.addAbility(new SimpleStaticAbility(new LocusOfEnlightenmentEffect())); - - // Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy. - this.addAbility(new ActivateAbilityTriggeredAbility(new CopyStackObjectEffect("it"), filter, SetTargetPointer.SPELL)); - } - - private LocusOfEnlightenment(final LocusOfEnlightenment card) { - super(card); - } - - @Override - public LocusOfEnlightenment copy() { - return new LocusOfEnlightenment(this); - } -} - -class LocusOfEnlightenmentEffect extends ContinuousEffectImpl { - - LocusOfEnlightenmentEffect() { - super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.Benefit); - staticText = "{this} has each activated ability of the exiled cards " + - "used to craft it. You may activate each of those abilities only once each turn"; - } - - private LocusOfEnlightenmentEffect(final LocusOfEnlightenmentEffect effect) { - super(effect); - } - - @Override - public LocusOfEnlightenmentEffect copy() { - return new LocusOfEnlightenmentEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = source.getSourcePermanentIfItStillExists(game); - if (permanent == null) { - return false; - } - ExileZone exileZone = game - .getExile() - .getExileZone(CardUtil.getExileZoneId( - game, permanent.getId(), permanent.getZoneChangeCounter(game) - 2 - )); - if (exileZone == null) { - return false; - } - for (Card card : exileZone.getCards(game)) { - for (Ability ability : card.getAbilities(game)) { - if (ability.isActivatedAbility()) { - ActivatedAbility copyAbility = (ActivatedAbility) ability.copy(); - copyAbility.setMaxActivationsPerTurn(1); - permanent.addAbility(copyAbility, source.getSourceId(), game, true); - } - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MagickedCard.java b/Mage.Sets/src/mage/cards/m/MagickedCard.java deleted file mode 100644 index 08ee1d907fb..00000000000 --- a/Mage.Sets/src/mage/cards/m/MagickedCard.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.keyword.CrewAbility; -import mage.abilities.keyword.FlyingAbility; -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 MagickedCard extends CardImpl { - - public MagickedCard(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.subtype.add(SubType.VEHICLE); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.nightCard = true; - this.color.setBlue(true); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Crew 1 - this.addAbility(new CrewAbility(1)); - } - - private MagickedCard(final MagickedCard card) { - super(card); - } - - @Override - public MagickedCard copy() { - return new MagickedCard(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MastercraftRaptor.java b/Mage.Sets/src/mage/cards/m/MastercraftRaptor.java deleted file mode 100644 index f24de42eba0..00000000000 --- a/Mage.Sets/src/mage/cards/m/MastercraftRaptor.java +++ /dev/null @@ -1,88 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.ExileZone; -import mage.game.Game; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class MastercraftRaptor extends CardImpl { - - public MastercraftRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.DINOSAUR); - this.power = new MageInt(0); - this.toughness = new MageInt(4); - this.nightCard = true; - this.color.setRed(true); - - // Mastercraft Raptor's power is equal to the total power of the exiled cards used to craft it. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, new SetBasePowerSourceEffect(MastercraftRaptorValue.instance) - .setText("{this}'s power is equal to the total power of the exiled cards used to craft it") - )); - } - - private MastercraftRaptor(final MastercraftRaptor card) { - super(card); - } - - @Override - public MastercraftRaptor copy() { - return new MastercraftRaptor(this); - } -} - -enum MastercraftRaptorValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - ExileZone exileZone = game - .getExile() - .getExileZone(CardUtil.getExileZoneId( - game, sourceAbility.getSourceId(), - game.getState().getZoneChangeCounter(sourceAbility.getSourceId()) - 2 - )); - if (exileZone == null) { - return 0; - } - return exileZone - .getCards(game) - .stream() - .map(MageObject::getPower) - .mapToInt(MageInt::getValue) - .sum(); - } - - @Override - public MastercraftRaptorValue copy() { - return this; - } - - @Override - public String getMessage() { - return ""; - } - - @Override - public String toString() { - return "1"; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MeatLockerDrownedDiner.java b/Mage.Sets/src/mage/cards/m/MeatLockerDrownedDiner.java new file mode 100644 index 00000000000..32bd8fcfc08 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MeatLockerDrownedDiner.java @@ -0,0 +1,46 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MeatLockerDrownedDiner extends RoomCard { + + public MeatLockerDrownedDiner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{U}", "{3}{U}{U}"); + + // Meat Locker + // When you unlock this door, tap up to one target creature and put two stun counters on it. + Ability ability = new UnlockThisDoorTriggeredAbility(new TapTargetEffect(), false, true); + ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance(2)) + .setText("and put two stun counters on it")); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.getLeftHalfCard().addAbility(ability); + + // Drowned Diner + // When you unlock this door, draw three cards, then discard a card. + this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility( + new DrawDiscardControllerEffect(3, 1), false, false + )); + } + + private MeatLockerDrownedDiner(final MeatLockerDrownedDiner card) { + super(card); + } + + @Override + public MeatLockerDrownedDiner copy() { + return new MeatLockerDrownedDiner(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MinasTirith.java b/Mage.Sets/src/mage/cards/m/MinasTirith.java index 6e580899c59..a284fc8d02e 100644 --- a/Mage.Sets/src/mage/cards/m/MinasTirith.java +++ b/Mage.Sets/src/mage/cards/m/MinasTirith.java @@ -4,7 +4,7 @@ import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.condition.Condition; -import mage.abilities.condition.common.YouControlPermanentCondition; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; @@ -16,8 +16,6 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SuperType; import mage.constants.WatcherScope; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.util.CardUtil; @@ -32,21 +30,14 @@ import java.util.UUID; */ public final class MinasTirith extends CardImpl { - private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter); - public MinasTirith(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add(SuperType.LEGENDARY); // Minas Tirith enters the battlefield tapped unless you control a legendary creature. - this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); + this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance) + .addHint(YouControlALegendaryCreatureCondition.getHint())); // {T}: Add {W}. this.addAbility(new WhiteManaAbility()); diff --git a/Mage.Sets/src/mage/cards/m/MinesOfMoria.java b/Mage.Sets/src/mage/cards/m/MinesOfMoria.java index 6738cdaceda..b940d83cd11 100644 --- a/Mage.Sets/src/mage/cards/m/MinesOfMoria.java +++ b/Mage.Sets/src/mage/cards/m/MinesOfMoria.java @@ -3,7 +3,7 @@ package mage.cards.m; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.common.YouControlPermanentCondition; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; import mage.abilities.costs.common.ExileFromGraveCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -13,8 +13,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.permanent.token.TreasureToken; import mage.target.common.TargetCardInYourGraveyard; @@ -25,21 +23,14 @@ import java.util.UUID; */ public final class MinesOfMoria extends CardImpl { - private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter); - public MinesOfMoria(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add(SuperType.LEGENDARY); // Mines of Moria enters the battlefield tapped unless you control a legendary creature. - this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); + this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance) + .addHint(YouControlALegendaryCreatureCondition.getHint())); // {T}: Add {R}. this.addAbility(new RedManaAbility()); diff --git a/Mage.Sets/src/mage/cards/m/MirrorRoomFracturedRealm.java b/Mage.Sets/src/mage/cards/m/MirrorRoomFracturedRealm.java new file mode 100644 index 00000000000..16582a29c0a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MirrorRoomFracturedRealm.java @@ -0,0 +1,89 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MirrorRoomFracturedRealm extends RoomCard { + + public MirrorRoomFracturedRealm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{U}", "{5}{U}{U}"); + + // Mirror Room + // When you unlock this door, create a token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types. + Ability ability = new UnlockThisDoorTriggeredAbility( + new CreateTokenCopyTargetEffect() + .withAdditionalSubType(SubType.REFLECTION) + .setText("create a token that's a copy of target creature you control, " + + "except it's a Reflection in addition to its other creature types"), + false, true + ); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.getLeftHalfCard().addAbility(ability); + + // Fractured Realm + // If a triggered ability of a permanent you control triggers, that ability triggers an additional time. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new FracturedRealmEffect())); + } + + private MirrorRoomFracturedRealm(final MirrorRoomFracturedRealm card) { + super(card); + } + + @Override + public MirrorRoomFracturedRealm copy() { + return new MirrorRoomFracturedRealm(this); + } +} + +class FracturedRealmEffect extends ReplacementEffectImpl { + + FracturedRealmEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "if a triggered ability of a permanent you control triggers, " + + "that ability triggers an additional time"; + } + + private FracturedRealmEffect(final FracturedRealmEffect effect) { + super(effect); + } + + @Override + public FracturedRealmEffect copy() { + return new FracturedRealmEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.NUMBER_OF_TRIGGERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + return permanent != null && permanent.isControlledBy(source.getControllerId()); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.overflowInc(event.getAmount(), 1)); + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MisterFantastic.java b/Mage.Sets/src/mage/cards/m/MisterFantastic.java new file mode 100644 index 00000000000..60178f8b45a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MisterFantastic.java @@ -0,0 +1,67 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CopyTargetStackObjectEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.ReachAbility; +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.constants.SuperType; +import mage.filter.StaticFilters; +import mage.target.TargetStackObject; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MisterFantastic extends CardImpl { + + public MisterFantastic(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCIENTIST); + this.subtype.add(SubType.HERO); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // At the beginning of combat on your turn, if you've cast a noncreature spell this turn, draw a card. + this.addAbility(new BeginningOfCombatTriggeredAbility(new DrawCardSourceControllerEffect(1)) + .withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance) + .addHint(CastNoncreatureSpellThisTurnCondition.getHint())); + + // {R}{G}{W}{U}, {T}: Copy target triggered ability you control twice. You may choose new targets for the copies. + Ability ability = new SimpleActivatedAbility(new CopyTargetStackObjectEffect() + .setText("copy target triggered ability you control twice"), new ManaCostsImpl<>("{R}{G}{W}{U}")); + ability.addCost(new TapSourceCost()); + ability.addEffect(new CopyTargetStackObjectEffect().setText("You may choose new targets for the copies.")); + ability.addTarget(new TargetStackObject(StaticFilters.FILTER_CONTROLLED_TRIGGERED_ABILITY)); + this.addAbility(ability); + } + + private MisterFantastic(final MisterFantastic card) { + super(card); + } + + @Override + public MisterFantastic copy() { + return new MisterFantastic(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MolderingGymWeightRoom.java b/Mage.Sets/src/mage/cards/m/MolderingGymWeightRoom.java new file mode 100644 index 00000000000..298ffeede31 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MolderingGymWeightRoom.java @@ -0,0 +1,45 @@ +package mage.cards.m; + +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.abilities.effects.keyword.ManifestDreadEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MolderingGymWeightRoom extends RoomCard { + + public MolderingGymWeightRoom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{G}", "{5}{G}"); + + // Moldering Gym + // When you unlock this door, search your library for a basic land card, put it onto the battlefield tapped, then shuffle. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility( + new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true + ), false, true + )); + + // Weight Room + // When you unlock this door, manifest dread, then put three +1/+1 counters on that creature. + this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility( + new ManifestDreadEffect(CounterType.P1P1.createInstance(3)), false, false + )); + } + + private MolderingGymWeightRoom(final MolderingGymWeightRoom card) { + super(card); + } + + @Override + public MolderingGymWeightRoom copy() { + return new MolderingGymWeightRoom(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MoonGirlAndDevilDinosaur.java b/Mage.Sets/src/mage/cards/m/MoonGirlAndDevilDinosaur.java new file mode 100644 index 00000000000..43fed2da365 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MoonGirlAndDevilDinosaur.java @@ -0,0 +1,60 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DrawNthCardTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.keyword.TrampleAbility; +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.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MoonGirlAndDevilDinosaur extends CardImpl { + + public MoonGirlAndDevilDinosaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.HERO); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever you draw your second card each turn, until end of turn, Moon Girl and Devil Dinosaur's base power and toughness become 6/6 and they gain trample. + Ability ability = new DrawNthCardTriggeredAbility( + new SetBasePowerToughnessSourceEffect(6, 6, Duration.EndOfTurn) + .setText("until end of turn, {this}'s base power and toughness become 6/6") + ); + ability.addEffect(new GainAbilitySourceEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn + ).setText("and they gain trample")); + this.addAbility(ability); + + // Whenever an artifact you control enters, draw a card. This ability triggers only once each turn. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT + ).setTriggersLimitEachTurn(1)); + } + + private MoonGirlAndDevilDinosaur(final MoonGirlAndDevilDinosaur card) { + super(card); + } + + @Override + public MoonGirlAndDevilDinosaur copy() { + return new MoonGirlAndDevilDinosaur(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java b/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java deleted file mode 100644 index 0d53062f18e..00000000000 --- a/Mage.Sets/src/mage/cards/m/MoonriseIntruder.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class MoonriseIntruder extends CardImpl { - - public MoonriseIntruder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setRed(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonrise Intruder. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private MoonriseIntruder(final MoonriseIntruder card) { - super(card); - } - - @Override - public MoonriseIntruder copy() { - return new MoonriseIntruder(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MoonscarredWerewolf.java b/Mage.Sets/src/mage/cards/m/MoonscarredWerewolf.java deleted file mode 100644 index 7bc6a02be36..00000000000 --- a/Mage.Sets/src/mage/cards/m/MoonscarredWerewolf.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.Mana; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.keyword.VigilanceAbility; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; - -import java.util.UUID; - -/** - * @author North - */ -public final class MoonscarredWerewolf extends CardImpl { - - public MoonscarredWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - - this.color.setGreen(true); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.addAbility(VigilanceAbility.getInstance()); - - // {tap}: Add {G}{G}. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(2), new TapSourceCost())); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonscarred Werewolf. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private MoonscarredWerewolf(final MoonscarredWerewolf card) { - super(card); - } - - @Override - public MoonscarredWerewolf copy() { - return new MoonscarredWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MoraugFuryOfAkoum.java b/Mage.Sets/src/mage/cards/m/MoraugFuryOfAkoum.java index addd453c276..1eae1d6cade 100644 --- a/Mage.Sets/src/mage/cards/m/MoraugFuryOfAkoum.java +++ b/Mage.Sets/src/mage/cards/m/MoraugFuryOfAkoum.java @@ -40,7 +40,7 @@ public final class MoraugFuryOfAkoum extends CardImpl { this.addAbility(new SimpleStaticAbility(new MoraugFuryOfAkoumBoostEffect())); // Landfall — Whenever a land you control enters, if it's your main phase, there's an additional combat phase after this phase. At the beginning of that combat, untap all creatures you control. - this.addAbility(new LandfallAbility(new MoraugFuryOfAkoumCombatEffect()).withInterveningIf(IsMainPhaseCondition.YOUR), new MoraugFuryOfAkoumWatcher()); + this.addAbility(new LandfallAbility(new MoraugFuryOfAkoumCombatEffect()).withInterveningIf(IsMainPhaseCondition.YOURS), new MoraugFuryOfAkoumWatcher()); } private MoraugFuryOfAkoum(final MoraugFuryOfAkoum card) { diff --git a/Mage.Sets/src/mage/cards/m/MycoidMaze.java b/Mage.Sets/src/mage/cards/m/MycoidMaze.java deleted file mode 100644 index 04fa111f543..00000000000 --- a/Mage.Sets/src/mage/cards/m/MycoidMaze.java +++ /dev/null @@ -1,51 +0,0 @@ -package mage.cards.m; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.mana.GreenManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.PutCards; -import mage.constants.SubType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author xenohedron - */ -public final class MycoidMaze extends CardImpl { - - public MycoidMaze(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.subtype.add(SubType.CAVE); - - // (Transforms from Twists and Turns.) - this.nightCard = true; - - // {T}: Add {G}. - this.addAbility(new GreenManaAbility()); - - // {3}{G}, {T}: Look at the top four cards of your library. You may reveal a creature card from among them and put that card into your hand. Put the rest on the bottom of your library in a random order. - Ability ability = new SimpleActivatedAbility(new LookLibraryAndPickControllerEffect( - 4, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM - ), new ManaCostsImpl<>("{3}{G}")); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - - } - - private MycoidMaze(final MycoidMaze card) { - super(card); - } - - @Override - public MycoidMaze copy() { - return new MycoidMaze(this); - } -} diff --git a/Mage.Sets/src/mage/cards/n/NamelessConqueror.java b/Mage.Sets/src/mage/cards/n/NamelessConqueror.java deleted file mode 100644 index 2151a7b5730..00000000000 --- a/Mage.Sets/src/mage/cards/n/NamelessConqueror.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.n; - -import mage.MageInt; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TrampleAbility; -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 NamelessConqueror extends CardImpl { - - public NamelessConqueror(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SAMURAI); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setRed(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - } - - private NamelessConqueror(final NamelessConqueror card) { - super(card); - } - - @Override - public NamelessConqueror copy() { - return new NamelessConqueror(this); - } -} diff --git a/Mage.Sets/src/mage/cards/n/NamorTheSubMariner.java b/Mage.Sets/src/mage/cards/n/NamorTheSubMariner.java new file mode 100644 index 00000000000..f1dfef46e5a --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NamorTheSubMariner.java @@ -0,0 +1,116 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterSpell; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.token.MerfolkToken; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class NamorTheSubMariner extends CardImpl { + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.MERFOLK)); + private static final Hint hint = new ValueHint("Merfolk you control", xValue); + private static final FilterSpell filter = new FilterSpell("a noncreature spell with one or more blue mana symbols in its mana cost"); + + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + filter.add(NamorTheSubMarinerPredicate.instance); + } + + public NamorTheSubMariner(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.MUTANT); + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.VILLAIN); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Namor's power is equal to the number of Merfolk you control. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerSourceEffect(xValue))); + + // Whenever you cast a noncreature spell with one or more blue mana symbols in its mana cost, create that many 1/1 blue Merfolk creature tokens. + this.addAbility(new SpellCastControllerTriggeredAbility( + new CreateTokenEffect(new MerfolkToken(), NamorTheSubMarinerValue.instance), filter, false + )); + } + + private NamorTheSubMariner(final NamorTheSubMariner card) { + super(card); + } + + @Override + public NamorTheSubMariner copy() { + return new NamorTheSubMariner(this); + } +} + +enum NamorTheSubMarinerPredicate implements Predicate { + instance; + + @Override + public boolean apply(StackObject input, Game game) { + return input + .getManaCost() + .stream() + .anyMatch(manaCost -> manaCost.containsColor(ColoredManaSymbol.U)); + } +} + +enum NamorTheSubMarinerValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Spell spell = (Spell) effect.getValue("spellCast"); + return spell != null + ? spell + .getManaCost() + .stream() + .mapToInt(manaCost -> manaCost.containsColor(ColoredManaSymbol.U) ? 1 : 0) + .sum() + : 0; + } + + @Override + public NamorTheSubMarinerValue copy() { + return this; + } + + @Override + public String getMessage() { + return "that many"; + } + + @Override + public String toString() { + return "1"; + } +} diff --git a/Mage.Sets/src/mage/cards/n/NoctisHeirApparent.java b/Mage.Sets/src/mage/cards/n/NoctisHeirApparent.java new file mode 100644 index 00000000000..086d41519a3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NoctisHeirApparent.java @@ -0,0 +1,167 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.IsPhaseCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachTargetToTargetEffect; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class NoctisHeirApparent extends CardImpl { + + private static final Condition condition = new IsPhaseCondition(TurnPhase.COMBAT); + + public NoctisHeirApparent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.NOBLE); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Whenever a creature you control enters during combat, you may attach target Equipment you control to target creature you control. + Ability ability = new EntersBattlefieldAllTriggeredAbility( + new AttachTargetToTargetEffect(), StaticFilters.FILTER_CONTROLLED_CREATURE, true + ).withTriggerCondition(condition); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_EQUIPMENT)); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + // Warp-Strike -- {3}: Exile Noctis. Return it to the battlefield under its owner's control tapped and attacking at the beginning of that player's next declare attackers step. It can't be blocked that combat. + this.addAbility(new SimpleActivatedAbility(new NoctisHeirApparentExileEffect(), new GenericManaCost(3)).withFlavorWord("Warp-Strike")); + } + + private NoctisHeirApparent(final NoctisHeirApparent card) { + super(card); + } + + @Override + public NoctisHeirApparent copy() { + return new NoctisHeirApparent(this); + } +} + +class NoctisHeirApparentExileEffect extends OneShotEffect { + + NoctisHeirApparentExileEffect() { + super(Outcome.Benefit); + staticText = "Exile {this}. Return it to the battlefield under its owner's control tapped and attacking " + + "at the beginning of that player's next declare attackers step. It can't be blocked that combat."; + } + + private NoctisHeirApparentExileEffect(final NoctisHeirApparentExileEffect effect) { + super(effect); + } + + @Override + public NoctisHeirApparentExileEffect copy() { + return new NoctisHeirApparentExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (player == null || permanent == null) { + return false; + } + player.moveCards(permanent, Zone.EXILED, source, game); + game.addDelayedTriggeredAbility(new NoctisHeirApparentTriggeredAbility(permanent, game), source); + return true; + } +} + +class NoctisHeirApparentTriggeredAbility extends DelayedTriggeredAbility { + + private final UUID playerId; + + NoctisHeirApparentTriggeredAbility(Permanent permanent, Game game) { + super(new NoctisHeirApparentReturnEffect(permanent, game), Duration.Custom, true, false); + this.playerId = permanent.getOwnerId(); + } + + private NoctisHeirApparentTriggeredAbility(final NoctisHeirApparentTriggeredAbility ability) { + super(ability); + this.playerId = ability.playerId; + } + + @Override + public NoctisHeirApparentTriggeredAbility copy() { + return new NoctisHeirApparentTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game.isActivePlayer(playerId); + } + + @Override + public String getRule() { + return "Return it to the battlefield under its owner's control tapped and attacking at " + + "the beginning of that player's next declare attackers step. It can't be blocked that combat."; + } +} + +class NoctisHeirApparentReturnEffect extends OneShotEffect { + + NoctisHeirApparentReturnEffect(Permanent permanent, Game game) { + super(Outcome.Benefit); + this.setTargetPointer(new FixedTarget(permanent.getId(), game)); + } + + private NoctisHeirApparentReturnEffect(final NoctisHeirApparentReturnEffect effect) { + super(effect); + } + + @Override + public NoctisHeirApparentReturnEffect copy() { + return new NoctisHeirApparentReturnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (player == null || card == null) { + return false; + } + player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); + Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); + if (permanent == null) { + return true; + } + game.getCombat().addAttackingCreature(permanent.getId(), game); + game.addEffect(new CantBeBlockedTargetEffect(Duration.EndOfCombat) + .setTargetPointer(new FixedTarget(permanent, game)), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/o/OKagachiMadeManifest.java b/Mage.Sets/src/mage/cards/o/OKagachiMadeManifest.java deleted file mode 100644 index d20338dc62a..00000000000 --- a/Mage.Sets/src/mage/cards/o/OKagachiMadeManifest.java +++ /dev/null @@ -1,120 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.InfoEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInGraveyard; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class OKagachiMadeManifest extends CardImpl { - - public OKagachiMadeManifest(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.DRAGON); - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.nightCard = true; - - // O-Kagachi Made Manifest is all colors. - this.color.setWhite(true); - this.color.setBlue(true); - this.color.setBlack(true); - this.color.setRed(true); - this.color.setGreen(true); - this.addAbility(new SimpleStaticAbility(new InfoEffect("{this} is all colors"))); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Whenever O-Kagachi Made Manifest attacks, defending player chooses a nonland card in your graveyard. Return that card to your hand. O-Kagachi Made Manifest gets +X/+0 until end of turn, where X is the mana value of that card. - this.addAbility(new AttacksTriggeredAbility( - new OKagachiMadeManifestEffect(), false, null, SetTargetPointer.PLAYER - )); - } - - private OKagachiMadeManifest(final OKagachiMadeManifest card) { - super(card); - } - - @Override - public OKagachiMadeManifest copy() { - return new OKagachiMadeManifest(this); - } -} - -class OKagachiMadeManifestEffect extends OneShotEffect { - - OKagachiMadeManifestEffect() { - super(Outcome.Benefit); - staticText = "defending player chooses a nonland card in your graveyard. Return that card to your hand. " + - "{this} gets +X/+0 until end of turn, where X is the mana value of that card"; - } - - private OKagachiMadeManifestEffect(final OKagachiMadeManifestEffect effect) { - super(effect); - } - - @Override - public OKagachiMadeManifestEffect copy() { - return new OKagachiMadeManifestEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); - if (controller == null || player == null) { - return false; - } - Card card; - switch (controller.getGraveyard().count(StaticFilters.FILTER_CARD_A_NON_LAND, game)) { - case 0: - return false; - case 1: - card = controller - .getGraveyard() - .getCards(StaticFilters.FILTER_CARD_A_NON_LAND, game) - .stream() - .findFirst() - .orElse(null); - break; - default: - TargetCard target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_A_NON_LAND); - target.withNotTarget(true); - player.choose(Outcome.ReturnToHand, controller.getGraveyard(), target, source, game); - card = game.getCard(target.getFirstTarget()); - } - if (card == null) { - return false; - } - int manaValue = card.getManaValue(); - player.moveCards(card, Zone.HAND, source, game); - if (manaValue > 0) { - game.addEffect(new BoostSourceEffect(manaValue, 0, Duration.EndOfTurn), source); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/o/OneOfThePack.java b/Mage.Sets/src/mage/cards/o/OneOfThePack.java deleted file mode 100644 index 40ce2562a2d..00000000000 --- a/Mage.Sets/src/mage/cards/o/OneOfThePack.java +++ /dev/null @@ -1,38 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class OneOfThePack extends CardImpl { - - public OneOfThePack(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(5); - this.toughness = new MageInt(6); - this.color.setGreen(true); - - this.nightCard = true; - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform One of the Pack. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private OneOfThePack(final OneOfThePack card) { - super(card); - } - - @Override - public OneOfThePack copy() { - return new OneOfThePack(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OreRichStalactite.java b/Mage.Sets/src/mage/cards/o/OreRichStalactite.java index e0b5ea18204..7feb3ac803e 100644 --- a/Mage.Sets/src/mage/cards/o/OreRichStalactite.java +++ b/Mage.Sets/src/mage/cards/o/OreRichStalactite.java @@ -1,18 +1,32 @@ package mage.cards.o; -import java.util.UUID; - +import mage.MageObject; import mage.Mana; import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.CraftAbility; import mage.abilities.mana.ConditionalColoredManaAbility; import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; -import mage.cards.c.CosmiumCatalyst; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInExile; +import mage.util.CardUtil; + +import java.util.UUID; /** * Ore-Rich Stalactite {1}{R} @@ -22,20 +36,30 @@ import mage.filter.predicate.mageobject.ColorPredicate; * * @author DominionSpy */ -public class OreRichStalactite extends CardImpl { +public class OreRichStalactite extends TransformingDoubleFacedCard { public OreRichStalactite(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{R}"); - this.secondSideCardClazz = CosmiumCatalyst.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{R}", + "Cosmium Catalyst", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "R" + ); + // Ore-Rich Stalactite // {T}: Add {R}. Spend this mana only to cast an instant or sorcery spell. - this.addAbility(new ConditionalColoredManaAbility(Mana.RedMana(1), new InstantOrSorcerySpellManaBuilder())); + this.getLeftHalfCard().addAbility(new ConditionalColoredManaAbility(Mana.RedMana(1), new InstantOrSorcerySpellManaBuilder())); // Craft with four or more red instant and/or sorcery cards {3}{R}{R} - this.addAbility(new CraftAbility("{3}{R}{R}", "four or more red instant and/or sorcery cards", + this.getLeftHalfCard().addAbility(new CraftAbility("{3}{R}{R}", "four or more red instant and/or sorcery cards", "red instant and/or sorcery cards in your graveyard", 4, Integer.MAX_VALUE, new ColorPredicate(ObjectColor.RED), Predicates.or(CardType.INSTANT.getPredicate(), CardType.SORCERY.getPredicate()))); + + // Cosmium Catalyst + // {1}{R}, {T}: Choose an exiled card used to craft Cosmium Catalyst at random. You may cast that card without paying its mana cost. + Ability ability = new SimpleActivatedAbility(new CosmiumCatalystEffect(), new ManaCostsImpl<>("{1}{R}")); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability); } private OreRichStalactite(final OreRichStalactite card) { @@ -43,7 +67,53 @@ public class OreRichStalactite extends CardImpl { } @Override - public OreRichStalactite copy() { + public OreRichStalactite copy() { return new OreRichStalactite(this); } } + +class CosmiumCatalystEffect extends OneShotEffect { + + CosmiumCatalystEffect() { + super(Outcome.PlayForFree); + this.staticText = "Choose an exiled card used to craft {this} at random." + + " You may cast that card without paying its mana cost."; + } + + private CosmiumCatalystEffect(CosmiumCatalystEffect effect) { + super(effect); + } + + @Override + public CosmiumCatalystEffect copy() { + return new CosmiumCatalystEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject == null) { + return false; + } + + Target target = new TargetCardInExile(StaticFilters.FILTER_CARD, + CardUtil.getExileZoneId(game, source.getSourceId(), + game.getState().getZoneChangeCounter(source.getSourceId()) - 2 + )); + target.withNotTarget(true); + target.setRandom(true); + if (!target.canChoose(controller.getId(), source, game)) { + return true; + } + target.chooseTarget(outcome, controller.getId(), source, game); + Card chosenCard = game.getCard(target.getFirstTarget()); + if (chosenCard != null) { + CardUtil.castSpellWithAttributesForFree(controller, source, game, chosenCard); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/o/OrmendahlProfanePrince.java b/Mage.Sets/src/mage/cards/o/OrmendahlProfanePrince.java deleted file mode 100644 index 1df4cf81eeb..00000000000 --- a/Mage.Sets/src/mage/cards/o/OrmendahlProfanePrince.java +++ /dev/null @@ -1,51 +0,0 @@ - -package mage.cards.o; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.IndestructibleAbility; -import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; - -/** - * - * @author fireshoes - */ -public final class OrmendahlProfanePrince extends CardImpl { - - public OrmendahlProfanePrince(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.DEMON); - this.power = new MageInt(9); - this.toughness = new MageInt(7); - this.color.setBlack(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - // Indestructible - this.addAbility(IndestructibleAbility.getInstance()); - // Haste - this.addAbility(HasteAbility.getInstance()); - } - - private OrmendahlProfanePrince(final OrmendahlProfanePrince card) { - super(card); - } - - @Override - public OrmendahlProfanePrince copy() { - return new OrmendahlProfanePrince(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/PaintersStudioDefacedGallery.java b/Mage.Sets/src/mage/cards/p/PaintersStudioDefacedGallery.java new file mode 100644 index 00000000000..b85b90b3296 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PaintersStudioDefacedGallery.java @@ -0,0 +1,43 @@ +package mage.cards.p; + +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.Duration; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PaintersStudioDefacedGallery extends RoomCard { + + public PaintersStudioDefacedGallery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{R}", "{1}{R}"); + + // Painter's Studio + // When you unlock this door, exile the top two cards of your library. You may play them until the end of your next turn. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility( + new ExileTopXMayPlayUntilEffect(2, Duration.UntilEndOfYourNextTurn), false, true + )); + + // Defaced Gallery + // Whenever you attack, attacking creatures you control get +1/+0 until end of turn. + this.getRightHalfCard().addAbility(new AttacksWithCreaturesTriggeredAbility(new BoostControlledEffect( + 1, 0, Duration.EndOfTurn, StaticFilters.FILTER_ATTACKING_CREATURES + ), 1)); + } + + private PaintersStudioDefacedGallery(final PaintersStudioDefacedGallery card) { + super(card); + } + + @Override + public PaintersStudioDefacedGallery copy() { + return new PaintersStudioDefacedGallery(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PerfectIntimidation.java b/Mage.Sets/src/mage/cards/p/PerfectIntimidation.java new file mode 100644 index 00000000000..2cfed3416bb --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PerfectIntimidation.java @@ -0,0 +1,89 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.RemoveAllCountersPermanentTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PerfectIntimidation extends CardImpl { + + public PerfectIntimidation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); + + // Choose one or both -- + // * Target opponent exiles two cards from their hand. + this.getSpellAbility().addEffect(new PerfectIntimidationEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + + // * Remove all counters from target creature. + this.getSpellAbility().addMode(new Mode(new RemoveAllCountersPermanentTargetEffect()) + .addTarget(new TargetCreaturePermanent())); + } + + private PerfectIntimidation(final PerfectIntimidation card) { + super(card); + } + + @Override + public PerfectIntimidation copy() { + return new PerfectIntimidation(this); + } +} + +class PerfectIntimidationEffect extends OneShotEffect { + + PerfectIntimidationEffect() { + super(Outcome.Benefit); + staticText = "target opponent exiles two cards from their hand"; + } + + private PerfectIntimidationEffect(final PerfectIntimidationEffect effect) { + super(effect); + } + + @Override + public PerfectIntimidationEffect copy() { + return new PerfectIntimidationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(); + switch (player.getHand().size()) { + case 0: + return false; + case 1: + case 2: + cards.addAll(player.getHand()); + break; + default: + TargetCard target = new TargetCardInHand(2, StaticFilters.FILTER_CARD_CARDS); + player.choose(Outcome.Discard, player.getHand(), target, source, game); + cards.addAll(target.getTargets()); + } + return player.moveCards(cards, Zone.EXILED, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PriceOfFame.java b/Mage.Sets/src/mage/cards/p/PriceOfFame.java index a05d3bfaebe..ec5d1f0683b 100644 --- a/Mage.Sets/src/mage/cards/p/PriceOfFame.java +++ b/Mage.Sets/src/mage/cards/p/PriceOfFame.java @@ -9,10 +9,8 @@ import mage.abilities.effects.keyword.SurveilEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SuperType; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -22,14 +20,7 @@ import java.util.UUID; */ public final class PriceOfFame extends CardImpl { - private static final FilterPermanent filter - = new FilterCreaturePermanent("a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final Condition condition = new SourceTargetsPermanentCondition(filter); + private static final Condition condition = new SourceTargetsPermanentCondition(StaticFilters.FILTER_CREATURE_LEGENDARY); public PriceOfFame(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B}"); diff --git a/Mage.Sets/src/mage/cards/q/QuicksilverBrashBlur.java b/Mage.Sets/src/mage/cards/q/QuicksilverBrashBlur.java new file mode 100644 index 00000000000..3fda66891f4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/q/QuicksilverBrashBlur.java @@ -0,0 +1,58 @@ +package mage.cards.q; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.LeylineAbility; +import mage.abilities.keyword.PowerUpAbility; +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 QuicksilverBrashBlur extends CardImpl { + + public QuicksilverBrashBlur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.MUTANT); + this.subtype.add(SubType.HERO); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // If Quicksilver, Brash Blur is in your opening hand, you may begin the game with him on the battlefield. + this.addAbility(LeylineAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Power-up -- {4}{R}: Put a +1/+1 counter and a double strike counter on Quicksilver. + Ability ability = new PowerUpAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()) + .setText("put a +1/+1 counter"), + new ManaCostsImpl<>("{4}{R}") + ); + ability.addEffect(new AddCountersSourceEffect(CounterType.DOUBLE_STRIKE.createInstance()) + .setText("and a double strike counter on {this}")); + this.addAbility(ability); + } + + private QuicksilverBrashBlur(final QuicksilverBrashBlur card) { + super(card); + } + + @Override + public QuicksilverBrashBlur copy() { + return new QuicksilverBrashBlur(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RalLeylineProdigy.java b/Mage.Sets/src/mage/cards/r/RalLeylineProdigy.java deleted file mode 100644 index 10e3fac4eb7..00000000000 --- a/Mage.Sets/src/mage/cards/r/RalLeylineProdigy.java +++ /dev/null @@ -1,206 +0,0 @@ -package mage.cards.r; - -import mage.MageIdentifier; -import mage.MageObject; -import mage.MageObjectReference; -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.dynamicvalue.common.InstantAndSorceryCastThisTurn; -import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DamageMultiEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.hint.ConditionHint; -import mage.abilities.hint.Hint; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; -import mage.filter.FilterCard; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterInstantOrSorceryCard; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetAnyTargetAmount; -import mage.util.CardUtil; - -import java.util.Set; -import java.util.UUID; - -/** - * @author Susucr - */ -public final class RalLeylineProdigy extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("blue permanent other than {this}"); - private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, true); - private static final Hint hint = new ConditionHint(condition, "you control another blue permanent"); - - static { - filter.add(new ColorPredicate(ObjectColor.BLUE)); - filter.add(AnotherPredicate.instance); - } - - public RalLeylineProdigy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.RAL); - this.setStartingLoyalty(2); - - this.color.setBlue(true); - this.color.setRed(true); - this.nightCard = true; - - // Ral, Leyline Prodigy enters the battlefield with an additional loyalty counter on him for each instant and sorcery spell you've cast this turn. - this.addAbility(new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(), InstantAndSorceryCastThisTurn.YOU, - false) - .setText("with an additional loyalty counter on him for each instant and sorcery spell you've cast this turn")) - .addHint(InstantAndSorceryCastThisTurn.YOU.getHint()) - ); - - // +1: Until your next turn, instant and sorcery spells you cast cost {1} less to cast. - this.addAbility(new LoyaltyAbility(new RalLeylineProdigyCostReductionEffect(), 1)); - - // -2: Ral deals 2 damage divided as you choose among one or two targets. Draw a card if you control a blue permanent other than Ral. - Ability ability = new LoyaltyAbility(new DamageMultiEffect(), -2); - ability.addTarget(new TargetAnyTargetAmount(2)); - ability.addEffect(new ConditionalOneShotEffect( - new DrawCardSourceControllerEffect(1), - condition, "Draw a card if you control a blue permanent other than {this}" - )); - ability.addHint(hint); - this.addAbility(ability); - - // -8: Exile the top eight cards of your library. You may cast instant and sorcery spells from among them this turn without paying their mana costs. - this.addAbility(new LoyaltyAbility(new RalLeylineProdigyMinusEightEffect(), -8) - .setIdentifier(MageIdentifier.WithoutPayingManaCostAlternateCast)); - } - - private RalLeylineProdigy(final RalLeylineProdigy card) { - super(card); - } - - @Override - public RalLeylineProdigy copy() { - return new RalLeylineProdigy(this); - } -} - -class RalLeylineProdigyCostReductionEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterInstantOrSorceryCard("instant and sorcery spells"); - - RalLeylineProdigyCostReductionEffect() { - super(Outcome.Benefit); - this.staticText = "Until your next turn, instant and sorcery spells you cast cost {1} less to cast"; - } - - private RalLeylineProdigyCostReductionEffect(final RalLeylineProdigyCostReductionEffect effect) { - super(effect); - } - - @Override - public RalLeylineProdigyCostReductionEffect copy() { - return new RalLeylineProdigyCostReductionEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - SpellsCostReductionControllerEffect effect = new SpellsCostReductionControllerEffect(filter, 1); - effect.setDuration(Duration.UntilYourNextTurn); - game.addEffect(effect, source); - return true; - } -} - -class RalLeylineProdigyMinusEightEffect extends OneShotEffect { - - RalLeylineProdigyMinusEightEffect() { - super(Outcome.Benefit); - staticText = "Exile the top eight cards of your library. " - + "You may cast instant and sorcery spells from among them this turn without paying their mana costs"; - } - - private RalLeylineProdigyMinusEightEffect(final RalLeylineProdigyMinusEightEffect effect) { - super(effect); - } - - @Override - public RalLeylineProdigyMinusEightEffect copy() { - return new RalLeylineProdigyMinusEightEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (player == null || sourceObject == null) { - return false; - } - Set cards = player.getLibrary().getTopCards(game, 8); - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getStackMomentSourceZCC()); - player.moveCardsToExile(cards, source, game, true, exileId, sourceObject.getIdName()); - for (Card card : cards) { - if (game.getState().getZone(card.getId()) == Zone.EXILED) { - game.addEffect(new RalLeylineProdigyCastEffect(new MageObjectReference(card, game)), source); - } - } - return true; - } - -} - -class RalLeylineProdigyCastEffect extends AsThoughEffectImpl { - - private final MageObjectReference mor; - - public RalLeylineProdigyCastEffect(MageObjectReference mor) { - super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - this.mor = mor; - } - - private RalLeylineProdigyCastEffect(final RalLeylineProdigyCastEffect effect) { - super(effect); - this.mor = effect.mor; - } - - @Override - public RalLeylineProdigyCastEffect copy() { - return new RalLeylineProdigyCastEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (mor.getCard(game) == null) { - discard(); - return false; - } - Card theCard = game.getCard(objectId); - if (theCard == null || !theCard.isInstantOrSorcery(game)) { - return false; - } - UUID mainId = theCard.getMainCard().getId(); // for split cards/MDFC/Adventure cards - if (!source.isControlledBy(affectedControllerId) || !mor.refersTo(mainId, game)) { - return false; - } - allowCardToPlayWithoutMana(mainId, source, affectedControllerId, MageIdentifier.WithoutPayingManaCostAlternateCast, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RalMonsoonMage.java b/Mage.Sets/src/mage/cards/r/RalMonsoonMage.java index c579098b09c..88f51bb66ce 100644 --- a/Mage.Sets/src/mage/cards/r/RalMonsoonMage.java +++ b/Mage.Sets/src/mage/cards/r/RalMonsoonMage.java @@ -1,53 +1,107 @@ package mage.cards.r; -import mage.MageInt; +import mage.MageIdentifier; +import mage.MageObject; +import mage.MageObjectReference; +import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.dynamicvalue.common.InstantAndSorceryCastThisTurn; -import mage.constants.Pronoun; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.InstantAndSorceryCastThisTurn; +import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageControllerEffect; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.counters.CounterType; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterInstantOrSorceryCard; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; +import mage.target.common.TargetAnyTargetAmount; +import mage.util.CardUtil; +import java.util.Set; import java.util.UUID; /** * @author Susucr */ -public final class RalMonsoonMage extends CardImpl { +public final class RalMonsoonMage extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterInstantOrSorceryCard("Instant and sorcery spells"); + private static final FilterPermanent filterBlue = new FilterPermanent("blue permanent other than {this}"); + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filterBlue, true); + private static final Hint hint = new ConditionHint(condition, "you control another blue permanent"); + + static { + filterBlue.add(new ColorPredicate(ObjectColor.BLUE)); + filterBlue.add(AnotherPredicate.instance); + } public RalMonsoonMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{1}{R}", + "Ral, Leyline Prodigy", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.RAL}, "UR" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - - this.secondSideCardClazz = RalLeylineProdigy.class; + // Ral, Monsoon Mage + this.getLeftHalfCard().setPT(1, 3); // Instant and sorcery spells you cast cost {1} less to cast. - this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1))); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1))); // Whenever you cast an instant or sorcery spell during your turn, flip a coin. If you lose the flip, Ral, Monsoon Mage deals 1 damage to you. If you win the flip, you may exile Ral. If you do, return him to the battlefield transformed under his owner control. - this.addAbility(new TransformAbility()); - this.addAbility(new RalMonsoonMageTriggeredAbility() + this.getLeftHalfCard().addAbility(new RalMonsoonMageTriggeredAbility() .addHint(InstantAndSorceryCastThisTurn.YOU.getHint())); + + // Ral, Leyline Prodigy + this.getRightHalfCard().setStartingLoyalty(2); + + // Ral, Leyline Prodigy enters the battlefield with an additional loyalty counter on him for each instant and sorcery spell you've cast this turn. + this.getRightHalfCard().addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(), InstantAndSorceryCastThisTurn.YOU, + false) + .setText("with an additional loyalty counter on him for each instant and sorcery spell you've cast this turn")) + .addHint(InstantAndSorceryCastThisTurn.YOU.getHint()) + ); + + // +1: Until your next turn, instant and sorcery spells you cast cost {1} less to cast. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new RalLeylineProdigyCostReductionEffect(), 1)); + + // -2: Ral deals 2 damage divided as you choose among one or two targets. Draw a card if you control a blue permanent other than Ral. + Ability ability = new LoyaltyAbility(new DamageMultiEffect(), -2); + ability.addTarget(new TargetAnyTargetAmount(2)); + ability.addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), + condition, "Draw a card if you control a blue permanent other than {this}" + )); + ability.addHint(hint); + this.getRightHalfCard().addAbility(ability); + + // -8: Exile the top eight cards of your library. You may cast instant and sorcery spells from among them this turn without paying their mana costs. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new RalLeylineProdigyMinusEightEffect(), -8) + .setIdentifier(MageIdentifier.WithoutPayingManaCostAlternateCast)); } private RalMonsoonMage(final RalMonsoonMage card) { @@ -118,3 +172,109 @@ class RalMonsoonMageEffect extends OneShotEffect { return true; } } + +class RalLeylineProdigyCostReductionEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterInstantOrSorceryCard("instant and sorcery spells"); + + RalLeylineProdigyCostReductionEffect() { + super(Outcome.Benefit); + this.staticText = "Until your next turn, instant and sorcery spells you cast cost {1} less to cast"; + } + + private RalLeylineProdigyCostReductionEffect(final RalLeylineProdigyCostReductionEffect effect) { + super(effect); + } + + @Override + public RalLeylineProdigyCostReductionEffect copy() { + return new RalLeylineProdigyCostReductionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + SpellsCostReductionControllerEffect effect = new SpellsCostReductionControllerEffect(filter, 1); + effect.setDuration(Duration.UntilYourNextTurn); + game.addEffect(effect, source); + return true; + } +} + +class RalLeylineProdigyMinusEightEffect extends OneShotEffect { + + RalLeylineProdigyMinusEightEffect() { + super(Outcome.Benefit); + staticText = "Exile the top eight cards of your library. " + + "You may cast instant and sorcery spells from among them this turn without paying their mana costs"; + } + + private RalLeylineProdigyMinusEightEffect(final RalLeylineProdigyMinusEightEffect effect) { + super(effect); + } + + @Override + public RalLeylineProdigyMinusEightEffect copy() { + return new RalLeylineProdigyMinusEightEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source); + if (player == null || sourceObject == null) { + return false; + } + Set cards = player.getLibrary().getTopCards(game, 8); + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getStackMomentSourceZCC()); + player.moveCardsToExile(cards, source, game, true, exileId, sourceObject.getIdName()); + for (Card card : cards) { + if (game.getState().getZone(card.getId()) == Zone.EXILED) { + game.addEffect(new RalLeylineProdigyCastEffect(new MageObjectReference(card, game)), source); + } + } + return true; + } +} + +class RalLeylineProdigyCastEffect extends AsThoughEffectImpl { + + private final MageObjectReference mor; + + public RalLeylineProdigyCastEffect(MageObjectReference mor) { + super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + this.mor = mor; + } + + private RalLeylineProdigyCastEffect(final RalLeylineProdigyCastEffect effect) { + super(effect); + this.mor = effect.mor; + } + + @Override + public RalLeylineProdigyCastEffect copy() { + return new RalLeylineProdigyCastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (mor.getCard(game) == null) { + discard(); + return false; + } + Card theCard = game.getCard(objectId); + if (theCard == null || !theCard.isInstantOrSorcery(game)) { + return false; + } + UUID mainId = theCard.getMainCard().getId(); // for split cards/MDFC/Adventure cards + if (!source.isControlledBy(affectedControllerId) || !mor.refersTo(mainId, game)) { + return false; + } + allowCardToPlayWithoutMana(mainId, source, affectedControllerId, MageIdentifier.WithoutPayingManaCostAlternateCast, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/r/RampagingSoulrager.java b/Mage.Sets/src/mage/cards/r/RampagingSoulrager.java new file mode 100644 index 00000000000..817f93282f3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RampagingSoulrager.java @@ -0,0 +1,96 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RampagingSoulrager extends CardImpl { + + public RampagingSoulrager(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // This creature gets +3/+0 as long as there are two or more unlocked doors among Rooms you control. + this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(3, 0, Duration.WhileOnBattlefield), + RampagingSoulragerCondition.instance, "{this} gets +3/+0 as long as " + + "there are two or more unlocked doors among Rooms you control" + )).addHint(RampagingSoulragerValue.getHint())); + } + + private RampagingSoulrager(final RampagingSoulrager card) { + super(card); + } + + @Override + public RampagingSoulrager copy() { + return new RampagingSoulrager(this); + } +} + +enum RampagingSoulragerCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return RampagingSoulragerValue.instance.calculate(game, source, null) >= 2; + } +} + +enum RampagingSoulragerValue implements DynamicValue { + instance; + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ROOM); + private static final Hint hint = new ValueHint("Unlocked doors among rooms you control", instance); + + public static Hint getHint() { + return hint; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return game + .getBattlefield() + .getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility, game) + .stream() + .mapToInt(permanent -> (permanent.isLeftDoorUnlocked() ? 1 : 0) + (permanent.isRightDoorUnlocked() ? 1 : 0)) + .sum(); + } + + @Override + public RampagingSoulragerValue copy() { + return this; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "1"; + } +} diff --git a/Mage.Sets/src/mage/cards/r/RampagingWerewolf.java b/Mage.Sets/src/mage/cards/r/RampagingWerewolf.java deleted file mode 100644 index b31735e695b..00000000000 --- a/Mage.Sets/src/mage/cards/r/RampagingWerewolf.java +++ /dev/null @@ -1,40 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class RampagingWerewolf extends CardImpl { - - public RampagingWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.color.setRed(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(6); - this.toughness = new MageInt(4); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Rampaging Werewolf. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private RampagingWerewolf(final RampagingWerewolf card) { - super(card); - } - - @Override - public RampagingWerewolf copy() { - return new RampagingWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RestrictedOfficeLectureHall.java b/Mage.Sets/src/mage/cards/r/RestrictedOfficeLectureHall.java new file mode 100644 index 00000000000..587c27d6a14 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RestrictedOfficeLectureHall.java @@ -0,0 +1,53 @@ +package mage.cards.r; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.ComparisonType; +import mage.constants.Duration; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RestrictedOfficeLectureHall extends RoomCard { + + private static final FilterPermanent filter = new FilterCreaturePermanent("creatures with power 3 or greater"); + + static { + filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 2)); + } + + public RestrictedOfficeLectureHall(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{W}{W}", "{5}{U}{U}"); + + // Restricted Office + // When you unlock this door, destroy all creatures with power 3 or greater. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new DestroyAllEffect(filter), false, true)); + + // Lecture Hall + // Other permanents you control have hexproof. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + HexproofAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_PERMANENTS, true + ))); + } + + private RestrictedOfficeLectureHall(final RestrictedOfficeLectureHall card) { + super(card); + } + + @Override + public RestrictedOfficeLectureHall copy() { + return new RestrictedOfficeLectureHall(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/Rivendell.java b/Mage.Sets/src/mage/cards/r/Rivendell.java index 2f0d377e354..b7903de9c0e 100644 --- a/Mage.Sets/src/mage/cards/r/Rivendell.java +++ b/Mage.Sets/src/mage/cards/r/Rivendell.java @@ -3,7 +3,7 @@ package mage.cards.r; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; -import mage.abilities.condition.common.YouControlPermanentCondition; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.keyword.ScryEffect; @@ -12,8 +12,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; import java.util.UUID; @@ -22,28 +20,22 @@ import java.util.UUID; */ public final class Rivendell extends CardImpl { - private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter); - public Rivendell(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add(SuperType.LEGENDARY); // Rivendell enters the battlefield tapped unless you control a legendary creature. - this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); + this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance) + .addHint(YouControlALegendaryCreatureCondition.getHint())); // {T}: Add {U}. this.addAbility(new BlueManaAbility()); // {1}{U}, {T}: Scry 2. Activate only if you control a legendary creature. Ability ability = new ActivateIfConditionActivatedAbility( - new ScryEffect(2, false), new ManaCostsImpl<>("{1}{U}"), condition + new ScryEffect(2, false), new ManaCostsImpl<>("{1}{U}"), + YouControlALegendaryCreatureCondition.instance ); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/r/RoaringFurnaceSteamingSauna.java b/Mage.Sets/src/mage/cards/r/RoaringFurnaceSteamingSauna.java new file mode 100644 index 00000000000..eb2952bd22d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RoaringFurnaceSteamingSauna.java @@ -0,0 +1,50 @@ +package mage.cards.r; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.Duration; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RoaringFurnaceSteamingSauna extends RoomCard { + + public RoaringFurnaceSteamingSauna(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{1}{R}", "{3}{U}{U}"); + + // Roaring Furnace + // When you unlock this door, this Room deals damage equal to the number of cards in your hand to target creature an opponent controls. + Ability ability = new UnlockThisDoorTriggeredAbility(new DamageTargetEffect(CardsInControllerHandCount.ANY), false, true); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.getLeftHalfCard().addAbility(ability); + + // Steaming Sauna + // You have no maximum hand size. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect( + Integer.MAX_VALUE, Duration.WhileOnBattlefield, MaximumHandSizeControllerEffect.HandSizeModification.SET + ))); + + // At the beginning of your end step, draw a card. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(1))); + } + + private RoaringFurnaceSteamingSauna(final RoaringFurnaceSteamingSauna card) { + super(card); + } + + @Override + public RoaringFurnaceSteamingSauna copy() { + return new RoaringFurnaceSteamingSauna(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java b/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java index 156aa64d14e..1196d5bd0e4 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java +++ b/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java @@ -1,17 +1,19 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.condition.common.NotTransformedCondition; import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.common.CardsInAllHandsCount; import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -21,20 +23,20 @@ import java.util.UUID; /** * @author fireshoes */ -public final class SageOfAncientLore extends CardImpl { +public final class SageOfAncientLore extends TransformingDoubleFacedCard { public SageOfAncientLore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SHAMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(0); - this.toughness = new MageInt(0); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SHAMAN, SubType.WEREWOLF}, "{4}{G}", + "Werewolf of Ancient Hunger", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.w.WerewolfOfAncientHunger.class; + // Sage of Ancient Lore + this.getLeftHalfCard().setPT(0, 0); // Sage of Ancient Lore's power and toughness are each equal to the number of cards in your hand. - this.addAbility(new SimpleStaticAbility( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility( Zone.ALL, new ConditionalContinuousEffect( new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY), NotTransformedCondition.instance, @@ -43,11 +45,31 @@ public final class SageOfAncientLore extends CardImpl { )); // When Sage of Ancient Lore enters the battlefield, draw a card. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); // At the beginning of each upkeep, if no spells were cast last turn, transform Sage of Ancient Lore. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Werewolf of Ancient Hunger + this.getRightHalfCard().setPT(0, 0); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Werewolf of Ancient Hunger's power and toughness are each equal to the total number of cards in all players' hands. + this.getRightHalfCard().addAbility(new SimpleStaticAbility( + Zone.ALL, + new ConditionalContinuousEffect( + new SetBasePowerToughnessSourceEffect(CardsInAllHandsCount.instance), NotTransformedCondition.instance, + "{this}'s power and toughness are each equal to the total number of cards in all players' hands" + ) + )); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Werewolf of Ancient Hunger. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private SageOfAncientLore(final SageOfAncientLore card) { diff --git a/Mage.Sets/src/mage/cards/s/SaheelisLattice.java b/Mage.Sets/src/mage/cards/s/SaheelisLattice.java index ebd54c53d84..0822ba96df3 100644 --- a/Mage.Sets/src/mage/cards/s/SaheelisLattice.java +++ b/Mage.Sets/src/mage/cards/s/SaheelisLattice.java @@ -1,36 +1,60 @@ package mage.cards.s; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.util.CardUtil; import java.util.UUID; /** * @author TheElk801 */ -public final class SaheelisLattice extends CardImpl { +public final class SaheelisLattice extends TransformingDoubleFacedCard { public SaheelisLattice(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{R}"); - this.secondSideCardClazz = mage.cards.m.MastercraftRaptor.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{R}", + "Mastercraft Raptor", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.DINOSAUR}, "R" + ); // When Saheeli's Lattice enters the battlefield, you may discard a card. If you do, draw two cards. - this.addAbility(new EntersBattlefieldTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( new DoIfCostPaid(new DrawCardSourceControllerEffect(2), new DiscardCardCost()) )); // Craft with one or more Dinosaurs {4}{R} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{4}{R}", "one or more Dinosaurs", "other Dinosaurs you control " + "or Dinosaur cards in your graveyard", 1, Integer.MAX_VALUE, SubType.DINOSAUR.getPredicate() )); + + // Mastercraft Raptor + this.getRightHalfCard().setPT(0, 4); + + // Mastercraft Raptor's power is equal to the total power of the exiled cards used to craft it. + this.getRightHalfCard().addAbility(new SimpleStaticAbility( + Zone.ALL, new SetBasePowerSourceEffect(MastercraftRaptorValue.instance) + .setText("{this}'s power is equal to the total power of the exiled cards used to craft it") + )); } private SaheelisLattice(final SaheelisLattice card) { @@ -42,3 +66,45 @@ public final class SaheelisLattice extends CardImpl { return new SaheelisLattice(this); } } + +enum MastercraftRaptorValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Card sourceCard = game.getCard(sourceAbility.getSourceId()); + if (sourceCard == null) { + return 0; + } + ExileZone exileZone = game + .getExile() + .getExileZone(CardUtil.getExileZoneId( + game, sourceCard.getMainCard().getId(), + sourceCard.getMainCard().getZoneChangeCounter(game) - 1 + )); + if (exileZone == null) { + return 0; + } + return exileZone + .getCards(game) + .stream() + .map(MageObject::getPower) + .mapToInt(MageInt::getValue) + .sum(); + } + + @Override + public MastercraftRaptorValue copy() { + return this; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "1"; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SandswirlWanderglyph.java b/Mage.Sets/src/mage/cards/s/SandswirlWanderglyph.java deleted file mode 100644 index eb39b60b2c4..00000000000 --- a/Mage.Sets/src/mage/cards/s/SandswirlWanderglyph.java +++ /dev/null @@ -1,123 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.RestrictionEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterSpell; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.watchers.common.PlayersAttackedThisTurnWatcher; - -import java.util.UUID; - -/** - * - * @author notgreat - */ -public final class SandswirlWanderglyph extends CardImpl { - private static final FilterSpell filter = new FilterSpell("a spell during their turn"); - - static { - filter.add(TargetController.ACTIVE.getControllerPredicate()); - } - public SandswirlWanderglyph(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.GOLEM); - this.power = new MageInt(5); - this.toughness = new MageInt(3); - this.nightCard = true; - this.color.setWhite(true); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever an opponent casts a spell during their turn, they can't attack you or planeswalkers you control this turn. - this.addAbility(new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, - new CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect(), filter, false, SetTargetPointer.PLAYER)); - - // Each opponent who attacked you or a planeswalker you control this turn can't cast spells. - this.addAbility(new SimpleStaticAbility(new SandswirlWanderglyphCantCastEffect()), new PlayersAttackedThisTurnWatcher()); - } - - private SandswirlWanderglyph(final SandswirlWanderglyph card) { - super(card); - } - - @Override - public SandswirlWanderglyph copy() { - return new SandswirlWanderglyph(this); - } -} - -class SandswirlWanderglyphCantCastEffect extends ContinuousRuleModifyingEffectImpl { - - SandswirlWanderglyphCantCastEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "Each opponent who attacked you or a planeswalker you control this turn can't cast spells"; - } - - private SandswirlWanderglyphCantCastEffect(final SandswirlWanderglyphCantCastEffect effect) { - super(effect); - } - - @Override - public SandswirlWanderglyphCantCastEffect copy() { - return new SandswirlWanderglyphCantCastEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.CAST_SPELL; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (game.isActivePlayer(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - PlayersAttackedThisTurnWatcher watcher = game.getState().getWatcher(PlayersAttackedThisTurnWatcher.class); - return watcher != null && watcher.hasPlayerAttackedPlayerOrControlledPlaneswalker(event.getPlayerId(), source.getControllerId()); - } - return false; - } - -} -class CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect extends RestrictionEffect { - CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect() { - super(Duration.EndOfTurn); - staticText = "they can't attack you or planeswalkers you control this turn"; - } - - private CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect(final CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect effect) { - super(effect); - } - - @Override - public CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect copy() { - return new CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect(this); - } - - @Override - public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game, boolean canUseChooseDialogs) { - if (game.getPlayer(defenderId) != null){ - return !(source.getControllerId().equals(defenderId)); - } - Permanent defender = game.getPermanent(defenderId); - if (defender != null && defender.isPlaneswalker()){ - return !(source.getControllerId().equals(defender.getControllerId())); - } - return true; - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getControllerId().equals(getTargetPointer().getFirst(game, source)); - } -} diff --git a/Mage.Sets/src/mage/cards/s/ScornedVillager.java b/Mage.Sets/src/mage/cards/s/ScornedVillager.java index 2092c0575b1..cd2d04dbf6d 100644 --- a/Mage.Sets/src/mage/cards/s/ScornedVillager.java +++ b/Mage.Sets/src/mage/cards/s/ScornedVillager.java @@ -1,37 +1,52 @@ package mage.cards.s; -import mage.MageInt; +import mage.Mana; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.keyword.VigilanceAbility; import mage.abilities.mana.GreenManaAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.Zone; import java.util.UUID; /** * @author North */ -public final class ScornedVillager extends CardImpl { +public final class ScornedVillager extends TransformingDoubleFacedCard { public ScornedVillager(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{1}{G}", + "Moonscarred Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - - this.secondSideCardClazz = mage.cards.m.MoonscarredWerewolf.class; + // Scorned Villager + this.getLeftHalfCard().setPT(1, 1); // {tap}: Add {G}. - this.addAbility(new GreenManaAbility()); + this.getLeftHalfCard().addAbility(new GreenManaAbility()); // At the beginning of each upkeep, if no spells were cast last turn, transform Scorned Villager. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Moonscarred Werewolf + this.getRightHalfCard().setPT(2, 2); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // {tap}: Add {G}{G}. + this.getRightHalfCard().addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(2), new TapSourceCost())); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonscarred Werewolf. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private ScornedVillager(final ScornedVillager card) { diff --git a/Mage.Sets/src/mage/cards/s/ScreechingBat.java b/Mage.Sets/src/mage/cards/s/ScreechingBat.java index 102b78c99a2..9323279b673 100644 --- a/Mage.Sets/src/mage/cards/s/ScreechingBat.java +++ b/Mage.Sets/src/mage/cards/s/ScreechingBat.java @@ -1,14 +1,13 @@ package mage.cards.s; -import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -17,25 +16,32 @@ import java.util.UUID; /** * @author nantuko */ -public final class ScreechingBat extends CardImpl { +public final class ScreechingBat extends TransformingDoubleFacedCard { public ScreechingBat(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); - this.subtype.add(SubType.BAT); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BAT}, "{2}{B}", + "Stalking Vampire", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE}, "B" + ); - this.secondSideCardClazz = mage.cards.s.StalkingVampire.class; + // Screeching Bat + this.getLeftHalfCard().setPT(2, 2); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // At the beginning of your upkeep, you may pay {2}{B}{B}. If you do, transform Screeching Bat. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid( + Ability transformAbility = new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid( new TransformSourceEffect(), new ManaCostsImpl<>("{2}{B}{B}") - ))); + )); + this.getLeftHalfCard().addAbility(transformAbility); + + // Stalking Vampire + this.getRightHalfCard().setPT(5, 5); + + // At the beginning of your upkeep, you may pay {2}{B}{B}. If you do, transform Screeching Bat. + this.getRightHalfCard().addAbility(transformAbility.copy()); } private ScreechingBat(final ScreechingBat card) { diff --git a/Mage.Sets/src/mage/cards/s/SeafaringWerewolf.java b/Mage.Sets/src/mage/cards/s/SeafaringWerewolf.java deleted file mode 100644 index 56b3b8c7054..00000000000 --- a/Mage.Sets/src/mage/cards/s/SeafaringWerewolf.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.CantBeBlockedSourceAbility; -import mage.abilities.keyword.NightboundAbility; -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 SeafaringWerewolf extends CardImpl { - - public SeafaringWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.color.setGreen(true); - this.nightCard = true; - - // Seafaring Werewolf can't be blocked. - this.addAbility(new CantBeBlockedSourceAbility()); - - // Whenever Seafaring Werewolf deals combat damage to a player, draw a card. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( - new DrawCardSourceControllerEffect(1), false - )); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private SeafaringWerewolf(final SeafaringWerewolf card) { - super(card); - } - - @Override - public SeafaringWerewolf copy() { - return new SeafaringWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java index 348a84913c5..c51f4756a0c 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java +++ b/Mage.Sets/src/mage/cards/s/SearchForAzcanta.java @@ -1,15 +1,19 @@ package mage.cards.s; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.keyword.SurveilEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -19,22 +23,41 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class SearchForAzcanta extends CardImpl { +public final class SearchForAzcanta extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard("a noncreature, nonland card"); + + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + filter.add(Predicates.not(CardType.LAND.getPredicate())); + } public SearchForAzcanta(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); - - this.secondSideCardClazz = mage.cards.a.AzcantaTheSunkenRuin.class; - - this.supertype.add(SuperType.LEGENDARY); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{1}{U}", + "Azcanta, The Sunken Ruin", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "U" + ); + // Search for Azcanta // At the beginning of your upkeep, look at the top card of your library. You may put it into your graveyard. Then if you have seven or more cards in your graveyard, you may transform Search for Azcanta. Ability ability = new BeginningOfUpkeepTriggeredAbility( new SurveilEffect(1, false) ); ability.addEffect(new SearchForAzcantaEffect()); - this.addAbility(new TransformAbility()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Azcanta, The Sunken Ruin + // {T} : Add {U}. + this.getRightHalfCard().addAbility(new BlueManaAbility()); + + // {2}{U} , {T} : Look at the top four cards of your library. You may reveal a noncreature, nonland card from among them and put it into your hand. Put the rest on the bottom of your library in any order. + Ability ability2 = new SimpleActivatedAbility( + new LookLibraryAndPickControllerEffect(4, 1, filter, PutCards.HAND, PutCards.BOTTOM_ANY), + new ManaCostsImpl<>("{2}{U}") + ); + ability2.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability2); } private SearchForAzcanta(final SearchForAzcanta card) { diff --git a/Mage.Sets/src/mage/cards/s/SeekerOfInsight.java b/Mage.Sets/src/mage/cards/s/SeekerOfInsight.java index 5a5b24a3247..f8afb4c2a63 100644 --- a/Mage.Sets/src/mage/cards/s/SeekerOfInsight.java +++ b/Mage.Sets/src/mage/cards/s/SeekerOfInsight.java @@ -1,17 +1,14 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.game.Game; -import mage.watchers.common.SpellsCastWatcher; import java.util.UUID; @@ -30,8 +27,8 @@ public final class SeekerOfInsight extends CardImpl { // {T}: Draw a card, then discard a card. Activate this ability only if you've cast a noncreature spell this turn. this.addAbility(new ActivateIfConditionActivatedAbility( - new DrawDiscardControllerEffect(), new TapSourceCost(), SeekerOfInsightCondition.instance - )); + new DrawDiscardControllerEffect(), new TapSourceCost(), CastNoncreatureSpellThisTurnCondition.instance + ).addHint(CastNoncreatureSpellThisTurnCondition.getHint())); } private SeekerOfInsight(final SeekerOfInsight card) { @@ -43,22 +40,3 @@ public final class SeekerOfInsight extends CardImpl { return new SeekerOfInsight(this); } } - -enum SeekerOfInsightCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return game - .getState() - .getWatcher(SpellsCastWatcher.class) - .getSpellsCastThisTurn(source.getControllerId()) - .stream() - .anyMatch(spell -> !spell.isCreature(game)); - } - - @Override - public String toString() { - return "you've cast a noncreature spell this turn"; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SephirothFabledSOLDIER.java b/Mage.Sets/src/mage/cards/s/SephirothFabledSOLDIER.java index b0e3b72d950..f105ff526dc 100644 --- a/Mage.Sets/src/mage/cards/s/SephirothFabledSOLDIER.java +++ b/Mage.Sets/src/mage/cards/s/SephirothFabledSOLDIER.java @@ -1,47 +1,53 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.*; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.command.emblems.SephirothOneWingedAngelEmblem; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.common.TargetOpponent; +import mage.target.common.TargetSacrifice; import mage.watchers.common.AbilityResolvedWatcher; +import java.util.Optional; import java.util.UUID; /** * @author TheElk801 */ -public final class SephirothFabledSOLDIER extends CardImpl { +public final class SephirothFabledSOLDIER extends TransformingDoubleFacedCard { public SephirothFabledSOLDIER(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.AVATAR, SubType.SOLDIER}, "{2}{B}", + "Sephiroth, One-Winged Angel", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ANGEL, SubType.NIGHTMARE, SubType.AVATAR}, "B" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.AVATAR); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.s.SephirothOneWingedAngel.class; + // Sephiroth, Fabled SOLDIER + this.getLeftHalfCard().setPT(3, 3); // Whenever Sephiroth enters or attacks, you may sacrifice another creature. If you do, draw a card. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DoIfCostPaid( + this.getLeftHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DoIfCostPaid( new DrawCardSourceControllerEffect(1), new SacrificeTargetCost(StaticFilters.FILTER_ANOTHER_CREATURE) ))); // Whenever another creature dies, target opponent loses 1 life and you gain 1 life. If this is the fourth time this ability has resolved this turn, transform Sephiroth. - this.addAbility(new TransformAbility()); Ability ability = new DiesCreatureTriggeredAbility( new LoseLifeTargetEffect(1), false, StaticFilters.FILTER_ANOTHER_CREATURE @@ -49,7 +55,21 @@ public final class SephirothFabledSOLDIER extends CardImpl { ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addEffect(new IfAbilityHasResolvedXTimesEffect(4, new TransformSourceEffect())); ability.addTarget(new TargetOpponent()); - this.addAbility(ability, new AbilityResolvedWatcher()); + ability.addWatcher(new AbilityResolvedWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Sephiroth, One-Winged Angel + this.getRightHalfCard().setPT(5, 5); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Super Nova -- As this creature transforms into Sephiroth, One-Winged Angel, you get an emblem with "Whenever a creature dies, target opponent loses 1 life and you gain 1 life." + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new SephirothOneWingedAngelEmblemEffect()).withFlavorWord("Super Nova")); + + // Whenever Sephiroth attacks, you may sacrifice any number of other creatures. If you do, draw that many cards. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new SephirothOneWingedAngelSacrificeEffect())); + } private SephirothFabledSOLDIER(final SephirothFabledSOLDIER card) { @@ -61,3 +81,80 @@ public final class SephirothFabledSOLDIER extends CardImpl { return new SephirothFabledSOLDIER(this); } } + +class SephirothOneWingedAngelEmblemEffect extends ReplacementEffectImpl { + + SephirothOneWingedAngelEmblemEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "as this creature transforms into {this}, " + + "you get an emblem with \"Whenever a creature dies, target opponent loses 1 life and you gain 1 life.\""; + } + + private SephirothOneWingedAngelEmblemEffect(final SephirothOneWingedAngelEmblemEffect effect) { + super(effect); + } + + @Override + public SephirothOneWingedAngelEmblemEffect copy() { + return new SephirothOneWingedAngelEmblemEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Optional.ofNullable(source.getSourceObject(game)) + .ifPresent(obj -> game.addEmblem(new SephirothOneWingedAngelEmblem(), obj, source)); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TRANSFORMING; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return source.getSourceId().equals(event.getTargetId()) + && source.getSourcePermanentIfItStillExists(game) != null; + } +} + +class SephirothOneWingedAngelSacrificeEffect extends OneShotEffect { + + SephirothOneWingedAngelSacrificeEffect() { + super(Outcome.Benefit); + staticText = "you may sacrifice any number of other creatures. If you do, draw that many cards"; + } + + private SephirothOneWingedAngelSacrificeEffect(final SephirothOneWingedAngelSacrificeEffect effect) { + super(effect); + } + + @Override + public SephirothOneWingedAngelSacrificeEffect copy() { + return new SephirothOneWingedAngelSacrificeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetSacrifice target = new TargetSacrifice( + 0, Integer.MAX_VALUE, StaticFilters.FILTER_ANOTHER_CREATURE + ); + player.choose(outcome, target, source, game); + int count = 0; + for (UUID targetId : target.getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null && permanent.sacrifice(source, game)) { + count++; + } + } + if (count < 1) { + return false; + } + player.drawCards(count, source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SephirothOneWingedAngel.java b/Mage.Sets/src/mage/cards/s/SephirothOneWingedAngel.java deleted file mode 100644 index 7b4cb758e14..00000000000 --- a/Mage.Sets/src/mage/cards/s/SephirothOneWingedAngel.java +++ /dev/null @@ -1,136 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.command.emblems.SephirothOneWingedAngelEmblem; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetSacrifice; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class SephirothOneWingedAngel extends CardImpl { - - public SephirothOneWingedAngel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ANGEL); - this.subtype.add(SubType.NIGHTMARE); - this.subtype.add(SubType.AVATAR); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.nightCard = true; - this.color.setBlack(true); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Super Nova -- As this creature transforms into Sephiroth, One-Winged Angel, you get an emblem with "Whenever a creature dies, target opponent loses 1 life and you gain 1 life." - this.addAbility(new SimpleStaticAbility(new SephirothOneWingedAngelEmblemEffect()).withFlavorWord("Super Nova")); - - // Whenever Sephiroth attacks, you may sacrifice any number of other creatures. If you do, draw that many cards. - this.addAbility(new AttacksTriggeredAbility(new SephirothOneWingedAngelSacrificeEffect())); - } - - private SephirothOneWingedAngel(final SephirothOneWingedAngel card) { - super(card); - } - - @Override - public SephirothOneWingedAngel copy() { - return new SephirothOneWingedAngel(this); - } -} - -class SephirothOneWingedAngelEmblemEffect extends ReplacementEffectImpl { - - SephirothOneWingedAngelEmblemEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "as this creature transforms into {this}, " + - "you get an emblem with \"Whenever a creature dies, target opponent loses 1 life and you gain 1 life.\""; - } - - private SephirothOneWingedAngelEmblemEffect(final SephirothOneWingedAngelEmblemEffect effect) { - super(effect); - } - - @Override - public SephirothOneWingedAngelEmblemEffect copy() { - return new SephirothOneWingedAngelEmblemEffect(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Optional.ofNullable(source.getSourceObject(game)) - .ifPresent(obj -> game.addEmblem(new SephirothOneWingedAngelEmblem(), obj, source)); - return false; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TRANSFORMING; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return source.getSourceId().equals(event.getTargetId()) - && source.getSourcePermanentIfItStillExists(game) != null; - } -} - -class SephirothOneWingedAngelSacrificeEffect extends OneShotEffect { - - SephirothOneWingedAngelSacrificeEffect() { - super(Outcome.Benefit); - staticText = "you may sacrifice any number of other creatures. If you do, draw that many cards"; - } - - private SephirothOneWingedAngelSacrificeEffect(final SephirothOneWingedAngelSacrificeEffect effect) { - super(effect); - } - - @Override - public SephirothOneWingedAngelSacrificeEffect copy() { - return new SephirothOneWingedAngelSacrificeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - TargetSacrifice target = new TargetSacrifice( - 0, Integer.MAX_VALUE, StaticFilters.FILTER_ANOTHER_CREATURE - ); - player.choose(outcome, target, source, game); - int count = 0; - for (UUID targetId : target.getTargets()) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null && permanent.sacrifice(source, game)) { - count++; - } - } - if (count < 1) { - return false; - } - player.drawCards(count, source, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SerahFarron.java b/Mage.Sets/src/mage/cards/s/SerahFarron.java index 5e77209c353..2c504648e74 100644 --- a/Mage.Sets/src/mage/cards/s/SerahFarron.java +++ b/Mage.Sets/src/mage/cards/s/SerahFarron.java @@ -1,26 +1,23 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueConditionHint; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.WatcherScope; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.ObjectSourcePlayer; @@ -38,7 +35,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SerahFarron extends CardImpl { +public final class SerahFarron extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterCreatureCard("the first legendary creature spell you cast each turn"); @@ -59,23 +56,32 @@ public final class SerahFarron extends CardImpl { ); public SerahFarron(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{W}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CITIZEN}, "{1}{G}{W}", + "Crystallized Serah", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "WG"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CITIZEN); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.c.CrystallizedSerah.class; + // Serah Farron + this.getLeftHalfCard().setPT(2, 2); // The first legendary creature spell you cast each turn costs {2} less to cast. - this.addAbility(makeAbility(), new SerahFarronWatcher()); + Ability ability = new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 2)); + ability.addWatcher(new SerahFarronWatcher()); + this.getLeftHalfCard().addAbility(ability); // At the beginning of combat on your turn, if you control two or more other legendary creatures, you may transform Serah Farron. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfCombatTriggeredAbility( + this.getLeftHalfCard().addAbility(new BeginningOfCombatTriggeredAbility( new TransformSourceEffect(), true ).withInterveningIf(condition).addHint(hint)); + + // Crystallized Serah + // The first legendary creature spell you cast each turn costs {2} less to cast. + this.getRightHalfCard().addAbility(ability.copy()); + + // Legendary creatures you control get +2/+2. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect( + 2, 2, Duration.WhileOnBattlefield, StaticFilters.FILTER_CREATURES_LEGENDARY + ))); } private SerahFarron(final SerahFarron card) { @@ -86,11 +92,6 @@ public final class SerahFarron extends CardImpl { public SerahFarron copy() { return new SerahFarron(this); } - - public static Ability makeAbility() { - return new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 2)); - } - } enum SerahFarronPredicate implements ObjectSourcePlayerPredicate { diff --git a/Mage.Sets/src/mage/cards/s/SeraphOfNewCapenna.java b/Mage.Sets/src/mage/cards/s/SeraphOfNewCapenna.java index 4fbe986ba2a..a5a726156d9 100644 --- a/Mage.Sets/src/mage/cards/s/SeraphOfNewCapenna.java +++ b/Mage.Sets/src/mage/cards/s/SeraphOfNewCapenna.java @@ -1,38 +1,54 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.StaticFilters; import java.util.UUID; /** * @author TheElk801 */ -public final class SeraphOfNewCapenna extends CardImpl { +public final class SeraphOfNewCapenna extends TransformingDoubleFacedCard { public SeraphOfNewCapenna(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ANGEL, SubType.SOLDIER}, "{2}{W}", + "Seraph of New Phyrexia", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.ANGEL}, "WB" + ); - this.subtype.add(SubType.ANGEL); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.s.SeraphOfNewPhyrexia.class; + // Seraph of New Capenna + this.getLeftHalfCard().setPT(2, 2); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // {4}{B/P}: Transform Seraph of New Capenna. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{B/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{B/P}"))); + + // Seraph of New Phyrexia + this.getRightHalfCard().setPT(3, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever Seraph of New Phyrexia attacks, you may sacrifice another creature or artifact. If you do, Seraph of New Phyrexia gets +2/+1 until end of turn. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( + new BoostSourceEffect(2, 1, Duration.EndOfTurn), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE_OR_ARTIFACT) + ))); } private SeraphOfNewCapenna(final SeraphOfNewCapenna card) { diff --git a/Mage.Sets/src/mage/cards/s/SeraphOfNewPhyrexia.java b/Mage.Sets/src/mage/cards/s/SeraphOfNewPhyrexia.java deleted file mode 100644 index 04a2cc66784..00000000000 --- a/Mage.Sets/src/mage/cards/s/SeraphOfNewPhyrexia.java +++ /dev/null @@ -1,52 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class SeraphOfNewPhyrexia extends CardImpl { - - public SeraphOfNewPhyrexia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.ANGEL); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever Seraph of New Phyrexia attacks, you may sacrifice another creature or artifact. If you do, Seraph of New Phyrexia gets +2/+1 until end of turn. - this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( - new BoostSourceEffect(2, 1, Duration.EndOfTurn), - new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE_OR_ARTIFACT) - ))); - } - - private SeraphOfNewPhyrexia(final SeraphOfNewPhyrexia card) { - super(card); - } - - @Override - public SeraphOfNewPhyrexia copy() { - return new SeraphOfNewPhyrexia(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SeshirosLivingLegacy.java b/Mage.Sets/src/mage/cards/s/SeshirosLivingLegacy.java deleted file mode 100644 index 61ed396df36..00000000000 --- a/Mage.Sets/src/mage/cards/s/SeshirosLivingLegacy.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.VigilanceAbility; -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 SeshirosLivingLegacy extends CardImpl { - - public SeshirosLivingLegacy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.SNAKE); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.color.setGreen(true); - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - } - - private SeshirosLivingLegacy(final SeshirosLivingLegacy card) { - super(card); - } - - @Override - public SeshirosLivingLegacy copy() { - return new SeshirosLivingLegacy(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/ShadyTraveler.java b/Mage.Sets/src/mage/cards/s/ShadyTraveler.java index a7c56fa4541..d6b8b7f501b 100644 --- a/Mage.Sets/src/mage/cards/s/ShadyTraveler.java +++ b/Mage.Sets/src/mage/cards/s/ShadyTraveler.java @@ -1,10 +1,10 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.keyword.DayboundAbility; import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,22 +13,32 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class ShadyTraveler extends CardImpl { +public final class ShadyTraveler extends TransformingDoubleFacedCard { public ShadyTraveler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{2}{B}", + "Stalking Predator", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "B" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.s.StalkingPredator.class; + // Shady Traveler + this.getLeftHalfCard().setPT(2, 3); // Menace - this.addAbility(new MenaceAbility()); + this.getLeftHalfCard().addAbility(new MenaceAbility()); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Stalking Predator + this.getRightHalfCard().setPT(4, 4); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private ShadyTraveler(final ShadyTraveler card) { diff --git a/Mage.Sets/src/mage/cards/s/ShayCormac.java b/Mage.Sets/src/mage/cards/s/ShayCormac.java index 5878a3d67ff..1e125076a7d 100644 --- a/Mage.Sets/src/mage/cards/s/ShayCormac.java +++ b/Mage.Sets/src/mage/cards/s/ShayCormac.java @@ -58,7 +58,7 @@ public final class ShayCormac extends CardImpl { // Whenever a creature with a bounty counter on it dies, put two +1/+1 counters on Shay Cormac. this.addAbility(new DiesCreatureTriggeredAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, filter2 + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), false, filter2 )); } diff --git a/Mage.Sets/src/mage/cards/s/Sheoldred.java b/Mage.Sets/src/mage/cards/s/Sheoldred.java index 49f1aad0ef4..b8c6397069a 100644 --- a/Mage.Sets/src/mage/cards/s/Sheoldred.java +++ b/Mage.Sets/src/mage/cards/s/Sheoldred.java @@ -1,27 +1,40 @@ package mage.cards.s; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SagaAbility; import mage.abilities.condition.common.CardsInOpponentGraveyardCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.effects.common.ExileAndReturnSourceEffect; -import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; import mage.abilities.keyword.MenaceAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlaneswalker; +import mage.target.targetadjustment.ForEachPlayerTargetsAdjuster; +import mage.target.targetpointer.EachTargetPointer; +import java.util.Collection; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** * @author TheElk801 */ -public final class Sheoldred extends CardImpl { +public final class Sheoldred extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent("nontoken creature or planeswalker"); @@ -31,27 +44,56 @@ public final class Sheoldred extends CardImpl { } public Sheoldred(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.PRAETOR}, "{3}{B}{B}", + "The True Scriptures", + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "B" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.PRAETOR); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.secondSideCardClazz = mage.cards.t.TheTrueScriptures.class; + // Sheoldred + this.getLeftHalfCard().setPT(4, 5); // Menace - this.addAbility(new MenaceAbility(false)); + this.getLeftHalfCard().addAbility(new MenaceAbility(false)); // When Sheoldred enters the battlefield, each opponent sacrifices a nontoken creature or planeswalker. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeOpponentsEffect(filter))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeOpponentsEffect(filter))); // {4}{B}: Exile Sheoldred, then return it to the battlefield transformed under its owner's control. Activate only as a sorcery and only if an opponent has eight or more cards in their graveyard. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateIfConditionActivatedAbility( + this.getLeftHalfCard().addAbility(new ActivateIfConditionActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{4}{B}"), CardsInOpponentGraveyardCondition.EIGHT ).setTiming(TimingRule.SORCERY).addHint(CardsInOpponentGraveyardCondition.EIGHT.getHint())); + + // The True Scriptures + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I -- For each opponent, destroy up to one target creature or planeswalker that player controls. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, false, + ability -> { + ability.addEffect(new DestroyTargetEffect().setTargetPointer(new EachTargetPointer()) + .setText("for each opponent, destroy up to one target creature or planeswalker that player controls")); + ability.addTarget(new TargetCreatureOrPlaneswalker(0, 1)); + ability.setTargetAdjuster(new ForEachPlayerTargetsAdjuster(false, true)); + } + ); + + // II -- Each opponent discards three cards, then mills three cards. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_II, + new DiscardEachPlayerEffect(StaticValue.get(3), false, TargetController.OPPONENT), + new MillCardsEachPlayerEffect(3, TargetController.OPPONENT).setText(", then mills three cards") + ); + + // III -- Put all creature cards from all graveyards onto the battlefield under your control. Exile The True Scriptures, then return it to the battlefield. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_III, + new SheoldredTrueScripturesEffect(), + new ExileSourceAndReturnFaceUpEffect() + ); + this.getRightHalfCard().addAbility(sagaAbility); } private Sheoldred(final Sheoldred card) { @@ -63,3 +105,39 @@ public final class Sheoldred extends CardImpl { return new Sheoldred(this); } } + +class SheoldredTrueScripturesEffect extends OneShotEffect { + + SheoldredTrueScripturesEffect() { + super(Outcome.Benefit); + staticText = "put all creature cards from all graveyards onto the battlefield under your control"; + } + + private SheoldredTrueScripturesEffect(final SheoldredTrueScripturesEffect effect) { + super(effect); + } + + @Override + public SheoldredTrueScripturesEffect copy() { + return new SheoldredTrueScripturesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(Player::getGraveyard) + .map(gy -> gy.getCards(StaticFilters.FILTER_CARD_CREATURE, game)) + .flatMap(Collection::stream) + .collect(Collectors.toList())); + return player.moveCards(cards, Zone.BATTLEFIELD, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/s/ShinryuTranscendentRival.java b/Mage.Sets/src/mage/cards/s/ShinryuTranscendentRival.java deleted file mode 100644 index 712dfdb3e7d..00000000000 --- a/Mage.Sets/src/mage/cards/s/ShinryuTranscendentRival.java +++ /dev/null @@ -1,137 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.WinGameSourceControllerEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetPlayer; -import mage.target.common.TargetOpponent; -import mage.util.CardUtil; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ShinryuTranscendentRival extends CardImpl { - - public ShinryuTranscendentRival(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.DRAGON); - this.power = new MageInt(8); - this.toughness = new MageInt(8); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // As this creature transforms into Shinryu, choose an opponent. - this.addAbility(new SimpleStaticAbility(new ShinryuTranscendentRivalEffect())); - - // Burning Chains -- When the chosen player loses the game, you win the game. - this.addAbility(new ShinryuTranscendentRivalTriggeredAbility()); - } - - private ShinryuTranscendentRival(final ShinryuTranscendentRival card) { - super(card); - } - - @Override - public ShinryuTranscendentRival copy() { - return new ShinryuTranscendentRival(this); - } -} - -class ShinryuTranscendentRivalEffect extends ReplacementEffectImpl { - - ShinryuTranscendentRivalEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "as this creature transforms into {this}, choose an opponent"; - } - - private ShinryuTranscendentRivalEffect(final ShinryuTranscendentRivalEffect effect) { - super(effect); - } - - @Override - public ShinryuTranscendentRivalEffect copy() { - return new ShinryuTranscendentRivalEffect(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (controller == null || permanent == null) { - return false; - } - TargetPlayer target = new TargetOpponent(true); - controller.choose(outcome, target, source, game); - Player opponent = game.getPlayer(target.getFirstTarget()); - if (opponent == null) { - return false; - } - game.informPlayers(permanent.getName() + ": " + controller.getLogName() + " has chosen " + opponent.getLogName()); - game.getState().setValue(permanent.getId() + "_" + permanent.getZoneChangeCounter(game) + "_opponent", opponent.getId()); - permanent.addInfo("chosen opponent", CardUtil.addToolTipMarkTags("Chosen Opponent " + opponent.getLogName()), game); - return false; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.TRANSFORMING; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return source.getSourceId().equals(event.getTargetId()) - && source.getSourcePermanentIfItStillExists(game) != null; - } -} - -class ShinryuTranscendentRivalTriggeredAbility extends TriggeredAbilityImpl { - - ShinryuTranscendentRivalTriggeredAbility() { - super(Zone.BATTLEFIELD, new WinGameSourceControllerEffect()); - this.setTriggerPhrase("When the chosen player loses the game, "); - this.withFlavorWord("Burning Chains"); - } - - private ShinryuTranscendentRivalTriggeredAbility(final ShinryuTranscendentRivalTriggeredAbility ability) { - super(ability); - } - - @Override - public ShinryuTranscendentRivalTriggeredAbility copy() { - return new ShinryuTranscendentRivalTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.LOST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - int zcc = game.getState().getZoneChangeCounter(this.getSourceId()); - return Optional - .of(this.getSourceId() + "_" + zcc + "_opponent") - .map(game.getState()::getValue) - .map(event.getPlayerId()::equals) - .orElse(false); - } -} diff --git a/Mage.Sets/src/mage/cards/s/ShrillHowler.java b/Mage.Sets/src/mage/cards/s/ShrillHowler.java index 40e9b05ce39..4f7742553d9 100644 --- a/Mage.Sets/src/mage/cards/s/ShrillHowler.java +++ b/Mage.Sets/src/mage/cards/s/ShrillHowler.java @@ -1,42 +1,49 @@ - package mage.cards.s; -import java.util.UUID; - -import mage.MageInt; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesWithLessPowerEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; +import mage.game.permanent.token.EldraziHorrorToken; + +import java.util.UUID; /** * @author LevelX2 */ -public final class ShrillHowler extends CardImpl { +public final class ShrillHowler extends TransformingDoubleFacedCard { public ShrillHowler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(3); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.HORROR}, "{2}{G}", + "Howling Chorus", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.WEREWOLF}, "" + ); - this.secondSideCardClazz = mage.cards.h.HowlingChorus.class; + // Shrill Howler + this.getLeftHalfCard().setPT(3, 1); // Creatures with power less than Shrill Howler's power can't block it. - this.addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesWithLessPowerEffect())); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesWithLessPowerEffect())); // {5}{G}: Transform Shrill Howler. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{G}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{G}"))); + // Howling Chorus + this.getRightHalfCard().setPT(3, 5); + + // Creatures with power less than Howling Chorus's power can't block it. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesWithLessPowerEffect())); + + // Whenever Howling Chorus deals combat damage to a player, create a 3/2 colorless Eldrazi Horror creature token. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenEffect(new EldraziHorrorToken()), false)); } private ShrillHowler(final ShrillHowler card) { diff --git a/Mage.Sets/src/mage/cards/s/SidequestCardCollection.java b/Mage.Sets/src/mage/cards/s/SidequestCardCollection.java index 16874c1afbc..36e79f2e98a 100644 --- a/Mage.Sets/src/mage/cards/s/SidequestCardCollection.java +++ b/Mage.Sets/src/mage/cards/s/SidequestCardCollection.java @@ -5,32 +5,45 @@ import mage.abilities.condition.Condition; import mage.abilities.condition.common.CardsInControllerGraveyardCondition; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.FlyingAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import java.util.UUID; /** * @author TheElk801 */ -public final class SidequestCardCollection extends CardImpl { +public final class SidequestCardCollection extends TransformingDoubleFacedCard { private static final Condition condition = new CardsInControllerGraveyardCondition(8); public SidequestCardCollection(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); - - this.secondSideCardClazz = mage.cards.m.MagickedCard.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{3}{U}", + "Magicked Card", + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "U" + ); + // Sidequest: Card Collection // When this enchantment enters, draw three cards, then discard two cards. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(3, 2))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(3, 2))); // At the beginning of your end step, if eight or more cards are in your graveyard, transform this enchantment. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()).withInterveningIf(condition)); + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()).withInterveningIf(condition)); + + // Magicked Card + this.getRightHalfCard().setPT(4, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Crew 1 + this.getRightHalfCard().addAbility(new CrewAbility(1)); } private SidequestCardCollection(final SidequestCardCollection card) { diff --git a/Mage.Sets/src/mage/cards/s/SidequestCatchAFish.java b/Mage.Sets/src/mage/cards/s/SidequestCatchAFish.java index a8c3b53caec..44872adf6b4 100644 --- a/Mage.Sets/src/mage/cards/s/SidequestCatchAFish.java +++ b/Mage.Sets/src/mage/cards/s/SidequestCatchAFish.java @@ -1,36 +1,58 @@ package mage.cards.s; -import java.util.UUID; - import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.mana.WhiteManaAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.token.FoodToken; import mage.players.Player; +import java.util.UUID; + /** * @author balazskristof */ -public final class SidequestCatchAFish extends CardImpl { +public final class SidequestCatchAFish extends TransformingDoubleFacedCard { public SidequestCatchAFish(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); - - this.secondSideCardClazz = mage.cards.c.CookingCampsite.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{2}{W}", + "Cooking Campsite", + new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Sidequest: Catch a Fish // At the beginning of your upkeep, look at the top card of your library. If it's an artifact or creature card, you may reveal it and put it into your hand. If you put a card into your hand this way, create a Food token and transform this enchantment. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SidequestCatchAFishEffect())); + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new SidequestCatchAFishEffect())); + + // Cooking Campsite + // {T}: Add {W}. + this.getRightHalfCard().addAbility(new WhiteManaAbility()); + + // {3}, {T}, Sacrifice an artifact: Put a +1/+1 counter on each creature you control. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new AddCountersAllEffect(CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE), new ManaCostsImpl<>("{3}") + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT_AN)); + this.getRightHalfCard().addAbility(ability); } private SidequestCatchAFish(final SidequestCatchAFish card) { @@ -48,8 +70,8 @@ class SidequestCatchAFishEffect extends OneShotEffect { SidequestCatchAFishEffect() { super(Outcome.Benefit); staticText = "look at the top card of your library. " + - "If it's an artifact or creature card, you may reveal it and put it into your hand. " + - "If you put a card into your hand this way, create a Food token and transform this enchantment."; + "If it's an artifact or creature card, you may reveal it and put it into your hand. " + + "If you put a card into your hand this way, create a Food token and transform this enchantment."; } private SidequestCatchAFishEffect(final SidequestCatchAFishEffect effect) { diff --git a/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java b/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java index 4b1ce5df4a5..78b97087cb3 100644 --- a/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java +++ b/Mage.Sets/src/mage/cards/s/SidequestHuntTheMark.java @@ -2,25 +2,30 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.TapSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.IndestructibleAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.SubType; -import mage.constants.WatcherScope; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; @@ -35,7 +40,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SidequestHuntTheMark extends CardImpl { +public final class SidequestHuntTheMark extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledPermanent(SubType.TREASURE), ComparisonType.MORE_THAN, 2 @@ -44,25 +49,51 @@ public final class SidequestHuntTheMark extends CardImpl { "Treasures you control", new PermanentsOnBattlefieldCount(new FilterControlledPermanent(SubType.TREASURE)) ); + private static final FilterPermanent ySacFilter = new FilterPermanent("another creature or artifact"); + + static { + ySacFilter.add(AnotherPredicate.instance); + ySacFilter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.ARTIFACT.getPredicate() + )); + } + public SidequestHuntTheMark(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); - - this.secondSideCardClazz = mage.cards.y.YiazmatUltimateMark.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{3}{B}{B}", + "Yiazmat, Ultimate Mark", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DRAGON}, "B" + ); + // Sidequest: Hunt the Mark // When this enchantment enters, destroy up to one target creature. Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); ability.addTarget(new TargetCreaturePermanent(0, 1)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of your end step, if a creature died under an opponent's control this turn, create a Treasure token. Then if you control three or more Treasures, transform this enchantment. - this.addAbility(new TransformAbility()); ability = new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new TreasureToken())) .withInterveningIf(SidequestHuntTheMarkCondition.instance); ability.addEffect(new ConditionalOneShotEffect( new TransformSourceEffect(), condition, "Then if you control three or more Treasures, transform {this}" )); - this.addAbility(ability.addHint(hint).addHint(SidequestHuntTheMarkCondition.getHint()), new SidequestHuntTheMarkWatcher()); + ability.addHint(hint) + .addHint(SidequestHuntTheMarkCondition.getHint()); + ability.addWatcher(new SidequestHuntTheMarkWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Yiazmat, Ultimate Mark + this.getRightHalfCard().setPT(5, 6); + + // {1}{B}, Sacrifice another creature or artifact: Yiazmat gains indestructible until end of turn. Tap it. + Ability yAbility = new SimpleActivatedAbility( + new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl<>("{1}{B}") + ); + yAbility.addCost(new SacrificeTargetCost(ySacFilter)); + yAbility.addEffect(new TapSourceEffect().setText("tap it")); + this.getRightHalfCard().addAbility(yAbility); } private SidequestHuntTheMark(final SidequestHuntTheMark card) { @@ -120,10 +151,10 @@ class SidequestHuntTheMarkWatcher extends Watcher { } static boolean checkPlayer(Game game, Ability source) { - return game + game .getState() - .getWatcher(SidequestHuntTheMarkWatcher.class) - .set + .getWatcher(SidequestHuntTheMarkWatcher.class); + return set .contains(source.getControllerId()); } } diff --git a/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java b/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java index 8720da23746..fc136ca045b 100644 --- a/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java +++ b/Mage.Sets/src/mage/cards/s/SidequestPlayBlitzball.java @@ -2,18 +2,19 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.common.EndOfCombatTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.EquipAbility; import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.WatcherScope; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.DamagedEvent; @@ -32,25 +33,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SidequestPlayBlitzball extends CardImpl { +public final class SidequestPlayBlitzball extends TransformingDoubleFacedCard { public SidequestPlayBlitzball(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); - - this.secondSideCardClazz = mage.cards.w.WorldChampionCelestialWeapon.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{2}{R}", + "World Champion, Celestial Weapon", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.EQUIPMENT}, "R" + ); + // Sidequest: Play Blitzball // At the beginning of combat on your turn, target creature you control gets +2/+0 until end of turn. Ability ability = new BeginningOfCombatTriggeredAbility(new BoostTargetEffect(2, 0)); ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the end of combat on your turn, if a player was dealt 6 or more combat damage this turn, transform this enchantment, then attach it to a creature you control. - this.addAbility(new TransformAbility()); ability = new EndOfCombatTriggeredAbility( new TransformSourceEffect(), TargetController.YOU, false ).withInterveningIf(SidequestPlayBlitzballCondition.instance).setTriggerPhrase("At the end of combat on your turn, "); ability.addEffect(new SidequestPlayBlitzballEffect()); - this.addAbility(ability, new SidequestPlayBlitzballWatcher()); + ability.addWatcher(new SidequestPlayBlitzballWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // World Champion, Celestial Weapon + // Double Overdrive -- Equipped creature gets +2/+0 and has double strike. + Ability eAbility = new SimpleStaticAbility(new BoostEquippedEffect(2, 0)); + eAbility.addEffect(new GainAbilityAttachedEffect( + DoubleStrikeAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has double strike")); + this.getRightHalfCard().addAbility(eAbility.withFlavorWord("Double Overdrive")); + + // Equip {3} + this.getRightHalfCard().addAbility(new EquipAbility(3)); } private SidequestPlayBlitzball(final SidequestPlayBlitzball card) { diff --git a/Mage.Sets/src/mage/cards/s/SidequestRaiseAChocobo.java b/Mage.Sets/src/mage/cards/s/SidequestRaiseAChocobo.java index da84b7ecc6d..ddca6715635 100644 --- a/Mage.Sets/src/mage/cards/s/SidequestRaiseAChocobo.java +++ b/Mage.Sets/src/mage/cards/s/SidequestRaiseAChocobo.java @@ -1,30 +1,38 @@ package mage.cards.s; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.LandfallAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.ComparisonType; +import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.ChocoboToken; +import mage.target.common.TargetCardInLibrary; import java.util.UUID; /** * @author TheElk801 */ -public final class SidequestRaiseAChocobo extends CardImpl { +public final class SidequestRaiseAChocobo extends TransformingDoubleFacedCard { + private static final FilterPermanent filter = new FilterPermanent(SubType.BIRD, "Birds"); private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledPermanent(SubType.BIRD, "you control four or more Birds"), ComparisonType.MORE_THAN, 3 @@ -34,17 +42,32 @@ public final class SidequestRaiseAChocobo extends CardImpl { ); public SidequestRaiseAChocobo(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); - - this.secondSideCardClazz = mage.cards.b.BlackChocobo.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{1}{G}", + "Black Chocobo", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BIRD}, "G" + ); + // Sidequest: Raise a Chocobo // When this enchantment enters, create a 2/2 green Bird creature token with "Whenever a land you control enters, this token gets +1/+0 until end of turn." - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ChocoboToken()))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ChocoboToken()))); // At the beginning of your first main phase, if you control four or more Birds, transform this enchantment. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfFirstMainTriggeredAbility(new TransformSourceEffect()) + this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility(new TransformSourceEffect()) .withInterveningIf(condition).addHint(hint)); + + // Black Chocobo + this.getRightHalfCard().setPT(2, 2); + + // When this permanent transforms into Black Chocobo, search your library for a land card, put it onto the battlefield tapped, then shuffle. + this.getRightHalfCard().addAbility(new TransformIntoSourceTriggeredAbility( + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_LAND_A), true) + )); + + // Landfall -- Whenever a land you control enters, Birds you control get +1/+0 until end of turn. + this.getRightHalfCard().addAbility(new LandfallAbility(new BoostControlledEffect( + 1, 0, Duration.EndOfTurn, filter, false + ))); } private SidequestRaiseAChocobo(final SidequestRaiseAChocobo card) { diff --git a/Mage.Sets/src/mage/cards/s/SkinInvasion.java b/Mage.Sets/src/mage/cards/s/SkinInvasion.java index 38647f13455..dda91e54c88 100644 --- a/Mage.Sets/src/mage/cards/s/SkinInvasion.java +++ b/Mage.Sets/src/mage/cards/s/SkinInvasion.java @@ -1,7 +1,5 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -11,45 +9,46 @@ import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.game.Game; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 */ -public final class SkinInvasion extends CardImpl { +public final class SkinInvasion extends TransformingDoubleFacedCard { public SkinInvasion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}"); - this.subtype.add(SubType.AURA); - - this.secondSideCardClazz = mage.cards.s.SkinShedder.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "{R}", + "Skin Shedder", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.INSECT, SubType.HORROR}, "R" + ); + // Skin Invasion // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); - this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + this.getLeftHalfCard().getSpellAbility().addTarget(auraTarget); + this.getLeftHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Enchanted creature attacks each combat if able. - this.addAbility(new SimpleStaticAbility( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility( new AttacksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA))); // When enchanted creature dies, return Skin Invasion to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesAttachedTriggeredAbility(new SkinInvasionEffect(), "enchanted creature", false)); + this.getLeftHalfCard().addAbility(new DiesAttachedTriggeredAbility(new SkinInvasionEffect(), "enchanted creature", false)); + + // Skin Shedder + this.getRightHalfCard().setPT(3, 4); } private SkinInvasion(final SkinInvasion card) { diff --git a/Mage.Sets/src/mage/cards/s/SkinShedder.java b/Mage.Sets/src/mage/cards/s/SkinShedder.java deleted file mode 100644 index 280214dbb26..00000000000 --- a/Mage.Sets/src/mage/cards/s/SkinShedder.java +++ /dev/null @@ -1,38 +0,0 @@ - -package mage.cards.s; - -import java.util.UUID; -import mage.MageInt; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -/** - * - * @author LevelX2 - */ -public final class SkinShedder extends CardImpl { - - public SkinShedder(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.INSECT); - this.subtype.add(SubType.HORROR); - this.color.setRed(true); - - this.nightCard = true; - - this.power = new MageInt(3); - this.toughness = new MageInt(4); - } - - private SkinShedder(final SkinShedder card) { - super(card); - } - - @Override - public SkinShedder copy() { - return new SkinShedder(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/s/SkyclaveAerialist.java b/Mage.Sets/src/mage/cards/s/SkyclaveAerialist.java index 07486d3175c..d56ceaf0eb2 100644 --- a/Mage.Sets/src/mage/cards/s/SkyclaveAerialist.java +++ b/Mage.Sets/src/mage/cards/s/SkyclaveAerialist.java @@ -1,38 +1,54 @@ package mage.cards.s; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; import java.util.UUID; /** * @author TheElk801 */ -public final class SkyclaveAerialist extends CardImpl { +public final class SkyclaveAerialist extends TransformingDoubleFacedCard { public SkyclaveAerialist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.MERFOLK, SubType.SCOUT}, "{1}{U}", + "Skyclave Invader", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.MERFOLK, SubType.SCOUT}, "UG" + ); - this.subtype.add(SubType.MERFOLK); - this.subtype.add(SubType.SCOUT); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.s.SkyclaveInvader.class; + // Skyclave Aerialist + this.getLeftHalfCard().setPT(2, 1); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // {4}{G/P}: Transform Skyclave Aerialist. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{G/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{G/P}"))); + + // Skyclave Invader + this.getRightHalfCard().setPT(2, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // When this creature transforms into Skyclave Invader, look at the top card of your library. If it's a land card, you may put it onto the battlefield. If you don't put the card onto the battlefield, put it into your hand. + this.getRightHalfCard().addAbility(new TransformIntoSourceTriggeredAbility(new SkyclaveInvaderEffect())); } private SkyclaveAerialist(final SkyclaveAerialist card) { @@ -44,3 +60,38 @@ public final class SkyclaveAerialist extends CardImpl { return new SkyclaveAerialist(this); } } + +class SkyclaveInvaderEffect extends OneShotEffect { + + SkyclaveInvaderEffect() { + super(Outcome.Benefit); + staticText = "look at the top card of your library. If it's a land card, you may put it onto the battlefield. " + + "If you don't put the card onto the battlefield, put it into your hand"; + } + + private SkyclaveInvaderEffect(final SkyclaveInvaderEffect effect) { + super(effect); + } + + @Override + public SkyclaveInvaderEffect copy() { + return new SkyclaveInvaderEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Card card = player.getLibrary().getFromTop(game); + if (card == null) { + return false; + } + player.lookAtCards(source, null, new CardsImpl(card), game); + return player.moveCards(card, card.isLand(game) && player.chooseUse( + Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield or into your hand?", + null, "Battlefield", "Hand", source, game + ) ? Zone.BATTLEFIELD : Zone.HAND, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SkyclaveInvader.java b/Mage.Sets/src/mage/cards/s/SkyclaveInvader.java deleted file mode 100644 index dec33c9ee6e..00000000000 --- a/Mage.Sets/src/mage/cards/s/SkyclaveInvader.java +++ /dev/null @@ -1,88 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.FlyingAbility; -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.constants.SubType; -import mage.constants.Zone; -import mage.game.Game; -import mage.players.Player; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class SkyclaveInvader extends CardImpl { - - public SkyclaveInvader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.MERFOLK); - this.subtype.add(SubType.SCOUT); - this.power = new MageInt(2); - this.toughness = new MageInt(4); - this.color.setBlue(true); - this.color.setGreen(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // When this creature transforms into Skyclave Invader, look at the top card of your library. If it's a land card, you may put it onto the battlefield. If you don't put the card onto the battlefield, put it into your hand. - this.addAbility(new TransformIntoSourceTriggeredAbility(new SkyclaveInvaderEffect())); - } - - private SkyclaveInvader(final SkyclaveInvader card) { - super(card); - } - - @Override - public SkyclaveInvader copy() { - return new SkyclaveInvader(this); - } -} - -class SkyclaveInvaderEffect extends OneShotEffect { - - SkyclaveInvaderEffect() { - super(Outcome.Benefit); - staticText = "look at the top card of your library. If it's a land card, you may put it onto the battlefield. " + - "If you don't put the card onto the battlefield, put it into your hand"; - } - - private SkyclaveInvaderEffect(final SkyclaveInvaderEffect effect) { - super(effect); - } - - @Override - public SkyclaveInvaderEffect copy() { - return new SkyclaveInvaderEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Card card = player.getLibrary().getFromTop(game); - if (card == null) { - return false; - } - player.lookAtCards(source, null, new CardsImpl(card), game); - return player.moveCards(card, card.isLand(game) && player.chooseUse( - Outcome.PutCardInPlay, "Put " + card.getName() + " onto the battlefield or into your hand?", - null, "Battlefield", "Hand", source, game - ) ? Zone.BATTLEFIELD : Zone.HAND, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SlicerHighSpeedAntagonist.java b/Mage.Sets/src/mage/cards/s/SlicerHighSpeedAntagonist.java deleted file mode 100644 index 61fb781a073..00000000000 --- a/Mage.Sets/src/mage/cards/s/SlicerHighSpeedAntagonist.java +++ /dev/null @@ -1,59 +0,0 @@ -package mage.cards.s; - -import java.util.UUID; - -import mage.MageInt; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.abilities.keyword.LivingMetalAbility; -import mage.abilities.keyword.FirstStrikeAbility; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; - -/** - * @author grimreap124 - */ -public final class SlicerHighSpeedAntagonist extends CardImpl { - - public SlicerHighSpeedAntagonist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[] { CardType.ARTIFACT }, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.VEHICLE); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.color.setRed(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // First strike - this.addAbility(FirstStrikeAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // Whenever Slicer deals combat damage to a player, convert it at end of combat. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( - new CreateDelayedTriggeredAbilityEffect( - new AtTheEndOfCombatDelayedTriggeredAbility(new TransformSourceEffect())) - .setText("convert it at end of combat"), - false)); - - } - - private SlicerHighSpeedAntagonist(final SlicerHighSpeedAntagonist card) { - super(card); - } - - @Override - public SlicerHighSpeedAntagonist copy() { - return new SlicerHighSpeedAntagonist(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SlicerHiredMuscle.java b/Mage.Sets/src/mage/cards/s/SlicerHiredMuscle.java index 8e5c77167ec..183989880be 100644 --- a/Mage.Sets/src/mage/cards/s/SlicerHiredMuscle.java +++ b/Mage.Sets/src/mage/cards/s/SlicerHiredMuscle.java @@ -1,56 +1,76 @@ package mage.cards.s; -import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.keyword.DoubleStrikeAbility; -import mage.abilities.keyword.HasteAbility; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.combat.GoadTargetEffect; +import mage.abilities.effects.common.continuous.CantBeSacrificedSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.continuous.CantBeSacrificedSourceEffect; -import mage.abilities.effects.OneShotEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.*; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; -import mage.game.Game; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.game.Game; import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; import mage.players.Player; -import mage.abilities.common.SimpleStaticAbility; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** * @author grimreap124 */ -public final class SlicerHiredMuscle extends CardImpl { +public final class SlicerHiredMuscle extends TransformingDoubleFacedCard { public SlicerHiredMuscle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[] { CardType.ARTIFACT, CardType.CREATURE }, "{4}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{4}{R}", + "Slicer, High-Speed Antagonist", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "R" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.s.SlicerHighSpeedAntagonist.class; + // Slicer, Hired Muscle + this.getLeftHalfCard().setPT(3, 4); // More Than Meets the Eye {2}{R} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{R}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{R}")); // Double strike - this.addAbility(DoubleStrikeAbility.getInstance()); + this.getLeftHalfCard().addAbility(DoubleStrikeAbility.getInstance()); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // At the beginning of each opponent's upkeep, you may have that player gain // control of Slicer until end of turn. If you do, untap Slicer, goad it, and it // can't be sacrificed this turn. If you don't, convert it. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(TargetController.OPPONENT, new SlicerHiredMuscleUpkeepEffect(), + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(TargetController.OPPONENT, new SlicerHiredMuscleUpkeepEffect(), false)); + // Slicer, High-Speed Antagonist + this.getRightHalfCard().setPT(3, 2); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // First strike + this.getRightHalfCard().addAbility(FirstStrikeAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // Whenever Slicer deals combat damage to a player, convert it at end of combat. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new TransformSourceEffect())) + .setText("convert it at end of combat"), + false)); } private SlicerHiredMuscle(final SlicerHiredMuscle card) { @@ -104,8 +124,8 @@ class SlicerHiredMuscleUpkeepEffect extends OneShotEffect { // Goad game.addEffect(new GoadTargetEffect() - .setDuration(Duration.EndOfTurn) - .setTargetPointer(new FixedTarget(sourcePermanent, game)), + .setDuration(Duration.EndOfTurn) + .setTargetPointer(new FixedTarget(sourcePermanent, game)), source); // Can't be sacrificed diff --git a/Mage.Sets/src/mage/cards/s/SmolderingEgg.java b/Mage.Sets/src/mage/cards/s/SmolderingEgg.java index 7add8019e87..12cedaa41b5 100644 --- a/Mage.Sets/src/mage/cards/s/SmolderingEgg.java +++ b/Mage.Sets/src/mage/cards/s/SmolderingEgg.java @@ -1,6 +1,5 @@ package mage.cards.s; -import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.AbilityImpl; @@ -11,19 +10,21 @@ import mage.abilities.costs.mana.ManaCost; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.RemoveAllCountersSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DefenderAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.stack.Spell; +import mage.target.common.TargetAnyTarget; import java.util.Optional; import java.util.UUID; @@ -31,24 +32,24 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SmolderingEgg extends CardImpl { +public final class SmolderingEgg extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.EMBER, 7); public SmolderingEgg(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DRAGON, SubType.EGG}, "{1}{R}", + "Ashmouth Dragon", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DRAGON}, "R" + ); - this.subtype.add(SubType.DRAGON); - this.subtype.add(SubType.EGG); - this.power = new MageInt(0); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.a.AshmouthDragon.class; + // Smoldering Egg + this.getLeftHalfCard().setPT(0, 4); // Defender - this.addAbility(DefenderAbility.getInstance()); + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // Whenever you cast an instant or sorcery spell, put a number of ember counters on Smoldering Egg equal to the amount of mana spent to cast that spell. Then if Smoldering Egg has seven or more ember counters on it, remove them and transform Smoldering Egg. - this.addAbility(new TransformAbility()); Ability ability = new SpellCastControllerTriggeredAbility( new AddCountersSourceEffect(CounterType.EMBER.createInstance(), SmolderingEggValue.instance) .setText("put a number of ember counters on {this} equal to the amount of mana spent to cast that spell"), @@ -58,7 +59,20 @@ public final class SmolderingEgg extends CardImpl { new RemoveAllCountersSourceEffect(CounterType.EMBER), condition, "Then if {this} has seven or more ember counters on it, remove them and transform {this}" ).addEffect(new TransformSourceEffect())); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Ashmouth Dragon + this.getRightHalfCard().setPT(4, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever you cast an instant or sorcery spell, Ashmouth Dragon deals 2 damage to any target. + Ability ability2 = new SpellCastControllerTriggeredAbility( + new DamageTargetEffect(2), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false + ); + ability2.addTarget(new TargetAnyTarget()); + this.getRightHalfCard().addAbility(ability2); } private SmolderingEgg(final SmolderingEgg card) { diff --git a/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java b/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java index d20600ca9b2..d1c066b0a6a 100644 --- a/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java +++ b/Mage.Sets/src/mage/cards/s/SmolderingWerewolf.java @@ -1,17 +1,17 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.target.common.TargetAnyTarget; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -19,25 +19,33 @@ import java.util.UUID; /** * @author fireshoes */ -public final class SmolderingWerewolf extends CardImpl { +public final class SmolderingWerewolf extends TransformingDoubleFacedCard { public SmolderingWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(3); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.HORROR}, "{2}{R}{R}", + "Erupting Dreadwolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.WEREWOLF}, "" + ); - this.secondSideCardClazz = mage.cards.e.EruptingDreadwolf.class; + // Smoldering Werewolf + this.getLeftHalfCard().setPT(3, 2); // When Smoldering Werewolf enters the battlefield, it deals 1 damage to each of up to two target creatures. Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1, "it")); ability.addTarget(new TargetCreaturePermanent(0, 2)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {4}{R}{R}: Transform Smoldering Werewolf. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{R}{R}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{R}{R}"))); + + // Erupting Dreadwolf + this.getRightHalfCard().setPT(6, 4); + + // Whenever Erupting Dreadwolf attacks, it deals 2 damage to any target. + Ability ability2 = new AttacksTriggeredAbility(new DamageTargetEffect(2, "it"), false); + ability2.addTarget(new TargetAnyTarget()); + this.getRightHalfCard().addAbility(ability2); } private SmolderingWerewolf(final SmolderingWerewolf card) { diff --git a/Mage.Sets/src/mage/cards/s/SolitaryHunter.java b/Mage.Sets/src/mage/cards/s/SolitaryHunter.java index 29ca759d8e4..b79e69fc433 100644 --- a/Mage.Sets/src/mage/cards/s/SolitaryHunter.java +++ b/Mage.Sets/src/mage/cards/s/SolitaryHunter.java @@ -1,10 +1,9 @@ package mage.cards.s; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,22 +12,26 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class SolitaryHunter extends CardImpl { +public final class SolitaryHunter extends TransformingDoubleFacedCard { public SolitaryHunter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARRIOR); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARRIOR, SubType.WEREWOLF}, "{3}{G}", + "One of the Pack", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - - this.secondSideCardClazz = mage.cards.o.OneOfThePack.class; + // Solitary Hunter + this.getLeftHalfCard().setPT(3, 4); // At the beginning of each upkeep, if no spells were cast last turn, transform Solitary Hunter. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // One of the Pack + this.getRightHalfCard().setPT(5, 6); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform One of the Pack. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private SolitaryHunter(final SolitaryHunter card) { diff --git a/Mage.Sets/src/mage/cards/s/SorinOfHouseMarkov.java b/Mage.Sets/src/mage/cards/s/SorinOfHouseMarkov.java index ccbbb37b09e..13eeb95a616 100644 --- a/Mage.Sets/src/mage/cards/s/SorinOfHouseMarkov.java +++ b/Mage.Sets/src/mage/cards/s/SorinOfHouseMarkov.java @@ -1,18 +1,38 @@ package mage.cards.s; -import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.condition.common.YouGainedLifeCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.ControllerGainedLifeCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureTypeTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; import mage.abilities.keyword.ExtortAbility; import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfPostcombatMainTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.FoodToken; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetCreaturePermanent; import mage.watchers.common.PlayerGainedLifeWatcher; import java.util.UUID; @@ -20,33 +40,73 @@ import java.util.UUID; /** * @author Susucr */ -public final class SorinOfHouseMarkov extends CardImpl { +public final class SorinOfHouseMarkov extends TransformingDoubleFacedCard { private static final Condition condition = new YouGainedLifeCondition(ComparisonType.MORE_THAN, 2); private static final Hint hint = new ConditionHint(condition); + private static final FilterPermanent filterWhite = new FilterPermanent("white permanent other than that creature or {this}"); + private static final Condition conditionWhite = new PermanentsOnTheBattlefieldCondition(filterWhite, true); + private static final Hint hintWhite = new ConditionHint(conditionWhite, "you control another white permanent"); + + static { + filterWhite.add(new ColorPredicate(ObjectColor.WHITE)); + filterWhite.add(AnotherPredicate.instance); + filterWhite.add(SorinRavenousNeonatePredicate.instance); + } + public SorinOfHouseMarkov(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE}, "{1}{B}", + "Sorin, Ravenous Neonate", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.SORIN}, "WB" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.power = new MageInt(1); - this.toughness = new MageInt(4); + // Sorin of House Markov + this.getLeftHalfCard().setPT(1, 4); - this.secondSideCardClazz = SorinRavenousNeonate.class; - - // Flying - this.addAbility(LifelinkAbility.getInstance()); + // Lifelink + this.getLeftHalfCard().addAbility(LifelinkAbility.getInstance()); // Extort - this.addAbility(new ExtortAbility()); + this.getLeftHalfCard().addAbility(new ExtortAbility()); // At the beginning of your postcombat main phase, if you gained 3 or more life this turn, exile Sorin of House Markov, then return him to the battlefield transformed under his owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfPostcombatMainTriggeredAbility( + Ability ability = new BeginningOfPostcombatMainTriggeredAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.HE), false - ).withInterveningIf(condition).addHint(hint), new PlayerGainedLifeWatcher()); + ).withInterveningIf(condition).addHint(hint); + ability.addWatcher(new PlayerGainedLifeWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Sorin, Ravenous Neonate + this.getRightHalfCard().setStartingLoyalty(3); + + // Extort + this.getRightHalfCard().addAbility(new ExtortAbility()); + + // +2: Create a Food token. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new CreateTokenEffect(new FoodToken()), 2)); + + // -1: Sorin, Ravenous Neonate deals damage equal to the amount of life you gained this turn to any target. + ability = new LoyaltyAbility( + new DamageTargetEffect(ControllerGainedLifeCount.instance) + .setText("{this} deals damage equal to the amount of life you gained this turn to any target"), + -1 + ); + ability.addTarget(new TargetAnyTarget()); + ability.addWatcher(new PlayerGainedLifeWatcher()); + this.getRightHalfCard().addAbility(ability.addHint(ControllerGainedLifeCount.getHint())); + + // -6: Gain control of target creature. It becomes a Vampire in addition to its other types. Put a lifelink counter on it if you control a white permanent other than that creature or Sorin. + Ability ability2 = new LoyaltyAbility(new GainControlTargetEffect(Duration.EndOfGame), -6); + ability2.addTarget(new TargetCreaturePermanent()); + ability2.addEffect(new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.VAMPIRE, false) + .setText("It becomes a Vampire in addition to its other types")); + ability2.addEffect(new ConditionalOneShotEffect( + new AddCountersTargetEffect(CounterType.LIFELINK.createInstance()), + conditionWhite, "Put a lifelink counter on it if you control a white permanent other than that creature or {this}" + )); + this.getRightHalfCard().addAbility(ability2.addHint(hintWhite)); } private SorinOfHouseMarkov(final SorinOfHouseMarkov card) { @@ -58,3 +118,16 @@ public final class SorinOfHouseMarkov extends CardImpl { return new SorinOfHouseMarkov(this); } } + +enum SorinRavenousNeonatePredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + Ability source = input.getSource(); + Permanent permanent = input.getObject(); + return source != null + && permanent != null + && !permanent.getId().equals(source.getFirstTarget()); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SorinRavenousNeonate.java b/Mage.Sets/src/mage/cards/s/SorinRavenousNeonate.java deleted file mode 100644 index e294dad377c..00000000000 --- a/Mage.Sets/src/mage/cards/s/SorinRavenousNeonate.java +++ /dev/null @@ -1,113 +0,0 @@ -package mage.cards.s; - -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.dynamicvalue.common.ControllerGainedLifeCount; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.continuous.BecomesCreatureTypeTargetEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.hint.ConditionHint; -import mage.abilities.hint.Hint; -import mage.abilities.keyword.ExtortAbility; -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.FilterPermanent; -import mage.filter.predicate.ObjectSourcePlayer; -import mage.filter.predicate.ObjectSourcePlayerPredicate; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.permanent.token.FoodToken; -import mage.target.common.TargetAnyTarget; -import mage.target.common.TargetCreaturePermanent; -import mage.watchers.common.PlayerGainedLifeWatcher; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class SorinRavenousNeonate extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("white permanent other than that creature or {this}"); - private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, true); - private static final Hint hint = new ConditionHint(condition, "you control another white permanent"); - - static { - filter.add(new ColorPredicate(ObjectColor.WHITE)); - filter.add(AnotherPredicate.instance); - filter.add(SorinRavenousNeonatePredicate.instance); - } - - public SorinRavenousNeonate(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.SORIN); - this.setStartingLoyalty(3); - - this.color.setWhite(true); - this.color.setBlack(true); - this.nightCard = true; - - // Extort - this.addAbility(new ExtortAbility()); - - // +2: Create a Food token. - this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new FoodToken()), 2)); - - // -1: Sorin, Ravenous Neonate deals damage equal to the amount of life you gained this turn to any target. - Ability ability = new LoyaltyAbility( - new DamageTargetEffect(ControllerGainedLifeCount.instance) - .setText("{this} deals damage equal to the amount of life you gained this turn to any target"), - -1 - ); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability.addHint(ControllerGainedLifeCount.getHint()), new PlayerGainedLifeWatcher()); - - // -6: Gain control of target creature. It becomes a Vampire in addition to its other types. Put a lifelink counter on it if you control a white permanent other than that creature or Sorin. - ability = new LoyaltyAbility(new GainControlTargetEffect(Duration.EndOfGame), -6); - ability.addTarget(new TargetCreaturePermanent()); - ability.addEffect(new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.VAMPIRE, false) - .setText("It becomes a Vampire in addition to its other types")); - ability.addEffect(new ConditionalOneShotEffect( - new AddCountersTargetEffect(CounterType.LIFELINK.createInstance()), - condition, "Put a lifelink counter on it if you control a white permanent other than that creature or {this}" - )); - this.addAbility(ability.addHint(hint)); - } - - private SorinRavenousNeonate(final SorinRavenousNeonate card) { - super(card); - } - - @Override - public SorinRavenousNeonate copy() { - return new SorinRavenousNeonate(this); - } -} - -enum SorinRavenousNeonatePredicate implements ObjectSourcePlayerPredicate { - instance; - - @Override - public boolean apply(ObjectSourcePlayer input, Game game) { - Ability source = input.getSource(); - Permanent permanent = input.getObject(); - return source != null - && permanent != null - && !permanent.getId().equals(source.getFirstTarget()); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SoulSeizer.java b/Mage.Sets/src/mage/cards/s/SoulSeizer.java index aa0cebb6f39..981e5101fd8 100644 --- a/Mage.Sets/src/mage/cards/s/SoulSeizer.java +++ b/Mage.Sets/src/mage/cards/s/SoulSeizer.java @@ -1,21 +1,24 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.ControlEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.target.Target; import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import mage.target.targetadjustment.ThatPlayerControlsTargetAdjuster; import java.util.UUID; @@ -23,26 +26,36 @@ import java.util.UUID; /** * @author BetaSteward */ -public final class SoulSeizer extends CardImpl { +public final class SoulSeizer extends TransformingDoubleFacedCard { public SoulSeizer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); - this.subtype.add(SubType.SPIRIT); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "{3}{U}{U}", + "Ghastly Haunting", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "U" + ); - this.secondSideCardClazz = mage.cards.g.GhastlyHaunting.class; + // Soul Seizer + this.getLeftHalfCard().setPT(1, 3); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - - this.addAbility(FlyingAbility.getInstance()); + // Flying + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // When Soul Seizer deals combat damage to a player, you may transform it. If you do, attach it to target creature that player controls. - this.addAbility(new TransformAbility()); TriggeredAbility ability = new DealsCombatDamageToAPlayerTriggeredAbility(new SoulSeizerEffect(), true, true); ability.setTriggerPhrase("When {this} deals combat damage to a player, "); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURE)); ability.setTargetAdjuster(new ThatPlayerControlsTargetAdjuster()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Ghastly Haunting + // Enchant creature + Target auraTarget = new TargetCreaturePermanent(); + this.getRightHalfCard().getSpellAbility().addTarget(auraTarget); + this.getRightHalfCard().addAbility(new EnchantAbility(auraTarget)); + + // You control enchanted creature. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new ControlEnchantedEffect())); } private SoulSeizer(final SoulSeizer card) { diff --git a/Mage.Sets/src/mage/cards/s/SoulcipherBoard.java b/Mage.Sets/src/mage/cards/s/SoulcipherBoard.java index 538dcae5506..85b8aadc9c5 100644 --- a/Mage.Sets/src/mage/cards/s/SoulcipherBoard.java +++ b/Mage.Sets/src/mage/cards/s/SoulcipherBoard.java @@ -1,6 +1,7 @@ package mage.cards.s; import mage.abilities.Ability; +import mage.abilities.common.CanBlockOnlyFlyingAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -9,17 +10,15 @@ import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.PutCards; -import mage.constants.TargetController; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.StaticFilters; @@ -28,16 +27,20 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SoulcipherBoard extends CardImpl { +public final class SoulcipherBoard extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.OMEN, ComparisonType.EQUAL_TO, 0); public SoulcipherBoard(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{U}"); - this.secondSideCardClazz = mage.cards.c.CipherboundSpirit.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{U}", + "Cipherbound Spirit", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "U" + ); + // Soulcipher Board // Soulcipher Board enters the battlefield with three omen counters on it. - this.addAbility(new EntersBattlefieldAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.OMEN.createInstance(3)), "with three omen counters on it" )); @@ -47,19 +50,32 @@ public final class SoulcipherBoard extends CardImpl { new LookLibraryAndPickControllerEffect(2, 1, PutCards.GRAVEYARD, PutCards.TOP_ANY), new ManaCostsImpl<>("{1}{U}")); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Whenever a creature card is put into your graveyard from anywhere, remove an omen counter from Soulcipher Board. Then if it has no omen counters on it, transform it. - this.addAbility(new TransformAbility()); - ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility( + Ability ability2 = new PutCardIntoGraveFromAnywhereAllTriggeredAbility( new RemoveCounterSourceEffect(CounterType.OMEN.createInstance()), false, StaticFilters.FILTER_CARD_CREATURE_A, TargetController.YOU ); - ability.addEffect(new ConditionalOneShotEffect( + ability2.addEffect(new ConditionalOneShotEffect( new TransformSourceEffect(), condition, "Then if it has no omen counters on it, transform it" )); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability2); + + // Cipherbound Spirit + this.getRightHalfCard().setPT(3, 2); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Cipherbound Spirit can block only creatures with flying. + this.getRightHalfCard().addAbility(new CanBlockOnlyFlyingAbility()); + + // {3}{U}: Draw two cards, then discard a card. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility( + new DrawDiscardControllerEffect(2, 1), new ManaCostsImpl<>("{3}{U}") + )); } private SoulcipherBoard(final SoulcipherBoard card) { diff --git a/Mage.Sets/src/mage/cards/s/SpellruneHowler.java b/Mage.Sets/src/mage/cards/s/SpellruneHowler.java deleted file mode 100644 index e8c5b16fdcf..00000000000 --- a/Mage.Sets/src/mage/cards/s/SpellruneHowler.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class SpellruneHowler extends CardImpl { - - public SpellruneHowler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.color.setRed(true); - this.nightCard = true; - - // Whenever you cast an instant or sorcery spell, Spellrune Howler gets +2/+2 until end of turn. - this.addAbility(new SpellCastControllerTriggeredAbility( - new BoostSourceEffect(2, 2, Duration.EndOfTurn), - StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false - )); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private SpellruneHowler(final SpellruneHowler card) { - super(card); - } - - @Override - public SpellruneHowler copy() { - return new SpellruneHowler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SpellrunePainter.java b/Mage.Sets/src/mage/cards/s/SpellrunePainter.java index db0d71157e1..b07d114ea56 100644 --- a/Mage.Sets/src/mage/cards/s/SpellrunePainter.java +++ b/Mage.Sets/src/mage/cards/s/SpellrunePainter.java @@ -1,11 +1,11 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.DayboundAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; @@ -16,26 +16,38 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SpellrunePainter extends CardImpl { +public final class SpellrunePainter extends TransformingDoubleFacedCard { public SpellrunePainter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SHAMAN, SubType.WEREWOLF}, "{2}{R}", + "Spellrune Howler", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SHAMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.s.SpellruneHowler.class; + // Spellrune Painter + this.getLeftHalfCard().setPT(2, 3); // Whenever you cast an instant or sorcery spell, Spellrune Painter gets +1/+1 until end of turn. - this.addAbility(new SpellCastControllerTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( new BoostSourceEffect(1, 1, Duration.EndOfTurn), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false )); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Spellrune Howler + this.getRightHalfCard().setPT(3, 4); + + // Whenever you cast an instant or sorcery spell, Spellrune Howler gets +2/+2 until end of turn. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new BoostSourceEffect(2, 2, Duration.EndOfTurn), + StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false + )); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private SpellrunePainter(final SpellrunePainter card) { diff --git a/Mage.Sets/src/mage/cards/s/SpikedCorridorTorturePit.java b/Mage.Sets/src/mage/cards/s/SpikedCorridorTorturePit.java new file mode 100644 index 00000000000..74f6e2e05ba --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpikedCorridorTorturePit.java @@ -0,0 +1,83 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.DamagePlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.token.DevilToken; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SpikedCorridorTorturePit extends RoomCard { + + public SpikedCorridorTorturePit(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{3}{R}", "{3}{R}"); + + // Spiked Corridor + // When you unlock this door, create three 1/1 red Devil creature tokens with "When this token dies, it deals 1 damage to any target." + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility( + new CreateTokenEffect(new DevilToken(), 3), false, true + )); + + // Torture Pit + // If a source you control would deal noncombat damage to an opponent, it deals that much damage plus 2 instead. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new TorturePitEffect())); + } + + private SpikedCorridorTorturePit(final SpikedCorridorTorturePit card) { + super(card); + } + + @Override + public SpikedCorridorTorturePit copy() { + return new SpikedCorridorTorturePit(this); + } +} + +class TorturePitEffect extends ReplacementEffectImpl { + + TorturePitEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "if a source you control would deal noncombat damage to an opponent, " + + "it deals that much damage plus 2 instead"; + } + + private TorturePitEffect(final TorturePitEffect effect) { + super(effect); + } + + @Override + public TorturePitEffect copy() { + return new TorturePitEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return !((DamagePlayerEvent) event).isCombatDamage() + && source.isControlledBy(game.getControllerId(event.getSourceId())) + && game.getOpponents(source.getControllerId()).contains(event.getTargetId()); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.overflowInc(event.getAmount(), 2)); + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java b/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java deleted file mode 100644 index 49d9508989b..00000000000 --- a/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java +++ /dev/null @@ -1,56 +0,0 @@ -package mage.cards.s; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.RemoveFromCombatTargetEffect; -import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.mana.ColorlessManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterOpponentsCreaturePermanent; -import mage.filter.predicate.permanent.AttackingPredicate; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class SpiresOfOrazca extends CardImpl { - - private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("attacking creature an opponent controls"); - - static { - filter.add(AttackingPredicate.instance); - } - - public SpiresOfOrazca(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.nightCard = true; - - // {T}: Add {C}. - this.addAbility(new ColorlessManaAbility()); - - // {T}: Untap target attacking creature an opponent controls and remove it from combat. - Ability ability = new SimpleActivatedAbility( - new UntapTargetEffect() - .setText("Untap target attacking creature an opponent controls"), - new TapSourceCost() - ); - ability.addEffect(new RemoveFromCombatTargetEffect().setText("and remove it from combat")); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - } - - private SpiresOfOrazca(final SpiresOfOrazca card) { - super(card); - } - - @Override - public SpiresOfOrazca copy() { - return new SpiresOfOrazca(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SpitfireBastion.java b/Mage.Sets/src/mage/cards/s/SpitfireBastion.java deleted file mode 100644 index 89482efbd3e..00000000000 --- a/Mage.Sets/src/mage/cards/s/SpitfireBastion.java +++ /dev/null @@ -1,48 +0,0 @@ - -package mage.cards.s; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.mana.RedManaAbility; -import mage.constants.SuperType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.target.common.TargetAnyTarget; - -/** - * - * @author TheElk801 - */ -public final class SpitfireBastion extends CardImpl { - - public SpitfireBastion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - - // {T}: Add {R}. - this.addAbility(new RedManaAbility()); - - // {2}{R}, {T}: Spitfire Bastion deals 3 damage to any target. - Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(3), new TapSourceCost()); - ability.addCost(new ManaCostsImpl<>("{2}{R}")); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); - } - - private SpitfireBastion(final SpitfireBastion card) { - super(card); - } - - @Override - public SpitfireBastion copy() { - return new SpitfireBastion(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SquallGunbladeDuelist.java b/Mage.Sets/src/mage/cards/s/SquallGunbladeDuelist.java new file mode 100644 index 00000000000..b0534bc5c43 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SquallGunbladeDuelist.java @@ -0,0 +1,144 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.AttacksPlayerWithCreaturesTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SquallGunbladeDuelist extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(SquallGunbladeDuelistPredicate.instance); + } + + public SquallGunbladeDuelist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.MERCENARY); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // As Squall enters, choose a number. + this.addAbility(new AsEntersBattlefieldAbility(new SquallGunbladeDuelistChooseEffect())); + + // Whenever one or more creatures attack one of your opponents, if any of those creatures have power or toughness equal to the chosen number, Squall deals damage equal to its power to defending player. + this.addAbility(new AttacksPlayerWithCreaturesTriggeredAbility( + new SquallGunbladeDuelistDamageEffect(), 1, + filter, SetTargetPointer.PLAYER, true + ).setTriggerPhrase("Whenever one or more creatures attack one of your opponents, " + + "if any of those creatures have power or toughness equal to the chosen number, ")); + } + + private SquallGunbladeDuelist(final SquallGunbladeDuelist card) { + super(card); + } + + @Override + public SquallGunbladeDuelist copy() { + return new SquallGunbladeDuelist(this); + } +} + +enum SquallGunbladeDuelistPredicate implements ObjectSourcePlayerPredicate { + instance; + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + Integer number = (Integer) game + .getState() + .getValue(CardUtil.getObjectZoneString( + "chosenNumber", input.getSource().getId(), game, + input.getSource().getStackMomentSourceZCC(), true + )); + return number != null + && (input.getObject().getPower().getValue() == number + || input.getObject().getToughness().getValue() == number); + } +} + +class SquallGunbladeDuelistChooseEffect extends OneShotEffect { + + SquallGunbladeDuelistChooseEffect() { + super(Outcome.Benefit); + staticText = "choose a number"; + } + + private SquallGunbladeDuelistChooseEffect(final SquallGunbladeDuelistChooseEffect effect) { + super(effect); + } + + @Override + public SquallGunbladeDuelistChooseEffect copy() { + return new SquallGunbladeDuelistChooseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + int number = player.getAmount(0, Integer.MAX_VALUE, "Choose a number", source, game); + game.getState().setValue(CardUtil.getObjectZoneString( + "chosenNumber", source.getId(), game, + source.getStackMomentSourceZCC(), false + ), number); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent != null) { + permanent.addInfo("chosen number", "Chosen Number: " + number + "", game); + game.informPlayers(permanent.getLogName() + ", chosen number: " + number); + } + return true; + } +} + +class SquallGunbladeDuelistDamageEffect extends OneShotEffect { + + SquallGunbladeDuelistDamageEffect() { + super(Outcome.Benefit); + staticText = "{this} deals damage equal to its power to defending player"; + } + + private SquallGunbladeDuelistDamageEffect(final SquallGunbladeDuelistDamageEffect effect) { + super(effect); + } + + @Override + public SquallGunbladeDuelistDamageEffect copy() { + return new SquallGunbladeDuelistDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + Permanent permanent = source.getSourcePermanentOrLKI(game); + return player != null + && permanent != null + && player.damage(permanent.getPower().getValue(), permanent.getId(), source, game) > 0; + } +} diff --git a/Mage.Sets/src/mage/cards/s/StalkingPredator.java b/Mage.Sets/src/mage/cards/s/StalkingPredator.java deleted file mode 100644 index 41a12f42f97..00000000000 --- a/Mage.Sets/src/mage/cards/s/StalkingPredator.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.keyword.MenaceAbility; -import mage.abilities.keyword.NightboundAbility; -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 StalkingPredator extends CardImpl { - - public StalkingPredator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setBlack(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private StalkingPredator(final StalkingPredator card) { - super(card); - } - - @Override - public StalkingPredator copy() { - return new StalkingPredator(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/StalkingVampire.java b/Mage.Sets/src/mage/cards/s/StalkingVampire.java deleted file mode 100644 index 0fc17107c6a..00000000000 --- a/Mage.Sets/src/mage/cards/s/StalkingVampire.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class StalkingVampire extends CardImpl { - - public StalkingVampire(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.VAMPIRE); - this.color.setBlack(true); - - this.nightCard = true; - - this.power = new MageInt(5); - this.toughness = new MageInt(5); - - // At the beginning of your upkeep, you may pay {2}{B}{B}. If you do, transform Stalking Vampire. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid( - new TransformSourceEffect(), - new ManaCostsImpl<>("{2}{B}{B}") - ))); - } - - private StalkingVampire(final StalkingVampire card) { - super(card); - } - - @Override - public StalkingVampire copy() { - return new StalkingVampire(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/StarscreamPowerHungry.java b/Mage.Sets/src/mage/cards/s/StarscreamPowerHungry.java index 9000a352fdb..97050e68e24 100644 --- a/Mage.Sets/src/mage/cards/s/StarscreamPowerHungry.java +++ b/Mage.Sets/src/mage/cards/s/StarscreamPowerHungry.java @@ -1,17 +1,19 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.BecomesMonarchSourceControllerTriggeredAbility; import mage.abilities.common.CombatDamageDealtToYouTriggeredAbility; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DrawCardControllerTriggeredAbility; +import mage.abilities.condition.common.MonarchIsNotSetCondition; import mage.abilities.condition.common.MonarchIsSourceControllerCondition; +import mage.abilities.effects.common.BecomesMonarchTargetEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.common.MonarchHint; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.*; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; @@ -22,31 +24,57 @@ import java.util.UUID; /** * @author Susucr */ -public final class StarscreamPowerHungry extends CardImpl { +public final class StarscreamPowerHungry extends TransformingDoubleFacedCard { public StarscreamPowerHungry(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{3}{B}", + "Starscream, Seeker Leader", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "B" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.s.StarscreamSeekerLeader.class; + // Starscream, Power Hungry + this.getLeftHalfCard().setPT(2, 3); // More Than Meets the Eye {2}{B} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{B}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{B}")); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Whenever you draw a card, if you're the monarch, target opponent loses 2 life. Ability ability = new DrawCardControllerTriggeredAbility(new LoseLifeTargetEffect(2), false) .withInterveningIf(MonarchIsSourceControllerCondition.instance); ability.addTarget(new TargetOpponent()); - this.addAbility(ability.addHint(MonarchHint.instance)); + this.getLeftHalfCard().addAbility(ability.addHint(MonarchHint.instance)); // Whenever one or more creatures deal combat damage to you, convert Starscream. - this.addAbility(new CombatDamageDealtToYouTriggeredAbility( + this.getLeftHalfCard().addAbility(new CombatDamageDealtToYouTriggeredAbility( + new TransformSourceEffect().setText("convert {this}") + )); + + // Starscream, Seeker Leader + this.getRightHalfCard().setPT(2, 3); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // Whenever Starscream deals combat damage to a player, if there is no monarch, that player becomes the monarch. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + new BecomesMonarchTargetEffect().setText("that player becomes the monarch"), false, true + ).withInterveningIf(MonarchIsNotSetCondition.instance).addHint(MonarchHint.instance)); + + // Whenever you become the monarch, convert Starscream. + this.getRightHalfCard().addAbility(new BecomesMonarchSourceControllerTriggeredAbility( new TransformSourceEffect().setText("convert {this}") )); } diff --git a/Mage.Sets/src/mage/cards/s/StarscreamSeekerLeader.java b/Mage.Sets/src/mage/cards/s/StarscreamSeekerLeader.java deleted file mode 100644 index e8f24856628..00000000000 --- a/Mage.Sets/src/mage/cards/s/StarscreamSeekerLeader.java +++ /dev/null @@ -1,68 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.common.BecomesMonarchSourceControllerTriggeredAbility; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.condition.common.MonarchIsNotSetCondition; -import mage.abilities.effects.common.BecomesMonarchTargetEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.hint.common.MonarchHint; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.LivingMetalAbility; -import mage.abilities.keyword.MenaceAbility; -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 Susucr - */ -public final class StarscreamSeekerLeader extends CardImpl { - - public StarscreamSeekerLeader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.VEHICLE); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // Whenever Starscream deals combat damage to a player, if there is no monarch, that player becomes the monarch. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( - new BecomesMonarchTargetEffect().setText("that player becomes the monarch"), false, true - ).withInterveningIf(MonarchIsNotSetCondition.instance).addHint(MonarchHint.instance)); - - // Whenever you become the monarch, convert Starscream. - this.addAbility(new BecomesMonarchSourceControllerTriggeredAbility( - new TransformSourceEffect().setText("convert {this}") - )); - } - - private StarscreamSeekerLeader(final StarscreamSeekerLeader card) { - super(card); - } - - @Override - public StarscreamSeekerLeader copy() { - return new StarscreamSeekerLeader(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/StonewingAntagonizer.java b/Mage.Sets/src/mage/cards/s/StonewingAntagonizer.java deleted file mode 100644 index 31f18cbdc2b..00000000000 --- a/Mage.Sets/src/mage/cards/s/StonewingAntagonizer.java +++ /dev/null @@ -1,40 +0,0 @@ - -package mage.cards.s; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -/** - * - * @author fireshoes - */ -public final class StonewingAntagonizer extends CardImpl { - - public StonewingAntagonizer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},""); - this.subtype.add(SubType.GARGOYLE); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(4); - this.toughness = new MageInt(2); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - } - - private StonewingAntagonizer(final StonewingAntagonizer card) { - super(card); - } - - @Override - public StonewingAntagonizer copy() { - return new StonewingAntagonizer(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/StormTheVault.java b/Mage.Sets/src/mage/cards/s/StormTheVault.java index a76502a82c5..b901243a79d 100644 --- a/Mage.Sets/src/mage/cards/s/StormTheVault.java +++ b/Mage.Sets/src/mage/cards/s/StormTheVault.java @@ -1,18 +1,21 @@ package mage.cards.s; +import mage.Mana; import mage.abilities.common.OneOrMoreCombatDamagePlayerTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.mana.DynamicManaEffect; import mage.abilities.hint.common.ArtifactYouControlHint; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.AnyColorManaAbility; +import mage.abilities.mana.SimpleManaAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.common.FilterControlledArtifactPermanent; import mage.game.permanent.token.TreasureToken; @@ -21,26 +24,34 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class StormTheVault extends CardImpl { +public final class StormTheVault extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledArtifactPermanent("you control five or more artifacts"), ComparisonType.MORE_THAN, 4 ); public StormTheVault(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{R}"); - - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.v.VaultOfCatlacan.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{2}{U}{R}", + "Vault of Catlacan", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); // Whenever one or more creatures you control deal combat damage to a player, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color." - this.addAbility(new OneOrMoreCombatDamagePlayerTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + this.getLeftHalfCard().addAbility(new OneOrMoreCombatDamagePlayerTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); // At the beginning of your end step, if you control five or more artifacts, transform Storm the Vault. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()) + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()) .withInterveningIf(condition).addHint(ArtifactYouControlHint.instance)); + + // Vault of Catlacan + // {T}: Add one mana of any color. + this.getRightHalfCard().addAbility(new AnyColorManaAbility()); + + // {T}: Add {U} for each artifact you control. + this.getRightHalfCard().addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, + new DynamicManaEffect(Mana.BlueMana(1), ArtifactYouControlCount.instance), + new TapSourceCost()).addHint(ArtifactYouControlHint.instance)); } private StormTheVault(final StormTheVault card) { diff --git a/Mage.Sets/src/mage/cards/s/StranglingGrasp.java b/Mage.Sets/src/mage/cards/s/StranglingGrasp.java deleted file mode 100644 index e8b2b3ab4ab..00000000000 --- a/Mage.Sets/src/mage/cards/s/StranglingGrasp.java +++ /dev/null @@ -1,113 +0,0 @@ -package mage.cards.s; - -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.keyword.EnchantAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.TargetController; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; -import mage.filter.common.FilterNonlandPermanent; -import mage.filter.predicate.permanent.CanBeSacrificedPredicate; -import mage.game.Controllable; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetPermanent; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class StranglingGrasp extends CardImpl { - - private static final FilterPermanent filter - = new FilterCreatureOrPlaneswalkerPermanent("creature or planeswalker an opponent controls"); - - static { - filter.add(TargetController.OPPONENT.getControllerPredicate()); - } - - public StranglingGrasp(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.AURA); - this.color.setBlack(true); - this.nightCard = true; - - // Enchant creature or planeswalker an opponent controls - TargetPermanent auraTarget = new TargetPermanent(filter); - this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - this.addAbility(new EnchantAbility(auraTarget)); - - // At the beginning of your upkeep, enchanted permanent's controller sacrifices a nonland permanent and loses 1 life. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new StranglingGraspEffect())); - } - - private StranglingGrasp(final StranglingGrasp card) { - super(card); - } - - @Override - public StranglingGrasp copy() { - return new StranglingGrasp(this); - } -} - -class StranglingGraspEffect extends OneShotEffect { - - private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanent you control"); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - filter.add(CanBeSacrificedPredicate.instance); - } - - StranglingGraspEffect() { - super(Outcome.Benefit); - staticText = "enchanted permanent's controller sacrifices a nonland permanent, then that player loses 1 life"; - } - - private StranglingGraspEffect(final StranglingGraspEffect effect) { - super(effect); - } - - @Override - public StranglingGraspEffect copy() { - return new StranglingGraspEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = Optional - .ofNullable(source.getSourcePermanentOrLKI(game)) - .map(Permanent::getAttachedTo) - .map(game::getPermanentOrLKIBattlefield) - .map(Controllable::getControllerId) - .map(game::getPlayer) - .orElse(null); - if (player == null) { - return false; - } - TargetPermanent target = new TargetPermanent(filter); - target.withNotTarget(true); - if (target.canChoose(player.getId(), source, game)) { - player.choose(outcome, target, source, game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - permanent.sacrifice(source, game); - } - } - player.loseLife(1, game, source, false); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/s/StrionicResonator.java b/Mage.Sets/src/mage/cards/s/StrionicResonator.java index c521659aad9..72a9a53b6c0 100644 --- a/Mage.Sets/src/mage/cards/s/StrionicResonator.java +++ b/Mage.Sets/src/mage/cards/s/StrionicResonator.java @@ -8,11 +8,7 @@ import mage.abilities.effects.common.CopyTargetStackObjectEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TargetController; -import mage.filter.FilterStackObject; -import mage.filter.predicate.Predicate; -import mage.game.Game; -import mage.game.stack.StackObject; +import mage.filter.StaticFilters; import mage.target.TargetStackObject; import java.util.UUID; @@ -22,20 +18,13 @@ import java.util.UUID; */ public final class StrionicResonator extends CardImpl { - private static final FilterStackObject filter = new FilterStackObject("triggered ability you control"); - - static { - filter.add(StrionicResonatorPredicate.instance); - filter.add(TargetController.YOU.getControllerPredicate()); - } - public StrionicResonator(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // {2}, {T}: Copy target triggered ability you control. You may choose new targets for the copy. Ability ability = new SimpleActivatedAbility(new CopyTargetStackObjectEffect(), new ManaCostsImpl<>("{2}")); ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetStackObject(filter)); + ability.addTarget(new TargetStackObject(StaticFilters.FILTER_CONTROLLED_TRIGGERED_ABILITY)); this.addAbility(ability); } @@ -48,12 +37,3 @@ public final class StrionicResonator extends CardImpl { return new StrionicResonator(this); } } - -enum StrionicResonatorPredicate implements Predicate { - instance; - - @Override - public boolean apply(StackObject input, Game game) { - return input instanceof Ability && ((Ability) input).isTriggeredAbility(); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SunBlessedGuardian.java b/Mage.Sets/src/mage/cards/s/SunBlessedGuardian.java index 4a19774bc99..07a58693e57 100644 --- a/Mage.Sets/src/mage/cards/s/SunBlessedGuardian.java +++ b/Mage.Sets/src/mage/cards/s/SunBlessedGuardian.java @@ -1,34 +1,46 @@ package mage.cards.s; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.SubType; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; import java.util.UUID; /** * @author TheElk801 */ -public final class SunBlessedGuardian extends CardImpl { +public final class SunBlessedGuardian extends TransformingDoubleFacedCard { public SunBlessedGuardian(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CLERIC}, "{1}{W}", + "Furnace-Blessed Conqueror", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.CLERIC}, "WR" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.f.FurnaceBlessedConqueror.class; + // Sun-Blessed Guardian + this.getLeftHalfCard().setPT(2, 2); // {5}{R/P}: Transform Sun-Blessed Guardian. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{R/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{R/P}"))); + + // Furnace-Blessed Conqueror + this.getRightHalfCard().setPT(3, 3); + + // Whenever Furnace-Blessed Conqueror attacks, create a tapped and attacking token that's a copy of it. Put a +1/+1 counter on that token for each +1/+1 counter on Furnace-Blessed Conqueror. Sacrifice that token at the beginning of the next end step. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new SunBlessedGuardianEffect())); } private SunBlessedGuardian(final SunBlessedGuardian card) { @@ -40,3 +52,44 @@ public final class SunBlessedGuardian extends CardImpl { return new SunBlessedGuardian(this); } } + +class SunBlessedGuardianEffect extends OneShotEffect { + + SunBlessedGuardianEffect() { + super(Outcome.Benefit); + staticText = "create a tapped and attacking token that's a copy of it. " + + "Put a +1/+1 counter on that token for each +1/+1 counter on {this}. " + + "Sacrifice that token at the beginning of the next end step"; + } + + private SunBlessedGuardianEffect(final SunBlessedGuardianEffect effect) { + super(effect); + } + + @Override + public SunBlessedGuardianEffect copy() { + return new SunBlessedGuardianEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent == null) { + return false; + } + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect( + null, null, false, 1, true, true + ); + effect.setSavedPermanent(permanent); + effect.apply(game, source); + effect.sacrificeTokensCreatedAtNextEndStep(game, source); + int counters = permanent.getCounters(game).getCount(CounterType.P1P1); + if (counters < 1) { + return true; + } + for (Permanent token : effect.getAddedPermanents()) { + token.addCounters(CounterType.P1P1.createInstance(counters), source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SunbirdEffigy.java b/Mage.Sets/src/mage/cards/s/SunbirdEffigy.java deleted file mode 100644 index f037f12199c..00000000000 --- a/Mage.Sets/src/mage/cards/s/SunbirdEffigy.java +++ /dev/null @@ -1,192 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.Mana; -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.abilities.effects.mana.ManaEffect; -import mage.abilities.hint.Hint; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.VigilanceAbility; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.ExileZone; -import mage.game.Game; -import mage.util.CardUtil; - -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * @author TheElk801 - */ -public final class SunbirdEffigy extends CardImpl { - - public SunbirdEffigy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.BIRD); - this.subtype.add(SubType.CONSTRUCT); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // Sunbird Effigy's power and toughness are each equal to the number of colors among the exiled cards used to craft it. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, new SetBasePowerToughnessSourceEffect(SunbirdEffigyValue.instance) - ).addHint(SunbirdEffigyHint.instance)); - - // {T}: For each color among the exiled cards used to craft Sunbird Effigy, add one mana of that color. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new SunbirdEffigyEffect(), new TapSourceCost())); - } - - private SunbirdEffigy(final SunbirdEffigy card) { - super(card); - } - - @Override - public SunbirdEffigy copy() { - return new SunbirdEffigy(this); - } -} - -enum SunbirdEffigyValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - return Optional - .ofNullable(getColor(game, sourceAbility)) - .filter(Objects::nonNull) - .map(ObjectColor::getColorCount) - .orElse(0); - } - - @Override - public SunbirdEffigyValue copy() { - return this; - } - - @Override - public String getMessage() { - return "colors among the exiled cards used to craft it"; - } - - @Override - public String toString() { - return "1"; - } - - static ObjectColor getColor(Game game, Ability source) { - ExileZone exileZone = game - .getExile() - .getExileZone(CardUtil.getExileZoneId( - game, - source.getSourceId(), - game.getState().getZoneChangeCounter(source.getSourceId()) - 2 - )); - return exileZone == null ? null : exileZone - .getCards(game) - .stream() - .map(card -> card.getColor(game)) - .reduce(new ObjectColor(), ObjectColor::union); - } -} - -enum SunbirdEffigyHint implements Hint { - instance; - - @Override - public String getText(Game game, Ability ability) { - ObjectColor color = SunbirdEffigyValue.getColor(game, ability); - if (color == null) { - return null; - } - if (color.isColorless()) { - return "No colors among exiled cards."; - } - return color - .getColors() - .stream() - .map(ObjectColor::getDescription) - .collect(Collectors.joining(", ", "Colors among exiled cards: ", "")); - } - - @Override - public Hint copy() { - return this; - } -} - -class SunbirdEffigyEffect extends ManaEffect { - - SunbirdEffigyEffect() { - super(); - staticText = "for each color among the exiled cards used to craft {this}, add one mana of that color"; - } - - private SunbirdEffigyEffect(final SunbirdEffigyEffect effect) { - super(effect); - } - - @Override - public SunbirdEffigyEffect copy() { - return new SunbirdEffigyEffect(this); - } - - @Override - public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); - if (game == null) { - return mana; - } - ExileZone exileZone = game - .getExile() - .getExileZone(CardUtil.getExileZoneId(game, source, -2)); - if (exileZone == null) { - return mana; - } - ObjectColor color = exileZone - .getCards(game) - .stream() - .map(card -> card.getColor(game)) - .reduce(new ObjectColor(), ObjectColor::union); - if (color.isWhite()) { - mana.increaseWhite(); - } - if (color.isBlue()) { - mana.increaseBlue(); - } - if (color.isBlack()) { - mana.increaseBlack(); - } - if (color.isRed()) { - mana.increaseRed(); - } - if (color.isGreen()) { - mana.increaseGreen(); - } - return mana; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SunbirdStandard.java b/Mage.Sets/src/mage/cards/s/SunbirdStandard.java index 0f82aa34aa4..55c7f85665b 100644 --- a/Mage.Sets/src/mage/cards/s/SunbirdStandard.java +++ b/Mage.Sets/src/mage/cards/s/SunbirdStandard.java @@ -1,30 +1,76 @@ package mage.cards.s; +import mage.Mana; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +import mage.abilities.effects.mana.ManaEffect; +import mage.abilities.hint.Hint; import mage.abilities.keyword.CraftAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.util.CardUtil; +import java.util.Objects; +import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; /** * @author TheElk801 */ -public final class SunbirdStandard extends CardImpl { +public final class SunbirdStandard extends TransformingDoubleFacedCard { public SunbirdStandard(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); - this.secondSideCardClazz = mage.cards.s.SunbirdEffigy.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{3}", + "Sunbird Effigy", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.BIRD, SubType.CONSTRUCT}, "" + ); // {T}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); + this.getLeftHalfCard().addAbility(new AnyColorManaAbility()); // Craft with one or more {5} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{5}", "one or more", "other permanents " + "you control and/or cards in your graveyard", 1, Integer.MAX_VALUE )); + + // Sunbird Effigy + this.getRightHalfCard().setPT(0, 0); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // Sunbird Effigy's power and toughness are each equal to the number of colors among the exiled cards used to craft it. + this.getRightHalfCard().addAbility(new SimpleStaticAbility( + Zone.ALL, new SetBasePowerToughnessSourceEffect(SunbirdEffigyValue.instance) + ).addHint(SunbirdEffigyHint.instance)); + + // {T}: For each color among the exiled cards used to craft Sunbird Effigy, add one mana of that color. + this.getRightHalfCard().addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new SunbirdEffigyEffect(), new TapSourceCost())); } private SunbirdStandard(final SunbirdStandard card) { @@ -36,3 +82,132 @@ public final class SunbirdStandard extends CardImpl { return new SunbirdStandard(this); } } + +enum SunbirdEffigyValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return Optional + .ofNullable(getColor(game, sourceAbility)) + .filter(Objects::nonNull) + .map(ObjectColor::getColorCount) + .orElse(0); + } + + @Override + public SunbirdEffigyValue copy() { + return this; + } + + @Override + public String getMessage() { + return "colors among the exiled cards used to craft it"; + } + + @Override + public String toString() { + return "1"; + } + + static ObjectColor getColor(Game game, Ability source) { + Card sourceCard = game.getCard(source.getSourceId()); + if (sourceCard == null) { + return null; + } + ExileZone exileZone = game + .getExile() + .getExileZone(CardUtil.getExileZoneId( + game, + sourceCard.getMainCard().getId(), + sourceCard.getMainCard().getZoneChangeCounter(game) - 1 + )); + return exileZone == null ? null : exileZone + .getCards(game) + .stream() + .map(card -> card.getColor(game)) + .reduce(new ObjectColor(), ObjectColor::union); + } +} + +enum SunbirdEffigyHint implements Hint { + instance; + + @Override + public String getText(Game game, Ability ability) { + ObjectColor color = SunbirdEffigyValue.getColor(game, ability); + if (color == null) { + return null; + } + if (color.isColorless()) { + return "No colors among exiled cards."; + } + return color + .getColors() + .stream() + .map(ObjectColor::getDescription) + .collect(Collectors.joining(", ", "Colors among exiled cards: ", "")); + } + + @Override + public Hint copy() { + return this; + } +} + +class SunbirdEffigyEffect extends ManaEffect { + + SunbirdEffigyEffect() { + super(); + staticText = "for each color among the exiled cards used to craft {this}, add one mana of that color"; + } + + private SunbirdEffigyEffect(final SunbirdEffigyEffect effect) { + super(effect); + } + + @Override + public SunbirdEffigyEffect copy() { + return new SunbirdEffigyEffect(this); + } + + @Override + public Mana produceMana(Game game, Ability source) { + Mana mana = new Mana(); + if (game == null) { + return mana; + } + Card sourceCard = game.getCard(source.getSourceId()); + if (sourceCard == null) { + return mana; + } + ExileZone exileZone = game + .getExile() + .getExileZone(CardUtil.getExileZoneId(game, sourceCard.getMainCard().getId(), + sourceCard.getMainCard().getZoneChangeCounter(game) - 1)); + if (exileZone == null) { + return mana; + } + ObjectColor color = exileZone + .getCards(game) + .stream() + .map(card -> card.getColor(game)) + .reduce(new ObjectColor(), ObjectColor::union); + if (color.isWhite()) { + mana.increaseWhite(); + } + if (color.isBlue()) { + mana.increaseBlue(); + } + if (color.isBlack()) { + mana.increaseBlack(); + } + if (color.isRed()) { + mana.increaseRed(); + } + if (color.isGreen()) { + mana.increaseGreen(); + } + return mana; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SuperSkrull.java b/Mage.Sets/src/mage/cards/s/SuperSkrull.java new file mode 100644 index 00000000000..3786fc5d88b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SuperSkrull.java @@ -0,0 +1,71 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.FlyingAbility; +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.game.permanent.token.WallColorlessToken; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SuperSkrull extends CardImpl { + + public SuperSkrull(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.SKRULL); + this.subtype.add(SubType.SHAPESHIFTER); + this.subtype.add(SubType.VILLAIN); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {2}{W}: Create a 0/4 colorless Wall creature token with defender. + this.addAbility(new SimpleActivatedAbility( + new CreateTokenEffect(new WallColorlessToken()), new ManaCostsImpl<>("{2}{W}") + )); + + // {3}{G}: Super-Skrull gets +4/+4 until end of turn. + this.addAbility(new SimpleActivatedAbility( + new BoostSourceEffect(4, 4, Duration.EndOfTurn), new ManaCostsImpl<>("{3}{G}") + )); + + // {4}{R}: Super-Skrull deals 4 damage to target creature. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(4), new ManaCostsImpl<>("{4}{R}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // {5}{U}: Target player draws four cards. + ability = new SimpleActivatedAbility(new DrawCardTargetEffect(4), new ManaCostsImpl<>("{5}{U}")); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + private SuperSkrull(final SuperSkrull card) { + super(card); + } + + @Override + public SuperSkrull copy() { + return new SuperSkrull(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SurgicalSuiteHospitalRoom.java b/Mage.Sets/src/mage/cards/s/SurgicalSuiteHospitalRoom.java index 05814b89827..962e1feb9d8 100644 --- a/Mage.Sets/src/mage/cards/s/SurgicalSuiteHospitalRoom.java +++ b/Mage.Sets/src/mage/cards/s/SurgicalSuiteHospitalRoom.java @@ -6,9 +6,7 @@ import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffec import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardSetInfo; import mage.cards.RoomCard; -import mage.constants.CardType; import mage.constants.ComparisonType; -import mage.constants.SpellAbilityType; import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.FilterCard; @@ -20,10 +18,10 @@ import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; /** - * * @author oscscull */ public final class SurgicalSuiteHospitalRoom extends RoomCard { + private static final FilterCard filter = new FilterCreatureCard( "creature card with mana value 3 or less from your graveyard"); @@ -41,8 +39,7 @@ public final class SurgicalSuiteHospitalRoom extends RoomCard { // Enchantment -- Room // Whenever you attack, put a +1/+1 counter on target attacking creature. super(ownerId, setInfo, - new CardType[] { CardType.ENCHANTMENT }, - "{1}{W}", "{3}{W}", SpellAbilityType.SPLIT); + "{1}{W}", "{3}{W}"); this.subtype.add(SubType.ROOM); // Left half ability - "When you unlock this door, return target creature card with mana value 3 or less from your graveyard to the battlefield." diff --git a/Mage.Sets/src/mage/cards/s/SuspiciousStowaway.java b/Mage.Sets/src/mage/cards/s/SuspiciousStowaway.java index a72eb131ce4..d06b0b02f89 100644 --- a/Mage.Sets/src/mage/cards/s/SuspiciousStowaway.java +++ b/Mage.Sets/src/mage/cards/s/SuspiciousStowaway.java @@ -1,12 +1,13 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.keyword.CantBeBlockedSourceAbility; import mage.abilities.keyword.DayboundAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -15,28 +16,42 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SuspiciousStowaway extends CardImpl { +public final class SuspiciousStowaway extends TransformingDoubleFacedCard { public SuspiciousStowaway(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ROGUE, SubType.WEREWOLF}, "{1}{U}", + "Seafaring Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ROGUE); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.s.SeafaringWerewolf.class; + // Suspicious Stowaway + this.getLeftHalfCard().setPT(1, 1); // Suspicious Stowaway can't be blocked. - this.addAbility(new CantBeBlockedSourceAbility()); + this.getLeftHalfCard().addAbility(new CantBeBlockedSourceAbility()); // Whenever Suspicious Stowaway deals combat damage to a player, draw a card, then discard a card. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + this.getLeftHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( new DrawDiscardControllerEffect(1, 1), false )); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Seafaring Werewolf + this.getRightHalfCard().setPT(2, 1); + + // Seafaring Werewolf can't be blocked. + this.getRightHalfCard().addAbility(new CantBeBlockedSourceAbility()); + + // Whenever Seafaring Werewolf deals combat damage to a player, draw a card. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + new DrawCardSourceControllerEffect(1), false + )); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private SuspiciousStowaway(final SuspiciousStowaway card) { diff --git a/Mage.Sets/src/mage/cards/s/SwordCoastSerpent.java b/Mage.Sets/src/mage/cards/s/SwordCoastSerpent.java index 1a12aa1277a..5abbfe7fad8 100644 --- a/Mage.Sets/src/mage/cards/s/SwordCoastSerpent.java +++ b/Mage.Sets/src/mage/cards/s/SwordCoastSerpent.java @@ -1,9 +1,8 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; import mage.abilities.decorator.ConditionalRestrictionEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; @@ -11,13 +10,8 @@ import mage.cards.AdventureCard; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.game.Game; -import mage.game.stack.Spell; import mage.target.common.TargetCreaturePermanent; -import mage.watchers.common.SpellsCastWatcher; -import java.util.List; -import java.util.Objects; import java.util.UUID; /** @@ -35,9 +29,9 @@ public final class SwordCoastSerpent extends AdventureCard { // Sword Coast Serpent can't be blocked as long as you've cast a noncreature spell this turn. this.addAbility(new SimpleStaticAbility(new ConditionalRestrictionEffect( - new CantBeBlockedSourceEffect(), SwordCoastSerpentCondition.instance, + new CantBeBlockedSourceEffect(), CastNoncreatureSpellThisTurnCondition.instance, "{this} can't be blocked as long as you've cast a noncreature spell this turn" - ))); + )).addHint(CastNoncreatureSpellThisTurnCondition.getHint())); // Capsizing Wave // Return target creature to its owner's hand. @@ -56,20 +50,3 @@ public final class SwordCoastSerpent extends AdventureCard { return new SwordCoastSerpent(this); } } - -enum SwordCoastSerpentCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class); - if (watcher == null) { - return false; - } - List spells = watcher.getSpellsCastThisTurn(source.getControllerId()); - return spells != null && spells - .stream() - .filter(Objects::nonNull) - .anyMatch(spell -> !spell.isCreature(game)); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SyggWanderbrineShield.java b/Mage.Sets/src/mage/cards/s/SyggWanderbrineShield.java deleted file mode 100644 index 23165237f4d..00000000000 --- a/Mage.Sets/src/mage/cards/s/SyggWanderbrineShield.java +++ /dev/null @@ -1,69 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.CantBeBlockedSourceAbility; -import mage.abilities.keyword.ProtectionAbility; -import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -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.predicate.Predicates; -import mage.filter.predicate.mageobject.ColorlessPredicate; -import mage.target.common.TargetControlledCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class SyggWanderbrineShield extends CardImpl { - - private static final FilterCard filter = new FilterCard("each color"); - - static { - filter.add(Predicates.not(ColorlessPredicate.instance)); - } - - public SyggWanderbrineShield(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.MERFOLK); - this.subtype.add(SubType.ROGUE); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setWhite(true); - this.nightCard = true; - - // Sygg can't be blocked. - this.addAbility(new CantBeBlockedSourceAbility()); - - // Whenever this creature transforms into Sygg, Wanderbrine Shield, target creature you control gains protection from each color until your next turn. - Ability ability = new TransformIntoSourceTriggeredAbility(new GainAbilityTargetEffect(new ProtectionAbility(filter))); - ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); - - // At the beginning of your first main phase, you may pay {U}. If you do, transform Sygg. - this.addAbility(new BeginningOfFirstMainTriggeredAbility( - new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{U}")) - )); - } - - private SyggWanderbrineShield(final SyggWanderbrineShield card) { - super(card); - } - - @Override - public SyggWanderbrineShield copy() { - return new SyggWanderbrineShield(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SyggWanderwineWisdom.java b/Mage.Sets/src/mage/cards/s/SyggWanderwineWisdom.java index fed8ae5083f..74481c8d303 100644 --- a/Mage.Sets/src/mage/cards/s/SyggWanderwineWisdom.java +++ b/Mage.Sets/src/mage/cards/s/SyggWanderwineWisdom.java @@ -1,8 +1,8 @@ package mage.cards.s; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.common.TransformsOrEntersTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DoIfCostPaid; @@ -10,14 +10,18 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.CantBeBlockedSourceAbility; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.ProtectionAbility; import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.SuperType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorlessPredicate; +import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -25,20 +29,26 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class SyggWanderwineWisdom extends CardImpl { +public final class SyggWanderwineWisdom extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard("each color"); + + static { + filter.add(Predicates.not(ColorlessPredicate.instance)); + } public SyggWanderwineWisdom(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.MERFOLK, SubType.WIZARD}, "{1}{U}", + "Sygg, Wanderbrine Shield", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.MERFOLK, SubType.ROGUE}, "W" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.MERFOLK); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.s.SyggWanderbrineShield.class; + // Sygg, Wanderwine Wisdom + this.getLeftHalfCard().setPT(2, 2); // Sygg can't be blocked. - this.addAbility(new CantBeBlockedSourceAbility()); + this.getLeftHalfCard().addAbility(new CantBeBlockedSourceAbility()); // Whenever this creature enters or transforms into Sygg, Wanderwine Wisdom, target creature gains "Whenever this creature deals combat damage to a player or planeswalker, draw a card" until end of turn. Ability ability = new TransformsOrEntersTriggeredAbility(new GainAbilityTargetEffect( @@ -47,13 +57,28 @@ public final class SyggWanderwineWisdom extends CardImpl { ), Duration.EndOfTurn ), false); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of your first main phase, you may pay {W}. If you do, transform Sygg. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfFirstMainTriggeredAbility( + this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{W}")) )); + + // Sygg, Wanderbrine Shield + this.getRightHalfCard().setPT(2, 2); + + // Sygg can't be blocked. + this.getRightHalfCard().addAbility(new CantBeBlockedSourceAbility()); + + // Whenever this creature transforms into Sygg, Wanderbrine Shield, target creature you control gains protection from each color until your next turn. + Ability ability2 = new TransformIntoSourceTriggeredAbility(new GainAbilityTargetEffect(new ProtectionAbility(filter), Duration.UntilYourNextTurn)); + ability2.addTarget(new TargetControlledCreaturePermanent()); + this.getRightHalfCard().addAbility(ability2); + + // At the beginning of your first main phase, you may pay {U}. If you do, transform Sygg. + this.getRightHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{U}")) + )); } private SyggWanderwineWisdom(final SyggWanderwineWisdom card) { diff --git a/Mage.Sets/src/mage/cards/t/TalesOfMasterSeshiro.java b/Mage.Sets/src/mage/cards/t/TalesOfMasterSeshiro.java index 6f85e081486..5f9a0a4d45d 100644 --- a/Mage.Sets/src/mage/cards/t/TalesOfMasterSeshiro.java +++ b/Mage.Sets/src/mage/cards/t/TalesOfMasterSeshiro.java @@ -5,10 +5,10 @@ import mage.abilities.effects.Effects; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SagaChapter; import mage.constants.SubType; @@ -21,20 +21,22 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TalesOfMasterSeshiro extends CardImpl { +public final class TalesOfMasterSeshiro extends TransformingDoubleFacedCard { public TalesOfMasterSeshiro(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.s.SeshirosLivingLegacy.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{4}{G}", + "Seshiro's Living Legacy", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SNAKE, SubType.WARRIOR}, "G" + ); + // Tales of Master Seshiro // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I, II — Put a +1/+1 counter on target creature or Vehicle you control. It gains vigilance until end of turn. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new Effects( new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GainAbilityTargetEffect(VigilanceAbility.getInstance()) @@ -43,10 +45,18 @@ public final class TalesOfMasterSeshiro extends CardImpl { ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Seshiro's Living Legacy + this.getRightHalfCard().setPT(5, 5); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); } private TalesOfMasterSeshiro(final TalesOfMasterSeshiro card) { diff --git a/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java b/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java index 4777b4073b6..68f64afa8e5 100644 --- a/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java +++ b/Mage.Sets/src/mage/cards/t/TangleclawWerewolf.java @@ -1,42 +1,52 @@ - package mage.cards.t; -import java.util.UUID; - -import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.SubType; + +import java.util.UUID; /** * @author LevelX2 */ -public final class TangleclawWerewolf extends CardImpl { +public final class TangleclawWerewolf extends TransformingDoubleFacedCard { public TangleclawWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(2); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.HORROR}, "{2}{G}{G}", + "Fibrous Entangler", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.WEREWOLF}, "" + ); - this.secondSideCardClazz = mage.cards.f.FibrousEntangler.class; + // Tangleclaw Werewolf + this.getLeftHalfCard().setPT(2, 4); // Tangleclaw Werewolf can block an additional creature each combat. - this.addAbility(new SimpleStaticAbility(new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1))); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1))); // {6}{G}: Transform Tangleclaw Werewolf. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{6}{G}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{6}{G}"))); + + // Fibrous Entangler + this.getRightHalfCard().setPT(4, 6); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Fibrous Entangler must be blocked if able. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new MustBeBlockedByAtLeastOneSourceEffect(Duration.WhileOnBattlefield))); + + // Fibrous Entangler can block an additional creature each combat. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new CanBlockAdditionalCreatureEffect(Duration.WhileOnBattlefield, 1))); } private TangleclawWerewolf(final TangleclawWerewolf card) { diff --git a/Mage.Sets/src/mage/cards/t/TapestryOfTheAges.java b/Mage.Sets/src/mage/cards/t/TapestryOfTheAges.java index da974f65989..b3aea14c7bb 100644 --- a/Mage.Sets/src/mage/cards/t/TapestryOfTheAges.java +++ b/Mage.Sets/src/mage/cards/t/TapestryOfTheAges.java @@ -2,21 +2,14 @@ package mage.cards.t; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.WatcherScope; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.Spell; -import mage.watchers.Watcher; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -30,10 +23,10 @@ public final class TapestryOfTheAges extends CardImpl { // {2}, {T}: Draw a card. Activate this ability only if you've cast a noncreature spell this turn. Ability ability = new ActivateIfConditionActivatedAbility( new DrawCardSourceControllerEffect(1), - new GenericManaCost(2), PlayerCastNonCreatureSpellCondition.instance + new GenericManaCost(2), CastNoncreatureSpellThisTurnCondition.instance ); ability.addCost(new TapSourceCost()); - this.addAbility(ability, new PlayerCastNonCreatureSpellWatcher()); + this.addAbility(ability.addHint(CastNoncreatureSpellThisTurnCondition.getHint())); } private TapestryOfTheAges(final TapestryOfTheAges card) { @@ -45,47 +38,3 @@ public final class TapestryOfTheAges extends CardImpl { return new TapestryOfTheAges(this); } } - -enum PlayerCastNonCreatureSpellCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - PlayerCastNonCreatureSpellWatcher watcher = game.getState().getWatcher(PlayerCastNonCreatureSpellWatcher.class); - return watcher != null && watcher.playerDidCastNonCreatureSpellThisTurn(source.getControllerId()); - } - - @Override - public String toString() { - return "you've cast a noncreature spell this turn"; - } -} - -class PlayerCastNonCreatureSpellWatcher extends Watcher { - - private Set playerIds = new HashSet<>(); - - public PlayerCastNonCreatureSpellWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.SPELL_CAST) { - Spell spell = (Spell) game.getObject(event.getTargetId()); - if (!spell.isCreature(game)) { - playerIds.add(spell.getControllerId()); - } - } - } - - @Override - public void reset() { - super.reset(); - playerIds.clear(); - } - - public boolean playerDidCastNonCreatureSpellThisTurn(UUID playerId) { - return playerIds.contains(playerId); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TarkirDuneshaper.java b/Mage.Sets/src/mage/cards/t/TarkirDuneshaper.java index 3b20c0913f1..1e2b32000df 100644 --- a/Mage.Sets/src/mage/cards/t/TarkirDuneshaper.java +++ b/Mage.Sets/src/mage/cards/t/TarkirDuneshaper.java @@ -1,12 +1,11 @@ package mage.cards.t; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -15,20 +14,26 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TarkirDuneshaper extends CardImpl { +public final class TarkirDuneshaper extends TransformingDoubleFacedCard { public TarkirDuneshaper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DOG, SubType.WARRIOR}, "{W}", + "Burnished Dunestomper", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.DOG, SubType.WARRIOR}, "WG" + ); - this.subtype.add(SubType.DOG); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(1); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.b.BurnishedDunestomper.class; + // Tarkir Duneshaper + this.getLeftHalfCard().setPT(1, 2); // {4}{G/P}: Transform Tarkir Duneshaper. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{G/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{G/P}"))); + + // Burnished Dunestomper + this.getRightHalfCard().setPT(4, 3); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); } private TarkirDuneshaper(final TarkirDuneshaper card) { diff --git a/Mage.Sets/src/mage/cards/t/TarriansJournal.java b/Mage.Sets/src/mage/cards/t/TarriansJournal.java index 3649563facd..5040d9877ef 100644 --- a/Mage.Sets/src/mage/cards/t/TarriansJournal.java +++ b/Mage.Sets/src/mage/cards/t/TarriansJournal.java @@ -1,29 +1,49 @@ package mage.cards.t; -import java.util.UUID; +import mage.MageIdentifier; +import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; +import mage.abilities.SpellAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardHandCost; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.counter.AddCounterEnteringCreatureEffect; +import mage.abilities.mana.BlackManaAbility; +import mage.cards.Card; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.counters.CounterType; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; +import mage.util.SubTypes; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; /** * * @author jeffwadsworth */ -public class TarriansJournal extends CardImpl { +public class TarriansJournal extends TransformingDoubleFacedCard { private static final FilterControlledPermanent filter = new FilterControlledPermanent("another artifact or creature"); @@ -36,23 +56,33 @@ public class TarriansJournal extends CardImpl { } public TarriansJournal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{B}"); - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.t.TheTombOfAclazotz.class; - this.color.setBlack(true); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{B}", + "The Tomb of Aclazotz", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{SubType.CAVE}, "" + ); + // Tarrian's Journal // T: Sacrifice another artifact or creature: Draw a card. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(filter)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {2}, {T}, Discard your hand: Transform Tarrian's Journal. - this.addAbility(new TransformAbility()); Ability transformAbility = new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{2}")); transformAbility.addCost(new TapSourceCost()); transformAbility.addCost(new DiscardHandCost()); - this.addAbility(transformAbility); + this.getLeftHalfCard().addAbility(transformAbility); + + // The Tomb of Aclazotz + // {T}: Add {B}. + this.getRightHalfCard().addAbility(new BlackManaAbility()); + + // You may cast a creature spell from your graveyard this turn. If you do, it enters with a finality counter on it and is a Vampire in addition to its other types. + Ability castSpellAbility = new SimpleActivatedAbility(new TheTombOfAclazotzEffect(), new TapSourceCost()); + castSpellAbility.setIdentifier(MageIdentifier.TheTombOfAclazotzWatcher); + castSpellAbility.addWatcher(new TheTombOfAclazotzWatcher()); + this.getRightHalfCard().addAbility(castSpellAbility); } @@ -66,3 +96,221 @@ public class TarriansJournal extends CardImpl { } } + +class TheTombOfAclazotzEffect extends AsThoughEffectImpl { + + TheTombOfAclazotzEffect() { + super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + staticText = "You may cast a creature spell from your graveyard this turn. If you do, it enters with a finality counter on it and is a Vampire in addition to its other types. (If a creature with a finality counter on it would die, exile it instead.)"; + } + + private TheTombOfAclazotzEffect(final TheTombOfAclazotzEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public TheTombOfAclazotzEffect copy() { + return new TheTombOfAclazotzEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + TheTombOfAclazotzWatcher watcher = game.getState().getWatcher(TheTombOfAclazotzWatcher.class); + if (watcher != null) { + watcher.addPlayable(source, game); + watcher.addPlayFromAnywhereEffect(this.getId()); + } + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + throw new IllegalArgumentException("Wrong code usage: can't call applies method on empty affectedAbility"); + } + + @Override + public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) { + TheTombOfAclazotzWatcher watcher = game.getState().getWatcher(TheTombOfAclazotzWatcher.class); + if (watcher == null + || !watcher.checkPermission(playerId, source, game) + || game.getState().getZone(objectId) != Zone.GRAVEYARD) { + return false; + } + Card card = game.getCard(objectId); + return card != null + && affectedAbility instanceof SpellAbility + && card.getOwnerId().equals(playerId) + && card.isCreature(game); + } +} + +class TheTombOfAclazotzWatcher extends Watcher { + + private final Map> morMap = new HashMap<>(); + private UUID playFromAnywhereEffectId; + + TheTombOfAclazotzWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (GameEvent.EventType.CAST_SPELL.equals(event.getType()) + && event.hasApprovingIdentifier(MageIdentifier.TheTombOfAclazotzWatcher)) { + Spell target = game.getSpell(event.getTargetId()); + Card card = target.getCard(); + if (card != null) { + game.getState().addEffect(new AddCounterEnteringCreatureEffect(new MageObjectReference(target.getCard(), game), + CounterType.FINALITY.createInstance(), Outcome.Neutral), + target.getSpellAbility()); + game.getState().addEffect(new AddSubtypeEnteringCreatureEffect(new MageObjectReference(target.getCard(), game), SubType.VAMPIRE, Outcome.Benefit), card.getSpellAbility()); + // Rule 728.2 we must insure the effect is used (creature is cast successfully) before discarding the play effect + UUID playEffectId = this.getPlayFromAnywhereEffect(); + if (playEffectId != null + && game.getContinuousEffects().getApplicableAsThoughEffects(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, game).listIterator().next().getId().equals(playEffectId)) { + // discard the play effect + game.getContinuousEffects().getApplicableAsThoughEffects(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, game).listIterator().next().discard(); + } + } + } + } + + boolean checkPermission(UUID playerId, Ability source, Game game) { + if (!playerId.equals(source.getControllerId())) { + return false; + } + MageObjectReference mor = new MageObjectReference( + source.getSourceId(), source.getStackMomentSourceZCC(), game + ); + return morMap.computeIfAbsent(mor, m -> new HashMap<>()).getOrDefault(playerId, 0) > 0; + } + + void addPlayable(Ability source, Game game) { + MageObjectReference mor = new MageObjectReference( + source.getSourceId(), source.getStackMomentSourceZCC(), game + ); + morMap.computeIfAbsent(mor, m -> new HashMap<>()) + .compute(source.getControllerId(), CardUtil::setOrIncrementValue); + } + + void addPlayFromAnywhereEffect(UUID uuid) { + playFromAnywhereEffectId = uuid; + } + + UUID getPlayFromAnywhereEffect() { + return playFromAnywhereEffectId; + } + + @Override + public void reset() { + morMap.clear(); + super.reset(); + } + +} + +class AddSubtypeEnteringCreatureEffect extends ReplacementEffectImpl { + + private final MageObjectReference mor; + private final SubType subType; + + AddSubtypeEnteringCreatureEffect(MageObjectReference mor, SubType subType, Outcome outcome) { + super(Duration.WhileOnBattlefield, outcome); + this.mor = mor; + this.subType = subType; + } + + private AddSubtypeEnteringCreatureEffect(final AddSubtypeEnteringCreatureEffect effect) { + super(effect); + this.mor = effect.mor; + this.subType = effect.subType; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL_LATE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject spell = game.getObject(event.getSourceId()); + return spell != null && mor.refersTo(spell, game); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Spell target = game.getSpell(event.getSourceId()); + if (target != null) { + AddCardSubTypeEnteringTargetEffect effect = new AddCardSubTypeEnteringTargetEffect(mor, subType, Duration.WhileOnBattlefield); + effect.setTargetPointer(new FixedTarget(target, game)); + game.addEffect(effect, source); + } + return false; + } + + @Override + public AddSubtypeEnteringCreatureEffect copy() { + return new AddSubtypeEnteringCreatureEffect(this); + } +} + +class AddCardSubTypeEnteringTargetEffect extends ContinuousEffectImpl { + + private final SubType addedSubType; + private final MageObjectReference mor; + private Card card; + + AddCardSubTypeEnteringTargetEffect(MageObjectReference mor, SubType addedSubType, Duration duration) { + super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + this.addedSubType = addedSubType; + this.mor = mor; + } + + protected AddCardSubTypeEnteringTargetEffect(final AddCardSubTypeEnteringTargetEffect effect) { + super(effect); + this.addedSubType = effect.addedSubType; + this.mor = effect.mor; + this.card = effect.card; + } + + @Override + public boolean apply(Game game, Ability source) { + Spell spell = game.getSpell(getTargetPointer().getFirst(game, source)); + MageObject target = game.getObject(getTargetPointer().getFirst(game, source)); + if (spell != null) { + card = spell.getCard(); + } + for (StackObject stackObject : game.getStack()) { + if (stackObject instanceof Spell + && target != null + && target.equals(stackObject) + && mor.refersTo(target, game)) { + setCreatureSubtype(stackObject, addedSubType, game); + setCreatureSubtype(((Spell) stackObject).getCard(), addedSubType, game); + } + } + if (card != null + && game.getPermanent(card.getId()) != null + && game.getState().getZoneChangeCounter(card.getId()) == mor.getZoneChangeCounter() + 1) { // blinking, etc + game.getPermanent(card.getId()).addSubType(game, addedSubType); + } + return true; + } + + private void setCreatureSubtype(MageObject object, SubType subtype, Game game) { + SubTypes subTypes = game.getState().getCreateMageObjectAttribute(object, game).getSubtype(); + if (!subTypes.contains(subtype)) { + subTypes.add(subtype); + } + } + + @Override + public AddCardSubTypeEnteringTargetEffect copy() { + return new AddCardSubTypeEnteringTargetEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TavernRuffian.java b/Mage.Sets/src/mage/cards/t/TavernRuffian.java index 804e7551083..22bc66e2b86 100644 --- a/Mage.Sets/src/mage/cards/t/TavernRuffian.java +++ b/Mage.Sets/src/mage/cards/t/TavernRuffian.java @@ -1,9 +1,9 @@ package mage.cards.t; -import mage.MageInt; import mage.abilities.keyword.DayboundAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -12,21 +12,26 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TavernRuffian extends CardImpl { +public final class TavernRuffian extends TransformingDoubleFacedCard { public TavernRuffian(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARRIOR, SubType.WEREWOLF}, "{3}{R}", + "Tavern Smasher", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARRIOR); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(5); - - this.secondSideCardClazz = mage.cards.t.TavernSmasher.class; + // Tavern Ruffian + this.getLeftHalfCard().setPT(2, 5); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Tavern Smasher + this.getRightHalfCard().setPT(6, 5); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private TavernRuffian(final TavernRuffian card) { diff --git a/Mage.Sets/src/mage/cards/t/TavernSmasher.java b/Mage.Sets/src/mage/cards/t/TavernSmasher.java deleted file mode 100644 index 23e61cd013e..00000000000 --- a/Mage.Sets/src/mage/cards/t/TavernSmasher.java +++ /dev/null @@ -1,41 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.keyword.NightboundAbility; -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 TavernSmasher extends CardImpl { - - public TavernSmasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - - this.color.setRed(true); - - this.nightCard = true; - - this.power = new MageInt(6); - this.toughness = new MageInt(5); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private TavernSmasher(final TavernSmasher card) { - super(card); - } - - @Override - public TavernSmasher copy() { - return new TavernSmasher(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TeachingsOfTheKirin.java b/Mage.Sets/src/mage/cards/t/TeachingsOfTheKirin.java index 7b0d51758cf..7a9802562c4 100644 --- a/Mage.Sets/src/mage/cards/t/TeachingsOfTheKirin.java +++ b/Mage.Sets/src/mage/cards/t/TeachingsOfTheKirin.java @@ -1,54 +1,84 @@ package mage.cards.t; -import java.util.UUID; - +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.MillCardsControllerEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.constants.SagaChapter; -import mage.constants.SubType; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; -import mage.constants.CardType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.filter.predicate.Predicates; +import mage.game.Game; import mage.game.permanent.token.SpiritToken; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * * @author weirddan455 */ -public final class TeachingsOfTheKirin extends CardImpl { +public final class TeachingsOfTheKirin extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard("noncreature card from a graveyard"); + + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + } public TeachingsOfTheKirin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.k.KirinTouchedOrochi.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{G}", + "Kirin-Touched Orochi", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SNAKE, SubType.MONK}, "G" + ); + // Teachings of the Kirin // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I - Mill three cards. Create a 1/1 colorless Spirit creature token. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new MillCardsControllerEffect(3), new CreateTokenEffect(new SpiritToken()) ); // II — Put a +1/+1 counter on target creature you control. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TargetControlledCreaturePermanent() ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Kirin-Touched Orochi + this.getRightHalfCard().setPT(1, 1); + + // Whenever Kirin-Touched Orochi attacks, choose one — + // • Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token. + Ability ability = new AttacksTriggeredAbility(new KirinTouchedOrochiTokenEffect()); + ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_A_GRAVEYARD)); + + // • Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control. + Mode mode = new Mode(new KirinTouchedOrochiCounterEffect()); + mode.addTarget(new TargetCardInGraveyard(filter)); + ability.addMode(mode); + this.getRightHalfCard().addAbility(ability); } private TeachingsOfTheKirin(final TeachingsOfTheKirin card) { @@ -60,3 +90,70 @@ public final class TeachingsOfTheKirin extends CardImpl { return new TeachingsOfTheKirin(this); } } + +class KirinTouchedOrochiTokenEffect extends OneShotEffect { + + KirinTouchedOrochiTokenEffect() { + super(Outcome.Exile); + this.staticText = "Exile target creature card from a graveyard. When you do, create a 1/1 colorless Spirit creature token"; + } + + private KirinTouchedOrochiTokenEffect(final KirinTouchedOrochiTokenEffect effect) { + super(effect); + } + + @Override + public KirinTouchedOrochiTokenEffect copy() { + return new KirinTouchedOrochiTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + UUID targetId = source.getFirstTarget(); + Card card = game.getCard(targetId); + if (controller == null || card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) { + return false; + } + if (!controller.moveCards(card, Zone.EXILED, source, game)) { + return false; + } + ReflexiveTriggeredAbility reflexiveTokenAbility = new ReflexiveTriggeredAbility(new CreateTokenEffect(new SpiritToken()), false); + game.fireReflexiveTriggeredAbility(reflexiveTokenAbility, source); + return true; + } +} + +class KirinTouchedOrochiCounterEffect extends OneShotEffect { + + KirinTouchedOrochiCounterEffect() { + super(Outcome.Exile); + this.staticText = "Exile target noncreature card from a graveyard. When you do, put a +1/+1 counter on target creature you control"; + } + + private KirinTouchedOrochiCounterEffect(final KirinTouchedOrochiCounterEffect effect) { + super(effect); + } + + @Override + public KirinTouchedOrochiCounterEffect copy() { + return new KirinTouchedOrochiCounterEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + UUID targetId = source.getFirstTarget(); + Card card = game.getCard(targetId); + if (controller == null || card == null || game.getState().getZone(targetId) != Zone.GRAVEYARD) { + return false; + } + if (!controller.moveCards(card, Zone.EXILED, source, game)) { + return false; + } + ReflexiveTriggeredAbility reflexiveCounterAbility = new ReflexiveTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false); + reflexiveCounterAbility.addTarget(new TargetControlledCreaturePermanent()); + game.fireReflexiveTriggeredAbility(reflexiveCounterAbility, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TerraMagicalAdept.java b/Mage.Sets/src/mage/cards/t/TerraMagicalAdept.java index 2b3d125cd26..d52e721e859 100644 --- a/Mage.Sets/src/mage/cards/t/TerraMagicalAdept.java +++ b/Mage.Sets/src/mage/cards/t/TerraMagicalAdept.java @@ -1,52 +1,91 @@ package mage.cards.t; -import mage.MageInt; +import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SagaAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; import mage.abilities.effects.common.MillThenPutInHandEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.mana.BasicManaEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.PutCards; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledEnchantmentPermanent; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import java.util.Optional; import java.util.UUID; /** * @author TheElk801 */ -public final class TerraMagicalAdept extends CardImpl { +public final class TerraMagicalAdept extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent("nonlegendary enchantment you control"); + + static { + filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + } public TerraMagicalAdept(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD, SubType.WARRIOR}, "{1}{R}{G}", + "Esper Terra", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SAGA, SubType.WIZARD}, "RG" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(4); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.e.EsperTerra.class; + // Terra, Magical Adept + this.getLeftHalfCard().setPT(4, 2); // When Terra enters, mill five cards. Put up to one enchantment milled this this way into your hand. - this.addAbility(new EntersBattlefieldTriggeredAbility(new MillThenPutInHandEffect( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new MillThenPutInHandEffect( 5, StaticFilters.FILTER_CARD_ENCHANTMENT, true ).setText("mill five cards. Put up to one enchantment card milled this way into your hand"))); // Trance -- {4}{R}{G}, {T}: Exile Terra, then return it to the battlefield transformed under its owner's control. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{4}{R}{G}") ); ability.addCost(new TapSourceCost()); - this.addAbility(ability.withFlavorWord("Trance")); + this.getLeftHalfCard().addAbility(ability.withFlavorWord("Trance")); + + // Esper Terra + this.getRightHalfCard().setPT(6, 6); + + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard(), SagaChapter.CHAPTER_IV); + + // I, II, III -- Create a token that's a copy of target nonlegendary enchantment you control. It gains haste. If it's a Saga, put up to three lore counters on it. Sacrifice it at the beginning of your next end step. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_III, + new EsperTerraEffect(), new TargetPermanent(filter) + ); + + // IV -- Add {W}{W}, {U}{U}, {B}{B}, {R}{R}, and {G}{G}. Exile Esper Terra, then return it to the battlefield. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_IV, + new BasicManaEffect(new Mana( + 2, 2, 2, 2, 2, 0, 0, 0 + )).setText("add {W}{W}, {U}{U}, {B}{B}, {R}{R}, and {G}{G}"), + new ExileSourceAndReturnFaceUpEffect()); + this.getRightHalfCard().addAbility(sagaAbility); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); } private TerraMagicalAdept(final TerraMagicalAdept card) { @@ -58,3 +97,48 @@ public final class TerraMagicalAdept extends CardImpl { return new TerraMagicalAdept(this); } } + +class EsperTerraEffect extends OneShotEffect { + + EsperTerraEffect() { + super(Outcome.Benefit); + staticText = "create a token that's a copy of target nonlegendary enchantment you control. " + + "It gains haste. If it's a Saga, put up to three lore counters on it. " + + "Sacrifice it at the beginning of your next end step"; + } + + private EsperTerraEffect(final EsperTerraEffect effect) { + super(effect); + } + + @Override + public EsperTerraEffect copy() { + return new EsperTerraEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); + effect.setSavedPermanent(permanent); + effect.addAdditionalAbilities(HasteAbility.getInstance()); + effect.apply(game, source); + for (Permanent token : effect.getAddedPermanents()) { + if (!token.hasSubtype(SubType.SAGA, game)) { + continue; + } + Optional.ofNullable(source.getControllerId()) + .map(game::getPlayer) + .map(player -> player.getAmount( + 0, 3, "Choose how many lore counters to put on " + token.getIdName(), source, game + )) + .filter(amount -> amount > 0) + .ifPresent(amount -> token.addCounters(CounterType.LORE.createInstance(amount), source, game)); + } + effect.removeTokensCreatedAt(game, source, false, PhaseStep.END_TURN, TargetController.YOU); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TetzinGnomeChampion.java b/Mage.Sets/src/mage/cards/t/TetzinGnomeChampion.java index 1f93a371526..b6d4297b2eb 100644 --- a/Mage.Sets/src/mage/cards/t/TetzinGnomeChampion.java +++ b/Mage.Sets/src/mage/cards/t/TetzinGnomeChampion.java @@ -1,11 +1,16 @@ package mage.cards.t; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.MillThenPutInHandEffect; +import mage.abilities.effects.common.TransformTargetEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; @@ -14,6 +19,8 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.card.DoubleFacedCardPredicate; import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.permanent.token.GnomeToken; +import mage.target.TargetPermanent; import java.util.UUID; @@ -21,43 +28,62 @@ import java.util.UUID; * * @author jeffwadsworth */ -public class TetzinGnomeChampion extends CardImpl { +public class TetzinGnomeChampion extends TransformingDoubleFacedCard { private static final FilterControlledPermanent filter = new FilterControlledPermanent("double-faced artifact"); + private static final FilterControlledPermanent filter2 = new FilterControlledPermanent("other target double-faced artifact you control"); static { filter.add(AnotherPredicate.instance); filter.add(Predicates.and( DoubleFacedCardPredicate.instance, - CardType.ARTIFACT.getPredicate() - ) + CardType.ARTIFACT.getPredicate()) + ); + filter2.add(AnotherPredicate.instance); + filter2.add(Predicates.and( + DoubleFacedCardPredicate.instance, + CardType.ARTIFACT.getPredicate()) ); } public TetzinGnomeChampion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}{R}{W}"); - this.supertype.add(SuperType.LEGENDARY); - this.cardType.add(CardType.CREATURE); - this.subtype.add(SubType.GNOME); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GNOME}, "{U}{R}{W}", + "The Golden-Gear Colossus", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GNOME}, "URW" + ); - this.secondSideCardClazz = mage.cards.t.TheGoldenGearColossus.class; - this.color.setBlue(true); - this.color.setRed(true); - this.color.setWhite(true); + // Tetzin, Gnome Champion + this.getLeftHalfCard().setPT(2, 2); // Whenever Tetzin or another double-faced artifact you control enters, mill three cards. You may put an artifact card from among them into your hand. - this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility( new MillThenPutInHandEffect(3, StaticFilters.FILTER_CARD_ARTIFACT_AN).withTextOptions("them"), filter, false, true )); // Craft with six artifacts 4 (4, Exile this artifact, Exile the six from among other permanents you control and/or cards from your graveyard: Return this card transformed under its owner's control. Craft only as a sorcery.) - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{4}", "six artifacts", "other artifacts you control and/or" + "artifact cards in your graveyard", 6, 6, CardType.ARTIFACT.getPredicate() )); + + // The Golden-Gear Colossus + this.getRightHalfCard().setPT(6, 6); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Whenever The Golden-Gear Colossus enters the battlefield or attacks, transform up to one other target double-faced artifact you control. Create two 1/1 colorless Gnome artifact creature tokens. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new TransformTargetEffect()); + TargetPermanent target = new TargetPermanent(0, 1, filter2); + ability.addTarget(target); + ability.addEffect(new CreateTokenEffect(new GnomeToken(), 2)); + this.getRightHalfCard().addAbility(ability); + } private TetzinGnomeChampion(final TetzinGnomeChampion card) { diff --git a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java index 9f87ab86bfc..ad31deb3782 100644 --- a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java +++ b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java @@ -6,17 +6,24 @@ import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.RemoveFromCombatTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.hint.common.LandsYouControlHint; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.ColorlessManaAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterLandPermanent; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.target.TargetPermanent; import mage.target.common.TargetCardInLibrary; import java.util.UUID; @@ -24,28 +31,51 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class ThaumaticCompass extends CardImpl { +public final class ThaumaticCompass extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterLandPermanent("you control seven or more lands"), ComparisonType.MORE_THAN, 6, true ); - public ThaumaticCompass(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - this.secondSideCardClazz = mage.cards.s.SpiresOfOrazca.class; + private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("attacking creature an opponent controls"); + static { + filter.add(AttackingPredicate.instance); + } + + public ThaumaticCompass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}", + "Spires of Orazca", + new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + + // Thaumatic Compass // {3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. Ability ability = new SimpleActivatedAbility( new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()) + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()) .withInterveningIf(condition).addHint(LandsYouControlHint.instance)); + + // Spires of Orazca + // {T}: Add {C}. + this.getRightHalfCard().addAbility(new ColorlessManaAbility()); + + // {T}: Untap target attacking creature an opponent controls and remove it from combat. + Ability ability2 = new SimpleActivatedAbility( + new UntapTargetEffect() + .setText("Untap target attacking creature an opponent controls"), + new TapSourceCost() + ); + ability2.addEffect(new RemoveFromCombatTargetEffect().setText("and remove it from combat")); + ability2.addTarget(new TargetPermanent(filter)); + this.getRightHalfCard().addAbility(ability2); } private ThaumaticCompass(final ThaumaticCompass card) { diff --git a/Mage.Sets/src/mage/cards/t/TheComingOfGalactus.java b/Mage.Sets/src/mage/cards/t/TheComingOfGalactus.java new file mode 100644 index 00000000000..c3069cb8c3b --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheComingOfGalactus.java @@ -0,0 +1,49 @@ +package mage.cards.t; + +import mage.abilities.common.SagaAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SagaChapter; +import mage.constants.SubType; +import mage.game.permanent.token.GalactusToken; +import mage.target.common.TargetNonlandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TheComingOfGalactus extends CardImpl { + + public TheComingOfGalactus(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}{G}"); + + this.subtype.add(SubType.SAGA); + + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.) + SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_IV); + + // I -- Destroy up to one target nonland permanent. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new DestroyTargetEffect(), new TargetNonlandPermanent(0, 1)); + + // II, III -- Each opponent loses 2 life. + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_III, new LoseLifeOpponentsEffect(2)); + + // IV -- Create Galactus, a legendary 16/16 black Elder Alien creature token with flying, trample, and "Whenever Galactus attacks, destroy target land." + sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_IV, new CreateTokenEffect(new GalactusToken())); + this.addAbility(sagaAbility); + } + + private TheComingOfGalactus(final TheComingOfGalactus card) { + super(card); + } + + @Override + public TheComingOfGalactus copy() { + return new TheComingOfGalactus(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheDragonKamiReborn.java b/Mage.Sets/src/mage/cards/t/TheDragonKamiReborn.java index 798e0674802..86e9be938cb 100644 --- a/Mage.Sets/src/mage/cards/t/TheDragonKamiReborn.java +++ b/Mage.Sets/src/mage/cards/t/TheDragonKamiReborn.java @@ -1,47 +1,63 @@ package mage.cards.t; import mage.abilities.Ability; +import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; import mage.abilities.common.SagaAbility; import mage.abilities.effects.Effects; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.keyword.TransformAbility; import mage.cards.*; import mage.constants.*; import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; +import java.util.Objects; import java.util.UUID; /** * @author TheElk801 */ -public final class TheDragonKamiReborn extends CardImpl { +public final class TheDragonKamiReborn extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DRAGON); public TheDragonKamiReborn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.d.DragonKamisEgg.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{G}", + "Dragon-Kami's Egg", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.EGG}, "G" + ); + // The Dragon-Kami Reborn // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I, II — You gain 2 life. Look at the top three cards of your library. Exile one of them face down with a hatching counter on it, then put the rest on the bottom of your library in any order. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new Effects(new GainLifeEffect(2), new TheDragonKamiRebornEffect()) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Dragon-Kami's Egg + this.getRightHalfCard().setPT(0, 1); + + // Whenever Dragon-Kami's Egg or a Dragon you control dies, you may cast a creature spell from among cards you own in exile with hatching counters on them without paying its mana cost. + this.getRightHalfCard().addAbility(new DiesThisOrAnotherTriggeredAbility( + new DragonKamisEggEffect(), false, filter + ).setTriggerPhrase("Whenever {this} or a Dragon you control dies, ")); } private TheDragonKamiReborn(final TheDragonKamiReborn card) { @@ -94,3 +110,39 @@ class TheDragonKamiRebornEffect extends OneShotEffect { return true; } } + +class DragonKamisEggEffect extends OneShotEffect { + + DragonKamisEggEffect() { + super(Outcome.Benefit); + staticText = "you may cast a creature spell from among cards you own in exile " + + "with hatching counters on them without paying its mana cost"; + } + + private DragonKamisEggEffect(final DragonKamisEggEffect effect) { + super(effect); + } + + @Override + public DragonKamisEggEffect copy() { + return new DragonKamisEggEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(); + game.getExile() + .getCardsOwned(game, player.getId()) + .stream() + .filter(Objects::nonNull) + .filter(card -> card.getCounters(game).containsKey(CounterType.HATCHLING)) + .forEach(cards::add); + return !cards.isEmpty() && CardUtil.castSpellWithAttributesForFree( + player, source, game, cards, StaticFilters.FILTER_CARD_CREATURE + ); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheEmperorOfPalamecia.java b/Mage.Sets/src/mage/cards/t/TheEmperorOfPalamecia.java index 734c875717f..ed36bbb4531 100644 --- a/Mage.Sets/src/mage/cards/t/TheEmperorOfPalamecia.java +++ b/Mage.Sets/src/mage/cards/t/TheEmperorOfPalamecia.java @@ -1,55 +1,70 @@ package mage.cards.t; -import mage.MageInt; import mage.Mana; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; +import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; import mage.abilities.mana.ConditionalColoredManaAbility; import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.abilities.mana.conditional.ConditionalSpellManaBuilder; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; +import mage.constants.TargetController; import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; import mage.filter.StaticFilters; +import mage.filter.predicate.Predicates; import java.util.UUID; /** * @author TheElk801 */ -public final class TheEmperorOfPalamecia extends CardImpl { +public final class TheEmperorOfPalamecia extends TransformingDoubleFacedCard { - private final ConditionalManaBuilder manaBuilder - = new ConditionalSpellManaBuilder(StaticFilters.FILTER_SPELLS_NON_CREATURE); + private final ConditionalManaBuilder manaBuilder = new ConditionalSpellManaBuilder(new FilterSpell("a noncreature spell")); private static final Condition condition = new SourceHasCounterCondition(CounterType.P1P1, 3); - public TheEmperorOfPalamecia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{R}"); + private static final FilterCard filter = new FilterCard("noncreature, nonland cards in your graveyard"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.t.TheLordMasterOfHell.class; + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + filter.add(Predicates.not(CardType.LAND.getPredicate())); + } + + private static final DynamicValue xValue = new CardsInControllerGraveyardCount(filter); + private static final Hint hint = new ValueHint("Noncreature, nonland cards in your graveyard", xValue); + + public TheEmperorOfPalamecia(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE, SubType.WIZARD}, "{U}{R}", + "The Lord Master of Hell", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON, SubType.NOBLE, SubType.WIZARD}, "UR" + ); + + // The Emperor of Palamecia + this.getLeftHalfCard().setPT(2, 2); // {T}: Add {U} or {R}. Spend this mana only to cast a noncreature spell. - this.addAbility(new ConditionalColoredManaAbility(new TapSourceCost(), Mana.BlueMana(1), manaBuilder)); - this.addAbility(new ConditionalColoredManaAbility(new TapSourceCost(), Mana.RedMana(1), manaBuilder)); + this.getLeftHalfCard().addAbility(new ConditionalColoredManaAbility(new TapSourceCost(), Mana.BlueMana(1), manaBuilder)); + this.getLeftHalfCard().addAbility(new ConditionalColoredManaAbility(new TapSourceCost(), Mana.RedMana(1), manaBuilder)); // Whenever you cast a noncreature spell, if at least four mana was spent to cast it, put a +1/+1 counter on The Emperor of Palamecia. Then if it has three or more +1/+1 counters on it, transform it. - this.addAbility(new TransformAbility()); Ability ability = new SpellCastControllerTriggeredAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_NONCREATURE_SPELL_FOUR_MANA_SPENT, false @@ -58,7 +73,17 @@ public final class TheEmperorOfPalamecia extends CardImpl { new TransformSourceEffect(), condition, "Then if it has three or more +1/+1 counters on it, transform it" )); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // The Lord Master of Hell + this.getRightHalfCard().setPT(3, 3); + + // Starfall -- Whenever The Lord Master of Hell attacks, it deals X damage to each opponent, where X is the number of noncreature, nonland cards in your graveyard. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new DamagePlayersEffect( + xValue, TargetController.OPPONENT + ).setText("it deals X damage to each opponent, where X is " + + "the number of noncreature, nonland cards in your graveyard")) + .withFlavorWord("Starfall").addHint(hint)); } private TheEmperorOfPalamecia(final TheEmperorOfPalamecia card) { diff --git a/Mage.Sets/src/mage/cards/t/TheEnigmaJewel.java b/Mage.Sets/src/mage/cards/t/TheEnigmaJewel.java index 6a515394202..5869e13e86b 100644 --- a/Mage.Sets/src/mage/cards/t/TheEnigmaJewel.java +++ b/Mage.Sets/src/mage/cards/t/TheEnigmaJewel.java @@ -1,43 +1,69 @@ package mage.cards.t; import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbility; +import mage.abilities.common.ActivateAbilityTriggeredAbility; import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.CopyStackObjectEffect; import mage.abilities.keyword.CraftAbility; import mage.abilities.mana.ConditionalColorlessManaAbility; import mage.abilities.mana.builder.common.ActivatedAbilityManaBuilder; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterStackObject; +import mage.filter.common.FilterActivatedOrTriggeredAbility; import mage.filter.predicate.Predicate; +import mage.filter.predicate.other.NotManaAbilityPredicate; +import mage.game.ExileZone; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; import java.util.UUID; /** * @author TheElk801 */ -public final class TheEnigmaJewel extends CardImpl { +public final class TheEnigmaJewel extends TransformingDoubleFacedCard { + + private static final FilterStackObject filter = new FilterActivatedOrTriggeredAbility("an ability that isn't a mana ability"); + + static { + filter.add(NotManaAbilityPredicate.instance); + } public TheEnigmaJewel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}"); - - this.supertype.add(SuperType.LEGENDARY); - this.secondSideCardClazz = mage.cards.l.LocusOfEnlightenment.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{U}", + "Locus of Enlightenment", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "U" + ); + // The Enigma Jewel // The Enigma Jewel enters the battlefield tapped. - this.addAbility(new EntersBattlefieldTappedAbility()); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTappedAbility()); // {T}: Add {C}{C}. Spend this mana only to activate abilities. - this.addAbility(new ConditionalColorlessManaAbility(2, new ActivatedAbilityManaBuilder())); + this.getLeftHalfCard().addAbility(new ConditionalColorlessManaAbility(2, new ActivatedAbilityManaBuilder())); // Craft with four or more nonlands with activated abilities {8}{U} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{8}{U}", "four or more nonlands with activated abilities", "other " + "nonland permanents you control with activated abilities and/or nonland cards in your " + "graveyard with activated abilities", 4, Integer.MAX_VALUE, TheEnigmaJewelPredicate.instance )); + + // Locus of Enlightenment + // Locus of Enlightenment has each activated ability of the exiled cards used to craft it. You may activate each of those abilities only once each turn. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new LocusOfEnlightenmentEffect())); + + // Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy. + this.getRightHalfCard().addAbility(new ActivateAbilityTriggeredAbility(new CopyStackObjectEffect("it"), filter, SetTargetPointer.SPELL)); } private TheEnigmaJewel(final TheEnigmaJewel card) { @@ -62,3 +88,46 @@ enum TheEnigmaJewelPredicate implements Predicate { .anyMatch(a -> (a.isActivatedAbility())); } } + +class LocusOfEnlightenmentEffect extends ContinuousEffectImpl { + + LocusOfEnlightenmentEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.Benefit); + staticText = "{this} has each activated ability of the exiled cards " + + "used to craft it. You may activate each of those abilities only once each turn"; + } + + private LocusOfEnlightenmentEffect(final LocusOfEnlightenmentEffect effect) { + super(effect); + } + + @Override + public LocusOfEnlightenmentEffect copy() { + return new LocusOfEnlightenmentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent == null) { + return false; + } + ExileZone exileZone = game + .getExile() + .getExileZone(CardUtil.getExileZoneId(game, permanent.getMainCard().getId(), + permanent.getMainCard().getZoneChangeCounter(game) - 1)); + if (exileZone == null) { + return false; + } + for (Card card : exileZone.getCards(game)) { + for (Ability ability : card.getAbilities(game)) { + if (ability.isActivatedAbility()) { + ActivatedAbility copyAbility = (ActivatedAbility) ability.copy(); + copyAbility.setMaxActivationsPerTurn(1); + permanent.addAbility(copyAbility, source.getSourceId(), game, true); + } + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheEverflowingWell.java b/Mage.Sets/src/mage/cards/t/TheEverflowingWell.java index 62aecfd6a98..787947c892a 100644 --- a/Mage.Sets/src/mage/cards/t/TheEverflowingWell.java +++ b/Mage.Sets/src/mage/cards/t/TheEverflowingWell.java @@ -1,42 +1,67 @@ package mage.cards.t; import mage.abilities.Ability; +import mage.abilities.common.CastSpellPaidBySourceTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.DescendCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CopyEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.MillCardsControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.BlueManaAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AbilityWord; -import mage.constants.CardType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.predicate.mageobject.PermanentPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentCard; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetPermanent; import java.util.UUID; /** * @author jeffwadsworth */ -public class TheEverflowingWell extends CardImpl { +public class TheEverflowingWell extends TransformingDoubleFacedCard { + + private static final FilterSpell filter = new FilterSpell("a permanent spell"); + + static { + filter.add(PermanentPredicate.instance); + } public TheEverflowingWell(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}"); - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.t.TheMyriadPools.class; - this.color.setBlue(true); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}{U}", + "The Myriad Pools", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.LAND}, new SubType[]{}, "" + ); + // The Everflowing Well // When the Everflowing Well enters the battlefield, mill two cards, then draw two cards. Ability entersAbility = new EntersBattlefieldTriggeredAbility(new MillCardsControllerEffect(2)); entersAbility.addEffect(new DrawCardSourceControllerEffect(2).concatBy(", then")); - this.addAbility(entersAbility); + this.getLeftHalfCard().addAbility(entersAbility); // Descend 8 -- At the beginning of your upkeep, if there are eight or more permanent cards in your graveyard, transform The Everflowing Well. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect()) + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect()) .withInterveningIf(DescendCondition.EIGHT).setAbilityWord(AbilityWord.DESCEND_8).addHint(DescendCondition.getHint())); + + // The Myriad Pools + // {T}: Add {U}. + this.getRightHalfCard().addAbility(new BlueManaAbility()); + + // Whenever you cast a permanent spell using mana produced by The Myriad Pools, up to one other target permanent you control becomes a copy of that spell until end of turn. + Ability ability = new CastSpellPaidBySourceTriggeredAbility(new TheMyriadPoolsCopyEffect(), filter, false); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_TARGET_PERMANENT)); + this.getRightHalfCard().addAbility(ability); } private TheEverflowingWell(final TheEverflowingWell card) { @@ -49,3 +74,37 @@ public class TheEverflowingWell extends CardImpl { } } + +class TheMyriadPoolsCopyEffect extends OneShotEffect { + + TheMyriadPoolsCopyEffect() { + super(Outcome.Neutral); + this.staticText = "up to one other target permanent you control becomes a copy of that spell until end of turn"; + } + + private TheMyriadPoolsCopyEffect(final TheMyriadPoolsCopyEffect effect) { + super(effect); + } + + @Override + public TheMyriadPoolsCopyEffect copy() { + return new TheMyriadPoolsCopyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetPermanentToCopyTo = game.getPermanent(getTargetPointer().getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + Object spell = getValue("spellCast"); + if (controller == null || targetPermanentToCopyTo == null || !(spell instanceof Spell)) { + return false; + } + Permanent newBluePrint = new PermanentCard(((Spell) spell).getCard(), source.getControllerId(), game); + newBluePrint.assignNewId(); + CopyEffect copyEffect = new CopyEffect(Duration.EndOfTurn, newBluePrint, targetPermanentToCopyTo.getId()); + Ability newAbility = source.copy(); + copyEffect.init(newAbility, game); + game.addEffect(copyEffect, newAbility); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheFallOfLordKonda.java b/Mage.Sets/src/mage/cards/t/TheFallOfLordKonda.java index 450b8d2312e..9968ca03993 100644 --- a/Mage.Sets/src/mage/cards/t/TheFallOfLordKonda.java +++ b/Mage.Sets/src/mage/cards/t/TheFallOfLordKonda.java @@ -1,12 +1,14 @@ package mage.cards.t; +import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.continuous.GainControlAllOwnedEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.DefenderAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SagaChapter; @@ -22,7 +24,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TheFallOfLordKonda extends CardImpl { +public final class TheFallOfLordKonda extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("creature an opponent controls with mana value 4 or greater"); @@ -32,34 +34,44 @@ public final class TheFallOfLordKonda extends CardImpl { } public TheFallOfLordKonda(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.f.FragmentOfKonda.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{W}", + "Fragment of Konda", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE}, "W" + ); + // The Fall of Lord Konda // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I — Exile target creature an opponent controls with mana value 4 or greater. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, new ExileTargetEffect(), new TargetPermanent(filter) ); // II — Each player gains control of all permanents they own. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new GainControlAllOwnedEffect(StaticFilters.FILTER_PERMANENTS) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, + this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect() ); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Fragment of Konda + this.getRightHalfCard().setPT(1, 3); + + // Defender + this.getRightHalfCard().addAbility(DefenderAbility.getInstance()); + + // When Fragment of Konda dies, draw a card. + this.getRightHalfCard().addAbility(new DiesSourceTriggeredAbility(new DrawCardSourceControllerEffect(1))); } private TheFallOfLordKonda(final TheFallOfLordKonda card) { diff --git a/Mage.Sets/src/mage/cards/t/TheGoldenGearColossus.java b/Mage.Sets/src/mage/cards/t/TheGoldenGearColossus.java deleted file mode 100644 index 02c6add9e7a..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheGoldenGearColossus.java +++ /dev/null @@ -1,74 +0,0 @@ -package mage.cards.t; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.TransformTargetEffect; -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.SubType; -import mage.constants.SuperType; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.card.DoubleFacedCardPredicate; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.permanent.token.GnomeToken; -import mage.target.TargetPermanent; - -/** - * - * @author jeffwadsworth - */ -public class TheGoldenGearColossus extends CardImpl { - - private static final FilterControlledPermanent filter = new FilterControlledPermanent("other target double-faced artifact you control"); - - static { - filter.add(AnotherPredicate.instance); - filter.add(Predicates.and( - DoubleFacedCardPredicate.instance, - CardType.ARTIFACT.getPredicate() - ) - ); - } - - public TheGoldenGearColossus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, null); - this.supertype.add(SuperType.LEGENDARY); - this.cardType.add(CardType.CREATURE); - this.subtype.add(SubType.GNOME); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - - this.nightCard = true; - - this.color.setBlue(true); - this.color.setRed(true); - this.color.setWhite(true); - - this.addAbility(VigilanceAbility.getInstance()); - this.addAbility(TrampleAbility.getInstance()); - - // Whenever The Golden-Gear Colossus enters the battlefield or attacks, transform up to one other target double-faced artifact you control. Create two 1/1 colorless Gnome artifact creature tokens. - Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new TransformTargetEffect()); - TargetPermanent target = new TargetPermanent(0, 1, filter); - ability.addTarget(target); - ability.addEffect(new CreateTokenEffect(new GnomeToken(), 2)); - this.addAbility(ability); - - } - - private TheGoldenGearColossus(final TheGoldenGearColossus card) { - super(card); - } - - @Override - public TheGoldenGearColossus copy() { - return new TheGoldenGearColossus(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheGrandEvolution.java b/Mage.Sets/src/mage/cards/t/TheGrandEvolution.java deleted file mode 100644 index cfcde708afd..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheGrandEvolution.java +++ /dev/null @@ -1,108 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.abilities.effects.common.FightTargetSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.DistributeCountersEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanentAmount; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TheGrandEvolution extends CardImpl { - - public TheGrandEvolution(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.SAGA); - this.color.setGreen(true); - this.nightCard = true; - - // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) - SagaAbility sagaAbility = new SagaAbility(this); - - // I -- Mill ten cards. Put up to two creature cards from among the milled cards onto the battlefield. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new TheGrandEvolutionEffect()); - - // II -- Distribute seven +1/+1 counters among any number of target creatures you control. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, - new DistributeCountersEffect(), - new TargetCreaturePermanentAmount(7, StaticFilters.FILTER_CONTROLLED_CREATURES) - ); - - // III -- Until end of turn, creatures you control gain "{1}: This creature fights target creature you don't control." Exile The Grand Evolution, then return it to the battlefield. - Ability ability = new SimpleActivatedAbility( - new FightTargetSourceEffect() - .setText("this creature fights target creature you don't control"), - new GenericManaCost(1) - ); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, - new GainAbilityControlledEffect( - ability, Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURE - ).setText("Until end of turn, creatures you control gain " + - "\"{1}: This creature fights target creature you don't control.\""), - new ExileSourceAndReturnFaceUpEffect() - ); - this.addAbility(sagaAbility); - } - - private TheGrandEvolution(final TheGrandEvolution card) { - super(card); - } - - @Override - public TheGrandEvolution copy() { - return new TheGrandEvolution(this); - } -} - -class TheGrandEvolutionEffect extends OneShotEffect { - - TheGrandEvolutionEffect() { - super(Outcome.Benefit); - staticText = "mill ten cards. Put up to two creature cards from among the milled cards onto the battlefield"; - } - - private TheGrandEvolutionEffect(final TheGrandEvolutionEffect effect) { - super(effect); - } - - @Override - public TheGrandEvolutionEffect copy() { - return new TheGrandEvolutionEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Cards cards = player.millCards(10, source, game); - TargetCard target = new TargetCard(0, 2, Zone.ALL, StaticFilters.FILTER_CARD_CREATURE); - target.withNotTarget(true); - player.choose(Outcome.PutCreatureInPlay, cards, target, source, game); - player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheGreatWork.java b/Mage.Sets/src/mage/cards/t/TheGreatWork.java deleted file mode 100644 index 7db947caf15..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheGreatWork.java +++ /dev/null @@ -1,186 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; -import mage.game.permanent.token.TreasureToken; -import mage.players.Player; -import mage.target.common.TargetOpponent; -import mage.watchers.common.CastFromGraveyardWatcher; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TheGreatWork extends CardImpl { - - public TheGreatWork(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.SAGA); - this.color.setRed(true); - this.nightCard = true; - - // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); - - // I -- The Great Work deals 3 damage to target opponent and each creature they control. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, - new TheGreatWorkEffect(), new TargetOpponent() - ); - - // II -- Create three Treasure tokens. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, - new CreateTokenEffect(new TreasureToken(), 3) - ); - - // III -- Until end of turn, you may cast instant and sorcery spells from any graveyard. If a spell cast this way would be put into a graveyard, exile it instead. Exile The Great Work, then return it to the battlefield. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, new TheGreatWorkCastFromGraveyardEffect(), - new TheGreatWorkReplacementEffect(), new ExileSourceAndReturnFaceUpEffect() - ); - this.addAbility(sagaAbility, new CastFromGraveyardWatcher()); - } - - private TheGreatWork(final TheGreatWork card) { - super(card); - } - - @Override - public TheGreatWork copy() { - return new TheGreatWork(this); - } -} - -class TheGreatWorkEffect extends OneShotEffect { - - TheGreatWorkEffect() { - super(Outcome.Benefit); - staticText = "{this} deals 3 damage to target opponent and each creature they control"; - } - - private TheGreatWorkEffect(final TheGreatWorkEffect effect) { - super(effect); - } - - @Override - public TheGreatWorkEffect copy() { - return new TheGreatWorkEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); - if (player == null) { - return false; - } - player.damage(3, source, game); - for (Permanent permanent : game.getBattlefield().getActivePermanents( - StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game - )) { - permanent.damage(3, source, game); - } - return true; - } -} - -class TheGreatWorkCastFromGraveyardEffect extends AsThoughEffectImpl { - - TheGreatWorkCastFromGraveyardEffect() { - super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "until end of turn, you may cast instant and sorcery spells from any graveyard"; - } - - private TheGreatWorkCastFromGraveyardEffect(final TheGreatWorkCastFromGraveyardEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public TheGreatWorkCastFromGraveyardEffect copy() { - return new TheGreatWorkCastFromGraveyardEffect(this); - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - Card card = game.getCard(objectId); - if (card != null - && affectedControllerId.equals(source.getControllerId()) - && StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(card, game) - && Zone.GRAVEYARD.equals(game.getState().getZone(card.getId()))) { - game.getState().setValue("TheGreatWork", card); - return true; - } - return false; - } -} - -class TheGreatWorkReplacementEffect extends ReplacementEffectImpl { - - TheGreatWorkReplacementEffect() { - super(Duration.EndOfTurn, Outcome.Exile); - staticText = "if a spell cast this way would be put into a graveyard, exile it instead"; - } - - private TheGreatWorkReplacementEffect(final TheGreatWorkReplacementEffect effect) { - super(effect); - } - - @Override - public TheGreatWorkReplacementEffect copy() { - return new TheGreatWorkReplacementEffect(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Card card = (Card) game.getState().getValue("TheGreatWork"); - if (card != null) { - ((ZoneChangeEvent) event).setToZone(Zone.EXILED); - } - return false; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (Zone.GRAVEYARD != ((ZoneChangeEvent) event).getToZone()) { - return false; - } - Card card = game.getCard(event.getSourceId()); - if (card == null || (!card.isInstant(game) && !card.isSorcery(game))) { - return false; - } - CastFromGraveyardWatcher watcher = game.getState().getWatcher(CastFromGraveyardWatcher.class); - return watcher != null - && watcher.spellWasCastFromGraveyard(event.getTargetId(), - game.getState().getZoneChangeCounter(event.getTargetId())); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheGrimCaptain.java b/Mage.Sets/src/mage/cards/t/TheGrimCaptain.java deleted file mode 100644 index 3ec8f196b3f..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheGrimCaptain.java +++ /dev/null @@ -1,112 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.SacrificeOpponentsEffect; -import mage.abilities.keyword.HexproofAbility; -import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInExile; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TheGrimCaptain extends CardImpl { - - public TheGrimCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.SKELETON); - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.PIRATE); - this.power = new MageInt(7); - this.toughness = new MageInt(7); - this.nightCard = true; - this.color.setBlack(true); - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - - // Hexproof - this.addAbility(HexproofAbility.getInstance()); - - // Whenever The Grim Captain attacks, each opponent sacrifices a nonland permanent. Then you may put an exiled creature card used to craft The Grim Captain onto the battlefield under your control tapped and attacking. - Ability ability = new AttacksTriggeredAbility(new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_NON_LAND)); - ability.addEffect(new TheGrimCaptainEffect()); - this.addAbility(ability); - } - - private TheGrimCaptain(final TheGrimCaptain card) { - super(card); - } - - @Override - public TheGrimCaptain copy() { - return new TheGrimCaptain(this); - } -} - -class TheGrimCaptainEffect extends OneShotEffect { - - TheGrimCaptainEffect() { - super(Outcome.Benefit); - staticText = "Then you may put an exiled creature card used to craft {this} " + - "onto the battlefield under your control tapped and attacking"; - } - - private TheGrimCaptainEffect(final TheGrimCaptainEffect effect) { - super(effect); - } - - @Override - public TheGrimCaptainEffect copy() { - return new TheGrimCaptainEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - TargetCard target = new TargetCardInExile( - 0, 1, StaticFilters.FILTER_CARD_CREATURE, - CardUtil.getExileZoneId(game, source, -2) - ); - target.withNotTarget(true); - player.choose(outcome, target, source, game); - Card card = game.getCard(target.getFirstTarget()); - if (card == null) { - return false; - } - player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); - Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); - if (permanent == null) { - return false; - } - game.getCombat().addAttackingCreature(card.getId(), game); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheKamiWar.java b/Mage.Sets/src/mage/cards/t/TheKamiWar.java index 62364fcf76d..05f5d7da75d 100644 --- a/Mage.Sets/src/mage/cards/t/TheKamiWar.java +++ b/Mage.Sets/src/mage/cards/t/TheKamiWar.java @@ -1,29 +1,39 @@ package mage.cards.t; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effects; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SagaChapter; -import mage.constants.SubType; -import mage.constants.TargetController; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; import mage.target.TargetPermanent; +import mage.target.common.TargetCardInGraveyard; import java.util.UUID; /** * @author TheElk801 */ -public final class TheKamiWar extends CardImpl { +public final class TheKamiWar extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanent an opponent controls"); @@ -36,23 +46,25 @@ public final class TheKamiWar extends CardImpl { } public TheKamiWar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{U}{B}{R}{G}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.o.OKagachiMadeManifest.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{W}{U}{B}{R}{G}", + "O-Kagachi Made Manifest", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.DRAGON, SubType.SPIRIT}, "WUBRG" + ); + // The Kami War // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I — Exile target nonland permanent an opponent controls. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, new ExileTargetEffect(), new TargetPermanent(filter) ); // II — Return up to one other target nonland permanent to its owner's hand. Then each opponent discards a card. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new Effects( new ReturnToHandTargetEffect(), new DiscardEachPlayerEffect(TargetController.OPPONENT) @@ -61,10 +73,26 @@ public final class TheKamiWar extends CardImpl { ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // O-Kagachi Made Manifest + this.getRightHalfCard().setPT(6, 6); + + // O-Kagachi Made Manifest is all colors. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new InfoEffect("{this} is all colors"))); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Whenever O-Kagachi Made Manifest attacks, defending player chooses a nonland card in your graveyard. Return that card to your hand. O-Kagachi Made Manifest gets +X/+0 until end of turn, where X is the mana value of that card. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility( + new OKagachiMadeManifestEffect(), false, null, SetTargetPointer.PLAYER + )); } private TheKamiWar(final TheKamiWar card) { @@ -76,3 +104,57 @@ public final class TheKamiWar extends CardImpl { return new TheKamiWar(this); } } + +class OKagachiMadeManifestEffect extends OneShotEffect { + + OKagachiMadeManifestEffect() { + super(Outcome.Benefit); + staticText = "defending player chooses a nonland card in your graveyard. Return that card to your hand. " + + "{this} gets +X/+0 until end of turn, where X is the mana value of that card"; + } + + private OKagachiMadeManifestEffect(final OKagachiMadeManifestEffect effect) { + super(effect); + } + + @Override + public OKagachiMadeManifestEffect copy() { + return new OKagachiMadeManifestEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (controller == null || player == null) { + return false; + } + Card card; + switch (controller.getGraveyard().count(StaticFilters.FILTER_CARD_A_NON_LAND, game)) { + case 0: + return false; + case 1: + card = controller + .getGraveyard() + .getCards(StaticFilters.FILTER_CARD_A_NON_LAND, game) + .stream() + .findFirst() + .orElse(null); + break; + default: + TargetCard target = new TargetCardInGraveyard(StaticFilters.FILTER_CARD_A_NON_LAND); + target.withNotTarget(true); + player.choose(Outcome.ReturnToHand, controller.getGraveyard(), target, source, game); + card = game.getCard(target.getFirstTarget()); + } + if (card == null) { + return false; + } + int manaValue = card.getManaValue(); + player.moveCards(card, Zone.HAND, source, game); + if (manaValue > 0) { + game.addEffect(new BoostSourceEffect(manaValue, 0, Duration.EndOfTurn), source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheLegendOfKuruk.java b/Mage.Sets/src/mage/cards/t/TheLegendOfKuruk.java index 17e8d452e98..55fb361f9f3 100644 --- a/Mage.Sets/src/mage/cards/t/TheLegendOfKuruk.java +++ b/Mage.Sets/src/mage/cards/t/TheLegendOfKuruk.java @@ -1,36 +1,45 @@ package mage.cards.t; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.common.WaterbendCost; import mage.abilities.effects.Effects; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; +import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; import mage.abilities.effects.keyword.ScryEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.ExhaustAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SagaChapter; import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; +import mage.game.permanent.token.SpiritWorldToken; import java.util.UUID; /** * @author TheElk801 */ -public final class TheLegendOfKuruk extends CardImpl { +public final class TheLegendOfKuruk extends TransformingDoubleFacedCard { public TheLegendOfKuruk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.a.AvatarKuruk.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{U}{U}", + "Avatar Kuruk", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.AVATAR}, "U" + ); + // The Legend of Kuruk // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I, II -- Scry 2, then draw a card. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new Effects( new ScryEffect(2, false), new DrawCardSourceControllerEffect(1).concatBy(", then") @@ -38,9 +47,19 @@ public final class TheLegendOfKuruk extends CardImpl { ); // III -- Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Avatar Kuruk + this.getRightHalfCard().setPT(4, 3); + + // Whenever you cast a spell, create a 1/1 colorless Spirit creature token with "This token can't block or be blocked by non-Spirit creatures." + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new CreateTokenEffect(new SpiritWorldToken()), StaticFilters.FILTER_SPELL_A, false + )); + + // Exhaust -- Waterbend {20}: Take an extra turn after this one. + this.getRightHalfCard().addAbility(new ExhaustAbility(new AddExtraTurnControllerEffect(), new WaterbendCost(20))); } private TheLegendOfKuruk(final TheLegendOfKuruk card) { diff --git a/Mage.Sets/src/mage/cards/t/TheLegendOfKyoshi.java b/Mage.Sets/src/mage/cards/t/TheLegendOfKyoshi.java index a07bc9bd4a9..162268e8b3e 100644 --- a/Mage.Sets/src/mage/cards/t/TheLegendOfKyoshi.java +++ b/Mage.Sets/src/mage/cards/t/TheLegendOfKyoshi.java @@ -1,20 +1,25 @@ package mage.cards.t; +import mage.Mana; +import mage.abilities.Ability; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; import mage.abilities.dynamicvalue.common.GreatestAmongPermanentsValue; import mage.abilities.effects.Effects; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.keyword.EarthbendTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.mana.DynamicManaAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SagaChapter; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.StaticFilters; import mage.target.common.TargetControlledLandPermanent; import java.util.UUID; @@ -22,27 +27,29 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TheLegendOfKyoshi extends CardImpl { +public final class TheLegendOfKyoshi extends TransformingDoubleFacedCard { public TheLegendOfKyoshi(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.a.AvatarKyoshi.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{4}{G}{G}", + "Avatar Kyoshi", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.AVATAR}, "" + ); + // The Legend of Kyoshi // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I -- Draw cards equal to the greatest power among creatures you control. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new DrawCardSourceControllerEffect(GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES) .setText("draw cards equal to the greatest power among creatures you control") ); // II -- Earthbend X, where X is the number of cards in your hand. That land becomes an Island in addition to its other types. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new Effects( new EarthbendTargetEffect(CardsInControllerHandCount.ANY, true) .setText("earthbend X, where X is the number of cards in your hand"), @@ -52,9 +59,27 @@ public final class TheLegendOfKyoshi extends CardImpl { ); // III -- Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility.addHint(GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES.getHint())); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + this.getLeftHalfCard().addAbility(sagaAbility.addHint(GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES.getHint())); + + // Avatar Kyoshi + this.getRightHalfCard().setPT(5, 4); + + // Lands you control have trample and hexproof. + Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS + )); + ability.addEffect(new GainAbilityControlledEffect( + HexproofAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS + ).setText("and hexproof")); + this.getRightHalfCard().addAbility(ability); + + // {T}: Add X mana of any one color, where X is the greatest power among creatures you control. + this.getRightHalfCard().addAbility(new DynamicManaAbility( + Mana.AnyMana(1), GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES, + new TapSourceCost(), "add X mana of any one color, " + + "where X is the greatest power among creatures you control", true + ).addHint(GreatestAmongPermanentsValue.POWER_CONTROLLED_CREATURES.getHint())); } private TheLegendOfKyoshi(final TheLegendOfKyoshi card) { diff --git a/Mage.Sets/src/mage/cards/t/TheLegendOfRoku.java b/Mage.Sets/src/mage/cards/t/TheLegendOfRoku.java index 37aa1bd902f..2914dd2741b 100644 --- a/Mage.Sets/src/mage/cards/t/TheLegendOfRoku.java +++ b/Mage.Sets/src/mage/cards/t/TheLegendOfRoku.java @@ -1,46 +1,59 @@ package mage.cards.t; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; import mage.abilities.effects.mana.AddManaOfAnyColorEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FirebendingAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SagaChapter; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.game.permanent.token.DragonFirebendingToken; import java.util.UUID; /** * @author TheElk801 */ -public final class TheLegendOfRoku extends CardImpl { +public final class TheLegendOfRoku extends TransformingDoubleFacedCard { public TheLegendOfRoku(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.a.AvatarRoku.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{R}{R}", + "Avatar Roku", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.AVATAR}, "" + ); + // The Legend of Roku // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I -- Exile the top three cards of your library. Until the end of your next turn, you may play those cards. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new ExileTopXMayPlayUntilEffect(3, Duration.UntilEndOfYourNextTurn) ); // II -- Add one mana of any color. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new AddManaOfAnyColorEffect(1)); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new AddManaOfAnyColorEffect(1)); // III -- Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Avatar Roku + this.getRightHalfCard().setPT(4, 4); + + // Firebending 4 + this.getRightHalfCard().addAbility(new FirebendingAbility(4)); + + // {8}: Create a 4/4 red Dragon creature token with flying and firebending 4. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility( + new CreateTokenEffect(new DragonFirebendingToken()), new GenericManaCost(8) + )); } private TheLegendOfRoku(final TheLegendOfRoku card) { diff --git a/Mage.Sets/src/mage/cards/t/TheLegendOfYangchen.java b/Mage.Sets/src/mage/cards/t/TheLegendOfYangchen.java index e38cae32e99..ab1dd21f630 100644 --- a/Mage.Sets/src/mage/cards/t/TheLegendOfYangchen.java +++ b/Mage.Sets/src/mage/cards/t/TheLegendOfYangchen.java @@ -1,18 +1,22 @@ package mage.cards.t; import mage.abilities.Ability; +import mage.abilities.common.CastSecondSpellTriggeredAbility; import mage.abilities.common.SagaAbility; import mage.abilities.effects.Effects; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.keyword.AirbendTargetEffect; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; +import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; @@ -29,23 +33,31 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TheLegendOfYangchen extends CardImpl { +public final class TheLegendOfYangchen extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterNonlandPermanent("other target nonland permanent"); + + static { + filter.add(AnotherPredicate.instance); + } public TheLegendOfYangchen(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.a.AvatarYangchen.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{3}{W}{W}", + "Avatar Yangchen", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.AVATAR}, "" + ); + // The Legend of Yangchen // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I -- Starting with you, each player chooses up to one permanent with mana value 3 or greater from among permanents your opponents control. Exile those permanents. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new TheLegendOfYangchenEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new TheLegendOfYangchenEffect()); // II -- You may have target opponent draw three cards. If you do, draw three cards. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new Effects( new DrawCardTargetEffect(3).setText("have target opponent draw three cards. If you do"), new DrawCardSourceControllerEffect(3).concatBy(",") @@ -53,9 +65,19 @@ public final class TheLegendOfYangchen extends CardImpl { ); // III -- Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Avatar Yangchen + this.getRightHalfCard().setPT(4, 5); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever you cast your second spell each turn, airbend up to one other target nonland permanent. + Ability ability = new CastSecondSpellTriggeredAbility(new AirbendTargetEffect()); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.getRightHalfCard().addAbility(ability); } private TheLegendOfYangchen(final TheLegendOfYangchen card) { diff --git a/Mage.Sets/src/mage/cards/t/TheLongReachOfNight.java b/Mage.Sets/src/mage/cards/t/TheLongReachOfNight.java index c883920df4b..241c6b8d50d 100644 --- a/Mage.Sets/src/mage/cards/t/TheLongReachOfNight.java +++ b/Mage.Sets/src/mage/cards/t/TheLongReachOfNight.java @@ -1,48 +1,83 @@ package mage.cards.t; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SagaAbility; import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.SacrificeOpponentsUnlessPayEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.MenaceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SagaChapter; import mage.constants.SubType; +import mage.filter.FilterCard; import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.card.DefendingPlayerOwnsCardPredicate; +import mage.game.Game; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** * @author TheElk801 */ -public final class TheLongReachOfNight extends CardImpl { +public final class TheLongReachOfNight extends TransformingDoubleFacedCard { + + private static final FilterCard filter + = new FilterCreatureCard("creature cards in defending player's graveyard"); + + static { + filter.add(DefendingPlayerOwnsCardPredicate.instance); + } + + private static final DynamicValue xValue = new CardsInAllGraveyardsCount(filter); public TheLongReachOfNight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.a.AnimusOfNightsReach.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{3}{B}", + "Animus of Night's Reach", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "B" + ); + // The Long Reach of Night // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I, II — Each opponent sacrifices a creature unless they discard a card. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new SacrificeOpponentsUnlessPayEffect( new DiscardCardCost(), StaticFilters.FILTER_PERMANENT_CREATURE ) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect() + this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect() ); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Animus of Night's Reach + this.getRightHalfCard().setPT(0, 4); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // Whenever Animus of Night's Reach attacks, it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new BoostSourceEffect( + xValue, StaticValue.get(0), Duration.EndOfTurn + ).setText("it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard")).addHint(AnimusOfNightsReachHint.instance)); } private TheLongReachOfNight(final TheLongReachOfNight card) { @@ -54,3 +89,28 @@ public final class TheLongReachOfNight extends CardImpl { return new TheLongReachOfNight(this); } } + +enum AnimusOfNightsReachHint implements Hint { + instance; + + @Override + public String getText(Game game, Ability ability) { + return "Cards in each opponent's graveyard:
" + + game + .getOpponents(ability.getControllerId()) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .map(player -> player + .getName() + + ": " + player + .getGraveyard() + .count(StaticFilters.FILTER_CARD_CREATURE, game)) + .collect(Collectors.joining("
")); + } + + @Override + public AnimusOfNightsReachHint copy() { + return instance; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheLordMasterOfHell.java b/Mage.Sets/src/mage/cards/t/TheLordMasterOfHell.java deleted file mode 100644 index 86f366c3704..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheLordMasterOfHell.java +++ /dev/null @@ -1,65 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.TargetController; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TheLordMasterOfHell extends CardImpl { - - private static final FilterCard filter = new FilterCard("noncreature, nonland cards in your graveyard"); - - static { - filter.add(Predicates.not(CardType.CREATURE.getPredicate())); - filter.add(Predicates.not(CardType.LAND.getPredicate())); - } - - private static final DynamicValue xValue = new CardsInControllerGraveyardCount(filter); - private static final Hint hint = new ValueHint("Noncreature, nonland cards in your graveyard", xValue); - - public TheLordMasterOfHell(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.DEMON); - this.subtype.add(SubType.NOBLE); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.nightCard = true; - this.color.setBlue(true); - this.color.setRed(true); - - // Starfall -- Whenever The Lord Master of Hell attacks, it deals X damage to each opponent, where X is the number of noncreature, nonland cards in your graveyard. - this.addAbility(new AttacksTriggeredAbility(new DamagePlayersEffect( - xValue, TargetController.OPPONENT - ).setText("it deals X damage to each opponent, where X is " + - "the number of noncreature, nonland cards in your graveyard")) - .withFlavorWord("Starfall").addHint(hint)); - } - - private TheLordMasterOfHell(final TheLordMasterOfHell card) { - super(card); - } - - @Override - public TheLordMasterOfHell copy() { - return new TheLordMasterOfHell(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheModernAge.java b/Mage.Sets/src/mage/cards/t/TheModernAge.java index 8377efec220..191e2cd3e21 100644 --- a/Mage.Sets/src/mage/cards/t/TheModernAge.java +++ b/Mage.Sets/src/mage/cards/t/TheModernAge.java @@ -3,9 +3,9 @@ package mage.cards.t; import mage.abilities.common.SagaAbility; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SagaChapter; import mage.constants.SubType; @@ -15,28 +15,35 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TheModernAge extends CardImpl { +public final class TheModernAge extends TransformingDoubleFacedCard { public TheModernAge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.v.VectorGlider.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{U}", + "Vector Glider", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "U" + ); + // The Modern Age // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I, II — Draw a card, then discard a card. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new DrawDiscardControllerEffect(1, 1) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Vector Glider + this.getRightHalfCard().setPT(2, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); } private TheModernAge(final TheModernAge card) { diff --git a/Mage.Sets/src/mage/cards/t/TheMyriadPools.java b/Mage.Sets/src/mage/cards/t/TheMyriadPools.java deleted file mode 100644 index bcde9f4288f..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheMyriadPools.java +++ /dev/null @@ -1,95 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.CastSpellPaidBySourceTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CopyEffect; -import mage.abilities.mana.BlueManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SuperType; -import mage.filter.FilterSpell; -import mage.filter.StaticFilters; -import mage.filter.predicate.mageobject.PermanentPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentCard; -import mage.game.stack.Spell; -import mage.players.Player; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author jeffwadsworth - */ -public class TheMyriadPools extends CardImpl { - - private static final FilterSpell filter = new FilterSpell("a permanent spell"); - - static { - filter.add(PermanentPredicate.instance); - } - - public TheMyriadPools(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.LAND}, null); - this.supertype.add(SuperType.LEGENDARY); - - // this is the second face of The Everflowing Well - this.nightCard = true; - - // {T}: Add {U}. - this.addAbility(new BlueManaAbility()); - - // Whenever you cast a permanent spell using mana produced by The Myriad Pools, up to one other target permanent you control becomes a copy of that spell until end of turn. - Ability ability = new CastSpellPaidBySourceTriggeredAbility(new TheMyriadPoolsCopyEffect(), filter, false); - ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_TARGET_PERMANENT)); - this.addAbility(ability); - } - - private TheMyriadPools(final TheMyriadPools card) { - super(card); - } - - @Override - public TheMyriadPools copy() { - return new TheMyriadPools(this); - } -} - -class TheMyriadPoolsCopyEffect extends OneShotEffect { - - TheMyriadPoolsCopyEffect() { - super(Outcome.Neutral); - this.staticText = "up to one other target permanent you control becomes a copy of that spell until end of turn"; - } - - private TheMyriadPoolsCopyEffect(final TheMyriadPoolsCopyEffect effect) { - super(effect); - } - - @Override - public TheMyriadPoolsCopyEffect copy() { - return new TheMyriadPoolsCopyEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetPermanentToCopyTo = game.getPermanent(getTargetPointer().getFirst(game, source)); - Player controller = game.getPlayer(source.getControllerId()); - Object spell = getValue("spellCast"); - if (controller == null || targetPermanentToCopyTo == null || !(spell instanceof Spell)) { - return false; - } - Permanent newBluePrint = new PermanentCard(((Spell)spell).getCard(), source.getControllerId(), game); - newBluePrint.assignNewId(); - CopyEffect copyEffect = new CopyEffect(Duration.EndOfTurn, newBluePrint, targetPermanentToCopyTo.getId()); - Ability newAbility = source.copy(); - copyEffect.init(newAbility, game); - game.addEffect(copyEffect, newAbility); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheRestorationOfEiganjo.java b/Mage.Sets/src/mage/cards/t/TheRestorationOfEiganjo.java index 3de02b60f26..645601c3a08 100644 --- a/Mage.Sets/src/mage/cards/t/TheRestorationOfEiganjo.java +++ b/Mage.Sets/src/mage/cards/t/TheRestorationOfEiganjo.java @@ -1,15 +1,17 @@ package mage.cards.t; +import mage.abilities.common.AttacksOrBlocksTriggeredAbility; import mage.abilities.common.SagaAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SagaChapter; @@ -18,6 +20,7 @@ import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.game.permanent.token.SpiritToken; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInYourGraveyard; @@ -26,7 +29,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TheRestorationOfEiganjo extends CardImpl { +public final class TheRestorationOfEiganjo extends TransformingDoubleFacedCard { private static final FilterCard filter2 = new FilterPermanentCard("permanent card with mana value 2 or less from your graveyard"); @@ -36,17 +39,19 @@ public final class TheRestorationOfEiganjo extends CardImpl { } public TheRestorationOfEiganjo(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.a.ArchitectOfRestoration.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{W}", + "Architect of Restoration", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.FOX, SubType.MONK}, "W" + ); + // The Restoration of Eiganjo // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I - Search your library for a basic Plains card, reveal it, put it into your hand, then shuffle. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, new SearchLibraryPutInHandEffect( + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new SearchLibraryPutInHandEffect( new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_PLAINS), true ) ); @@ -57,16 +62,24 @@ public final class TheRestorationOfEiganjo extends CardImpl { ); ability.addTarget(new TargetCardInYourGraveyard(filter2)); sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, new DoWhenCostPaid( + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new DoWhenCostPaid( ability, new DiscardCardCost(), "Discard a card?" ) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Architect of Restoration + this.getRightHalfCard().setPT(3, 4); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Whenever Architect of Restoration attacks or blocks, create a 1/1 colorless Spirit creature token. + this.getRightHalfCard().addAbility(new AttacksOrBlocksTriggeredAbility(new CreateTokenEffect(new SpiritToken()), false)); } private TheRestorationOfEiganjo(final TheRestorationOfEiganjo card) { diff --git a/Mage.Sets/src/mage/cards/t/TheRiseOfSozin.java b/Mage.Sets/src/mage/cards/t/TheRiseOfSozin.java index 78a8b2bd579..3383f91df6a 100644 --- a/Mage.Sets/src/mage/cards/t/TheRiseOfSozin.java +++ b/Mage.Sets/src/mage/cards/t/TheRiseOfSozin.java @@ -1,55 +1,83 @@ package mage.cards.t; +import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effects; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseACardNameEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FirebendingAbility; +import mage.abilities.keyword.MenaceAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SagaChapter; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterCard; import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.card.OwnerIdPredicate; import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetOpponent; +import mage.util.CardUtil; +import java.util.Objects; +import java.util.Set; import java.util.UUID; /** * @author TheElk801 */ -public final class TheRiseOfSozin extends CardImpl { +public final class TheRiseOfSozin extends TransformingDoubleFacedCard { public TheRiseOfSozin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}{B}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.f.FireLordSozin.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{4}{B}{B}", + "Fire Lord Sozin", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE}, "B" + ); + // The Rise of Sozin // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I -- Destroy all creatures. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES) + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES) ); // II -- Choose a card name. Search target opponent's graveyard, hand, and library for up to four cards with that name and exile them. Then that player shuffles. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new Effects( new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.ALL), new TheRiseOfSozinEffect() ), new TargetOpponent() ); // III -- Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Fire Lord Sozin + this.getRightHalfCard().setPT(5, 5); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // Firebending 3 + this.getRightHalfCard().addAbility(new FirebendingAbility(3)); + + // Whenever Fire Lord Sozin deals combat damage to a player, you may pay {X}. When you do, put any number of target creature cards with total mana value X or less from that player's graveyard onto the battlefield under your control. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new FireLordSozinEffect())); } private TheRiseOfSozin(final TheRiseOfSozin card) { @@ -83,3 +111,94 @@ class TheRiseOfSozinEffect extends SearchTargetGraveyardHandLibraryForCardNameAn return applySearchAndExile(game, source, chosenCardName, getTargetPointer().getFirst(game, source)); } } + +class FireLordSozinEffect extends OneShotEffect { + + FireLordSozinEffect() { + super(Outcome.Benefit); + staticText = "you may pay {X}. When you do, put any number of target creature cards with " + + "total mana value X or less from that player's graveyard onto the battlefield under your control"; + } + + private FireLordSozinEffect(final FireLordSozinEffect effect) { + super(effect); + } + + @Override + public FireLordSozinEffect copy() { + return new FireLordSozinEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + if (!controller.chooseUse(Outcome.BoostCreature, "Pay {X}?", source, game)) { + return false; + } + int xValue = controller.announceX(0, Integer.MAX_VALUE, "Announce the value for {X}", game, source, true); + ManaCosts cost = new ManaCostsImpl<>("{X}"); + cost.add(new GenericManaCost(xValue)); + if (!cost.pay(source, game, source, source.getControllerId(), false, null)) { + return false; + } + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), false); + ability.addTarget(new FireLordSozinTarget((UUID) getValue("damagedPlayer"), xValue)); + game.fireReflexiveTriggeredAbility(ability, source); + return true; + } +} + +class FireLordSozinTarget extends TargetCardInGraveyard { + + private final int xValue; + + private static final FilterCard makeFilter(UUID ownerId, int xValue) { + FilterCard filter = new FilterCreatureCard("creature cards with total mana value " + xValue + " or less from that player's graveyard"); + filter.add(new OwnerIdPredicate(ownerId)); + return filter; + } + + FireLordSozinTarget(UUID ownerId, int xValue) { + super(0, Integer.MAX_VALUE, makeFilter(ownerId, xValue), false); + this.xValue = xValue; + } + + private FireLordSozinTarget(final FireLordSozinTarget target) { + super(target); + this.xValue = target.xValue; + } + + @Override + public FireLordSozinTarget copy() { + return new FireLordSozinTarget(this); + } + + @Override + public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) { + return super.canTarget(playerId, id, source, game) + && CardUtil.checkCanTargetTotalValueLimit(this.getTargets(), id, MageObject::getManaValue, xValue, game); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) { + return CardUtil.checkPossibleTargetsTotalValueLimit( + this.getTargets(), + super.possibleTargets(sourceControllerId, source, game), + MageObject::getManaValue, xValue, game + ); + } + + @Override + public String getMessage(Game game) { + // shows selected total + int selectedValue = this.getTargets().stream() + .map(game::getObject) + .filter(Objects::nonNull) + .mapToInt(MageObject::getManaValue) + .sum(); + return super.getMessage(game) + " (selected total mana value " + selectedValue + ")"; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheSentryGoldenGuardian.java b/Mage.Sets/src/mage/cards/t/TheSentryGoldenGuardian.java new file mode 100644 index 00000000000..b75edce7f1b --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheSentryGoldenGuardian.java @@ -0,0 +1,57 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.IndestructibleAbility; +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.game.permanent.token.TheVoidToken; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TheSentryGoldenGuardian extends CardImpl { + + public TheSentryGoldenGuardian(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.HERO); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Indestructible + this.addAbility(IndestructibleAbility.getInstance()); + + // When The Sentry enters, target opponent creates The Void, a legendary 5/5 black Horror Villain creature token with flying, indestructible, and "The Void attacks each combat if able." + Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenTargetEffect(new TheVoidToken())); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + private TheSentryGoldenGuardian(final TheSentryGoldenGuardian card) { + super(card); + } + + @Override + public TheSentryGoldenGuardian copy() { + return new TheSentryGoldenGuardian(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheShatteredStatesEra.java b/Mage.Sets/src/mage/cards/t/TheShatteredStatesEra.java index 69b38aa04b7..4b3ee17b6d5 100644 --- a/Mage.Sets/src/mage/cards/t/TheShatteredStatesEra.java +++ b/Mage.Sets/src/mage/cards/t/TheShatteredStatesEra.java @@ -8,9 +8,9 @@ import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SagaChapter; @@ -22,20 +22,22 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TheShatteredStatesEra extends CardImpl { +public final class TheShatteredStatesEra extends TransformingDoubleFacedCard { public TheShatteredStatesEra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{R}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.n.NamelessConqueror.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{4}{R}", + "Nameless Conqueror", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SAMURAI}, "R" + ); + // The Shattered States Era // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I — Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, new Effects( new GainControlTargetEffect(Duration.EndOfTurn), new UntapTargetEffect().setText("Untap it."), @@ -47,19 +49,27 @@ public final class TheShatteredStatesEra extends CardImpl { // II — Creatures you control get +1/+0 until end of turn. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, new BoostControlledEffect( + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new BoostControlledEffect( 1, 0, Duration.EndOfTurn ) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, + this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect() ); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Nameless Conqueror + this.getRightHalfCard().setPT(3, 3); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); } private TheShatteredStatesEra(final TheShatteredStatesEra card) { diff --git a/Mage.Sets/src/mage/cards/t/TheShire.java b/Mage.Sets/src/mage/cards/t/TheShire.java index 1bfbc46d91b..e6744fbc6e1 100644 --- a/Mage.Sets/src/mage/cards/t/TheShire.java +++ b/Mage.Sets/src/mage/cards/t/TheShire.java @@ -3,7 +3,7 @@ package mage.cards.t; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.common.YouControlPermanentCondition; +import mage.abilities.condition.common.YouControlALegendaryCreatureCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -13,9 +13,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SuperType; -import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.permanent.token.FoodToken; import mage.target.common.TargetControlledPermanent; @@ -26,21 +24,14 @@ import java.util.UUID; */ public final class TheShire extends CardImpl { - private static final FilterPermanent filter = new FilterControlledCreaturePermanent("a legendary creature"); - - static { - filter.add(SuperType.LEGENDARY.getPredicate()); - } - - private static final YouControlPermanentCondition condition = new YouControlPermanentCondition(filter); - public TheShire(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); this.supertype.add(SuperType.LEGENDARY); // The Shire enters the battlefield tapped unless you control a legendary creature. - this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); + this.addAbility(new EntersBattlefieldTappedUnlessAbility(YouControlALegendaryCreatureCondition.instance) + .addHint(YouControlALegendaryCreatureCondition.getHint())); // {T}: Add {G}. this.addAbility(new GreenManaAbility()); diff --git a/Mage.Sets/src/mage/cards/t/TheThing.java b/Mage.Sets/src/mage/cards/t/TheThing.java new file mode 100644 index 00000000000..456312ec728 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheThing.java @@ -0,0 +1,106 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.condition.common.CastNoncreatureSpellThisTurnCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoWhenCostPaid; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; + +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class TheThing extends CardImpl { + + public TheThing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.HERO); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // At the beginning of combat on your turn, if you've cast a noncreature spell this turn, put four +1/+1 counters on The Thing. + this.addAbility(new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4))) + .withInterveningIf(CastNoncreatureSpellThisTurnCondition.instance) + .addHint(CastNoncreatureSpellThisTurnCondition.getHint())); + + // Whenever The Thing attacks, you may pay {R}{G}{W}{U}. When you do, double the number of each kind of counter on any number of target permanents you control. + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new TheThingEffect(), false); + ability.addTarget(new TargetPermanent(0, Integer.MAX_VALUE, StaticFilters.FILTER_CONTROLLED_PERMANENTS)); + this.addAbility(new AttacksTriggeredAbility(new DoWhenCostPaid( + ability, new ManaCostsImpl<>("{R}{G}{W}{U}"), "Pay {R}{G}{W}{U}?" + ))); + } + + private TheThing(final TheThing card) { + super(card); + } + + @Override + public TheThing copy() { + return new TheThing(this); + } +} + +class TheThingEffect extends OneShotEffect { + + TheThingEffect() { + super(Outcome.Benefit); + staticText = "double the number of each kind of counter on any number of target permanents you control"; + } + + private TheThingEffect(final TheThingEffect effect) { + super(effect); + } + + @Override + public TheThingEffect copy() { + return new TheThingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent == null) { + continue; + } + Set counters = permanent + .getCounters(game) + .values() + .stream() + .map(Counter::copy) + .collect(Collectors.toSet()); + for (Counter counter : counters) { + permanent.addCounters(counter, source, game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TheTombOfAclazotz.java b/Mage.Sets/src/mage/cards/t/TheTombOfAclazotz.java deleted file mode 100644 index 18e338ca97f..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheTombOfAclazotz.java +++ /dev/null @@ -1,283 +0,0 @@ -package mage.cards.t; - -import mage.MageIdentifier; -import mage.MageObject; -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.SpellAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.counter.AddCounterEnteringCreatureEffect; -import mage.abilities.mana.BlackManaAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.Spell; -import mage.game.stack.StackObject; -import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; -import mage.util.SubTypes; -import mage.watchers.Watcher; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * @author jeffwadsworth - */ -public class TheTombOfAclazotz extends CardImpl { - - public TheTombOfAclazotz(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, null); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.CAVE); - - // this is the second face of Tarrian's Journal - this.nightCard = true; - - // {T}: Add {B}. - this.addAbility(new BlackManaAbility()); - - // You may cast a creature spell from your graveyard this turn. If you do, it enters with a finality counter on it and is a Vampire in addition to its other types. - Ability castSpellAbility = new SimpleActivatedAbility(new TheTombOfAclazotzEffect(), new TapSourceCost()); - castSpellAbility.setIdentifier(MageIdentifier.TheTombOfAclazotzWatcher); - castSpellAbility.addWatcher(new TheTombOfAclazotzWatcher()); - this.addAbility(castSpellAbility); - - } - - private TheTombOfAclazotz(final TheTombOfAclazotz card) { - super(card); - } - - @Override - public TheTombOfAclazotz copy() { - return new TheTombOfAclazotz(this); - } -} - -class TheTombOfAclazotzEffect extends AsThoughEffectImpl { - - TheTombOfAclazotzEffect() { - super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - staticText = "You may cast a creature spell from your graveyard this turn. If you do, it enters with a finality counter on it and is a Vampire in addition to its other types. (If a creature with a finality counter on it would die, exile it instead.)"; - } - - private TheTombOfAclazotzEffect(final TheTombOfAclazotzEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public TheTombOfAclazotzEffect copy() { - return new TheTombOfAclazotzEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - TheTombOfAclazotzWatcher watcher = game.getState().getWatcher(TheTombOfAclazotzWatcher.class); - if (watcher != null) { - watcher.addPlayable(source, game); - watcher.addPlayFromAnywhereEffect(this.getId()); - } - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - throw new IllegalArgumentException("Wrong code usage: can't call applies method on empty affectedAbility"); - } - - @Override - public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) { - TheTombOfAclazotzWatcher watcher = game.getState().getWatcher(TheTombOfAclazotzWatcher.class); - if (watcher == null - || !watcher.checkPermission(playerId, source, game) - || game.getState().getZone(objectId) != Zone.GRAVEYARD) { - return false; - } - Card card = game.getCard(objectId); - return card != null - && affectedAbility instanceof SpellAbility - && card.getOwnerId().equals(playerId) - && card.isCreature(game); - } -} - -class TheTombOfAclazotzWatcher extends Watcher { - - private final Map> morMap = new HashMap<>(); - private UUID playFromAnywhereEffectId; - - TheTombOfAclazotzWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (GameEvent.EventType.CAST_SPELL.equals(event.getType()) - && event.hasApprovingIdentifier(MageIdentifier.TheTombOfAclazotzWatcher)) { - Spell target = game.getSpell(event.getTargetId()); - Card card = target.getCard(); - if (card != null) { - game.getState().addEffect(new AddCounterEnteringCreatureEffect(new MageObjectReference(target.getCard(), game), - CounterType.FINALITY.createInstance(), Outcome.Neutral), - target.getSpellAbility()); - game.getState().addEffect(new AddSubtypeEnteringCreatureEffect(new MageObjectReference(target.getCard(), game), SubType.VAMPIRE, Outcome.Benefit), card.getSpellAbility()); - // Rule 728.2 we must insure the effect is used (creature is cast successfully) before discarding the play effect - UUID playEffectId = this.getPlayFromAnywhereEffect(); - if (playEffectId != null - && game.getContinuousEffects().getApplicableAsThoughEffects(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, game).listIterator().next().getId().equals(playEffectId)) { - // discard the play effect - game.getContinuousEffects().getApplicableAsThoughEffects(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, game).listIterator().next().discard(); - } - } - } - } - - boolean checkPermission(UUID playerId, Ability source, Game game) { - if (!playerId.equals(source.getControllerId())) { - return false; - } - MageObjectReference mor = new MageObjectReference( - source.getSourceId(), source.getStackMomentSourceZCC(), game - ); - return morMap.computeIfAbsent(mor, m -> new HashMap<>()).getOrDefault(playerId, 0) > 0; - } - - void addPlayable(Ability source, Game game) { - MageObjectReference mor = new MageObjectReference( - source.getSourceId(), source.getStackMomentSourceZCC(), game - ); - morMap.computeIfAbsent(mor, m -> new HashMap<>()) - .compute(source.getControllerId(), CardUtil::setOrIncrementValue); - } - - void addPlayFromAnywhereEffect(UUID uuid) { - playFromAnywhereEffectId = uuid; - } - - UUID getPlayFromAnywhereEffect() { - return playFromAnywhereEffectId; - } - - @Override - public void reset() { - morMap.clear(); - super.reset(); - } - -} - -class AddSubtypeEnteringCreatureEffect extends ReplacementEffectImpl { - - private final MageObjectReference mor; - private final SubType subType; - - AddSubtypeEnteringCreatureEffect(MageObjectReference mor, SubType subType, Outcome outcome) { - super(Duration.WhileOnBattlefield, outcome); - this.mor = mor; - this.subType = subType; - } - - private AddSubtypeEnteringCreatureEffect(final AddSubtypeEnteringCreatureEffect effect) { - super(effect); - this.mor = effect.mor; - this.subType = effect.subType; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.CAST_SPELL_LATE; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - MageObject spell = game.getObject(event.getSourceId()); - return spell != null && mor.refersTo(spell, game); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Spell target = game.getSpell(event.getSourceId()); - if (target != null) { - AddCardSubTypeEnteringTargetEffect effect = new AddCardSubTypeEnteringTargetEffect(mor, subType, Duration.WhileOnBattlefield); - effect.setTargetPointer(new FixedTarget(target, game)); - game.addEffect(effect, source); - } - return false; - } - - @Override - public AddSubtypeEnteringCreatureEffect copy() { - return new AddSubtypeEnteringCreatureEffect(this); - } -} - -class AddCardSubTypeEnteringTargetEffect extends ContinuousEffectImpl { - - private final SubType addedSubType; - private final MageObjectReference mor; - private Card card; - - AddCardSubTypeEnteringTargetEffect(MageObjectReference mor, SubType addedSubType, Duration duration) { - super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); - this.addedSubType = addedSubType; - this.mor = mor; - } - - protected AddCardSubTypeEnteringTargetEffect(final AddCardSubTypeEnteringTargetEffect effect) { - super(effect); - this.addedSubType = effect.addedSubType; - this.mor = effect.mor; - this.card = effect.card; - } - - @Override - public boolean apply(Game game, Ability source) { - Spell spell = game.getSpell(getTargetPointer().getFirst(game, source)); - MageObject target = game.getObject(getTargetPointer().getFirst(game, source)); - if (spell != null) { - card = spell.getCard(); - } - for (StackObject stackObject : game.getStack()) { - if (stackObject instanceof Spell - && target != null - && target.equals(stackObject) - && mor.refersTo(target, game)) { - setCreatureSubtype(stackObject, addedSubType, game); - setCreatureSubtype(((Spell) stackObject).getCard(), addedSubType, game); - } - } - if (card != null - && game.getPermanent(card.getId()) != null - && game.getState().getZoneChangeCounter(card.getId()) == mor.getZoneChangeCounter() + 1) { // blinking, etc - game.getPermanent(card.getId()).addSubType(game, addedSubType); - } - return true; - } - - private void setCreatureSubtype(MageObject object, SubType subtype, Game game) { - SubTypes subTypes = game.getState().getCreateMageObjectAttribute(object, game).getSubtype(); - if (!subTypes.contains(subtype)) { - subTypes.add(subtype); - } - } - - @Override - public AddCardSubTypeEnteringTargetEffect copy() { - return new AddCardSubTypeEnteringTargetEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java b/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java deleted file mode 100644 index d29aba1a894..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java +++ /dev/null @@ -1,114 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.abilities.effects.common.MillCardsEachPlayerEffect; -import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCreatureOrPlaneswalker; -import mage.target.targetadjustment.ForEachPlayerTargetsAdjuster; -import mage.target.targetpointer.EachTargetPointer; - -import java.util.Collection; -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * @author TheElk801 - */ -public final class TheTrueScriptures extends CardImpl { - - public TheTrueScriptures(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.SAGA); - this.color.setBlack(true); - this.nightCard = true; - - // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); - - // I -- For each opponent, destroy up to one target creature or planeswalker that player controls. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, false, - ability -> { - ability.addEffect(new DestroyTargetEffect().setTargetPointer(new EachTargetPointer()) - .setText("for each opponent, destroy up to one target creature or planeswalker that player controls")); - ability.addTarget(new TargetCreatureOrPlaneswalker(0,1)); - ability.setTargetAdjuster(new ForEachPlayerTargetsAdjuster(false, true)); - } - ); - - // II -- Each opponent discards three cards, then mills three cards. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, - new DiscardEachPlayerEffect(StaticValue.get(3), false, TargetController.OPPONENT), - new MillCardsEachPlayerEffect(3, TargetController.OPPONENT).setText(", then mills three cards") - ); - - // III -- Put all creature cards from all graveyards onto the battlefield under your control. Exile The True Scriptures, then return it to the battlefield. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, - new TheTrueScripturesEffect(), - new ExileSourceAndReturnFaceUpEffect() - ); - this.addAbility(sagaAbility); - } - - private TheTrueScriptures(final TheTrueScriptures card) { - super(card); - } - - @Override - public TheTrueScriptures copy() { - return new TheTrueScriptures(this); - } -} - -class TheTrueScripturesEffect extends OneShotEffect { - - TheTrueScripturesEffect() { - super(Outcome.Benefit); - staticText = "put all creature cards from all graveyards onto the battlefield under your control"; - } - - private TheTrueScripturesEffect(final TheTrueScripturesEffect effect) { - super(effect); - } - - @Override - public TheTrueScripturesEffect copy() { - return new TheTrueScripturesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Cards cards = new CardsImpl(game - .getState() - .getPlayersInRange(source.getControllerId(), game) - .stream() - .map(game::getPlayer) - .filter(Objects::nonNull) - .map(Player::getGraveyard) - .map(gy -> gy.getCards(StaticFilters.FILTER_CARD_CREATURE, game)) - .flatMap(Collection::stream) - .collect(Collectors.toList())); - return player.moveCards(cards, Zone.BATTLEFIELD, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/t/ThingInTheIce.java b/Mage.Sets/src/mage/cards/t/ThingInTheIce.java index 149beca63ac..e0f3f72026d 100644 --- a/Mage.Sets/src/mage/cards/t/ThingInTheIce.java +++ b/Mage.Sets/src/mage/cards/t/ThingInTheIce.java @@ -1,24 +1,25 @@ package mage.cards.t; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.DefenderAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.ComparisonType; import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.FilterSpell; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import java.util.UUID; @@ -26,36 +27,39 @@ import java.util.UUID; /** * @author fireshoes */ -public final class ThingInTheIce extends CardImpl { +public final class ThingInTheIce extends TransformingDoubleFacedCard { private static final FilterSpell filter = new FilterSpell("an instant or sorcery spell"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("non-Horror creatures"); static { filter.add(Predicates.or( CardType.INSTANT.getPredicate(), CardType.SORCERY.getPredicate())); + filter2.add(Predicates.not(SubType.HORROR.getPredicate())); } private static final Condition condition = new SourceHasCounterCondition(CounterType.ICE, ComparisonType.EQUAL_TO, 0); public ThingInTheIce(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(0); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HORROR}, "{1}{U}", + "Awoken Horror", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.KRAKEN, SubType.HORROR}, "U" + ); - this.secondSideCardClazz = mage.cards.a.AwokenHorror.class; + // Thing in the Ice + this.getLeftHalfCard().setPT(0, 4); // Defender - this.addAbility(DefenderAbility.getInstance()); + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // Thing in the Ice enters the battlefield with four ice counters on it. - this.addAbility(new EntersBattlefieldAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.ICE.createInstance(4)).setText("with four ice counters on it") )); // Whenever you cast an instant or sorcery spell, remove an ice counter from Thing in the Ice. Then if it has no ice counters on it, transform it. - this.addAbility(new TransformAbility()); Ability ability = new SpellCastControllerTriggeredAbility( new RemoveCounterSourceEffect(CounterType.ICE.createInstance(1)), filter, false ); @@ -63,7 +67,13 @@ public final class ThingInTheIce extends CardImpl { new TransformSourceEffect(), condition, "Then if it has no ice counters on it, transform it" )); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Awoken Horror + this.getRightHalfCard().setPT(7, 8); + + // When this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands. + this.getRightHalfCard().addAbility(new TransformIntoSourceTriggeredAbility(new ReturnToHandFromBattlefieldAllEffect(filter2))); } private ThingInTheIce(final ThingInTheIce card) { diff --git a/Mage.Sets/src/mage/cards/t/ThousandMoonsSmithy.java b/Mage.Sets/src/mage/cards/t/ThousandMoonsSmithy.java index 7a5010aca01..d499844897d 100644 --- a/Mage.Sets/src/mage/cards/t/ThousandMoonsSmithy.java +++ b/Mage.Sets/src/mage/cards/t/ThousandMoonsSmithy.java @@ -1,16 +1,19 @@ package mage.cards.t; -import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; +import mage.abilities.common.CastSpellPaidBySourceTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.costs.common.TapTargetCost; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.WhiteManaAbility; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; +import mage.filter.FilterSpell; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.TappedPredicate; @@ -22,36 +25,55 @@ import java.util.UUID; /** * @author Susucr */ -public final class ThousandMoonsSmithy extends CardImpl { +public final class ThousandMoonsSmithy extends TransformingDoubleFacedCard { public static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped artifacts and/or creatures you control"); + private static final FilterSpell filter2 = new FilterSpell("an artifact or creature spell"); + static { filter.add(TappedPredicate.UNTAPPED); filter.add(Predicates.or( CardType.CREATURE.getPredicate(), CardType.ARTIFACT.getPredicate() )); + filter2.add(Predicates.or( + CardType.ARTIFACT.getPredicate(), + CardType.CREATURE.getPredicate() + )); } public ThousandMoonsSmithy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{W}{W}"); - this.secondSideCardClazz = mage.cards.b.BarracksOfTheThousand.class; - - this.supertype.add(SuperType.LEGENDARY); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}{W}{W}", + "Barracks of the Thousand", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.LAND}, new SubType[]{}, "" + ); + // Thousand Moons Smithy // When Thousand Moons Smithy enters the battlefield, create a white Gnome Soldier artifact creature token with "This creature's power and toughness are each equal to the number of artifacts and/or creatures you control." - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GnomeSoldierStarStarToken()))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GnomeSoldierStarStarToken()))); // At the beginning of your precombat main phase, you may tap five untapped artifacts and/or creatures you control. If you do, transform Thousand Moons Smithy. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfFirstMainTriggeredAbility( + this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( new DoIfCostPaid( new TransformSourceEffect(), new TapTargetCost(new TargetControlledPermanent(5, filter)) ) )); + + // Barracks of the Thousand + // (Transforms from Thousand Moons Smithy.) + + // {T}: Add {W}. + this.getRightHalfCard().addAbility(new WhiteManaAbility()); + + // Whenever you cast an artifact or creature spell using mana produced by Barracks of the Thousand, create a white Gnome Soldier artifact creature token with "This creature's power and toughness are each equal to the number of artifacts and/or creatures you control." + this.getRightHalfCard().addAbility(new CastSpellPaidBySourceTriggeredAbility( + new CreateTokenEffect(new GnomeSoldierStarStarToken()), + filter2, false + )); } private ThousandMoonsSmithy(final ThousandMoonsSmithy card) { diff --git a/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java b/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java index 58d9fdb799e..4296d7dc735 100644 --- a/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java +++ b/Mage.Sets/src/mage/cards/t/ThrabenGargoyle.java @@ -1,39 +1,43 @@ - package mage.cards.t; -import java.util.UUID; - -import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.DefenderAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; + +import java.util.UUID; /** * @author fireshoes */ -public final class ThrabenGargoyle extends CardImpl { +public final class ThrabenGargoyle extends TransformingDoubleFacedCard { public ThrabenGargoyle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); - this.subtype.add(SubType.GARGOYLE); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GARGOYLE}, "{1}", + "Stonewing Antagonizer", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GARGOYLE, SubType.HORROR}, "" + ); - this.secondSideCardClazz = mage.cards.s.StonewingAntagonizer.class; + // Thraben Gargoyle + this.getLeftHalfCard().setPT(2, 2); // Defender - this.addAbility(DefenderAbility.getInstance()); + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // {6}: Transform Thraben Gargoyle. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new GenericManaCost(6))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new GenericManaCost(6))); + + // Stonewing Antagonizer + this.getRightHalfCard().setPT(4, 2); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); } private ThrabenGargoyle(final ThrabenGargoyle card) { diff --git a/Mage.Sets/src/mage/cards/t/ThrabenMilitia.java b/Mage.Sets/src/mage/cards/t/ThrabenMilitia.java deleted file mode 100644 index d9998dc5920..00000000000 --- a/Mage.Sets/src/mage/cards/t/ThrabenMilitia.java +++ /dev/null @@ -1,40 +0,0 @@ - -package mage.cards.t; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -/** - * @author nantuko - */ -public final class ThrabenMilitia extends CardImpl { - - public ThrabenMilitia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SOLDIER); - this.color.setWhite(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(5); - this.toughness = new MageInt(4); - - this.addAbility(TrampleAbility.getInstance()); - } - - private ThrabenMilitia(final ThrabenMilitia card) { - super(card); - } - - @Override - public ThrabenMilitia copy() { - return new ThrabenMilitia(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/ThrabenSentry.java b/Mage.Sets/src/mage/cards/t/ThrabenSentry.java index 7ccaf78bd07..c4e6be3c500 100644 --- a/Mage.Sets/src/mage/cards/t/ThrabenSentry.java +++ b/Mage.Sets/src/mage/cards/t/ThrabenSentry.java @@ -1,38 +1,41 @@ - package mage.cards.t; -import java.util.UUID; -import mage.MageInt; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.StaticFilters; +import java.util.UUID; + /** * @author nantuko */ -public final class ThrabenSentry extends CardImpl { +public final class ThrabenSentry extends TransformingDoubleFacedCard { public ThrabenSentry(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SOLDIER); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SOLDIER}, "{3}{W}", + "Thraben Militia", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SOLDIER}, "W" + ); - this.secondSideCardClazz = mage.cards.t.ThrabenMilitia.class; + // Thraben Sentry + this.getLeftHalfCard().setPT(2, 2); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - this.addAbility(VigilanceAbility.getInstance()); + this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance()); // Whenever another creature you control dies, you may transform Thraben Sentry. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesCreatureTriggeredAbility(new TransformSourceEffect(), true, StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL)); + this.getLeftHalfCard().addAbility(new DiesCreatureTriggeredAbility(new TransformSourceEffect(), true, StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL)); + + // Thraben Militia + this.getRightHalfCard().setPT(5, 4); + + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); } private ThrabenSentry(final ThrabenSentry card) { diff --git a/Mage.Sets/src/mage/cards/t/ThroneOfTheGrimCaptain.java b/Mage.Sets/src/mage/cards/t/ThroneOfTheGrimCaptain.java index 9a668ec3be6..8df9d2898d1 100644 --- a/Mage.Sets/src/mage/cards/t/ThroneOfTheGrimCaptain.java +++ b/Mage.Sets/src/mage/cards/t/ThroneOfTheGrimCaptain.java @@ -2,27 +2,32 @@ package mage.cards.t; import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.assignment.common.SubTypeAssignment; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.assignment.common.SubTypeAssignment; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MillCardsControllerEffect; -import mage.abilities.keyword.CraftAbility; +import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.abilities.keyword.*; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.TargetController; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInGraveyardBattlefieldOrStack; +import mage.util.CardUtil; import java.util.Objects; import java.util.Set; @@ -32,19 +37,41 @@ import java.util.stream.Collectors; /** * @author TheElk801 */ -public final class ThroneOfTheGrimCaptain extends CardImpl { +public final class ThroneOfTheGrimCaptain extends TransformingDoubleFacedCard { public ThroneOfTheGrimCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - - this.supertype.add(SuperType.LEGENDARY); - this.secondSideCardClazz = mage.cards.t.TheGrimCaptain.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}", + "The Grim Captain", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SKELETON, SubType.SPIRIT, SubType.PIRATE}, "B" + ); + // Throne of the Grim Captain // {T}: Mill two cards. - this.addAbility(new SimpleActivatedAbility(new MillCardsControllerEffect(2), new TapSourceCost())); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new MillCardsControllerEffect(2), new TapSourceCost())); // Craft with a Dinosaur, a Merfolk, a Pirate, and a Vampire {4} - this.addAbility(new CraftAbility("{4}", "a Dinosaur, a Merfolk, a Pirate, and a Vampire", new ThroneOfTheGrimCaptainTarget())); + this.getLeftHalfCard().addAbility(new CraftAbility("{4}", "a Dinosaur, a Merfolk, a Pirate, and a Vampire", new ThroneOfTheGrimCaptainTarget())); + + // The Grim Captain + this.getRightHalfCard().setPT(7, 7); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // Hexproof + this.getRightHalfCard().addAbility(HexproofAbility.getInstance()); + + // Whenever The Grim Captain attacks, each opponent sacrifices a nonland permanent. Then you may put an exiled creature card used to craft The Grim Captain onto the battlefield under your control tapped and attacking. + Ability ability = new AttacksTriggeredAbility(new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_NON_LAND)); + ability.addEffect(new TheGrimCaptainEffect()); + this.getRightHalfCard().addAbility(ability); } private ThroneOfTheGrimCaptain(final ThroneOfTheGrimCaptain card) { @@ -109,3 +136,46 @@ class ThroneOfTheGrimCaptainTarget extends TargetCardInGraveyardBattlefieldOrSta return subtypeAssigner.getRoleCount(cards, game) <= 4; } } + +class TheGrimCaptainEffect extends OneShotEffect { + + TheGrimCaptainEffect() { + super(Outcome.Benefit); + staticText = "Then you may put an exiled creature card used to craft {this} " + + "onto the battlefield under your control tapped and attacking"; + } + + private TheGrimCaptainEffect(final TheGrimCaptainEffect effect) { + super(effect); + } + + @Override + public TheGrimCaptainEffect copy() { + return new TheGrimCaptainEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetCard target = new TargetCardInExile( + 0, 1, StaticFilters.FILTER_CARD_CREATURE, + CardUtil.getExileZoneId(game, source, -2) + ); + target.withNotTarget(true); + player.choose(outcome, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return false; + } + player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, false, null); + Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); + if (permanent == null) { + return false; + } + game.getCombat().addAttackingCreature(card.getId(), game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TicketBoothTunnelOfHate.java b/Mage.Sets/src/mage/cards/t/TicketBoothTunnelOfHate.java new file mode 100644 index 00000000000..8eff7e5a755 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TicketBoothTunnelOfHate.java @@ -0,0 +1,42 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.keyword.ManifestDreadEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.target.common.TargetAttackingCreature; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TicketBoothTunnelOfHate extends RoomCard { + + public TicketBoothTunnelOfHate(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{2}{R}", "{4}{R}{R}"); + + // Ticket Booth + // When you unlock this door, manifest dread. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new ManifestDreadEffect(), false, true)); + + // Tunnel of Hate + // Whenever you attack, target attacking creature gains double strike until end of turn. + Ability ability = new AttacksWithCreaturesTriggeredAbility(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance()), 1); + ability.addTarget(new TargetAttackingCreature()); + this.getRightHalfCard().addAbility(ability); + } + + private TicketBoothTunnelOfHate(final TicketBoothTunnelOfHate card) { + super(card); + } + + @Override + public TicketBoothTunnelOfHate copy() { + return new TicketBoothTunnelOfHate(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TirelessHauler.java b/Mage.Sets/src/mage/cards/t/TirelessHauler.java index 4f3cb398b9a..ec32a2f125e 100644 --- a/Mage.Sets/src/mage/cards/t/TirelessHauler.java +++ b/Mage.Sets/src/mage/cards/t/TirelessHauler.java @@ -1,10 +1,10 @@ package mage.cards.t; -import mage.MageInt; import mage.abilities.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,22 +13,32 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TirelessHauler extends CardImpl { +public final class TirelessHauler extends TransformingDoubleFacedCard { public TirelessHauler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{4}{G}", + "Dire-Strain Brawler", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.secondSideCardClazz = mage.cards.d.DireStrainBrawler.class; + // Tireless Hauler + this.getLeftHalfCard().setPT(4, 5); // Vigilance - this.addAbility(VigilanceAbility.getInstance()); + this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance()); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Dire-Strain Brawler + this.getRightHalfCard().setPT(6, 6); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private TirelessHauler(final TirelessHauler card) { diff --git a/Mage.Sets/src/mage/cards/t/TithingBlade.java b/Mage.Sets/src/mage/cards/t/TithingBlade.java index 4ef97edc81b..409425b040d 100644 --- a/Mage.Sets/src/mage/cards/t/TithingBlade.java +++ b/Mage.Sets/src/mage/cards/t/TithingBlade.java @@ -1,11 +1,16 @@ package mage.cards.t; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.common.SacrificeOpponentsEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.StaticFilters; import java.util.UUID; @@ -13,22 +18,34 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TithingBlade extends CardImpl { +public final class TithingBlade extends TransformingDoubleFacedCard { public TithingBlade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{B}"); - this.secondSideCardClazz = mage.cards.c.ConsumingSepulcher.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{B}", + "Consuming Sepulcher", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "B" + ); + // Tithing Blade // When Tithing Blade enters the battlefield, each opponent sacrifices a creature. - this.addAbility(new EntersBattlefieldTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_CREATURE) )); // Craft with creature {4}{B} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{4}{B}", "creature", "another creature you control " + "or a creature card in your graveyard", CardType.CREATURE.getPredicate()) ); + + // Consuming Sepulcher + // At the beginning of your upkeep, each opponent loses 1 life and you gain 1 life. + Ability ability = new BeginningOfUpkeepTriggeredAbility( + new LoseLifeOpponentsEffect(1) + ); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); + this.getRightHalfCard().addAbility(ability); } private TithingBlade(final TithingBlade card) { diff --git a/Mage.Sets/src/mage/cards/t/TormentedPariah.java b/Mage.Sets/src/mage/cards/t/TormentedPariah.java index 7d5997a1c5c..9dfea2e28e3 100644 --- a/Mage.Sets/src/mage/cards/t/TormentedPariah.java +++ b/Mage.Sets/src/mage/cards/t/TormentedPariah.java @@ -1,10 +1,9 @@ package mage.cards.t; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,22 +12,26 @@ import java.util.UUID; /** * @author nantuko */ -public final class TormentedPariah extends CardImpl { +public final class TormentedPariah extends TransformingDoubleFacedCard { public TormentedPariah(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARRIOR); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARRIOR, SubType.WEREWOLF}, "{3}{R}", + "Rampaging Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.r.RampagingWerewolf.class; - - this.power = new MageInt(3); - this.toughness = new MageInt(2); + // Tormented Pariah + this.getLeftHalfCard().setPT(3, 2); // At the beginning of each upkeep, if no spells were cast last turn, transform Tormented Pariah. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Rampaging Werewolf + this.getRightHalfCard().setPT(6, 4); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Rampaging Werewolf. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private TormentedPariah(final TormentedPariah card) { diff --git a/Mage.Sets/src/mage/cards/t/TovolarDireOverlord.java b/Mage.Sets/src/mage/cards/t/TovolarDireOverlord.java index 38c837a9a2b..704e701d151 100644 --- a/Mage.Sets/src/mage/cards/t/TovolarDireOverlord.java +++ b/Mage.Sets/src/mage/cards/t/TovolarDireOverlord.java @@ -1,19 +1,26 @@ package mage.cards.t; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; +import mage.abilities.keyword.TrampleAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; @@ -28,41 +35,68 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TovolarDireOverlord extends CardImpl { +public final class TovolarDireOverlord extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledPermanent("you control three or more Wolves and/or Werewolves"); + private static final FilterPermanent filter2 = new FilterControlledPermanent("a Wolf or Werewolf you control"); static { filter.add(Predicates.or( SubType.WOLF.getPredicate(), SubType.WEREWOLF.getPredicate() )); + filter2.add(Predicates.or( + SubType.WOLF.getPredicate(), + SubType.WEREWOLF.getPredicate() + )); } private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 2); private static final Hint hint = new ValueHint("Wolves and Werewolves you control", new PermanentsOnBattlefieldCount(filter)); public TovolarDireOverlord(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{1}{R}{G}", + "Tovolar, the Midnight Scourge", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "RG" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.t.TovolarTheMidnightScourge.class; + // Tovolar, Dire Overlord + this.getLeftHalfCard().setPT(3, 3); // Whenever a Wolf or Werewolf you control deals combat damage to a player, draw a card. - this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility( - new DrawCardSourceControllerEffect(1), filter, + this.getLeftHalfCard().addAbility(new DealsDamageToAPlayerAllTriggeredAbility( + new DrawCardSourceControllerEffect(1), filter2, false, SetTargetPointer.NONE, true ).setTriggerPhrase("Whenever a Wolf or Werewolf you control deals combat damage to a player, ")); // At the beginning of your upkeep, if you control three or more Wolves and/or Werewolves, it becomes night. Then transform any number of Human Werewolves you control. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TovolarDireOverlordEffect()).withInterveningIf(condition).addHint(hint)); + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new TovolarDireOverlordEffect()).withInterveningIf(condition).addHint(hint)); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Tovolar, the Midnight Scourge + this.getRightHalfCard().setPT(4, 4); + + // Whenever a Wolf or Werewolf you control deals combat damage to a player, draw a card. + this.getRightHalfCard().addAbility(new DealsDamageToAPlayerAllTriggeredAbility( + new DrawCardSourceControllerEffect(1), filter2, + false, SetTargetPointer.NONE, true + )); + + // {X}{R}{G}: Target Wolf or Werewolf you control gets +X/+0 and gains trample until end of turn. + Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn + ).setText("Target Wolf or Werewolf you control gets +X/+0"), new ManaCostsImpl<>("{X}{R}{G}")); + ability.addEffect(new BoostTargetEffect( + GetXValue.instance, StaticValue.get(0), Duration.EndOfTurn + ).setText("and gains trample until end of turn")); + ability.addTarget(new TargetPermanent(filter2)); + this.getRightHalfCard().addAbility(ability); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private TovolarDireOverlord(final TovolarDireOverlord card) { diff --git a/Mage.Sets/src/mage/cards/t/TovolarTheMidnightScourge.java b/Mage.Sets/src/mage/cards/t/TovolarTheMidnightScourge.java deleted file mode 100644 index 4f6a6f75d0a..00000000000 --- a/Mage.Sets/src/mage/cards/t/TovolarTheMidnightScourge.java +++ /dev/null @@ -1,78 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.common.GetXValue; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.Predicates; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TovolarTheMidnightScourge extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledPermanent("a Wolf or Werewolf you control"); - - static { - filter.add(Predicates.or( - SubType.WOLF.getPredicate(), - SubType.WEREWOLF.getPredicate() - )); - } - - public TovolarTheMidnightScourge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setRed(true); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever a Wolf or Werewolf you control deals combat damage to a player, draw a card. - this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility( - new DrawCardSourceControllerEffect(1), filter, - false, SetTargetPointer.NONE, true - )); - - // {X}{R}{G}: Target Wolf or Werewolf you control gets +X/+0 and gains trample until end of turn. - Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect( - TrampleAbility.getInstance(), Duration.EndOfTurn - ).setText("Target Wolf or Werewolf you control gets +X/+0"), new ManaCostsImpl<>("{X}{R}{G}")); - ability.addEffect(new BoostTargetEffect( - GetXValue.instance, StaticValue.get(0), Duration.EndOfTurn - ).setText("and gains trample until end of turn")); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private TovolarTheMidnightScourge(final TovolarTheMidnightScourge card) { - super(card); - } - - @Override - public TovolarTheMidnightScourge copy() { - return new TovolarTheMidnightScourge(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TovolarsHuntmaster.java b/Mage.Sets/src/mage/cards/t/TovolarsHuntmaster.java index 4e075bb75b4..b6e3580e7c3 100644 --- a/Mage.Sets/src/mage/cards/t/TovolarsHuntmaster.java +++ b/Mage.Sets/src/mage/cards/t/TovolarsHuntmaster.java @@ -1,36 +1,78 @@ package mage.cards.t; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.FightTargetsEffect; import mage.abilities.keyword.DayboundAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.permanent.token.WolfToken; +import mage.target.TargetPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class TovolarsHuntmaster extends CardImpl { +public final class TovolarsHuntmaster extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter + = new FilterControlledPermanent("another Wolf or Werewolf you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.or( + SubType.WOLF.getPredicate(), + SubType.WEREWOLF.getPredicate() + )); + } public TovolarsHuntmaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{4}{G}{G}", + "Tovolar's Packleader", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.secondSideCardClazz = mage.cards.t.TovolarsPackleader.class; + // Tovolar's Huntmaster + this.getLeftHalfCard().setPT(6, 6); // Whenever Tovolar's Huntmaster enters the battlefield, create two 2/2 green Wolf creature tokens. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WolfToken(), 2))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WolfToken(), 2))); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Tovolar's Packleader + this.getRightHalfCard().setPT(7, 7); + + // Whenever Tovolar's Packleader enters the battlefield or attacks, create two 2/2 green Wolf creature tokens. + this.getRightHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( + new CreateTokenEffect(new WolfToken(), 2) + )); + + // {2}{G}{G}: Another target Wolf or Werewolf you control fights target creature you don't control. + Ability ability = new SimpleActivatedAbility(new FightTargetsEffect().setText( + "another target Wolf or Werewolf you control fights target creature you don't control" + ), new ManaCostsImpl<>("{2}{G}{G}")); + ability.addTarget(new TargetPermanent(filter)); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); + this.getRightHalfCard().addAbility(ability); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private TovolarsHuntmaster(final TovolarsHuntmaster card) { diff --git a/Mage.Sets/src/mage/cards/t/TovolarsPackleader.java b/Mage.Sets/src/mage/cards/t/TovolarsPackleader.java deleted file mode 100644 index de4fc98fa8e..00000000000 --- a/Mage.Sets/src/mage/cards/t/TovolarsPackleader.java +++ /dev/null @@ -1,75 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.FightTargetsEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.permanent.token.WolfToken; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TovolarsPackleader extends CardImpl { - - private static final FilterPermanent filter - = new FilterControlledPermanent("another Wolf or Werewolf you control"); - - static { - filter.add(AnotherPredicate.instance); - filter.add(Predicates.or( - SubType.WOLF.getPredicate(), - SubType.WEREWOLF.getPredicate() - )); - } - - public TovolarsPackleader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(7); - this.toughness = new MageInt(7); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever Tovolar's Packleader enters the battlefield or attacks, create two 2/2 green Wolf creature tokens. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( - new CreateTokenEffect(new WolfToken(), 2) - )); - - // {2}{G}{G}: Another target Wolf or Werewolf you control fights target creature you don't control. - Ability ability = new SimpleActivatedAbility(new FightTargetsEffect().setText( - "another target Wolf or Werewolf you control fights target creature you don't control" - ), new ManaCostsImpl<>("{2}{G}{G}")); - ability.addTarget(new TargetPermanent(filter)); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private TovolarsPackleader(final TovolarsPackleader card) { - super(card); - } - - @Override - public TovolarsPackleader copy() { - return new TovolarsPackleader(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TownGossipmonger.java b/Mage.Sets/src/mage/cards/t/TownGossipmonger.java index 1ebe153eed6..ca84a843ccc 100644 --- a/Mage.Sets/src/mage/cards/t/TownGossipmonger.java +++ b/Mage.Sets/src/mage/cards/t/TownGossipmonger.java @@ -1,15 +1,17 @@ package mage.cards.t; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.AttacksEachCombatStaticAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.filter.StaticFilters; @@ -18,21 +20,31 @@ import java.util.UUID; /** * @author escplan9 (Derek Monturo - dmontur1 at gmail dot com) */ -public final class TownGossipmonger extends CardImpl { +public final class TownGossipmonger extends TransformingDoubleFacedCard { public TownGossipmonger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); - this.subtype.add(SubType.HUMAN); - this.power = new MageInt(1); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN}, "{W}", + "Incited Rabble", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN}, "R" + ); - this.secondSideCardClazz = mage.cards.i.IncitedRabble.class; + // Town Gossipmonger + this.getLeftHalfCard().setPT(1, 1); // {T}, Tap an untapped creature you control: Transform Town Gossipmonger. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new TransformSourceEffect(), new TapSourceCost()); ability.addCost(new TapTargetCost(StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURE)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Incited Rabble + this.getRightHalfCard().setPT(2, 3); + + // Incited Rabble attacks each combat if able. + this.getRightHalfCard().addAbility(new AttacksEachCombatStaticAbility()); + + // {2}: Incited Rabble gets +1/+0 until end of turn. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{2}"))); } private TownGossipmonger(final TownGossipmonger card) { diff --git a/Mage.Sets/src/mage/cards/t/TreasureCove.java b/Mage.Sets/src/mage/cards/t/TreasureCove.java deleted file mode 100644 index 62aa078d389..00000000000 --- a/Mage.Sets/src/mage/cards/t/TreasureCove.java +++ /dev/null @@ -1,53 +0,0 @@ - -package mage.cards.t; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.mana.ColorlessManaAbility; -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.TargetControlledPermanent; - -/** - * - * @author TheElk801 - */ -public final class TreasureCove extends CardImpl { - - private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Treasure"); - - static { - filter.add(SubType.TREASURE.getPredicate()); - } - - public TreasureCove(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.nightCard = true; - - // {T}: Add {C}. - this.addAbility(new ColorlessManaAbility()); - - // {T}, Sacrifice a Treasure: Draw a card. - Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(filter)); - this.addAbility(ability); - } - - private TreasureCove(final TreasureCove card) { - super(card); - } - - @Override - public TreasureCove copy() { - return new TreasureCove(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TreasureMap.java b/Mage.Sets/src/mage/cards/t/TreasureMap.java index 224fbd8290d..bfaedc3b592 100644 --- a/Mage.Sets/src/mage/cards/t/TreasureMap.java +++ b/Mage.Sets/src/mage/cards/t/TreasureMap.java @@ -4,19 +4,23 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.RemoveAllCountersSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.keyword.ScryEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.counters.CounterType; +import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.TreasureToken; import java.util.UUID; @@ -24,17 +28,24 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class TreasureMap extends CardImpl { +public final class TreasureMap extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.LANDMARK, 3); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Treasure"); + + static { + filter.add(SubType.TREASURE.getPredicate()); + } public TreasureMap(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - - this.secondSideCardClazz = mage.cards.t.TreasureCove.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}", + "Treasure Cove", + new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Treasure Map // {1}, {T}: Scry 1. Put a landmark counter on Treasure Map. Then if there are three or more landmark counters on it, remove those counters, transform Treasure Map, and create three colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color." - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new ScryEffect(1, false), new ManaCostsImpl<>("{1}")); ability.addCost(new TapSourceCost()); ability.addEffect(new AddCountersSourceEffect(CounterType.LANDMARK.createInstance())); @@ -42,7 +53,16 @@ public final class TreasureMap extends CardImpl { new RemoveAllCountersSourceEffect(CounterType.LANDMARK), condition, "Then if there are three or " + "more landmark counters on it, remove those counters, transform {this}, and create three Treasure tokens" ).addEffect(new TransformSourceEffect()).addEffect(new CreateTokenEffect(new TreasureToken(), 3))); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Treasure Cove + // {T}: Add {C}. + this.getRightHalfCard().addAbility(new ColorlessManaAbility()); + + // {T}, Sacrifice a Treasure: Draw a card. + Ability ability2 = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()); + ability2.addCost(new SacrificeTargetCost(filter)); + this.getRightHalfCard().addAbility(ability2); } private TreasureMap(final TreasureMap card) { diff --git a/Mage.Sets/src/mage/cards/t/TributeToHorobi.java b/Mage.Sets/src/mage/cards/t/TributeToHorobi.java index 5ae827f0d1c..94b70c92b3c 100644 --- a/Mage.Sets/src/mage/cards/t/TributeToHorobi.java +++ b/Mage.Sets/src/mage/cards/t/TributeToHorobi.java @@ -1,15 +1,22 @@ package mage.cards.t; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.common.CreateTokenAllEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.GainControlAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SagaChapter; -import mage.constants.SubType; -import mage.constants.TargetController; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.RatRogueToken; import java.util.UUID; @@ -17,28 +24,53 @@ import java.util.UUID; /** * @author weirddan455 */ -public final class TributeToHorobi extends CardImpl { +public final class TributeToHorobi extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterPermanent(SubType.RAT, "Rat tokens"); + + static { + filter.add(TokenPredicate.TRUE); + } public TributeToHorobi(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.e.EchoOfDeathsWail.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{B}", + "Echo of Death's Wail", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "B" + ); + // Tribute to Horobi // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I, II — Each opponent creates a 1/1 black Rat Rouge creature token. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new CreateTokenAllEffect(new RatRogueToken(), TargetController.OPPONENT) ); // III — Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Echo of Death's Wail + this.getRightHalfCard().setPT(3, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // When Echo of Death's Wail enters the battlefield, gain control of all Rat tokens. + this.getRightHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new GainControlAllEffect(Duration.Custom, filter))); + + // Whenever Echo of Death's Wail attacks, you may sacrifice another creature. If you do, draw a card. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) + ))); } private TributeToHorobi(final TributeToHorobi card) { diff --git a/Mage.Sets/src/mage/cards/t/TruthOrConsequences.java b/Mage.Sets/src/mage/cards/t/TruthOrConsequences.java index f919624b10f..1c10266bbb1 100644 --- a/Mage.Sets/src/mage/cards/t/TruthOrConsequences.java +++ b/Mage.Sets/src/mage/cards/t/TruthOrConsequences.java @@ -10,8 +10,9 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; -import mage.target.common.TargetOpponent; +import mage.util.RandomUtil; +import java.util.Optional; import java.util.UUID; /** @@ -64,10 +65,13 @@ class TruthOrConsequencesEffect extends OneShotEffect { TwoChoiceVote vote = new TwoChoiceVote("Truth (draw card)", "Consequences (deal damage)", Outcome.DrawCard, true); vote.doVotes(source, game); player.drawCards(vote.getVoteCount(true), source, game); - TargetOpponent target = new TargetOpponent(true); - target.setRandom(true); - target.choose(outcome, source.getControllerId(), source.getSourceId(), source, game); - Player opponent = game.getPlayer(target.getFirstTarget()); - return opponent == null || opponent.damage(3 * vote.getVoteCount(false), source, game) > 0; + Optional.of(game.getOpponents(player.getId(), true)) + .map(RandomUtil::randomFromCollection) + .map(game::getPlayer) + .ifPresent(opponent -> { + game.informPlayers(opponent.getLogName() + " has been chosen at random."); + opponent.damage(3 * vote.getVoteCount(false), source, game); + }); + return true; } } diff --git a/Mage.Sets/src/mage/cards/t/TwinbladeGeist.java b/Mage.Sets/src/mage/cards/t/TwinbladeGeist.java index 3323597e51e..a85e49ad3bb 100644 --- a/Mage.Sets/src/mage/cards/t/TwinbladeGeist.java +++ b/Mage.Sets/src/mage/cards/t/TwinbladeGeist.java @@ -1,35 +1,57 @@ package mage.cards.t; -import mage.MageInt; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.DisturbAbility; import mage.abilities.keyword.DoubleStrikeAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.EnchantAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +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 TwinbladeGeist extends CardImpl { +public final class TwinbladeGeist extends TransformingDoubleFacedCard { public TwinbladeGeist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT, SubType.WARRIOR}, "{1}{W}", + "Twinblade Invocation", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "W" + ); - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.t.TwinbladeInvocation.class; + // Twinblade Geist + this.getLeftHalfCard().setPT(1, 1); // Double strike - this.addAbility(DoubleStrikeAbility.getInstance()); + this.getLeftHalfCard().addAbility(DoubleStrikeAbility.getInstance()); // Disturb {2}{W} - this.addAbility(new DisturbAbility(this, "{2}{W}")); + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{2}{W}")); + + // Twinblade Invocation + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getRightHalfCard().getSpellAbility().addTarget(auraTarget); + this.getRightHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getRightHalfCard().addAbility(new EnchantAbility(auraTarget)); + + // Enchanted creature has double strike. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + DoubleStrikeAbility.getInstance(), AttachmentType.AURA + ))); + + // If Twinblade Invocation would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private TwinbladeGeist(final TwinbladeGeist card) { diff --git a/Mage.Sets/src/mage/cards/t/TwinbladeInvocation.java b/Mage.Sets/src/mage/cards/t/TwinbladeInvocation.java deleted file mode 100644 index 1ade18bdba1..00000000000 --- a/Mage.Sets/src/mage/cards/t/TwinbladeInvocation.java +++ /dev/null @@ -1,55 +0,0 @@ -package mage.cards.t; - -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.keyword.DisturbAbility; -import mage.abilities.keyword.DoubleStrikeAbility; -import mage.abilities.keyword.EnchantAbility; -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 TwinbladeInvocation extends CardImpl { - - public TwinbladeInvocation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.AURA); - this.color.setWhite(true); - this.nightCard = true; - - // Enchant creature - TargetPermanent auraTarget = new TargetCreaturePermanent(); - this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - this.addAbility(new EnchantAbility(auraTarget)); - - // Enchanted creature has double strike. - this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( - DoubleStrikeAbility.getInstance(), AttachmentType.AURA - ))); - - // If Twinblade Invocation would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private TwinbladeInvocation(final TwinbladeInvocation card) { - super(card); - } - - @Override - public TwinbladeInvocation copy() { - return new TwinbladeInvocation(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TwistsAndTurns.java b/Mage.Sets/src/mage/cards/t/TwistsAndTurns.java index 76c33e1b534..7ad5ef13c07 100644 --- a/Mage.Sets/src/mage/cards/t/TwistsAndTurns.java +++ b/Mage.Sets/src/mage/cards/t/TwistsAndTurns.java @@ -3,19 +3,20 @@ package mage.cards.t; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.keyword.ExploreTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.GreenManaAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.Duration; -import mage.constants.Outcome; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; @@ -28,7 +29,7 @@ import java.util.UUID; /** * @author xenohedron */ -public final class TwistsAndTurns extends CardImpl { +public final class TwistsAndTurns extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledLandPermanent("you control seven or more lands"), @@ -36,22 +37,36 @@ public final class TwistsAndTurns extends CardImpl { ); public TwistsAndTurns(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); - this.secondSideCardClazz = mage.cards.m.MycoidMaze.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{G}", + "Mycoid Maze", + new CardType[]{CardType.LAND}, new SubType[]{SubType.CAVE}, "" + ); + // Twists and Turns // If a creature you control would explore, instead you scry 1, then that creature explores. - this.addAbility(new SimpleStaticAbility(new TwistsAndTurnsReplacementEffect())); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new TwistsAndTurnsReplacementEffect())); // When Twists and Turns enters the battlefield, target creature you control explores. Ability ability = new EntersBattlefieldTriggeredAbility(new ExploreTargetEffect(false)); ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // When a land you control enters, if you control seven or more lands, transform Twists and Turns. - this.addAbility(new TransformAbility()); - this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldControlledTriggeredAbility( new TransformSourceEffect(), StaticFilters.FILTER_LAND ).withInterveningIf(condition).setTriggerPhrase("When a land you control enters, ")); + + // Mycoid Maze + // {T}: Add {G}. + this.getRightHalfCard().addAbility(new GreenManaAbility()); + + // {3}{G}, {T}: Look at the top four cards of your library. You may reveal a creature card from among them and put that card into your hand. Put the rest on the bottom of your library in a random order. + Ability ability2 = new SimpleActivatedAbility(new LookLibraryAndPickControllerEffect( + 4, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM + ), new ManaCostsImpl<>("{3}{G}")); + ability2.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability2); } private TwistsAndTurns(final TwistsAndTurns card) { diff --git a/Mage.Sets/src/mage/cards/u/UlrichOfTheKrallenhorde.java b/Mage.Sets/src/mage/cards/u/UlrichOfTheKrallenhorde.java index 92b6bb25ea4..463cc3c97ae 100644 --- a/Mage.Sets/src/mage/cards/u/UlrichOfTheKrallenhorde.java +++ b/Mage.Sets/src/mage/cards/u/UlrichOfTheKrallenhorde.java @@ -1,16 +1,21 @@ package mage.cards.u; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.common.TransformsOrEntersTriggeredAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; +import mage.abilities.effects.common.FightTargetSourceEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -18,28 +23,50 @@ import java.util.UUID; /** * @author fireshoes */ -public final class UlrichOfTheKrallenhorde extends CardImpl { +public final class UlrichOfTheKrallenhorde extends TransformingDoubleFacedCard { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("non-Werewolf creature you don't control"); + + static { + filter.add(Predicates.not(SubType.WEREWOLF.getPredicate())); + filter.add(TargetController.NOT_YOU.getControllerPredicate()); + } public UlrichOfTheKrallenhorde(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{3}{R}{G}", + "Ulrich, Uncontested Alpha", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "RG" + ); - this.secondSideCardClazz = mage.cards.u.UlrichUncontestedAlpha.class; + // Ulrich of the Krallenhorde + this.getLeftHalfCard().setPT(4, 4); // Whenever this creature enters the battlefield or transforms into Ulrich of the Krallenhorde, target creature gets +4/+4 until end of turn. Ability ability = new TransformsOrEntersTriggeredAbility( new BoostTargetEffect(4, 4), false ); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of each upkeep, if no spells were cast last turn, transform Ulrich of the Krallenhorde. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Ulrich, Uncontested Alpha + this.getRightHalfCard().setPT(6, 6); + + // Whenever this creature transforms into Ulrich, Uncontested Alpha, you may have it fight target non-Werewolf creature you don't control. + Ability ability2 = new TransformIntoSourceTriggeredAbility( + new FightTargetSourceEffect() + .setText("you may have it fight target non-Werewolf creature you don't control"), + true, true + ); + ability2.addTarget(new TargetPermanent(filter)); + this.getRightHalfCard().addAbility(ability2); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ulrich, Uncontested Alpha. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private UlrichOfTheKrallenhorde(final UlrichOfTheKrallenhorde card) { diff --git a/Mage.Sets/src/mage/cards/u/UlrichUncontestedAlpha.java b/Mage.Sets/src/mage/cards/u/UlrichUncontestedAlpha.java deleted file mode 100644 index a900e313e68..00000000000 --- a/Mage.Sets/src/mage/cards/u/UlrichUncontestedAlpha.java +++ /dev/null @@ -1,66 +0,0 @@ -package mage.cards.u; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.FightTargetSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.TargetController; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class UlrichUncontestedAlpha extends CardImpl { - - private static final FilterCreaturePermanent filter - = new FilterCreaturePermanent("non-Werewolf creature you don't control"); - - static { - filter.add(Predicates.not(SubType.WEREWOLF.getPredicate())); - filter.add(TargetController.NOT_YOU.getControllerPredicate()); - } - - public UlrichUncontestedAlpha(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.color.setRed(true); - this.color.setGreen(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Whenever this creature transforms into Ulrich, Uncontested Alpha, you may have it fight target non-Werewolf creature you don't control. - Ability ability = new TransformIntoSourceTriggeredAbility( - new FightTargetSourceEffect() - .setText("you may have it fight target non-Werewolf creature you don't control"), - true, true - ); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ulrich, Uncontested Alpha. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private UlrichUncontestedAlpha(final UlrichUncontestedAlpha card) { - super(card); - } - - @Override - public UlrichUncontestedAlpha copy() { - return new UlrichUncontestedAlpha(this); - } -} diff --git a/Mage.Sets/src/mage/cards/u/UltimeciaOmnipotent.java b/Mage.Sets/src/mage/cards/u/UltimeciaOmnipotent.java deleted file mode 100644 index db51fd3f13d..00000000000 --- a/Mage.Sets/src/mage/cards/u/UltimeciaOmnipotent.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.u; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; - -/** - * @author balazskristof - */ -public final class UltimeciaOmnipotent extends CardImpl { - - public UltimeciaOmnipotent(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.NIGHTMARE); - this.subtype.add(SubType.WARLOCK); - this.power = new MageInt(7); - this.toughness = new MageInt(7); - - this.color.setBlack(true); - this.color.setBlue(true); - - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // Time Compression -- When this creature transforms into Ultimecia, Omnipotent, take an extra turn after this one. - this.addAbility(new TransformIntoSourceTriggeredAbility(new AddExtraTurnControllerEffect()).withFlavorWord("Time Compression")); - } - - private UltimeciaOmnipotent(final UltimeciaOmnipotent card) { - super(card); - } - - @Override - public UltimeciaOmnipotent copy() { - return new UltimeciaOmnipotent(this); - } -} diff --git a/Mage.Sets/src/mage/cards/u/UltimeciaTimeSorceress.java b/Mage.Sets/src/mage/cards/u/UltimeciaTimeSorceress.java index 539ac995609..31291e84299 100644 --- a/Mage.Sets/src/mage/cards/u/UltimeciaTimeSorceress.java +++ b/Mage.Sets/src/mage/cards/u/UltimeciaTimeSorceress.java @@ -1,44 +1,45 @@ package mage.cards.u; -import java.util.UUID; -import mage.MageInt; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.costs.CompositeCost; import mage.abilities.costs.common.ExileFromGraveCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; import mage.abilities.effects.keyword.SurveilEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.MenaceAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** * @author balazskristof */ -public final class UltimeciaTimeSorceress extends CardImpl { +public final class UltimeciaTimeSorceress extends TransformingDoubleFacedCard { public UltimeciaTimeSorceress(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARLOCK); - this.power = new MageInt(4); - this.toughness = new MageInt(5); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARLOCK}, "{3}{U}{B}", + "Ultimecia, Omnipotent", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.NIGHTMARE, SubType.WARLOCK}, "UB" + ); - this.secondSideCardClazz = mage.cards.u.UltimeciaOmnipotent.class; + // Ultimecia, Time Sorceress + this.getLeftHalfCard().setPT(4, 5); // Whenever Ultimecia enters or attacks, surveil 2. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new SurveilEffect(2))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new SurveilEffect(2))); // At the beginning of your end step, you may pay {4}{U}{U}{B}{B} and exile eight cards from your graveyard. If you do, transform Ultimecia. - this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoIfCostPaid( + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new DoIfCostPaid( new TransformSourceEffect(), new CompositeCost( new ManaCostsImpl<>("{4}{U}{U}{B}{B}"), @@ -46,7 +47,15 @@ public final class UltimeciaTimeSorceress extends CardImpl { "{4}{U}{U}{B}{B} and exile eight cards from your graveyard" ) ))); - this.addAbility(new TransformAbility()); + + // Ultimecia, Omnipotent + this.getRightHalfCard().setPT(7, 7); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // Time Compression -- When this creature transforms into Ultimecia, Omnipotent, take an extra turn after this one. + this.getRightHalfCard().addAbility(new TransformIntoSourceTriggeredAbility(new AddExtraTurnControllerEffect()).withFlavorWord("Time Compression")); } private UltimeciaTimeSorceress(final UltimeciaTimeSorceress card) { diff --git a/Mage.Sets/src/mage/cards/u/UltraMagnusArmoredCarrier.java b/Mage.Sets/src/mage/cards/u/UltraMagnusArmoredCarrier.java deleted file mode 100644 index 7e7d04bbe4b..00000000000 --- a/Mage.Sets/src/mage/cards/u/UltraMagnusArmoredCarrier.java +++ /dev/null @@ -1,87 +0,0 @@ -package mage.cards.u; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.IndestructibleAbility; -import mage.abilities.keyword.LivingMetalAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.common.FilterAttackingCreature; -import mage.game.Game; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class UltraMagnusArmoredCarrier extends CardImpl { - - public UltraMagnusArmoredCarrier(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.VEHICLE); - this.power = new MageInt(4); - this.toughness = new MageInt(7); - this.color.setRed(true); - this.color.setGreen(true); - this.color.setWhite(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // Formidable -- Whenever Ultra Magnus attacks, attacking creatures you control gain indestructible until end of turn. If those creatures have total power 8 or greater, convert Ultra Magnus. - Ability ability = new AttacksTriggeredAbility(new GainAbilityControlledEffect( - IndestructibleAbility.getInstance(), Duration.EndOfTurn, - StaticFilters.FILTER_ATTACKING_CREATURES - )); - ability.addEffect(new ConditionalOneShotEffect( - new TransformSourceEffect(), UltraMagnusArmoredCarrierCondition.instance, - "If those creatures have total power 8 or greater, convert {this}" - )); - this.addAbility(ability.setAbilityWord(AbilityWord.FORMIDABLE)); - } - - private UltraMagnusArmoredCarrier(final UltraMagnusArmoredCarrier card) { - super(card); - } - - @Override - public UltraMagnusArmoredCarrier copy() { - return new UltraMagnusArmoredCarrier(this); - } -} - -enum UltraMagnusArmoredCarrierCondition implements Condition { - instance; - private static final FilterPermanent filter = new FilterAttackingCreature(); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - } - - @Override - public boolean apply(Game game, Ability source) { - return game - .getBattlefield() - .getActivePermanents(filter, source.getControllerId(), source, game) - .stream() - .map(MageObject::getPower) - .mapToInt(MageInt::getValue) - .sum() >= 8; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/u/UltraMagnusTactician.java b/Mage.Sets/src/mage/cards/u/UltraMagnusTactician.java index 88775f8e8b6..e1fd4428dcd 100644 --- a/Mage.Sets/src/mage/cards/u/UltraMagnusTactician.java +++ b/Mage.Sets/src/mage/cards/u/UltraMagnusTactician.java @@ -1,20 +1,26 @@ package mage.cards.u; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -import mage.abilities.keyword.WardAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.*; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterArtifactCard; +import mage.filter.common.FilterAttackingCreature; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -27,26 +33,46 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class UltraMagnusTactician extends CardImpl { +public final class UltraMagnusTactician extends TransformingDoubleFacedCard { public UltraMagnusTactician(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{R}{G}{W}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{4}{R}{G}{W}", + "Ultra Magnus, Armored Carrier", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "RGW" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(7); - this.toughness = new MageInt(7); - - this.secondSideCardClazz = mage.cards.u.UltraMagnusArmoredCarrier.class; + // Ultra Magnus, Tactician + this.getLeftHalfCard().setPT(7, 7); // More Than Meets the Eye {2}{R}{G}{W} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{R}{G}{W}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{R}{G}{W}")); // Ward {2} - this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); + this.getLeftHalfCard().addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); // Whenever Ultra Magnus attacks, you may put an artifact creature card from your hand onto the battlefield tapped and attacking. If you do, convert Ultra Magnus at end of combat. - this.addAbility(new AttacksTriggeredAbility(new UltraMagnusTacticianEffect())); + this.getLeftHalfCard().addAbility(new AttacksTriggeredAbility(new UltraMagnusTacticianEffect())); + + // Ultra Magnus, Armored Carrier + this.getRightHalfCard().setPT(4, 7); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // Formidable -- Whenever Ultra Magnus attacks, attacking creatures you control gain indestructible until end of turn. If those creatures have total power 8 or greater, convert Ultra Magnus. + Ability ability = new AttacksTriggeredAbility(new GainAbilityControlledEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_ATTACKING_CREATURES + )); + ability.addEffect(new ConditionalOneShotEffect( + new TransformSourceEffect(), UltraMagnusArmoredCarrierCondition.instance, + "If those creatures have total power 8 or greater, convert {this}" + )); + this.getRightHalfCard().addAbility(ability.setAbilityWord(AbilityWord.FORMIDABLE)); } private UltraMagnusTactician(final UltraMagnusTactician card) { @@ -109,3 +135,23 @@ class UltraMagnusTacticianEffect extends OneShotEffect { return true; } } + +enum UltraMagnusArmoredCarrierCondition implements Condition { + instance; + private static final FilterPermanent filter = new FilterAttackingCreature(); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + } + + @Override + public boolean apply(Game game, Ability source) { + return game + .getBattlefield() + .getActivePermanents(filter, source.getControllerId(), source, game) + .stream() + .map(MageObject::getPower) + .mapToInt(MageInt::getValue) + .sum() >= 8; + } +} diff --git a/Mage.Sets/src/mage/cards/u/UlvenwaldAbomination.java b/Mage.Sets/src/mage/cards/u/UlvenwaldAbomination.java deleted file mode 100644 index 99ea3e10cc7..00000000000 --- a/Mage.Sets/src/mage/cards/u/UlvenwaldAbomination.java +++ /dev/null @@ -1,43 +0,0 @@ - -package mage.cards.u; - -import java.util.UUID; -import mage.MageInt; -import mage.Mana; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Zone; - -/** - * - * @author fireshoes - */ -public final class UlvenwaldAbomination extends CardImpl { - - public UlvenwaldAbomination(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(6); - - // this card is the second face of double-faced card - this.nightCard = true; - - // {T}: Add {C}{C}. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(2), new TapSourceCost())); - } - - private UlvenwaldAbomination(final UlvenwaldAbomination card) { - super(card); - } - - @Override - public UlvenwaldAbomination copy() { - return new UlvenwaldAbomination(this); - } -} diff --git a/Mage.Sets/src/mage/cards/u/UlvenwaldBehemoth.java b/Mage.Sets/src/mage/cards/u/UlvenwaldBehemoth.java deleted file mode 100644 index 46d6434e6c9..00000000000 --- a/Mage.Sets/src/mage/cards/u/UlvenwaldBehemoth.java +++ /dev/null @@ -1,63 +0,0 @@ -package mage.cards.u; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class UlvenwaldBehemoth extends CardImpl { - - public UlvenwaldBehemoth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.BEAST); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(8); - this.toughness = new MageInt(8); - this.color.setGreen(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // Other creatures you control get +1/+1 and have trample and haste. - Ability ability = new SimpleStaticAbility(new BoostControlledEffect( - 1, 1, Duration.WhileOnBattlefield, true - )); - ability.addEffect(new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.WhileOnBattlefield, - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ).setText("and have trample")); - ability.addEffect(new GainAbilityControlledEffect( - HasteAbility.getInstance(), Duration.WhileOnBattlefield, - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ).setText("and haste")); - this.addAbility(ability); - } - - private UlvenwaldBehemoth(final UlvenwaldBehemoth card) { - super(card); - } - - @Override - public UlvenwaldBehemoth copy() { - return new UlvenwaldBehemoth(this); - } -} diff --git a/Mage.Sets/src/mage/cards/u/UlvenwaldCaptive.java b/Mage.Sets/src/mage/cards/u/UlvenwaldCaptive.java index f8207fb0d22..302067464ca 100644 --- a/Mage.Sets/src/mage/cards/u/UlvenwaldCaptive.java +++ b/Mage.Sets/src/mage/cards/u/UlvenwaldCaptive.java @@ -1,15 +1,15 @@ - package mage.cards.u; -import mage.MageInt; +import mage.Mana; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.DefenderAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.GreenManaAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -19,26 +19,32 @@ import java.util.UUID; /** * @author fireshoes */ -public final class UlvenwaldCaptive extends CardImpl { +public final class UlvenwaldCaptive extends TransformingDoubleFacedCard { public UlvenwaldCaptive(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(1); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.HORROR}, "{1}{G}", + "Ulvenwald Abomination", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.WEREWOLF}, "" + ); - this.secondSideCardClazz = mage.cards.u.UlvenwaldAbomination.class; + // Ulvenwald Captive + this.getLeftHalfCard().setPT(1, 2); // Defender - this.addAbility(DefenderAbility.getInstance()); + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // {T}: Add {G}. - this.addAbility(new GreenManaAbility()); + this.getLeftHalfCard().addAbility(new GreenManaAbility()); // {5}{G}{G}: Transform Ulvenwald Captive. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{G}{G}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{G}{G}"))); + + // Ulvenwald Abomination + this.getRightHalfCard().setPT(4, 6); + + // {T}: Add {C}{C}. + this.getRightHalfCard().addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(2), new TapSourceCost())); } private UlvenwaldCaptive(final UlvenwaldCaptive card) { diff --git a/Mage.Sets/src/mage/cards/u/UlvenwaldMystics.java b/Mage.Sets/src/mage/cards/u/UlvenwaldMystics.java index cf32607f3d1..0f5fb24efb0 100644 --- a/Mage.Sets/src/mage/cards/u/UlvenwaldMystics.java +++ b/Mage.Sets/src/mage/cards/u/UlvenwaldMystics.java @@ -1,10 +1,12 @@ package mage.cards.u; -import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.RegenerateSourceEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,22 +15,29 @@ import java.util.UUID; /** * @author nantuko */ -public final class UlvenwaldMystics extends CardImpl { +public final class UlvenwaldMystics extends TransformingDoubleFacedCard { public UlvenwaldMystics(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SHAMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SHAMAN, SubType.WEREWOLF}, "{2}{G}{G}", + "Ulvenwald Primordials", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.u.UlvenwaldPrimordials.class; - - this.power = new MageInt(3); - this.toughness = new MageInt(3); + // Ulvenwald Mystics + this.getLeftHalfCard().setPT(3, 3); // At the beginning of each upkeep, if no spells were cast last turn, transform Ulvenwald Mystics. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Ulvenwald Primordials + this.getRightHalfCard().setPT(5, 5); + + // {G}: Regenerate Ulvenwald Primordials. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new RegenerateSourceEffect(), new ManaCostsImpl<>("{G}"))); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ulvenwald Primordials. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private UlvenwaldMystics(final UlvenwaldMystics card) { diff --git a/Mage.Sets/src/mage/cards/u/UlvenwaldOddity.java b/Mage.Sets/src/mage/cards/u/UlvenwaldOddity.java index ae8c3820b74..ee54571f214 100644 --- a/Mage.Sets/src/mage/cards/u/UlvenwaldOddity.java +++ b/Mage.Sets/src/mage/cards/u/UlvenwaldOddity.java @@ -1,43 +1,71 @@ package mage.cards.u; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.StaticFilters; import java.util.UUID; /** * @author TheElk801 */ -public final class UlvenwaldOddity extends CardImpl { +public final class UlvenwaldOddity extends TransformingDoubleFacedCard { public UlvenwaldOddity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BEAST}, "{2}{G}{G}", + "Ulvenwald Behemoth", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BEAST, SubType.HORROR}, "G" + ); - this.subtype.add(SubType.BEAST); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.u.UlvenwaldBehemoth.class; + // Ulvenwald Oddity + this.getLeftHalfCard().setPT(4, 4); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // {5}{G}{G}: Transform Ulvenwald Oddity. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility( + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility( new TransformSourceEffect(), new ManaCostsImpl<>("{5}{G}{G}") )); + + // Ulvenwald Behemoth + this.getRightHalfCard().setPT(8, 8); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // Other creatures you control get +1/+1 and have trample and haste. + Ability ability = new SimpleStaticAbility(new BoostControlledEffect( + 1, 1, Duration.WhileOnBattlefield, true + )); + ability.addEffect(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE + ).setText("and have trample")); + ability.addEffect(new GainAbilityControlledEffect( + HasteAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE + ).setText("and haste")); + this.getRightHalfCard().addAbility(ability); } private UlvenwaldOddity(final UlvenwaldOddity card) { diff --git a/Mage.Sets/src/mage/cards/u/UlvenwaldPrimordials.java b/Mage.Sets/src/mage/cards/u/UlvenwaldPrimordials.java deleted file mode 100644 index e74217697d3..00000000000 --- a/Mage.Sets/src/mage/cards/u/UlvenwaldPrimordials.java +++ /dev/null @@ -1,46 +0,0 @@ -package mage.cards.u; - -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.RegenerateSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class UlvenwaldPrimordials extends CardImpl { - - public UlvenwaldPrimordials(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.color.setGreen(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(5); - this.toughness = new MageInt(5); - - // {G}: Regenerate Ulvenwald Primordials. - this.addAbility(new SimpleActivatedAbility(new RegenerateSourceEffect(), new ManaCostsImpl<>("{G}"))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ulvenwald Primordials. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private UlvenwaldPrimordials(final UlvenwaldPrimordials card) { - super(card); - } - - @Override - public UlvenwaldPrimordials copy() { - return new UlvenwaldPrimordials(this); - } -} diff --git a/Mage.Sets/src/mage/cards/u/UnderwaterTunnelSlimyAquarium.java b/Mage.Sets/src/mage/cards/u/UnderwaterTunnelSlimyAquarium.java new file mode 100644 index 00000000000..93331c50117 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnderwaterTunnelSlimyAquarium.java @@ -0,0 +1,37 @@ +package mage.cards.u; + +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.effects.keyword.ManifestDreadEffect; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class UnderwaterTunnelSlimyAquarium extends RoomCard { + + public UnderwaterTunnelSlimyAquarium(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{U}", "{3}{U}"); + + // Underwater Tunnel + // When you unlock this door, surveil 2. + this.getLeftHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new SurveilEffect(2), false, true)); + + // Slimy Aquarium + // When you unlock this door, manifest dread, then put a +1/+1 counter on that creature. + this.getRightHalfCard().addAbility(new UnlockThisDoorTriggeredAbility(new ManifestDreadEffect(CounterType.P1P1.createInstance()), false, false)); + } + + private UnderwaterTunnelSlimyAquarium(final UnderwaterTunnelSlimyAquarium card) { + super(card); + } + + @Override + public UnderwaterTunnelSlimyAquarium copy() { + return new UnderwaterTunnelSlimyAquarium(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnexpectedAssistance.java b/Mage.Sets/src/mage/cards/u/UnexpectedAssistance.java new file mode 100644 index 00000000000..07614b9e66d --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnexpectedAssistance.java @@ -0,0 +1,34 @@ +package mage.cards.u; + +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class UnexpectedAssistance extends CardImpl { + + public UnexpectedAssistance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}{U}"); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // Draw three cards, then discard a card. + this.getSpellAbility().addEffect(new DrawDiscardControllerEffect(3, 1)); + } + + private UnexpectedAssistance(final UnexpectedAssistance card) { + super(card); + } + + @Override + public UnexpectedAssistance copy() { + return new UnexpectedAssistance(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnholyAnnexRitualChamber.java b/Mage.Sets/src/mage/cards/u/UnholyAnnexRitualChamber.java index 0e84acb85eb..4cabd2ee8de 100644 --- a/Mage.Sets/src/mage/cards/u/UnholyAnnexRitualChamber.java +++ b/Mage.Sets/src/mage/cards/u/UnholyAnnexRitualChamber.java @@ -12,9 +12,7 @@ import mage.abilities.hint.ConditionHint; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardSetInfo; import mage.cards.RoomCard; -import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.SpellAbilityType; import mage.constants.SubType; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; @@ -35,7 +33,7 @@ public final class UnholyAnnexRitualChamber extends RoomCard { } public UnholyAnnexRitualChamber(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}", "{3}{B}{B}", SpellAbilityType.SPLIT); + super(ownerId, setInfo, "{2}{B}", "{3}{B}{B}"); this.subtype.add(SubType.ROOM); // Unholy Annex: At the beginning of your end step, draw a card. If you control a Demon, each opponent loses 2 life and you gain 2 life. Otherwise, you lose 2 life. diff --git a/Mage.Sets/src/mage/cards/u/UnstableGlyphbridge.java b/Mage.Sets/src/mage/cards/u/UnstableGlyphbridge.java index 2115fe4af1a..aab3f9d2138 100644 --- a/Mage.Sets/src/mage/cards/u/UnstableGlyphbridge.java +++ b/Mage.Sets/src/mage/cards/u/UnstableGlyphbridge.java @@ -2,42 +2,73 @@ package mage.cards.u; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; import mage.abilities.condition.common.CastFromEverywhereSourceCondition; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.RestrictionEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.Outcome; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterSpell; import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.watchers.common.PlayersAttackedThisTurnWatcher; import java.util.UUID; /** * @author notgreat */ -public final class UnstableGlyphbridge extends CardImpl { +public final class UnstableGlyphbridge extends TransformingDoubleFacedCard { + + private static final FilterSpell filter = new FilterSpell("a spell during their turn"); + + static { + filter.add(TargetController.ACTIVE.getControllerPredicate()); + } public UnstableGlyphbridge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{W}{W}"); - this.secondSideCardClazz = mage.cards.s.SandswirlWanderglyph.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{3}{W}{W}", + "Sandswirl Wanderglyph", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "W" + ); + // Unstable Glyphbridge // When Unstable Glyphbridge enters the battlefield, if you cast it, for each player, choose a creature with power 2 or less that player controls. Then destroy all creatures except creatures chosen this way. - this.addAbility(new EntersBattlefieldTriggeredAbility(new UnstableGlyphbridgeEffect()) + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new UnstableGlyphbridgeEffect()) .withInterveningIf(CastFromEverywhereSourceCondition.instance)); // Craft with artifact {3}{W}{W} - this.addAbility(new CraftAbility("{3}{W}{W}")); + this.getLeftHalfCard().addAbility(new CraftAbility("{3}{W}{W}")); + + // Sandswirl Wanderglyph + this.getRightHalfCard().setPT(5, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever an opponent casts a spell during their turn, they can't attack you or planeswalkers you control this turn. + this.getRightHalfCard().addAbility(new SpellCastOpponentTriggeredAbility(Zone.BATTLEFIELD, + new CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect(), filter, false, SetTargetPointer.PLAYER)); + + // Each opponent who attacked you or a planeswalker you control this turn can't cast spells. + Ability ability = new SimpleStaticAbility(new SandswirlWanderglyphCantCastEffect()); + ability.addWatcher(new PlayersAttackedThisTurnWatcher()); + this.getRightHalfCard().addAbility(ability); } private UnstableGlyphbridge(final UnstableGlyphbridge card) { @@ -97,3 +128,68 @@ class UnstableGlyphbridgeEffect extends OneShotEffect { return true; } } + +class SandswirlWanderglyphCantCastEffect extends ContinuousRuleModifyingEffectImpl { + + SandswirlWanderglyphCantCastEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "Each opponent who attacked you or a planeswalker you control this turn can't cast spells"; + } + + private SandswirlWanderglyphCantCastEffect(final SandswirlWanderglyphCantCastEffect effect) { + super(effect); + } + + @Override + public SandswirlWanderglyphCantCastEffect copy() { + return new SandswirlWanderglyphCantCastEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (game.isActivePlayer(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + PlayersAttackedThisTurnWatcher watcher = game.getState().getWatcher(PlayersAttackedThisTurnWatcher.class); + return watcher != null && watcher.hasPlayerAttackedPlayerOrControlledPlaneswalker(event.getPlayerId(), source.getControllerId()); + } + return false; + } + +} + +class CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect extends RestrictionEffect { + CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect() { + super(Duration.EndOfTurn); + staticText = "they can't attack you or planeswalkers you control this turn"; + } + + private CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect(final CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect effect) { + super(effect); + } + + @Override + public CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect copy() { + return new CantAttackSourcePlayerOrPlaneswalkerThisTurnEffect(this); + } + + @Override + public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game, boolean canUseChooseDialogs) { + if (game.getPlayer(defenderId) != null) { + return !(source.getControllerId().equals(defenderId)); + } + Permanent defender = game.getPermanent(defenderId); + if (defender != null && defender.isPlaneswalker()) { + return !(source.getControllerId().equals(defender.getControllerId())); + } + return true; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return permanent.getControllerId().equals(getTargetPointer().getFirst(game, source)); + } +} diff --git a/Mage.Sets/src/mage/cards/u/Urabrask.java b/Mage.Sets/src/mage/cards/u/Urabrask.java index 899f4552ec6..b3a97c37229 100644 --- a/Mage.Sets/src/mage/cards/u/Urabrask.java +++ b/Mage.Sets/src/mage/cards/u/Urabrask.java @@ -1,23 +1,34 @@ package mage.cards.u; -import mage.MageInt; import mage.Mana; import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SagaAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.keyword.FirstStrikeAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.TreasureToken; +import mage.players.Player; import mage.target.common.TargetOpponent; +import mage.watchers.common.CastFromGraveyardWatcher; import mage.watchers.common.SpellsCastWatcher; import java.util.Objects; @@ -26,20 +37,20 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class Urabrask extends CardImpl { +public final class Urabrask extends TransformingDoubleFacedCard { public Urabrask(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.PRAETOR}, "{2}{R}{R}", + "The Great Work", + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "R" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.PRAETOR); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.t.TheGreatWork.class; + // Urabrask + this.getLeftHalfCard().setPT(4, 4); // First strike - this.addAbility(FirstStrikeAbility.getInstance()); + this.getLeftHalfCard().addAbility(FirstStrikeAbility.getInstance()); // Whenever you cast an instant or sorcery spell, Urabrask deals 1 damage to target opponent. Add {R}. Ability ability = new SpellCastControllerTriggeredAbility( @@ -47,14 +58,37 @@ public final class Urabrask extends CardImpl { ); ability.addEffect(new BasicManaEffect(Mana.RedMana(1))); ability.addTarget(new TargetOpponent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {R}: Exile Urabrask, then return it to the battlefield transformed under its owner's control. Activate only as a sorcery and only if you've cast three or more instant and/or sorcery spells this turn. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateIfConditionActivatedAbility( + this.getLeftHalfCard().addAbility(new ActivateIfConditionActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{R}"), UrabraskCondition.instance ).setTiming(TimingRule.SORCERY)); + + // The Great Work + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I -- The Great Work deals 3 damage to target opponent and each creature they control. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + new TheGreatWorkEffect(), new TargetOpponent() + ); + + // II -- Create three Treasure tokens. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_II, + new CreateTokenEffect(new TreasureToken(), 3) + ); + + // III -- Until end of turn, you may cast instant and sorcery spells from any graveyard. If a spell cast this way would be put into a graveyard, exile it instead. Exile The Great Work, then return it to the battlefield. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_III, new TheGreatWorkCastFromGraveyardEffect(), + new TheGreatWorkReplacementEffect(), new ExileSourceAndReturnFaceUpEffect() + ); + sagaAbility.addWatcher(new CastFromGraveyardWatcher()); + this.getRightHalfCard().addAbility(sagaAbility); } private Urabrask(final Urabrask card) { @@ -87,3 +121,120 @@ enum UrabraskCondition implements Condition { return "if you've cast three or more instant and/or sorcery spells this turn"; } } + +class TheGreatWorkEffect extends OneShotEffect { + + TheGreatWorkEffect() { + super(Outcome.Benefit); + staticText = "{this} deals 3 damage to target opponent and each creature they control"; + } + + private TheGreatWorkEffect(final TheGreatWorkEffect effect) { + super(effect); + } + + @Override + public TheGreatWorkEffect copy() { + return new TheGreatWorkEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (player == null) { + return false; + } + player.damage(3, source, game); + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game + )) { + permanent.damage(3, source, game); + } + return true; + } +} + +class TheGreatWorkCastFromGraveyardEffect extends AsThoughEffectImpl { + + TheGreatWorkCastFromGraveyardEffect() { + super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); + staticText = "until end of turn, you may cast instant and sorcery spells from any graveyard"; + } + + private TheGreatWorkCastFromGraveyardEffect(final TheGreatWorkCastFromGraveyardEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public TheGreatWorkCastFromGraveyardEffect copy() { + return new TheGreatWorkCastFromGraveyardEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + Card card = game.getCard(objectId); + if (card != null + && affectedControllerId.equals(source.getControllerId()) + && StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY.match(card, game) + && Zone.GRAVEYARD.equals(game.getState().getZone(card.getId()))) { + game.getState().setValue("TheGreatWork", card); + return true; + } + return false; + } +} + +class TheGreatWorkReplacementEffect extends ReplacementEffectImpl { + + TheGreatWorkReplacementEffect() { + super(Duration.EndOfTurn, Outcome.Exile); + staticText = "if a spell cast this way would be put into a graveyard, exile it instead"; + } + + private TheGreatWorkReplacementEffect(final TheGreatWorkReplacementEffect effect) { + super(effect); + } + + @Override + public TheGreatWorkReplacementEffect copy() { + return new TheGreatWorkReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Card card = (Card) game.getState().getValue("TheGreatWork"); + if (card != null) { + ((ZoneChangeEvent) event).setToZone(Zone.EXILED); + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (Zone.GRAVEYARD != ((ZoneChangeEvent) event).getToZone()) { + return false; + } + Card card = game.getCard(event.getSourceId()); + if (card == null || (!card.isInstant(game) && !card.isSorcery(game))) { + return false; + } + CastFromGraveyardWatcher watcher = game.getState().getWatcher(CastFromGraveyardWatcher.class); + return watcher != null + && watcher.spellWasCastFromGraveyard(event.getTargetId(), + game.getState().getZoneChangeCounter(event.getTargetId())); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java index 481660bf8b7..1647c56c58f 100644 --- a/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java +++ b/Mage.Sets/src/mage/cards/v/VancesBlastingCannons.java @@ -1,19 +1,23 @@ - package mage.cards.v; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.RedManaAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; +import mage.target.common.TargetAnyTarget; import mage.util.CardUtil; import mage.watchers.common.CastSpellLastTurnWatcher; @@ -22,20 +26,31 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class VancesBlastingCannons extends CardImpl { +public final class VancesBlastingCannons extends TransformingDoubleFacedCard { public VancesBlastingCannons(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); - - this.supertype.add(SuperType.LEGENDARY); - this.secondSideCardClazz = mage.cards.s.SpitfireBastion.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{3}{R}", + "Spitfire Bastion", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Vance's Blasting Cannons // At the beginning of your upkeep, exile the top card of your library. If it's a nonland card, you may cast that card this turn. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new VancesBlastingCannonsExileEffect())); + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new VancesBlastingCannonsExileEffect())); // Whenever you cast your third spell in a turn, transform Vance's Blasting Cannons. - this.addAbility(new TransformAbility()); - this.addAbility(new VancesBlastingCannonsTriggeredAbility()); + this.getLeftHalfCard().addAbility(new VancesBlastingCannonsTriggeredAbility()); + + // Spitfire Bastion + // {T}: Add {R}. + this.getRightHalfCard().addAbility(new RedManaAbility()); + + // {2}{R}, {T}: Spitfire Bastion deals 3 damage to any target. + Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(3), new TapSourceCost()); + ability.addCost(new ManaCostsImpl<>("{2}{R}")); + ability.addTarget(new TargetAnyTarget()); + this.getRightHalfCard().addAbility(ability); } private VancesBlastingCannons(final VancesBlastingCannons card) { diff --git a/Mage.Sets/src/mage/cards/v/VaultOfCatlacan.java b/Mage.Sets/src/mage/cards/v/VaultOfCatlacan.java deleted file mode 100644 index 97dcd4e08c2..00000000000 --- a/Mage.Sets/src/mage/cards/v/VaultOfCatlacan.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.v; - -import mage.Mana; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; -import mage.abilities.effects.mana.DynamicManaEffect; -import mage.abilities.hint.common.ArtifactYouControlHint; -import mage.abilities.mana.AnyColorManaAbility; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; -import mage.constants.Zone; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class VaultOfCatlacan extends CardImpl { - - public VaultOfCatlacan(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - - // (Transforms from Storm the Vault.) - - // {T}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); - - // {T}: Add {U} for each artifact you control. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, - new DynamicManaEffect(Mana.BlueMana(1), ArtifactYouControlCount.instance), - new TapSourceCost()) - .addHint(ArtifactYouControlHint.instance)); - - } - - private VaultOfCatlacan(final VaultOfCatlacan card) { - super(card); - } - - @Override - public VaultOfCatlacan copy() { - return new VaultOfCatlacan(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VectorGlider.java b/Mage.Sets/src/mage/cards/v/VectorGlider.java deleted file mode 100644 index bab0f279c24..00000000000 --- a/Mage.Sets/src/mage/cards/v/VectorGlider.java +++ /dev/null @@ -1,38 +0,0 @@ -package mage.cards.v; - -import mage.MageInt; -import mage.abilities.keyword.FlyingAbility; -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 VectorGlider extends CardImpl { - - public VectorGlider(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - } - - private VectorGlider(final VectorGlider card) { - super(card); - } - - @Override - public VectorGlider copy() { - return new VectorGlider(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VenatHeartOfHydaelyn.java b/Mage.Sets/src/mage/cards/v/VenatHeartOfHydaelyn.java index 217d13738c9..f7d7e9b394f 100644 --- a/Mage.Sets/src/mage/cards/v/VenatHeartOfHydaelyn.java +++ b/Mage.Sets/src/mage/cards/v/VenatHeartOfHydaelyn.java @@ -1,29 +1,36 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.counters.CounterType; import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.game.Controllable; +import mage.game.Game; +import mage.target.TargetPermanent; import mage.target.common.TargetNonlandPermanent; +import java.util.Optional; import java.util.UUID; /** * @author TheElk801 */ -public final class VenatHeartOfHydaelyn extends CardImpl { +public final class VenatHeartOfHydaelyn extends TransformingDoubleFacedCard { private static final FilterSpell filter = new FilterSpell("a legendary spell"); @@ -32,27 +39,41 @@ public final class VenatHeartOfHydaelyn extends CardImpl { } public VenatHeartOfHydaelyn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDER, SubType.WIZARD}, "{1}{W}{W}", + "Hydaelyn, the Mothercrystal", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "W" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ELDER); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.h.HydaelynTheMothercrystal.class; + // Venat, Heart of Hydaelyn + this.getLeftHalfCard().setPT(3, 3); // Whenever you cast a legendary spell, draw a card. This ability triggers only once each turn. - this.addAbility(new SpellCastControllerTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( new DrawCardSourceControllerEffect(1), filter, false ).setTriggersLimitEachTurn(1)); // Hero's Sundering -- {7}, {T}: Exile target nonland permanent. Transform Venat. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility(new ExileTargetEffect(), new GenericManaCost(7)); ability.addCost(new TapSourceCost()); ability.addEffect(new TransformSourceEffect()); ability.addTarget(new TargetNonlandPermanent()); - this.addAbility(ability.withFlavorWord("Hero's Sundering")); + this.getLeftHalfCard().addAbility(ability.withFlavorWord("Hero's Sundering")); + + // Hydaelyn, the Mothercrystal + this.getRightHalfCard().setPT(4, 4); + + // Indestructible + this.getRightHalfCard().addAbility(IndestructibleAbility.getInstance()); + + // Blessing of Light -- At the beginning of combat on your turn, put a +1/+1 counter on another target creature you control. Until your next turn, it gains indestructible. If that creature is legendary, draw a card. + Ability ability2 = new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability2.addEffect(new GainAbilityTargetEffect( + IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn + ).setText("Until your next turn, it gains indestructible")); + ability2.addEffect(new HydaelynTheMothercrystalEffect()); + ability2.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); + this.getRightHalfCard().addAbility(ability2.withFlavorWord("Blessing of Light")); } private VenatHeartOfHydaelyn(final VenatHeartOfHydaelyn card) { @@ -64,3 +85,34 @@ public final class VenatHeartOfHydaelyn extends CardImpl { return new VenatHeartOfHydaelyn(this); } } + +class HydaelynTheMothercrystalEffect extends OneShotEffect { + + HydaelynTheMothercrystalEffect() { + super(Outcome.Benefit); + staticText = "If that creature is legendary, draw a card"; + } + + private HydaelynTheMothercrystalEffect(final HydaelynTheMothercrystalEffect effect) { + super(effect); + } + + @Override + public HydaelynTheMothercrystalEffect copy() { + return new HydaelynTheMothercrystalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return Optional.ofNullable(getTargetPointer().getFirst(game, source)) + .map(game::getPermanent) + .filter(permanent -> permanent.isLegendary(game)) + .isPresent() + && Optional + .ofNullable(source) + .map(Controllable::getControllerId) + .map(game::getPlayer) + .filter(player -> player.drawCards(1, source, game) > 0) + .isPresent(); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VengefulStrangler.java b/Mage.Sets/src/mage/cards/v/VengefulStrangler.java index 89d335b6562..5d0fd76b8f2 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulStrangler.java +++ b/Mage.Sets/src/mage/cards/v/VengefulStrangler.java @@ -1,28 +1,34 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.CantBlockAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TransformAbility; -import mage.cards.Card; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.DoubleFacedCardHalf; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.CanBeSacrificedPredicate; +import mage.game.Controllable; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import java.util.Optional; import java.util.UUID; /** * @author TheElk801 */ -public final class VengefulStrangler extends CardImpl { +public final class VengefulStrangler extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent("creature or planeswalker an opponent controls"); @@ -32,22 +38,32 @@ public final class VengefulStrangler extends CardImpl { } public VengefulStrangler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ROGUE}, "{1}{B}", + "Strangling Grasp", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "B" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ROGUE); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.s.StranglingGrasp.class; + // Vengeful Strangler + this.getLeftHalfCard().setPT(2, 1); // Vengeful Strangler can't block. - this.addAbility(new CantBlockAbility()); + this.getLeftHalfCard().addAbility(new CantBlockAbility()); // When Vengeful Strangler dies, return it to the battlefield transformed under your control attached to target creature or planeswalker an opponent controls. - this.addAbility(new TransformAbility()); Ability ability = new DiesSourceTriggeredAbility(new VengefulStranglerEffect()); ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Strangling Grasp + // Enchant creature or planeswalker an opponent controls + TargetPermanent auraTarget = new TargetPermanent(filter); + this.getRightHalfCard().getSpellAbility().addTarget(auraTarget); + this.getRightHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getRightHalfCard().addAbility(new EnchantAbility(auraTarget)); + + // At the beginning of your upkeep, enchanted permanent's controller sacrifices a nonland permanent and loses 1 life. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new StranglingGraspEffect())); } private VengefulStrangler(final VengefulStrangler card) { @@ -86,17 +102,65 @@ class VengefulStranglerEffect extends OneShotEffect { return false; } - Card card = game.getCard(source.getSourceId()); + DoubleFacedCardHalf card = (DoubleFacedCardHalf) game.getCard(source.getSourceId()); if (card == null) { return false; } game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); - game.getState().setValue("attachTo:" + source.getSourceId(), permanent); + game.getState().setValue("attachTo:" + card.getOtherSide().getId(), permanent); if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { - permanent.addAttachment(card.getId(), source, game); + permanent.addAttachment(card.getOtherSide().getId(), source, game); } return true; } } +class StranglingGraspEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanent you control"); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + filter.add(CanBeSacrificedPredicate.instance); + } + + StranglingGraspEffect() { + super(Outcome.Benefit); + staticText = "enchanted permanent's controller sacrifices a nonland permanent of their choice, then that player loses 1 life"; + } + + private StranglingGraspEffect(final StranglingGraspEffect effect) { + super(effect); + } + + @Override + public StranglingGraspEffect copy() { + return new StranglingGraspEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = Optional + .ofNullable(source.getSourcePermanentOrLKI(game)) + .map(Permanent::getAttachedTo) + .map(game::getPermanentOrLKIBattlefield) + .map(Controllable::getControllerId) + .map(game::getPlayer) + .orElse(null); + if (player == null) { + return false; + } + TargetPermanent target = new TargetPermanent(filter); + target.withNotTarget(true); + if (target.canChoose(player.getId(), source, game)) { + player.choose(outcome, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.sacrifice(source, game); + } + } + player.loseLife(1, game, source, false); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java b/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java index f01e7c00595..3efd763a62f 100644 --- a/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java +++ b/Mage.Sets/src/mage/cards/v/VildinPackOutcast.java @@ -1,45 +1,51 @@ - package mage.cards.v; -import java.util.UUID; - -import mage.MageInt; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; -import mage.constants.Zone; +import mage.constants.SubType; + +import java.util.UUID; /** * @author fireshoes */ -public final class VildinPackOutcast extends CardImpl { +public final class VildinPackOutcast extends TransformingDoubleFacedCard { public VildinPackOutcast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(4); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.HORROR}, "{4}{R}", + "Dronepack Kindred", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.WEREWOLF}, "" + ); - this.secondSideCardClazz = mage.cards.d.DronepackKindred.class; + // Vildin-Pack Outcast + this.getLeftHalfCard().setPT(4, 4); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // {R}: Vildin-Pack Outcast gets +1/-1 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, -1, Duration.EndOfTurn), new ManaCostsImpl<>("{R}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, -1, Duration.EndOfTurn), new ManaCostsImpl<>("{R}"))); // {5}{R}{R}: Transform Vildin-Pack Outcast. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{R}{R}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{R}{R}"))); + + // Dronepack Kindred + this.getRightHalfCard().setPT(5, 7); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // {1}: Dronepack Kindred gets +1/+0 until end of turn. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new BoostSourceEffect(1, 0, Duration.EndOfTurn), new GenericManaCost(1))); } private VildinPackOutcast(final VildinPackOutcast card) { diff --git a/Mage.Sets/src/mage/cards/v/VillageIronsmith.java b/Mage.Sets/src/mage/cards/v/VillageIronsmith.java index 408f637c9d1..8b4b9ff390f 100644 --- a/Mage.Sets/src/mage/cards/v/VillageIronsmith.java +++ b/Mage.Sets/src/mage/cards/v/VillageIronsmith.java @@ -1,11 +1,10 @@ package mage.cards.v; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.keyword.FirstStrikeAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -14,23 +13,30 @@ import java.util.UUID; /** * @author nantuko */ -public final class VillageIronsmith extends CardImpl { +public final class VillageIronsmith extends TransformingDoubleFacedCard { public VillageIronsmith(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{1}{R}", + "Ironfang", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.i.Ironfang.class; + // Village Ironsmith + this.getLeftHalfCard().setPT(1, 1); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - - this.addAbility(FirstStrikeAbility.getInstance()); + this.getLeftHalfCard().addAbility(FirstStrikeAbility.getInstance()); // At the beginning of each upkeep, if no spells were cast last turn, transform Village Ironsmith. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Ironfang + this.getRightHalfCard().setPT(3, 1); + + this.getRightHalfCard().addAbility(FirstStrikeAbility.getInstance()); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ironfang. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private VillageIronsmith(final VillageIronsmith card) { diff --git a/Mage.Sets/src/mage/cards/v/VillageMessenger.java b/Mage.Sets/src/mage/cards/v/VillageMessenger.java index c1f2f7b5aa5..f3cfbe1cceb 100644 --- a/Mage.Sets/src/mage/cards/v/VillageMessenger.java +++ b/Mage.Sets/src/mage/cards/v/VillageMessenger.java @@ -1,11 +1,11 @@ package mage.cards.v; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.MenaceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -14,23 +14,32 @@ import java.util.UUID; /** * @author fireshoes */ -public final class VillageMessenger extends CardImpl { +public final class VillageMessenger extends TransformingDoubleFacedCard { public VillageMessenger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(1); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{R}", + "Moonrise Intruder", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.m.MoonriseIntruder.class; + // Village Messenger + this.getLeftHalfCard().setPT(1, 1); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // At the beginning of each upkeep, if no spells were cast last turn, transform Village Messenger. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Moonrise Intruder + this.getRightHalfCard().setPT(2, 2); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Moonrise Intruder. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private VillageMessenger(final VillageMessenger card) { diff --git a/Mage.Sets/src/mage/cards/v/VillageReavers.java b/Mage.Sets/src/mage/cards/v/VillageReavers.java deleted file mode 100644 index 632bcfddb62..00000000000 --- a/Mage.Sets/src/mage/cards/v/VillageReavers.java +++ /dev/null @@ -1,62 +0,0 @@ -package mage.cards.v; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.Predicates; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class VillageReavers extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledPermanent("Wolves and Werewolves"); - - static { - filter.add(Predicates.or( - SubType.WOLF.getPredicate(), - SubType.WEREWOLF.getPredicate() - )); - } - - public VillageReavers(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - - this.color.setRed(true); - - this.nightCard = true; - - this.power = new MageInt(5); - this.toughness = new MageInt(4); - - // Wolves and Werewolves you control have haste. - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( - HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter - ))); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private VillageReavers(final VillageReavers card) { - super(card); - } - - @Override - public VillageReavers copy() { - return new VillageReavers(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VillageWatch.java b/Mage.Sets/src/mage/cards/v/VillageWatch.java index 8efa14cdf32..bb51e927419 100644 --- a/Mage.Sets/src/mage/cards/v/VillageWatch.java +++ b/Mage.Sets/src/mage/cards/v/VillageWatch.java @@ -1,35 +1,61 @@ package mage.cards.v; -import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.DayboundAbility; import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; import java.util.UUID; /** * @author TheElk801 */ -public final class VillageWatch extends CardImpl { +public final class VillageWatch extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterControlledPermanent("Wolves and Werewolves"); + + static { + filter.add(Predicates.or( + SubType.WOLF.getPredicate(), + SubType.WEREWOLF.getPredicate() + )); + } public VillageWatch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{4}{R}", + "Village Reavers", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - - this.secondSideCardClazz = mage.cards.v.VillageReavers.class; + // Village Watch + this.getLeftHalfCard().setPT(4, 3); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Village Reavers + this.getRightHalfCard().setPT(5, 4); + + // Wolves and Werewolves you control have haste. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter + ))); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private VillageWatch(final VillageWatch card) { diff --git a/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java b/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java index ce821011a2f..67e9ae67a89 100644 --- a/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java +++ b/Mage.Sets/src/mage/cards/v/VillagersOfEstwald.java @@ -1,10 +1,9 @@ package mage.cards.v; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,21 +12,26 @@ import java.util.UUID; /** * @author nantuko */ -public final class VillagersOfEstwald extends CardImpl { +public final class VillagersOfEstwald extends TransformingDoubleFacedCard { public VillagersOfEstwald(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{2}{G}", + "Howlpack of Estwald", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.h.HowlpackOfEstwald.class; - - this.power = new MageInt(2); - this.toughness = new MageInt(3); + // Villagers of Estwald + this.getLeftHalfCard().setPT(2, 3); // At the beginning of each upkeep, if no spells were cast last turn, transform Villagers of Estwald. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Howlpack of Estwald + this.getRightHalfCard().setPT(4, 6); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Howlpack of Estwald. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private VillagersOfEstwald(final VillagersOfEstwald card) { diff --git a/Mage.Sets/src/mage/cards/v/VincentValentine.java b/Mage.Sets/src/mage/cards/v/VincentValentine.java index 6cbb8596dd6..68d19cf445b 100644 --- a/Mage.Sets/src/mage/cards/v/VincentValentine.java +++ b/Mage.Sets/src/mage/cards/v/VincentValentine.java @@ -5,13 +5,16 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; @@ -26,27 +29,40 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class VincentValentine extends CardImpl { +public final class VincentValentine extends TransformingDoubleFacedCard { public VincentValentine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ASSASSIN}, "{2}{B}{B}", + "Galian Beast", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.BEAST}, "B" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ASSASSIN); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.g.GalianBeast.class; + // Vincent Valentine + this.getLeftHalfCard().setPT(2, 2); // Whenever a creature an opponent controls dies, put a number of +1/+1 counters on Vincent Valentine equal to that creature's power. - this.addAbility(new DiesCreatureTriggeredAbility( + this.getLeftHalfCard().addAbility(new DiesCreatureTriggeredAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), VincentValentineValue.instance) .setText("put a number of +1/+1 counters on {this} equal to that creature's power"), false, StaticFilters.FILTER_OPPONENTS_PERMANENT_A_CREATURE )); // Whenever Vincent Valentine attacks, you may transform it. - this.addAbility(new TransformAbility()); - this.addAbility(new AttacksTriggeredAbility(new TransformSourceEffect(), true)); + this.getLeftHalfCard().addAbility(new AttacksTriggeredAbility(new TransformSourceEffect(), true)); + + // Galian Beast + this.getRightHalfCard().setPT(3, 2); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // When Galian Beast dies, return it to the battlefield tapped. + this.getRightHalfCard().addAbility(new DiesSourceTriggeredAbility(new ReturnSourceFromGraveyardToBattlefieldEffect(true) + .setText("return it to the battlefield tapped"))); } private VincentValentine(final VincentValentine card) { diff --git a/Mage.Sets/src/mage/cards/v/VisageOfDread.java b/Mage.Sets/src/mage/cards/v/VisageOfDread.java index a37a21a94d0..af909fc98f5 100644 --- a/Mage.Sets/src/mage/cards/v/VisageOfDread.java +++ b/Mage.Sets/src/mage/cards/v/VisageOfDread.java @@ -1,12 +1,16 @@ package mage.cards.v; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.MillCardsControllerEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.MenaceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.StaticFilters; import mage.target.common.TargetOpponent; @@ -15,24 +19,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class VisageOfDread extends CardImpl { +public final class VisageOfDread extends TransformingDoubleFacedCard { public VisageOfDread(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{B}"); - this.secondSideCardClazz = mage.cards.d.DreadOsseosaur.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{B}", + "Dread Osseosaur", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DINOSAUR, SubType.SKELETON, SubType.HORROR}, "B" + ); + // Visage of Dread // When Visage of Dread enters the battlefield, target opponent reveals their hand. You choose an artifact or creature card from it. That player discards that card. Ability ability = new EntersBattlefieldTriggeredAbility( new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_ARTIFACT_OR_CREATURE) ); ability.addTarget(new TargetOpponent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Craft with two creatures {5}{B} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{5}{B}", "two creatures", "other creatures you control and/or " + "creature cards in your graveyard", 2, 2, CardType.CREATURE.getPredicate() )); + + // Dread Osseosaur + this.getRightHalfCard().setPT(5, 4); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Whenever Dread Osseosaur enters the battlefield or attacks, you may mill two cards. + this.getRightHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( + new MillCardsControllerEffect(2), true + )); } private VisageOfDread(final VisageOfDread card) { diff --git a/Mage.Sets/src/mage/cards/v/VolatileArsonist.java b/Mage.Sets/src/mage/cards/v/VolatileArsonist.java index 17e4322bcf9..ef71160e9ad 100644 --- a/Mage.Sets/src/mage/cards/v/VolatileArsonist.java +++ b/Mage.Sets/src/mage/cards/v/VolatileArsonist.java @@ -1,14 +1,14 @@ package mage.cards.v; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.DayboundAbility; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.target.TargetPlayer; @@ -20,22 +20,23 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class VolatileArsonist extends CardImpl { +public final class VolatileArsonist extends TransformingDoubleFacedCard { public VolatileArsonist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{3}{R}{R}", + "Dire-Strain Anarchist", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.d.DireStrainAnarchist.class; + // Volatile Arsonist + this.getLeftHalfCard().setPT(4, 4); // Menace - this.addAbility(new MenaceAbility(false)); + this.getLeftHalfCard().addAbility(new MenaceAbility(false)); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // Whenever Volatile Arsonist attacks, it deals 1 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker. Ability ability = new AttacksTriggeredAbility(new DamageTargetEffect(1) @@ -43,10 +44,29 @@ public final class VolatileArsonist extends CardImpl { ability.addTarget(new TargetCreaturePermanent(0, 1)); ability.addTarget(new TargetPlayer(0, 1, false)); ability.addTarget(new TargetPlaneswalkerPermanent(0, 1)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Dire-Strain Anarchist + this.getRightHalfCard().setPT(5, 5); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // Whenever Dire-Strain Anarchist attacks, it deals 2 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker. + Ability ability2 = new AttacksTriggeredAbility(new DamageTargetEffect(2).setText("it deals 2 damage to each of up to one target creature, up to one target player, and/or up to one target planeswalker")); + ability2.addTarget(new TargetCreaturePermanent(0, 1)); + ability2.addTarget(new TargetPlayer(0, 1, false)); + ability2.addTarget(new TargetPlaneswalkerPermanent(0, 1)); + this.getRightHalfCard().addAbility(ability2); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private VolatileArsonist(final VolatileArsonist card) { diff --git a/Mage.Sets/src/mage/cards/v/VoldarenBloodcaster.java b/Mage.Sets/src/mage/cards/v/VoldarenBloodcaster.java index 87a3a831d6e..8c99e827ac3 100644 --- a/Mage.Sets/src/mage/cards/v/VoldarenBloodcaster.java +++ b/Mage.Sets/src/mage/cards/v/VoldarenBloodcaster.java @@ -1,18 +1,21 @@ package mage.cards.v; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; @@ -23,41 +26,64 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.permanent.token.BloodToken; +import mage.game.permanent.token.custom.CreatureToken; +import mage.target.TargetPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class VoldarenBloodcaster extends CardImpl { +public final class VoldarenBloodcaster extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledCreaturePermanent("nontoken creature you control"); + private static final FilterPermanent filter2 + = new FilterControlledPermanent(SubType.BLOOD, "Blood token you control"); static { filter.add(TokenPredicate.FALSE); + filter2.add(TokenPredicate.TRUE); } public VoldarenBloodcaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE, SubType.WIZARD}, "{1}{B}", + "Bloodbat Summoner", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE, SubType.WIZARD}, "B" + ); - this.subtype.add(SubType.VAMPIRE); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.b.BloodbatSummoner.class; + // Voldaren Bloodcaster + this.getLeftHalfCard().setPT(2, 1); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Whenever Voldaren Bloodcaster or another nontoken creature you control dies, create a Blood token. - this.addAbility(new DiesThisOrAnotherTriggeredAbility( + this.getLeftHalfCard().addAbility(new DiesThisOrAnotherTriggeredAbility( new CreateTokenEffect(new BloodToken()), false, filter )); // Whenever you create a Blood token, if you control five or more Blood tokens, transform Voldaren Bloodcaster. - this.addAbility(new TransformAbility()); - this.addAbility(new VoldarenBloodcasterTriggeredAbility()); + this.getLeftHalfCard().addAbility(new VoldarenBloodcasterTriggeredAbility()); + + // Bloodbat Summoner + this.getRightHalfCard().setPT(3, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // At the beginning of combat on your turn, up to one target Blood token you control becomes a 2/2 black Bat creature with flying and haste in addition to its other types. + Ability ability = new BeginningOfCombatTriggeredAbility(new BecomesCreatureTargetEffect( + new CreatureToken(2, 2, "", SubType.BAT) + .withAbility(FlyingAbility.getInstance()) + .withAbility(HasteAbility.getInstance()) + .withColor("B"), + false, false, Duration.Custom + ).setText("up to one target Blood token you control becomes a " + + "2/2 black Bat creature with flying and haste in addition to its other types")); + ability.addTarget(new TargetPermanent(0, 1, filter2)); + this.getRightHalfCard().addAbility(ability); } private VoldarenBloodcaster(final VoldarenBloodcaster card) { diff --git a/Mage.Sets/src/mage/cards/v/VoldarenPariah.java b/Mage.Sets/src/mage/cards/v/VoldarenPariah.java index a903a942286..0a343267da2 100644 --- a/Mage.Sets/src/mage/cards/v/VoldarenPariah.java +++ b/Mage.Sets/src/mage/cards/v/VoldarenPariah.java @@ -1,29 +1,29 @@ - package mage.cards.v; -import java.util.UUID; - -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.SacrificeEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.MadnessAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetOpponent; + +import java.util.UUID; /** * @author fireshoes */ -public final class VoldarenPariah extends CardImpl { +public final class VoldarenPariah extends TransformingDoubleFacedCard { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("other creatures"); @@ -32,24 +32,37 @@ public final class VoldarenPariah extends CardImpl { } public VoldarenPariah(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); - this.subtype.add(SubType.VAMPIRE); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(3); - this.toughness = new MageInt(3); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE, SubType.HORROR}, "{3}{B}{B}", + "Abolisher of Bloodlines", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.VAMPIRE}, "" + ); - this.secondSideCardClazz = mage.cards.a.AbolisherOfBloodlines.class; + // Voldaren Pariah + this.getLeftHalfCard().setPT(3, 3); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Sacrifice three other creatures: Transform Voldaren Pariah. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new SacrificeTargetCost(3, filter))); // Madness {B}{B}{B} - this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{B}{B}{B}"))); + this.getLeftHalfCard().addAbility(new MadnessAbility(new ManaCostsImpl<>("{B}{B}{B}"))); + + // Abolisher of Bloodlines + this.getRightHalfCard().setPT(6, 5); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // When this creature transforms into Abolisher of Bloodlines, target opponent sacrifices three creatures. + Ability ability = new TransformIntoSourceTriggeredAbility(new SacrificeEffect( + StaticFilters.FILTER_PERMANENT_CREATURES, 3, "target opponent" + )); + ability.addTarget(new TargetOpponent()); + this.getRightHalfCard().addAbility(ability); } private VoldarenPariah(final VoldarenPariah card) { diff --git a/Mage.Sets/src/mage/cards/v/VoltChargedBerserker.java b/Mage.Sets/src/mage/cards/v/VoltChargedBerserker.java deleted file mode 100644 index 0663ca39e0a..00000000000 --- a/Mage.Sets/src/mage/cards/v/VoltChargedBerserker.java +++ /dev/null @@ -1,39 +0,0 @@ -package mage.cards.v; - -import mage.MageInt; -import mage.abilities.common.CantBlockAbility; -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 VoltChargedBerserker extends CardImpl { - - public VoltChargedBerserker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.BERSERKER); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - this.color.setRed(true); - this.nightCard = true; - - // Volt-Charged Berserker can't block. - this.addAbility(new CantBlockAbility()); - } - - private VoltChargedBerserker(final VoltChargedBerserker card) { - super(card); - } - - @Override - public VoltChargedBerserker copy() { - return new VoltChargedBerserker(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VoltaicVisionary.java b/Mage.Sets/src/mage/cards/v/VoltaicVisionary.java index 78ef1ce7b04..668ae5c4b87 100644 --- a/Mage.Sets/src/mage/cards/v/VoltaicVisionary.java +++ b/Mage.Sets/src/mage/cards/v/VoltaicVisionary.java @@ -1,18 +1,17 @@ package mage.cards.v; -import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.CantBlockAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.DamageControllerEffect; import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.ExileZone; import mage.game.Game; @@ -26,27 +25,33 @@ import java.util.*; /** * @author TheElk801 */ -public final class VoltaicVisionary extends CardImpl { +public final class VoltaicVisionary extends TransformingDoubleFacedCard { public VoltaicVisionary(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{1}{R}", + "Volt-Charged Berserker", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.BERSERKER}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.v.VoltChargedBerserker.class; + // Voltaic Visionary + this.getLeftHalfCard().setPT(3, 1); // {T}: Voltaic Visionary deals 2 damage to you. Exile the top card of your library. You may play that card this turn. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility( new DamageControllerEffect(2), new TapSourceCost() ); ability.addEffect(new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // When you play a card exiled with Voltaic Visionary, transform Voltaic Visionary. - this.addAbility(new TransformAbility()); - this.addAbility(new VoltaicVisionaryTriggeredAbility()); + this.getLeftHalfCard().addAbility(new VoltaicVisionaryTriggeredAbility()); + + // Volt-Charged Berserker + this.getRightHalfCard().setPT(4, 3); + + // Volt-Charged Berserker can't block. + this.getRightHalfCard().addAbility(new CantBlockAbility()); } private VoltaicVisionary(final VoltaicVisionary card) { diff --git a/Mage.Sets/src/mage/cards/v/Vorinclex.java b/Mage.Sets/src/mage/cards/v/Vorinclex.java index 65313f60c00..f6164bfb5b5 100644 --- a/Mage.Sets/src/mage/cards/v/Vorinclex.java +++ b/Mage.Sets/src/mage/cards/v/Vorinclex.java @@ -1,29 +1,41 @@ package mage.cards.v; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; +import mage.abilities.effects.common.FightTargetSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.keyword.ReachAbility; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.PutCards; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.TargetPermanent; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetCreaturePermanentAmount; import java.util.UUID; /** * @author TheElk801 */ -public final class Vorinclex extends CardImpl { +public final class Vorinclex extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterCard("Forest cards"); @@ -32,32 +44,62 @@ public final class Vorinclex extends CardImpl { } public Vorinclex(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.PRAETOR}, "{3}{G}{G}", + "The Grand Evolution", + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "G" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.PRAETOR); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.secondSideCardClazz = mage.cards.t.TheGrandEvolution.class; + // Vorinclex + this.getLeftHalfCard().setPT(6, 6); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // Reach - this.addAbility(ReachAbility.getInstance()); + this.getLeftHalfCard().addAbility(ReachAbility.getInstance()); // When Vorinclex enters the battlefield, search your library for up to two Forest cards, reveal them, put them into your hand, then shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect( new TargetCardInLibrary(0, 2, filter), true ))); // {6}{G}{G}: Exile Vorinclex, then return it to the battlefield transformed under its owner's control. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility( + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{6}{G}{G}") )); + + // The Grand Evolution + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I -- Mill ten cards. Put up to two creature cards from among the milled cards onto the battlefield. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, new TheGrandEvolutionEffect()); + + // II -- Distribute seven +1/+1 counters among any number of target creatures you control. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, + new DistributeCountersEffect(), + new TargetCreaturePermanentAmount(7, StaticFilters.FILTER_CONTROLLED_CREATURES) + ); + + // III -- Until end of turn, creatures you control gain "{1}: This creature fights target creature you don't control." Exile The Grand Evolution, then return it to the battlefield. + Ability ability = new SimpleActivatedAbility( + new FightTargetSourceEffect() + .setText("this creature fights target creature you don't control"), + new GenericManaCost(1) + ); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_III, + new GainAbilityControlledEffect( + ability, Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("Until end of turn, creatures you control gain " + + "\"{1}: This creature fights target creature you don't control.\""), + new ExileSourceAndReturnFaceUpEffect() + ); + this.getRightHalfCard().addAbility(sagaAbility); } private Vorinclex(final Vorinclex card) { @@ -69,3 +111,34 @@ public final class Vorinclex extends CardImpl { return new Vorinclex(this); } } + +class TheGrandEvolutionEffect extends OneShotEffect { + + TheGrandEvolutionEffect() { + super(Outcome.Benefit); + staticText = "mill ten cards. Put up to two creature cards from among the milled cards onto the battlefield"; + } + + private TheGrandEvolutionEffect(final TheGrandEvolutionEffect effect) { + super(effect); + } + + @Override + public TheGrandEvolutionEffect copy() { + return new TheGrandEvolutionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = player.millCards(10, source, game); + TargetCard target = new TargetCard(0, 2, Zone.ALL, StaticFilters.FILTER_CARD_CREATURE); + target.withNotTarget(true); + player.choose(Outcome.PutCreatureInPlay, cards, target, source, game); + player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/w/WalkInClosetForgottenCellar.java b/Mage.Sets/src/mage/cards/w/WalkInClosetForgottenCellar.java index 5cebbbdc39c..4e9026e5e9b 100644 --- a/Mage.Sets/src/mage/cards/w/WalkInClosetForgottenCellar.java +++ b/Mage.Sets/src/mage/cards/w/WalkInClosetForgottenCellar.java @@ -6,9 +6,7 @@ import mage.abilities.effects.common.replacement.GraveyardFromAnywhereExileRepla import mage.abilities.effects.common.ruleModifying.PlayFromGraveyardControllerEffect; import mage.cards.CardSetInfo; import mage.cards.RoomCard; -import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.SpellAbilityType; import mage.constants.SubType; import mage.filter.StaticFilters; @@ -20,7 +18,7 @@ import java.util.UUID; public final class WalkInClosetForgottenCellar extends RoomCard { public WalkInClosetForgottenCellar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}", "{3}{G}{G}", SpellAbilityType.SPLIT); + super(ownerId, setInfo, "{2}{G}", "{3}{G}{G}"); this.subtype.add(SubType.ROOM); // Walk-In Closet: You may play lands from your graveyard. diff --git a/Mage.Sets/src/mage/cards/w/WaterloggedHulk.java b/Mage.Sets/src/mage/cards/w/WaterloggedHulk.java index b90cf8e7fa8..17739f43c89 100644 --- a/Mage.Sets/src/mage/cards/w/WaterloggedHulk.java +++ b/Mage.Sets/src/mage/cards/w/WaterloggedHulk.java @@ -1,11 +1,19 @@ package mage.cards.w; +import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.DescendCondition; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.decorator.ConditionalRestrictionEffect; import mage.abilities.effects.common.MillCardsControllerEffect; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; @@ -14,24 +22,44 @@ import java.util.UUID; /** * @author Susucr */ -public final class WaterloggedHulk extends CardImpl { +public final class WaterloggedHulk extends TransformingDoubleFacedCard { public WaterloggedHulk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}"); - this.secondSideCardClazz = mage.cards.w.WatertightGondola.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{U}", + "Watertight Gondola", + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "U" + ); + // Waterlogged Hulk // {T}: Mill a card. - this.addAbility(new SimpleActivatedAbility( + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility( new MillCardsControllerEffect(1), new TapSourceCost() )); // Craft with Island {3}{U} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{3}{U}", "Island", "another Island you control or an Island card from your graveyard", SubType.ISLAND.getPredicate() )); + + // Watertight Gondola + this.getRightHalfCard().setPT(4, 4); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Descend 8 -- Watertight Gondola can't be blocked as long as there are eight or more permanent cards in your graveyard. + Ability ability = new SimpleStaticAbility(new ConditionalRestrictionEffect( + new CantBeBlockedSourceEffect(), + DescendCondition.EIGHT + ).setText("{this} can't be blocked as long as there are eight or more permanent cards in your graveyard")); + this.getRightHalfCard().addAbility(ability.addHint(DescendCondition.getHint()).setAbilityWord(AbilityWord.DESCEND_8)); + + // Crew 1 + this.getRightHalfCard().addAbility(new CrewAbility(1)); } private WaterloggedHulk(final WaterloggedHulk card) { diff --git a/Mage.Sets/src/mage/cards/w/WatertightGondola.java b/Mage.Sets/src/mage/cards/w/WatertightGondola.java deleted file mode 100644 index f7e46376672..00000000000 --- a/Mage.Sets/src/mage/cards/w/WatertightGondola.java +++ /dev/null @@ -1,56 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.common.DescendCondition; -import mage.abilities.decorator.ConditionalRestrictionEffect; -import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; -import mage.abilities.keyword.CrewAbility; -import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.AbilityWord; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class WatertightGondola extends CardImpl { - - public WatertightGondola(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - this.nightCard = true; - this.color.setBlue(true); - - this.subtype.add(SubType.VEHICLE); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Descend 8 -- Watertight Gondola can't be blocked as long as there are eight or more permanent cards in your graveyard. - Ability ability = new SimpleStaticAbility(new ConditionalRestrictionEffect( - new CantBeBlockedSourceEffect(), - DescendCondition.EIGHT - ).setText("{this} can't be blocked as long as there are eight or more permanent cards in your graveyard")); - this.addAbility(ability.addHint(DescendCondition.getHint()).setAbilityWord(AbilityWord.DESCEND_8)); - - // Crew 1 - this.addAbility(new CrewAbility(1)); - - } - - private WatertightGondola(final WatertightGondola card) { - super(card); - } - - @Override - public WatertightGondola copy() { - return new WatertightGondola(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WearyPrisoner.java b/Mage.Sets/src/mage/cards/w/WearyPrisoner.java index 83b8d2469ac..6b6086b9a99 100644 --- a/Mage.Sets/src/mage/cards/w/WearyPrisoner.java +++ b/Mage.Sets/src/mage/cards/w/WearyPrisoner.java @@ -1,10 +1,11 @@ package mage.cards.w; -import mage.MageInt; +import mage.abilities.common.AttacksEachCombatStaticAbility; import mage.abilities.keyword.DayboundAbility; import mage.abilities.keyword.DefenderAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,23 +14,32 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class WearyPrisoner extends CardImpl { +public final class WearyPrisoner extends TransformingDoubleFacedCard { public WearyPrisoner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{3}{R}", + "Wrathful Jailbreaker", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(6); - - this.secondSideCardClazz = mage.cards.w.WrathfulJailbreaker.class; + // Weary Prisoner + this.getLeftHalfCard().setPT(2, 6); // Defender - this.addAbility(DefenderAbility.getInstance()); + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Wrathful Jailbreaker + this.getRightHalfCard().setPT(6, 6); + + // Wrathful Jailbreaker attacks each combat if able. + this.getRightHalfCard().addAbility(new AttacksEachCombatStaticAbility()); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private WearyPrisoner(final WearyPrisoner card) { diff --git a/Mage.Sets/src/mage/cards/w/WeaverOfBlossoms.java b/Mage.Sets/src/mage/cards/w/WeaverOfBlossoms.java index 3f00c090a34..3da13b5b4b0 100644 --- a/Mage.Sets/src/mage/cards/w/WeaverOfBlossoms.java +++ b/Mage.Sets/src/mage/cards/w/WeaverOfBlossoms.java @@ -1,34 +1,50 @@ package mage.cards.w; -import mage.MageInt; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.Zone; import java.util.UUID; /** * @author TheElk801 */ -public final class WeaverOfBlossoms extends CardImpl { +public final class WeaverOfBlossoms extends TransformingDoubleFacedCard { public WeaverOfBlossoms(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{2}{G}", + "Blossom-Clad Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.b.BlossomCladWerewolf.class; + // Weaver of Blossoms + this.getLeftHalfCard().setPT(2, 3); // {T}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); + this.getLeftHalfCard().addAbility(new AnyColorManaAbility()); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Blossom-Clad Werewolf + this.getRightHalfCard().setPT(3, 4); + + // {T}: Add two mana of any one color. + this.getRightHalfCard().addAbility(new SimpleManaAbility( + Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost() + )); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private WeaverOfBlossoms(final WeaverOfBlossoms card) { diff --git a/Mage.Sets/src/mage/cards/w/WeddingAnnouncement.java b/Mage.Sets/src/mage/cards/w/WeddingAnnouncement.java index 3aeec3b1c6a..5adb45a4eef 100644 --- a/Mage.Sets/src/mage/cards/w/WeddingAnnouncement.java +++ b/Mage.Sets/src/mage/cards/w/WeddingAnnouncement.java @@ -1,41 +1,46 @@ package mage.cards.w; -import java.util.UUID; - import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.token.HumanToken; import mage.watchers.common.AttackedThisTurnWatcher; +import java.util.UUID; + /** * * @author weirddan455 */ -public final class WeddingAnnouncement extends CardImpl { +public final class WeddingAnnouncement extends TransformingDoubleFacedCard { public WeddingAnnouncement(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); - - this.secondSideCardClazz = mage.cards.w.WeddingFestivity.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{2}{W}", + "Wedding Festivity", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "W" + ); + // Wedding Announcement // At the beginning of your end step, put an invitation counter on Wedding Announcement. // If you attacked with two or more creatures this turn, draw card. // Otherwise, create a 1/1 white Human creature token. // Then if Wedding Announcement has three or more invitation counters on it, transform it. - this.addAbility(new TransformAbility()); Ability ability = new BeginningOfEndStepTriggeredAbility(new AddCountersSourceEffect(CounterType.INVITATION.createInstance())); ability.addEffect(new ConditionalOneShotEffect( new DrawCardSourceControllerEffect(1), @@ -48,7 +53,11 @@ public final class WeddingAnnouncement extends CardImpl { new SourceHasCounterCondition(CounterType.INVITATION, 3), "Then if {this} has three or more invitation counters on it, transform it" )); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Wedding Festivity + // Creatures you control get +1/+1 + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield))); } private WeddingAnnouncement(final WeddingAnnouncement card) { diff --git a/Mage.Sets/src/mage/cards/w/WeddingCrasher.java b/Mage.Sets/src/mage/cards/w/WeddingCrasher.java deleted file mode 100644 index 662b9eea17b..00000000000 --- a/Mage.Sets/src/mage/cards/w/WeddingCrasher.java +++ /dev/null @@ -1,57 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.Predicates; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class WeddingCrasher extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledPermanent("Wolf or Werewolf you control"); - - static { - filter.add(Predicates.or( - SubType.WOLF.getPredicate(), - SubType.WEREWOLF.getPredicate() - )); - } - - public WeddingCrasher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(6); - this.toughness = new MageInt(5); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever Wedding Crasher or another Wolf or Werewolf you control dies, draw a card. - this.addAbility(new DiesThisOrAnotherTriggeredAbility( - new DrawCardSourceControllerEffect(1), false, filter - )); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private WeddingCrasher(final WeddingCrasher card) { - super(card); - } - - @Override - public WeddingCrasher copy() { - return new WeddingCrasher(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WeddingFestivity.java b/Mage.Sets/src/mage/cards/w/WeddingFestivity.java deleted file mode 100644 index e456652aa21..00000000000 --- a/Mage.Sets/src/mage/cards/w/WeddingFestivity.java +++ /dev/null @@ -1,36 +0,0 @@ -package mage.cards.w; - -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; - -import java.util.UUID; - -/** - * - * @author weirddan455 - */ -public class WeddingFestivity extends CardImpl { - - public WeddingFestivity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setWhite(true); - this.nightCard = true; - - // Creatures you control get +1/+1 - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield))); - } - - private WeddingFestivity(final WeddingFestivity card) { - super(card); - } - - @Override - public WeddingFestivity copy() { - return new WeddingFestivity(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WelcomeTo.java b/Mage.Sets/src/mage/cards/w/WelcomeTo.java index 42cde76dfbd..7889a2a05d3 100644 --- a/Mage.Sets/src/mage/cards/w/WelcomeTo.java +++ b/Mage.Sets/src/mage/cards/w/WelcomeTo.java @@ -1,59 +1,77 @@ package mage.cards.w; +import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.EscapeAbility; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.DynamicManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.token.DinosaurToken; import mage.game.permanent.token.custom.CreatureToken; +import mage.players.Player; import mage.target.TargetPermanent; import mage.target.targetadjustment.ForEachPlayerTargetsAdjuster; import mage.target.targetpointer.EachTargetPointer; import mage.target.targetpointer.FixedTarget; +import java.util.Objects; import java.util.UUID; /** * * @author jimga150 */ -public final class WelcomeTo extends CardImpl { +public final class WelcomeTo extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterPermanent("Walls"); private static final FilterPermanent filterNoncreatureArtifact = new FilterPermanent("noncreature artifact"); + private static final FilterPermanent filterDinosaur = new FilterControlledPermanent("Dinosaur you control"); static { filter.add(SubType.WALL.getPredicate()); filterNoncreatureArtifact.add(Predicates.not(CardType.CREATURE.getPredicate())); filterNoncreatureArtifact.add(CardType.ARTIFACT.getPredicate()); + filterDinosaur.add(SubType.DINOSAUR.getPredicate()); } + private static final Hint hint = new ValueHint( + "Number of Dinosaurs you control", new PermanentsOnBattlefieldCount(filterDinosaur) + ); + // Based on Azusa's Many Journeys // Likeness of the Seeker, Vronos Masked Inquisitor, In the Darkness Bind Then, public WelcomeTo(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{G}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.j.JurassicPark.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{G}{G}", + "Jurassic Park", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Welcome to . . . // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); + SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard()); // I -- For each opponent, up to one target noncreature artifact they control becomes a 0/4 Wall artifact creature with defender for as long as you control this Saga. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> { + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, ability -> { ability.addEffect( new BecomesCreatureTargetEffect( new CreatureToken(0, 4) @@ -69,16 +87,28 @@ public final class WelcomeTo extends CardImpl { // II -- Create a 3/3 green Dinosaur creature token with trample. It gains haste until end of turn. // Based on Mordor on the March - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new WelcomeToEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new WelcomeToEffect()); // III -- Destroy all Walls. Exile this Saga, then return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> { + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, ability -> { ability.addEffect(new DestroyAllEffect(filter)); ability.addEffect(new ExileSagaAndReturnTransformedEffect()); }); - this.addAbility(sagaAbility); + this.getLeftHalfCard().addAbility(sagaAbility); + + // Jurassic Park + // Each Dinosaur card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. + // Based on Underworld Breach + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new JurassicParkEffect())); + + // {T}: Add {G} for each Dinosaur you control. + // Based on Gaea's Cradle + DynamicManaAbility ability = new DynamicManaAbility( + Mana.GreenMana(1), + new PermanentsOnBattlefieldCount(filterDinosaur) + ); + this.getRightHalfCard().addAbility(ability.addHint(hint)); } private WelcomeTo(final WelcomeTo card) { @@ -121,5 +151,44 @@ class WelcomeToEffect extends OneShotEffect { }); return true; } - +} + +class JurassicParkEffect extends ContinuousEffectImpl { + + JurassicParkEffect() { + super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + staticText = "Each Dinosaur card in your graveyard has escape. " + + "The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard."; + } + + private JurassicParkEffect(final JurassicParkEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + controller + .getGraveyard() + .getCards(game) + .stream() + .filter(Objects::nonNull) + .filter(card -> !card.getManaCost().getText().isEmpty()) // card must have a mana cost + .filter(card -> card.hasSubtype(SubType.DINOSAUR, game)) + .forEach(card -> { + Ability ability = new EscapeAbility(card, card.getManaCost().getText(), 3); + ability.setSourceId(card.getId()); + ability.setControllerId(card.getOwnerId()); + game.getState().addOtherAbility(card, ability); + }); + return true; + } + + @Override + public JurassicParkEffect copy() { + return new JurassicParkEffect(this); + } } diff --git a/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java b/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java deleted file mode 100644 index 461ec0d4dc7..00000000000 --- a/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java +++ /dev/null @@ -1,61 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.condition.common.NotTransformedCondition; -import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.dynamicvalue.common.CardsInAllHandsCount; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -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.SubType; -import mage.constants.Zone; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class WerewolfOfAncientHunger extends CardImpl { - - public WerewolfOfAncientHunger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.color.setGreen(true); - - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Werewolf of Ancient Hunger's power and toughness are each equal to the total number of cards in all players' hands. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new ConditionalContinuousEffect( - new SetBasePowerToughnessSourceEffect(CardsInAllHandsCount.instance), NotTransformedCondition.instance, - "{this}'s power and toughness are each equal to the total number of cards in all players' hands" - ) - )); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Werewolf of Ancient Hunger. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private WerewolfOfAncientHunger(final WerewolfOfAncientHunger card) { - super(card); - } - - @Override - public WerewolfOfAncientHunger copy() { - return new WerewolfOfAncientHunger(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java b/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java index f618bb62b61..10b8acdbee9 100644 --- a/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java +++ b/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java @@ -1,8 +1,5 @@ - package mage.cards.w; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.PayLifeCost; @@ -12,43 +9,64 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.UntapSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.LifelinkAbility; import mage.abilities.mana.ColorlessManaAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; -import mage.constants.Zone; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.permanent.token.HumanClericToken; -import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; /** * @author fireshoes */ -public final class WestvaleAbbey extends CardImpl { +public final class WestvaleAbbey extends TransformingDoubleFacedCard { public WestvaleAbbey(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.secondSideCardClazz = mage.cards.o.OrmendahlProfanePrince.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, "", + "Ormendahl, Profane Prince", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "B" + ); + // Westvale Abbey // {T}: Add {C}. - this.addAbility(new ColorlessManaAbility()); + this.getLeftHalfCard().addAbility(new ColorlessManaAbility()); // {5}, {T}, Pay 1 life: Create a 1/1 white and black Human Cleric creature token. Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new HumanClericToken()), new GenericManaCost(5)); ability.addCost(new TapSourceCost()); ability.addCost(new PayLifeCost(1)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {5}, {T}, Sacrifice five creatures: Transform Westvale Abbey and untap it. - this.addAbility(new TransformAbility()); ability = new SimpleActivatedAbility(new TransformSourceEffect(), new GenericManaCost(5)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeTargetCost(5, StaticFilters.FILTER_PERMANENT_CREATURES)); ability.addEffect(new UntapSourceEffect().setText("untap it").concatBy(", then")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Ormendahl, Profane Prince + this.getRightHalfCard().setPT(9, 7); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // Indestructible + this.getRightHalfCard().addAbility(IndestructibleAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); } private WestvaleAbbey(final WestvaleAbbey card) { diff --git a/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java b/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java index ab976d8286d..0953e800441 100644 --- a/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java +++ b/Mage.Sets/src/mage/cards/w/WolfbittenCaptive.java @@ -1,13 +1,12 @@ package mage.cards.w; -import mage.MageInt; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; @@ -18,24 +17,32 @@ import java.util.UUID; /** * @author Loki */ -public final class WolfbittenCaptive extends CardImpl { +public final class WolfbittenCaptive extends TransformingDoubleFacedCard { public WolfbittenCaptive(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{G}", + "Krallenhorde Killer", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - - this.secondSideCardClazz = mage.cards.k.KrallenhordeKiller.class; + // Wolfbitten Captive + this.getLeftHalfCard().setPT(1, 1); // {1}{G}: Wolfbitten Captive gets +2/+2 until end of turn. Activate this ability only once each turn. - this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{G}"))); + this.getLeftHalfCard().addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{G}"))); // At the beginning of each upkeep, if no spells were cast last turn, transform Wolfbitten Captive. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Krallenhorde Killer + this.getRightHalfCard().setPT(2, 2); + + // {3}{G}: Krallenhorde Killer gets +4/+4 until end of turn. Activate this ability only once each turn. + this.getRightHalfCard().addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(4, 4, Duration.EndOfTurn), new ManaCostsImpl<>("{3}{G}"))); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Krallenhorde Killer. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private WolfbittenCaptive(final WolfbittenCaptive card) { diff --git a/Mage.Sets/src/mage/cards/w/WolfkinOutcast.java b/Mage.Sets/src/mage/cards/w/WolfkinOutcast.java index 21595ce0f23..b0d3e0bfa84 100644 --- a/Mage.Sets/src/mage/cards/w/WolfkinOutcast.java +++ b/Mage.Sets/src/mage/cards/w/WolfkinOutcast.java @@ -1,15 +1,17 @@ package mage.cards.w; -import mage.MageInt; +import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; import mage.abilities.keyword.DayboundAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -22,15 +24,20 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class WolfkinOutcast extends CardImpl { +public final class WolfkinOutcast extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledPermanent("you control a Wolf or Werewolf"); + private static final FilterPermanent filter2 = new FilterControlledPermanent("Wolf or Werewolf you control"); static { filter.add(Predicates.or( SubType.WOLF.getPredicate(), SubType.WEREWOLF.getPredicate() )); + filter2.add(Predicates.or( + SubType.WOLF.getPredicate(), + SubType.WEREWOLF.getPredicate() + )); } private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); @@ -39,21 +46,35 @@ public final class WolfkinOutcast extends CardImpl { ); public WolfkinOutcast(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{5}{G}", + "Wedding Crasher", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(5); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.w.WeddingCrasher.class; + // Wolfkin Outcast + this.getLeftHalfCard().setPT(5, 4); // This spell costs {2} less to cast if you control a Wolf or Werewolf. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, new SpellCostReductionSourceEffect(2, condition).setCanWorksOnStackOnly(true) - ).setRuleAtTheTop(true)); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility( + Zone.ALL, new SpellCostReductionSourceEffect(2, condition).setCanWorksOnStackOnly(true)) + .setRuleAtTheTop(true) + .addHint(hint) + ); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Wedding Crasher + this.getRightHalfCard().setPT(6, 5); + + // Whenever Wedding Crasher or another Wolf or Werewolf you control dies, draw a card. + this.getRightHalfCard().addAbility(new DiesThisOrAnotherTriggeredAbility( + new DrawCardSourceControllerEffect(1), false, filter2 + )); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private WolfkinOutcast(final WolfkinOutcast card) { diff --git a/Mage.Sets/src/mage/cards/w/WorldChampionCelestialWeapon.java b/Mage.Sets/src/mage/cards/w/WorldChampionCelestialWeapon.java deleted file mode 100644 index 5b81bc4e926..00000000000 --- a/Mage.Sets/src/mage/cards/w/WorldChampionCelestialWeapon.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.w; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.BoostEquippedEffect; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.keyword.DoubleStrikeAbility; -import mage.abilities.keyword.EquipAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class WorldChampionCelestialWeapon extends CardImpl { - - public WorldChampionCelestialWeapon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.EQUIPMENT); - this.nightCard = true; - this.color.setRed(true); - - // Double Overdrive -- Equipped creature gets +2/+0 and has double strike. - Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 0)); - ability.addEffect(new GainAbilityAttachedEffect( - DoubleStrikeAbility.getInstance(), AttachmentType.EQUIPMENT - ).setText("and has double strike")); - this.addAbility(ability.withFlavorWord("Double Overdrive")); - - // Equip {3} - this.addAbility(new EquipAbility(3)); - } - - private WorldChampionCelestialWeapon(final WorldChampionCelestialWeapon card) { - super(card); - } - - @Override - public WorldChampionCelestialWeapon copy() { - return new WorldChampionCelestialWeapon(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WrathfulJailbreaker.java b/Mage.Sets/src/mage/cards/w/WrathfulJailbreaker.java deleted file mode 100644 index 3e0bf2c9f1b..00000000000 --- a/Mage.Sets/src/mage/cards/w/WrathfulJailbreaker.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.common.AttacksEachCombatStaticAbility; -import mage.abilities.keyword.NightboundAbility; -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 WrathfulJailbreaker extends CardImpl { - - public WrathfulJailbreaker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.color.setRed(true); - - this.nightCard = true; - - // Wrathful Jailbreaker attacks each combat if able. - this.addAbility(new AttacksEachCombatStaticAbility()); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private WrathfulJailbreaker(final WrathfulJailbreaker card) { - super(card); - } - - @Override - public WrathfulJailbreaker copy() { - return new WrathfulJailbreaker(this); - } -} diff --git a/Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java b/Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java deleted file mode 100644 index 277a6a11108..00000000000 --- a/Mage.Sets/src/mage/cards/y/YiazmatUltimateMark.java +++ /dev/null @@ -1,65 +0,0 @@ -package mage.cards.y; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.TapSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.keyword.IndestructibleAbility; -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.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AnotherPredicate; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class YiazmatUltimateMark extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("another creature or artifact"); - - static { - filter.add(AnotherPredicate.instance); - filter.add(Predicates.or( - CardType.CREATURE.getPredicate(), - CardType.ARTIFACT.getPredicate() - )); - } - - public YiazmatUltimateMark(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.DRAGON); - this.power = new MageInt(5); - this.toughness = new MageInt(6); - this.nightCard = true; - this.color.setBlack(true); - - // {1}{B}, Sacrifice another creature or artifact: Yiazmat gains indestructible until end of turn. Tap it. - Ability ability = new SimpleActivatedAbility( - new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl<>("{1}{B}") - ); - ability.addCost(new SacrificeTargetCost(filter)); - ability.addEffect(new TapSourceEffect().setText("tap it")); - this.addAbility(ability); - } - - private YiazmatUltimateMark(final YiazmatUltimateMark card) { - super(card); - } - - @Override - public YiazmatUltimateMark copy() { - return new YiazmatUltimateMark(this); - } -} diff --git a/Mage.Sets/src/mage/cards/z/ZenosYaeGalvus.java b/Mage.Sets/src/mage/cards/z/ZenosYaeGalvus.java index d808e24232d..72f226bec8f 100644 --- a/Mage.Sets/src/mage/cards/z/ZenosYaeGalvus.java +++ b/Mage.Sets/src/mage/cards/z/ZenosYaeGalvus.java @@ -1,27 +1,31 @@ package mage.cards.z; -import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.ChooseCreatureEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.WinGameSourceControllerEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetOpponent; import mage.util.CardUtil; import java.util.Optional; @@ -30,7 +34,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class ZenosYaeGalvus extends CardImpl { +public final class ZenosYaeGalvus extends TransformingDoubleFacedCard { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); private static final FilterPermanent filter2 = new FilterPermanent(); @@ -41,15 +45,14 @@ public final class ZenosYaeGalvus extends CardImpl { } public ZenosYaeGalvus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE, SubType.WARRIOR}, "{3}{B}{B}", + "Shinryu, Transcendent Rival", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DRAGON}, "B" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.s.ShinryuTranscendentRival.class; + // Zenos yae Galvus + this.getLeftHalfCard().setPT(4, 4); // My First Friend -- When Zenos yae Galvus enters, choose a creature an opponent controls. Until end of turn, creatures other than Zenos yae Galvus and the chosen creature get -2/-2. Ability ability = new EntersBattlefieldTriggeredAbility( @@ -58,13 +61,24 @@ public final class ZenosYaeGalvus extends CardImpl { ability.addEffect(new BoostAllEffect( -2, -2, Duration.EndOfTurn, filter, true ).setText("until end of turn, creatures other than {this} and the chosen creature get -2/-2")); - this.addAbility(ability.withFlavorWord("My First Friend")); + this.getLeftHalfCard().addAbility(ability.withFlavorWord("My First Friend")); // When the chosen creature leaves the battlefield, transform Zenos yae Galvus. - this.addAbility(new TransformAbility()); - this.addAbility(new LeavesBattlefieldAllTriggeredAbility( + this.getLeftHalfCard().addAbility(new LeavesBattlefieldAllTriggeredAbility( new TransformSourceEffect(), filter2 ).setTriggerPhrase("When the chosen creature leaves the battlefield, ")); + + // Shinryu, Transcendent Rival + this.getRightHalfCard().setPT(8, 8); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // As this creature transforms into Shinryu, choose an opponent. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new ShinryuTranscendentRivalEffect())); + + // Burning Chains -- When the chosen player loses the game, you win the game. + this.getRightHalfCard().addAbility(new ShinryuTranscendentRivalTriggeredAbility()); } private ZenosYaeGalvus(final ZenosYaeGalvus card) { @@ -101,3 +115,83 @@ enum ZenosYaeGalvusPredicate implements ObjectSourcePlayerPredicate { .orElse(false); } } + +class ShinryuTranscendentRivalEffect extends ReplacementEffectImpl { + + ShinryuTranscendentRivalEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "as this creature transforms into {this}, choose an opponent"; + } + + private ShinryuTranscendentRivalEffect(final ShinryuTranscendentRivalEffect effect) { + super(effect); + } + + @Override + public ShinryuTranscendentRivalEffect copy() { + return new ShinryuTranscendentRivalEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (controller == null || permanent == null) { + return false; + } + TargetPlayer target = new TargetOpponent(true); + controller.choose(Outcome.Benefit, target, source, game); + Player opponent = game.getPlayer(target.getFirstTarget()); + if (opponent == null) { + return false; + } + game.informPlayers(permanent.getName() + ": " + controller.getLogName() + " has chosen " + opponent.getLogName()); + game.getState().setValue(permanent.getId() + "_" + permanent.getZoneChangeCounter(game) + "_opponent", opponent.getId()); + permanent.addInfo("chosen opponent", CardUtil.addToolTipMarkTags("Chosen Opponent " + opponent.getLogName()), game); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.TRANSFORMING; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return source.getSourceId().equals(event.getTargetId()) + && source.getSourcePermanentIfItStillExists(game) != null; + } +} + +class ShinryuTranscendentRivalTriggeredAbility extends TriggeredAbilityImpl { + + ShinryuTranscendentRivalTriggeredAbility() { + super(Zone.BATTLEFIELD, new WinGameSourceControllerEffect()); + this.setTriggerPhrase("When the chosen player loses the game, "); + this.withFlavorWord("Burning Chains"); + } + + private ShinryuTranscendentRivalTriggeredAbility(final ShinryuTranscendentRivalTriggeredAbility ability) { + super(ability); + } + + @Override + public ShinryuTranscendentRivalTriggeredAbility copy() { + return new ShinryuTranscendentRivalTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.LOST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + int zcc = game.getState().getZoneChangeCounter(this.getSourceId()); + return Optional + .of(this.getSourceId() + "_" + zcc + "_opponent") + .map(game.getState()::getValue) + .map(event.getPlayerId()::equals) + .orElse(false); + } +} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index c930478e179..705abf5f972 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -57,14 +57,6 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Avatar Destiny", 165, Rarity.RARE, mage.cards.a.AvatarDestiny.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Destiny", 333, Rarity.RARE, mage.cards.a.AvatarDestiny.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar Enthusiasts", 11, Rarity.COMMON, mage.cards.a.AvatarEnthusiasts.class)); - cards.add(new SetCardInfo("Avatar Kuruk", 355, Rarity.MYTHIC, mage.cards.a.AvatarKuruk.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Kuruk", 61, Rarity.MYTHIC, mage.cards.a.AvatarKuruk.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Kyoshi", 186, Rarity.MYTHIC, mage.cards.a.AvatarKyoshi.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Kyoshi", 358, Rarity.MYTHIC, mage.cards.a.AvatarKyoshi.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Roku", 145, Rarity.MYTHIC, mage.cards.a.AvatarRoku.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Roku", 357, Rarity.MYTHIC, mage.cards.a.AvatarRoku.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Yangchen", 27, Rarity.MYTHIC, mage.cards.a.AvatarYangchen.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Yangchen", 354, Rarity.MYTHIC, mage.cards.a.AvatarYangchen.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar's Wrath", 12, Rarity.RARE, mage.cards.a.AvatarsWrath.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avatar's Wrath", 365, Rarity.RARE, mage.cards.a.AvatarsWrath.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azula Always Lies", 84, Rarity.COMMON, mage.cards.a.AzulaAlwaysLies.class)); @@ -148,8 +140,6 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Fire Lord Azula", 220, Rarity.RARE, mage.cards.f.FireLordAzula.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Azula", 313, Rarity.RARE, mage.cards.f.FireLordAzula.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Azula", 334, Rarity.RARE, mage.cards.f.FireLordAzula.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fire Lord Sozin", 117, Rarity.MYTHIC, mage.cards.f.FireLordSozin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fire Lord Sozin", 356, Rarity.MYTHIC, mage.cards.f.FireLordSozin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Zuko", 221, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Zuko", 315, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fire Lord Zuko", 360, Rarity.RARE, mage.cards.f.FireLordZuko.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index a7b26312367..51a5ad2f8f8 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -39,10 +39,6 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Appa, Aang's Companion", 268, Rarity.UNCOMMON, mage.cards.a.AppaAangsCompanion.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Appa, the Vigilant", 62, Rarity.RARE, mage.cards.a.AppaTheVigilant.class)); cards.add(new SetCardInfo("Arcane Signet", 315, Rarity.RARE, mage.cards.a.ArcaneSignet.class)); - cards.add(new SetCardInfo("Avatar Kyoshi, Earthbender", 130, Rarity.MYTHIC, mage.cards.a.AvatarKyoshiEarthbender.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Kyoshi, Earthbender", 201, Rarity.MYTHIC, mage.cards.a.AvatarKyoshiEarthbender.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Roku, Firebender", 112, Rarity.MYTHIC, mage.cards.a.AvatarRokuFirebender.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Avatar Roku, Firebender", 191, Rarity.MYTHIC, mage.cards.a.AvatarRokuFirebender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azula, Ruthless Firebender", 101, Rarity.MYTHIC, mage.cards.a.AzulaRuthlessFirebender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Azula, Ruthless Firebender", 184, Rarity.MYTHIC, mage.cards.a.AzulaRuthlessFirebender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Baboon Spirit", 177, Rarity.RARE, mage.cards.b.BaboonSpirit.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/DarkAscension.java b/Mage.Sets/src/mage/sets/DarkAscension.java index 8e6f3d7c182..9273ed0220e 100644 --- a/Mage.Sets/src/mage/sets/DarkAscension.java +++ b/Mage.Sets/src/mage/sets/DarkAscension.java @@ -96,7 +96,6 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Gavony Ironwright", 9, Rarity.UNCOMMON, mage.cards.g.GavonyIronwright.class)); cards.add(new SetCardInfo("Geralf's Messenger", 63, Rarity.RARE, mage.cards.g.GeralfsMessenger.class)); cards.add(new SetCardInfo("Geralf's Mindcrusher", 37, Rarity.RARE, mage.cards.g.GeralfsMindcrusher.class)); - cards.add(new SetCardInfo("Ghastly Haunting", 50, Rarity.UNCOMMON, mage.cards.g.GhastlyHaunting.class)); cards.add(new SetCardInfo("Ghoultree", 115, Rarity.RARE, mage.cards.g.Ghoultree.class)); cards.add(new SetCardInfo("Grafdigger's Cage", 149, Rarity.RARE, mage.cards.g.GrafdiggersCage.class)); cards.add(new SetCardInfo("Gravecrawler", 64, Rarity.RARE, mage.cards.g.Gravecrawler.class)); @@ -129,7 +128,6 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Increasing Vengeance", 95, Rarity.RARE, mage.cards.i.IncreasingVengeance.class)); cards.add(new SetCardInfo("Jar of Eyeballs", 152, Rarity.RARE, mage.cards.j.JarOfEyeballs.class)); cards.add(new SetCardInfo("Kessig Recluse", 121, Rarity.COMMON, mage.cards.k.KessigRecluse.class)); - cards.add(new SetCardInfo("Krallenhorde Killer", 133, Rarity.RARE, mage.cards.k.KrallenhordeKiller.class)); cards.add(new SetCardInfo("Lambholt Elder", 122, Rarity.UNCOMMON, mage.cards.l.LambholtElder.class)); cards.add(new SetCardInfo("Lingering Souls", 12, Rarity.UNCOMMON, mage.cards.l.LingeringSouls.class)); cards.add(new SetCardInfo("Lost in the Woods", 123, Rarity.RARE, mage.cards.l.LostInTheWoods.class)); @@ -139,7 +137,6 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Midnight Guard", 14, Rarity.COMMON, mage.cards.m.MidnightGuard.class)); cards.add(new SetCardInfo("Mikaeus, the Unhallowed", 70, Rarity.MYTHIC, mage.cards.m.MikaeusTheUnhallowed.class)); cards.add(new SetCardInfo("Mondronen Shaman", 98, Rarity.RARE, mage.cards.m.MondronenShaman.class)); - cards.add(new SetCardInfo("Moonscarred Werewolf", 125, Rarity.COMMON, mage.cards.m.MoonscarredWerewolf.class)); cards.add(new SetCardInfo("Moonveil Dragon", 99, Rarity.MYTHIC, mage.cards.m.MoonveilDragon.class)); cards.add(new SetCardInfo("Mystic Retrieval", 42, Rarity.UNCOMMON, mage.cards.m.MysticRetrieval.class)); cards.add(new SetCardInfo("Nearheath Stalker", 100, Rarity.COMMON, mage.cards.n.NearheathStalker.class)); diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java index 869362df083..dd4e6aa7428 100644 --- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java +++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java @@ -73,14 +73,16 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Dazzling Theater // Prop Room", 3, Rarity.RARE, mage.cards.d.DazzlingTheaterPropRoom.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dazzling Theater // Prop Room", 334, Rarity.RARE, mage.cards.d.DazzlingTheaterPropRoom.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Defiant Survivor", 175, Rarity.UNCOMMON, mage.cards.d.DefiantSurvivor.class)); + cards.add(new SetCardInfo("Defiled Crypt // Cadaver Lab", 91, Rarity.UNCOMMON, mage.cards.d.DefiledCryptCadaverLab.class)); cards.add(new SetCardInfo("Demonic Counsel", 310, Rarity.RARE, mage.cards.d.DemonicCounsel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Demonic Counsel", 92, Rarity.RARE, mage.cards.d.DemonicCounsel.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Derelict Attic // Widow's Walk", 93, Rarity.COMMON, mage.cards.d.DerelictAtticWidowsWalk.class)); cards.add(new SetCardInfo("Dissection Tools", 245, Rarity.RARE, mage.cards.d.DissectionTools.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dissection Tools", 385, Rarity.RARE, mage.cards.d.DissectionTools.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Disturbing Mirth", 212, Rarity.UNCOMMON, mage.cards.d.DisturbingMirth.class)); cards.add(new SetCardInfo("Diversion Specialist", 132, Rarity.UNCOMMON, mage.cards.d.DiversionSpecialist.class)); - cards.add(new SetCardInfo("Dollmaker's Shop // Porcelain Gallery", 4, Rarity.MYTHIC, mage.cards.d.DollmakersShopPorcelainGallery.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dollmaker's Shop // Porcelain Gallery", 335, Rarity.MYTHIC, mage.cards.d.DollmakersShopPorcelainGallery.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dollmaker's Shop // Porcelain Gallery", 4, Rarity.MYTHIC, mage.cards.d.DollmakersShopPorcelainGallery.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Don't Make a Sound", 49, Rarity.COMMON, mage.cards.d.DontMakeASound.class)); cards.add(new SetCardInfo("Doomsday Excruciator", 346, Rarity.RARE, mage.cards.d.DoomsdayExcruciator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Doomsday Excruciator", 94, Rarity.RARE, mage.cards.d.DoomsdayExcruciator.class, NON_FULL_USE_VARIOUS)); @@ -151,14 +153,19 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Ghost Vacuum", 326, Rarity.RARE, mage.cards.g.GhostVacuum.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ghostly Dancers", 13, Rarity.RARE, mage.cards.g.GhostlyDancers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ghostly Dancers", 302, Rarity.RARE, mage.cards.g.GhostlyDancers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ghostly Keybearer", 61, Rarity.UNCOMMON, mage.cards.g.GhostlyKeybearer.class)); cards.add(new SetCardInfo("Give In to Violence", 101, Rarity.COMMON, mage.cards.g.GiveInToViolence.class)); + cards.add(new SetCardInfo("Glassworks // Shattered Yard", 137, Rarity.COMMON, mage.cards.g.GlassworksShatteredYard.class)); cards.add(new SetCardInfo("Glimmer Seeker", 14, Rarity.UNCOMMON, mage.cards.g.GlimmerSeeker.class)); cards.add(new SetCardInfo("Glimmerburst", 62, Rarity.COMMON, mage.cards.g.Glimmerburst.class)); cards.add(new SetCardInfo("Glimmerlight", 249, Rarity.COMMON, mage.cards.g.Glimmerlight.class)); cards.add(new SetCardInfo("Gloomlake Verge", 260, Rarity.RARE, mage.cards.g.GloomlakeVerge.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gloomlake Verge", 331, Rarity.RARE, mage.cards.g.GloomlakeVerge.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grab the Prize", 138, Rarity.COMMON, mage.cards.g.GrabThePrize.class)); + cards.add(new SetCardInfo("Grand Entryway // Elegant Rotunda", 15, Rarity.COMMON, mage.cards.g.GrandEntrywayElegantRotunda.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Grand Entryway // Elegant Rotunda", 287, Rarity.COMMON, mage.cards.g.GrandEntrywayElegantRotunda.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grasping Longneck", 180, Rarity.COMMON, mage.cards.g.GraspingLongneck.class)); + cards.add(new SetCardInfo("Greenhouse // Rickety Gazebo", 181, Rarity.UNCOMMON, mage.cards.g.GreenhouseRicketyGazebo.class)); cards.add(new SetCardInfo("Gremlin Tamer", 215, Rarity.UNCOMMON, mage.cards.g.GremlinTamer.class)); cards.add(new SetCardInfo("Grievous Wound", 102, Rarity.RARE, mage.cards.g.GrievousWound.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grievous Wound", 375, Rarity.RARE, mage.cards.g.GrievousWound.class, NON_FULL_USE_VARIOUS)); @@ -218,11 +225,15 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Marina Vendrell's Grimoire", 64, Rarity.RARE, mage.cards.m.MarinaVendrellsGrimoire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Marvin, Murderous Mimic", 253, Rarity.RARE, mage.cards.m.MarvinMurderousMimic.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Marvin, Murderous Mimic", 367, Rarity.RARE, mage.cards.m.MarvinMurderousMimic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Meat Locker // Drowned Diner", 65, Rarity.COMMON, mage.cards.m.MeatLockerDrownedDiner.class)); cards.add(new SetCardInfo("Meathook Massacre II", 108, Rarity.MYTHIC, mage.cards.m.MeathookMassacreII.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Meathook Massacre II", 293, 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("Midnight Mayhem", 222, Rarity.UNCOMMON, mage.cards.m.MidnightMayhem.class)); + cards.add(new SetCardInfo("Mirror Room // Fractured Realm", 67, Rarity.MYTHIC, mage.cards.m.MirrorRoomFracturedRealm.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mirror Room // Fractured Realm", 337, Rarity.MYTHIC, mage.cards.m.MirrorRoomFracturedRealm.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Moldering Gym // Weight Room", 190, Rarity.COMMON, mage.cards.m.MolderingGymWeightRoom.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("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); @@ -267,6 +278,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Overlord of the Mistmoors", 370, Rarity.MYTHIC, mage.cards.o.OverlordOfTheMistmoors.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Overlord of the Mistmoors", 387, Rarity.MYTHIC, mage.cards.o.OverlordOfTheMistmoors.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Overlord of the Mistmoors", 397, Rarity.MYTHIC, mage.cards.o.OverlordOfTheMistmoors.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Painter's Studio // Defaced Gallery", 147, Rarity.UNCOMMON, mage.cards.p.PaintersStudioDefacedGallery.class)); cards.add(new SetCardInfo("Paranormal Analyst", 69, Rarity.UNCOMMON, mage.cards.p.ParanormalAnalyst.class)); cards.add(new SetCardInfo("Patched Plaything", 24, Rarity.UNCOMMON, mage.cards.p.PatchedPlaything.class)); cards.add(new SetCardInfo("Patchwork Beastie", 195, Rarity.UNCOMMON, mage.cards.p.PatchworkBeastie.class)); @@ -283,6 +295,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Pyroclasm", 149, Rarity.UNCOMMON, mage.cards.p.Pyroclasm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Pyroclasm", 413, Rarity.UNCOMMON, mage.cards.p.Pyroclasm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ragged Playmate", 150, Rarity.COMMON, mage.cards.r.RaggedPlaymate.class)); + cards.add(new SetCardInfo("Rampaging Soulrager", 151, Rarity.COMMON, mage.cards.r.RampagingSoulrager.class)); cards.add(new SetCardInfo("Raucous Carnival", 266, Rarity.COMMON, mage.cards.r.RaucousCarnival.class)); cards.add(new SetCardInfo("Razorkin Hordecaller", 152, Rarity.UNCOMMON, mage.cards.r.RazorkinHordecaller.class)); cards.add(new SetCardInfo("Razorkin Needlehead", 153, Rarity.RARE, mage.cards.r.RazorkinNeedlehead.class, NON_FULL_USE_VARIOUS)); @@ -291,11 +304,15 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Reluctant Role Model", 26, Rarity.RARE, mage.cards.r.ReluctantRoleModel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reluctant Role Model", 289, Rarity.RARE, mage.cards.r.ReluctantRoleModel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reluctant Role Model", 303, Rarity.RARE, mage.cards.r.ReluctantRoleModel.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Restricted Office // Lecture Hall", 342, Rarity.RARE, mage.cards.r.RestrictedOfficeLectureHall.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Restricted Office // Lecture Hall", 227, Rarity.RARE, mage.cards.r.RestrictedOfficeLectureHall.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Resurrected Cultist", 115, Rarity.COMMON, mage.cards.r.ResurrectedCultist.class)); cards.add(new SetCardInfo("Rip, Spawn Hunter", 228, Rarity.RARE, mage.cards.r.RipSpawnHunter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rip, Spawn Hunter", 362, Rarity.RARE, mage.cards.r.RipSpawnHunter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ripchain Razorkin", 154, Rarity.COMMON, mage.cards.r.RipchainRazorkin.class)); cards.add(new SetCardInfo("Rite of the Moth", 229, Rarity.UNCOMMON, mage.cards.r.RiteOfTheMoth.class)); + cards.add(new SetCardInfo("Roaring Furnace // Steaming Sauna", 343, Rarity.RARE, mage.cards.r.RoaringFurnaceSteamingSauna.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Roaring Furnace // Steaming Sauna", 230, Rarity.RARE, mage.cards.r.RoaringFurnaceSteamingSauna.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rootwise Survivor", 196, Rarity.UNCOMMON, mage.cards.r.RootwiseSurvivor.class)); cards.add(new SetCardInfo("Savior of the Small", 27, Rarity.UNCOMMON, mage.cards.s.SaviorOfTheSmall.class)); cards.add(new SetCardInfo("Saw", 254, Rarity.UNCOMMON, mage.cards.s.Saw.class)); @@ -347,6 +364,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Thornspire Verge", 270, Rarity.RARE, mage.cards.t.ThornspireVerge.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thornspire Verge", 333, Rarity.RARE, mage.cards.t.ThornspireVerge.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Threats Around Every Corner", 200, Rarity.UNCOMMON, mage.cards.t.ThreatsAroundEveryCorner.class)); + cards.add(new SetCardInfo("Ticket Booth // Tunnel of Hate", 158, Rarity.COMMON, mage.cards.t.TicketBoothTunnelOfHate.class)); cards.add(new SetCardInfo("Toby, Beastie Befriender", 35, Rarity.RARE, mage.cards.t.TobyBeastieBefriender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Toby, Beastie Befriender", 356, Rarity.RARE, mage.cards.t.TobyBeastieBefriender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Trapped in the Screen", 36, Rarity.COMMON, mage.cards.t.TrappedInTheScreen.class)); @@ -365,6 +383,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Undead Sprinter", 350, Rarity.RARE, mage.cards.u.UndeadSprinter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Under the Skin", 203, Rarity.UNCOMMON, mage.cards.u.UnderTheSkin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Under the Skin", 323, Rarity.UNCOMMON, mage.cards.u.UnderTheSkin.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Underwater Tunnel // Slimy Aquarium", 79, Rarity.COMMON, mage.cards.u.UnderwaterTunnelSlimyAquarium.class)); cards.add(new SetCardInfo("Unholy Annex // Ritual Chamber", 118, Rarity.RARE, mage.cards.u.UnholyAnnexRitualChamber.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Unholy Annex // Ritual Chamber", 339, Rarity.RARE, mage.cards.u.UnholyAnnexRitualChamber.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Unidentified Hovership", 305, Rarity.RARE, mage.cards.u.UnidentifiedHovership.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java index 353c7fc6d8a..691e9746422 100644 --- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java +++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java @@ -23,13 +23,14 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Aesi, Tyrant of Gyre Strait", 210, Rarity.MYTHIC, mage.cards.a.AesiTyrantOfGyreStrait.class)); cards.add(new SetCardInfo("Aether Gale", 109, Rarity.RARE, mage.cards.a.AetherGale.class)); cards.add(new SetCardInfo("Aminatou's Augury", 71, Rarity.RARE, mage.cards.a.AminatousAugury.class)); - cards.add(new SetCardInfo("Ancient Cellarspawn", 16, Rarity.RARE, mage.cards.a.AncientCellarspawn.class)); + cards.add(new SetCardInfo("Ancient Cellarspawn", 16, Rarity.RARE, mage.cards.a.AncientCellarspawn.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ancient Cellarspawn", 47, Rarity.RARE, mage.cards.a.AncientCellarspawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arachnogenesis", 169, Rarity.RARE, mage.cards.a.Arachnogenesis.class)); cards.add(new SetCardInfo("Arcane Denial", 110, Rarity.COMMON, mage.cards.a.ArcaneDenial.class)); cards.add(new SetCardInfo("Arcane Sanctum", 259, Rarity.UNCOMMON, mage.cards.a.ArcaneSanctum.class)); cards.add(new SetCardInfo("Arcane Signet", 92, Rarity.COMMON, mage.cards.a.ArcaneSignet.class)); cards.add(new SetCardInfo("Archetype of Imagination", 111, Rarity.UNCOMMON, mage.cards.a.ArchetypeOfImagination.class)); - cards.add(new SetCardInfo("Archon of Cruelty", 371, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class, FULL_ART)); + cards.add(new SetCardInfo("Archon of Cruelty", 371, Rarity.MYTHIC, mage.cards.a.ArchonOfCruelty.class)); cards.add(new SetCardInfo("Arixmethes, Slumbering Isle", 211, Rarity.RARE, mage.cards.a.ArixmethesSlumberingIsle.class)); cards.add(new SetCardInfo("Arvinox, the Mind Flail", 130, Rarity.MYTHIC, mage.cards.a.ArvinoxTheMindFlail.class)); cards.add(new SetCardInfo("Ash Barrens", 260, Rarity.COMMON, mage.cards.a.AshBarrens.class)); @@ -39,7 +40,8 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Auramancer", 97, Rarity.COMMON, mage.cards.a.Auramancer.class)); cards.add(new SetCardInfo("Azorius Chancery", 261, Rarity.UNCOMMON, mage.cards.a.AzoriusChancery.class)); cards.add(new SetCardInfo("Azorius Signet", 240, Rarity.UNCOMMON, mage.cards.a.AzoriusSignet.class)); - cards.add(new SetCardInfo("Barbflare Gremlin", 26, Rarity.RARE, mage.cards.b.BarbflareGremlin.class)); + cards.add(new SetCardInfo("Barbflare Gremlin", 26, Rarity.RARE, mage.cards.b.BarbflareGremlin.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Barbflare Gremlin", 55, Rarity.RARE, mage.cards.b.BarbflareGremlin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Barren Moor", 262, Rarity.UNCOMMON, mage.cards.b.BarrenMoor.class)); cards.add(new SetCardInfo("Basilisk Collar", 241, Rarity.RARE, mage.cards.b.BasiliskCollar.class)); cards.add(new SetCardInfo("Bastion of Remembrance", 131, Rarity.UNCOMMON, mage.cards.b.BastionOfRemembrance.class)); @@ -73,13 +75,15 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Combustible Gearhulk", 163, Rarity.MYTHIC, mage.cards.c.CombustibleGearhulk.class)); cards.add(new SetCardInfo("Command Tower", 96, Rarity.COMMON, mage.cards.c.CommandTower.class)); cards.add(new SetCardInfo("Commander's Sphere", 244, Rarity.COMMON, mage.cards.c.CommandersSphere.class)); - cards.add(new SetCardInfo("Convert to Slime", 37, Rarity.RARE, mage.cards.c.ConvertToSlime.class)); + cards.add(new SetCardInfo("Convert to Slime", 37, Rarity.RARE, mage.cards.c.ConvertToSlime.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Convert to Slime", 64, Rarity.RARE, mage.cards.c.ConvertToSlime.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Counterspell", 114, Rarity.UNCOMMON, mage.cards.c.Counterspell.class)); cards.add(new SetCardInfo("Crawling Sensation", 173, Rarity.UNCOMMON, mage.cards.c.CrawlingSensation.class)); cards.add(new SetCardInfo("Crypt Ghast", 368, Rarity.MYTHIC, mage.cards.c.CryptGhast.class)); cards.add(new SetCardInfo("Culling Ritual", 85, Rarity.RARE, mage.cards.c.CullingRitual.class)); cards.add(new SetCardInfo("Cultivate", 174, Rarity.COMMON, mage.cards.c.Cultivate.class)); - cards.add(new SetCardInfo("Curator Beastie", 30, Rarity.RARE, mage.cards.c.CuratorBeastie.class)); + cards.add(new SetCardInfo("Curator Beastie", 30, Rarity.RARE, mage.cards.c.CuratorBeastie.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Curator Beastie", 58, Rarity.RARE, mage.cards.c.CuratorBeastie.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Damn", 369, Rarity.MYTHIC, mage.cards.d.Damn.class)); cards.add(new SetCardInfo("Darkmoss Bridge", 269, Rarity.COMMON, mage.cards.d.DarkmossBridge.class)); cards.add(new SetCardInfo("Deadbridge Chant", 215, Rarity.MYTHIC, mage.cards.d.DeadbridgeChant.class)); @@ -87,14 +91,18 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Deathmist Raptor", 176, Rarity.MYTHIC, mage.cards.d.DeathmistRaptor.class)); cards.add(new SetCardInfo("Deathreap Ritual", 86, Rarity.UNCOMMON, mage.cards.d.DeathreapRitual.class)); cards.add(new SetCardInfo("Decree of Pain", 136, Rarity.RARE, mage.cards.d.DecreeOfPain.class)); - cards.add(new SetCardInfo("Deluge of Doom", 18, Rarity.RARE, mage.cards.d.DelugeOfDoom.class)); - cards.add(new SetCardInfo("Demolisher Spawn", 31, Rarity.RARE, mage.cards.d.DemolisherSpawn.class)); + cards.add(new SetCardInfo("Deluge of Doom", 18, Rarity.RARE, mage.cards.d.DelugeOfDoom.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Deluge of Doom", 48, Rarity.RARE, mage.cards.d.DelugeOfDoom.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Demolisher Spawn", 31, Rarity.RARE, mage.cards.d.DemolisherSpawn.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Demolisher Spawn", 59, Rarity.RARE, mage.cards.d.DemolisherSpawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Demon of Fate's Design", 137, Rarity.RARE, mage.cards.d.DemonOfFatesDesign.class)); - cards.add(new SetCardInfo("Demonic Covenant", 19, Rarity.RARE, mage.cards.d.DemonicCovenant.class)); + cards.add(new SetCardInfo("Demonic Covenant", 19, Rarity.RARE, mage.cards.d.DemonicCovenant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Demonic Covenant", 49, Rarity.RARE, mage.cards.d.DemonicCovenant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Diabolic Vision", 87, Rarity.UNCOMMON, mage.cards.d.DiabolicVision.class)); cards.add(new SetCardInfo("Dig Through Time", 115, Rarity.RARE, mage.cards.d.DigThroughTime.class)); cards.add(new SetCardInfo("Dimir Aqueduct", 270, Rarity.UNCOMMON, mage.cards.d.DimirAqueduct.class)); - cards.add(new SetCardInfo("Disorienting Choice", 32, Rarity.RARE, mage.cards.d.DisorientingChoice.class)); + cards.add(new SetCardInfo("Disorienting Choice", 32, Rarity.RARE, mage.cards.d.DisorientingChoice.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Disorienting Choice", 60, Rarity.RARE, mage.cards.d.DisorientingChoice.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Doomwake Giant", 138, Rarity.RARE, mage.cards.d.DoomwakeGiant.class)); cards.add(new SetCardInfo("Dragonskull Summit", 271, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dream Eater", 116, Rarity.MYTHIC, mage.cards.d.DreamEater.class)); @@ -106,27 +114,33 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Evolving Wilds", 274, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); cards.add(new SetCardInfo("Exhume", 370, Rarity.MYTHIC, mage.cards.e.Exhume.class)); cards.add(new SetCardInfo("Exotic Orchard", 275, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); + cards.add(new SetCardInfo("Experimental Lab // Staff Room", 33, Rarity.RARE, mage.cards.e.ExperimentalLabStaffRoom.class)); cards.add(new SetCardInfo("Explosive Vegetation", 177, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); cards.add(new SetCardInfo("Extravagant Replication", 117, Rarity.RARE, mage.cards.e.ExtravagantReplication.class)); cards.add(new SetCardInfo("Ezuri's Predation", 178, Rarity.RARE, mage.cards.e.EzurisPredation.class)); cards.add(new SetCardInfo("Falkenrath Noble", 140, Rarity.COMMON, mage.cards.f.FalkenrathNoble.class)); cards.add(new SetCardInfo("Fate Unraveler", 141, Rarity.RARE, mage.cards.f.FateUnraveler.class)); - cards.add(new SetCardInfo("Fear of Sleep Paralysis", 12, Rarity.RARE, mage.cards.f.FearOfSleepParalysis.class)); + cards.add(new SetCardInfo("Fear of Sleep Paralysis", 12, Rarity.RARE, mage.cards.f.FearOfSleepParalysis.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Fear of Sleep Paralysis", 43, Rarity.RARE, mage.cards.f.FearOfSleepParalysis.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Feed the Swarm", 78, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class)); cards.add(new SetCardInfo("Fellwar Stone", 245, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class)); cards.add(new SetCardInfo("Flooded Grove", 276, Rarity.RARE, mage.cards.f.FloodedGrove.class)); cards.add(new SetCardInfo("Florian, Voldaren Scion", 217, Rarity.RARE, mage.cards.f.FlorianVoldarenScion.class)); cards.add(new SetCardInfo("Foreboding Ruins", 277, Rarity.RARE, mage.cards.f.ForebodingRuins.class)); - cards.add(new SetCardInfo("Formless Genesis", 34, Rarity.RARE, mage.cards.f.FormlessGenesis.class)); + cards.add(new SetCardInfo("Formless Genesis", 34, Rarity.RARE, mage.cards.f.FormlessGenesis.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Formless Genesis", 61, Rarity.RARE, mage.cards.f.FormlessGenesis.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Geothermal Bog", 278, Rarity.COMMON, mage.cards.g.GeothermalBog.class)); cards.add(new SetCardInfo("Giant Adephage", 179, Rarity.MYTHIC, mage.cards.g.GiantAdephage.class)); - cards.add(new SetCardInfo("Giggling Skitterspike", 39, Rarity.RARE, mage.cards.g.GigglingSkitterspike.class)); - cards.add(new SetCardInfo("Gleeful Arsonist", 27, Rarity.RARE, mage.cards.g.GleefulArsonist.class)); - cards.add(new SetCardInfo("Glitch Interpreter", 13, Rarity.RARE, mage.cards.g.GlitchInterpreter.class)); + cards.add(new SetCardInfo("Giggling Skitterspike", 39, Rarity.RARE, mage.cards.g.GigglingSkitterspike.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Giggling Skitterspike", 66, Rarity.RARE, mage.cards.g.GigglingSkitterspike.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gleeful Arsonist", 27, Rarity.RARE, mage.cards.g.GleefulArsonist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gleeful Arsonist", 56, Rarity.RARE, mage.cards.g.GleefulArsonist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Glitch Interpreter", 13, Rarity.RARE, mage.cards.g.GlitchInterpreter.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Glitch Interpreter", 44, Rarity.RARE, mage.cards.g.GlitchInterpreter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gnarlwood Dryad", 180, Rarity.UNCOMMON, mage.cards.g.GnarlwoodDryad.class)); cards.add(new SetCardInfo("Golgari Rot Farm", 279, Rarity.UNCOMMON, mage.cards.g.GolgariRotFarm.class)); cards.add(new SetCardInfo("Golgari Signet", 246, Rarity.UNCOMMON, mage.cards.g.GolgariSignet.class)); - cards.add(new SetCardInfo("Goryo's Vengeance", 372, Rarity.MYTHIC, mage.cards.g.GoryosVengeance.class, FULL_ART)); + cards.add(new SetCardInfo("Goryo's Vengeance", 372, Rarity.MYTHIC, mage.cards.g.GoryosVengeance.class)); cards.add(new SetCardInfo("Grapple with the Past", 82, Rarity.COMMON, mage.cards.g.GrappleWithThePast.class)); cards.add(new SetCardInfo("Graven Cairns", 280, Rarity.RARE, mage.cards.g.GravenCairns.class)); cards.add(new SetCardInfo("Gray Merchant of Asphodel", 142, Rarity.UNCOMMON, mage.cards.g.GrayMerchantOfAsphodel.class)); @@ -148,7 +162,8 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Infernal Grasp", 143, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class)); cards.add(new SetCardInfo("Inkshield", 221, Rarity.RARE, mage.cards.i.Inkshield.class)); cards.add(new SetCardInfo("Inscription of Abundance", 186, Rarity.RARE, mage.cards.i.InscriptionOfAbundance.class)); - cards.add(new SetCardInfo("Into the Pit", 20, Rarity.RARE, mage.cards.i.IntoThePit.class)); + cards.add(new SetCardInfo("Into the Pit", 20, Rarity.RARE, mage.cards.i.IntoThePit.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Into the Pit", 50, Rarity.RARE, mage.cards.i.IntoThePit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ishkanah, Grafwidow", 187, Rarity.MYTHIC, mage.cards.i.IshkanahGrafwidow.class)); cards.add(new SetCardInfo("Jungle Hollow", 285, Rarity.COMMON, mage.cards.j.JungleHollow.class)); cards.add(new SetCardInfo("Kaervek the Merciless", 222, Rarity.RARE, mage.cards.k.KaervekTheMerciless.class)); @@ -161,14 +176,15 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Life Insurance", 224, Rarity.RARE, mage.cards.l.LifeInsurance.class)); cards.add(new SetCardInfo("Light Up the Stage", 166, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class)); cards.add(new SetCardInfo("Lightning Greaves", 93, Rarity.UNCOMMON, mage.cards.l.LightningGreaves.class)); - cards.add(new SetCardInfo("Living Death", 373, Rarity.MYTHIC, mage.cards.l.LivingDeath.class, FULL_ART)); + cards.add(new SetCardInfo("Living Death", 373, Rarity.MYTHIC, mage.cards.l.LivingDeath.class)); cards.add(new SetCardInfo("Llanowar Wastes", 287, Rarity.RARE, mage.cards.l.LlanowarWastes.class)); cards.add(new SetCardInfo("Mask of Griselbrand", 145, Rarity.RARE, mage.cards.m.MaskOfGriselbrand.class)); cards.add(new SetCardInfo("Massacre Girl", 146, Rarity.RARE, mage.cards.m.MassacreGirl.class)); cards.add(new SetCardInfo("Massacre Wurm", 147, Rarity.MYTHIC, mage.cards.m.MassacreWurm.class)); cards.add(new SetCardInfo("Mayhem Devil", 225, Rarity.UNCOMMON, mage.cards.m.MayhemDevil.class)); cards.add(new SetCardInfo("Mesa Enchantress", 68, Rarity.RARE, mage.cards.m.MesaEnchantress.class)); - cards.add(new SetCardInfo("Metamorphosis Fanatic", 21, Rarity.RARE, mage.cards.m.MetamorphosisFanatic.class)); + cards.add(new SetCardInfo("Metamorphosis Fanatic", 21, Rarity.RARE, mage.cards.m.MetamorphosisFanatic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Metamorphosis Fanatic", 51, Rarity.RARE, mage.cards.m.MetamorphosisFanatic.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mind Stone", 248, Rarity.UNCOMMON, mage.cards.m.MindStone.class)); cards.add(new SetCardInfo("Mirrormade", 120, Rarity.RARE, mage.cards.m.Mirrormade.class)); cards.add(new SetCardInfo("Mogis, God of Slaughter", 89, Rarity.MYTHIC, mage.cards.m.MogisGodOfSlaughter.class)); @@ -199,8 +215,10 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Overflowing Basin", 293, Rarity.RARE, mage.cards.o.OverflowingBasin.class)); cards.add(new SetCardInfo("Oversimplify", 228, Rarity.RARE, mage.cards.o.Oversimplify.class)); cards.add(new SetCardInfo("Overwhelming Stampede", 192, Rarity.RARE, mage.cards.o.OverwhelmingStampede.class)); - cards.add(new SetCardInfo("Persistent Constrictor", 22, Rarity.RARE, mage.cards.p.PersistentConstrictor.class)); - cards.add(new SetCardInfo("Phenomenon Investigators", 38, Rarity.RARE, mage.cards.p.PhenomenonInvestigators.class)); + cards.add(new SetCardInfo("Persistent Constrictor", 22, Rarity.RARE, mage.cards.p.PersistentConstrictor.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Persistent Constrictor", 52, Rarity.RARE, mage.cards.p.PersistentConstrictor.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Phenomenon Investigators", 38, Rarity.RARE, mage.cards.p.PhenomenonInvestigators.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Phenomenon Investigators", 65, Rarity.RARE, mage.cards.p.PhenomenonInvestigators.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ponder", 73, Rarity.COMMON, mage.cards.p.Ponder.class)); cards.add(new SetCardInfo("Portent", 74, Rarity.COMMON, mage.cards.p.Portent.class)); cards.add(new SetCardInfo("Primordial Mist", 123, Rarity.RARE, mage.cards.p.PrimordialMist.class)); @@ -217,23 +235,27 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Read the Bones", 154, Rarity.COMMON, mage.cards.r.ReadTheBones.class)); cards.add(new SetCardInfo("Reality Shift", 125, Rarity.UNCOMMON, mage.cards.r.RealityShift.class)); cards.add(new SetCardInfo("Reanimate", 155, Rarity.RARE, mage.cards.r.Reanimate.class)); - cards.add(new SetCardInfo("Redress Fate", 9, Rarity.RARE, mage.cards.r.RedressFate.class)); + cards.add(new SetCardInfo("Redress Fate", 41, Rarity.RARE, mage.cards.r.RedressFate.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Redress Fate", 9, Rarity.RARE, mage.cards.r.RedressFate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reliquary Tower", 295, Rarity.UNCOMMON, mage.cards.r.ReliquaryTower.class)); cards.add(new SetCardInfo("Rendmaw, Creaking Nest", 5, Rarity.MYTHIC, mage.cards.r.RendmawCreakingNest.class)); cards.add(new SetCardInfo("Retreat to Coralhelm", 126, Rarity.UNCOMMON, mage.cards.r.RetreatToCoralhelm.class)); cards.add(new SetCardInfo("Return to Dust", 102, Rarity.UNCOMMON, mage.cards.r.ReturnToDust.class)); - cards.add(new SetCardInfo("Sadistic Shell Game", 24, Rarity.RARE, mage.cards.s.SadisticShellGame.class)); + cards.add(new SetCardInfo("Sadistic Shell Game", 24, Rarity.RARE, mage.cards.s.SadisticShellGame.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sadistic Shell Game", 53, Rarity.RARE, mage.cards.s.SadisticShellGame.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sakura-Tribe Elder", 194, Rarity.COMMON, mage.cards.s.SakuraTribeElder.class)); cards.add(new SetCardInfo("Sandwurm Convergence", 195, Rarity.RARE, mage.cards.s.SandwurmConvergence.class)); cards.add(new SetCardInfo("Scavenging Ooze", 196, Rarity.RARE, mage.cards.s.ScavengingOoze.class)); cards.add(new SetCardInfo("Scroll of Fate", 251, Rarity.RARE, mage.cards.s.ScrollOfFate.class)); cards.add(new SetCardInfo("Scute Swarm", 197, Rarity.RARE, mage.cards.s.ScuteSwarm.class)); - cards.add(new SetCardInfo("Seance Board", 40, Rarity.RARE, mage.cards.s.SeanceBoard.class)); + cards.add(new SetCardInfo("Seance Board", 40, Rarity.RARE, mage.cards.s.SeanceBoard.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Seance Board", 67, Rarity.RARE, mage.cards.s.SeanceBoard.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Shadowblood Ridge", 296, Rarity.RARE, mage.cards.s.ShadowbloodRidge.class)); cards.add(new SetCardInfo("Shark Typhoon", 127, Rarity.RARE, mage.cards.s.SharkTyphoon.class)); cards.add(new SetCardInfo("Shigeki, Jukai Visionary", 198, Rarity.RARE, mage.cards.s.ShigekiJukaiVisionary.class)); cards.add(new SetCardInfo("Shivan Gorge", 297, Rarity.RARE, mage.cards.s.ShivanGorge.class)); - cards.add(new SetCardInfo("Shriekwood Devourer", 35, Rarity.RARE, mage.cards.s.ShriekwoodDevourer.class)); + cards.add(new SetCardInfo("Shriekwood Devourer", 35, Rarity.RARE, mage.cards.s.ShriekwoodDevourer.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Shriekwood Devourer", 62, Rarity.RARE, mage.cards.s.ShriekwoodDevourer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sigil of the Empty Throne", 103, Rarity.RARE, mage.cards.s.SigilOfTheEmptyThrone.class)); cards.add(new SetCardInfo("Sign in Blood", 156, Rarity.COMMON, mage.cards.s.SignInBlood.class)); cards.add(new SetCardInfo("Simic Growth Chamber", 298, Rarity.UNCOMMON, mage.cards.s.SimicGrowthChamber.class)); @@ -241,19 +263,23 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("Skaab Ruinator", 128, Rarity.MYTHIC, mage.cards.s.SkaabRuinator.class)); cards.add(new SetCardInfo("Skola Grovedancer", 199, Rarity.COMMON, mage.cards.s.SkolaGrovedancer.class)); cards.add(new SetCardInfo("Smoldering Marsh", 299, Rarity.RARE, mage.cards.s.SmolderingMarsh.class)); - cards.add(new SetCardInfo("Soaring Lightbringer", 11, Rarity.RARE, mage.cards.s.SoaringLightbringer.class)); + cards.add(new SetCardInfo("Soaring Lightbringer", 11, Rarity.RARE, mage.cards.s.SoaringLightbringer.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Soaring Lightbringer", 42, Rarity.RARE, mage.cards.s.SoaringLightbringer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sol Ring", 94, Rarity.UNCOMMON, mage.cards.s.SolRing.class)); cards.add(new SetCardInfo("Solemn Simulacrum", 253, Rarity.RARE, mage.cards.s.SolemnSimulacrum.class)); cards.add(new SetCardInfo("Sphere of Safety", 104, Rarity.UNCOMMON, mage.cards.s.SphereOfSafety.class)); + cards.add(new SetCardInfo("Spiked Corridor // Torture Pit", 28, Rarity.RARE, mage.cards.s.SpikedCorridorTorturePit.class)); cards.add(new SetCardInfo("Spinerock Knoll", 300, Rarity.RARE, mage.cards.s.SpinerockKnoll.class)); cards.add(new SetCardInfo("Spirit-Sister's Call", 232, Rarity.MYTHIC, mage.cards.s.SpiritSistersCall.class)); cards.add(new SetCardInfo("Spiteful Visions", 233, Rarity.RARE, mage.cards.s.SpitefulVisions.class)); - cards.add(new SetCardInfo("Star Athlete", 29, Rarity.RARE, mage.cards.s.StarAthlete.class)); + cards.add(new SetCardInfo("Star Athlete", 29, Rarity.RARE, mage.cards.s.StarAthlete.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Star Athlete", 57, Rarity.RARE, mage.cards.s.StarAthlete.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Starfield Mystic", 105, Rarity.RARE, mage.cards.s.StarfieldMystic.class)); cards.add(new SetCardInfo("Stitcher's Supplier", 157, Rarity.UNCOMMON, mage.cards.s.StitchersSupplier.class)); cards.add(new SetCardInfo("Stormfist Crusader", 234, Rarity.RARE, mage.cards.s.StormfistCrusader.class)); cards.add(new SetCardInfo("Sulfurous Springs", 301, Rarity.RARE, mage.cards.s.SulfurousSprings.class)); - cards.add(new SetCardInfo("Suspended Sentence", 25, Rarity.RARE, mage.cards.s.SuspendedSentence.class)); + cards.add(new SetCardInfo("Suspended Sentence", 25, Rarity.RARE, mage.cards.s.SuspendedSentence.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Suspended Sentence", 54, Rarity.RARE, mage.cards.s.SuspendedSentence.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Suspicious Bookcase", 95, Rarity.UNCOMMON, mage.cards.s.SuspiciousBookcase.class)); cards.add(new SetCardInfo("Swords to Plowshares", 106, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); cards.add(new SetCardInfo("Syr Konrad, the Grim", 158, Rarity.UNCOMMON, mage.cards.s.SyrKonradTheGrim.class)); @@ -280,7 +306,8 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { cards.add(new SetCardInfo("The Lord of Pain", 3, Rarity.MYTHIC, mage.cards.t.TheLordOfPain.class)); cards.add(new SetCardInfo("The Master of Keys", 4, Rarity.MYTHIC, mage.cards.t.TheMasterOfKeys.class)); cards.add(new SetCardInfo("Theater of Horrors", 236, Rarity.RARE, mage.cards.t.TheaterOfHorrors.class)); - cards.add(new SetCardInfo("They Came from the Pipes", 14, Rarity.RARE, mage.cards.t.TheyCameFromThePipes.class)); + cards.add(new SetCardInfo("They Came from the Pipes", 14, Rarity.RARE, mage.cards.t.TheyCameFromThePipes.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("They Came from the Pipes", 45, Rarity.RARE, mage.cards.t.TheyCameFromThePipes.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thirst for Meaning", 129, Rarity.COMMON, mage.cards.t.ThirstForMeaning.class)); cards.add(new SetCardInfo("Thornwood Falls", 314, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class)); cards.add(new SetCardInfo("Thought Vessel", 256, Rarity.COMMON, mage.cards.t.ThoughtVessel.class)); diff --git a/Mage.Sets/src/mage/sets/EldritchMoon.java b/Mage.Sets/src/mage/sets/EldritchMoon.java index 7606ba3e3b6..76aa983a42f 100644 --- a/Mage.Sets/src/mage/sets/EldritchMoon.java +++ b/Mage.Sets/src/mage/sets/EldritchMoon.java @@ -42,7 +42,6 @@ public final class EldritchMoon extends ExpansionSet { this.numBoosterDoubleFaced = 1; cards.add(new SetCardInfo("Abandon Reason", 115, Rarity.UNCOMMON, mage.cards.a.AbandonReason.class)); - cards.add(new SetCardInfo("Abolisher of Bloodlines", 111, Rarity.RARE, mage.cards.a.AbolisherOfBloodlines.class)); cards.add(new SetCardInfo("Abundant Maw", 1, Rarity.UNCOMMON, mage.cards.a.AbundantMaw.class)); cards.add(new SetCardInfo("Advanced Stitchwing", 49, Rarity.UNCOMMON, mage.cards.a.AdvancedStitchwing.class)); cards.add(new SetCardInfo("Alchemist's Greeting", 116, Rarity.COMMON, mage.cards.a.AlchemistsGreeting.class)); @@ -95,7 +94,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Docent of Perfection", 56, Rarity.RARE, mage.cards.d.DocentOfPerfection.class)); cards.add(new SetCardInfo("Drag Under", 57, Rarity.COMMON, mage.cards.d.DragUnder.class)); cards.add(new SetCardInfo("Drogskol Shieldmate", 22, Rarity.UNCOMMON, mage.cards.d.DrogskolShieldmate.class)); - cards.add(new SetCardInfo("Dronepack Kindred", 148, Rarity.COMMON, mage.cards.d.DronepackKindred.class)); cards.add(new SetCardInfo("Drownyard Behemoth", 4, Rarity.UNCOMMON, mage.cards.d.DrownyardBehemoth.class)); cards.add(new SetCardInfo("Dusk Feaster", 88, Rarity.UNCOMMON, mage.cards.d.DuskFeaster.class)); cards.add(new SetCardInfo("Elder Deep-Fiend", 5, Rarity.RARE, mage.cards.e.ElderDeepFiend.class)); @@ -104,17 +102,14 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Emrakul's Influence", 157, Rarity.UNCOMMON, mage.cards.e.EmrakulsInfluence.class)); cards.add(new SetCardInfo("Emrakul, the Promised End", 6, Rarity.MYTHIC, mage.cards.e.EmrakulThePromisedEnd.class)); cards.add(new SetCardInfo("Enlightened Maniac", 58, Rarity.COMMON, mage.cards.e.EnlightenedManiac.class)); - cards.add(new SetCardInfo("Erupting Dreadwolf", 142, Rarity.UNCOMMON, mage.cards.e.EruptingDreadwolf.class)); cards.add(new SetCardInfo("Eternal Scourge", 7, Rarity.RARE, mage.cards.e.EternalScourge.class)); cards.add(new SetCardInfo("Extricator of Sin", 23, Rarity.UNCOMMON, mage.cards.e.ExtricatorOfSin.class)); cards.add(new SetCardInfo("Exultant Cultist", 59, Rarity.COMMON, mage.cards.e.ExultantCultist.class)); cards.add(new SetCardInfo("Faith Unbroken", 24, Rarity.UNCOMMON, mage.cards.f.FaithUnbroken.class)); cards.add(new SetCardInfo("Faithbearer Paladin", 25, Rarity.COMMON, mage.cards.f.FaithbearerPaladin.class)); cards.add(new SetCardInfo("Falkenrath Reaver", 127, Rarity.COMMON, mage.cards.f.FalkenrathReaver.class)); - cards.add(new SetCardInfo("Fibrous Entangler", 174, Rarity.UNCOMMON, mage.cards.f.FibrousEntangler.class)); cards.add(new SetCardInfo("Field Creeper", 195, Rarity.COMMON, mage.cards.f.FieldCreeper.class)); cards.add(new SetCardInfo("Fiend Binder", 26, Rarity.COMMON, mage.cards.f.FiendBinder.class)); - cards.add(new SetCardInfo("Final Iteration", 56, Rarity.RARE, mage.cards.f.FinalIteration.class)); cards.add(new SetCardInfo("Fogwalker", 60, Rarity.COMMON, mage.cards.f.Fogwalker.class)); cards.add(new SetCardInfo("Fortune's Favor", 61, Rarity.UNCOMMON, mage.cards.f.FortunesFavor.class)); cards.add(new SetCardInfo("Foul Emissary", 158, Rarity.UNCOMMON, mage.cards.f.FoulEmissary.class)); @@ -142,7 +137,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Harmless Offering", 131, Rarity.RARE, mage.cards.h.HarmlessOffering.class)); cards.add(new SetCardInfo("Haunted Dead", 92, Rarity.UNCOMMON, mage.cards.h.HauntedDead.class)); cards.add(new SetCardInfo("Heron's Grace Champion", 185, Rarity.RARE, mage.cards.h.HeronsGraceChampion.class)); - cards.add(new SetCardInfo("Howling Chorus", 168, Rarity.UNCOMMON, mage.cards.h.HowlingChorus.class)); cards.add(new SetCardInfo("Identity Thief", 64, Rarity.RARE, mage.cards.i.IdentityThief.class)); cards.add(new SetCardInfo("Impetuous Devils", 132, Rarity.RARE, mage.cards.i.ImpetuousDevils.class)); cards.add(new SetCardInfo("Imprisoned in the Moon", 65, Rarity.RARE, mage.cards.i.ImprisonedInTheMoon.class)); @@ -238,8 +232,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Tree of Perdition", 109, Rarity.MYTHIC, mage.cards.t.TreeOfPerdition.class)); cards.add(new SetCardInfo("Turn Aside", 78, Rarity.COMMON, mage.cards.t.TurnAside.class)); cards.add(new SetCardInfo("Ulrich of the Krallenhorde", 191, Rarity.MYTHIC, mage.cards.u.UlrichOfTheKrallenhorde.class)); - cards.add(new SetCardInfo("Ulrich, Uncontested Alpha", 191, Rarity.MYTHIC, mage.cards.u.UlrichUncontestedAlpha.class)); - cards.add(new SetCardInfo("Ulvenwald Abomination", 175, Rarity.COMMON, mage.cards.u.UlvenwaldAbomination.class)); cards.add(new SetCardInfo("Ulvenwald Captive", 175, Rarity.COMMON, mage.cards.u.UlvenwaldCaptive.class)); cards.add(new SetCardInfo("Ulvenwald Observer", 176, Rarity.RARE, mage.cards.u.UlvenwaldObserver.class)); cards.add(new SetCardInfo("Unsubstantiate", 79, Rarity.UNCOMMON, mage.cards.u.Unsubstantiate.class)); diff --git a/Mage.Sets/src/mage/sets/EldritchMoonPromos.java b/Mage.Sets/src/mage/sets/EldritchMoonPromos.java index 8083a9daf47..32cae370100 100644 --- a/Mage.Sets/src/mage/sets/EldritchMoonPromos.java +++ b/Mage.Sets/src/mage/sets/EldritchMoonPromos.java @@ -20,7 +20,6 @@ public class EldritchMoonPromos extends ExpansionSet { this.hasBoosters = false; this.hasBasicLands = false; - cards.add(new SetCardInfo("Abolisher of Bloodlines", "111s", Rarity.RARE, mage.cards.a.AbolisherOfBloodlines.class)); cards.add(new SetCardInfo("Assembled Alphas", 117, Rarity.RARE, mage.cards.a.AssembledAlphas.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Assembled Alphas", "117s", Rarity.RARE, mage.cards.a.AssembledAlphas.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bedlam Reveler", "118s", Rarity.RARE, mage.cards.b.BedlamReveler.class)); @@ -42,7 +41,6 @@ public class EldritchMoonPromos extends ExpansionSet { cards.add(new SetCardInfo("Emrakul's Evangel", "156s", Rarity.RARE, mage.cards.e.EmrakulsEvangel.class)); cards.add(new SetCardInfo("Emrakul, the Promised End", "6s", Rarity.MYTHIC, mage.cards.e.EmrakulThePromisedEnd.class)); cards.add(new SetCardInfo("Eternal Scourge", "7s", Rarity.RARE, mage.cards.e.EternalScourge.class)); - cards.add(new SetCardInfo("Final Iteration", "56s", Rarity.RARE, mage.cards.f.FinalIteration.class)); cards.add(new SetCardInfo("Geier Reach Sanitarium", "203s", Rarity.RARE, mage.cards.g.GeierReachSanitarium.class)); cards.add(new SetCardInfo("Gisa and Geralf", "183s", Rarity.MYTHIC, mage.cards.g.GisaAndGeralf.class)); cards.add(new SetCardInfo("Gisela, the Broken Blade", "28s", Rarity.MYTHIC, mage.cards.g.GiselaTheBrokenBlade.class)); @@ -88,7 +86,6 @@ public class EldritchMoonPromos extends ExpansionSet { cards.add(new SetCardInfo("Thalia, Heretic Cathar", 46, Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thalia, Heretic Cathar", "46s", Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tree of Perdition", "109s", Rarity.MYTHIC, mage.cards.t.TreeOfPerdition.class)); - cards.add(new SetCardInfo("Ulrich, Uncontested Alpha", "191s", Rarity.MYTHIC, mage.cards.u.UlrichUncontestedAlpha.class)); cards.add(new SetCardInfo("Ulrich of the Krallenhorde", "191s", Rarity.MYTHIC, mage.cards.u.UlrichOfTheKrallenhorde.class)); cards.add(new SetCardInfo("Ulvenwald Observer", 176, Rarity.RARE, mage.cards.u.UlvenwaldObserver.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ulvenwald Observer", "176s", Rarity.RARE, mage.cards.u.UlvenwaldObserver.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/FinalFantasy.java b/Mage.Sets/src/mage/sets/FinalFantasy.java index 5358be44209..08f1ff1161e 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -74,7 +74,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Battle Menu", 9, Rarity.UNCOMMON, mage.cards.b.BattleMenu.class)); cards.add(new SetCardInfo("Beatrix, Loyal General", 426, Rarity.RARE, mage.cards.b.BeatrixLoyalGeneral.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Beatrix, Loyal General", 554, Rarity.RARE, mage.cards.b.BeatrixLoyalGeneral.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Black Chocobo", 201, Rarity.UNCOMMON, mage.cards.b.BlackChocobo.class)); cards.add(new SetCardInfo("Black Mage's Rod", 90, Rarity.COMMON, mage.cards.b.BlackMagesRod.class)); cards.add(new SetCardInfo("Black Waltz No. 3", 214, Rarity.UNCOMMON, mage.cards.b.BlackWaltzNo3.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Black Waltz No. 3", 478, Rarity.UNCOMMON, mage.cards.b.BlackWaltzNo3.class, NON_FULL_USE_VARIOUS)); @@ -137,14 +136,11 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Coliseum Behemoth", 181, Rarity.UNCOMMON, mage.cards.c.ColiseumBehemoth.class)); cards.add(new SetCardInfo("Combat Tutorial", 48, Rarity.COMMON, mage.cards.c.CombatTutorial.class)); cards.add(new SetCardInfo("Commune with Beavers", 182, Rarity.COMMON, mage.cards.c.CommuneWithBeavers.class)); - cards.add(new SetCardInfo("Cooking Campsite", 31, Rarity.UNCOMMON, mage.cards.c.CookingCampsite.class)); cards.add(new SetCardInfo("Coral Sword", 134, Rarity.UNCOMMON, mage.cards.c.CoralSword.class)); cards.add(new SetCardInfo("Cornered by Black Mages", 93, Rarity.COMMON, mage.cards.c.CorneredByBlackMages.class)); cards.add(new SetCardInfo("Crossroads Village", 276, Rarity.COMMON, mage.cards.c.CrossroadsVillage.class)); cards.add(new SetCardInfo("Crystal Fragments", 13, Rarity.UNCOMMON, mage.cards.c.CrystalFragments.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Crystal Fragments", 357, Rarity.UNCOMMON, mage.cards.c.CrystalFragments.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Crystallized Serah", 240, Rarity.RARE, mage.cards.c.CrystallizedSerah.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Crystallized Serah", 506, Rarity.RARE, mage.cards.c.CrystallizedSerah.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dark Confidant", 334, Rarity.MYTHIC, mage.cards.d.DarkConfidant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dark Confidant", 94, Rarity.MYTHIC, mage.cards.d.DarkConfidant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dark Knight's Greatsword", 95, Rarity.UNCOMMON, mage.cards.d.DarkKnightsGreatsword.class)); @@ -173,9 +169,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Emet-Selch, Unsundered", 539, Rarity.MYTHIC, mage.cards.e.EmetSelchUnsundered.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Esper Origins", 185, Rarity.RARE, mage.cards.e.EsperOrigins.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Esper Origins", 370, Rarity.RARE, mage.cards.e.EsperOrigins.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Esper Terra", 245, Rarity.MYTHIC, mage.cards.e.EsperTerra.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Esper Terra", 323, Rarity.MYTHIC, mage.cards.e.EsperTerra.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Esper Terra", 511, Rarity.MYTHIC, mage.cards.e.EsperTerra.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ether", 53, Rarity.UNCOMMON, mage.cards.e.Ether.class)); cards.add(new SetCardInfo("Evil Reawakened", 98, Rarity.UNCOMMON, mage.cards.e.EvilReawakened.class)); cards.add(new SetCardInfo("Excalibur II", 257, Rarity.RARE, mage.cards.e.ExcaliburII.class, NON_FULL_USE_VARIOUS)); @@ -205,10 +198,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Gaelicat", 22, Rarity.COMMON, mage.cards.g.Gaelicat.class)); cards.add(new SetCardInfo("Gaius van Baelsar", 102, Rarity.UNCOMMON, mage.cards.g.GaiusVanBaelsar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gaius van Baelsar", 447, Rarity.UNCOMMON, mage.cards.g.GaiusVanBaelsar.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Galian Beast", 125, Rarity.RARE, mage.cards.g.GalianBeast.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Galian Beast", 383, Rarity.RARE, mage.cards.g.GalianBeast.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Galian Beast", 454, Rarity.RARE, mage.cards.g.GalianBeast.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Galian Beast", 528, Rarity.RARE, mage.cards.g.GalianBeast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Galuf's Final Act", 186, Rarity.UNCOMMON, mage.cards.g.GalufsFinalAct.class)); cards.add(new SetCardInfo("Garland, Knight of Cornelia", 221, Rarity.UNCOMMON, mage.cards.g.GarlandKnightOfCornelia.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Garland, Knight of Cornelia", 486, Rarity.UNCOMMON, mage.cards.g.GarlandKnightOfCornelia.class, NON_FULL_USE_VARIOUS)); @@ -244,9 +233,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Hope Estheim", 396, Rarity.RARE, mage.cards.h.HopeEstheim.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hope Estheim", 491, Rarity.RARE, mage.cards.h.HopeEstheim.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hope Estheim", 541, Rarity.RARE, mage.cards.h.HopeEstheim.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hydaelyn, the Mothercrystal", 329, Rarity.RARE, mage.cards.h.HydaelynTheMothercrystal.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hydaelyn, the Mothercrystal", 39, Rarity.RARE, mage.cards.h.HydaelynTheMothercrystal.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hydaelyn, the Mothercrystal", 434, Rarity.RARE, mage.cards.h.HydaelynTheMothercrystal.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ice Flan", 55, Rarity.COMMON, mage.cards.i.IceFlan.class)); cards.add(new SetCardInfo("Ice Magic", 56, Rarity.COMMON, mage.cards.i.IceMagic.class)); cards.add(new SetCardInfo("Ignis Scientia", 227, Rarity.UNCOMMON, mage.cards.i.IgnisScientia.class, NON_FULL_USE_VARIOUS)); @@ -316,7 +302,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Machinist's Arsenal", 23, Rarity.RARE, mage.cards.m.MachinistsArsenal.class)); cards.add(new SetCardInfo("Magic Damper", 61, Rarity.COMMON, mage.cards.m.MagicDamper.class)); cards.add(new SetCardInfo("Magic Pot", 263, Rarity.COMMON, mage.cards.m.MagicPot.class)); - cards.add(new SetCardInfo("Magicked Card", 73, Rarity.UNCOMMON, mage.cards.m.MagickedCard.class)); cards.add(new SetCardInfo("Magitek Armor", 24, Rarity.UNCOMMON, mage.cards.m.MagitekArmor.class)); cards.add(new SetCardInfo("Magitek Infantry", 25, Rarity.COMMON, mage.cards.m.MagitekInfantry.class)); cards.add(new SetCardInfo("Magitek Scythe", 562, Rarity.RARE, mage.cards.m.MagitekScythe.class)); @@ -425,11 +410,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Sephiroth, Fabled SOLDIER", 382, Rarity.MYTHIC, mage.cards.s.SephirothFabledSOLDIER.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sephiroth, Fabled SOLDIER", 451, Rarity.MYTHIC, mage.cards.s.SephirothFabledSOLDIER.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sephiroth, Fabled SOLDIER", 527, Rarity.MYTHIC, mage.cards.s.SephirothFabledSOLDIER.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sephiroth, One-Winged Angel", 115, Rarity.MYTHIC, mage.cards.s.SephirothOneWingedAngel.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sephiroth, One-Winged Angel", 317, Rarity.MYTHIC, mage.cards.s.SephirothOneWingedAngel.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sephiroth, One-Winged Angel", 382, Rarity.MYTHIC, mage.cards.s.SephirothOneWingedAngel.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sephiroth, One-Winged Angel", 451, Rarity.MYTHIC, mage.cards.s.SephirothOneWingedAngel.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sephiroth, One-Winged Angel", 527, Rarity.MYTHIC, mage.cards.s.SephirothOneWingedAngel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sephiroth, Planet's Heir", 505, Rarity.MYTHIC, mage.cards.s.SephirothPlanetsHeir.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sephiroth, Planet's Heir", 553, Rarity.MYTHIC, mage.cards.s.SephirothPlanetsHeir.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Serah Farron", 240, Rarity.RARE, mage.cards.s.SerahFarron.class, NON_FULL_USE_VARIOUS)); @@ -441,10 +421,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Shantotto, Tactician Magician", 507, Rarity.UNCOMMON, mage.cards.s.ShantottoTacticianMagician.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sharlayan, Nation of Scholars", 288, Rarity.COMMON, mage.cards.s.SharlayanNationOfScholars.class)); cards.add(new SetCardInfo("Shinra Reinforcements", 118, Rarity.COMMON, mage.cards.s.ShinraReinforcements.class)); - cards.add(new SetCardInfo("Shinryu, Transcendent Rival", 127, Rarity.RARE, mage.cards.s.ShinryuTranscendentRival.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shinryu, Transcendent Rival", 384, Rarity.RARE, mage.cards.s.ShinryuTranscendentRival.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shinryu, Transcendent Rival", 455, Rarity.RARE, mage.cards.s.ShinryuTranscendentRival.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shinryu, Transcendent Rival", 529, Rarity.RARE, mage.cards.s.ShinryuTranscendentRival.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sidequest: Card Collection", 73, Rarity.UNCOMMON, mage.cards.s.SidequestCardCollection.class)); cards.add(new SetCardInfo("Sidequest: Catch a Fish", 31, Rarity.UNCOMMON, mage.cards.s.SidequestCatchAFish.class)); cards.add(new SetCardInfo("Sidequest: Hunt the Mark", 119, Rarity.UNCOMMON, mage.cards.s.SidequestHuntTheMark.class, NON_FULL_USE_VARIOUS)); @@ -526,8 +502,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("The Fire Crystal", 135, Rarity.RARE, mage.cards.t.TheFireCrystal.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Fire Crystal", 337, Rarity.RARE, mage.cards.t.TheFireCrystal.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Gold Saucer", 279, Rarity.UNCOMMON, mage.cards.t.TheGoldSaucer.class)); - cards.add(new SetCardInfo("The Lord Master of Hell", 219, Rarity.UNCOMMON, mage.cards.t.TheLordMasterOfHell.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Lord Master of Hell", 484, Rarity.UNCOMMON, mage.cards.t.TheLordMasterOfHell.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Lunar Whale", 60, Rarity.RARE, mage.cards.t.TheLunarWhale.class)); cards.add(new SetCardInfo("The Masamune", 264, Rarity.RARE, mage.cards.t.TheMasamune.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Masamune", 353, Rarity.RARE, mage.cards.t.TheMasamune.class, NON_FULL_USE_VARIOUS)); @@ -575,8 +549,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Ultima, Origin of Oblivion", 2, Rarity.RARE, mage.cards.u.UltimaOriginOfOblivion.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ultima, Origin of Oblivion", 324, Rarity.RARE, mage.cards.u.UltimaOriginOfOblivion.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ultima, Origin of Oblivion", 421, Rarity.RARE, mage.cards.u.UltimaOriginOfOblivion.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ultimecia, Omnipotent", 247, Rarity.UNCOMMON, mage.cards.u.UltimeciaOmnipotent.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ultimecia, Omnipotent", 513, Rarity.UNCOMMON, mage.cards.u.UltimeciaOmnipotent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ultimecia, Temporal Threat", 441, Rarity.RARE, mage.cards.u.UltimeciaTemporalThreat.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ultimecia, Temporal Threat", 556, Rarity.RARE, mage.cards.u.UltimeciaTemporalThreat.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ultimecia, Time Sorceress", 247, Rarity.UNCOMMON, mage.cards.u.UltimeciaTimeSorceress.class, NON_FULL_USE_VARIOUS)); @@ -615,15 +587,12 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("White Auracite", 579, Rarity.COMMON, mage.cards.w.WhiteAuracite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("White Mage's Staff", 42, Rarity.COMMON, mage.cards.w.WhiteMagesStaff.class)); cards.add(new SetCardInfo("Windurst, Federation Center", 292, Rarity.COMMON, mage.cards.w.WindurstFederationCenter.class)); - cards.add(new SetCardInfo("World Champion, Celestial Weapon", 158, Rarity.UNCOMMON, mage.cards.w.WorldChampionCelestialWeapon.class)); cards.add(new SetCardInfo("World Map", 270, Rarity.COMMON, mage.cards.w.WorldMap.class)); cards.add(new SetCardInfo("Xande, Dark Mage", 516, Rarity.RARE, mage.cards.x.XandeDarkMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Xande, Dark Mage", 561, Rarity.RARE, mage.cards.x.XandeDarkMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Y'shtola Rhul", 443, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Y'shtola Rhul", 577, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Y'shtola Rhul", 86, Rarity.MYTHIC, mage.cards.y.YshtolaRhul.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Yiazmat, Ultimate Mark", 119, Rarity.UNCOMMON, mage.cards.y.YiazmatUltimateMark.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Yiazmat, Ultimate Mark", 453, Rarity.UNCOMMON, mage.cards.y.YiazmatUltimateMark.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("You're Not Alone", 44, Rarity.COMMON, mage.cards.y.YoureNotAlone.class)); cards.add(new SetCardInfo("Yuna, Hope of Spira", 250, Rarity.MYTHIC, mage.cards.y.YunaHopeOfSpira.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Yuna, Hope of Spira", 404, Rarity.MYTHIC, mage.cards.y.YunaHopeOfSpira.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java index 483a1b2442c..3735cf1f758 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java +++ b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java @@ -88,6 +88,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Champions from Beyond", 11, Rarity.RARE, mage.cards.c.ChampionsFromBeyond.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chaos Warp", 291, Rarity.RARE, mage.cards.c.ChaosWarp.class)); cards.add(new SetCardInfo("Chasm Skulker", 262, Rarity.RARE, mage.cards.c.ChasmSkulker.class)); + cards.add(new SetCardInfo("Chocobo Camp", 462, Rarity.RARE, mage.cards.c.ChocoboCamp.class)); cards.add(new SetCardInfo("Chocobo Knights", 102, Rarity.RARE, mage.cards.c.ChocoboKnights.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chocobo Knights", 12, Rarity.RARE, mage.cards.c.ChocoboKnights.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Choked Estuary", 379, Rarity.RARE, mage.cards.c.ChokedEstuary.class)); @@ -187,6 +188,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("G'raha Tia, Scion Reborn", 222, Rarity.MYTHIC, mage.cards.g.GrahaTiaScionReborn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("G'raha Tia, Scion Reborn", 3, Rarity.MYTHIC, mage.cards.g.GrahaTiaScionReborn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Game Trail", 398, Rarity.RARE, mage.cards.g.GameTrail.class)); + cards.add(new SetCardInfo("Garland, Royal Kidnapper", 442, Rarity.RARE, mage.cards.g.GarlandRoyalKidnapper.class)); cards.add(new SetCardInfo("Gatta and Luzzu", 134, Rarity.RARE, mage.cards.g.GattaAndLuzzu.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gatta and Luzzu", 19, Rarity.RARE, mage.cards.g.GattaAndLuzzu.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gau, Feral Youth", 152, Rarity.RARE, mage.cards.g.GauFeralYouth.class, NON_FULL_USE_VARIOUS)); @@ -273,6 +275,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Nature's Lore", 311, Rarity.COMMON, mage.cards.n.NaturesLore.class)); cards.add(new SetCardInfo("Nesting Grounds", 408, Rarity.UNCOMMON, mage.cards.n.NestingGrounds.class)); cards.add(new SetCardInfo("Night's Whisper", 280, Rarity.COMMON, mage.cards.n.NightsWhisper.class)); + cards.add(new SetCardInfo("Noctis, Heir Apparent", 460, Rarity.RARE, mage.cards.n.NoctisHeirApparent.class)); cards.add(new SetCardInfo("Nomad Outpost", 409, Rarity.UNCOMMON, mage.cards.n.NomadOutpost.class)); cards.add(new SetCardInfo("O'aka, Traveling Merchant", 144, Rarity.RARE, mage.cards.o.OakaTravelingMerchant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("O'aka, Traveling Merchant", 39, Rarity.RARE, mage.cards.o.OakaTravelingMerchant.class, NON_FULL_USE_VARIOUS)); @@ -366,6 +369,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Sphere Grid", 123, Rarity.RARE, mage.cards.s.SphereGrid.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sphere Grid", 70, Rarity.RARE, mage.cards.s.SphereGrid.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spire of Industry", 426, Rarity.RARE, mage.cards.s.SpireOfIndustry.class)); + cards.add(new SetCardInfo("Squall, Gunblade Duelist", 453, Rarity.RARE, mage.cards.s.SquallGunbladeDuelist.class)); cards.add(new SetCardInfo("Stitch Together", 286, Rarity.UNCOMMON, mage.cards.s.StitchTogether.class)); cards.add(new SetCardInfo("Stitcher's Supplier", 287, Rarity.UNCOMMON, mage.cards.s.StitchersSupplier.class)); cards.add(new SetCardInfo("Strago and Relm", 155, Rarity.RARE, mage.cards.s.StragoAndRelm.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/Innistrad.java b/Mage.Sets/src/mage/sets/Innistrad.java index 668a62749ab..13615469bf5 100644 --- a/Mage.Sets/src/mage/sets/Innistrad.java +++ b/Mage.Sets/src/mage/sets/Innistrad.java @@ -150,7 +150,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Heretic's Punishment", 147, Rarity.RARE, mage.cards.h.HereticsPunishment.class)); cards.add(new SetCardInfo("Hinterland Harbor", 241, Rarity.RARE, mage.cards.h.HinterlandHarbor.class)); cards.add(new SetCardInfo("Hollowhenge Scavenger", 188, Rarity.UNCOMMON, mage.cards.h.HollowhengeScavenger.class)); - cards.add(new SetCardInfo("Howlpack of Estwald", 209, Rarity.COMMON, mage.cards.h.HowlpackOfEstwald.class)); cards.add(new SetCardInfo("Hysterical Blindness", 59, Rarity.COMMON, mage.cards.h.HystericalBlindness.class)); cards.add(new SetCardInfo("Infernal Plunge", 148, Rarity.COMMON, mage.cards.i.InfernalPlunge.class)); cards.add(new SetCardInfo("Inquisitor's Flail", 227, Rarity.UNCOMMON, mage.cards.i.InquisitorsFlail.class)); @@ -158,7 +157,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Intangible Virtue", 19, Rarity.UNCOMMON, mage.cards.i.IntangibleVirtue.class)); cards.add(new SetCardInfo("Into the Maw of Hell", 150, Rarity.UNCOMMON, mage.cards.i.IntoTheMawOfHell.class)); cards.add(new SetCardInfo("Invisible Stalker", 60, Rarity.UNCOMMON, mage.cards.i.InvisibleStalker.class)); - cards.add(new SetCardInfo("Ironfang", 168, Rarity.COMMON, mage.cards.i.Ironfang.class)); cards.add(new SetCardInfo("Island", 253, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 254, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 255, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -222,7 +220,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Rage Thrower", 157, Rarity.UNCOMMON, mage.cards.r.RageThrower.class)); cards.add(new SetCardInfo("Rakish Heir", 158, Rarity.UNCOMMON, mage.cards.r.RakishHeir.class)); cards.add(new SetCardInfo("Rally the Peasants", 28, Rarity.UNCOMMON, mage.cards.r.RallyThePeasants.class)); - cards.add(new SetCardInfo("Rampaging Werewolf", 165, Rarity.COMMON, mage.cards.r.RampagingWerewolf.class)); cards.add(new SetCardInfo("Ranger's Guile", 201, Rarity.COMMON, mage.cards.r.RangersGuile.class)); cards.add(new SetCardInfo("Reaper from the Abyss", 112, Rarity.MYTHIC, mage.cards.r.ReaperFromTheAbyss.class)); cards.add(new SetCardInfo("Rebuke", 29, Rarity.COMMON, mage.cards.r.Rebuke.class)); @@ -259,7 +256,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Spider Spawning", 203, Rarity.UNCOMMON, mage.cards.s.SpiderSpawning.class)); cards.add(new SetCardInfo("Spidery Grasp", 204, Rarity.COMMON, mage.cards.s.SpideryGrasp.class)); cards.add(new SetCardInfo("Splinterfright", 205, Rarity.RARE, mage.cards.s.Splinterfright.class)); - cards.add(new SetCardInfo("Stalking Vampire", 114, Rarity.UNCOMMON, mage.cards.s.StalkingVampire.class)); cards.add(new SetCardInfo("Stensia Bloodhall", 247, Rarity.RARE, mage.cards.s.StensiaBloodhall.class)); cards.add(new SetCardInfo("Stitched Drake", 80, Rarity.COMMON, mage.cards.s.StitchedDrake.class)); cards.add(new SetCardInfo("Stitcher's Apprentice", 81, Rarity.COMMON, mage.cards.s.StitchersApprentice.class)); @@ -272,7 +268,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 257, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 258, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Think Twice", 83, Rarity.COMMON, mage.cards.t.ThinkTwice.class)); - cards.add(new SetCardInfo("Thraben Militia", 38, Rarity.COMMON, mage.cards.t.ThrabenMilitia.class)); cards.add(new SetCardInfo("Thraben Purebloods", 37, Rarity.COMMON, mage.cards.t.ThrabenPurebloods.class)); cards.add(new SetCardInfo("Thraben Sentry", 38, Rarity.COMMON, mage.cards.t.ThrabenSentry.class)); cards.add(new SetCardInfo("Tormented Pariah", 165, Rarity.COMMON, mage.cards.t.TormentedPariah.class)); @@ -284,7 +279,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Tribute to Hunger", 119, Rarity.UNCOMMON, mage.cards.t.TributeToHunger.class)); cards.add(new SetCardInfo("Typhoid Rats", 120, Rarity.COMMON, mage.cards.t.TyphoidRats.class)); cards.add(new SetCardInfo("Ulvenwald Mystics", 208, Rarity.UNCOMMON, mage.cards.u.UlvenwaldMystics.class)); - cards.add(new SetCardInfo("Ulvenwald Primordials", 208, Rarity.UNCOMMON, mage.cards.u.UlvenwaldPrimordials.class)); cards.add(new SetCardInfo("Unbreathing Horde", 121, Rarity.RARE, mage.cards.u.UnbreathingHorde.class)); cards.add(new SetCardInfo("Unburial Rites", 122, Rarity.UNCOMMON, mage.cards.u.UnburialRites.class)); cards.add(new SetCardInfo("Undead Alchemist", 84, Rarity.RARE, mage.cards.u.UndeadAlchemist.class)); diff --git a/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java b/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java index 241813b7699..4cf85b4fdca 100644 --- a/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java +++ b/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java @@ -70,9 +70,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Blood Petal Celebrant", 146, Rarity.COMMON, mage.cards.b.BloodPetalCelebrant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Petal Celebrant", 303, Rarity.COMMON, mage.cards.b.BloodPetalCelebrant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Servitor", 252, Rarity.COMMON, mage.cards.b.BloodServitor.class)); - cards.add(new SetCardInfo("Bloodbat Summoner", 137, Rarity.RARE, mage.cards.b.BloodbatSummoner.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Bloodbat Summoner", 298, Rarity.RARE, mage.cards.b.BloodbatSummoner.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Bloodbat Summoner", 338, Rarity.RARE, mage.cards.b.BloodbatSummoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodcrazed Socialite", 288, Rarity.COMMON, mage.cards.b.BloodcrazedSocialite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodcrazed Socialite", 96, Rarity.COMMON, mage.cards.b.BloodcrazedSocialite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodsworn Squire", 289, Rarity.UNCOMMON, mage.cards.b.BloodswornSquire.class, NON_FULL_USE_VARIOUS)); @@ -82,7 +79,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Bloodvial Purveyor", 290, Rarity.RARE, mage.cards.b.BloodvialPurveyor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodvial Purveyor", 98, Rarity.RARE, mage.cards.b.BloodvialPurveyor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloody Betrayal", 147, Rarity.COMMON, mage.cards.b.BloodyBetrayal.class)); - cards.add(new SetCardInfo("Blossom-Clad Werewolf", 226, Rarity.COMMON, mage.cards.b.BlossomCladWerewolf.class)); cards.add(new SetCardInfo("Boarded Window", 253, Rarity.UNCOMMON, mage.cards.b.BoardedWindow.class)); cards.add(new SetCardInfo("Bramble Armor", 188, Rarity.COMMON, mage.cards.b.BrambleArmor.class)); cards.add(new SetCardInfo("Bramble Wurm", 189, Rarity.UNCOMMON, mage.cards.b.BrambleWurm.class)); @@ -109,7 +105,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Change of Fortune", 375, Rarity.RARE, mage.cards.c.ChangeOfFortune.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Child of the Pack", 234, Rarity.UNCOMMON, mage.cards.c.ChildOfThePack.class)); cards.add(new SetCardInfo("Chill of the Grave", 51, Rarity.COMMON, mage.cards.c.ChillOfTheGrave.class)); - cards.add(new SetCardInfo("Cipherbound Spirit", 79, Rarity.UNCOMMON, mage.cards.c.CipherboundSpirit.class)); cards.add(new SetCardInfo("Circle of Confinement", 329, Rarity.UNCOMMON, mage.cards.c.CircleOfConfinement.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Circle of Confinement", 7, Rarity.UNCOMMON, mage.cards.c.CircleOfConfinement.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cloaked Cadet", 192, Rarity.UNCOMMON, mage.cards.c.CloakedCadet.class)); @@ -139,8 +134,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Desperate Farmer", 104, Rarity.COMMON, mage.cards.d.DesperateFarmer.class)); cards.add(new SetCardInfo("Dig Up", 197, Rarity.RARE, mage.cards.d.DigUp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dig Up", 387, Rarity.RARE, mage.cards.d.DigUp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dire-Strain Anarchist", 181, Rarity.MYTHIC, mage.cards.d.DireStrainAnarchist.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dire-Strain Anarchist", 382, Rarity.MYTHIC, mage.cards.d.DireStrainAnarchist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Diregraf Scavenger", 105, Rarity.COMMON, mage.cards.d.DiregrafScavenger.class)); cards.add(new SetCardInfo("Distracting Geist", 9, Rarity.UNCOMMON, mage.cards.d.DistractingGeist.class)); cards.add(new SetCardInfo("Diver Skaab", 56, Rarity.UNCOMMON, mage.cards.d.DiverSkaab.class)); @@ -412,9 +405,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Toxrill, the Corrosive", 321, Rarity.MYTHIC, mage.cards.t.ToxrillTheCorrosive.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Traveling Minister", 39, Rarity.COMMON, mage.cards.t.TravelingMinister.class)); cards.add(new SetCardInfo("Twinblade Geist", 40, Rarity.UNCOMMON, mage.cards.t.TwinbladeGeist.class)); - cards.add(new SetCardInfo("Twinblade Invocation", 40, Rarity.UNCOMMON, mage.cards.t.TwinbladeInvocation.class)); - cards.add(new SetCardInfo("Ulvenwald Behemoth", 225, Rarity.RARE, mage.cards.u.UlvenwaldBehemoth.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ulvenwald Behemoth", 394, Rarity.RARE, mage.cards.u.UlvenwaldBehemoth.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ulvenwald Oddity", 225, Rarity.RARE, mage.cards.u.UlvenwaldOddity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ulvenwald Oddity", 394, Rarity.RARE, mage.cards.u.UlvenwaldOddity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Undead Butler", 133, Rarity.UNCOMMON, mage.cards.u.UndeadButler.class)); @@ -440,7 +430,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Voldaren Estate", 267, Rarity.RARE, mage.cards.v.VoldarenEstate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Voldaren Estate", 397, Rarity.RARE, mage.cards.v.VoldarenEstate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Voldaren Estate", 403, Rarity.RARE, mage.cards.v.VoldarenEstate.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Volt-Charged Berserker", 183, Rarity.UNCOMMON, mage.cards.v.VoltChargedBerserker.class)); cards.add(new SetCardInfo("Voltaic Visionary", 183, Rarity.UNCOMMON, mage.cards.v.VoltaicVisionary.class)); cards.add(new SetCardInfo("Wandering Mind", 251, Rarity.UNCOMMON, mage.cards.w.WanderingMind.class)); cards.add(new SetCardInfo("Wanderlight Spirit", 86, Rarity.COMMON, mage.cards.w.WanderlightSpirit.class)); @@ -449,9 +438,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Weaver of Blossoms", 226, Rarity.COMMON, mage.cards.w.WeaverOfBlossoms.class)); cards.add(new SetCardInfo("Wedding Announcement", 355, Rarity.RARE, mage.cards.w.WeddingAnnouncement.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wedding Announcement", 45, Rarity.RARE, mage.cards.w.WeddingAnnouncement.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wedding Crasher", 229, Rarity.UNCOMMON, mage.cards.w.WeddingCrasher.class)); - cards.add(new SetCardInfo("Wedding Festivity", 355, Rarity.RARE, mage.cards.w.WeddingFestivity.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wedding Festivity", 45, Rarity.RARE, mage.cards.w.WeddingFestivity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wedding Invitation", 260, Rarity.COMMON, mage.cards.w.WeddingInvitation.class)); cards.add(new SetCardInfo("Wedding Security", 138, Rarity.UNCOMMON, mage.cards.w.WeddingSecurity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wedding Security", 299, Rarity.UNCOMMON, mage.cards.w.WeddingSecurity.class, NON_FULL_USE_VARIOUS)); @@ -464,7 +450,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Witness the Future", 90, Rarity.UNCOMMON, mage.cards.w.WitnessTheFuture.class)); cards.add(new SetCardInfo("Wolf Strike", 228, Rarity.COMMON, mage.cards.w.WolfStrike.class)); cards.add(new SetCardInfo("Wolfkin Outcast", 229, Rarity.UNCOMMON, mage.cards.w.WolfkinOutcast.class)); - cards.add(new SetCardInfo("Wrathful Jailbreaker", 184, Rarity.COMMON, mage.cards.w.WrathfulJailbreaker.class)); cards.add(new SetCardInfo("Wretched Throng", 91, Rarity.COMMON, mage.cards.w.WretchedThrong.class)); } diff --git a/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java b/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java index d4894338ec2..3a0aa70042d 100644 --- a/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java +++ b/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java @@ -48,7 +48,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Arm the Cathars", 270, Rarity.UNCOMMON, mage.cards.a.ArmTheCathars.class)); cards.add(new SetCardInfo("Arrogant Outlaw", 84, Rarity.COMMON, mage.cards.a.ArrogantOutlaw.class)); cards.add(new SetCardInfo("Ascendant Packleader", 453, Rarity.RARE, mage.cards.a.AscendantPackleader.class)); - cards.add(new SetCardInfo("Ashmouth Dragon", 159, Rarity.RARE, mage.cards.a.AshmouthDragon.class)); cards.add(new SetCardInfo("Augur of Autumn", 168, Rarity.RARE, mage.cards.a.AugurOfAutumn.class)); cards.add(new SetCardInfo("Avabruck Caretaker", 454, Rarity.MYTHIC, mage.cards.a.AvabruckCaretaker.class)); cards.add(new SetCardInfo("Baithook Angler", 42, Rarity.COMMON, mage.cards.b.BaithookAngler.class)); @@ -70,7 +69,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Blood Pact", 88, Rarity.COMMON, mage.cards.b.BloodPact.class)); cards.add(new SetCardInfo("Blood Petal Celebrant", 413, Rarity.COMMON, mage.cards.b.BloodPetalCelebrant.class)); cards.add(new SetCardInfo("Blood Servitor", 519, Rarity.COMMON, mage.cards.b.BloodServitor.class)); - cards.add(new SetCardInfo("Bloodbat Summoner", 404, Rarity.RARE, mage.cards.b.BloodbatSummoner.class)); cards.add(new SetCardInfo("Bloodcrazed Socialite", 363, Rarity.COMMON, mage.cards.b.BloodcrazedSocialite.class)); cards.add(new SetCardInfo("Bloodline Culling", 89, Rarity.RARE, mage.cards.b.BloodlineCulling.class)); cards.add(new SetCardInfo("Bloodsworn Squire", 364, Rarity.UNCOMMON, mage.cards.b.BloodswornSquire.class)); @@ -79,7 +77,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Bloodtithe Harvester", 499, Rarity.UNCOMMON, mage.cards.b.BloodtitheHarvester.class)); cards.add(new SetCardInfo("Bloodvial Purveyor", 365, Rarity.RARE, mage.cards.b.BloodvialPurveyor.class)); cards.add(new SetCardInfo("Bloody Betrayal", 414, Rarity.COMMON, mage.cards.b.BloodyBetrayal.class)); - cards.add(new SetCardInfo("Blossom-Clad Werewolf", 493, Rarity.COMMON, mage.cards.b.BlossomCladWerewolf.class)); cards.add(new SetCardInfo("Boarded Window", 520, Rarity.UNCOMMON, mage.cards.b.BoardedWindow.class)); cards.add(new SetCardInfo("Borrowed Time", 6, Rarity.UNCOMMON, mage.cards.b.BorrowedTime.class)); cards.add(new SetCardInfo("Bounding Wolf", 170, Rarity.COMMON, mage.cards.b.BoundingWolf.class)); @@ -118,7 +115,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Chaplain of Alms", 13, Rarity.UNCOMMON, mage.cards.c.ChaplainOfAlms.class)); cards.add(new SetCardInfo("Child of the Pack", 501, Rarity.UNCOMMON, mage.cards.c.ChildOfThePack.class)); cards.add(new SetCardInfo("Chill of the Grave", 318, Rarity.COMMON, mage.cards.c.ChillOfTheGrave.class)); - cards.add(new SetCardInfo("Cipherbound Spirit", 346, Rarity.UNCOMMON, mage.cards.c.CipherboundSpirit.class)); cards.add(new SetCardInfo("Circle of Confinement", 274, Rarity.UNCOMMON, mage.cards.c.CircleOfConfinement.class)); cards.add(new SetCardInfo("Clarion Cathars", 14, Rarity.COMMON, mage.cards.c.ClarionCathars.class)); cards.add(new SetCardInfo("Clear Shot", 176, Rarity.UNCOMMON, mage.cards.c.ClearShot.class)); @@ -166,8 +162,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Devious Cover-Up", 48, Rarity.COMMON, mage.cards.d.DeviousCoverUp.class)); cards.add(new SetCardInfo("Devoted Grafkeeper", 218, Rarity.UNCOMMON, mage.cards.d.DevotedGrafkeeper.class)); cards.add(new SetCardInfo("Dig Up", 464, Rarity.RARE, mage.cards.d.DigUp.class)); - cards.add(new SetCardInfo("Dire-Strain Anarchist", 448, Rarity.MYTHIC, mage.cards.d.DireStrainAnarchist.class)); - cards.add(new SetCardInfo("Dire-Strain Brawler", 203, Rarity.COMMON, mage.cards.d.DireStrainBrawler.class)); cards.add(new SetCardInfo("Dire-Strain Rampage", 219, Rarity.RARE, mage.cards.d.DireStrainRampage.class)); cards.add(new SetCardInfo("Diregraf Horde", 96, Rarity.COMMON, mage.cards.d.DiregrafHorde.class)); cards.add(new SetCardInfo("Diregraf Rebirth", 220, Rarity.UNCOMMON, mage.cards.d.DiregrafRebirth.class)); @@ -436,7 +430,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Sawblade Slinger", 484, Rarity.UNCOMMON, mage.cards.s.SawbladeSlinger.class)); cards.add(new SetCardInfo("Scattered Thoughts", 341, Rarity.COMMON, mage.cards.s.ScatteredThoughts.class)); cards.add(new SetCardInfo("Screaming Swarm", 342, Rarity.UNCOMMON, mage.cards.s.ScreamingSwarm.class)); - cards.add(new SetCardInfo("Seafaring Werewolf", 80, Rarity.RARE, mage.cards.s.SeafaringWerewolf.class)); cards.add(new SetCardInfo("Search Party Captain", 32, Rarity.COMMON, mage.cards.s.SearchPartyCaptain.class)); cards.add(new SetCardInfo("Secrets of the Key", 73, Rarity.COMMON, mage.cards.s.SecretsOfTheKey.class)); cards.add(new SetCardInfo("Seize the Storm", 158, Rarity.UNCOMMON, mage.cards.s.SeizeTheStorm.class)); @@ -471,13 +464,11 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Soul-Guide Gryff", 35, Rarity.COMMON, mage.cards.s.SoulGuideGryff.class)); cards.add(new SetCardInfo("Soulcipher Board", 346, Rarity.UNCOMMON, mage.cards.s.SoulcipherBoard.class)); cards.add(new SetCardInfo("Spectral Adversary", 77, Rarity.MYTHIC, mage.cards.s.SpectralAdversary.class)); - cards.add(new SetCardInfo("Spellrune Howler", 160, Rarity.UNCOMMON, mage.cards.s.SpellruneHowler.class)); cards.add(new SetCardInfo("Spellrune Painter", 160, Rarity.UNCOMMON, mage.cards.s.SpellrunePainter.class)); cards.add(new SetCardInfo("Spiked Ripsaw", 487, Rarity.UNCOMMON, mage.cards.s.SpikedRipsaw.class)); cards.add(new SetCardInfo("Splendid Reclamation", 488, Rarity.RARE, mage.cards.s.SplendidReclamation.class)); cards.add(new SetCardInfo("Spore Crawler", 489, Rarity.COMMON, mage.cards.s.SporeCrawler.class)); cards.add(new SetCardInfo("Sporeback Wolf", 490, Rarity.COMMON, mage.cards.s.SporebackWolf.class)); - cards.add(new SetCardInfo("Stalking Predator", 120, Rarity.COMMON, mage.cards.s.StalkingPredator.class)); cards.add(new SetCardInfo("Startle", 78, Rarity.COMMON, mage.cards.s.Startle.class)); cards.add(new SetCardInfo("Steelclad Spirit", 347, Rarity.COMMON, mage.cards.s.SteelcladSpirit.class)); cards.add(new SetCardInfo("Stensia Uprising", 445, Rarity.RARE, mage.cards.s.StensiaUprising.class)); @@ -488,7 +479,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Stormcarved Coast", 532, Rarity.RARE, mage.cards.s.StormcarvedCoast.class)); cards.add(new SetCardInfo("Stormchaser Drake", 349, Rarity.UNCOMMON, mage.cards.s.StormchaserDrake.class)); cards.add(new SetCardInfo("Stormrider Spirit", 79, Rarity.COMMON, mage.cards.s.StormriderSpirit.class)); - cards.add(new SetCardInfo("Strangling Grasp", 126, Rarity.UNCOMMON, mage.cards.s.StranglingGrasp.class)); cards.add(new SetCardInfo("Stromkirk Bloodthief", 123, Rarity.UNCOMMON, mage.cards.s.StromkirkBloodthief.class)); cards.add(new SetCardInfo("Stuffed Bear", 259, Rarity.COMMON, mage.cards.s.StuffedBear.class)); cards.add(new SetCardInfo("Sundown Pass", 533, Rarity.RARE, mage.cards.s.SundownPass.class)); @@ -505,7 +495,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Tainted Adversary", 124, Rarity.MYTHIC, mage.cards.t.TaintedAdversary.class)); cards.add(new SetCardInfo("Tapping at the Window", 201, Rarity.COMMON, mage.cards.t.TappingAtTheWindow.class)); cards.add(new SetCardInfo("Tavern Ruffian", 163, Rarity.COMMON, mage.cards.t.TavernRuffian.class)); - cards.add(new SetCardInfo("Tavern Smasher", 163, Rarity.COMMON, mage.cards.t.TavernSmasher.class)); cards.add(new SetCardInfo("Teferi, Who Slows the Sunset", 245, Rarity.MYTHIC, mage.cards.t.TeferiWhoSlowsTheSunset.class)); cards.add(new SetCardInfo("Thalia, Guardian of Thraben", 305, Rarity.RARE, mage.cards.t.ThaliaGuardianOfThraben.class)); cards.add(new SetCardInfo("The Celestus", 252, Rarity.RARE, mage.cards.t.TheCelestus.class)); @@ -517,17 +506,13 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Tireless Hauler", 203, Rarity.COMMON, mage.cards.t.TirelessHauler.class)); cards.add(new SetCardInfo("Torens, Fist of the Angels", 516, Rarity.RARE, mage.cards.t.TorensFistOfTheAngels.class)); cards.add(new SetCardInfo("Tovolar's Huntmaster", 204, Rarity.RARE, mage.cards.t.TovolarsHuntmaster.class)); - cards.add(new SetCardInfo("Tovolar's Packleader", 204, Rarity.RARE, mage.cards.t.TovolarsPackleader.class)); cards.add(new SetCardInfo("Tovolar, Dire Overlord", 246, Rarity.RARE, mage.cards.t.TovolarDireOverlord.class)); - cards.add(new SetCardInfo("Tovolar, the Midnight Scourge", 246, Rarity.RARE, mage.cards.t.TovolarTheMidnightScourge.class)); cards.add(new SetCardInfo("Toxic Scorpion", 491, Rarity.COMMON, mage.cards.t.ToxicScorpion.class)); cards.add(new SetCardInfo("Toxrill, the Corrosive", 399, Rarity.MYTHIC, mage.cards.t.ToxrillTheCorrosive.class)); cards.add(new SetCardInfo("Traveling Minister", 306, Rarity.COMMON, mage.cards.t.TravelingMinister.class)); cards.add(new SetCardInfo("Triskaidekaphile", 81, Rarity.RARE, mage.cards.t.Triskaidekaphile.class)); cards.add(new SetCardInfo("Turn the Earth", 205, Rarity.UNCOMMON, mage.cards.t.TurnTheEarth.class)); cards.add(new SetCardInfo("Twinblade Geist", 307, Rarity.UNCOMMON, mage.cards.t.TwinbladeGeist.class)); - cards.add(new SetCardInfo("Twinblade Invocation", 307, Rarity.UNCOMMON, mage.cards.t.TwinbladeInvocation.class)); - cards.add(new SetCardInfo("Ulvenwald Behemoth", 492, Rarity.RARE, mage.cards.u.UlvenwaldBehemoth.class)); cards.add(new SetCardInfo("Ulvenwald Oddity", 492, Rarity.RARE, mage.cards.u.UlvenwaldOddity.class)); cards.add(new SetCardInfo("Unblinking Observer", 82, Rarity.COMMON, mage.cards.u.UnblinkingObserver.class)); cards.add(new SetCardInfo("Undead Butler", 400, Rarity.UNCOMMON, mage.cards.u.UndeadButler.class)); @@ -547,7 +532,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Vanquish the Horde", 41, Rarity.RARE, mage.cards.v.VanquishTheHorde.class)); cards.add(new SetCardInfo("Vengeful Strangler", 126, Rarity.UNCOMMON, mage.cards.v.VengefulStrangler.class)); cards.add(new SetCardInfo("Vilespawn Spider", 517, Rarity.UNCOMMON, mage.cards.v.VilespawnSpider.class)); - cards.add(new SetCardInfo("Village Reavers", 165, Rarity.UNCOMMON, mage.cards.v.VillageReavers.class)); cards.add(new SetCardInfo("Village Watch", 165, Rarity.UNCOMMON, mage.cards.v.VillageWatch.class)); cards.add(new SetCardInfo("Vivisection", 83, Rarity.UNCOMMON, mage.cards.v.Vivisection.class)); cards.add(new SetCardInfo("Voice of the Blessed", 311, Rarity.RARE, mage.cards.v.VoiceOfTheBlessed.class)); @@ -557,7 +541,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Voldaren Epicure", 449, Rarity.COMMON, mage.cards.v.VoldarenEpicure.class)); cards.add(new SetCardInfo("Voldaren Estate", 534, Rarity.RARE, mage.cards.v.VoldarenEstate.class)); cards.add(new SetCardInfo("Voldaren Stinger", 167, Rarity.COMMON, mage.cards.v.VoldarenStinger.class)); - cards.add(new SetCardInfo("Volt-Charged Berserker", 450, Rarity.UNCOMMON, mage.cards.v.VoltChargedBerserker.class)); cards.add(new SetCardInfo("Voltaic Visionary", 450, Rarity.UNCOMMON, mage.cards.v.VoltaicVisionary.class)); cards.add(new SetCardInfo("Wake to Slaughter", 250, Rarity.RARE, mage.cards.w.WakeToSlaughter.class)); cards.add(new SetCardInfo("Wandering Mind", 518, Rarity.UNCOMMON, mage.cards.w.WanderingMind.class)); @@ -566,8 +549,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Weary Prisoner", 451, Rarity.COMMON, mage.cards.w.WearyPrisoner.class)); cards.add(new SetCardInfo("Weaver of Blossoms", 493, Rarity.COMMON, mage.cards.w.WeaverOfBlossoms.class)); cards.add(new SetCardInfo("Wedding Announcement", 312, Rarity.RARE, mage.cards.w.WeddingAnnouncement.class)); - cards.add(new SetCardInfo("Wedding Crasher", 496, Rarity.UNCOMMON, mage.cards.w.WeddingCrasher.class)); - cards.add(new SetCardInfo("Wedding Festivity", 312, Rarity.RARE, mage.cards.w.WeddingFestivity.class)); cards.add(new SetCardInfo("Wedding Invitation", 527, Rarity.COMMON, mage.cards.w.WeddingInvitation.class)); cards.add(new SetCardInfo("Wedding Security", 405, Rarity.UNCOMMON, mage.cards.w.WeddingSecurity.class)); cards.add(new SetCardInfo("Welcoming Vampire", 313, Rarity.RARE, mage.cards.w.WelcomingVampire.class)); @@ -579,7 +560,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Witness the Future", 357, Rarity.UNCOMMON, mage.cards.w.WitnessTheFuture.class)); cards.add(new SetCardInfo("Wolf Strike", 495, Rarity.COMMON, mage.cards.w.WolfStrike.class)); cards.add(new SetCardInfo("Wolfkin Outcast", 496, Rarity.UNCOMMON, mage.cards.w.WolfkinOutcast.class)); - cards.add(new SetCardInfo("Wrathful Jailbreaker", 451, Rarity.COMMON, mage.cards.w.WrathfulJailbreaker.class)); cards.add(new SetCardInfo("Wrenn and Seven", 208, Rarity.MYTHIC, mage.cards.w.WrennAndSeven.class)); cards.add(new SetCardInfo("Wretched Throng", 358, Rarity.COMMON, mage.cards.w.WretchedThrong.class)); } diff --git a/Mage.Sets/src/mage/sets/InnistradMidnightHunt.java b/Mage.Sets/src/mage/sets/InnistradMidnightHunt.java index fb87175a93f..7bfffd9308b 100644 --- a/Mage.Sets/src/mage/sets/InnistradMidnightHunt.java +++ b/Mage.Sets/src/mage/sets/InnistradMidnightHunt.java @@ -51,8 +51,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 279, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 307, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arrogant Outlaw", 84, Rarity.COMMON, mage.cards.a.ArrogantOutlaw.class)); - cards.add(new SetCardInfo("Ashmouth Dragon", 159, Rarity.RARE, mage.cards.a.AshmouthDragon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ashmouth Dragon", 358, Rarity.RARE, mage.cards.a.AshmouthDragon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Augur of Autumn", 168, Rarity.RARE, mage.cards.a.AugurOfAutumn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Augur of Autumn", 360, Rarity.RARE, mage.cards.a.AugurOfAutumn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Baithook Angler", 42, Rarity.COMMON, mage.cards.b.BaithookAngler.class)); @@ -139,8 +137,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Deserted Beach", 281, Rarity.RARE, mage.cards.d.DesertedBeach.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Devious Cover-Up", 48, Rarity.COMMON, mage.cards.d.DeviousCoverUp.class)); cards.add(new SetCardInfo("Devoted Grafkeeper", 218, Rarity.UNCOMMON, mage.cards.d.DevotedGrafkeeper.class)); - cards.add(new SetCardInfo("Dire-Strain Brawler", 203, Rarity.COMMON, mage.cards.d.DireStrainBrawler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dire-Strain Brawler", 305, Rarity.COMMON, mage.cards.d.DireStrainBrawler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dire-Strain Rampage", 219, Rarity.RARE, mage.cards.d.DireStrainRampage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dire-Strain Rampage", 370, Rarity.RARE, mage.cards.d.DireStrainRampage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Diregraf Horde", 96, Rarity.COMMON, mage.cards.d.DiregrafHorde.class)); @@ -332,8 +328,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Sacred Fire", 239, Rarity.UNCOMMON, mage.cards.s.SacredFire.class)); cards.add(new SetCardInfo("Saryth, the Viper's Fang", 197, Rarity.RARE, mage.cards.s.SarythTheVipersFang.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Saryth, the Viper's Fang", 304, Rarity.RARE, mage.cards.s.SarythTheVipersFang.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Seafaring Werewolf", 288, Rarity.RARE, mage.cards.s.SeafaringWerewolf.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Seafaring Werewolf", 80, Rarity.RARE, mage.cards.s.SeafaringWerewolf.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Search Party Captain", 32, Rarity.COMMON, mage.cards.s.SearchPartyCaptain.class)); cards.add(new SetCardInfo("Secrets of the Key", 73, Rarity.COMMON, mage.cards.s.SecretsOfTheKey.class)); cards.add(new SetCardInfo("Seize the Storm", 158, Rarity.UNCOMMON, mage.cards.s.SeizeTheStorm.class)); @@ -366,19 +360,14 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Soul-Guide Gryff", 35, Rarity.COMMON, mage.cards.s.SoulGuideGryff.class)); cards.add(new SetCardInfo("Spectral Adversary", 341, Rarity.MYTHIC, mage.cards.s.SpectralAdversary.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spectral Adversary", 77, Rarity.MYTHIC, mage.cards.s.SpectralAdversary.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Spellrune Howler", 160, Rarity.UNCOMMON, mage.cards.s.SpellruneHowler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Spellrune Howler", 295, Rarity.UNCOMMON, mage.cards.s.SpellruneHowler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spellrune Painter", 160, Rarity.UNCOMMON, mage.cards.s.SpellrunePainter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spellrune Painter", 295, Rarity.UNCOMMON, mage.cards.s.SpellrunePainter.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Stalking Predator", 120, Rarity.COMMON, mage.cards.s.StalkingPredator.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Stalking Predator", 291, Rarity.COMMON, mage.cards.s.StalkingPredator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Startle", 78, Rarity.COMMON, mage.cards.s.Startle.class)); cards.add(new SetCardInfo("Stolen Vitality", 161, Rarity.COMMON, mage.cards.s.StolenVitality.class)); cards.add(new SetCardInfo("Storm Skreelix", 243, Rarity.UNCOMMON, mage.cards.s.StormSkreelix.class)); cards.add(new SetCardInfo("Storm the Festival", 200, Rarity.RARE, mage.cards.s.StormTheFestival.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Storm the Festival", 364, Rarity.RARE, mage.cards.s.StormTheFestival.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Stormrider Spirit", 79, Rarity.COMMON, mage.cards.s.StormriderSpirit.class)); - cards.add(new SetCardInfo("Strangling Grasp", 126, Rarity.UNCOMMON, mage.cards.s.StranglingGrasp.class)); cards.add(new SetCardInfo("Stromkirk Bloodthief", 123, Rarity.UNCOMMON, mage.cards.s.StromkirkBloodthief.class)); cards.add(new SetCardInfo("Stuffed Bear", 259, Rarity.COMMON, mage.cards.s.StuffedBear.class)); cards.add(new SetCardInfo("Sungold Barrage", 36, Rarity.COMMON, mage.cards.s.SungoldBarrage.class)); @@ -398,8 +387,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Tapping at the Window", 201, Rarity.COMMON, mage.cards.t.TappingAtTheWindow.class)); cards.add(new SetCardInfo("Tavern Ruffian", 163, Rarity.COMMON, mage.cards.t.TavernRuffian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tavern Ruffian", 296, Rarity.COMMON, mage.cards.t.TavernRuffian.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tavern Smasher", 163, Rarity.COMMON, mage.cards.t.TavernSmasher.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tavern Smasher", 296, Rarity.COMMON, mage.cards.t.TavernSmasher.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Teferi, Who Slows the Sunset", 245, Rarity.MYTHIC, mage.cards.t.TeferiWhoSlowsTheSunset.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Teferi, Who Slows the Sunset", 280, Rarity.MYTHIC, mage.cards.t.TeferiWhoSlowsTheSunset.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Celestus", 252, Rarity.RARE, mage.cards.t.TheCelestus.class, NON_FULL_USE_VARIOUS)); @@ -413,12 +400,8 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Tireless Hauler", 305, Rarity.COMMON, mage.cards.t.TirelessHauler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tovolar's Huntmaster", 204, Rarity.RARE, mage.cards.t.TovolarsHuntmaster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tovolar's Huntmaster", 306, Rarity.RARE, mage.cards.t.TovolarsHuntmaster.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tovolar's Packleader", 204, Rarity.RARE, mage.cards.t.TovolarsPackleader.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tovolar's Packleader", 306, Rarity.RARE, mage.cards.t.TovolarsPackleader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tovolar, Dire Overlord", 246, Rarity.RARE, mage.cards.t.TovolarDireOverlord.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tovolar, Dire Overlord", 311, Rarity.RARE, mage.cards.t.TovolarDireOverlord.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tovolar, the Midnight Scourge", 246, Rarity.RARE, mage.cards.t.TovolarTheMidnightScourge.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tovolar, the Midnight Scourge", 311, Rarity.RARE, mage.cards.t.TovolarTheMidnightScourge.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Triskaidekaphile", 342, Rarity.RARE, mage.cards.t.Triskaidekaphile.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Triskaidekaphile", 386, Rarity.RARE, mage.cards.t.Triskaidekaphile.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Triskaidekaphile", 81, Rarity.RARE, mage.cards.t.Triskaidekaphile.class, NON_FULL_USE_VARIOUS)); @@ -435,8 +418,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Vanquish the Horde", 333, Rarity.RARE, mage.cards.v.VanquishTheHorde.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vanquish the Horde", 41, Rarity.RARE, mage.cards.v.VanquishTheHorde.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vengeful Strangler", 126, Rarity.UNCOMMON, mage.cards.v.VengefulStrangler.class)); - cards.add(new SetCardInfo("Village Reavers", 165, Rarity.UNCOMMON, mage.cards.v.VillageReavers.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Village Reavers", 297, Rarity.UNCOMMON, mage.cards.v.VillageReavers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Village Watch", 165, Rarity.UNCOMMON, mage.cards.v.VillageWatch.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Village Watch", 297, Rarity.UNCOMMON, mage.cards.v.VillageWatch.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vivisection", 83, Rarity.UNCOMMON, mage.cards.v.Vivisection.class)); diff --git a/Mage.Sets/src/mage/sets/InnistradRemastered.java b/Mage.Sets/src/mage/sets/InnistradRemastered.java index 90321974994..f2644ce218f 100644 --- a/Mage.Sets/src/mage/sets/InnistradRemastered.java +++ b/Mage.Sets/src/mage/sets/InnistradRemastered.java @@ -58,8 +58,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Avacyn, Angel of Hope", 482, Rarity.MYTHIC, mage.cards.a.AvacynAngelOfHope.class, FULL_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Avacynian Priest", 12, Rarity.COMMON, mage.cards.a.AvacynianPriest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avacynian Priest", 334, Rarity.COMMON, mage.cards.a.AvacynianPriest.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Awoken Horror", 460, Rarity.RARE, mage.cards.a.AwokenHorror.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Awoken Horror", 91, Rarity.RARE, mage.cards.a.AwokenHorror.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Balefire Dragon", 479, Rarity.MYTHIC, mage.cards.b.BalefireDragon.class, RETRO_ART)); cards.add(new SetCardInfo("Battleground Geist", 53, Rarity.COMMON, mage.cards.b.BattlegroundGeist.class)); cards.add(new SetCardInfo("Bedlam Reveler", 142, Rarity.RARE, mage.cards.b.BedlamReveler.class, NON_FULL_USE_VARIOUS)); @@ -75,7 +73,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Blood Mist", 143, Rarity.UNCOMMON, mage.cards.b.BloodMist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Mist", 395, Rarity.UNCOMMON, mage.cards.b.BloodMist.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Petal Celebrant", 144, Rarity.COMMON, mage.cards.b.BloodPetalCelebrant.class)); - cards.add(new SetCardInfo("Bloodbat Summoner", 138, Rarity.RARE, mage.cards.b.BloodbatSummoner.class)); cards.add(new SetCardInfo("Bloodhall Priest", 232, Rarity.RARE, mage.cards.b.BloodhallPriest.class)); cards.add(new SetCardInfo("Bloodline Keeper", 327, Rarity.MYTHIC, mage.cards.b.BloodlineKeeper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodline Keeper", 461, Rarity.MYTHIC, mage.cards.b.BloodlineKeeper.class, RETRO_ART_USE_VARIOUS)); @@ -114,8 +111,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Chalice of Life", 471, Rarity.UNCOMMON, mage.cards.c.ChaliceOfLife.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Chandra, Dressed to Kill", 148, Rarity.MYTHIC, mage.cards.c.ChandraDressedToKill.class)); cards.add(new SetCardInfo("Chittering Host", "123b", Rarity.COMMON, mage.cards.c.ChitteringHost.class)); - cards.add(new SetCardInfo("Cipherbound Spirit", 459, Rarity.UNCOMMON, mage.cards.c.CipherboundSpirit.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Cipherbound Spirit", 85, Rarity.UNCOMMON, mage.cards.c.CipherboundSpirit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Clear Shot", 188, Rarity.UNCOMMON, mage.cards.c.ClearShot.class)); cards.add(new SetCardInfo("Cobbled Lancer", 56, Rarity.UNCOMMON, mage.cards.c.CobbledLancer.class)); cards.add(new SetCardInfo("Cobbled Wings", 258, Rarity.COMMON, mage.cards.c.CobbledWings.class)); @@ -185,8 +180,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Emrakul, the Promised End", 481, Rarity.MYTHIC, mage.cards.e.EmrakulThePromisedEnd.class, FULL_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Emrakul, the Promised End", 5, Rarity.MYTHIC, mage.cards.e.EmrakulThePromisedEnd.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Epitaph Golem", 262, Rarity.COMMON, mage.cards.e.EpitaphGolem.class)); - cards.add(new SetCardInfo("Erupting Dreadwolf", 171, Rarity.UNCOMMON, mage.cards.e.EruptingDreadwolf.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Erupting Dreadwolf", 465, Rarity.UNCOMMON, mage.cards.e.EruptingDreadwolf.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Essence Flux", 354, Rarity.COMMON, mage.cards.e.EssenceFlux.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Essence Flux", 64, Rarity.COMMON, mage.cards.e.EssenceFlux.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Evolving Wilds", 278, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); @@ -199,7 +192,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Fiend Hunter", 22, Rarity.UNCOMMON, mage.cards.f.FiendHunter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fiend Hunter", 340, Rarity.UNCOMMON, mage.cards.f.FiendHunter.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Fiery Temper", 154, Rarity.UNCOMMON, mage.cards.f.FieryTemper.class)); - cards.add(new SetCardInfo("Final Iteration", 62, Rarity.RARE, mage.cards.f.FinalIteration.class)); cards.add(new SetCardInfo("Fleshtaker", 235, Rarity.UNCOMMON, mage.cards.f.Fleshtaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fleshtaker", 429, Rarity.UNCOMMON, mage.cards.f.Fleshtaker.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Forbidden Alchemy", 355, Rarity.UNCOMMON, mage.cards.f.ForbiddenAlchemy.class, RETRO_ART_USE_VARIOUS)); @@ -264,9 +256,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Honeymoon Hearse", 159, Rarity.UNCOMMON, mage.cards.h.HoneymoonHearse.class)); cards.add(new SetCardInfo("Hopeful Initiate", 27, Rarity.RARE, mage.cards.h.HopefulInitiate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hopeful Initiate", 343, Rarity.RARE, mage.cards.h.HopefulInitiate.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Howling Chorus", 214, Rarity.UNCOMMON, mage.cards.h.HowlingChorus.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Howling Chorus", 469, Rarity.UNCOMMON, mage.cards.h.HowlingChorus.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Howlpack of Estwald", 224, Rarity.COMMON, mage.cards.h.HowlpackOfEstwald.class)); cards.add(new SetCardInfo("Howlpack Resurgence", 204, Rarity.UNCOMMON, mage.cards.h.HowlpackResurgence.class)); cards.add(new SetCardInfo("Hullbreaker Horror", 303, Rarity.RARE, mage.cards.h.HullbreakerHorror.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hullbreaker Horror", 357, Rarity.RARE, mage.cards.h.HullbreakerHorror.class, RETRO_ART_USE_VARIOUS)); @@ -277,8 +266,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Huntmaster of the Fells", 470, Rarity.RARE, mage.cards.h.HuntmasterOfTheFells.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Imprisoned in the Moon", 358, Rarity.COMMON, mage.cards.i.ImprisonedInTheMoon.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Imprisoned in the Moon", 69, Rarity.COMMON, mage.cards.i.ImprisonedInTheMoon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Incited Rabble", 451, Rarity.UNCOMMON, mage.cards.i.IncitedRabble.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Incited Rabble", 46, Rarity.UNCOMMON, mage.cards.i.IncitedRabble.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Indulgent Aristocrat", 118, Rarity.UNCOMMON, mage.cards.i.IndulgentAristocrat.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Indulgent Aristocrat", 384, Rarity.UNCOMMON, mage.cards.i.IndulgentAristocrat.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Infernal Grasp", 119, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class, NON_FULL_USE_VARIOUS)); @@ -340,10 +327,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Mist Raven", 76, Rarity.UNCOMMON, mage.cards.m.MistRaven.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Moldgraf Millipede", 208, Rarity.COMMON, mage.cards.m.MoldgrafMillipede.class)); cards.add(new SetCardInfo("Moonlight Hunt", 209, Rarity.UNCOMMON, mage.cards.m.MoonlightHunt.class)); - cards.add(new SetCardInfo("Moonrise Intruder", 179, Rarity.COMMON, mage.cards.m.MoonriseIntruder.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Moonrise Intruder", 466, Rarity.COMMON, mage.cards.m.MoonriseIntruder.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Moonscarred Werewolf", 212, Rarity.COMMON, mage.cards.m.MoonscarredWerewolf.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Moonscarred Werewolf", 468, Rarity.COMMON, mage.cards.m.MoonscarredWerewolf.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Morbid Opportunist", 124, Rarity.UNCOMMON, mage.cards.m.MorbidOpportunist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Morbid Opportunist", 388, Rarity.UNCOMMON, mage.cards.m.MorbidOpportunist.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Morkrut Banshee", 125, Rarity.UNCOMMON, mage.cards.m.MorkrutBanshee.class)); @@ -368,8 +351,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Olivia Voldaren", 246, Rarity.MYTHIC, mage.cards.o.OliviaVoldaren.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Olivia Voldaren", 490, Rarity.MYTHIC, mage.cards.o.OliviaVoldaren.class, FULL_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Olivia's Dragoon", 127, Rarity.COMMON, mage.cards.o.OliviasDragoon.class)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", 287, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", 474, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Overcharged Amalgam", 80, Rarity.RARE, mage.cards.o.OverchargedAmalgam.class)); cards.add(new SetCardInfo("Overgrown Farmland", 281, Rarity.RARE, mage.cards.o.OvergrownFarmland.class)); cards.add(new SetCardInfo("Pack Guardian", 211, Rarity.UNCOMMON, mage.cards.p.PackGuardian.class, NON_FULL_USE_VARIOUS)); @@ -493,8 +474,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Triskaidekaphobia", 391, Rarity.UNCOMMON, mage.cards.t.Triskaidekaphobia.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Twinblade Geist", 452, Rarity.UNCOMMON, mage.cards.t.TwinbladeGeist.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Twinblade Geist", 47, Rarity.UNCOMMON, mage.cards.t.TwinbladeGeist.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Twinblade Invocation", 452, Rarity.UNCOMMON, mage.cards.t.TwinbladeInvocation.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Twinblade Invocation", 47, Rarity.UNCOMMON, mage.cards.t.TwinbladeInvocation.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ulrich's Kindred", 176, Rarity.UNCOMMON, mage.cards.u.UlrichsKindred.class)); cards.add(new SetCardInfo("Ulvenwald Mysteries", 222, Rarity.UNCOMMON, mage.cards.u.UlvenwaldMysteries.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ulvenwald Mysteries", 423, Rarity.UNCOMMON, mage.cards.u.UlvenwaldMysteries.class, RETRO_ART_USE_VARIOUS)); @@ -523,8 +502,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Wandering Mind", 437, Rarity.UNCOMMON, mage.cards.w.WanderingMind.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Wedding Announcement", 453, Rarity.RARE, mage.cards.w.WeddingAnnouncement.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Wedding Announcement", 51, Rarity.RARE, mage.cards.w.WeddingAnnouncement.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wedding Festivity", 453, Rarity.RARE, mage.cards.w.WeddingFestivity.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Wedding Festivity", 51, Rarity.RARE, mage.cards.w.WeddingFestivity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Westvale Abbey", 287, Rarity.RARE, mage.cards.w.WestvaleAbbey.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Westvale Abbey", 474, Rarity.RARE, mage.cards.w.WestvaleAbbey.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Wild Hunger", 225, Rarity.UNCOMMON, mage.cards.w.WildHunger.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 71963129b6a..00048cbae25 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -47,7 +47,6 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); cards.add(new SetCardInfo("Atzocan Archer", 176, Rarity.UNCOMMON, mage.cards.a.AtzocanArcher.class)); cards.add(new SetCardInfo("Axis of Mortality", 3, Rarity.MYTHIC, mage.cards.a.AxisOfMortality.class)); - cards.add(new SetCardInfo("Azcanta, the Sunken Ruin", 74, Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); @@ -270,8 +269,6 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.COMMON, mage.cards.s.SpellPierce.class)); cards.add(new SetCardInfo("Spell Swindle", 82, Rarity.RARE, mage.cards.s.SpellSwindle.class)); cards.add(new SetCardInfo("Spike-Tailed Ceratops", 209, Rarity.COMMON, mage.cards.s.SpikeTailedCeratops.class)); - cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); - cards.add(new SetCardInfo("Spitfire Bastion", 173, Rarity.RARE, mage.cards.s.SpitfireBastion.class)); cards.add(new SetCardInfo("Spreading Rot", 125, Rarity.COMMON, mage.cards.s.SpreadingRot.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Steadfast Armasaur", 39, Rarity.UNCOMMON, mage.cards.s.SteadfastArmasaur.class)); @@ -303,7 +300,6 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); cards.add(new SetCardInfo("Tishana, Voice of Thunder", 230, Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); - cards.add(new SetCardInfo("Treasure Cove", 250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); cards.add(new SetCardInfo("Trove of Temptation", 171, Rarity.UNCOMMON, mage.cards.t.TroveOfTemptation.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); diff --git a/Mage.Sets/src/mage/sets/IxalanPromos.java b/Mage.Sets/src/mage/sets/IxalanPromos.java index 8b63ffa01c6..7f08fba3205 100644 --- a/Mage.Sets/src/mage/sets/IxalanPromos.java +++ b/Mage.Sets/src/mage/sets/IxalanPromos.java @@ -28,7 +28,6 @@ public class IxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Ashes of the Abhorrent", "2p", Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ashes of the Abhorrent", "2s", Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Axis of Mortality", "3s", Rarity.MYTHIC, mage.cards.a.AxisOfMortality.class)); - cards.add(new SetCardInfo("Azcanta, the Sunken Ruin", "74s", Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bishop of Rebirth", "5s", Rarity.RARE, mage.cards.b.BishopOfRebirth.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodcrazed Paladin", "93s", Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); @@ -113,8 +112,6 @@ public class IxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Sorcerous Spyglass", "248s", Rarity.RARE, mage.cards.s.SorcerousSpyglass.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spell Swindle", "82p", Rarity.RARE, mage.cards.s.SpellSwindle.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spell Swindle", "82s", Rarity.RARE, mage.cards.s.SpellSwindle.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Spires of Orazca", "249s", Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); - cards.add(new SetCardInfo("Spitfire Bastion", "173s", Rarity.RARE, mage.cards.s.SpitfireBastion.class)); cards.add(new SetCardInfo("Star of Extinction", "161p", Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Star of Extinction", "161s", Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sunbird's Invocation", "165p", Rarity.RARE, mage.cards.s.SunbirdsInvocation.class, NON_FULL_USE_VARIOUS)); @@ -128,7 +125,6 @@ public class IxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Tishana, Voice of Thunder", "230s", Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); cards.add(new SetCardInfo("Tocatli Honor Guard", "42p", Rarity.RARE, mage.cards.t.TocatliHonorGuard.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tocatli Honor Guard", "42s", Rarity.RARE, mage.cards.t.TocatliHonorGuard.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Treasure Cove", "250s", Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", "250s", Rarity.RARE, mage.cards.t.TreasureMap.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", "173s", Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); diff --git a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java index 899e568fce2..d22ade219c3 100644 --- a/Mage.Sets/src/mage/sets/JurassicWorldCollection.java +++ b/Mage.Sets/src/mage/sets/JurassicWorldCollection.java @@ -50,7 +50,6 @@ public final class JurassicWorldCollection extends ExpansionSet { cards.add(new SetCardInfo("Indoraptor, the Perfect Hybrid", 40, Rarity.RARE, mage.cards.i.IndoraptorThePerfectHybrid.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 22, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", "22b", Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); - cards.add(new SetCardInfo("Jurassic Park", 7, Rarity.RARE, mage.cards.j.JurassicPark.class)); cards.add(new SetCardInfo("Life Finds a Way", 31, Rarity.RARE, mage.cards.l.LifeFindsAWay.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Life Finds a Way", 5, Rarity.RARE, mage.cards.l.LifeFindsAWay.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 24, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java index 8fb66058d82..81e349639fa 100644 --- a/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java +++ b/Mage.Sets/src/mage/sets/KamigawaNeonDynasty.java @@ -48,13 +48,9 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Ambitious Assault", 133, Rarity.COMMON, mage.cards.a.AmbitiousAssault.class)); cards.add(new SetCardInfo("Ancestral Katana", 1, Rarity.COMMON, mage.cards.a.AncestralKatana.class)); cards.add(new SetCardInfo("Anchor to Reality", 45, Rarity.UNCOMMON, mage.cards.a.AnchorToReality.class)); - cards.add(new SetCardInfo("Animus of Night's Reach", 109, Rarity.UNCOMMON, mage.cards.a.AnimusOfNightsReach.class)); cards.add(new SetCardInfo("Ao, the Dawn Sky", 2, Rarity.MYTHIC, mage.cards.a.AoTheDawnSky.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ao, the Dawn Sky", 406, Rarity.MYTHIC, mage.cards.a.AoTheDawnSky.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ao, the Dawn Sky", 433, Rarity.MYTHIC, mage.cards.a.AoTheDawnSky.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Architect of Restoration", 34, Rarity.RARE, mage.cards.a.ArchitectOfRestoration.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Architect of Restoration", 354, Rarity.RARE, mage.cards.a.ArchitectOfRestoration.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Architect of Restoration", 442, Rarity.RARE, mage.cards.a.ArchitectOfRestoration.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Armguard Familiar", 46, Rarity.COMMON, mage.cards.a.ArmguardFamiliar.class)); cards.add(new SetCardInfo("Asari Captain", 215, Rarity.UNCOMMON, mage.cards.a.AsariCaptain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Asari Captain", 327, Rarity.UNCOMMON, mage.cards.a.AsariCaptain.class, NON_FULL_USE_VARIOUS)); @@ -118,18 +114,12 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Dokuchi Shadow-Walker", 94, Rarity.COMMON, mage.cards.d.DokuchiShadowWalker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dokuchi Silencer", 340, Rarity.UNCOMMON, mage.cards.d.DokuchiSilencer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dokuchi Silencer", 95, Rarity.UNCOMMON, mage.cards.d.DokuchiSilencer.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dragon-Kami's Egg", 181, Rarity.RARE, mage.cards.d.DragonKamisEgg.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dragon-Kami's Egg", 358, Rarity.RARE, mage.cards.d.DragonKamisEgg.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dragon-Kami's Egg", 473, Rarity.RARE, mage.cards.d.DragonKamisEgg.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dragonfly Suit", 9, Rarity.COMMON, mage.cards.d.DragonflySuit.class)); cards.add(new SetCardInfo("Dragonspark Reactor", 137, Rarity.UNCOMMON, mage.cards.d.DragonsparkReactor.class)); cards.add(new SetCardInfo("Dramatist's Puppet", 244, Rarity.COMMON, mage.cards.d.DramatistsPuppet.class)); cards.add(new SetCardInfo("Eater of Virtue", 245, Rarity.RARE, mage.cards.e.EaterOfVirtue.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Eater of Virtue", 401, Rarity.RARE, mage.cards.e.EaterOfVirtue.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Eater of Virtue", 496, Rarity.RARE, mage.cards.e.EaterOfVirtue.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Echo of Death's Wail", 124, Rarity.RARE, mage.cards.e.EchoOfDeathsWail.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Echo of Death's Wail", 356, Rarity.RARE, mage.cards.e.EchoOfDeathsWail.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Echo of Death's Wail", 462, Rarity.RARE, mage.cards.e.EchoOfDeathsWail.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ecologist's Terrarium", 246, Rarity.COMMON, mage.cards.e.EcologistsTerrarium.class)); cards.add(new SetCardInfo("Eiganjo Exemplar", 10, Rarity.COMMON, mage.cards.e.EiganjoExemplar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Eiganjo Exemplar", 309, Rarity.COMMON, mage.cards.e.EiganjoExemplar.class, NON_FULL_USE_VARIOUS)); @@ -166,7 +156,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Forest", 292, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 301, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_UST_VARIOUS)); cards.add(new SetCardInfo("Forest", 302, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_UST_VARIOUS)); - cards.add(new SetCardInfo("Fragment of Konda", 12, Rarity.UNCOMMON, mage.cards.f.FragmentOfKonda.class)); cards.add(new SetCardInfo("Futurist Operative", 333, Rarity.UNCOMMON, mage.cards.f.FuturistOperative.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Futurist Operative", 53, Rarity.UNCOMMON, mage.cards.f.FuturistOperative.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Futurist Sentinel", 54, Rarity.COMMON, mage.cards.f.FuturistSentinel.class)); @@ -283,9 +272,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Kappa Tech-Wrecker", 198, Rarity.UNCOMMON, mage.cards.k.KappaTechWrecker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kappa Tech-Wrecker", 348, Rarity.UNCOMMON, mage.cards.k.KappaTechWrecker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kindled Fury", 151, Rarity.COMMON, mage.cards.k.KindledFury.class)); - cards.add(new SetCardInfo("Kirin-Touched Orochi", 212, Rarity.RARE, mage.cards.k.KirinTouchedOrochi.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kirin-Touched Orochi", 360, Rarity.RARE, mage.cards.k.KirinTouchedOrochi.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kirin-Touched Orochi", 482, Rarity.RARE, mage.cards.k.KirinTouchedOrochi.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kitsune Ace", 22, Rarity.COMMON, mage.cards.k.KitsuneAce.class)); cards.add(new SetCardInfo("Kodama of the West Tree", 199, Rarity.MYTHIC, mage.cards.k.KodamaOfTheWestTree.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kodama of the West Tree", 392, Rarity.MYTHIC, mage.cards.k.KodamaOfTheWestTree.class, NON_FULL_USE_VARIOUS)); @@ -362,7 +348,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Mukotai Soulripper", 113, Rarity.RARE, mage.cards.m.MukotaiSoulripper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mukotai Soulripper", 381, Rarity.RARE, mage.cards.m.MukotaiSoulripper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mukotai Soulripper", 458, Rarity.RARE, mage.cards.m.MukotaiSoulripper.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Nameless Conqueror", 162, Rarity.COMMON, mage.cards.n.NamelessConqueror.class)); cards.add(new SetCardInfo("Naomi, Pillar of Order", 229, Rarity.UNCOMMON, mage.cards.n.NaomiPillarOfOrder.class)); cards.add(new SetCardInfo("Nashi, Moon Sage's Scion", 114, Rarity.MYTHIC, mage.cards.n.NashiMoonSagesScion.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nashi, Moon Sage's Scion", 343, Rarity.MYTHIC, mage.cards.n.NashiMoonSagesScion.class, NON_FULL_USE_VARIOUS)); @@ -377,9 +362,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Ninja's Kunai", 252, Rarity.COMMON, mage.cards.n.NinjasKunai.class)); cards.add(new SetCardInfo("Norika Yamazaki, the Poet", 31, Rarity.UNCOMMON, mage.cards.n.NorikaYamazakiThePoet.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Norika Yamazaki, the Poet", 311, Rarity.UNCOMMON, mage.cards.n.NorikaYamazakiThePoet.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("O-Kagachi Made Manifest", 227, Rarity.MYTHIC, mage.cards.o.OKagachiMadeManifest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("O-Kagachi Made Manifest", 362, Rarity.MYTHIC, mage.cards.o.OKagachiMadeManifest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("O-Kagachi Made Manifest", 489, Rarity.MYTHIC, mage.cards.o.OKagachiMadeManifest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ogre-Head Helm", 155, Rarity.RARE, mage.cards.o.OgreHeadHelm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ogre-Head Helm", 387, Rarity.RARE, mage.cards.o.OgreHeadHelm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ogre-Head Helm", 470, Rarity.RARE, mage.cards.o.OgreHeadHelm.class, NON_FULL_USE_VARIOUS)); @@ -448,7 +430,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Seismic Wave", 161, Rarity.UNCOMMON, mage.cards.s.SeismicWave.class)); cards.add(new SetCardInfo("Selfless Samurai", 312, Rarity.UNCOMMON, mage.cards.s.SelflessSamurai.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Selfless Samurai", 35, Rarity.UNCOMMON, mage.cards.s.SelflessSamurai.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Seshiro's Living Legacy", 210, Rarity.COMMON, mage.cards.s.SeshirosLivingLegacy.class)); cards.add(new SetCardInfo("Seven-Tail Mentor", 313, Rarity.COMMON, mage.cards.s.SevenTailMentor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Seven-Tail Mentor", 36, Rarity.COMMON, mage.cards.s.SevenTailMentor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Shigeki, Jukai Visionary", 206, Rarity.RARE, mage.cards.s.ShigekiJukaiVisionary.class, NON_FULL_USE_VARIOUS)); @@ -560,7 +541,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Unstoppable Ogre", 169, Rarity.COMMON, mage.cards.u.UnstoppableOgre.class)); cards.add(new SetCardInfo("Upriser Renegade", 170, Rarity.UNCOMMON, mage.cards.u.UpriserRenegade.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Upriser Renegade", 324, Rarity.UNCOMMON, mage.cards.u.UpriserRenegade.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vector Glider", 66, Rarity.COMMON, mage.cards.v.VectorGlider.class)); cards.add(new SetCardInfo("Virus Beetle", 128, Rarity.COMMON, mage.cards.v.VirusBeetle.class)); cards.add(new SetCardInfo("Voltage Surge", 171, Rarity.COMMON, mage.cards.v.VoltageSurge.class)); cards.add(new SetCardInfo("Walking Skyscraper", 263, Rarity.UNCOMMON, mage.cards.w.WalkingSkyscraper.class)); diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsed.java b/Mage.Sets/src/mage/sets/LorwynEclipsed.java index befe63c281e..80497f7960e 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -22,13 +22,17 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Ashling's Command", 205, Rarity.RARE, mage.cards.a.AshlingsCommand.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ashling's Command", 330, Rarity.RARE, mage.cards.a.AshlingsCommand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ashling, Rekindled", 124, Rarity.RARE, mage.cards.a.AshlingRekindled.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ashling, Rekindled", 290, Rarity.RARE, mage.cards.a.AshlingRekindled.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bitterbloom Bearer", 310, Rarity.MYTHIC, mage.cards.b.BitterbloomBearer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bitterbloom Bearer", 352, Rarity.MYTHIC, mage.cards.b.BitterbloomBearer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bitterbloom Bearer", 88, Rarity.MYTHIC, mage.cards.b.BitterbloomBearer.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Blood Crypt", "349b", Rarity.RARE, mage.cards.b.BloodCrypt.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Crypt", 262, Rarity.RARE, mage.cards.b.BloodCrypt.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Crypt", 349, Rarity.RARE, mage.cards.b.BloodCrypt.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deceit", 212, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deceit", 293, Rarity.MYTHIC, mage.cards.d.Deceit.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dose of Dawnglow", 100, Rarity.UNCOMMON, mage.cards.d.DoseOfDawnglow.class)); cards.add(new SetCardInfo("Eirdu, Carrier of Dawn", 13, Rarity.MYTHIC, mage.cards.e.EirduCarrierOfDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Eirdu, Carrier of Dawn", 286, Rarity.MYTHIC, mage.cards.e.EirduCarrierOfDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Emptiness", 222, Rarity.MYTHIC, mage.cards.e.Emptiness.class, NON_FULL_USE_VARIOUS)); @@ -37,21 +41,29 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Figure of Fable", 372, Rarity.RARE, mage.cards.f.FigureOfFable.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Formidable Speaker", 176, Rarity.RARE, mage.cards.f.FormidableSpeaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Formidable Speaker", 366, Rarity.RARE, mage.cards.f.FormidableSpeaker.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hallowed Fountain", "347b", Rarity.RARE, mage.cards.h.HallowedFountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hallowed Fountain", 265, Rarity.RARE, mage.cards.h.HallowedFountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hallowed Fountain", 347, Rarity.RARE, mage.cards.h.HallowedFountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("High Perfect Morcant", 229, Rarity.RARE, mage.cards.h.HighPerfectMorcant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("High Perfect Morcant", 373, Rarity.RARE, mage.cards.h.HighPerfectMorcant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Kirol, Attentive First-Year", 231, Rarity.RARE, mage.cards.k.KirolAttentiveFirstYear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Kirol, Attentive First-Year", 374, Rarity.RARE, mage.cards.k.KirolAttentiveFirstYear.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Morningtide's Light", 27, Rarity.MYTHIC, mage.cards.m.MorningtidesLight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Morningtide's Light", 301, Rarity.MYTHIC, mage.cards.m.MorningtidesLight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mutable Explorer", 186, Rarity.RARE, mage.cards.m.MutableExplorer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mutable Explorer", 327, Rarity.RARE, mage.cards.m.MutableExplorer.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Overgrown Tomb", "350b", Rarity.RARE, mage.cards.o.OvergrownTomb.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Overgrown Tomb", 266, Rarity.RARE, mage.cards.o.OvergrownTomb.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Overgrown Tomb", 350, Rarity.RARE, mage.cards.o.OvergrownTomb.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Perfect Intimidation", 115, Rarity.UNCOMMON, mage.cards.p.PerfectIntimidation.class)); + cards.add(new SetCardInfo("Steam Vents", "348b", Rarity.RARE, mage.cards.s.SteamVents.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Steam Vents", 267, Rarity.RARE, mage.cards.s.SteamVents.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Steam Vents", 348, Rarity.RARE, mage.cards.s.SteamVents.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sygg, Wanderbrine Shield", 288, Rarity.RARE, mage.cards.s.SyggWanderbrineShield.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sygg, Wanderbrine Shield", 76, Rarity.RARE, mage.cards.s.SyggWanderbrineShield.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sygg, Wanderwine Wisdom", 288, Rarity.RARE, mage.cards.s.SyggWanderwineWisdom.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sygg, Wanderwine Wisdom", 76, Rarity.RARE, mage.cards.s.SyggWanderwineWisdom.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Temple Garden", "351b", Rarity.RARE, mage.cards.t.TempleGarden.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Temple Garden", 268, Rarity.RARE, mage.cards.t.TempleGarden.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Temple Garden", 351, Rarity.RARE, mage.cards.t.TempleGarden.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Unexpected Assistance", 80, Rarity.COMMON, mage.cards.u.UnexpectedAssistance.class)); } } diff --git a/Mage.Sets/src/mage/sets/MagicOnlinePromos.java b/Mage.Sets/src/mage/sets/MagicOnlinePromos.java index 5cd3a661a05..a9be1013abe 100644 --- a/Mage.Sets/src/mage/sets/MagicOnlinePromos.java +++ b/Mage.Sets/src/mage/sets/MagicOnlinePromos.java @@ -139,7 +139,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Archfiend of Depravity", 55711, Rarity.RARE, mage.cards.a.ArchfiendOfDepravity.class)); cards.add(new SetCardInfo("Archfiend of Ifnir", 64422, Rarity.RARE, mage.cards.a.ArchfiendOfIfnir.class)); cards.add(new SetCardInfo("Archipelagore", 81005, Rarity.UNCOMMON, mage.cards.a.Archipelagore.class)); - cards.add(new SetCardInfo("Architect of Restoration", 97897, Rarity.RARE, mage.cards.a.ArchitectOfRestoration.class)); cards.add(new SetCardInfo("Archmage Emeritus", 90016, Rarity.RARE, mage.cards.a.ArchmageEmeritus.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Archmage Emeritus", 90018, Rarity.RARE, mage.cards.a.ArchmageEmeritus.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Archmage's Charm", 91233, Rarity.RARE, mage.cards.a.ArchmagesCharm.class, RETRO_ART)); @@ -174,7 +173,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Ashiok, Dream Render", 72259, Rarity.UNCOMMON, mage.cards.a.AshiokDreamRender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ashiok, Dream Render", 77993, Rarity.UNCOMMON, mage.cards.a.AshiokDreamRender.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ashiok, Nightmare Muse", 79847, Rarity.MYTHIC, mage.cards.a.AshiokNightmareMuse.class)); - cards.add(new SetCardInfo("Ashmouth Dragon", 94012, Rarity.RARE, mage.cards.a.AshmouthDragon.class)); cards.add(new SetCardInfo("Ashnod the Uncaring", 105806, Rarity.MYTHIC, mage.cards.a.AshnodTheUncaring.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ashnod the Uncaring", 105808, Rarity.MYTHIC, mage.cards.a.AshnodTheUncaring.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Ashnod, Flesh Mechanist", 105688, Rarity.RARE, mage.cards.a.AshnodFleshMechanist.class)); @@ -661,7 +659,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Dimir Guildmage", 32579, Rarity.UNCOMMON, mage.cards.d.DimirGuildmage.class)); cards.add(new SetCardInfo("Dimir Signet", 46924, Rarity.UNCOMMON, mage.cards.d.DimirSignet.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Dimir Signet", 62435, Rarity.COMMON, mage.cards.d.DimirSignet.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Dire-Strain Anarchist", 95397, Rarity.MYTHIC, mage.cards.d.DireStrainAnarchist.class)); cards.add(new SetCardInfo("Dire-Strain Rampage", 94070, Rarity.RARE, mage.cards.d.DireStrainRampage.class)); cards.add(new SetCardInfo("Diregraf Ghoul", 42882, Rarity.UNCOMMON, mage.cards.d.DiregrafGhoul.class)); cards.add(new SetCardInfo("Dirge Bat", 80935, Rarity.RARE, mage.cards.d.DirgeBat.class, NON_FULL_USE_VARIOUS)); @@ -706,7 +703,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Dragon Broodmother", 32553, Rarity.MYTHIC, mage.cards.d.DragonBroodmother.class)); cards.add(new SetCardInfo("Dragon Fodder", 55898, Rarity.COMMON, mage.cards.d.DragonFodder.class)); cards.add(new SetCardInfo("Dragon Throne of Tarkir", 54565, Rarity.RARE, mage.cards.d.DragonThroneOfTarkir.class)); - cards.add(new SetCardInfo("Dragon-Kami's Egg", 98051, Rarity.RARE, mage.cards.d.DragonKamisEgg.class)); cards.add(new SetCardInfo("Dragonkin Berserker", 88310, Rarity.RARE, mage.cards.d.DragonkinBerserker.class)); cards.add(new SetCardInfo("Dragonlord Dromoka", 102319, Rarity.MYTHIC, mage.cards.d.DragonlordDromoka.class)); cards.add(new SetCardInfo("Dragonlord's Servant", 55884, Rarity.UNCOMMON, mage.cards.d.DragonlordsServant.class)); @@ -752,7 +748,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Eater of Hope", 51918, Rarity.RARE, mage.cards.e.EaterOfHope.class)); cards.add(new SetCardInfo("Eater of Virtue", 98111, Rarity.RARE, mage.cards.e.EaterOfVirtue.class)); cards.add(new SetCardInfo("Ebondeath, Dracolich", 92692, Rarity.MYTHIC, mage.cards.e.EbondeathDracolich.class)); - cards.add(new SetCardInfo("Echo of Death's Wail", 97969, Rarity.RARE, mage.cards.e.EchoOfDeathsWail.class)); cards.add(new SetCardInfo("Echo of Eons", 95469, Rarity.RARE, mage.cards.e.EchoOfEons.class)); cards.add(new SetCardInfo("Ecological Appreciation", 90166, Rarity.MYTHIC, mage.cards.e.EcologicalAppreciation.class)); cards.add(new SetCardInfo("Eerie Ultimatum", 80895, Rarity.RARE, mage.cards.e.EerieUltimatum.class)); @@ -1457,7 +1452,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Kiora, Behemoth Beckoner", 78027, Rarity.UNCOMMON, mage.cards.k.KioraBehemothBeckoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kiora, the Crashing Wave", 59651, Rarity.MYTHIC, mage.cards.k.KioraTheCrashingWave.class)); cards.add(new SetCardInfo("Kird Ape", 31383, Rarity.UNCOMMON, mage.cards.k.KirdApe.class)); - cards.add(new SetCardInfo("Kirin-Touched Orochi", 98047, Rarity.RARE, mage.cards.k.KirinTouchedOrochi.class)); cards.add(new SetCardInfo("Kitchen Finks", 36166, Rarity.UNCOMMON, mage.cards.k.KitchenFinks.class)); cards.add(new SetCardInfo("Kiyomaro, First to Stand", 32015, Rarity.RARE, mage.cards.k.KiyomaroFirstToStand.class)); cards.add(new SetCardInfo("Kjeldoran Outpost", 23952, Rarity.RARE, mage.cards.k.KjeldoranOutpost.class, RETRO_ART_USE_VARIOUS)); @@ -1892,7 +1886,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Nymris, Oona's Trickster", 86342, Rarity.RARE, mage.cards.n.NymrisOonasTrickster.class)); cards.add(new SetCardInfo("Nyx Lotus", 79917, Rarity.RARE, mage.cards.n.NyxLotus.class)); cards.add(new SetCardInfo("Nyxbloom Ancient", 79965, Rarity.MYTHIC, mage.cards.n.NyxbloomAncient.class)); - cards.add(new SetCardInfo("O-Kagachi Made Manifest", 98101, Rarity.MYTHIC, mage.cards.o.OKagachiMadeManifest.class)); cards.add(new SetCardInfo("Oakhame Ranger", 78738, Rarity.UNCOMMON, mage.cards.o.OakhameRanger.class)); cards.add(new SetCardInfo("Oath of Druids", 36092, Rarity.RARE, mage.cards.o.OathOfDruids.class, RETRO_ART)); cards.add(new SetCardInfo("Ob Nixilis Reignited", 62509, Rarity.MYTHIC, mage.cards.o.ObNixilisReignited.class)); @@ -2896,7 +2889,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Uktabi Orangutan", 36016, Rarity.UNCOMMON, mage.cards.u.UktabiOrangutan.class, RETRO_ART)); cards.add(new SetCardInfo("Ulamog, the Infinite Gyre", 102345, Rarity.MYTHIC, mage.cards.u.UlamogTheInfiniteGyre.class)); cards.add(new SetCardInfo("Ultimate Price", 58269, Rarity.UNCOMMON, mage.cards.u.UltimatePrice.class)); - cards.add(new SetCardInfo("Ulvenwald Behemoth", 95421, Rarity.RARE, mage.cards.u.UlvenwaldBehemoth.class)); cards.add(new SetCardInfo("Ulvenwald Observer", 61553, Rarity.RARE, mage.cards.u.UlvenwaldObserver.class)); cards.add(new SetCardInfo("Ulvenwald Oddity", 95421, Rarity.RARE, mage.cards.u.UlvenwaldOddity.class)); cards.add(new SetCardInfo("Umezawa's Jitte", 36210, Rarity.RARE, mage.cards.u.UmezawasJitte.class)); @@ -3030,7 +3022,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Weathered Wayfarer", 102223, Rarity.RARE, mage.cards.w.WeatheredWayfarer.class)); cards.add(new SetCardInfo("Weaver of Harmony", 98031, Rarity.RARE, mage.cards.w.WeaverOfHarmony.class)); cards.add(new SetCardInfo("Wedding Announcement", 95267, Rarity.RARE, mage.cards.w.WeddingAnnouncement.class)); - cards.add(new SetCardInfo("Wedding Festivity", 95267, Rarity.RARE, mage.cards.w.WeddingFestivity.class)); cards.add(new SetCardInfo("Wee Dragonauts", 35174, Rarity.COMMON, mage.cards.w.WeeDragonauts.class)); cards.add(new SetCardInfo("Werewolf Pack Leader", 92760, Rarity.RARE, mage.cards.w.WerewolfPackLeader.class)); cards.add(new SetCardInfo("Wheel and Deal", 62411, Rarity.RARE, mage.cards.w.WheelAndDeal.class)); diff --git a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java index 9fa03ecb0f8..03bc2d1c727 100644 --- a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java +++ b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java @@ -83,7 +83,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Breach the Multiverse", 358, Rarity.RARE, mage.cards.b.BreachTheMultiverse.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Breach the Multiverse", 94, Rarity.RARE, mage.cards.b.BreachTheMultiverse.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Burning Sun's Fury", 133, Rarity.COMMON, mage.cards.b.BurningSunsFury.class)); - cards.add(new SetCardInfo("Burnished Dunestomper", 43, Rarity.COMMON, mage.cards.b.BurnishedDunestomper.class)); cards.add(new SetCardInfo("Captive Weird", 49, Rarity.UNCOMMON, mage.cards.c.CaptiveWeird.class)); cards.add(new SetCardInfo("Chandra, Hope's Beacon", 134, Rarity.MYTHIC, mage.cards.c.ChandraHopesBeacon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chandra, Hope's Beacon", 321, Rarity.MYTHIC, mage.cards.c.ChandraHopesBeacon.class, NON_FULL_USE_VARIOUS)); @@ -153,7 +152,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Furnace Gremlin", 139, Rarity.UNCOMMON, mage.cards.f.FurnaceGremlin.class)); cards.add(new SetCardInfo("Furnace Host Charger", 140, Rarity.COMMON, mage.cards.f.FurnaceHostCharger.class)); cards.add(new SetCardInfo("Furnace Reins", 141, Rarity.UNCOMMON, mage.cards.f.FurnaceReins.class)); - cards.add(new SetCardInfo("Furnace-Blessed Conqueror", 38, Rarity.UNCOMMON, mage.cards.f.FurnaceBlessedConqueror.class)); cards.add(new SetCardInfo("Furtive Analyst", 59, Rarity.COMMON, mage.cards.f.FurtiveAnalyst.class)); cards.add(new SetCardInfo("Ghalta and Mavren", 225, Rarity.RARE, mage.cards.g.GhaltaAndMavren.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ghalta and Mavren", 307, Rarity.RARE, mage.cards.g.GhaltaAndMavren.class, NON_FULL_USE_VARIOUS)); @@ -344,7 +342,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Seedpod Caretaker", 325, Rarity.UNCOMMON, mage.cards.s.SeedpodCaretaker.class)); cards.add(new SetCardInfo("Seer of Stolen Sight", 330, Rarity.UNCOMMON, mage.cards.s.SeerOfStolenSight.class)); cards.add(new SetCardInfo("Seraph of New Capenna", 36, Rarity.UNCOMMON, mage.cards.s.SeraphOfNewCapenna.class)); - cards.add(new SetCardInfo("Seraph of New Phyrexia", 36, Rarity.UNCOMMON, mage.cards.s.SeraphOfNewPhyrexia.class)); cards.add(new SetCardInfo("Serpent-Blade Assailant", 205, Rarity.COMMON, mage.cards.s.SerpentBladeAssailant.class)); cards.add(new SetCardInfo("Shatter the Source", 164, Rarity.COMMON, mage.cards.s.ShatterTheSource.class)); cards.add(new SetCardInfo("Sheoldred", 125, Rarity.MYTHIC, mage.cards.s.Sheoldred.class, NON_FULL_USE_VARIOUS)); @@ -354,7 +351,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Sigiled Sentinel", 37, Rarity.COMMON, mage.cards.s.SigiledSentinel.class)); cards.add(new SetCardInfo("Skittering Surveyor", 264, Rarity.COMMON, mage.cards.s.SkitteringSurveyor.class)); cards.add(new SetCardInfo("Skyclave Aerialist", 78, Rarity.UNCOMMON, mage.cards.s.SkyclaveAerialist.class)); - cards.add(new SetCardInfo("Skyclave Invader", 78, Rarity.UNCOMMON, mage.cards.s.SkyclaveInvader.class)); cards.add(new SetCardInfo("Stasis Field", 79, Rarity.COMMON, mage.cards.s.StasisField.class)); cards.add(new SetCardInfo("Stoke the Flames", 166, Rarity.UNCOMMON, mage.cards.s.StokeTheFlames.class)); cards.add(new SetCardInfo("Storm the Seedcore", 206, Rarity.UNCOMMON, mage.cards.s.StormTheSeedcore.class)); @@ -383,15 +379,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Terror of Towashi", 378, Rarity.RARE, mage.cards.t.TerrorOfTowashi.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thalia and The Gitrog Monster", 255, Rarity.MYTHIC, mage.cards.t.ThaliaAndTheGitrogMonster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thalia and The Gitrog Monster", 316, Rarity.MYTHIC, mage.cards.t.ThaliaAndTheGitrogMonster.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Grand Evolution", 213, Rarity.MYTHIC, mage.cards.t.TheGrandEvolution.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Grand Evolution", 301, Rarity.MYTHIC, mage.cards.t.TheGrandEvolution.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Grand Evolution", 342, Rarity.MYTHIC, mage.cards.t.TheGrandEvolution.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Great Work", 169, Rarity.MYTHIC, mage.cards.t.TheGreatWork.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Great Work", 299, Rarity.MYTHIC, mage.cards.t.TheGreatWork.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Great Work", 341, Rarity.MYTHIC, mage.cards.t.TheGreatWork.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The True Scriptures", 125, Rarity.MYTHIC, mage.cards.t.TheTrueScriptures.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The True Scriptures", 297, Rarity.MYTHIC, mage.cards.t.TheTrueScriptures.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The True Scriptures", 340, Rarity.MYTHIC, mage.cards.t.TheTrueScriptures.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thornwood Falls", 274, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class)); cards.add(new SetCardInfo("Thrashing Frontliner", 167, Rarity.COMMON, mage.cards.t.ThrashingFrontliner.class)); cards.add(new SetCardInfo("Thunderhead Squadron", 81, Rarity.COMMON, mage.cards.t.ThunderheadSquadron.class)); diff --git a/Mage.Sets/src/mage/sets/MarvelSuperHeroes.java b/Mage.Sets/src/mage/sets/MarvelSuperHeroes.java new file mode 100644 index 00000000000..dd95b3dd38f --- /dev/null +++ b/Mage.Sets/src/mage/sets/MarvelSuperHeroes.java @@ -0,0 +1,39 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class MarvelSuperHeroes extends ExpansionSet { + + private static final MarvelSuperHeroes instance = new MarvelSuperHeroes(); + + public static MarvelSuperHeroes getInstance() { + return instance; + } + + private MarvelSuperHeroes() { + super("Marvel Super Heroes", "MSH", ExpansionSet.buildDate(2026, 6, 26), SetType.EXPANSION); + this.blockName = "Marvel Super Heroes"; // for sorting in GUI + this.hasBasicLands = false; // temporary + + cards.add(new SetCardInfo("Attuma, Atlantean Warlord", 47, Rarity.UNCOMMON, mage.cards.a.AttumaAtlanteanWarlord.class)); + cards.add(new SetCardInfo("Bruce Banner", 390, Rarity.MYTHIC, mage.cards.b.BruceBanner.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bruce Banner", 49, Rarity.MYTHIC, mage.cards.b.BruceBanner.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Captain America, Super-Soldier", 387, Rarity.MYTHIC, mage.cards.c.CaptainAmericaSuperSoldier.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Captain America, Super-Soldier", 9, Rarity.MYTHIC, mage.cards.c.CaptainAmericaSuperSoldier.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Doctor Doom", 394, Rarity.MYTHIC, mage.cards.d.DoctorDoom.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Doctor Doom", 95, Rarity.MYTHIC, mage.cards.d.DoctorDoom.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Moon Girl and Devil Dinosaur", 223, Rarity.RARE, mage.cards.m.MoonGirlAndDevilDinosaur.class)); + cards.add(new SetCardInfo("Namor the Sub-Mariner", 391, Rarity.MYTHIC, mage.cards.n.NamorTheSubMariner.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Namor the Sub-Mariner", 69, Rarity.MYTHIC, mage.cards.n.NamorTheSubMariner.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Quicksilver, Brash Blur", 148, Rarity.RARE, mage.cards.q.QuicksilverBrashBlur.class)); + cards.add(new SetCardInfo("Super-Skrull", 115, Rarity.RARE, mage.cards.s.SuperSkrull.class)); + cards.add(new SetCardInfo("The Coming of Galactus", 212, Rarity.MYTHIC, mage.cards.t.TheComingOfGalactus.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("The Coming of Galactus", 307, Rarity.MYTHIC, mage.cards.t.TheComingOfGalactus.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("The Sentry, Golden Guardian", 35, Rarity.RARE, mage.cards.t.TheSentryGoldenGuardian.class)); + } +} diff --git a/Mage.Sets/src/mage/sets/MarvelSuperHeroesCommander.java b/Mage.Sets/src/mage/sets/MarvelSuperHeroesCommander.java new file mode 100644 index 00000000000..d66f0f251ce --- /dev/null +++ b/Mage.Sets/src/mage/sets/MarvelSuperHeroesCommander.java @@ -0,0 +1,28 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class MarvelSuperHeroesCommander extends ExpansionSet { + + private static final MarvelSuperHeroesCommander instance = new MarvelSuperHeroesCommander(); + + public static MarvelSuperHeroesCommander getInstance() { + return instance; + } + + private MarvelSuperHeroesCommander() { + super("Marvel Super Heroes Commander", "MSC", ExpansionSet.buildDate(2026, 6, 26), SetType.SUPPLEMENTAL); + this.blockName = "Marvel Super Heroes"; // for sorting in GUI + this.hasBasicLands = false; // temporary + + cards.add(new SetCardInfo("Human Torch", 3, Rarity.MYTHIC, mage.cards.h.HumanTorch.class)); + cards.add(new SetCardInfo("Invisible Woman", 1, Rarity.MYTHIC, mage.cards.i.InvisibleWoman.class)); + cards.add(new SetCardInfo("Mister Fantastic", 2, Rarity.MYTHIC, mage.cards.m.MisterFantastic.class)); + cards.add(new SetCardInfo("The Thing", 4, Rarity.MYTHIC, mage.cards.t.TheThing.class)); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3.java b/Mage.Sets/src/mage/sets/ModernHorizons3.java index 81aee2e1d69..57fe3560988 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons3.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons3.java @@ -213,9 +213,6 @@ public final class ModernHorizons3 extends ExpansionSet { cards.add(new SetCardInfo("Gravedig", 96, Rarity.COMMON, mage.cards.g.Gravedig.class)); cards.add(new SetCardInfo("Grim Servant", 97, Rarity.UNCOMMON, mage.cards.g.GrimServant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grim Servant", 409, Rarity.UNCOMMON, mage.cards.g.GrimServant.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Grist, the Plague Swarm", 251, Rarity.MYTHIC, mage.cards.g.GristThePlagueSwarm.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Grist, the Plague Swarm", 446, Rarity.MYTHIC, mage.cards.g.GristThePlagueSwarm.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Grist, the Plague Swarm", 472, Rarity.MYTHIC, mage.cards.g.GristThePlagueSwarm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grist, Voracious Larva", 251, Rarity.MYTHIC, mage.cards.g.GristVoraciousLarva.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grist, Voracious Larva", 446, Rarity.MYTHIC, mage.cards.g.GristVoraciousLarva.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grist, Voracious Larva", 472, Rarity.MYTHIC, mage.cards.g.GristVoraciousLarva.class, NON_FULL_USE_VARIOUS)); @@ -381,9 +378,6 @@ public final class ModernHorizons3 extends ExpansionSet { cards.add(new SetCardInfo("Pyretic Rebirth", 200, Rarity.UNCOMMON, mage.cards.p.PyreticRebirth.class)); cards.add(new SetCardInfo("Quest for the Necropolis", 104, Rarity.UNCOMMON, mage.cards.q.QuestForTheNecropolis.class)); cards.add(new SetCardInfo("Ral and the Implicit Maze", 132, Rarity.UNCOMMON, mage.cards.r.RalAndTheImplicitMaze.class)); - cards.add(new SetCardInfo("Ral, Leyline Prodigy", 247, Rarity.MYTHIC, mage.cards.r.RalLeylineProdigy.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ral, Leyline Prodigy", 445, Rarity.MYTHIC, mage.cards.r.RalLeylineProdigy.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ral, Leyline Prodigy", 471, Rarity.MYTHIC, mage.cards.r.RalLeylineProdigy.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ral, Monsoon Mage", 247, Rarity.MYTHIC, mage.cards.r.RalMonsoonMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ral, Monsoon Mage", 445, Rarity.MYTHIC, mage.cards.r.RalMonsoonMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ral, Monsoon Mage", 471, Rarity.MYTHIC, mage.cards.r.RalMonsoonMage.class, NON_FULL_USE_VARIOUS)); @@ -452,9 +446,6 @@ public final class ModernHorizons3 extends ExpansionSet { cards.add(new SetCardInfo("Sorin of House Markov", 245, Rarity.MYTHIC, mage.cards.s.SorinOfHouseMarkov.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sorin of House Markov", 444, Rarity.MYTHIC, mage.cards.s.SorinOfHouseMarkov.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sorin of House Markov", 470, Rarity.MYTHIC, mage.cards.s.SorinOfHouseMarkov.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sorin, Ravenous Neonate", 245, Rarity.MYTHIC, mage.cards.s.SorinRavenousNeonate.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sorin, Ravenous Neonate", 444, Rarity.MYTHIC, mage.cards.s.SorinRavenousNeonate.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sorin, Ravenous Neonate", 470, Rarity.MYTHIC, mage.cards.s.SorinRavenousNeonate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sowing Mycospawn", 170, Rarity.RARE, mage.cards.s.SowingMycospawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sowing Mycospawn", 340, Rarity.RARE, mage.cards.s.SowingMycospawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Spawn-Gang Commander", 140, Rarity.UNCOMMON, mage.cards.s.SpawnGangCommander.class)); diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java index a978c5e2fe7..03e984070f9 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java @@ -229,7 +229,6 @@ public final class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Twilight Prophet", 88, Rarity.MYTHIC, mage.cards.t.TwilightProphet.class)); cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class)); cards.add(new SetCardInfo("Vampire Revenant", 89, Rarity.COMMON, mage.cards.v.VampireRevenant.class)); - cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class)); cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class)); cards.add(new SetCardInfo("Voracious Vampire", 91, Rarity.COMMON, mage.cards.v.VoraciousVampire.class)); cards.add(new SetCardInfo("Vraska, Scheming Gorgon", 197, Rarity.MYTHIC, mage.cards.v.VraskaSchemingGorgon.class)); diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java b/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java index 11f54859518..b4271b59ac6 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java @@ -103,7 +103,6 @@ public class RivalsOfIxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Tomb Robber", "87s", Rarity.RARE, mage.cards.t.TombRobber.class)); cards.add(new SetCardInfo("Trapjaw Tyrant", "29s", Rarity.MYTHIC, mage.cards.t.TrapjawTyrant.class)); cards.add(new SetCardInfo("Twilight Prophet", "88s", Rarity.MYTHIC, mage.cards.t.TwilightProphet.class)); - cards.add(new SetCardInfo("Vault of Catlacan", "173s", Rarity.RARE, mage.cards.v.VaultOfCatlacan.class)); cards.add(new SetCardInfo("Vona's Hunger", "90p", Rarity.RARE, mage.cards.v.VonasHunger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vona's Hunger", "90s", Rarity.RARE, mage.cards.v.VonasHunger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Warkite Marauder", "60p", Rarity.RARE, mage.cards.w.WarkiteMarauder.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/SecretLairDrop.java b/Mage.Sets/src/mage/sets/SecretLairDrop.java index 7215d18d4eb..4fc7205f1d3 100644 --- a/Mage.Sets/src/mage/sets/SecretLairDrop.java +++ b/Mage.Sets/src/mage/sets/SecretLairDrop.java @@ -1062,7 +1062,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Bloodline Keeper", 1157, Rarity.RARE, mage.cards.b.BloodlineKeeper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nicol Bolas, the Ravager", 1158, Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Westvale Abbey", 1159, Rarity.RARE, mage.cards.w.WestvaleAbbey.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", 1159, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Emrakul, the Promised End", 1160, Rarity.MYTHIC, mage.cards.e.EmrakulThePromisedEnd.class)); cards.add(new SetCardInfo("Serra Angel", 1161, Rarity.RARE, mage.cards.s.SerraAngel.class)); cards.add(new SetCardInfo("Brainstorm", 1162, Rarity.RARE, mage.cards.b.Brainstorm.class, NON_FULL_USE_VARIOUS)); @@ -1116,7 +1115,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Bloodline Keeper", 1210, Rarity.RARE, mage.cards.b.BloodlineKeeper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nicol Bolas, the Ravager", 1211, Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Westvale Abbey", 1212, Rarity.RARE, mage.cards.w.WestvaleAbbey.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", 1212, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian Unlife", 1213, Rarity.RARE, mage.cards.p.PhyrexianUnlife.class)); cards.add(new SetCardInfo("Phyrexian Crusader", 1214, Rarity.RARE, mage.cards.p.PhyrexianCrusader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plague Engineer", 1215, Rarity.RARE, mage.cards.p.PlagueEngineer.class)); @@ -1146,7 +1144,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Evin, Waterdeep Opportunist", 1239, Rarity.RARE, mage.cards.e.EvinWaterdeepOpportunist.class)); cards.add(new SetCardInfo("Jurin, Leading the Charge", 1240, Rarity.RARE, mage.cards.j.JurinLeadingTheCharge.class)); cards.add(new SetCardInfo("Casal, Lurkwood Pathfinder", 1241, Rarity.RARE, mage.cards.c.CasalLurkwoodPathfinder.class)); - cards.add(new SetCardInfo("Casal, Pathbreaker Owlbear", 1241, Rarity.RARE, mage.cards.c.CasalPathbreakerOwlbear.class)); cards.add(new SetCardInfo("Bohn, Beguiling Balladeer", 1242, Rarity.RARE, mage.cards.b.BohnBeguilingBalladeer.class)); cards.add(new SetCardInfo("Ugin, the Ineffable", 1243, Rarity.RARE, mage.cards.u.UginTheIneffable.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sorin, Imperious Bloodlord", 1244, Rarity.MYTHIC, mage.cards.s.SorinImperiousBloodlord.class)); @@ -1461,7 +1458,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Time Stop", "1500*", Rarity.RARE, mage.cards.t.TimeStop.class, FULL_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Lara Croft, Tomb Raider", 1501, Rarity.MYTHIC, mage.cards.l.LaraCroftTombRaider.class)); cards.add(new SetCardInfo("Search for Azcanta", 1502, Rarity.RARE, mage.cards.s.SearchForAzcanta.class)); - cards.add(new SetCardInfo("Azcanta, the Sunken Ruin", 1502, Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); cards.add(new SetCardInfo("Anger of the Gods", 1503, Rarity.RARE, mage.cards.a.AngerOfTheGods.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bow of Nylea", 1504, Rarity.RARE, mage.cards.b.BowOfNylea.class)); cards.add(new SetCardInfo("Shadowspear", 1505, Rarity.RARE, mage.cards.s.Shadowspear.class)); @@ -1607,7 +1603,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Howl of the Night Pack", 1610, Rarity.RARE, mage.cards.h.HowlOfTheNightPack.class)); cards.add(new SetCardInfo("Second Harvest", 1611, Rarity.RARE, mage.cards.s.SecondHarvest.class)); cards.add(new SetCardInfo("Tovolar, Dire Overlord", 1612, Rarity.RARE, mage.cards.t.TovolarDireOverlord.class)); - cards.add(new SetCardInfo("Tovolar, the Midnight Scourge", 1612, Rarity.RARE, mage.cards.t.TovolarTheMidnightScourge.class)); cards.add(new SetCardInfo("Brash Taunter", 1614, Rarity.RARE, mage.cards.b.BrashTaunter.class)); cards.add(new SetCardInfo("Goblin Chieftain", 1615, Rarity.RARE, mage.cards.g.GoblinChieftain.class)); cards.add(new SetCardInfo("Goblin Ringleader", 1616, Rarity.RARE, mage.cards.g.GoblinRingleader.class)); diff --git a/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java b/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java index 371b1ae3e8c..f475231ccc2 100644 --- a/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java +++ b/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java @@ -53,7 +53,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Autumnal Gloom", 194, Rarity.UNCOMMON, mage.cards.a.AutumnalGloom.class)); cards.add(new SetCardInfo("Avacyn's Judgment", 145, Rarity.RARE, mage.cards.a.AvacynsJudgment.class)); cards.add(new SetCardInfo("Avacynian Missionaries", 6, Rarity.UNCOMMON, mage.cards.a.AvacynianMissionaries.class)); - cards.add(new SetCardInfo("Awoken Horror", 92, Rarity.RARE, mage.cards.a.AwokenHorror.class)); cards.add(new SetCardInfo("Behind the Scenes", 100, Rarity.UNCOMMON, mage.cards.b.BehindTheScenes.class)); cards.add(new SetCardInfo("Behold the Beyond", 101, Rarity.MYTHIC, mage.cards.b.BeholdTheBeyond.class)); cards.add(new SetCardInfo("Biting Rain", 102, Rarity.UNCOMMON, mage.cards.b.BitingRain.class)); @@ -162,7 +161,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Howlpack Wolf", 164, Rarity.COMMON, mage.cards.h.HowlpackWolf.class)); cards.add(new SetCardInfo("Hulking Devil", 165, Rarity.COMMON, mage.cards.h.HulkingDevil.class)); cards.add(new SetCardInfo("Humble the Brute", 23, Rarity.UNCOMMON, mage.cards.h.HumbleTheBrute.class)); - cards.add(new SetCardInfo("Incited Rabble", 46, Rarity.UNCOMMON, mage.cards.i.IncitedRabble.class)); cards.add(new SetCardInfo("Incorrigible Youths", 166, Rarity.UNCOMMON, mage.cards.i.IncorrigibleYouths.class)); cards.add(new SetCardInfo("Indulgent Aristocrat", 118, Rarity.UNCOMMON, mage.cards.i.IndulgentAristocrat.class)); cards.add(new SetCardInfo("Inexorable Blob", 212, Rarity.RARE, mage.cards.i.InexorableBlob.class)); @@ -200,7 +198,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Mindwrack Demon", 124, Rarity.MYTHIC, mage.cards.m.MindwrackDemon.class)); cards.add(new SetCardInfo("Moldgraf Scavenger", 218, Rarity.COMMON, mage.cards.m.MoldgrafScavenger.class)); cards.add(new SetCardInfo("Moonlight Hunt", 219, Rarity.UNCOMMON, mage.cards.m.MoonlightHunt.class)); - cards.add(new SetCardInfo("Moonrise Intruder", 190, Rarity.UNCOMMON, mage.cards.m.MoonriseIntruder.class)); cards.add(new SetCardInfo("Moorland Drifter", 27, Rarity.COMMON, mage.cards.m.MoorlandDrifter.class)); cards.add(new SetCardInfo("Morkrut Necropod", 125, Rarity.UNCOMMON, mage.cards.m.MorkrutNecropod.class)); cards.add(new SetCardInfo("Mountain", 292, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); @@ -220,10 +217,8 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Odric, Lunarch Marshal", 31, Rarity.RARE, mage.cards.o.OdricLunarchMarshal.class)); cards.add(new SetCardInfo("Olivia's Bloodsworn", 127, Rarity.UNCOMMON, mage.cards.o.OliviasBloodsworn.class)); cards.add(new SetCardInfo("Olivia, Mobilized for War", 248, Rarity.MYTHIC, mage.cards.o.OliviaMobilizedForWar.class)); - cards.add(new SetCardInfo("One of the Pack", 229, Rarity.COMMON, mage.cards.o.OneOfThePack.class)); cards.add(new SetCardInfo("Ongoing Investigation", 77, Rarity.UNCOMMON, mage.cards.o.OngoingInvestigation.class)); cards.add(new SetCardInfo("Open the Armory", 32, Rarity.UNCOMMON, mage.cards.o.OpenTheArmory.class)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", 281, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class)); cards.add(new SetCardInfo("Pack Guardian", 221, Rarity.UNCOMMON, mage.cards.p.PackGuardian.class)); cards.add(new SetCardInfo("Pale Rider of Trostad", 128, Rarity.UNCOMMON, mage.cards.p.PaleRiderOfTrostad.class)); cards.add(new SetCardInfo("Paranoid Parish-Blade", 33, Rarity.UNCOMMON, mage.cards.p.ParanoidParishBlade.class)); @@ -272,7 +267,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Sinister Concoction", 135, Rarity.UNCOMMON, mage.cards.s.SinisterConcoction.class)); cards.add(new SetCardInfo("Skeleton Key", 263, Rarity.UNCOMMON, mage.cards.s.SkeletonKey.class)); cards.add(new SetCardInfo("Skin Invasion", 182, Rarity.UNCOMMON, mage.cards.s.SkinInvasion.class)); - cards.add(new SetCardInfo("Skin Shedder", 182, Rarity.UNCOMMON, mage.cards.s.SkinShedder.class)); cards.add(new SetCardInfo("Slayer's Plate", 264, Rarity.RARE, mage.cards.s.SlayersPlate.class)); cards.add(new SetCardInfo("Sleep Paralysis", 87, Rarity.COMMON, mage.cards.s.SleepParalysis.class)); cards.add(new SetCardInfo("Solitary Hunter", 229, Rarity.COMMON, mage.cards.s.SolitaryHunter.class)); @@ -288,7 +282,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Stitchwing Skaab", 90, Rarity.UNCOMMON, mage.cards.s.StitchwingSkaab.class)); cards.add(new SetCardInfo("Stoic Builder", 231, Rarity.COMMON, mage.cards.s.StoicBuilder.class)); cards.add(new SetCardInfo("Stone Quarry", 279, Rarity.UNCOMMON, mage.cards.s.StoneQuarry.class)); - cards.add(new SetCardInfo("Stonewing Antagonizer", 266, Rarity.UNCOMMON, mage.cards.s.StonewingAntagonizer.class)); cards.add(new SetCardInfo("Stormrider Spirit", 91, Rarity.COMMON, mage.cards.s.StormriderSpirit.class)); cards.add(new SetCardInfo("Strength of Arms", 40, Rarity.COMMON, mage.cards.s.StrengthOfArms.class)); cards.add(new SetCardInfo("Stromkirk Mentor", 137, Rarity.COMMON, mage.cards.s.StromkirkMentor.class)); @@ -341,7 +334,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Watcher in the Web", 239, Rarity.COMMON, mage.cards.w.WatcherInTheWeb.class)); cards.add(new SetCardInfo("Weirding Wood", 240, Rarity.UNCOMMON, mage.cards.w.WeirdingWood.class)); cards.add(new SetCardInfo("Welcome to the Fold", 96, Rarity.RARE, mage.cards.w.WelcomeToTheFold.class)); - cards.add(new SetCardInfo("Werewolf of Ancient Hunger", 225, Rarity.RARE, mage.cards.w.WerewolfOfAncientHunger.class)); cards.add(new SetCardInfo("Westvale Abbey", 281, Rarity.RARE, mage.cards.w.WestvaleAbbey.class)); cards.add(new SetCardInfo("Wicker Witch", 268, Rarity.COMMON, mage.cards.w.WickerWitch.class)); cards.add(new SetCardInfo("Wild-Field Scarecrow", 269, Rarity.UNCOMMON, mage.cards.w.WildFieldScarecrow.class)); diff --git a/Mage.Sets/src/mage/sets/ShadowsOverInnistradPromos.java b/Mage.Sets/src/mage/sets/ShadowsOverInnistradPromos.java index 6072500d9ab..02d295c4b5e 100644 --- a/Mage.Sets/src/mage/sets/ShadowsOverInnistradPromos.java +++ b/Mage.Sets/src/mage/sets/ShadowsOverInnistradPromos.java @@ -31,7 +31,6 @@ public class ShadowsOverInnistradPromos extends ExpansionSet { cards.add(new SetCardInfo("Arlinn Kord", "243s", Rarity.MYTHIC, mage.cards.a.ArlinnKord.class)); cards.add(new SetCardInfo("Asylum Visitor", "99s", Rarity.RARE, mage.cards.a.AsylumVisitor.class)); cards.add(new SetCardInfo("Avacyn's Judgment", "145s", Rarity.RARE, mage.cards.a.AvacynsJudgment.class)); - cards.add(new SetCardInfo("Awoken Horror", "92s", Rarity.RARE, mage.cards.a.AwokenHorror.class)); cards.add(new SetCardInfo("Behold the Beyond", "101s", Rarity.MYTHIC, mage.cards.b.BeholdTheBeyond.class)); cards.add(new SetCardInfo("Brain in a Jar", "252s", Rarity.RARE, mage.cards.b.BrainInAJar.class)); cards.add(new SetCardInfo("Burn from Within", "148s", Rarity.RARE, mage.cards.b.BurnFromWithin.class)); @@ -81,7 +80,6 @@ public class ShadowsOverInnistradPromos extends ExpansionSet { cards.add(new SetCardInfo("Nephalia Moondrakes", 75, Rarity.RARE, mage.cards.n.NephaliaMoondrakes.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Odric, Lunarch Marshal", "31s", Rarity.RARE, mage.cards.o.OdricLunarchMarshal.class)); cards.add(new SetCardInfo("Olivia, Mobilized for War", "248s", Rarity.MYTHIC, mage.cards.o.OliviaMobilizedForWar.class)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", "281s", Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class)); cards.add(new SetCardInfo("Port Town", "278s", Rarity.RARE, mage.cards.p.PortTown.class)); cards.add(new SetCardInfo("Prized Amalgam", "249s", Rarity.RARE, mage.cards.p.PrizedAmalgam.class)); cards.add(new SetCardInfo("Rattlechains", "81s", Rarity.RARE, mage.cards.r.Rattlechains.class)); @@ -110,7 +108,6 @@ public class ShadowsOverInnistradPromos extends ExpansionSet { cards.add(new SetCardInfo("Triskaidekaphobia", "141s", Rarity.RARE, mage.cards.t.Triskaidekaphobia.class)); cards.add(new SetCardInfo("Ulvenwald Hydra", "235s", Rarity.MYTHIC, mage.cards.u.UlvenwaldHydra.class)); cards.add(new SetCardInfo("Welcome to the Fold", "96s", Rarity.RARE, mage.cards.w.WelcomeToTheFold.class)); - cards.add(new SetCardInfo("Werewolf of Ancient Hunger", "225s", Rarity.RARE, mage.cards.w.WerewolfOfAncientHunger.class)); cards.add(new SetCardInfo("Westvale Abbey", "281s", Rarity.RARE, mage.cards.w.WestvaleAbbey.class)); cards.add(new SetCardInfo("Wolf of Devil's Breach", "192s", Rarity.MYTHIC, mage.cards.w.WolfOfDevilsBreach.class)); } diff --git a/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java b/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java index 1ba96211e95..beae6f1be95 100644 --- a/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java +++ b/Mage.Sets/src/mage/sets/ShadowsOverInnistradRemastered.java @@ -25,7 +25,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { // TODO: implement special slot with x1 card from SIS - Shadows of the Past // https://mtg.fandom.com/wiki/Shadows_over_Innistrad_Remastered/Shadows_of_the_Past - cards.add(new SetCardInfo("Abolisher of Bloodlines", 138, Rarity.RARE, mage.cards.a.AbolisherOfBloodlines.class)); cards.add(new SetCardInfo("Abundant Maw", 1, Rarity.UNCOMMON, mage.cards.a.AbundantMaw.class)); cards.add(new SetCardInfo("Accursed Witch", 97, Rarity.UNCOMMON, mage.cards.a.AccursedWitch.class)); cards.add(new SetCardInfo("Advanced Stitchwing", 54, Rarity.UNCOMMON, mage.cards.a.AdvancedStitchwing.class)); @@ -41,7 +40,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Arlinn Kord", 230, Rarity.MYTHIC, mage.cards.a.ArlinnKord.class)); cards.add(new SetCardInfo("Assembled Alphas", 141, Rarity.RARE, mage.cards.a.AssembledAlphas.class)); cards.add(new SetCardInfo("Avacyn's Judgment", 142, Rarity.RARE, mage.cards.a.AvacynsJudgment.class)); - cards.add(new SetCardInfo("Awoken Horror", 95, Rarity.RARE, mage.cards.a.AwokenHorror.class)); cards.add(new SetCardInfo("Bedlam Reveler", 143, Rarity.RARE, mage.cards.b.BedlamReveler.class)); cards.add(new SetCardInfo("Biting Rain", 99, Rarity.UNCOMMON, mage.cards.b.BitingRain.class)); cards.add(new SetCardInfo("Blessed Alliance", 14, Rarity.UNCOMMON, mage.cards.b.BlessedAlliance.class)); @@ -121,7 +119,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Field Creeper", 251, Rarity.COMMON, mage.cards.f.FieldCreeper.class)); cards.add(new SetCardInfo("Fiend Binder", 29, Rarity.COMMON, mage.cards.f.FiendBinder.class)); cards.add(new SetCardInfo("Fiery Temper", 154, Rarity.UNCOMMON, mage.cards.f.FieryTemper.class)); - cards.add(new SetCardInfo("Final Iteration", 61, Rarity.RARE, mage.cards.f.FinalIteration.class)); cards.add(new SetCardInfo("Flameblade Angel", 155, Rarity.RARE, mage.cards.f.FlamebladeAngel.class)); cards.add(new SetCardInfo("Fleeting Memories", 69, Rarity.UNCOMMON, mage.cards.f.FleetingMemories.class)); cards.add(new SetCardInfo("Fogwalker", 70, Rarity.COMMON, mage.cards.f.Fogwalker.class)); @@ -167,13 +164,11 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Highland Lake", 272, Rarity.UNCOMMON, mage.cards.h.HighlandLake.class)); cards.add(new SetCardInfo("Hinterland Logger", 201, Rarity.COMMON, mage.cards.h.HinterlandLogger.class)); cards.add(new SetCardInfo("Hope Against Hope", 33, Rarity.UNCOMMON, mage.cards.h.HopeAgainstHope.class)); - cards.add(new SetCardInfo("Howling Chorus", 214, Rarity.UNCOMMON, mage.cards.h.HowlingChorus.class)); cards.add(new SetCardInfo("Howlpack Resurgence", 202, Rarity.UNCOMMON, mage.cards.h.HowlpackResurgence.class)); cards.add(new SetCardInfo("Howlpack Wolf", 162, Rarity.COMMON, mage.cards.h.HowlpackWolf.class)); cards.add(new SetCardInfo("Humble the Brute", 34, Rarity.UNCOMMON, mage.cards.h.HumbleTheBrute.class)); cards.add(new SetCardInfo("Imprisoned in the Moon", 74, Rarity.COMMON, mage.cards.i.ImprisonedInTheMoon.class)); cards.add(new SetCardInfo("Incendiary Flow", 163, Rarity.COMMON, mage.cards.i.IncendiaryFlow.class)); - cards.add(new SetCardInfo("Incited Rabble", 53, Rarity.UNCOMMON, mage.cards.i.IncitedRabble.class)); cards.add(new SetCardInfo("Indulgent Aristocrat", 118, Rarity.UNCOMMON, mage.cards.i.IndulgentAristocrat.class)); cards.add(new SetCardInfo("Ingenious Skaab", 75, Rarity.COMMON, mage.cards.i.IngeniousSkaab.class)); cards.add(new SetCardInfo("Insatiable Gorgers", 164, Rarity.COMMON, mage.cards.i.InsatiableGorgers.class)); @@ -210,7 +205,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Mirrorwing Dragon", 170, Rarity.MYTHIC, mage.cards.m.MirrorwingDragon.class)); cards.add(new SetCardInfo("Mockery of Nature", 8, Rarity.UNCOMMON, mage.cards.m.MockeryOfNature.class)); cards.add(new SetCardInfo("Moonlight Hunt", 205, Rarity.COMMON, mage.cards.m.MoonlightHunt.class)); - cards.add(new SetCardInfo("Moonrise Intruder", 184, Rarity.UNCOMMON, mage.cards.m.MoonriseIntruder.class)); cards.add(new SetCardInfo("Morkrut Necropod", 125, Rarity.COMMON, mage.cards.m.MorkrutNecropod.class)); cards.add(new SetCardInfo("Mountain", 286, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 287, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); @@ -230,7 +224,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Olivia's Dragoon", 128, Rarity.COMMON, mage.cards.o.OliviasDragoon.class)); cards.add(new SetCardInfo("Olivia, Mobilized for War", 239, Rarity.MYTHIC, mage.cards.o.OliviaMobilizedForWar.class)); cards.add(new SetCardInfo("Ongoing Investigation", 84, Rarity.UNCOMMON, mage.cards.o.OngoingInvestigation.class)); - cards.add(new SetCardInfo("Ormendahl, Profane Prince", 275, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class)); cards.add(new SetCardInfo("Pack Guardian", 208, Rarity.UNCOMMON, mage.cards.p.PackGuardian.class)); cards.add(new SetCardInfo("Permeating Mass", 209, Rarity.RARE, mage.cards.p.PermeatingMass.class)); cards.add(new SetCardInfo("Pick the Brain", 129, Rarity.UNCOMMON, mage.cards.p.PickTheBrain.class)); @@ -310,8 +303,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("True-Faith Censer", 262, Rarity.COMMON, mage.cards.t.TrueFaithCenser.class)); cards.add(new SetCardInfo("Ulrich of the Krallenhorde", 246, Rarity.RARE, mage.cards.u.UlrichOfTheKrallenhorde.class)); cards.add(new SetCardInfo("Ulrich's Kindred", 182, Rarity.UNCOMMON, mage.cards.u.UlrichsKindred.class)); - cards.add(new SetCardInfo("Ulrich, Uncontested Alpha", 246, Rarity.RARE, mage.cards.u.UlrichUncontestedAlpha.class)); - cards.add(new SetCardInfo("Ulvenwald Abomination", 221, Rarity.COMMON, mage.cards.u.UlvenwaldAbomination.class)); cards.add(new SetCardInfo("Ulvenwald Captive", 221, Rarity.COMMON, mage.cards.u.UlvenwaldCaptive.class)); cards.add(new SetCardInfo("Ulvenwald Hydra", 222, Rarity.RARE, mage.cards.u.UlvenwaldHydra.class)); cards.add(new SetCardInfo("Ulvenwald Mysteries", 223, Rarity.UNCOMMON, mage.cards.u.UlvenwaldMysteries.class)); @@ -323,7 +314,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Voracious Reader", 58, Rarity.UNCOMMON, mage.cards.v.VoraciousReader.class)); cards.add(new SetCardInfo("Weirded Vampire", 139, Rarity.COMMON, mage.cards.w.WeirdedVampire.class)); cards.add(new SetCardInfo("Weirding Wood", 226, Rarity.COMMON, mage.cards.w.WeirdingWood.class)); - cards.add(new SetCardInfo("Werewolf of Ancient Hunger", 211, Rarity.RARE, mage.cards.w.WerewolfOfAncientHunger.class)); cards.add(new SetCardInfo("Westvale Abbey", 275, Rarity.RARE, mage.cards.w.WestvaleAbbey.class)); cards.add(new SetCardInfo("Wharf Infiltrator", 96, Rarity.RARE, mage.cards.w.WharfInfiltrator.class)); cards.add(new SetCardInfo("Wild-Field Scarecrow", 263, Rarity.COMMON, mage.cards.w.WildFieldScarecrow.class)); diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index 0b95a843d19..19c32dd560e 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java @@ -62,8 +62,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Another Chance", 90, Rarity.COMMON, mage.cards.a.AnotherChance.class)); cards.add(new SetCardInfo("Armored Kincaller", 174, Rarity.COMMON, mage.cards.a.ArmoredKincaller.class)); cards.add(new SetCardInfo("Attentive Sunscribe", 4, Rarity.COMMON, mage.cards.a.AttentiveSunscribe.class)); - cards.add(new SetCardInfo("Barracks of the Thousand", 357, Rarity.RARE, mage.cards.b.BarracksOfTheThousand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Barracks of the Thousand", 39, Rarity.RARE, mage.cards.b.BarracksOfTheThousand.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bartolome del Presidio", 224, Rarity.UNCOMMON, mage.cards.b.BartolomeDelPresidio.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bartolome del Presidio", 301, Rarity.UNCOMMON, mage.cards.b.BartolomeDelPresidio.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bartolome del Presidio", 409, Rarity.UNCOMMON, mage.cards.b.BartolomeDelPresidio.class, NON_FULL_USE_VARIOUS)); @@ -123,7 +121,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Colossadactyl", 180, Rarity.UNCOMMON, mage.cards.c.Colossadactyl.class)); cards.add(new SetCardInfo("Compass Gnome", 250, Rarity.COMMON, mage.cards.c.CompassGnome.class)); cards.add(new SetCardInfo("Confounding Riddle", 50, Rarity.UNCOMMON, mage.cards.c.ConfoundingRiddle.class)); - cards.add(new SetCardInfo("Consuming Sepulcher", 128, Rarity.COMMON, mage.cards.c.ConsumingSepulcher.class)); cards.add(new SetCardInfo("Contested Game Ball", 251, Rarity.UNCOMMON, mage.cards.c.ContestedGameBall.class)); cards.add(new SetCardInfo("Corpses of the Lost", 366, Rarity.RARE, mage.cards.c.CorpsesOfTheLost.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Corpses of the Lost", 98, Rarity.RARE, mage.cards.c.CorpsesOfTheLost.class, NON_FULL_USE_VARIOUS)); @@ -154,7 +151,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Disruptor Wanderglyph", 253, Rarity.COMMON, mage.cards.d.DisruptorWanderglyph.class)); cards.add(new SetCardInfo("Disturbed Slumber", 182, Rarity.COMMON, mage.cards.d.DisturbedSlumber.class)); cards.add(new SetCardInfo("Dowsing Device", 146, Rarity.UNCOMMON, mage.cards.d.DowsingDevice.class)); - cards.add(new SetCardInfo("Dread Osseosaur", 129, Rarity.UNCOMMON, mage.cards.d.DreadOsseosaur.class)); cards.add(new SetCardInfo("Dreadmaw's Ire", 147, Rarity.UNCOMMON, mage.cards.d.DreadmawsIre.class)); cards.add(new SetCardInfo("Dusk Rose Reliquary", 10, Rarity.UNCOMMON, mage.cards.d.DuskRoseReliquary.class)); cards.add(new SetCardInfo("Earthshaker Dreadmaw", 183, Rarity.UNCOMMON, mage.cards.e.EarthshakerDreadmaw.class, NON_FULL_USE_VARIOUS)); @@ -245,8 +241,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Kutzil's Flanker", 355, Rarity.RARE, mage.cards.k.KutzilsFlanker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kutzil, Malamet Exemplar", 232, Rarity.UNCOMMON, mage.cards.k.KutzilMalametExemplar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kutzil, Malamet Exemplar", 304, Rarity.UNCOMMON, mage.cards.k.KutzilMalametExemplar.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Locus of Enlightenment", 362, Rarity.MYTHIC, mage.cards.l.LocusOfEnlightenment.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Locus of Enlightenment", 55, Rarity.MYTHIC, mage.cards.l.LocusOfEnlightenment.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lodestone Needle", 62, Rarity.UNCOMMON, mage.cards.l.LodestoneNeedle.class)); cards.add(new SetCardInfo("Magmatic Galleon", 157, Rarity.RARE, mage.cards.m.MagmaticGalleon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Magmatic Galleon", 376, Rarity.RARE, mage.cards.m.MagmaticGalleon.class, NON_FULL_USE_VARIOUS)); @@ -261,7 +255,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Marauding Brinefang", 64, Rarity.COMMON, mage.cards.m.MaraudingBrinefang.class)); cards.add(new SetCardInfo("Market Gnome", 22, Rarity.UNCOMMON, mage.cards.m.MarketGnome.class)); cards.add(new SetCardInfo("Master's Guide-Mural", 233, Rarity.UNCOMMON, mage.cards.m.MastersGuideMural.class)); - cards.add(new SetCardInfo("Mastercraft Raptor", 164, Rarity.UNCOMMON, mage.cards.m.MastercraftRaptor.class)); cards.add(new SetCardInfo("Matzalantli, the Great Door", 256, Rarity.RARE, mage.cards.m.MatzalantliTheGreatDoor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Matzalantli, the Great Door", 387, Rarity.RARE, mage.cards.m.MatzalantliTheGreatDoor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mephitic Draught", 112, Rarity.COMMON, mage.cards.m.MephiticDraught.class)); @@ -275,7 +268,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 290, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_UST_VARIOUS)); cards.add(new SetCardInfo("Mountain", 399, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 400, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mycoid Maze", 217, Rarity.UNCOMMON, mage.cards.m.MycoidMaze.class)); cards.add(new SetCardInfo("Nicanzil, Current Conductor", 236, Rarity.UNCOMMON, mage.cards.n.NicanzilCurrentConductor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nicanzil, Current Conductor", 306, Rarity.UNCOMMON, mage.cards.n.NicanzilCurrentConductor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nurturing Bristleback", 203, Rarity.COMMON, mage.cards.n.NurturingBristleback.class)); @@ -348,8 +340,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Saheeli's Lattice", 164, Rarity.UNCOMMON, mage.cards.s.SaheelisLattice.class)); cards.add(new SetCardInfo("Saheeli, the Sun's Brilliance", 239, Rarity.MYTHIC, mage.cards.s.SaheeliTheSunsBrilliance.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Saheeli, the Sun's Brilliance", 308, Rarity.MYTHIC, mage.cards.s.SaheeliTheSunsBrilliance.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sandswirl Wanderglyph", 358, Rarity.RARE, mage.cards.s.SandswirlWanderglyph.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sandswirl Wanderglyph", 41, Rarity.RARE, mage.cards.s.SandswirlWanderglyph.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sanguine Evangelist", 34, Rarity.RARE, mage.cards.s.SanguineEvangelist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sanguine Evangelist", 356, Rarity.RARE, mage.cards.s.SanguineEvangelist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Scampering Surveyor", 260, Rarity.UNCOMMON, mage.cards.s.ScamperingSurveyor.class)); @@ -387,7 +377,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Stinging Cave Crawler", 124, Rarity.UNCOMMON, mage.cards.s.StingingCaveCrawler.class)); cards.add(new SetCardInfo("Subterranean Schooner", 365, Rarity.RARE, mage.cards.s.SubterraneanSchooner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Subterranean Schooner", 80, Rarity.RARE, mage.cards.s.SubterraneanSchooner.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sunbird Effigy", 262, Rarity.UNCOMMON, mage.cards.s.SunbirdEffigy.class)); cards.add(new SetCardInfo("Sunbird Standard", 262, Rarity.UNCOMMON, mage.cards.s.SunbirdStandard.class)); cards.add(new SetCardInfo("Sunfire Torch", 167, Rarity.COMMON, mage.cards.s.SunfireTorch.class)); cards.add(new SetCardInfo("Sunken Citadel", 285, Rarity.RARE, mage.cards.s.SunkenCitadel.class, NON_FULL_USE_VARIOUS)); @@ -414,18 +403,12 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("The Enigma Jewel", 55, Rarity.MYTHIC, mage.cards.t.TheEnigmaJewel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Everflowing Well", 363, Rarity.RARE, mage.cards.t.TheEverflowingWell.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Everflowing Well", 56, Rarity.RARE, mage.cards.t.TheEverflowingWell.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Grim Captain", 266, Rarity.RARE, mage.cards.t.TheGrimCaptain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Grim Captain", 313, Rarity.RARE, mage.cards.t.TheGrimCaptain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Millennium Calendar", 257, Rarity.MYTHIC, mage.cards.t.TheMillenniumCalendar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Millennium Calendar", 388, Rarity.MYTHIC, mage.cards.t.TheMillenniumCalendar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Mycotyrant", 235, Rarity.MYTHIC, mage.cards.t.TheMycotyrant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Mycotyrant", 305, Rarity.MYTHIC, mage.cards.t.TheMycotyrant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Myriad Pools", 363, Rarity.RARE, mage.cards.t.TheMyriadPools.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Myriad Pools", 56, Rarity.RARE, mage.cards.t.TheMyriadPools.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Skullspore Nexus", 212, Rarity.MYTHIC, mage.cards.t.TheSkullsporeNexus.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Skullspore Nexus", 340, Rarity.MYTHIC, mage.cards.t.TheSkullsporeNexus.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Tomb of Aclazotz", 126, Rarity.RARE, mage.cards.t.TheTombOfAclazotz.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Tomb of Aclazotz", 371, Rarity.RARE, mage.cards.t.TheTombOfAclazotz.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thousand Moons Crackshot", 37, Rarity.COMMON, mage.cards.t.ThousandMoonsCrackshot.class)); cards.add(new SetCardInfo("Thousand Moons Infantry", 38, Rarity.COMMON, mage.cards.t.ThousandMoonsInfantry.class)); cards.add(new SetCardInfo("Thousand Moons Smithy", 357, Rarity.RARE, mage.cards.t.ThousandMoonsSmithy.class, NON_FULL_USE_VARIOUS)); @@ -440,8 +423,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Tishana's Tidebinder", 335, Rarity.RARE, mage.cards.t.TishanasTidebinder.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tishana's Tidebinder", 81, Rarity.RARE, mage.cards.t.TishanasTidebinder.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tithing Blade", 128, Rarity.COMMON, mage.cards.t.TithingBlade.class)); - cards.add(new SetCardInfo("Treasure Cove", 267, Rarity.RARE, mage.cards.t.TreasureCove.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Treasure Cove", 391, Rarity.RARE, mage.cards.t.TreasureCove.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Treasure Map", 267, Rarity.RARE, mage.cards.t.TreasureMap.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Treasure Map", 391, Rarity.RARE, mage.cards.t.TreasureMap.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Triumphant Chomp", 170, Rarity.UNCOMMON, mage.cards.t.TriumphantChomp.class)); @@ -466,7 +447,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Warden of the Inner Sky", 359, Rarity.RARE, mage.cards.w.WardenOfTheInnerSky.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Warden of the Inner Sky", 43, Rarity.RARE, mage.cards.w.WardenOfTheInnerSky.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Waterlogged Hulk", 83, Rarity.UNCOMMON, mage.cards.w.WaterloggedHulk.class)); - cards.add(new SetCardInfo("Watertight Gondola", 83, Rarity.UNCOMMON, mage.cards.w.WatertightGondola.class)); cards.add(new SetCardInfo("Waterwind Scout", 84, Rarity.COMMON, mage.cards.w.WaterwindScout.class)); cards.add(new SetCardInfo("Waylaying Pirates", 85, Rarity.COMMON, mage.cards.w.WaylayingPirates.class)); cards.add(new SetCardInfo("Zoetic Glyph", 86, Rarity.UNCOMMON, mage.cards.z.ZoeticGlyph.class)); diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalanCommander.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalanCommander.java index 14f9f6d5b44..1fccd3b5ec5 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalanCommander.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalanCommander.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -84,7 +83,6 @@ public final class TheLostCavernsOfIxalanCommander extends ExpansionSet { cards.add(new SetCardInfo("Coralhelm Commander", 148, Rarity.RARE, mage.cards.c.CoralhelmCommander.class)); cards.add(new SetCardInfo("Cordial Vampire", 189, Rarity.RARE, mage.cards.c.CordialVampire.class)); cards.add(new SetCardInfo("Corsair Captain", 149, Rarity.RARE, mage.cards.c.CorsairCaptain.class)); - cards.add(new SetCardInfo("Cosmium Catalyst", 11, Rarity.RARE, mage.cards.c.CosmiumCatalyst.class)); cards.add(new SetCardInfo("Crossway Troublemakers", 190, Rarity.RARE, mage.cards.c.CrosswayTroublemakers.class)); cards.add(new SetCardInfo("Cruel Celebrant", 267, Rarity.UNCOMMON, mage.cards.c.CruelCelebrant.class)); cards.add(new SetCardInfo("Crumbling Necropolis", 326, Rarity.UNCOMMON, mage.cards.c.CrumblingNecropolis.class)); @@ -284,10 +282,8 @@ public final class TheLostCavernsOfIxalanCommander extends ExpansionSet { cards.add(new SetCardInfo("Terramorphic Expanse", 360, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); cards.add(new SetCardInfo("Tetzin, Gnome Champion", 13, Rarity.RARE, mage.cards.t.TetzinGnomeChampion.class)); cards.add(new SetCardInfo("Thassa, God of the Sea", 176, Rarity.MYTHIC, mage.cards.t.ThassaGodOfTheSea.class)); - cards.add(new SetCardInfo("The Golden-Gear Colossus", 13, Rarity.RARE, mage.cards.t.TheGoldenGearColossus.class)); cards.add(new SetCardInfo("The Indomitable", 43, Rarity.RARE, mage.cards.t.TheIndomitable.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Indomitable", 75, Rarity.RARE, mage.cards.t.TheIndomitable.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Grim Captain's Locker", 82, Rarity.RARE, mage.cards.t.TheGrimCaptainsLocker.class)); cards.add(new SetCardInfo("Thieving Skydiver", 177, Rarity.RARE, mage.cards.t.ThievingSkydiver.class)); cards.add(new SetCardInfo("Thought Vessel", 118, Rarity.UNCOMMON, mage.cards.t.ThoughtVessel.class)); cards.add(new SetCardInfo("Thriving Bluff", 361, Rarity.COMMON, mage.cards.t.ThrivingBluff.class)); diff --git a/Mage.Sets/src/mage/sets/Transformers.java b/Mage.Sets/src/mage/sets/Transformers.java index 817ab7a94bc..ae99a1418d0 100644 --- a/Mage.Sets/src/mage/sets/Transformers.java +++ b/Mage.Sets/src/mage/sets/Transformers.java @@ -29,11 +29,8 @@ public final class Transformers extends ExpansionSet { cards.add(new SetCardInfo("Optimus Prime, Hero", 13, Rarity.MYTHIC, mage.cards.o.OptimusPrimeHero.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Optimus Prime, Hero", 27, Rarity.MYTHIC, mage.cards.o.OptimusPrimeHero.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ratchet, Field Medic", 2, Rarity.MYTHIC, mage.cards.r.RatchetFieldMedic.class)); - cards.add(new SetCardInfo("Slicer, High-Speed Antagonist", 6, Rarity.MYTHIC, mage.cards.s.SlicerHighSpeedAntagonist.class)); cards.add(new SetCardInfo("Slicer, Hired Muscle", 6, Rarity.MYTHIC, mage.cards.s.SlicerHiredMuscle.class)); cards.add(new SetCardInfo("Starscream, Power Hungry", 5, Rarity.MYTHIC, mage.cards.s.StarscreamPowerHungry.class)); - cards.add(new SetCardInfo("Starscream, Seeker Leader", 5, Rarity.MYTHIC, mage.cards.s.StarscreamSeekerLeader.class)); - cards.add(new SetCardInfo("Ultra Magnus, Armored Carrier", 15, Rarity.MYTHIC, mage.cards.u.UltraMagnusArmoredCarrier.class)); cards.add(new SetCardInfo("Ultra Magnus, Tactician", 15, Rarity.MYTHIC, mage.cards.u.UltraMagnusTactician.class)); } } diff --git a/Mage.Sets/src/mage/sets/UniversesWithin.java b/Mage.Sets/src/mage/sets/UniversesWithin.java index c125b00b5e0..cdf48b12faf 100644 --- a/Mage.Sets/src/mage/sets/UniversesWithin.java +++ b/Mage.Sets/src/mage/sets/UniversesWithin.java @@ -26,7 +26,6 @@ public final class UniversesWithin extends ExpansionSet { cards.add(new SetCardInfo("Bohn, Beguiling Balladeer", 30, Rarity.RARE, mage.cards.b.BohnBeguilingBalladeer.class)); cards.add(new SetCardInfo("Bjorna, Nightfall Alchemist", 2, Rarity.RARE, mage.cards.b.BjornaNightfallAlchemist.class)); cards.add(new SetCardInfo("Casal, Lurkwood Pathfinder", 29, Rarity.RARE, mage.cards.c.CasalLurkwoodPathfinder.class)); - cards.add(new SetCardInfo("Casal, Pathbreaker Owlbear", 29, Rarity.RARE, mage.cards.c.CasalPathbreakerOwlbear.class)); cards.add(new SetCardInfo("Cecily, Haunted Mage", 3, Rarity.RARE, mage.cards.c.CecilyHauntedMage.class)); cards.add(new SetCardInfo("Elmar, Ulvenwald Informant", 4, Rarity.RARE, mage.cards.e.ElmarUlvenwaldInformant.class)); cards.add(new SetCardInfo("Enkira, Hostile Scavenger", 20, Rarity.MYTHIC, mage.cards.e.EnkiraHostileScavenger.class)); diff --git a/Mage.Sets/src/mage/sets/XLNTreasureChest.java b/Mage.Sets/src/mage/sets/XLNTreasureChest.java index a7c1e163508..c8fe454fa4d 100644 --- a/Mage.Sets/src/mage/sets/XLNTreasureChest.java +++ b/Mage.Sets/src/mage/sets/XLNTreasureChest.java @@ -21,17 +21,13 @@ public class XLNTreasureChest extends ExpansionSet { this.hasBasicLands = false; cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); - cards.add(new SetCardInfo("Azcanta, the Sunken Ruin", 74, Rarity.RARE, mage.cards.a.AzcantaTheSunkenRuin.class)); cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); cards.add(new SetCardInfo("Dowsing Dagger", 235, Rarity.RARE, mage.cards.d.DowsingDagger.class)); cards.add(new SetCardInfo("Growing Rites of Itlimoc", 191, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); cards.add(new SetCardInfo("Legion's Landing", 22, Rarity.RARE, mage.cards.l.LegionsLanding.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Search for Azcanta", 74, Rarity.RARE, mage.cards.s.SearchForAzcanta.class)); - cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); - cards.add(new SetCardInfo("Spitfire Bastion", 173, Rarity.RARE, mage.cards.s.SpitfireBastion.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); - cards.add(new SetCardInfo("Treasure Cove", 250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); cards.add(new SetCardInfo("Vance's Blasting Cannons", 173, Rarity.RARE, mage.cards.v.VancesBlastingCannons.class)); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DayNightTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DayNightTest.java index 3a58e0dad27..f2970d1bc14 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DayNightTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DayNightTest.java @@ -1,6 +1,7 @@ package org.mage.test.cards.abilities.keywords; import mage.cards.Card; +import mage.cards.DoubleFacedCard; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.game.permanent.Permanent; @@ -67,7 +68,7 @@ public class DayNightTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, ruffian); runCode("copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> { - Card card = currentGame.getCards().stream().filter(c -> c.getName().equals(ruffian)).findFirst().orElse(null); + Card card = currentGame.getCards().stream().filter(c -> c.getName().equals(ruffian) && c instanceof DoubleFacedCard).findFirst().orElse(null); Assert.assertNotNull(card); Assert.assertNotNull(card.getSecondCardFace()); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/lcc/AltarOfTheWretchedTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/lcc/AltarOfTheWretchedTest.java new file mode 100644 index 00000000000..b829ca93a16 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/lcc/AltarOfTheWretchedTest.java @@ -0,0 +1,72 @@ +package org.mage.test.cards.single.lcc; + +import mage.abilities.Ability; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Jmlundeen + */ +public class AltarOfTheWretchedTest extends CardTestPlayerBase { + + /* + Altar of the Wretched + {2}{B} + Artifact + When Altar of the Wretched enters the battlefield, you may sacrifice a nontoken creature. If you do, draw X cards, then mill X cards, where X is that creature's power. + Craft with one or more creatures {2}{B}{B} + {2}{B}: Return Altar of the Wretched from your graveyard to your hand. + + Wretched Bonemass + Color Indicator: Black + Creature — Skeleton Horror + Wretched Bonemass’s power and toughness are each equal to the total power of the exiled cards used to craft it. + This creature has flying as long as an exiled card used to craft it has flying. The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, protection, reach, trample, and vigilance. + 0/0 + */ + private static final String altarOfTheWretched = "Altar of the Wretched"; + private static final String wretchedBoneMass = "Wretched Bonemass"; + + /* + Angel of Invention + {3}{W}{W} + Creature - Angel + Flying, vigilance, lifelink + Fabricate 2 + Other creatures you control get +1/+1. + 2/1 + */ + private static final String angelOfInvention = "Angel of Invention"; + + + @Test + public void testAltarOfTheWretched() { + addCard(Zone.BATTLEFIELD, playerA, altarOfTheWretched); + addCard(Zone.BATTLEFIELD, playerA, angelOfInvention); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft with one or more"); + addTarget(playerA, angelOfInvention); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPowerToughness(playerA, wretchedBoneMass, 2, 2); + assertExileCount(playerA, angelOfInvention, 1); + List abilities = new ArrayList<>(); + abilities.add(FlyingAbility.getInstance()); + abilities.add(VigilanceAbility.getInstance()); + abilities.add(LifelinkAbility.getInstance()); + assertAbilities(playerA, wretchedBoneMass, abilities); + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/lcc/EyeOfOjerTaqTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/lcc/EyeOfOjerTaqTest.java new file mode 100644 index 00000000000..2053ff2367f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/lcc/EyeOfOjerTaqTest.java @@ -0,0 +1,86 @@ +package org.mage.test.cards.single.lcc; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author Jmlundeen + */ +public class EyeOfOjerTaqTest extends CardTestPlayerBase { + + /* + Eye of Ojer Taq + {3} + Artifact + {T}: Add one mana of any color. + Craft with two that share a card type {6} + + Apex Observatory + Artifact + Apex Observatory enters the battlefield tapped. As it enters, choose a card type shared among two exiled cards used to craft it. + {T}: The next spell you cast this turn of the chosen type can be cast without paying its mana cost. + */ + private static final String eyeOfOjerTaq = "Eye of Ojer Taq"; + private static final String apexObservatory = "Apex Observatory"; + + /* + Lightning Bolt + {R} + Instant + Lightning Bolt deals 3 damage to any target. + */ + private static final String lightningBolt = "Lightning Bolt"; + + /* + Ponder + {U} + Sorcery + Look at the top three cards of your library, then put them back in any order. You may shuffle your library. + Draw a card. + */ + private static final String ponder = "Ponder"; + + /* + Shock + {R} + Instant + Shock deals 2 damage to any target. + */ + private static final String shock = "Shock"; + + @Test + public void testEyeOfOjerTaq() { + addCard(Zone.BATTLEFIELD, playerA, eyeOfOjerTaq); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); + addCard(Zone.GRAVEYARD, playerA, lightningBolt); + addCard(Zone.GRAVEYARD, playerA, shock); + addCard(Zone.HAND, playerA, shock, 2); + addCard(Zone.HAND, playerA, ponder); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft with two that share a card type"); + addTarget(playerA, lightningBolt + "^" + shock); + setChoice(playerA, "Instant"); + + activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: The next spell"); + waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN, playerA); + + castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, shock, playerB); // should be able to cast for free + setChoice(playerA, "Cast without paying"); + checkPlayableAbility("Can't cast second shock", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Shock", false); + + checkPlayableAbility("Can't cast ponder", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast Ponder", false); + + setStrictChooseMode(true); + setStopAt(3, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 20 - 2); // took 2 damage from shock + assertExileCount(playerA, lightningBolt, 1); + assertExileCount(playerA, shock, 1); + assertGraveyardCount(playerA, shock, 1); + assertPermanentCount(playerA, apexObservatory, 1); + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/SaheelisLatticeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/SaheelisLatticeTest.java new file mode 100644 index 00000000000..010a6ef18a6 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/SaheelisLatticeTest.java @@ -0,0 +1,67 @@ +package org.mage.test.cards.single.lci; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author Jmlundeen + */ +public class SaheelisLatticeTest extends CardTestPlayerBase { + + /* + Saheeli's Lattice + {1}{R} + Artifact + When Saheeli's Lattice enters the battlefield, you may discard a card. If you do, draw two cards. + Craft with one or more Dinosaurs {4}{R} + Mastercraft Raptor + Artifact Creature - Dinosaur + Mastercraft Raptor's power is equal to the total power of the exiled cards used to craft it. + 0/4 + */ + private static final String saheelisLattice = "Saheeli's Lattice"; + private static final String mastercraftRaptor = "Mastercraft Raptor"; + + /* + Balamb T-Rexaur + {4}{G}{G} + Creature - Dinosaur + Trample + When this creature enters, you gain 3 life. + Forestcycling {2} + 6/6 + */ + private static final String balambTRexaur = "Balamb T-Rexaur"; + + /* + Zetalpa, Primal Dawn + {6}{W}{W} + Legendary Creature - Elder Dinosaur + Flying, double strike, vigilance, trample, indestructible + 4/8 + */ + private static final String zetalpaPrimalDawn = "Zetalpa, Primal Dawn"; + + @Test + public void testSaheelisLattice() { + addCard(Zone.BATTLEFIELD, playerA, saheelisLattice); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5); + addCard(Zone.GRAVEYARD, playerA, balambTRexaur); + addCard(Zone.GRAVEYARD, playerA, zetalpaPrimalDawn); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft with one"); + addTarget(playerA, balambTRexaur + "^" + zetalpaPrimalDawn); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, mastercraftRaptor, 1); + assertPowerToughness(playerA, mastercraftRaptor, 6 + 4, 4); + assertExileCount(playerA, balambTRexaur, 1); + assertExileCount(playerA, zetalpaPrimalDawn, 1); + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/TheEnigmaJewelTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/TheEnigmaJewelTest.java new file mode 100644 index 00000000000..feb38725cfd --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/lci/TheEnigmaJewelTest.java @@ -0,0 +1,93 @@ +package org.mage.test.cards.single.lci; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * + * @author Jmlundeen + */ +public class TheEnigmaJewelTest extends CardTestPlayerBase { + + /* + The Enigma Jewel + {U} + Legendary Artifact + The Enigma Jewel enters the battlefield tapped. + {T}: Add {C}{C}. Spend this mana only to activate abilities. + Craft with four or more nonlands with activated abilities {8}{U} + Locus of Enlightenment + Legendary Artifact + Locus of Enlightenment has each activated ability of the exiled cards used to craft it. You may activate each of those abilities only once each turn. + Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy. + */ + private static final String theEnigmaJewel = "The Enigma Jewel"; + private static final String locusOfEnlightenment = "Locus of Enlightenment"; + + /* + Scavenging Ooze + {1}{G} + Creature - Ooze + {G}: Exile target card from a graveyard. If it was a creature card, put a +1/+1 counter on Scavenging Ooze and you gain 1 life. + 2/2 + */ + private static final String scavengingOoze = "Scavenging Ooze"; + + /* + Aetherflame Wall + {1}{R} + Creature - Wall + Defender + Ætherflame Wall can block creatures with shadow as though they didn't have shadow. + {R}: Ætherflame Wall gets +1/+0 until end of turn. + 0/4 + */ + private static final String aetherflameWall = "Aetherflame Wall"; + + /* + Ancient Silverback + {4}{G}{G} + Creature - Ape + {G}: Regenerate Ancient Silverback. (The next time this creature would be destroyed this turn, it isn't. Instead tap it, remove all damage from it, and remove it from combat.) + 6/5 + */ + private static final String ancientSilverback = "Ancient Silverback"; + + /* + Ancient Hellkite + {4}{R}{R}{R} + Creature - Dragon + Flying + {R}: Ancient Hellkite deals 1 damage to target creature defending player controls. Activate this ability only if Ancient Hellkite is attacking. + 6/6 + */ + private static final String ancientHellkite = "Ancient Hellkite"; + + @Test + public void testTheEnigmaJewelCraft() { + addCard(Zone.BATTLEFIELD, playerA, theEnigmaJewel); + addCard(Zone.BATTLEFIELD, playerA, scavengingOoze); + addCard(Zone.BATTLEFIELD, playerA, aetherflameWall); + addCard(Zone.BATTLEFIELD, playerA, ancientSilverback); + addCard(Zone.BATTLEFIELD, playerA, ancientHellkite); + addCard(Zone.BATTLEFIELD, playerA, "Taiga", 10); + addCard(Zone.BATTLEFIELD, playerA, "Island"); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft with"); + addTarget(playerA, scavengingOoze + "^" + aetherflameWall + "^" + ancientSilverback + "^" + ancientHellkite); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.PRECOMBAT_MAIN); + execute(); + + Permanent permanent = getPermanent(locusOfEnlightenment, playerA); + assertNotNull(permanent); + assertEquals(4, permanent.getAbilities(currentGame).getActivatedAbilities(Zone.BATTLEFIELD).size()); + } +} \ No newline at end of file diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/CommanderTypeTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/CommanderTypeTest.java new file mode 100644 index 00000000000..607324085ae --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/commander/CommanderTypeTest.java @@ -0,0 +1,76 @@ +package org.mage.test.commander; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestCommander4Players; + +public class CommanderTypeTest extends CardTestCommander4Players { + + /* + Sephiroth, Fabled SOLDIER + {2}{B} + Legendary Creature - Human Avatar Soldier + Whenever Sephiroth enters or attacks, you may sacrifice another creature. If you do, draw a card. + Whenever another creature dies, target opponent loses 1 life and you gain 1 life. If this is the fourth time this ability has resolved this turn, transform Sephiroth. + 3/3 + */ + private static final String sephirothFabledSOLDIER = "Sephiroth, Fabled SOLDIER"; + + /* + Sephiroth, One-Winged Angel + Legendary Creature - Angel Nightmare Avatar + Flying + Super Nova -- As this creature transforms into Sephiroth, One-Winged Angel, you get an emblem with "Whenever a creature dies, target opponent loses 1 life and you gain 1 life." + Whenever Sephiroth attacks, you may sacrifice any number of other creatures. If you do, draw that many cards. + 5/5 + */ + private static final String sephirothOneWingedAngel = "Sephiroth, One-Winged Angel"; + + /* + Grizzly Bears + {1}{G} + Creature - Bear + + 2/2 + */ + private static final String grizzlyBears = "Grizzly Bears"; + + @Test + public void testCommanderTypeTransform() { + addCustomEffect_TargetDestroy(playerA); + addCard(Zone.COMMAND, playerA, sephirothFabledSOLDIER); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 8); + addCard(Zone.BATTLEFIELD, playerA, grizzlyBears, 5); + + // Cast commander + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sephirothFabledSOLDIER); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + setChoice(playerA, "Yes"); // Sacrifice another creature to draw a card + setChoice(playerA, grizzlyBears); + + // Trigger death of another creature 5 times to transform + addTarget(playerA, playerB, 6); + for (int i = 0; i < 4; i++) { + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", grizzlyBears); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + } + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", sephirothOneWingedAngel); + setChoice(playerA, "Yes"); // move to command zone + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + + // re-cast commander + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sephirothFabledSOLDIER); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerB, 20 - 6); + assertLife(playerA, 20 + 6); + assertPermanentCount(playerA, sephirothFabledSOLDIER, 1); + assertGraveyardCount(playerA, grizzlyBears, 5); + assertEmblemCount(playerA, 1); // Emblem from second side + } +} diff --git a/Mage/src/main/java/mage/abilities/condition/common/CastNoncreatureSpellThisTurnCondition.java b/Mage/src/main/java/mage/abilities/condition/common/CastNoncreatureSpellThisTurnCondition.java new file mode 100644 index 00000000000..6a71b11474c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/CastNoncreatureSpellThisTurnCondition.java @@ -0,0 +1,35 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.game.Game; +import mage.watchers.common.SpellsCastWatcher; + +/** + * @author TheElk801 + */ +public enum CastNoncreatureSpellThisTurnCondition implements Condition { + instance; + private static final Hint hint = new ConditionHint(instance); + + public static Hint getHint() { + return hint; + } + + @Override + public boolean apply(Game game, Ability source) { + return game + .getState() + .getWatcher(SpellsCastWatcher.class) + .getSpellsCastThisTurn(source.getControllerId()) + .stream() + .anyMatch(spell -> !spell.isCreature(game)); + } + + @Override + public String toString() { + return "you've cast a noncreature spell this turn"; + } +} diff --git a/Mage/src/main/java/mage/abilities/condition/common/IsMainPhaseCondition.java b/Mage/src/main/java/mage/abilities/condition/common/IsMainPhaseCondition.java index 4d10747d907..d832a21d774 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/IsMainPhaseCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/IsMainPhaseCondition.java @@ -1,4 +1,3 @@ - package mage.abilities.condition.common; import mage.abilities.Ability; @@ -10,23 +9,22 @@ import mage.game.Game; */ public enum IsMainPhaseCondition implements Condition { - YOUR(true), - ANY(false); + YOURS(true), + NOT_YOURS(false); - private final boolean yourMainPhaseOnly; + private final boolean yours; - IsMainPhaseCondition(boolean yourMainPhaseOnly) { - this.yourMainPhaseOnly = yourMainPhaseOnly; + IsMainPhaseCondition(boolean yours) { + this.yours = yours; } @Override public boolean apply(Game game, Ability source) { - return game.getTurnPhaseType().isMain() && - (!yourMainPhaseOnly || game.getActivePlayerId().equals(source.getControllerId())); + return game.getTurnPhaseType().isMain() && yours == game.isActivePlayer(source.getControllerId()); } @Override public String toString() { - return "it's" + (yourMainPhaseOnly ? " your " : " ") + "main phase"; + return "it" + (yours ? "'s" : " isn't") + " your main phase"; } } diff --git a/Mage/src/main/java/mage/abilities/condition/common/YouControlALegendaryCreatureCondition.java b/Mage/src/main/java/mage/abilities/condition/common/YouControlALegendaryCreatureCondition.java new file mode 100644 index 00000000000..99f509bc1e7 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/YouControlALegendaryCreatureCondition.java @@ -0,0 +1,30 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.filter.StaticFilters; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public enum YouControlALegendaryCreatureCondition implements Condition { + instance; + private static final Hint hint = new ConditionHint(instance); + + public static Hint getHint() { + return hint; + } + + @Override + public boolean apply(Game game, Ability source) { + return game.getBattlefield().contains(StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY, source.getControllerId(), source, game, 1); + } + + @Override + public String toString() { + return "you control a legendary creature"; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java index b8a7b236791..5aeef1bd8d4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/BecomesMonarchTargetEffect.java @@ -13,7 +13,7 @@ public class BecomesMonarchTargetEffect extends OneShotEffect { public BecomesMonarchTargetEffect() { super(Outcome.Benefit); - staticText = "target player becomes the monarch"; + staticText = "target opponent becomes the monarch"; } protected BecomesMonarchTargetEffect(final BecomesMonarchTargetEffect effect) { @@ -34,5 +34,4 @@ public class BecomesMonarchTargetEffect extends OneShotEffect { } return false; } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnSourceEffect.java index df118893b41..1e8b2c1c4e9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnSourceEffect.java @@ -5,8 +5,6 @@ import mage.abilities.Mode; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.DoubleFacedCardHalf; import mage.constants.Outcome; import mage.constants.Pronoun; import mage.constants.PutCards; @@ -76,15 +74,7 @@ public class ExileAndReturnSourceEffect extends OneShotEffect { returnUnderYourControl ? controller : game.getPlayer(permanent.getOwnerId()), permanent.getMainCard(), source, game, "card" ); - Permanent newPermanent = game.getPermanent(permanent.getId()); - if (newPermanent == null) { - // check if permanent returned with a new face (e.g., transform) - Card card = game.getCard(permanent.getId()); - if (card instanceof DoubleFacedCardHalf) { - newPermanent = game.getPermanent(((DoubleFacedCardHalf) card).getOtherSide().getId()); - } - } - if (additionalEffect == null || newPermanent == null) { + if (additionalEffect == null || !game.getState().getZone(permanent.getMainCard().getId()).equals(Zone.BATTLEFIELD)) { return true; } if (additionalEffect instanceof ContinuousEffect) { diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/BlightControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/BlightControllerEffect.java new file mode 100644 index 00000000000..05dd095a522 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/keyword/BlightControllerEffect.java @@ -0,0 +1,59 @@ +package mage.abilities.effects.keyword; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * @author TheElk801 + */ +public class BlightControllerEffect extends OneShotEffect { + + private final int amount; + + public BlightControllerEffect(int amount) { + super(Outcome.Detriment); + this.amount = amount; + staticText = "blight " + amount; + } + + private BlightControllerEffect(final BlightControllerEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public BlightControllerEffect copy() { + return new BlightControllerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + return doBlight(player, amount, game, source) != null; + } + + public static Permanent doBlight(Player player, int amount, Game game, Ability source) { + if (player == null || amount < 1 || !game.getBattlefield().contains( + StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game, 1 + )) { + return null; + } + TargetPermanent target = new TargetControlledCreaturePermanent(); + target.withNotTarget(true); + target.withChooseHint("to put a -1/-1 counter on"); + player.choose(Outcome.UnboostCreature, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + permanent.addCounters(CounterType.M1M1.createInstance(amount), source, game); + } + return permanent; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ManifestDreadEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ManifestDreadEffect.java index 08b39d74c6d..603228ccf48 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/ManifestDreadEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ManifestDreadEffect.java @@ -7,25 +7,39 @@ import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; +import mage.counters.Counter; import mage.game.Game; import mage.game.events.ManifestedDreadEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; /** * @author TheElk801 */ public class ManifestDreadEffect extends OneShotEffect { - public ManifestDreadEffect() { + private final List counters = new ArrayList<>(); + + public ManifestDreadEffect(Counter... counters) { super(Outcome.Benefit); - staticText = "manifest dread"; + for (Counter counter : counters) { + this.counters.add(counter); + } + staticText = this.makeText(); } private ManifestDreadEffect(final ManifestDreadEffect effect) { super(effect); + for (Counter counter : effect.counters) { + this.counters.add(counter.copy()); + } } @Override @@ -36,7 +50,17 @@ public class ManifestDreadEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - return player != null && doManifestDread(player, source, game) != null; + if (player == null) { + return false; + } + Permanent permanent = doManifestDread(player, source, game); + if (permanent == null) { + return true; + } + for (Counter counter : counters) { + permanent.addCounters(counter, source, game); + } + return true; } public static Permanent doManifestDread(Player player, Ability source, Game game) { @@ -70,4 +94,15 @@ public class ManifestDreadEffect extends OneShotEffect { game.fireEvent(new ManifestedDreadEvent(permanent, source, player.getId(), cards, game)); return permanent; } + + private String makeText() { + StringBuilder sb = new StringBuilder("manifest dread"); + if (this.counters.isEmpty()) { + return sb.toString(); + } + sb.append(", then put "); + sb.append(CardUtil.concatWithAnd(counters.stream().map(Counter::getDescription).collect(Collectors.toList()))); + sb.append(" on that creature"); + return sb.toString(); + } } diff --git a/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java b/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java index 1a1900d55fe..ca871fbffed 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CraftAbility.java @@ -9,7 +9,6 @@ import mage.abilities.costs.common.ExileSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; -import mage.cards.TransformingDoubleFacedCardHalf; import mage.constants.*; import mage.filter.FilterCard; import mage.filter.FilterPermanent; @@ -122,7 +121,8 @@ class CraftCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Card sourceCard = game.getCard(source.getSourceId()); + if (player == null || sourceCard == null) { paid = false; return paid; } @@ -143,7 +143,7 @@ class CraftCost extends CostImpl { .collect(Collectors.toSet()); player.moveCardsToExile( cards, source, game, true, - CardUtil.getExileZoneId(game, source), + CardUtil.getExileZoneId(game, sourceCard.getMainCard().getId(), sourceCard.getMainCard().getZoneChangeCounter(game)), CardUtil.getSourceName(game, source) ); paid = true; diff --git a/Mage/src/main/java/mage/abilities/keyword/PowerUpAbility.java b/Mage/src/main/java/mage/abilities/keyword/PowerUpAbility.java new file mode 100644 index 00000000000..7f93014345a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/PowerUpAbility.java @@ -0,0 +1,53 @@ +package mage.abilities.keyword; + +import mage.abilities.Ability; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostAdjuster; +import mage.abilities.effects.Effect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public class PowerUpAbility extends ActivatedAbilityImpl { + + private enum PowerUpAbilityAdjuster implements CostAdjuster { + instance; + + @Override + public void reduceCost(Ability ability, Game game) { + Permanent permanent = ability.getSourcePermanentIfItStillExists(game); + if (permanent != null && permanent.getTurnsOnBattlefield() == 0) { + CardUtil.adjustCost(ability, permanent.getManaCost(), false); + } + } + } + + public PowerUpAbility(Effect effect, Cost cost) { + this(Zone.BATTLEFIELD, effect, cost); + this.maxActivationsPerGame = 1; + this.setCostAdjuster(PowerUpAbilityAdjuster.instance); + } + + public PowerUpAbility(Zone zone, Effect effect, Cost cost) { + super(zone, effect, cost); + } + + private PowerUpAbility(final PowerUpAbility ability) { + super(ability); + } + + @Override + public PowerUpAbility copy() { + return new PowerUpAbility(this); + } + + @Override + public String getRule() { + return "Power-up — " + super.getRule(); + } +} diff --git a/Mage/src/main/java/mage/cards/RoomCard.java b/Mage/src/main/java/mage/cards/RoomCard.java index 8685b9c84f1..0380ff93064 100644 --- a/Mage/src/main/java/mage/cards/RoomCard.java +++ b/Mage/src/main/java/mage/cards/RoomCard.java @@ -22,20 +22,17 @@ import java.util.UUID; public abstract class RoomCard extends SplitCard { private SpellAbilityType lastCastHalf = null; - protected RoomCard(UUID ownerId, CardSetInfo setInfo, CardType[] types, String costsLeft, - String costsRight, SpellAbilityType spellAbilityType) { - super(ownerId, setInfo, costsLeft, costsRight, spellAbilityType, types); + protected RoomCard(UUID ownerId, CardSetInfo setInfo, String costsLeft, String costsRight) { + super(ownerId, setInfo, costsLeft, costsRight, SpellAbilityType.SPLIT, new CardType[]{CardType.ENCHANTMENT}); String[] names = setInfo.getName().split(" // "); leftHalfCard = new RoomCardHalfImpl( - this.getOwnerId(), new CardSetInfo(names[0], setInfo.getExpansionSetCode(), setInfo.getCardNumber(), - setInfo.getRarity(), setInfo.getGraphicInfo()), - types, costsLeft, this, SpellAbilityType.SPLIT_LEFT); + new CardSetInfo(names[0], setInfo), costsLeft, this, SpellAbilityType.SPLIT_LEFT + ); rightHalfCard = new RoomCardHalfImpl( - this.getOwnerId(), new CardSetInfo(names[1], setInfo.getExpansionSetCode(), setInfo.getCardNumber(), - setInfo.getRarity(), setInfo.getGraphicInfo()), - types, costsRight, this, SpellAbilityType.SPLIT_RIGHT); + new CardSetInfo(names[1], setInfo), costsRight, this, SpellAbilityType.SPLIT_RIGHT + ); // Add the one-shot effect to unlock a door on cast -> ETB Ability entersAbility = new EntersBattlefieldAbility(new RoomEnterUnlockEffect()); @@ -113,7 +110,7 @@ public abstract class RoomCard extends SplitCard { Abilities rightAbilities = roomCard.getRightHalfCard().getAbilities(); for (Ability ability : rightAbilities) { - permanent.addAbility(ability, roomCard.getRightHalfCard().getId(), game,true); + permanent.addAbility(ability, roomCard.getRightHalfCard().getId(), game, true); } } } @@ -173,4 +170,3 @@ class RoomEnterUnlockEffect extends OneShotEffect { return true; } } - diff --git a/Mage/src/main/java/mage/cards/RoomCardHalfImpl.java b/Mage/src/main/java/mage/cards/RoomCardHalfImpl.java index efcca5c7bb4..eee08e22d78 100644 --- a/Mage/src/main/java/mage/cards/RoomCardHalfImpl.java +++ b/Mage/src/main/java/mage/cards/RoomCardHalfImpl.java @@ -14,9 +14,8 @@ import java.util.UUID; */ public class RoomCardHalfImpl extends SplitCardHalfImpl implements RoomCardHalf { - public RoomCardHalfImpl(UUID ownerId, CardSetInfo setInfo, CardType[] cardTypes, String costs, - RoomCard splitCardParent, SpellAbilityType spellAbilityType) { - super(ownerId, setInfo, cardTypes, costs, splitCardParent, spellAbilityType); + public RoomCardHalfImpl(CardSetInfo setInfo, String costs, RoomCard splitCardParent, SpellAbilityType spellAbilityType) { + super(splitCardParent.ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, costs, splitCardParent, spellAbilityType); this.addSubType(SubType.ROOM); } @@ -65,4 +64,4 @@ public class RoomCardHalfImpl extends SplitCardHalfImpl implements RoomCardHalf } super.setZone(zone, game); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index ac396d048b2..1cfe065e997 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -45,6 +45,7 @@ public enum SubType { CASE("Case", SubTypeSet.EnchantmentType), CLASS("Class", SubTypeSet.EnchantmentType), CURSE("Curse", SubTypeSet.EnchantmentType), + PLAN("Plan", SubTypeSet.EnchantmentType), ROLE("Role", SubTypeSet.EnchantmentType), ROOM("Room", SubTypeSet.EnchantmentType), RUNE("Rune", SubTypeSet.EnchantmentType), @@ -193,6 +194,7 @@ public enum SubType { FUNGUS("Fungus", SubTypeSet.CreatureType), // G GAMER("Gamer", SubTypeSet.CreatureType), + GAMMA("Gamma", SubTypeSet.CreatureType), GAMORREAN("Gamorrean", SubTypeSet.CreatureType, true), // Star Wars GAND("Gand", SubTypeSet.CreatureType, true), // Star Wars GARGOYLE("Gargoyle", SubTypeSet.CreatureType), @@ -382,6 +384,7 @@ public enum SubType { SIREN("Siren", SubTypeSet.CreatureType), SITH("Sith", SubTypeSet.CreatureType), SKELETON("Skeleton", SubTypeSet.CreatureType), + SKRULL("Skrull", SubTypeSet.CreatureType), SKUNK("Skunk", SubTypeSet.CreatureType), SLITH("Slith", SubTypeSet.CreatureType), SLIVER("Sliver", SubTypeSet.CreatureType), @@ -391,6 +394,7 @@ public enum SubType { SNAKE("Snake", SubTypeSet.CreatureType), SOLDIER("Soldier", SubTypeSet.CreatureType), SOLTARI("Soltari", SubTypeSet.CreatureType), + SORCERER("Sorcerer", SubTypeSet.CreatureType), SPAWN("Spawn", SubTypeSet.CreatureType), SPECTER("Specter", SubTypeSet.CreatureType), SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType), diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index fd391577bbb..7de344997a0 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -8,6 +8,7 @@ import mage.filter.common.*; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.*; import mage.filter.predicate.other.AnotherTargetPredicate; +import mage.filter.predicate.other.TriggeredAbilityPredicate; import mage.filter.predicate.permanent.*; /** @@ -989,6 +990,14 @@ public final class StaticFilters { FILTER_SPELL_OR_ABILITY_A.setLockedFilter(true); } + public static final FilterStackObject FILTER_CONTROLLED_TRIGGERED_ABILITY = new FilterStackObject("triggered ability you control"); + + static { + FILTER_CONTROLLED_TRIGGERED_ABILITY.add(TriggeredAbilityPredicate.instance); + FILTER_CONTROLLED_TRIGGERED_ABILITY.add(TargetController.YOU.getControllerPredicate()); + FILTER_CONTROLLED_TRIGGERED_ABILITY.setLockedFilter(true); + } + public static final FilterCreatureSpell FILTER_SPELL_A_CREATURE = new FilterCreatureSpell("a creature spell"); static { diff --git a/Mage/src/main/java/mage/filter/predicate/other/TriggeredAbilityPredicate.java b/Mage/src/main/java/mage/filter/predicate/other/TriggeredAbilityPredicate.java new file mode 100644 index 00000000000..3b1f80fd693 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/other/TriggeredAbilityPredicate.java @@ -0,0 +1,18 @@ +package mage.filter.predicate.other; + +import mage.abilities.Ability; +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.stack.StackObject; + +/** + * @author TheElk801 + */ +public enum TriggeredAbilityPredicate implements Predicate { + instance; + + @Override + public boolean apply(StackObject input, Game game) { + return input instanceof Ability && ((Ability) input).isTriggeredAbility(); + } +} diff --git a/Mage/src/main/java/mage/game/command/Commander.java b/Mage/src/main/java/mage/game/command/Commander.java index 7ff69e6101d..24f01ee4f2c 100644 --- a/Mage/src/main/java/mage/game/command/Commander.java +++ b/Mage/src/main/java/mage/game/command/Commander.java @@ -52,6 +52,7 @@ public class Commander extends CommandObjectImpl { case MODAL: case MODAL_LEFT: case MODAL_RIGHT: + case TRANSFORMED_LEFT: case ADVENTURE_SPELL: // can be used from command zone if (canUseAbilityFromCommandZone(spellAbility)) { diff --git a/Mage/src/main/java/mage/game/permanent/token/WallToken.java b/Mage/src/main/java/mage/game/permanent/token/BasaltGolemToken.java similarity index 71% rename from Mage/src/main/java/mage/game/permanent/token/WallToken.java rename to Mage/src/main/java/mage/game/permanent/token/BasaltGolemToken.java index 00ffad3b5bb..eeec6781c3f 100644 --- a/Mage/src/main/java/mage/game/permanent/token/WallToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/BasaltGolemToken.java @@ -8,9 +8,9 @@ import mage.constants.SubType; /** * @author lagdotcom */ -public final class WallToken extends TokenImpl { +public final class BasaltGolemToken extends TokenImpl { - public WallToken() { + public BasaltGolemToken() { super("Wall Token", "0/2 colorless Wall artifact creature token with defender"); cardType.add(CardType.ARTIFACT); cardType.add(CardType.CREATURE); @@ -20,11 +20,11 @@ public final class WallToken extends TokenImpl { addAbility(DefenderAbility.getInstance()); } - private WallToken(final WallToken token) { + private BasaltGolemToken(final BasaltGolemToken token) { super(token); } - public WallToken copy() { - return new WallToken(this); + public BasaltGolemToken copy() { + return new BasaltGolemToken(this); } } diff --git a/Mage/src/main/java/mage/game/permanent/token/DoombotToken.java b/Mage/src/main/java/mage/game/permanent/token/DoombotToken.java new file mode 100644 index 00000000000..eb2edf84eb9 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/DoombotToken.java @@ -0,0 +1,29 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class DoombotToken extends TokenImpl { + + public DoombotToken() { + super("Doombot", "3/3 colorless Robot Villain artifact creature token named Doombot"); + cardType.add(CardType.ARTIFACT); + cardType.add(CardType.CREATURE); + subtype.add(SubType.ROBOT); + subtype.add(SubType.VILLAIN); + power = new MageInt(3); + toughness = new MageInt(3); + } + + private DoombotToken(final DoombotToken token) { + super(token); + } + + public DoombotToken copy() { + return new DoombotToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/GalactusToken.java b/Mage/src/main/java/mage/game/permanent/token/GalactusToken.java new file mode 100644 index 00000000000..b1c5ad47449 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/GalactusToken.java @@ -0,0 +1,44 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.target.common.TargetLandPermanent; + +/** + * @author TheElk801 + */ +public final class GalactusToken extends TokenImpl { + + public GalactusToken() { + super("Galactus", "Galactus, a legendary 16/16 black Elder Alien creature token with flying, trample, and \"Whenever Galactus attacks, destroy target land.\""); + supertype.add(SuperType.LEGENDARY); + cardType.add(CardType.CREATURE); + subtype.add(SubType.ELDER); + subtype.add(SubType.ALIEN); + + color.setBlack(true); + power = new MageInt(16); + toughness = new MageInt(16); + + this.addAbility(FlyingAbility.getInstance()); + this.addAbility(TrampleAbility.getInstance()); + Ability ability = new AttacksTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetLandPermanent()); + this.addAbility(ability); + } + + private GalactusToken(final GalactusToken token) { + super(token); + } + + public GalactusToken copy() { + return new GalactusToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/TheVoidToken.java b/Mage/src/main/java/mage/game/permanent/token/TheVoidToken.java new file mode 100644 index 00000000000..6ff4514f894 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/TheVoidToken.java @@ -0,0 +1,39 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.common.AttacksEachCombatStaticAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; + +/** + * @author TheElk801 + */ +public final class TheVoidToken extends TokenImpl { + + public TheVoidToken() { + super("The Void", "The Void, a legendary 5/5 black Horror Villain creature token with flying, indestructible, and \"The Void attacks each combat if able.\""); + supertype.add(SuperType.LEGENDARY); + cardType.add(CardType.CREATURE); + subtype.add(SubType.HORROR); + subtype.add(SubType.VILLAIN); + + color.setBlack(true); + power = new MageInt(5); + toughness = new MageInt(5); + + this.addAbility(FlyingAbility.getInstance()); + this.addAbility(IndestructibleAbility.getInstance()); + this.addAbility(new AttacksEachCombatStaticAbility()); + } + + private TheVoidToken(final TheVoidToken token) { + super(token); + } + + public TheVoidToken copy() { + return new TheVoidToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/WallColorlessReachToken.java b/Mage/src/main/java/mage/game/permanent/token/WallColorlessReachToken.java new file mode 100644 index 00000000000..befd19724e9 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/WallColorlessReachToken.java @@ -0,0 +1,31 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.ReachAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class WallColorlessReachToken extends TokenImpl { + + public WallColorlessReachToken() { + super("Wall Token", "0/3 colorless Wall creature token with defender and reach"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.WALL); + power = new MageInt(0); + toughness = new MageInt(3); + addAbility(DefenderAbility.getInstance()); + addAbility(ReachAbility.getInstance()); + } + + private WallColorlessReachToken(final WallColorlessReachToken token) { + super(token); + } + + public WallColorlessReachToken copy() { + return new WallColorlessReachToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/WallColorlessToken.java b/Mage/src/main/java/mage/game/permanent/token/WallColorlessToken.java new file mode 100644 index 00000000000..969299ebcae --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/WallColorlessToken.java @@ -0,0 +1,29 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.DefenderAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class WallColorlessToken extends TokenImpl { + + public WallColorlessToken() { + super("Wall Token", "0/4 colorless Wall creature token with defender"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.WALL); + power = new MageInt(0); + toughness = new MageInt(4); + addAbility(DefenderAbility.getInstance()); + } + + private WallColorlessToken(final WallColorlessToken token) { + super(token); + } + + public WallColorlessToken copy() { + return new WallColorlessToken(this); + } +} diff --git a/Mage/src/main/java/mage/watchers/common/CommanderInfoWatcher.java b/Mage/src/main/java/mage/watchers/common/CommanderInfoWatcher.java index cd5d1681808..a9ef959bb88 100644 --- a/Mage/src/main/java/mage/watchers/common/CommanderInfoWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/CommanderInfoWatcher.java @@ -5,6 +5,8 @@ import java.util.Map; import java.util.UUID; import mage.MageObject; import mage.cards.Card; +import mage.cards.DoubleFacedCard; +import mage.cards.DoubleFacedCardHalf; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; @@ -36,7 +38,12 @@ public class CommanderInfoWatcher extends Watcher { @Override public void watch(GameEvent event, Game game) { if (checkCommanderDamage && event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event instanceof DamagedPlayerEvent) { - if (sourceId.equals(event.getSourceId())) { + Card sourceCard = game.getCard(event.getSourceId()); + if (sourceCard == null) { + return; + } + sourceCard = sourceCard.getMainCard(); + if (sourceId.equals(sourceCard.getId())) { DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; if (damageEvent.isCombatDamage()) { UUID playerUUID = event.getTargetId(); @@ -44,7 +51,7 @@ public class CommanderInfoWatcher extends Watcher { damage += damageEvent.getAmount(); damageToPlayer.put(playerUUID, damage); Player player = game.getPlayer(playerUUID); - MageObject commander = game.getObject(sourceId); + MageObject commander = game.getObject(event.getSourceId()); if (player != null && commander != null) { if (!game.isSimulation()) { game.informPlayers(commander.getLogName() + " did " + damage + " combat damage to " + player.getLogName() + " during the game."); @@ -62,8 +69,15 @@ public class CommanderInfoWatcher extends Watcher { public void addCardInfoToCommander(Game game) { MageObject object = game.getPermanent(sourceId); + MageObject leftObject = null; + MageObject rightObject = null; if (object == null) { object = game.getCard(sourceId); + if (object instanceof DoubleFacedCard) { + DoubleFacedCard cardObject = (DoubleFacedCard)object; + leftObject = game.getPermanent(cardObject.getLeftHalfCard().getId()); + rightObject = game.getPermanent(cardObject.getRightHalfCard().getId()); + } } if (object != null) { StringBuilder sb = new StringBuilder(); @@ -74,6 +88,12 @@ public class CommanderInfoWatcher extends Watcher { sb.append(' ').append(playsCount).append(playsCount == 1 ? " time" : " times").append(" played from the command zone."); } this.addInfoToObject(object, "Commander", sb.toString(), game); + if (leftObject != null) { + this.addInfoToObject(leftObject, "Commander", sb.toString(), game); + } + if (rightObject != null) { + this.addInfoToObject(rightObject, "Commander", sb.toString(), game); + } if (checkCommanderDamage) { for (Map.Entry entry : damageToPlayer.entrySet()) { @@ -81,6 +101,14 @@ public class CommanderInfoWatcher extends Watcher { sb.append("").append(commanderTypeName).append(" did ").append(entry.getValue()).append(" combat damage to player ").append(damagedPlayer.getLogName()).append('.'); this.addInfoToObject(object, "Commander" + entry.getKey(), "" + commanderTypeName + " did " + entry.getValue() + " combat damage to player " + damagedPlayer.getLogName() + '.', game); + if (leftObject != null) { + this.addInfoToObject(leftObject, "Commander" + entry.getKey(), + "" + commanderTypeName + " did " + entry.getValue() + " combat damage to player " + damagedPlayer.getLogName() + '.', game); + } + if (rightObject != null) { + this.addInfoToObject(object, "Commander" + entry.getKey(), + "" + commanderTypeName + " did " + entry.getValue() + " combat damage to player " + damagedPlayer.getLogName() + '.', game); + } } } } diff --git a/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java b/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java index fb3e83d95f0..c6fb4fb1dd5 100644 --- a/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/PermanentsSacrificedWatcher.java @@ -44,10 +44,10 @@ public class PermanentsSacrificedWatcher extends Watcher { } public List getThisTurnSacrificedPermanents(UUID playerId) { - return sacrificedPermanents.get(playerId); + return sacrificedPermanents.getOrDefault(playerId, new ArrayList<>()); } public int getThisTurnSacrificedPermanents() { - return sacrificedPermanents.values().stream().mapToInt(permanents -> permanents.size()).sum(); + return sacrificedPermanents.values().stream().mapToInt(List::size).sum(); } } diff --git a/Utils/cardSplitClass.tmpl b/Utils/cardSplitClass.tmpl index c9d9200ba43..bea55bfc800 100644 --- a/Utils/cardSplitClass.tmpl +++ b/Utils/cardSplitClass.tmpl @@ -3,7 +3,7 @@ package mage.cards.[=$cardNameFirstLetter=]; import java.util.UUID; [=$abilitiesImports=] import mage.cards.CardSetInfo; -import mage.cards.SplitCard; +import mage.cards.RoomCard; import mage.constants.CardType; import mage.constants.SpellAbilityType; @@ -11,17 +11,13 @@ import mage.constants.SpellAbilityType; * * @author [=$author=] */ -public final class [=$className=] extends SplitCard { +public final class [=$className=] extends RoomCard { + public [=$className=](UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{[=$type=]}, new CardType[]{??}, "[=$manaCost=]", "??", SpellAbilityType.SPLIT_AFTERMATH); - [=$subType=][=$colors=] + super(ownerId, setInfo, "[=$manaCost=]"); [= if ($power || $power eq 0) { $OUT .= "\n this.power = new MageInt($power);"; $OUT .= "\n this.toughness = new MageInt($toughness);";} =][=$abilities=] - // getLeftHalfCard().getSpellAbility().addEffect(new Effect()); - - // getRightHalfCard().getSpellAbility().addEffect(new Effect()); - } private [=$className=](final [=$className=] card) { diff --git a/Utils/known-sets.txt b/Utils/known-sets.txt index 5d64c87398c..aee325dffed 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -191,6 +191,8 @@ Media Inserts|MediaInserts| March of the Machine|MarchOfTheMachine| March of the Machine Commander|MarchOfTheMachineCommander| March of the Machine: The Aftermath|MarchOfTheMachineTheAftermath| +Marvel Super Heroes|MarvelSuperHeroes| +Marvel Super Heroes Commander|MarvelSuperHeroesCommander| Mercadian Masques|MercadianMasques| Mirage|Mirage| Mirrodin|Mirrodin| diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 0a34c5276c5..41952ffe63c 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -53982,8 +53982,8 @@ Forceful Cultivator|Alchemy: Kamigawa|29|M|{2}{G}{G}|Creature - Snake Shaman|2|3 Imperial Blademaster|Alchemy: Kamigawa|30|R|{1}{R}{W}|Creature - Human Samurai|2|3|Double strike$Whenever a Samurai or Warrior you control attacks alone, draft a card from Imperial Blademaster's spellbook.| Acrobatic Cheerleader|Duskmourn: House of Horror|1|C|{1}{W}|Creature - Human Survivor|2|2|Survival -- At the beginning of your second main phase, if this creature is tapped, put a flying counter on it. This ability triggers only once.| Cult Healer|Duskmourn: House of Horror|2|C|{2}{W}|Creature - Human Doctor|3|3|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, this creature gains lifelink until end of turn.| -Dazzling Theater // Prop Room|Duskmourn: House of Horror|3|R|{3}{W}|Enchantment - Room|||Creature spells you cast have convoke.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Prop Room${2}{W}$Enchantment -- Room$Untap each creature you control during each other player's untap step.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Dollmaker's Shop // Porcelain Gallery|Duskmourn: House of Horror|4|M|{1}{W}|Enchantment - Room|||Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Porcelain Gallery${4}{W}{W}$Enchantment -- Room$Creatures you control have base power and toughness each equal to the number of creatures you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Dazzling Theater // Prop Room|Duskmourn: House of Horror|3|R|{3}{W}","{2}{W}|Enchantment - Room|||Dazzling Theater$Creature spells you cast have convoke.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Prop Room$Enchantment -- Room$Untap each creature you control during each other player's untap step.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Dollmaker's Shop // Porcelain Gallery|Duskmourn: House of Horror|4|M|{1}{W}","{4}{W}{W}|Enchantment - Room|||Dollmaker's Shop$Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Porcelain Gallery$Enchantment -- Room$Creatures you control have base power and toughness each equal to the number of creatures you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Emerge from the Cocoon|Duskmourn: House of Horror|5|C|{4}{W}|Sorcery|||Return target creature card from your graveyard to the battlefield. You gain 3 life.| Enduring Innocence|Duskmourn: House of Horror|6|R|{1}{W}{W}|Enchantment Creature - Sheep Glimmer|2|1|Lifelink$Whenever one or more other creatures you control with power 2 or less enter, draw a card. This ability triggers only once each turn.$When Enduring Innocence dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment.| Ethereal Armor|Duskmourn: House of Horror|7|U|{W}|Enchantment - Aura|||Enchant creature$Enchanted creature gets +1/+1 for each enchantment you control and has first strike.| @@ -53994,7 +53994,7 @@ Fear of Surveillance|Duskmourn: House of Horror|11|C|{1}{W}|Enchantment Creature Friendly Ghost|Duskmourn: House of Horror|12|C|{3}{W}|Creature - Spirit|2|4|Flying$When this creature enters, target creature gets +2/+4 until end of turn.| Ghostly Dancers|Duskmourn: House of Horror|13|R|{3}{W}{W}|Creature - Spirit|2|5|Flying$When this creature enters, return an enchantment card from your graveyard to your hand or unlock a locked door of a Room you control.$Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 3/1 white Spirit creature token with flying.| Glimmer Seeker|Duskmourn: House of Horror|14|U|{2}{W}|Creature - Human Survivor|3|3|Survival -- At the beginning of your second main phase, if this creature is tapped, draw a card if you control a Glimmer creature. If you don't control a Glimmer creature, create a 1/1 white Glimmer enchantment creature token.| -Grand Entryway // Elegant Rotunda|Duskmourn: House of Horror|15|C|{1}{W}|Enchantment - Room|||When you unlock this door, create a 1/1 white Glimmer enchantment creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Elegant Rotunda${2}{W}$Enchantment -- Room$When you unlock this door, put a +1/+1 counter on each of up to two target creatures.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Grand Entryway // Elegant Rotunda|Duskmourn: House of Horror|15|C|{1}{W}","{2}{W}|Enchantment - Room|||Grand Entryway$When you unlock this door, create a 1/1 white Glimmer enchantment creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Elegant Rotunda$Enchantment -- Room$When you unlock this door, put a +1/+1 counter on each of up to two target creatures.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Hardened Escort|Duskmourn: House of Horror|16|C|{2}{W}|Creature - Human Soldier|2|4|Whenever this creature attacks, another target creature you control gets +1/+0 and gains indestructible until end of turn.| Jump Scare|Duskmourn: House of Horror|17|C|{W}|Instant|||Until end of turn, target creature gets +2/+2, gains flying, and becomes a Horror enchantment creature in addition to its other types.| Leyline of Hope|Duskmourn: House of Horror|18|R|{2}{W}{W}|Enchantment|||If this card is in your opening hand, you may begin the game with it on the battlefield.$If you would gain life, you gain that much life plus 1 instead.$As long as you have at least 7 life more than your starting life total, creatures you control get +2/+2.| @@ -54013,7 +54013,7 @@ Sheltered by Ghosts|Duskmourn: House of Horror|30|U|{1}{W}|Enchantment - Aura||| Shepherding Spirits|Duskmourn: House of Horror|31|C|{4}{W}{W}|Creature - Spirit|4|5|Flying$Plainscycling {2}| Split Up|Duskmourn: House of Horror|32|R|{1}{W}{W}|Sorcery|||Choose one --$* Destroy all tapped creatures.$* Destroy all untapped creatures.| Splitskin Doll|Duskmourn: House of Horror|33|U|{1}{W}|Artifact Creature - Toy|2|1|When this creature enters, draw a card. Then discard a card unless you control another creature with power 2 or less.| -Surgical Suite // Hospital Room|Duskmourn: House of Horror|34|U|{1}{W}|Enchantment - Room|||When you unlock this door, return target creature card with mana value 3 or less from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Hospital Room${3}{W}$Enchantment -- Room$Whenever you attack, put a +1/+1 counter on target attacking creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Surgical Suite // Hospital Room|Duskmourn: House of Horror|34|U|{1}{W}","{3}{W}|Enchantment - Room|||Surgical Suite$When you unlock this door, return target creature card with mana value 3 or less from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Hospital Room$Enchantment -- Room$Whenever you attack, put a +1/+1 counter on target attacking creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Toby, Beastie Befriender|Duskmourn: House of Horror|35|R|{2}{W}|Legendary Creature - Human Wizard|1|1|When Toby enters, create a 4/4 white Beast creature token with "This token can't attack or block alone."$As long as you control four or more creature tokens, creature tokens you control have flying.| Trapped in the Screen|Duskmourn: House of Horror|36|C|{2}{W}|Enchantment|||Ward {2}$When this enchantment enters, exile target artifact, creature, or enchantment an opponent controls until this enchantment leaves the battlefield.| Unidentified Hovership|Duskmourn: House of Horror|37|R|{1}{W}{W}|Artifact - Vehicle|2|2|Flying$When this Vehicle enters, exile up to one target creature with toughness 5 or less.$When this Vehicle leaves the battlefield, the exiled card's owner manifests dread.$Crew 1| @@ -54022,8 +54022,8 @@ Unwanted Remake|Duskmourn: House of Horror|39|U|{W}|Instant|||Destroy target cre Veteran Survivor|Duskmourn: House of Horror|40|U|{W}|Creature - Human Survivor|2|1|Survival -- At the beginning of your second main phase, if this creature is tapped, exile up to one target card from a graveyard.$As long as there are three or more cards exiled with this creature, it gets +3/+3 and has hexproof.| The Wandering Rescuer|Duskmourn: House of Horror|41|M|{3}{W}{W}|Legendary Creature - Human Samurai Noble|3|4|Flash$Convoke$Double strike$Other tapped creatures you control have hexproof.| Abhorrent Oculus|Duskmourn: House of Horror|42|M|{2}{U}|Creature - Eye|5|5|As an additional cost to cast this spell, exile six cards from your graveyard.$Flying$At the beginning of each opponent's upkeep, manifest dread.| -Bottomless Pool // Locker Room|Duskmourn: House of Horror|43|U|{U}|Enchantment - Room|||When you unlock this door, return up to one target creature to its owner's hand.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Locker Room${4}{U}$Enchantment -- Room$Whenever one or more creatures you control deal combat damage to a player, draw a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Central Elevator // Promising Stairs|Duskmourn: House of Horror|44|R|{3}{U}|Enchantment - Room|||When you unlock this door, search your library for a Room card that doesn't have the same name as a Room you control, reveal it, put it into your hand, then shuffle.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Promising Stairs${2}{U}$Enchantment -- Room$At the beginning of your upkeep, surveil 1. You win the game if there are eight or more different names among unlocked doors of Rooms you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Bottomless Pool // Locker Room|Duskmourn: House of Horror|43|U|{U}","{4}{U}|Enchantment - Room|||Bottomless Pool$When you unlock this door, return up to one target creature to its owner's hand.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Locker Room$Enchantment -- Room$Whenever one or more creatures you control deal combat damage to a player, draw a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Central Elevator // Promising Stairs|Duskmourn: House of Horror|44|R|{3}{U}","{2}{U}|Enchantment - Room|||Central Elevator$When you unlock this door, search your library for a Room card that doesn't have the same name as a Room you control, reveal it, put it into your hand, then shuffle.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Promising Stairs$Enchantment -- Room$At the beginning of your upkeep, surveil 1. You win the game if there are eight or more different names among unlocked doors of Rooms you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Clammy Prowler|Duskmourn: House of Horror|45|C|{3}{U}|Enchantment Creature - Horror|2|5|Whenever this creature attacks, another target attacking creature can't be blocked this turn.| Creeping Peeper|Duskmourn: House of Horror|46|C|{1}{U}|Creature - Eye|2|1|{T}: Add {U}. Spend this mana only to cast an enchantment spell, unlock a door, or turn a permanent face up.| Cursed Windbreaker|Duskmourn: House of Horror|47|U|{2}{U}|Artifact - Equipment|||When this Equipment enters, manifest dread, then attach this Equipment to that creature.$Equipped creature has flying.$Equip {3}| @@ -54044,9 +54044,9 @@ Ghostly Keybearer|Duskmourn: House of Horror|61|U|{3}{U}|Creature - Spirit|3|3|F Glimmerburst|Duskmourn: House of Horror|62|C|{3}{U}|Instant|||Draw two cards. Create a 1/1 white Glimmer enchantment creature token.| Leyline of Transformation|Duskmourn: House of Horror|63|R|{2}{U}{U}|Enchantment|||If this card is in your opening hand, you may begin the game with it on the battlefield.$As this enchantment enters, choose a creature type.$Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.| Marina Vendrell's Grimoire|Duskmourn: House of Horror|64|R|{5}{U}|Legendary Artifact|||When Marina Vendrell's Grimoire enters, if you cast it, draw five cards.$You have no maximum hand size and don't lose the game for having 0 or less life.$Whenever you gain life, draw that many cards.$Whenever you lose life, discard that many cards. Then if you have no cards in hand, you lose the game.| -Meat Locker // Drowned Diner|Duskmourn: House of Horror|65|C|{2}{U}|Enchantment - Room|||When you unlock this door, tap up to one target creature and put two stun counters on it.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Drowned Diner${3}{U}{U}$Enchantment -- Room$When you unlock this door, draw three cards, then discard a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Meat Locker // Drowned Diner|Duskmourn: House of Horror|65|C|{2}{U}","{3}{U}{U}|Enchantment - Room|||Meat Locker$When you unlock this door, tap up to one target creature and put two stun counters on it.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Drowned Diner$Enchantment -- Room$When you unlock this door, draw three cards, then discard a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| The Mindskinner|Duskmourn: House of Horror|66|R|{U}{U}{U}|Legendary Enchantment Creature - Nightmare|10|1|The Mindskinner can't be blocked.$If a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.| -Mirror Room // Fractured Realm|Duskmourn: House of Horror|67|M|{2}{U}|Enchantment - Room|||When you unlock this door, create a token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Fractured Realm${5}{U}{U}$Enchantment -- Room$If a triggered ability of a permanent you control triggers, that ability triggers an additional time.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Mirror Room // Fractured Realm|Duskmourn: House of Horror|67|M|{2}{U}","{5}{U}{U}|Enchantment - Room|||Mirror Room$When you unlock this door, create a token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Fractured Realm$Enchantment -- Room$If a triggered ability of a permanent you control triggers, that ability triggers an additional time.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Overlord of the Floodpits|Duskmourn: House of Horror|68|M|{3}{U}{U}|Enchantment Creature - Avatar Horror|5|3|Impending 4--{1}{U}{U}$Flying$Whenever this permanent enters or attacks, draw two cards, then discard a card.| Paranormal Analyst|Duskmourn: House of Horror|69|U|{1}{U}|Creature - Human Detective|1|3|Whenever you manifest dread, put a card you put into your graveyard this way into your hand.| Piranha Fly|Duskmourn: House of Horror|70|C|{1}{U}|Creature - Fish Insect|2|1|Flying$This creature enters tapped.| @@ -54058,7 +54058,7 @@ The Tale of Tamiyo|Duskmourn: House of Horror|75|R|{2}{U}|Legendary Enchantment Tunnel Surveyor|Duskmourn: House of Horror|76|C|{2}{U}|Creature - Human Detective|2|2|When this creature enters, create a 1/1 white Glimmer enchantment creature token.| Twist Reality|Duskmourn: House of Horror|77|C|{1}{U}{U}|Instant|||Choose one --$* Counter target spell.$* Manifest dread.| Unable to Scream|Duskmourn: House of Horror|78|C|{U}|Enchantment - Aura|||Enchant creature$Enchanted creature loses all abilities and is a Toy artifact creature with base power and toughness 0/2 in addition to its other types.$As long as enchanted creature is face down, it can't be turned face up.| -Underwater Tunnel // Slimy Aquarium|Duskmourn: House of Horror|79|C|{U}|Enchantment - Room|||When you unlock this door, surveil 2.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Slimy Aquarium${3}{U}$Enchantment -- Room$When you unlock this door, manifest dread, then put a +1/+1 counter on that creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Underwater Tunnel // Slimy Aquarium|Duskmourn: House of Horror|79|C|{U}","{3}{U}|Enchantment - Room|||Underwater Tunnel$When you unlock this door, surveil 2.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Slimy Aquarium$Enchantment -- Room$When you unlock this door, manifest dread, then put a +1/+1 counter on that creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Unnerving Grasp|Duskmourn: House of Horror|80|U|{2}{U}|Sorcery|||Return up to one target nonland permanent to its owner's hand. Manifest dread.| Unwilling Vessel|Duskmourn: House of Horror|81|U|{2}{U}|Creature - Human Wizard|3|2|Vigilance$Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on this creature.$When this creature dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on this creature.| Vanish from Sight|Duskmourn: House of Horror|82|C|{3}{U}|Instant|||Target nonland permanent's owner puts it on their choice of the top or bottom of their library. Surveil 1.| @@ -54070,16 +54070,16 @@ Commune with Evil|Duskmourn: House of Horror|87|U|{2}{B}|Sorcery|||Look at the t Cracked Skull|Duskmourn: House of Horror|88|C|{2}{B}|Enchantment - Aura|||Enchant creature$When this Aura enters, look at target player's hand. You may choose a nonland card from it. That player discards that card.$When enchanted creature is dealt damage, destroy it.| Cynical Loner|Duskmourn: House of Horror|89|U|{1}{B}|Creature - Human Survivor|3|1|This creature can't be blocked by Glimmers.$Survival -- At the beginning of your second main phase, if this creature is tapped, you may search your library for a card, put it into your graveyard, then shuffle.| Dashing Bloodsucker|Duskmourn: House of Horror|90|U|{3}{B}|Creature - Vampire Warrior|2|5|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, this creature gets +2/+0 and gains lifelink until end of turn.| -Defiled Crypt // Cadaver Lab|Duskmourn: House of Horror|91|U|{3}{B}|Enchantment - Room|||Whenever one or more cards leave your graveyard, create a 2/2 black Horror enchantment creature token. This ability triggers only once each turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Cadaver Lab${B}$Enchantment -- Room$When you unlock this door, return target creature card from your graveyard to your hand.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Defiled Crypt // Cadaver Lab|Duskmourn: House of Horror|91|U|{3}{B}","{B}|Enchantment - Room|||Defiled Crypt$Whenever one or more cards leave your graveyard, create a 2/2 black Horror enchantment creature token. This ability triggers only once each turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Cadaver Lab$Enchantment -- Room$When you unlock this door, return target creature card from your graveyard to your hand.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Demonic Counsel|Duskmourn: House of Horror|92|R|{1}{B}|Sorcery|||Search your library for a Demon card, reveal it, put it into your hand, then shuffle.$Delirium -- If there are four or more card types among cards in your graveyard, instead search your library for any card, put it into your hand, then shuffle.| -Derelict Attic // Widow's Walk|Duskmourn: House of Horror|93|C|{2}{B}|Enchantment - Room|||When you unlock this door, you draw two cards and you lose 2 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Widow's Walk${3}{B}$Enchantment -- Room$Whenever a creature you control attacks alone, it gets +1/+0 and gains deathtouch until end of turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Derelict Attic // Widow's Walk|Duskmourn: House of Horror|93|C|{2}{B}","{3}{B}|Enchantment - Room|||Derelict Attic$When you unlock this door, you draw two cards and you lose 2 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Widow's Walk$Enchantment -- Room$Whenever a creature you control attacks alone, it gets +1/+0 and gains deathtouch until end of turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Doomsday Excruciator|Duskmourn: House of Horror|94|R|{B}{B}{B}{B}{B}{B}|Creature - Demon|6|6|Flying$When this creature enters, if it was cast, each player exiles all but the bottom six cards of their library face down.$At the beginning of your upkeep, draw a card.| Enduring Tenacity|Duskmourn: House of Horror|95|R|{2}{B}{B}|Enchantment Creature - Snake Glimmer|4|3|Whenever you gain life, target opponent loses that much life.$When Enduring Tenacity dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment.| Fanatic of the Harrowing|Duskmourn: House of Horror|96|C|{3}{B}|Creature - Human Cleric|2|2|When this creature enters, each player discards a card. If you discarded a card this way, draw a card.| Fear of Lost Teeth|Duskmourn: House of Horror|97|C|{B}|Enchantment Creature - Nightmare|1|1|When this creature dies, it deals 1 damage to any target and you gain 1 life.| Fear of the Dark|Duskmourn: House of Horror|98|C|{4}{B}|Enchantment Creature - Nightmare|5|5|Whenever this creature attacks, if defending player controls no Glimmer creatures, it gains menace and deathtouch until end of turn.| Final Vengeance|Duskmourn: House of Horror|99|C|{B}|Sorcery|||As an additional cost to cast this spell, sacrifice a creature or enchantment.$Exile target creature.| -Funeral Room // Awakening Hall|Duskmourn: House of Horror|100|M|{2}{B}|Enchantment - Room|||Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Awakening Hall${6}{B}{B}$Enchantment -- Room$When you unlock this door, return all creature cards from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Funeral Room // Awakening Hall|Duskmourn: House of Horror|100|M|{2}{B}","{6}{B}{B}|Enchantment - Room|||Funeral Room$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Awakening Hall$Enchantment -- Room$When you unlock this door, return all creature cards from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Give In to Violence|Duskmourn: House of Horror|101|C|{1}{B}|Instant|||Target creature gets +2/+2 and gains lifelink until end of turn.| Grievous Wound|Duskmourn: House of Horror|102|R|{3}{B}{B}|Enchantment - Aura|||Enchant player$Enchanted player can't gain life.$Whenever enchanted player is dealt damage, they lose half their life, rounded up.| Innocuous Rat|Duskmourn: House of Horror|103|C|{1}{B}|Creature - Rat|1|1|When this creature dies, manifest dread.| @@ -54097,7 +54097,7 @@ Popular Egotist|Duskmourn: House of Horror|114|U|{2}{B}|Creature - Human Rogue|3 Resurrected Cultist|Duskmourn: House of Horror|115|C|{2}{B}|Creature - Human Cleric|4|1|Delirium -- {2}{B}{B}: Return this card from your graveyard to the battlefield with a finality counter on it. Activate only if there are four or more card types among cards in your graveyard and only as a sorcery.| Spectral Snatcher|Duskmourn: House of Horror|116|C|{4}{B}{B}|Creature - Spirit|6|5|Ward--Discard a card.$Swampcycling {2}| Sporogenic Infection|Duskmourn: House of Horror|117|U|{1}{B}|Enchantment - Aura|||Enchant creature$When this Aura enters, target player sacrifices a creature of their choice other than enchanted creature.$When enchanted creature is dealt damage, destroy it.| -Unholy Annex // Ritual Chamber|Duskmourn: House of Horror|118|R|{2}{B}|Enchantment - Room|||At the beginning of your end step, draw a card. If you control a Demon, each opponent loses 2 life and you gain 2 life. Otherwise, you lose 2 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Ritual Chamber${3}{B}{B}$Enchantment -- Room$When you unlock this door, create a 6/6 black Demon creature token with flying.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Unholy Annex // Ritual Chamber|Duskmourn: House of Horror|118|R|{2}{B}","{3}{B}{B}|Enchantment - Room|||Unholy Annex$At the beginning of your end step, draw a card. If you control a Demon, each opponent loses 2 life and you gain 2 life. Otherwise, you lose 2 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Ritual Chamber$Enchantment -- Room$When you unlock this door, create a 6/6 black Demon creature token with flying.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Unstoppable Slasher|Duskmourn: House of Horror|119|R|{2}{B}|Creature - Zombie Assassin|2|3|Deathtouch$Whenever this creature deals combat damage to a player, they lose half their life, rounded up.$When this creature dies, if it had no counters on it, return it to the battlefield tapped under its owner's control with two stun counters on it.| Valgavoth, Terror Eater|Duskmourn: House of Horror|120|M|{6}{B}{B}{B}|Legendary Creature - Elder Demon|9|9|Flying, lifelink$Ward--Sacrifice three nonland permanents.$If a card you didn't control would be put into an opponent's graveyard from anywhere, exile it instead.$During your turn, you may play cards exiled with Valgavoth. If you cast a spell this way, pay life equal to its mana value rather than pay its mana cost.| Valgavoth's Faithful|Duskmourn: House of Horror|121|U|{B}|Creature - Human Cleric|1|1|{3}{B}, Sacrifice this creature: Return target creature card from your graveyard to the battlefield. Activate only as a sorcery.| @@ -54108,7 +54108,7 @@ Bedhead Beastie|Duskmourn: House of Horror|125|C|{4}{R}{R}|Creature - Beast|5|6| Betrayer's Bargain|Duskmourn: House of Horror|126|U|{1}{R}|Instant|||As an additional cost to cast this spell, sacrifice a creature or enchantment or pay {2}.$Betrayer's Bargain deals 5 damage to target creature. If that creature would die this turn, exile it instead.| Boilerbilges Ripper|Duskmourn: House of Horror|127|C|{4}{R}|Creature - Human Assassin|4|4|When this creature enters, you may sacrifice another creature or enchantment. When you do, this creature deals 2 damage to any target.| Chainsaw|Duskmourn: House of Horror|128|R|{1}{R}|Artifact - Equipment|||When this Equipment enters, it deals 3 damage to up to one target creature.$Whenever one or more creatures die, put a rev counter on this Equipment.$Equipped creature gets +X/+0, where X is the number of rev counters on this Equipment.$Equip {3}| -Charred Foyer // Warped Space|Duskmourn: House of Horror|129|M|{3}{R}|Enchantment - Room|||At the beginning of your upkeep, exile the top card of your library. You may play it this turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Warped Space${4}{R}{R}$Enchantment -- Room$Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast from exile.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Charred Foyer // Warped Space|Duskmourn: House of Horror|129|M|{3}{R}","{4}{R}{R}|Enchantment - Room|||Charred Foyer$At the beginning of your upkeep, exile the top card of your library. You may play it this turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Warped Space$Enchantment -- Room$Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast from exile.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Clockwork Percussionist|Duskmourn: House of Horror|130|C|{R}|Artifact Creature - Monkey Toy|1|1|Haste$When this creature dies, exile the top card of your library. You may play it until the end of your next turn.| Cursed Recording|Duskmourn: House of Horror|131|R|{2}{R}{R}|Artifact|||Whenever you cast an instant or sorcery spell, put a time counter on this artifact. Then if there are seven or more time counters on it, remove those counters and it deals 20 damage to you.${T}: When you next cast an instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy.| Diversion Specialist|Duskmourn: House of Horror|132|U|{3}{R}|Creature - Human Warrior|4|3|Menace${1}, Sacrifice another creature or enchantment: Exile the top card of your library. You may play it this turn.| @@ -54116,7 +54116,7 @@ Enduring Courage|Duskmourn: House of Horror|133|R|{2}{R}{R}|Enchantment Creature Fear of Being Hunted|Duskmourn: House of Horror|134|U|{1}{R}{R}|Enchantment Creature - Nightmare|4|2|Haste$This creature must be blocked if able.| Fear of Burning Alive|Duskmourn: House of Horror|135|U|{4}{R}{R}|Enchantment Creature - Nightmare|4|4|When this creature enters, it deals 4 damage to each opponent.$Delirium -- Whenever a source you control deals noncombat damage to an opponent, if there are four or more card types among cards in your graveyard, this creature deals that amount of damage to target creature that player controls.| Fear of Missing Out|Duskmourn: House of Horror|136|R|{1}{R}|Enchantment Creature - Nightmare|2|3|When this creature enters, discard a card, then draw a card.$Delirium -- Whenever this creature attacks for the first time each turn, if there are four or more card types among cards in your graveyard, untap target creature. After this phase, there is an additional combat phase.| -Glassworks // Shattered Yard|Duskmourn: House of Horror|137|C|{2}{R}|Enchantment - Room|||When you unlock this door, this Room deals 4 damage to target creature an opponent controls.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Shattered Yard${4}{R}$Enchantment -- Room$At the beginning of your end step, this Room deals 1 damage to each opponent.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Glassworks // Shattered Yard|Duskmourn: House of Horror|137|C|{2}{R}","{4}{R}|Enchantment - Room|||Glassworks$When you unlock this door, this Room deals 4 damage to target creature an opponent controls.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Shattered Yard$Enchantment -- Room$At the beginning of your end step, this Room deals 1 damage to each opponent.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Grab the Prize|Duskmourn: House of Horror|138|C|{1}{R}|Sorcery|||As an additional cost to cast this spell, discard a card.$Draw two cards. If the discarded card wasn't a land card, Grab the Prize deals 2 damage to each opponent.| Hand That Feeds|Duskmourn: House of Horror|139|C|{1}{R}|Creature - Mutant|2|2|Delirium -- Whenever this creature attacks while there are four or more card types among cards in your graveyard, it gets +2/+0 and gains menace until end of turn.| Impossible Inferno|Duskmourn: House of Horror|140|C|{4}{R}|Instant|||Impossible Inferno deals 6 damage to target creature.$Delirium -- If there are four or more card types among cards in your graveyard, exile the top card of your library. You may play it until the end of your next turn.| @@ -54127,7 +54127,7 @@ Leyline of Resonance|Duskmourn: House of Horror|143|R|{2}{R}{R}|Enchantment|||If Most Valuable Slayer|Duskmourn: House of Horror|144|C|{3}{R}|Creature - Human Warrior|2|4|Whenever you attack, target attacking creature gets +1/+0 and gains first strike until end of turn.| Norin, Swift Survivalist|Duskmourn: House of Horror|145|U|{R}|Legendary Creature - Human Coward|2|1|Norin can't block.$Whenever a creature you control becomes blocked, you may exile it. You may play that card from exile this turn.| Overlord of the Boilerbilges|Duskmourn: House of Horror|146|M|{4}{R}{R}|Enchantment Creature - Avatar Horror|5|5|Impending 4--{2}{R}{R}$Whenever this permanent enters or attacks, it deals 4 damage to any target.| -Painter's Studio // Defaced Gallery|Duskmourn: House of Horror|147|U|{2}{R}|Enchantment - Room|||When you unlock this door, exile the top two cards of your library. You may play them until the end of your next turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Defaced Gallery${1}{R}$Enchantment -- Room$Whenever you attack, attacking creatures you control get +1/+0 until end of turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Painter's Studio // Defaced Gallery|Duskmourn: House of Horror|147|U|{2}{R}","{1}{R}|Enchantment - Room|||Painter's Studio$When you unlock this door, exile the top two cards of your library. You may play them until the end of your next turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Defaced Gallery$Enchantment -- Room$Whenever you attack, attacking creatures you control get +1/+0 until end of turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Piggy Bank|Duskmourn: House of Horror|148|U|{1}{R}|Artifact Creature - Boar Toy|3|2|When this creature dies, create a Treasure token.| Pyroclasm|Duskmourn: House of Horror|149|U|{1}{R}|Sorcery|||Pyroclasm deals 2 damage to each creature.| Ragged Playmate|Duskmourn: House of Horror|150|C|{1}{R}|Artifact Creature - Toy|2|2|{1}, {T}: Target creature with power 2 or less can't be blocked this turn.| @@ -54138,7 +54138,7 @@ Ripchain Razorkin|Duskmourn: House of Horror|154|C|{3}{R}|Creature - Human Berse The Rollercrusher Ride|Duskmourn: House of Horror|155|M|{X}{2}{R}|Legendary Enchantment|||Delirium -- If a source you control would deal noncombat damage to a permanent or player while there are four or more card types among cards in your graveyard, it deals double that damage instead.$When The Rollercrusher Ride enters, it deals X damage to each of up to X target creatures.| Scorching Dragonfire|Duskmourn: House of Horror|156|C|{1}{R}|Instant|||Scorching Dragonfire deals 3 damage to target creature or planeswalker. If that creature or planeswalker would die this turn, exile it instead.| Screaming Nemesis|Duskmourn: House of Horror|157|M|{2}{R}|Creature - Spirit|3|3|Haste$Whenever this creature is dealt damage, it deals that much damage to any other target. If a player is dealt damage this way, they can't gain life for the rest of the game.| -Ticket Booth // Tunnel of Hate|Duskmourn: House of Horror|158|C|{2}{R}|Enchantment - Room|||When you unlock this door, manifest dread.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Tunnel of Hate${4}{R}{R}$Enchantment -- Room$Whenever you attack, target attacking creature gains double strike until end of turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Ticket Booth // Tunnel of Hate|Duskmourn: House of Horror|158|C|{2}{R}","{4}{R}{R}|Enchantment - Room|||Ticket Booth$When you unlock this door, manifest dread.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Tunnel of Hate$Enchantment -- Room$Whenever you attack, target attacking creature gains double strike until end of turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Trial of Agony|Duskmourn: House of Horror|159|U|{R}|Sorcery|||Choose two target creatures controlled by the same opponent. That player chooses one of those creatures. Trial of Agony deals 5 damage to that creature, and the other can't block this turn.| Turn Inside Out|Duskmourn: House of Horror|160|C|{R}|Instant|||Target creature gets +3/+0 until end of turn. When it dies this turn, manifest dread.| Untimely Malfunction|Duskmourn: House of Horror|161|U|{1}{R}|Instant|||Choose one --$* Destroy target artifact.$* Change the target of target spell or ability with a single target.$* One or two target creatures can't block this turn.| @@ -54161,7 +54161,7 @@ Fear of Exposure|Duskmourn: House of Horror|177|U|{2}{G}|Enchantment Creature - Flesh Burrower|Duskmourn: House of Horror|178|C|{1}{G}|Creature - Insect|2|2|Deathtouch$Whenever this creature attacks, another target creature you control gains deathtouch until end of turn.| Frantic Strength|Duskmourn: House of Horror|179|C|{2}{G}|Enchantment - Aura|||Flash$Enchant creature$Enchanted creature gets +2/+2 and has trample.| Grasping Longneck|Duskmourn: House of Horror|180|C|{2}{G}|Enchantment Creature - Horror|4|2|Reach$When this creature dies, you gain 2 life.| -Greenhouse // Rickety Gazebo|Duskmourn: House of Horror|181|U|{2}{G}|Enchantment - Room|||Lands you control have "{T}: Add one mana of any color."$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Rickety Gazebo${3}{G}$Enchantment -- Room$When you unlock this door, mill four cards, then return up to two permanent cards from among them to your hand.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Greenhouse // Rickety Gazebo|Duskmourn: House of Horror|181|U|{2}{G}","{3}{G}|Enchantment - Room|||Greenhouse$Lands you control have "{T}: Add one mana of any color."$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Rickety Gazebo$Enchantment -- Room$When you unlock this door, mill four cards, then return up to two permanent cards from among them to your hand.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Hauntwoods Shrieker|Duskmourn: House of Horror|182|M|{1}{G}{G}|Creature - Beast Mutant|3|3|Whenever this creature attacks, manifest dread.${1}{G}: Reveal target face-down permanent. If it's a creature card, you may turn it face up.| Hedge Shredder|Duskmourn: House of Horror|183|R|{2}{G}{G}|Artifact - Vehicle|5|5|Whenever this Vehicle attacks, you may mill two cards.$Whenever one or more land cards are put into your graveyard from your library, put them onto the battlefield tapped.$Crew 1| Horrid Vigor|Duskmourn: House of Horror|184|C|{1}{G}|Instant|||Target creature gains deathtouch and indestructible until end of turn.| @@ -54170,7 +54170,7 @@ Insidious Fungus|Duskmourn: House of Horror|186|U|{G}|Creature - Fungus|1|2|{2}, Kona, Rescue Beastie|Duskmourn: House of Horror|187|R|{3}{G}|Legendary Creature - Beast Survivor|4|3|Survival -- At the beginning of your second main phase, if Kona is tapped, you may put a permanent card from your hand onto the battlefield.| Leyline of Mutation|Duskmourn: House of Horror|188|R|{2}{G}{G}|Enchantment|||If this card is in your opening hand, you may begin the game with it on the battlefield.$You may pay {W}{U}{B}{R}{G} rather than pay the mana cost for spells you cast.| Manifest Dread|Duskmourn: House of Horror|189|C|{1}{G}|Sorcery|||Manifest dread.| -Moldering Gym // Weight Room|Duskmourn: House of Horror|190|C|{2}{G}|Enchantment - Room|||When you unlock this door, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Weight Room${5}{G}$Enchantment -- Room$When you unlock this door, manifest dread, then put three +1/+1 counters on that creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Moldering Gym // Weight Room|Duskmourn: House of Horror|190|C|{2}{G}","{5}{G}|Enchantment - Room|||Moldering Gym$When you unlock this door, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Weight Room$Enchantment -- Room$When you unlock this door, manifest dread, then put three +1/+1 counters on that creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Monstrous Emergence|Duskmourn: House of Horror|191|C|{1}{G}|Sorcery|||As an additional cost to cast this spell, choose a creature you control or reveal a creature card from your hand.$Monstrous Emergence deals damage equal to the power of the creature you chose or the card you revealed to target creature.| Omnivorous Flytrap|Duskmourn: House of Horror|192|R|{2}{G}|Creature - Plant|2|4|Delirium -- Whenever this creature enters or attacks, if there are four or more card types among cards in your graveyard, distribute two +1/+1 counters among one or two target creatures. Then if there are six or more card types among cards in your graveyard, double the number of +1/+1 counters on those creatures.| Overgrown Zealot|Duskmourn: House of Horror|193|U|{1}{G}|Creature - Elf Druid|0|4|{T}: Add one mana of any color.${T}: Add two mana of any one color. Spend this mana only to turn permanents face up.| @@ -54185,7 +54185,7 @@ Twitching Doll|Duskmourn: House of Horror|201|R|{1}{G}|Artifact Creature - Spide Tyvar, the Pummeler|Duskmourn: House of Horror|202|M|{1}{G}{G}|Legendary Creature - Elf Warrior|3|3|Tap another untapped creature you control: Tyvar gains indestructible until end of turn. Tap it.${3}{G}{G}: Creatures you control get +X/+X until end of turn, where X is the greatest power among creatures you control.| Under the Skin|Duskmourn: House of Horror|203|U|{2}{G}|Sorcery|||Manifest dread.$You may return a permanent card from your graveyard to your hand.| Valgavoth's Onslaught|Duskmourn: House of Horror|204|R|{X}{X}{G}|Sorcery|||Manifest dread X times, then put X +1/+1 counters on each of those creatures.| -Walk-In Closet // Forgotten Cellar|Duskmourn: House of Horror|205|M|{2}{G}|Enchantment - Room|||You may play lands from your graveyard.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Forgotten Cellar${3}{G}{G}$Enchantment -- Room$When you unlock this door, you may cast spells from your graveyard this turn, and if a card would be put into your graveyard from anywhere this turn, exile it instead.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Walk-In Closet // Forgotten Cellar|Duskmourn: House of Horror|205|M|{2}{G}","{3}{G}{G}|Enchantment - Room|||Walk-In Closet$You may play lands from your graveyard.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Forgotten Cellar$Enchantment -- Room$When you unlock this door, you may cast spells from your graveyard this turn, and if a card would be put into your graveyard from anywhere this turn, exile it instead.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Wary Watchdog|Duskmourn: House of Horror|206|C|{1}{G}|Creature - Dog|3|1|When this creature enters or dies, surveil 1.| Wickerfolk Thresher|Duskmourn: House of Horror|207|U|{3}{G}|Artifact Creature - Scarecrow|5|4|Delirium -- Whenever this creature attacks, if there are four or more card types among cards in your graveyard, look at the top card of your library. If it's a land card, you may put it onto the battlefield. If you don't put the card onto the battlefield, put it into your hand.| Arabella, Abandoned Doll|Duskmourn: House of Horror|208|U|{R}{W}|Legendary Artifact Creature - Toy|1|3|Whenever Arabella attacks, it deals X damage to each opponent and you gain X life, where X is the number of creatures you control with power 2 or less.| @@ -54207,15 +54207,15 @@ Nashi, Searcher in the Dark|Duskmourn: House of Horror|223|R|{U}{B}|Legendary Cr Niko, Light of Hope|Duskmourn: House of Horror|224|M|{2}{W}{U}|Legendary Creature - Human Wizard|3|4|When Niko enters, create two Shard tokens.${2}, {T}: Exile target nonlegendary creature you control. Shards you control become copies of it until the next end step. Return it to the battlefield under its owner's control at the beginning of the next end step.| Oblivious Bookworm|Duskmourn: House of Horror|225|U|{G}{U}|Creature - Human Wizard|2|3|At the beginning of your end step, you may draw a card. If you do, discard a card unless a permanent entered the battlefield face down under your control this turn or you turned a permanent face up this turn.| Peer Past the Veil|Duskmourn: House of Horror|226|R|{2}{R}{G}|Instant|||Discard your hand. Then draw X cards, where X is the number of card types among cards in your graveyard.| -Restricted Office // Lecture Hall|Duskmourn: House of Horror|227|R|{2}{W}{W}|Enchantment - Room|||When you unlock this door, destroy all creatures with power 3 or greater.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Lecture Hall${5}{U}{U}$Enchantment -- Room$Other permanents you control have hexproof.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Restricted Office // Lecture Hall|Duskmourn: House of Horror|227|R|{2}{W}{W}","{5}{U}{U}|Enchantment - Room|||Restricted Office$When you unlock this door, destroy all creatures with power 3 or greater.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Lecture Hall$Enchantment -- Room$Other permanents you control have hexproof.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Rip, Spawn Hunter|Duskmourn: House of Horror|228|R|{2}{G}{W}|Legendary Creature - Human Survivor|4|4|Survival -- At the beginning of your second main phase, if Rip is tapped, reveal the top X cards of your library, where X is its power. Put any number of creature and/or Vehicle cards with different powers from among them into your hand. Put the rest on the bottom of your library in a random order.| Rite of the Moth|Duskmourn: House of Horror|229|U|{1}{W}{B}{B}|Sorcery|||Return target creature card from your graveyard to the battlefield with a finality counter on it.$Flashback {3}{W}{W}{B}| -Roaring Furnace // Steaming Sauna|Duskmourn: House of Horror|230|R|{1}{R}|Enchantment - Room|||When you unlock this door, this Room deals damage equal to the number of cards in your hand to target creature an opponent controls.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Steaming Sauna${3}{U}{U}$Enchantment -- Room$You have no maximum hand size.$At the beginning of your end step, draw a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Roaring Furnace // Steaming Sauna|Duskmourn: House of Horror|230|R|{1}{R}","{3}{U}{U}|Enchantment - Room|||Roaring Furnace$When you unlock this door, this Room deals damage equal to the number of cards in your hand to target creature an opponent controls.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Steaming Sauna$Enchantment -- Room$You have no maximum hand size.$At the beginning of your end step, draw a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Sawblade Skinripper|Duskmourn: House of Horror|231|U|{1}{B}{R}|Creature - Human Assassin|3|2|Menace${2}, Sacrifice another creature or enchantment: Put a +1/+1 counter on this creature.$At the beginning of your end step, if you sacrificed one or more permanents this turn, this creature deals that much damage to any target.| Shrewd Storyteller|Duskmourn: House of Horror|232|U|{1}{G}{W}|Creature - Human Survivor|3|3|Survival -- At the beginning of your second main phase, if this creature is tapped, put a +1/+1 counter on target creature.| Shroudstomper|Duskmourn: House of Horror|233|U|{3}{W}{W}{B}{B}|Creature - Elemental|5|5|Deathtouch$Whenever this creature enters or attacks, each opponent loses 2 life. You gain 2 life and draw a card.| Skullsnap Nuisance|Duskmourn: House of Horror|234|U|{U}{B}|Creature - Insect Skeleton|1|4|Flying$Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1.| -Smoky Lounge // Misty Salon|Duskmourn: House of Horror|235|U|{2}{R}|Enchantment - Room|||At the beginning of your first main phase, add {R}{R}. Spend this mana only to cast Room spells and unlock doors.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Misty Salon${3}{U}$Enchantment -- Room$When you unlock this door, create an X/X blue Spirit creature token with flying, where X is the number of unlocked doors among Rooms you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Smoky Lounge // Misty Salon|Duskmourn: House of Horror|235|U|{2}{R}","{3}{U}|Enchantment - Room|||Smoky Lounge$At the beginning of your first main phase, add {R}{R}. Spend this mana only to cast Room spells and unlock doors.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Misty Salon$Enchantment -- Room$When you unlock this door, create an X/X blue Spirit creature token with flying, where X is the number of unlocked doors among Rooms you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| The Swarmweaver|Duskmourn: House of Horror|236|R|{2}{B}{G}|Legendary Artifact Creature - Scarecrow|2|3|When The Swarmweaver enters, create two 1/1 black and green Insect creature tokens with flying.$Delirium -- As long as there are four or more card types among cards in your graveyard, Insects and Spiders you control get +1/+1 and have deathtouch.| Undead Sprinter|Duskmourn: House of Horror|237|R|{B}{R}|Creature - Zombie|2|2|Trample, haste$You may cast this card from your graveyard if a non-Zombie creature died this turn. If you do, this creature enters with a +1/+1 counter on it.| Victor, Valgavoth's Seneschal|Duskmourn: House of Horror|238|R|{1}{W}{B}|Legendary Creature - Human Warlock|3|3|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.| @@ -54267,7 +54267,7 @@ Mountain|Duskmourn: House of Horror|283|C||Basic Land - Mountain|||({T}: Add {R} Mountain|Duskmourn: House of Horror|284|C||Basic Land - Mountain|||({T}: Add {R}.)| Forest|Duskmourn: House of Horror|285|C||Basic Land - Forest|||({T}: Add {G}.)| Forest|Duskmourn: House of Horror|286|C||Basic Land - Forest|||({T}: Add {G}.)| -Grand Entryway // Elegant Rotunda|Duskmourn: House of Horror|287|C|{1}{W}|Enchantment - Room|||When you unlock this door, create a 1/1 white Glimmer enchantment creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Elegant Rotunda${2}{W}$Enchantment -- Room$When you unlock this door, put a +1/+1 counter on each of up to two target creatures.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Grand Entryway // Elegant Rotunda|Duskmourn: House of Horror|287|C|{1}{W}","{2}{W}|Enchantment - Room|||Grand Entryway$When you unlock this door, create a 1/1 white Glimmer enchantment creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Elegant Rotunda$Enchantment -- Room$When you unlock this door, put a +1/+1 counter on each of up to two target creatures.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Optimistic Scavenger|Duskmourn: House of Horror|288|U|{W}|Creature - Human Scout|1|1|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature.| Reluctant Role Model|Duskmourn: House of Horror|289|R|{1}{W}|Creature - Human Survivor|2|2|Survival -- At the beginning of your second main phase, if this creature is tapped, put a flying, lifelink, or +1/+1 counter on it.$Whenever this creature or another creature you control dies, if it had counters on it, put those counters on up to one target creature.| Entity Tracker|Duskmourn: House of Horror|290|R|{2}{U}|Creature - Human Scout|2|3|Flash$Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, draw a card.| @@ -54314,16 +54314,16 @@ Floodfarm Verge|Duskmourn: House of Horror|330|R||Land|||{T}: Add {W}.${T}: Add Gloomlake Verge|Duskmourn: House of Horror|331|R||Land|||{T}: Add {U}.${T}: Add {B}. Activate only if you control an Island or a Swamp.| Hushwood Verge|Duskmourn: House of Horror|332|R||Land|||{T}: Add {G}.${T}: Add {W}. Activate only if you control a Forest or a Plains.| Thornspire Verge|Duskmourn: House of Horror|333|R||Land|||{T}: Add {R}.${T}: Add {G}. Activate only if you control a Mountain or a Forest.| -Dazzling Theater // Prop Room|Duskmourn: House of Horror|334|R|{3}{W}|Enchantment - Room|||Creature spells you cast have convoke.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Prop Room${2}{W}$Enchantment -- Room$Untap each creature you control during each other player's untap step.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Dollmaker's Shop // Porcelain Gallery|Duskmourn: House of Horror|335|M|{1}{W}|Enchantment - Room|||Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Porcelain Gallery${4}{W}{W}$Enchantment -- Room$Creatures you control have base power and toughness each equal to the number of creatures you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Central Elevator // Promising Stairs|Duskmourn: House of Horror|336|R|{3}{U}|Enchantment - Room|||When you unlock this door, search your library for a Room card that doesn't have the same name as a Room you control, reveal it, put it into your hand, then shuffle.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Promising Stairs${2}{U}$Enchantment -- Room$At the beginning of your upkeep, surveil 1. You win the game if there are eight or more different names among unlocked doors of Rooms you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Mirror Room // Fractured Realm|Duskmourn: House of Horror|337|M|{2}{U}|Enchantment - Room|||When you unlock this door, create a token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Fractured Realm${5}{U}{U}$Enchantment -- Room$If a triggered ability of a permanent you control triggers, that ability triggers an additional time.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Funeral Room // Awakening Hall|Duskmourn: House of Horror|338|M|{2}{B}|Enchantment - Room|||Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Awakening Hall${6}{B}{B}$Enchantment -- Room$When you unlock this door, return all creature cards from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Unholy Annex // Ritual Chamber|Duskmourn: House of Horror|339|R|{2}{B}|Enchantment - Room|||At the beginning of your end step, draw a card. If you control a Demon, each opponent loses 2 life and you gain 2 life. Otherwise, you lose 2 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Ritual Chamber${3}{B}{B}$Enchantment -- Room$When you unlock this door, create a 6/6 black Demon creature token with flying.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Charred Foyer // Warped Space|Duskmourn: House of Horror|340|M|{3}{R}|Enchantment - Room|||At the beginning of your upkeep, exile the top card of your library. You may play it this turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Warped Space${4}{R}{R}$Enchantment -- Room$Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast from exile.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Walk-In Closet // Forgotten Cellar|Duskmourn: House of Horror|341|M|{2}{G}|Enchantment - Room|||You may play lands from your graveyard.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Forgotten Cellar${3}{G}{G}$Enchantment -- Room$When you unlock this door, you may cast spells from your graveyard this turn, and if a card would be put into your graveyard from anywhere this turn, exile it instead.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Restricted Office // Lecture Hall|Duskmourn: House of Horror|342|R|{2}{W}{W}|Enchantment - Room|||When you unlock this door, destroy all creatures with power 3 or greater.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Lecture Hall${5}{U}{U}$Enchantment -- Room$Other permanents you control have hexproof.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| -Roaring Furnace // Steaming Sauna|Duskmourn: House of Horror|343|R|{1}{R}|Enchantment - Room|||When you unlock this door, this Room deals damage equal to the number of cards in your hand to target creature an opponent controls.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Steaming Sauna${3}{U}{U}$Enchantment -- Room$You have no maximum hand size.$At the beginning of your end step, draw a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Dazzling Theater // Prop Room|Duskmourn: House of Horror|334|R|{3}{W}","{2}{W}|Enchantment - Room|||Dazzling Theater$Creature spells you cast have convoke.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Prop Room$Enchantment -- Room$Untap each creature you control during each other player's untap step.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Dollmaker's Shop // Porcelain Gallery|Duskmourn: House of Horror|335|M|{1}{W}","{4}{W}{W}|Enchantment - Room|||Dollmaker's Shop$Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Porcelain Gallery$Enchantment -- Room$Creatures you control have base power and toughness each equal to the number of creatures you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Central Elevator // Promising Stairs|Duskmourn: House of Horror|336|R|{3}{U}","{2}{U}|Enchantment - Room|||Central Elevator$When you unlock this door, search your library for a Room card that doesn't have the same name as a Room you control, reveal it, put it into your hand, then shuffle.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Promising Stairs$Enchantment -- Room$At the beginning of your upkeep, surveil 1. You win the game if there are eight or more different names among unlocked doors of Rooms you control.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Mirror Room // Fractured Realm|Duskmourn: House of Horror|337|M|{2}{U}","{5}{U}{U}|Enchantment - Room|||Mirror Room$When you unlock this door, create a token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Fractured Realm$Enchantment -- Room$If a triggered ability of a permanent you control triggers, that ability triggers an additional time.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Funeral Room // Awakening Hall|Duskmourn: House of Horror|338|M|{2}{B}","{6}{B}{B}|Enchantment - Room|||Funeral Room$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Awakening Hall$Enchantment -- Room$When you unlock this door, return all creature cards from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Unholy Annex // Ritual Chamber|Duskmourn: House of Horror|339|R|{2}{B}","{3}{B}{B}|Enchantment - Room|||Unholy Annex$At the beginning of your end step, draw a card. If you control a Demon, each opponent loses 2 life and you gain 2 life. Otherwise, you lose 2 life.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Ritual Chamber$Enchantment -- Room$When you unlock this door, create a 6/6 black Demon creature token with flying.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Charred Foyer // Warped Space|Duskmourn: House of Horror|340|M|{3}{R}","{4}{R}{R}|Enchantment - Room|||Charred Foyer$At the beginning of your upkeep, exile the top card of your library. You may play it this turn.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Warped Space$Enchantment -- Room$Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast from exile.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Walk-In Closet // Forgotten Cellar|Duskmourn: House of Horror|341|M|{2}{G}","{3}{G}{G}|Enchantment - Room|||Walk-In Closet$You may play lands from your graveyard.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Forgotten Cellar$Enchantment -- Room$When you unlock this door, you may cast spells from your graveyard this turn, and if a card would be put into your graveyard from anywhere this turn, exile it instead.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Restricted Office // Lecture Hall|Duskmourn: House of Horror|342|R|{2}{W}{W}","{5}{U}{U}|Enchantment - Room|||Restricted Office$When you unlock this door, destroy all creatures with power 3 or greater.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Lecture Hall$Enchantment -- Room$Other permanents you control have hexproof.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Roaring Furnace // Steaming Sauna|Duskmourn: House of Horror|343|R|{1}{R}","{3}{U}{U}|Enchantment - Room|||Roaring Furnace$When you unlock this door, this Room deals damage equal to the number of cards in your hand to target creature an opponent controls.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Steaming Sauna$Enchantment -- Room$You have no maximum hand size.$At the beginning of your end step, draw a card.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Abhorrent Oculus|Duskmourn: House of Horror|344|M|{2}{U}|Creature - Eye|5|5|As an additional cost to cast this spell, exile six cards from your graveyard.$Flying$At the beginning of each opponent's upkeep, manifest dread.| Silent Hallcreeper|Duskmourn: House of Horror|345|R|{1}{U}|Enchantment Creature - Horror|1|1|This creature can't be blocked.$Whenever this creature deals combat damage to a player, choose one that hasn't been chosen --$* Put two +1/+1 counters on this creature.$* Draw a card.$* This creature becomes a copy of another target creature you control.| Doomsday Excruciator|Duskmourn: House of Horror|346|R|{B}{B}{B}{B}{B}{B}|Creature - Demon|6|6|Flying$When this creature enters, if it was cast, each player exiles all but the bottom six cards of their library face down.$At the beginning of your upkeep, draw a card.| @@ -55243,44 +55243,71 @@ Aminatou, Veil Piercer|Duskmourn: House of Horror Commander|1|M|{1}{W}{U}{B}|Leg Kianne, Corrupted Memory|Duskmourn: House of Horror Commander|2|M|{2}{G}{U}|Legendary Creature - Illusion|2|2|As long as Kianne's power is even, you may cast noncreature spells as though they had flash.$As long as Kianne's power is odd, you may cast creature spells as though they had flash.$Whenever you draw a card, put a +1/+1 counter on Kianne.| The Lord of Pain|Duskmourn: House of Horror Commander|3|M|{3}{B}{R}|Legendary Creature - Human Assassin|5|5|Menace$Your opponents can't gain life.$Whenever a player casts their first spell each turn, choose another target player. The Lord of Pain deals damage equal to that spell's mana value to the chosen player.| The Master of Keys|Duskmourn: House of Horror Commander|4|M|{X}{W}{U}{B}|Legendary Enchantment Creature - Horror|3|3|Flying$When The Master of Keys enters, put X +1/+1 counters on it and mill twice X cards.$Each enchantment card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard.| -Rendmaw, Creaking Nest|Duskmourn: House of Horror Commander|5|M|{3}{B}{G}|Legendary Artifact Creature - Scarecrow|5|5|Menace, reach$When Rendmaw, Creaking Nest enters and whenever you play a card with two or more card types, each player creates a tapped 2/2 black Bird creature token with flying. The tokens are goaded for the rest of the game.| -Valgavoth, Harrower of Souls|Duskmourn: House of Horror Commander|6|M|{2}{B}{R}|Legendary Creature - Elder Demon|4|4|Flying$Ward--Pay 2 life.$Whenever an opponent loses life for the first time during each of their turns, put a +1/+1 counter on Valgavoth, Harrower of Souls and draw a card.| +Rendmaw, Creaking Nest|Duskmourn: House of Horror Commander|5|M|{3}{B}{G}|Legendary Artifact Creature - Scarecrow|5|5|Menace, reach$When Rendmaw enters and whenever you play a card with two or more card types, each player creates a tapped 2/2 black Bird creature token with flying. The tokens are goaded for the rest of the game.| +Valgavoth, Harrower of Souls|Duskmourn: House of Horror Commander|6|M|{2}{B}{R}|Legendary Creature - Elder Demon|4|4|Flying$Ward--Pay 2 life.$Whenever an opponent loses life for the first time during each of their turns, put a +1/+1 counter on Valgavoth and draw a card.| Winter, Cynical Opportunist|Duskmourn: House of Horror Commander|7|M|{2}{B}{G}|Legendary Creature - Human Warlock|2|5|Deathtouch$Whenever Winter attacks, mill three cards.$Delirium -- At the beginning of your end step, you may exile any number of cards from your graveyard with four or more card types among them. If you do, put a permanent card from among them onto the battlefield with a finality counter on it.| Zimone, Mystery Unraveler|Duskmourn: House of Horror Commander|8|M|{2}{G}{U}|Legendary Creature - Human Wizard|3|3|Landfall -- Whenever a land you control enters, manifest dread if this is the first time this ability has resolved this turn. Otherwise, you may turn a permanent you control face up.| Redress Fate|Duskmourn: House of Horror Commander|9|R|{6}{W}{W}|Sorcery|||Return all artifact and enchantment cards from your graveyard to the battlefield.$Miracle {3}{W}| -Secret Arcade // Dusty Parlor|Duskmourn: House of Horror Commander|10|R|{4}{W}|Enchantment - Room|||(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Nonland permanents you control and permanent spells you control are enchantments in addition to their other types.$Dusty Parlor${2}{W}$Enchantment -- Room$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Whenever you cast an enchantment spell, put a number of +1/+1 counters equal to that spell's mana value on up to one target creature.| +Secret Arcade // Dusty Parlor|Duskmourn: House of Horror Commander|10|R|{4}{W}","{2}{W}|Enchantment - Room|||Secret Arcade$Nonland permanents you control and permanent spells you control are enchantments in addition to their other types.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Dusty Parlor$Enchantment -- Room$Whenever you cast an enchantment spell, put a number of +1/+1 counters equal to that spell's mana value on up to one target creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Soaring Lightbringer|Duskmourn: House of Horror Commander|11|R|{4}{W}|Enchantment Creature - Bird Glimmer|4|5|Flying$Other enchantment creatures you control have flying.$Whenever you attack a player, create a 1/1 white Glimmer enchantment creature token that's tapped and attacking that player.| -Fear of Sleep Paralysis|Duskmourn: House of Horror Commander|12|R|{5}{U}|Enchantment Creature - Nightmare|6|6|Flying$Eerie -- Whenever Fear of Sleep Paralysis or another enchantment you control enters and whenever you fully unlock a Room, tap up to one target creature and put a stun counter on it.$Stun counters can't be removed from permanents your opponents control.| -Glitch Interpreter|Duskmourn: House of Horror Commander|13|R|{2}{U}|Creature - Human Wizard|2|3|When Glitch Interpreter enters, if you control no face-down permanents, return Glitch Interpreter to its owner's hand and manifest dread.$Whenever one or more colorless creatures you control deal combat damage to a player, draw a card.| -They Came from the Pipes|Duskmourn: House of Horror Commander|14|R|{4}{U}|Enchantment|||When They Came from the Pipes enters, manifest dread twice.$Whenever a face-down creature you control enters, draw a card.| +Fear of Sleep Paralysis|Duskmourn: House of Horror Commander|12|R|{5}{U}|Enchantment Creature - Nightmare|6|6|Flying$Eerie -- Whenever this creature or another enchantment you control enters and whenever you fully unlock a Room, tap up to one target creature and put a stun counter on it.$Stun counters can't be removed from permanents your opponents control.| +Glitch Interpreter|Duskmourn: House of Horror Commander|13|R|{2}{U}|Creature - Human Wizard|2|3|When this creature enters, if you control no face-down permanents, return this creature to its owner's hand and manifest dread.$Whenever one or more colorless creatures you control deal combat damage to a player, draw a card.| +They Came from the Pipes|Duskmourn: House of Horror Commander|14|R|{4}{U}|Enchantment|||When this enchantment enters, manifest dread twice.$Whenever a face-down creature you control enters, draw a card.| Zimone's Hypothesis|Duskmourn: House of Horror Commander|15|R|{3}{U}{U}|Instant|||You may put a +1/+1 counter on a creature. Then choose odd or even. Return each creature with power of the chosen quality to its owner's hand.| Ancient Cellarspawn|Duskmourn: House of Horror Commander|16|R|{1}{B}{B}|Enchantment Creature - Horror|3|3|Each spell you cast that's a Demon, Horror, or Nightmare costs {1} less to cast.$Whenever you cast a spell, if the amount of mana spent to cast it was less than its mana value, target opponent loses life equal to the difference.| -Cramped Vents // Access Maze|Duskmourn: House of Horror Commander|17|R|{3}{B}|Enchantment - Room|||(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$When you unlock this door, this Room deals 6 damage to target creature an opponent controls. You gain life equal to the excess damage dealt this way.$Access Maze${5}{B}{B}$Enchantment -- Room$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Once during each of your turns, you may cast a spell from your hand by paying life equal to its mana value rather than paying its mana cost.| +Cramped Vents // Access Maze|Duskmourn: House of Horror Commander|17|R|{3}{B}","{5}{B}{B}|Enchantment - Room|||Cramped Vents$When you unlock this door, this Room deals 6 damage to target creature an opponent controls. You gain life equal to the excess damage dealt this way.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Access Maze$Enchantment -- Room$Once during each of your turns, you may cast a spell from your hand by paying life equal to its mana value rather than paying its mana cost.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Deluge of Doom|Duskmourn: House of Horror Commander|18|R|{2}{B}|Sorcery|||All creatures get -X/-X until end of turn, where X is the number of card types among cards in your graveyard.| -Demonic Covenant|Duskmourn: House of Horror Commander|19|R|{4}{B}{B}|Kindred Enchantment - Demon|||Whenever one or more Demons you control attack a player, you draw a card and lose 1 life.$At the beginning of your end step, create a 5/5 black Demon creature token with flying, then mill two cards. If two cards that share all their card types were milled this way, sacrifice Demonic Covenant.| +Demonic Covenant|Duskmourn: House of Horror Commander|19|R|{4}{B}{B}|Kindred Enchantment - Demon|||Whenever one or more Demons you control attack a player, you draw a card and lose 1 life.$At the beginning of your end step, create a 5/5 black Demon creature token with flying, then mill two cards. If two cards that share all their card types were milled this way, sacrifice this enchantment.| Into the Pit|Duskmourn: House of Horror Commander|20|R|{2}{B}|Enchantment|||You may look at the top card of your library any time.$You may cast spells from the top of your library by sacrificing a nonland permanent in addition to paying their other costs.| -Metamorphosis Fanatic|Duskmourn: House of Horror Commander|21|R|{4}{B}{B}|Creature - Human Cleric|4|4|Lifelink$When Metamorphosis Fanatic enters, return up to one target creature card from your graveyard to the battlefield with a lifelink counter on it.$Miracle {1}{B}| +Metamorphosis Fanatic|Duskmourn: House of Horror Commander|21|R|{4}{B}{B}|Creature - Human Cleric|4|4|Lifelink$When this creature enters, return up to one target creature card from your graveyard to the battlefield with a lifelink counter on it.$Miracle {1}{B}| Persistent Constrictor|Duskmourn: House of Horror Commander|22|R|{4}{B}|Creature - Zombie Snake|5|3|At the beginning of each opponent's upkeep, they lose 1 life and you put a -1/-1 counter on up to one target creature they control.$Persist| -Polluted Cistern // Dim Oubliette|Duskmourn: House of Horror Commander|23|R|{1}{B}|Enchantment - Room|||(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Whenever one or more cards are put into your graveyard from your library, each opponent loses 1 life for each card type among those cards.$Dim Oubliette${4}{B}$Enchantment -- Room$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$When you unlock this door, mill three cards, then return a creature card from your graveyard to the battlefield.| +Polluted Cistern // Dim Oubliette|Duskmourn: House of Horror Commander|23|R|{1}{B}","{4}{B}|Enchantment - Room|||Polluted Cistern$Whenever one or more cards are put into your graveyard from your library, each opponent loses 1 life for each card type among those cards.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Dim Oubliette$Enchantment -- Room$When you unlock this door, mill three cards, then return a creature card from your graveyard to the battlefield.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Sadistic Shell Game|Duskmourn: House of Horror Commander|24|R|{4}{B}|Sorcery|||Starting with the next opponent in turn order, each player chooses a creature you don't control. Destroy the chosen creatures.| Suspended Sentence|Duskmourn: House of Horror Commander|25|R|{3}{B}|Instant|||Destroy target creature an opponent controls. That player loses 3 life. Exile Suspended Sentence with three time counters on it.$Suspend 3--{1}{B}| -Barbflare Gremlin|Duskmourn: House of Horror Commander|26|R|{3}{R}|Creature - Gremlin|3|2|First strike, haste$Whenever a player taps a land for mana, if Barbflare Gremlin is tapped, that player adds one mana of any type that land produced. Then that land deals 1 damage to that player.| -Gleeful Arsonist|Duskmourn: House of Horror Commander|27|R|{2}{R}|Creature - Human Wizard|1|2|Whenever an opponent casts a noncreature spell, Gleeful Arsonist deals damage equal to its power to that player.$Undying| -Spiked Corridor // Torture Pit|Duskmourn: House of Horror Commander|28|R|{3}{R}|Enchantment - Room|||(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$When you unlock this door, create three 1/1 red Devil creature tokens with "When this creature dies, it deals 1 damage to any target."$Torture Pit${3}{R}$Enchantment -- Room$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$If a source you control would deal noncombat damage to an opponent, it deals that much damage plus 2 instead.| -Star Athlete|Duskmourn: House of Horror Commander|29|R|{1}{R}{R}|Creature - Human Warrior|3|2|Menace$Whenever Star Athlete attacks, choose up to one target nonland permanent. Its controller may sacrifice it. If they don't, Star Athlete deals 5 damage to that player.$Blitz {3}{R}| -Curator Beastie|Duskmourn: House of Horror Commander|30|R|{4}{G}{G}|Creature - Beast|6|6|Reach$Colorless creatures you control enter with two additional +1/+1 counters on them.$Whenever Curator Beastie enters or attacks, manifest dread.| -Demolisher Spawn|Duskmourn: House of Horror Commander|31|R|{5}{G}{G}|Enchantment Creature - Horror|7|7|Trample, haste$Delirium -- Whenever Demolisher Spawn attacks, if there are four or more card types among cards in your graveyard, other attacking creatures get +4/+4 until end of turn.| +Barbflare Gremlin|Duskmourn: House of Horror Commander|26|R|{3}{R}|Creature - Gremlin|3|2|First strike, haste$Whenever a player taps a land for mana, if this creature is tapped, that player adds one mana of any type that land produced. Then that land deals 1 damage to that player.| +Gleeful Arsonist|Duskmourn: House of Horror Commander|27|R|{2}{R}|Creature - Human Wizard|1|2|Whenever an opponent casts a noncreature spell, this creature deals damage equal to its power to that player.$Undying| +Spiked Corridor // Torture Pit|Duskmourn: House of Horror Commander|28|R|{3}{R}","{3}{R}|Enchantment - Room|||Spiked Corridor$When you unlock this door, create three 1/1 red Devil creature tokens with "When this token dies, it deals 1 damage to any target."$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Torture Pit$Enchantment -- Room$If a source you control would deal noncombat damage to an opponent, it deals that much damage plus 2 instead.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| +Star Athlete|Duskmourn: House of Horror Commander|29|R|{1}{R}{R}|Creature - Human Warrior|3|2|Menace$Whenever this creature attacks, choose up to one target nonland permanent. Its controller may sacrifice it. If they don't, this creature deals 5 damage to that player.$Blitz {3}{R}| +Curator Beastie|Duskmourn: House of Horror Commander|30|R|{4}{G}{G}|Creature - Beast|6|6|Reach$Colorless creatures you control enter with two additional +1/+1 counters on them.$Whenever this creature enters or attacks, manifest dread.| +Demolisher Spawn|Duskmourn: House of Horror Commander|31|R|{5}{G}{G}|Enchantment Creature - Horror|7|7|Trample, haste$Delirium -- Whenever this creature attacks, if there are four or more card types among cards in your graveyard, other attacking creatures get +4/+4 until end of turn.| Disorienting Choice|Duskmourn: House of Horror Commander|32|R|{3}{G}|Sorcery|||For each opponent, choose up to one target artifact or enchantment that player controls. For each permanent chosen this way, its controller may exile it. Then if one or more of the chosen permanents are still on the battlefield, you search your library for up to that many land cards, put them onto the battlefield tapped, then shuffle.| -Experimental Lab // Staff Room|Duskmourn: House of Horror Commander|33|R|{3}{G}|Enchantment - Room|||(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$When you unlock this door, manifest dread, then put two +1/+1 counters and a trample counter on that creature.$Staff Room${2}{G}$Enchantment -- Room$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Whenever a creature you control deals combat damage to a player, turn that creature face up or put a +1/+1 counter on it.| +Experimental Lab // Staff Room|Duskmourn: House of Horror Commander|33|R|{3}{G}","{2}{G}|Enchantment - Room|||Experimental Lab$When you unlock this door, manifest dread, then put two +1/+1 counters and a trample counter on that creature.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$Staff Room$Enchantment -- Room$Whenever a creature you control deals combat damage to a player, turn that creature face up or put a +1/+1 counter on it.$(You may cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)| Formless Genesis|Duskmourn: House of Horror Commander|34|R|{2}{G}|Kindred Sorcery - Shapeshifter|||Changeling$Create an X/X colorless Shapeshifter creature token with changeling and deathtouch, where X is the number of land cards in your graveyard.$Retrace| Shriekwood Devourer|Duskmourn: House of Horror Commander|35|R|{5}{G}{G}|Creature - Treefolk|7|5|Trample$Whenever you attack with one or more creatures, untap up to X lands, where X is the greatest power among those creatures.| -Ursine Monstrosity|Duskmourn: House of Horror Commander|36|R|{2}{G}|Creature - Bear Mutant|3|3|Trample$At the beginning of combat on your turn, mill a card and choose an opponent at random. Ursine Monstrosity attacks that player this combat if able. Until end of turn, Ursine Monstrosity gains indestructible and gets +1/+1 for each card type among cards in your graveyard.| +Ursine Monstrosity|Duskmourn: House of Horror Commander|36|R|{2}{G}|Creature - Bear Mutant|3|3|Trample$At the beginning of combat on your turn, mill a card and choose an opponent at random. This creature attacks that player this combat if able. Until end of turn, this creature gains indestructible and gets +1/+1 for each card type among cards in your graveyard.| Convert to Slime|Duskmourn: House of Horror Commander|37|R|{3}{B}{G}|Sorcery|||Destroy up to one target artifact, up to one target creature, and up to one target enchantment.$Delirium -- Then if there are four or more card types among cards in your graveyard, create an X/X green Ooze creature token, where X is the total mana value of permanents destroyed this way.| -Phenomenon Investigators|Duskmourn: House of Horror Commander|38|R|{2}{U}{B}|Creature - Human Detective|3|4|As Phenomenon Investigators enters, choose Believe or Doubt.$* Believe -- Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token.$* Doubt -- At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card.| -Giggling Skitterspike|Duskmourn: House of Horror Commander|39|R|{4}|Artifact Creature - Toy|1|1|Indestructible$Whenever Giggling Skitterspike attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent.${5}: Monstrosity 5.| -Seance Board|Duskmourn: House of Horror Commander|40|R|{2}|Artifact|||Morbid -- At the beginning of each end step, if a creature died this turn, put a soul counter on Seance Board.${T}: Add X mana of any one color, where X is the number of soul counters on Seance Board. Spend this mana only to cast instant, sorcery, Demon, and Spirit spells.| +Phenomenon Investigators|Duskmourn: House of Horror Commander|38|R|{2}{U}{B}|Creature - Human Detective|3|4|As this creature enters, choose Believe or Doubt.$* Believe -- Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token.$* Doubt -- At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card.| +Giggling Skitterspike|Duskmourn: House of Horror Commander|39|R|{4}|Artifact Creature - Toy|1|1|Indestructible$Whenever this creature attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent.${5}: Monstrosity 5.| +Seance Board|Duskmourn: House of Horror Commander|40|R|{2}|Artifact|||Morbid -- At the beginning of each end step, if a creature died this turn, put a soul counter on this artifact.${T}: Add X mana of any one color, where X is the number of soul counters on this artifact. Spend this mana only to cast instant, sorcery, Demon, and Spirit spells.| +Redress Fate|Duskmourn: House of Horror Commander|41|R|{6}{W}{W}|Sorcery|||Return all artifact and enchantment cards from your graveyard to the battlefield.$Miracle {3}{W}| +Soaring Lightbringer|Duskmourn: House of Horror Commander|42|R|{4}{W}|Enchantment Creature - Bird Glimmer|4|5|Flying$Other enchantment creatures you control have flying.$Whenever you attack a player, create a 1/1 white Glimmer enchantment creature token that's tapped and attacking that player.| +Fear of Sleep Paralysis|Duskmourn: House of Horror Commander|43|R|{5}{U}|Enchantment Creature - Nightmare|6|6|Flying$Eerie -- Whenever this creature or another enchantment you control enters and whenever you fully unlock a Room, tap up to one target creature and put a stun counter on it.$Stun counters can't be removed from permanents your opponents control.| +Glitch Interpreter|Duskmourn: House of Horror Commander|44|R|{2}{U}|Creature - Human Wizard|2|3|When this creature enters, if you control no face-down permanents, return this creature to its owner's hand and manifest dread.$Whenever one or more colorless creatures you control deal combat damage to a player, draw a card.| +They Came from the Pipes|Duskmourn: House of Horror Commander|45|R|{4}{U}|Enchantment|||When this enchantment enters, manifest dread twice.$Whenever a face-down creature you control enters, draw a card.| +Zimone's Hypothesis|Duskmourn: House of Horror Commander|46|R|{3}{U}{U}|Instant|||You may put a +1/+1 counter on a creature. Then choose odd or even. Return each creature with power of the chosen quality to its owner's hand.| +Ancient Cellarspawn|Duskmourn: House of Horror Commander|47|R|{1}{B}{B}|Enchantment Creature - Horror|3|3|Each spell you cast that's a Demon, Horror, or Nightmare costs {1} less to cast.$Whenever you cast a spell, if the amount of mana spent to cast it was less than its mana value, target opponent loses life equal to the difference.| +Deluge of Doom|Duskmourn: House of Horror Commander|48|R|{2}{B}|Sorcery|||All creatures get -X/-X until end of turn, where X is the number of card types among cards in your graveyard.| +Demonic Covenant|Duskmourn: House of Horror Commander|49|R|{4}{B}{B}|Kindred Enchantment - Demon|||Whenever one or more Demons you control attack a player, you draw a card and lose 1 life.$At the beginning of your end step, create a 5/5 black Demon creature token with flying, then mill two cards. If two cards that share all their card types were milled this way, sacrifice this enchantment.| +Into the Pit|Duskmourn: House of Horror Commander|50|R|{2}{B}|Enchantment|||You may look at the top card of your library any time.$You may cast spells from the top of your library by sacrificing a nonland permanent in addition to paying their other costs.| +Metamorphosis Fanatic|Duskmourn: House of Horror Commander|51|R|{4}{B}{B}|Creature - Human Cleric|4|4|Lifelink$When this creature enters, return up to one target creature card from your graveyard to the battlefield with a lifelink counter on it.$Miracle {1}{B}| +Persistent Constrictor|Duskmourn: House of Horror Commander|52|R|{4}{B}|Creature - Zombie Snake|5|3|At the beginning of each opponent's upkeep, they lose 1 life and you put a -1/-1 counter on up to one target creature they control.$Persist| +Sadistic Shell Game|Duskmourn: House of Horror Commander|53|R|{4}{B}|Sorcery|||Starting with the next opponent in turn order, each player chooses a creature you don't control. Destroy the chosen creatures.| +Suspended Sentence|Duskmourn: House of Horror Commander|54|R|{3}{B}|Instant|||Destroy target creature an opponent controls. That player loses 3 life. Exile Suspended Sentence with three time counters on it.$Suspend 3--{1}{B}| +Barbflare Gremlin|Duskmourn: House of Horror Commander|55|R|{3}{R}|Creature - Gremlin|3|2|First strike, haste$Whenever a player taps a land for mana, if this creature is tapped, that player adds one mana of any type that land produced. Then that land deals 1 damage to that player.| +Gleeful Arsonist|Duskmourn: House of Horror Commander|56|R|{2}{R}|Creature - Human Wizard|1|2|Whenever an opponent casts a noncreature spell, this creature deals damage equal to its power to that player.$Undying| +Star Athlete|Duskmourn: House of Horror Commander|57|R|{1}{R}{R}|Creature - Human Warrior|3|2|Menace$Whenever this creature attacks, choose up to one target nonland permanent. Its controller may sacrifice it. If they don't, this creature deals 5 damage to that player.$Blitz {3}{R}| +Curator Beastie|Duskmourn: House of Horror Commander|58|R|{4}{G}{G}|Creature - Beast|6|6|Reach$Colorless creatures you control enter with two additional +1/+1 counters on them.$Whenever this creature enters or attacks, manifest dread.| +Demolisher Spawn|Duskmourn: House of Horror Commander|59|R|{5}{G}{G}|Enchantment Creature - Horror|7|7|Trample, haste$Delirium -- Whenever this creature attacks, if there are four or more card types among cards in your graveyard, other attacking creatures get +4/+4 until end of turn.| +Disorienting Choice|Duskmourn: House of Horror Commander|60|R|{3}{G}|Sorcery|||For each opponent, choose up to one target artifact or enchantment that player controls. For each permanent chosen this way, its controller may exile it. Then if one or more of the chosen permanents are still on the battlefield, you search your library for up to that many land cards, put them onto the battlefield tapped, then shuffle.| +Formless Genesis|Duskmourn: House of Horror Commander|61|R|{2}{G}|Kindred Sorcery - Shapeshifter|||Changeling$Create an X/X colorless Shapeshifter creature token with changeling and deathtouch, where X is the number of land cards in your graveyard.$Retrace| +Shriekwood Devourer|Duskmourn: House of Horror Commander|62|R|{5}{G}{G}|Creature - Treefolk|7|5|Trample$Whenever you attack with one or more creatures, untap up to X lands, where X is the greatest power among those creatures.| +Ursine Monstrosity|Duskmourn: House of Horror Commander|63|R|{2}{G}|Creature - Bear Mutant|3|3|Trample$At the beginning of combat on your turn, mill a card and choose an opponent at random. This creature attacks that player this combat if able. Until end of turn, this creature gains indestructible and gets +1/+1 for each card type among cards in your graveyard.| +Convert to Slime|Duskmourn: House of Horror Commander|64|R|{3}{B}{G}|Sorcery|||Destroy up to one target artifact, up to one target creature, and up to one target enchantment.$Delirium -- Then if there are four or more card types among cards in your graveyard, create an X/X green Ooze creature token, where X is the total mana value of permanents destroyed this way.| +Phenomenon Investigators|Duskmourn: House of Horror Commander|65|R|{2}{U}{B}|Creature - Human Detective|3|4|As this creature enters, choose Believe or Doubt.$* Believe -- Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token.$* Doubt -- At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card.| +Giggling Skitterspike|Duskmourn: House of Horror Commander|66|R|{4}|Artifact Creature - Toy|1|1|Indestructible$Whenever this creature attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent.${5}: Monstrosity 5.| +Seance Board|Duskmourn: House of Horror Commander|67|R|{2}|Artifact|||Morbid -- At the beginning of each end step, if a creature died this turn, put a soul counter on this artifact.${T}: Add X mana of any one color, where X is the number of soul counters on this artifact. Spend this mana only to cast instant, sorcery, Demon, and Spirit spells.| Mesa Enchantress|Duskmourn: House of Horror Commander|68|R|{1}{W}{W}|Creature - Human Druid|0|2|Whenever you cast an enchantment spell, you may draw a card.| -Moon-Blessed Cleric|Duskmourn: House of Horror Commander|69|U|{2}{W}|Creature - Human Elf Cleric|3|2|Divine Intervention -- When Moon-Blessed Cleric enters, you may search your library for an enchantment card, reveal it, then shuffle and put that card on top.| +Moon-Blessed Cleric|Duskmourn: House of Horror Commander|69|U|{2}{W}|Creature - Human Elf Cleric|3|2|Divine Intervention -- When this creature enters, you may search your library for an enchantment card, reveal it, then shuffle and put that card on top.| Terminus|Duskmourn: House of Horror Commander|70|R|{4}{W}{W}|Sorcery|||Put all creatures on the bottom of their owners' libraries.$Miracle {W}| Aminatou's Augury|Duskmourn: House of Horror Commander|71|R|{6}{U}{U}|Sorcery|||Exile the top eight cards of your library. You may put a land card from among them onto the battlefield. Until end of turn, for each nonland card type, you may cast a spell of that type from among the exiled cards without paying its mana cost.| Cackling Counterpart|Duskmourn: House of Horror Commander|72|R|{1}{U}{U}|Instant|||Create a token that's a copy of target creature you control.$Flashback {5}{U}{U}| @@ -55294,13 +55321,13 @@ Night's Whisper|Duskmourn: House of Horror Commander|79|C|{1}{B}|Sorcery|||You d Beast Within|Duskmourn: House of Horror Commander|80|U|{2}{G}|Instant|||Destroy target permanent. Its controller creates a 3/3 green Beast creature token.| Citanul Hierophants|Duskmourn: House of Horror Commander|81|R|{3}{G}|Creature - Human Druid|3|2|Creatures you control have "{T}: Add {G}."| Grapple with the Past|Duskmourn: House of Horror Commander|82|C|{1}{G}|Instant|||Mill three cards, then you may return a creature or land card from your graveyard to your hand.| -Moldgraf Monstrosity|Duskmourn: House of Horror Commander|83|R|{4}{G}{G}{G}|Creature - Insect|8|8|Trample$When Moldgraf Monstrosity dies, exile it, then return two creature cards at random from your graveyard to the battlefield.| +Moldgraf Monstrosity|Duskmourn: House of Horror Commander|83|R|{4}{G}{G}{G}|Creature - Insect|8|8|Trample$When this creature dies, exile it, then return two creature cards at random from your graveyard to the battlefield.| Bedevil|Duskmourn: House of Horror Commander|84|R|{B}{B}{R}|Instant|||Destroy target artifact, creature, or planeswalker.| Culling Ritual|Duskmourn: House of Horror Commander|85|R|{2}{B}{G}|Sorcery|||Destroy each nonland permanent with mana value 2 or less. Add {B} or {G} for each permanent destroyed this way.| Deathreap Ritual|Duskmourn: House of Horror Commander|86|U|{2}{B}{G}|Enchantment|||Morbid -- At the beginning of each end step, if a creature died this turn, you may draw a card.| Diabolic Vision|Duskmourn: House of Horror Commander|87|U|{U}{B}|Sorcery|||Look at the top five cards of your library. Put one of them into your hand and the rest on top of your library in any order.| Growth Spiral|Duskmourn: House of Horror Commander|88|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.| -Mogis, God of Slaughter|Duskmourn: House of Horror Commander|89|M|{2}{B}{R}|Legendary Enchantment Creature - God|7|5|Indestructible$As long as your devotion to black and red is less than seven, Mogis isn't a creature.$At the beginning of each opponent's upkeep, Mogis deals 2 damage to that player unless they sacrifice a creature.| +Mogis, God of Slaughter|Duskmourn: House of Horror Commander|89|M|{2}{B}{R}|Legendary Enchantment Creature - God|7|5|Indestructible$As long as your devotion to black and red is less than seven, Mogis isn't a creature.$At the beginning of each opponent's upkeep, Mogis deals 2 damage to that player unless they sacrifice a creature of their choice.| Putrefy|Duskmourn: House of Horror Commander|90|U|{1}{B}{G}|Instant|||Destroy target artifact or creature. It can't be regenerated.| Utter End|Duskmourn: House of Horror Commander|91|R|{2}{W}{B}|Instant|||Exile target nonland permanent.| Arcane Signet|Duskmourn: House of Horror Commander|92|C|{2}|Artifact|||{T}: Add one mana of any color in your commander's color identity.| @@ -55308,242 +55335,242 @@ Lightning Greaves|Duskmourn: House of Horror Commander|93|U|{2}|Artifact - Equip Sol Ring|Duskmourn: House of Horror Commander|94|U|{1}|Artifact|||{T}: Add {C}{C}.| Suspicious Bookcase|Duskmourn: House of Horror Commander|95|U|{2}|Artifact Creature - Wall|0|4|Defender${3}, {T}: Target creature can't be blocked this turn.| Command Tower|Duskmourn: House of Horror Commander|96|C||Land|||{T}: Add one mana of any color in your commander's color identity.| -Auramancer|Duskmourn: House of Horror Commander|97|C|{2}{W}|Creature - Human Wizard|2|2|When Auramancer enters, you may return target enchantment card from your graveyard to your hand.| -Cast Out|Duskmourn: House of Horror Commander|98|U|{3}{W}|Enchantment|||Flash$When Cast Out enters, exile target nonland permanent an opponent controls until Cast Out leaves the battlefield.$Cycling {W}| +Auramancer|Duskmourn: House of Horror Commander|97|C|{2}{W}|Creature - Human Wizard|2|2|When this creature enters, you may return target enchantment card from your graveyard to your hand.| +Cast Out|Duskmourn: House of Horror Commander|98|U|{3}{W}|Enchantment|||Flash$When this enchantment enters, exile target nonland permanent an opponent controls until this enchantment leaves the battlefield.$Cycling {W}| Entreat the Angels|Duskmourn: House of Horror Commander|99|M|{X}{X}{W}{W}{W}|Sorcery|||Create X 4/4 white Angel creature tokens with flying.$Miracle {X}{W}{W}| Monologue Tax|Duskmourn: House of Horror Commander|100|R|{2}{W}|Enchantment|||Whenever an opponent casts their second spell each turn, you create a Treasure token.| Ondu Spiritdancer|Duskmourn: House of Horror Commander|101|R|{4}{W}|Creature - Kor Cleric|3|3|Whenever an enchantment you control enters, you may create a token that's a copy of it. Do this only once each turn.| Return to Dust|Duskmourn: House of Horror Commander|102|U|{2}{W}{W}|Instant|||Exile target artifact or enchantment. If you cast this spell during your main phase, you may exile up to one other target artifact or enchantment.| Sigil of the Empty Throne|Duskmourn: House of Horror Commander|103|R|{3}{W}{W}|Enchantment|||Whenever you cast an enchantment spell, create a 4/4 white Angel creature token with flying.| Sphere of Safety|Duskmourn: House of Horror Commander|104|U|{4}{W}|Enchantment|||Creatures can't attack you or planeswalkers you control unless their controller pays {X} for each of those creatures, where X is the number of enchantments you control.| -Starfield Mystic|Duskmourn: House of Horror Commander|105|R|{1}{W}|Creature - Human Cleric|2|2|Enchantment spells you cast cost {1} less to cast.$Whenever an enchantment you control is put into a graveyard from the battlefield, put a +1/+1 counter on Starfield Mystic.| +Starfield Mystic|Duskmourn: House of Horror Commander|105|R|{1}{W}|Creature - Human Cleric|2|2|Enchantment spells you cast cost {1} less to cast.$Whenever an enchantment you control is put into a graveyard from the battlefield, put a +1/+1 counter on this creature.| Swords to Plowshares|Duskmourn: House of Horror Commander|106|U|{W}|Instant|||Exile target creature. Its controller gains life equal to its power.| -Timely Ward|Duskmourn: House of Horror Commander|107|R|{2}{W}|Enchantment - Aura|||You may cast Timely Ward as though it had flash if it targets a commander.$Enchant creature$Enchanted creature has indestructible.| +Timely Ward|Duskmourn: House of Horror Commander|107|R|{2}{W}|Enchantment - Aura|||You may cast this spell as though it had flash if it targets a commander.$Enchant creature$Enchanted creature has indestructible.| Verge Rangers|Duskmourn: House of Horror Commander|108|R|{2}{W}|Creature - Human Scout Ranger|3|3|First strike$You may look at the top card of your library any time.$As long as an opponent controls more lands than you, you may play lands from the top of your library.| Aether Gale|Duskmourn: House of Horror Commander|109|R|{3}{U}{U}|Sorcery|||Return six target nonland permanents to their owners' hands.| Arcane Denial|Duskmourn: House of Horror Commander|110|C|{1}{U}|Instant|||Counter target spell. Its controller may draw up to two cards at the beginning of the next turn's upkeep.$You draw a card at the beginning of the next turn's upkeep.| Archetype of Imagination|Duskmourn: House of Horror Commander|111|U|{4}{U}{U}|Enchantment Creature - Human Wizard|3|2|Creatures you control have flying.$Creatures your opponents control lose flying and can't have or gain flying.| -Body of Knowledge|Duskmourn: House of Horror Commander|112|R|{3}{U}{U}|Creature - Avatar|*|*|Body of Knowledge's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$Whenever Body of Knowledge is dealt damage, draw that many cards.| +Body of Knowledge|Duskmourn: House of Horror Commander|112|R|{3}{U}{U}|Creature - Avatar|*|*|Body of Knowledge's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$Whenever this creature is dealt damage, draw that many cards.| Brainstorm|Duskmourn: House of Horror Commander|113|C|{U}|Instant|||Draw three cards, then put two cards from your hand on top of your library in any order.| -Counterspell|Duskmourn: House of Horror Commander|114|C|{U}{U}|Instant|||Counter target spell.| +Counterspell|Duskmourn: House of Horror Commander|114|U|{U}{U}|Instant|||Counter target spell.| Dig Through Time|Duskmourn: House of Horror Commander|115|R|{6}{U}{U}|Instant|||Delve$Look at the top seven cards of your library. Put two of them into your hand and the rest on the bottom of your library in any order.| -Dream Eater|Duskmourn: House of Horror Commander|116|M|{4}{U}{U}|Creature - Nightmare Sphinx|4|3|Flash$Flying$When Dream Eater enters, surveil 4. When you do, you may return target nonland permanent an opponent controls to its owner's hand.| +Dream Eater|Duskmourn: House of Horror Commander|116|M|{4}{U}{U}|Creature - Nightmare Sphinx|4|3|Flash$Flying$When this creature enters, surveil 4. When you do, you may return target nonland permanent an opponent controls to its owner's hand.| Extravagant Replication|Duskmourn: House of Horror Commander|117|R|{4}{U}{U}|Enchantment|||At the beginning of your upkeep, create a token that's a copy of another target nonland permanent you control.| -Kefnet the Mindful|Duskmourn: House of Horror Commander|118|M|{2}{U}|Legendary Creature - God|5|5|Flying, indestructible$Kefnet the Mindful can't attack or block unless you have seven or more cards in hand.${3}{U}: Draw a card, then you may return a land you control to its owner's hand.| -Kheru Spellsnatcher|Duskmourn: House of Horror Commander|119|R|{3}{U}|Creature - Snake Wizard|3|3|Morph {4}{U}{U}$When Kheru Spellsnatcher is turned face up, counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may cast that card without paying its mana cost for as long as it remains exiled.| -Mirrormade|Duskmourn: House of Horror Commander|120|R|{1}{U}{U}|Enchantment|||You may have Mirrormade enter as a copy of any artifact or enchantment on the battlefield.| +Kefnet the Mindful|Duskmourn: House of Horror Commander|118|M|{2}{U}|Legendary Creature - God|5|5|Flying, indestructible$Kefnet can't attack or block unless you have seven or more cards in hand.${3}{U}: Draw a card, then you may return a land you control to its owner's hand.| +Kheru Spellsnatcher|Duskmourn: House of Horror Commander|119|R|{3}{U}|Creature - Snake Wizard|3|3|Morph {4}{U}{U}$When this creature is turned face up, counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may cast that card without paying its mana cost for as long as it remains exiled.| +Mirrormade|Duskmourn: House of Horror Commander|120|R|{1}{U}{U}|Enchantment|||You may have this enchantment enter as a copy of any artifact or enchantment on the battlefield.| One with the Multiverse|Duskmourn: House of Horror Commander|121|M|{6}{U}{U}|Enchantment|||You may look at the top card of your library any time.$You may play lands and cast spells from the top of your library.$Once during each of your turns, you may cast a spell from your hand or the top of your library without paying its mana cost.| Otherworldly Gaze|Duskmourn: House of Horror Commander|122|C|{U}|Instant|||Surveil 3.$Flashback {1}{U}| Primordial Mist|Duskmourn: House of Horror Commander|123|R|{4}{U}|Enchantment|||At the beginning of your end step, you may manifest the top card of your library.$Exile a face-down permanent you control face up: You may play that card this turn.| -Prognostic Sphinx|Duskmourn: House of Horror Commander|124|R|{3}{U}{U}|Creature - Sphinx|3|5|Flying$Discard a card: Prognostic Sphinx gains hexproof until end of turn. Tap it.$Whenever Prognostic Sphinx attacks, scry 3.| +Prognostic Sphinx|Duskmourn: House of Horror Commander|124|R|{3}{U}{U}|Creature - Sphinx|3|5|Flying$Discard a card: This creature gains hexproof until end of turn. Tap it.$Whenever this creature attacks, scry 3.| Reality Shift|Duskmourn: House of Horror Commander|125|U|{1}{U}|Instant|||Exile target creature. Its controller manifests the top card of their library.| Retreat to Coralhelm|Duskmourn: House of Horror Commander|126|U|{2}{U}|Enchantment|||Landfall -- Whenever a land you control enters, choose one --$* You may tap or untap target creature.$* Scry 1.| -Shark Typhoon|Duskmourn: House of Horror Commander|127|R|{5}{U}|Enchantment|||Whenever you cast a noncreature spell, create an X/X blue Shark creature token with flying, where X is that spell's mana value.$Cycling {X}{1}{U}$When you cycle Shark Typhoon, create an X/X blue Shark creature token with flying.| -Skaab Ruinator|Duskmourn: House of Horror Commander|128|M|{1}{U}{U}|Creature - Zombie Horror|5|6|As an additional cost to cast this spell, exile three creature cards from your graveyard.$Flying$You may cast Skaab Ruinator from your graveyard.| +Shark Typhoon|Duskmourn: House of Horror Commander|127|R|{5}{U}|Enchantment|||Whenever you cast a noncreature spell, create an X/X blue Shark creature token with flying, where X is that spell's mana value.$Cycling {X}{1}{U}$When you cycle this card, create an X/X blue Shark creature token with flying.| +Skaab Ruinator|Duskmourn: House of Horror Commander|128|M|{1}{U}{U}|Creature - Zombie Horror|5|6|As an additional cost to cast this spell, exile three creature cards from your graveyard.$Flying$You may cast this card from your graveyard.| Thirst for Meaning|Duskmourn: House of Horror Commander|129|C|{2}{U}|Instant|||Draw three cards. Then discard two cards unless you discard an enchantment card.| -Arvinox, the Mind Flail|Duskmourn: House of Horror Commander|130|M|{4}{B}{B}{B}|Legendary Enchantment Creature - Horror|9|9|Arvinox, the Mind Flail isn't a creature unless you control three or more permanents you don't own.$At the beginning of your end step, exile the bottom card of each opponent's library face down. For as long as those cards remain exiled, you may look at them, you may cast permanent spells from among them, and you may spend mana as though it were mana of any color to cast those spells.| -Bastion of Remembrance|Duskmourn: House of Horror Commander|131|U|{2}{B}|Enchantment|||When Bastion of Remembrance enters, create a 1/1 white Human Soldier creature token.$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.| -Blood Artist|Duskmourn: House of Horror Commander|132|U|{1}{B}|Creature - Vampire|0|1|Whenever Blood Artist or another creature dies, target player loses 1 life and you gain 1 life.| -Braids, Arisen Nightmare|Duskmourn: House of Horror Commander|133|R|{1}{B}{B}|Legendary Creature - Nightmare|3|3|At the beginning of your end step, you may sacrifice an artifact, creature, enchantment, land, or planeswalker. If you do, each opponent may sacrifice a permanent that shares a card type with it. For each opponent who doesn't, that player loses 2 life and you draw a card.| -Carrion Grub|Duskmourn: House of Horror Commander|134|C|{3}{B}|Creature - Insect|0|5|Carrion Grub gets +X/+0, where X is the greatest power among creature cards in your graveyard.$When Carrion Grub enters, mill four cards.| +Arvinox, the Mind Flail|Duskmourn: House of Horror Commander|130|M|{4}{B}{B}{B}|Legendary Enchantment Creature - Horror|9|9|Arvinox isn't a creature unless you control three or more permanents you don't own.$At the beginning of your end step, exile the bottom card of each opponent's library face down. For as long as those cards remain exiled, you may look at them, you may cast permanent spells from among them, and you may spend mana as though it were mana of any color to cast those spells.| +Bastion of Remembrance|Duskmourn: House of Horror Commander|131|U|{2}{B}|Enchantment|||When this enchantment enters, create a 1/1 white Human Soldier creature token.$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.| +Blood Artist|Duskmourn: House of Horror Commander|132|U|{1}{B}|Creature - Vampire|0|1|Whenever this creature or another creature dies, target player loses 1 life and you gain 1 life.| +Braids, Arisen Nightmare|Duskmourn: House of Horror Commander|133|R|{1}{B}{B}|Legendary Creature - Nightmare|3|3|At the beginning of your end step, you may sacrifice an artifact, creature, enchantment, land, or planeswalker. If you do, each opponent may sacrifice a permanent of their choice that shares a card type with it. For each opponent who doesn't, that player loses 2 life and you draw a card.| +Carrion Grub|Duskmourn: House of Horror Commander|134|U|{3}{B}|Creature - Insect|0|5|This creature gets +X/+0, where X is the greatest power among creature cards in your graveyard.$When this creature enters, mill four cards.| Cemetery Tampering|Duskmourn: House of Horror Commander|135|R|{2}{B}|Enchantment|||Hideaway 5$At the beginning of your upkeep, you may mill three cards. Then if there are twenty or more cards in your graveyard, you may play the exiled card without paying its mana cost.| -Decree of Pain|Duskmourn: House of Horror Commander|136|R|{6}{B}{B}|Sorcery|||Destroy all creatures. They can't be regenerated. Draw a card for each creature destroyed this way.$Cycling {3}{B}{B}$When you cycle Decree of Pain, all creatures get -2/-2 until end of turn.| -Demon of Fate's Design|Duskmourn: House of Horror Commander|137|R|{4}{B}{B}|Enchantment Creature - Demon|6|6|Flying, trample$Once during each of your turns, you may cast an enchantment spell by paying life equal to its mana value rather than paying its mana cost.${2}{B}, Sacrifice another enchantment: Demon of Fate's Design gets +X/+0 until end of turn, where X is the sacrificed enchantment's mana value.| -Doomwake Giant|Duskmourn: House of Horror Commander|138|R|{4}{B}|Enchantment Creature - Giant|4|6|Constellation -- Whenever Doomwake Giant or another enchantment you control enters, creatures your opponents control get -1/-1 until end of turn.| -The Eldest Reborn|Duskmourn: House of Horror Commander|139|U|{4}{B}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- Each opponent sacrifices a creature or planeswalker.$II -- Each opponent discards a card.$III -- Put target creature or planeswalker card from a graveyard onto the battlefield under your control.| -Falkenrath Noble|Duskmourn: House of Horror Commander|140|U|{3}{B}|Creature - Vampire Noble|2|2|Flying$Whenever Falkenrath Noble or another creature dies, target player loses 1 life and you gain 1 life.| -Fate Unraveler|Duskmourn: House of Horror Commander|141|R|{3}{B}|Enchantment Creature - Hag|3|4|Whenever an opponent draws a card, Fate Unraveler deals 1 damage to that player.| -Gray Merchant of Asphodel|Duskmourn: House of Horror Commander|142|U|{3}{B}{B}|Creature - Zombie|2|4|When Gray Merchant of Asphodel enters, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way.| +Decree of Pain|Duskmourn: House of Horror Commander|136|R|{6}{B}{B}|Sorcery|||Destroy all creatures. They can't be regenerated. Draw a card for each creature destroyed this way.$Cycling {3}{B}{B}$When you cycle this card, all creatures get -2/-2 until end of turn.| +Demon of Fate's Design|Duskmourn: House of Horror Commander|137|R|{4}{B}{B}|Enchantment Creature - Demon|6|6|Flying, trample$Once during each of your turns, you may cast an enchantment spell by paying life equal to its mana value rather than paying its mana cost.${2}{B}, Sacrifice another enchantment: This creature gets +X/+0 until end of turn, where X is the sacrificed enchantment's mana value.| +Doomwake Giant|Duskmourn: House of Horror Commander|138|R|{4}{B}|Enchantment Creature - Giant|4|6|Constellation -- Whenever this creature or another enchantment you control enters, creatures your opponents control get -1/-1 until end of turn.| +The Eldest Reborn|Duskmourn: House of Horror Commander|139|U|{4}{B}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- Each opponent sacrifices a creature or planeswalker of their choice.$II -- Each opponent discards a card.$III -- Put target creature or planeswalker card from a graveyard onto the battlefield under your control.| +Falkenrath Noble|Duskmourn: House of Horror Commander|140|C|{3}{B}|Creature - Vampire Noble|2|2|Flying$Whenever this creature or another creature dies, target player loses 1 life and you gain 1 life.| +Fate Unraveler|Duskmourn: House of Horror Commander|141|R|{3}{B}|Enchantment Creature - Hag|3|4|Whenever an opponent draws a card, this creature deals 1 damage to that player.| +Gray Merchant of Asphodel|Duskmourn: House of Horror Commander|142|U|{3}{B}{B}|Creature - Zombie|2|4|When this creature enters, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way.| Infernal Grasp|Duskmourn: House of Horror Commander|143|U|{1}{B}|Instant|||Destroy target creature. You lose 2 life.| -Kederekt Parasite|Duskmourn: House of Horror Commander|144|R|{B}|Creature - Horror|1|1|Whenever an opponent draws a card, if you control a red permanent, you may have Kederekt Parasite deal 1 damage to that player.| +Kederekt Parasite|Duskmourn: House of Horror Commander|144|R|{B}|Creature - Horror|1|1|Whenever an opponent draws a card, if you control a red permanent, you may have this creature deal 1 damage to that player.| Mask of Griselbrand|Duskmourn: House of Horror Commander|145|R|{1}{B}{B}|Legendary Artifact - Equipment|||Equipped creature has flying and lifelink.$Whenever equipped creature dies, you may pay X life, where X is its power. If you do, draw X cards.$Equip {3}| Massacre Girl|Duskmourn: House of Horror Commander|146|R|{3}{B}{B}|Legendary Creature - Human Assassin|4|4|Menace$When Massacre Girl enters, each other creature gets -1/-1 until end of turn. Whenever a creature dies this turn, each creature other than Massacre Girl gets -1/-1 until end of turn.| -Massacre Wurm|Duskmourn: House of Horror Commander|147|M|{3}{B}{B}{B}|Creature - Phyrexian Wurm|6|5|When Massacre Wurm enters, creatures your opponents control get -2/-2 until end of turn.$Whenever a creature an opponent controls dies, that player loses 2 life.| +Massacre Wurm|Duskmourn: House of Horror Commander|147|M|{3}{B}{B}{B}|Creature - Phyrexian Wurm|6|5|When this creature enters, creatures your opponents control get -2/-2 until end of turn.$Whenever a creature an opponent controls dies, that player loses 2 life.| Morbid Opportunist|Duskmourn: House of Horror Commander|148|U|{2}{B}|Creature - Human Rogue|1|3|Whenever one or more other creatures die, draw a card. This ability triggers only once each turn.| Nightmare Shepherd|Duskmourn: House of Horror Commander|149|R|{2}{B}{B}|Enchantment Creature - Demon|4|4|Flying$Whenever another nontoken creature you control dies, you may exile it. If you do, create a token that's a copy of that creature, except it's 1/1 and it's a Nightmare in addition to its other types.| -Nightshade Harvester|Duskmourn: House of Horror Commander|150|R|{3}{B}|Creature - Elf Shaman|2|2|Whenever a land an opponent controls enters, that player loses 1 life. Put a +1/+1 counter on Nightshade Harvester.| -Noxious Gearhulk|Duskmourn: House of Horror Commander|151|M|{4}{B}{B}|Artifact Creature - Construct|5|4|Menace$When Noxious Gearhulk enters, you may destroy another target creature. If a creature is destroyed this way, you gain life equal to its toughness.| +Nightshade Harvester|Duskmourn: House of Horror Commander|150|R|{3}{B}|Creature - Elf Shaman|2|2|Whenever a land an opponent controls enters, that player loses 1 life. Put a +1/+1 counter on this creature.| +Noxious Gearhulk|Duskmourn: House of Horror Commander|151|M|{4}{B}{B}|Artifact Creature - Construct|5|4|Menace$When this creature enters, you may destroy another target creature. If a creature is destroyed this way, you gain life equal to its toughness.| Ob Nixilis Reignited|Duskmourn: House of Horror Commander|152|M|{3}{B}{B}|Legendary Planeswalker - Nixilis|5|+1: You draw a card and you lose 1 life.$-3: Destroy target creature.$-8: Target opponent gets an emblem with "Whenever a player draws a card, you lose 2 life."| Professor Onyx|Duskmourn: House of Horror Commander|153|M|{4}{B}{B}|Legendary Planeswalker - Liliana|5|Magecraft -- Whenever you cast or copy an instant or sorcery spell, each opponent loses 2 life and you gain 2 life.$+1: You lose 1 life. Look at the top three cards of your library. Put one of them into your hand and the rest into your graveyard.$-3: Each opponent sacrifices a creature with the greatest power among creatures that player controls.$-8: Each opponent may discard a card. If they don't, they lose 3 life. Repeat this process six more times.| Read the Bones|Duskmourn: House of Horror Commander|154|C|{2}{B}|Sorcery|||Scry 2, then draw two cards. You lose 2 life.| Reanimate|Duskmourn: House of Horror Commander|155|R|{B}|Sorcery|||Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its mana value.| Sign in Blood|Duskmourn: House of Horror Commander|156|C|{B}{B}|Sorcery|||Target player draws two cards and loses 2 life.| -Stitcher's Supplier|Duskmourn: House of Horror Commander|157|U|{B}|Creature - Zombie|1|1|When Stitcher's Supplier enters or dies, mill three cards.| -Syr Konrad, the Grim|Duskmourn: House of Horror Commander|158|U|{3}{B}{B}|Legendary Creature - Human Knight|5|4|Whenever another creature dies, or a creature card is put into a graveyard from anywhere other than the battlefield, or a creature card leaves your graveyard, Syr Konrad, the Grim deals 1 damage to each opponent.${1}{B}: Each player mills a card.| +Stitcher's Supplier|Duskmourn: House of Horror Commander|157|U|{B}|Creature - Zombie|1|1|When this creature enters or dies, mill three cards.| +Syr Konrad, the Grim|Duskmourn: House of Horror Commander|158|U|{3}{B}{B}|Legendary Creature - Human Knight|5|4|Whenever another creature dies, or a creature card is put into a graveyard from anywhere other than the battlefield, or a creature card leaves your graveyard, Syr Konrad deals 1 damage to each opponent.${1}{B}: Each player mills a card.| Whip of Erebos|Duskmourn: House of Horror Commander|159|R|{2}{B}{B}|Legendary Enchantment Artifact|||Creatures you control have lifelink.${2}{B}{B}, {T}: Return target creature card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step. If it would leave the battlefield, exile it instead of putting it anywhere else. Activate only as a sorcery.| Blasphemous Act|Duskmourn: House of Horror Commander|160|R|{8}{R}|Sorcery|||This spell costs {1} less to cast for each creature on the battlefield.$Blasphemous Act deals 13 damage to each creature.| -Brash Taunter|Duskmourn: House of Horror Commander|161|R|{4}{R}|Creature - Goblin|1|1|Indestructible$Whenever Brash Taunter is dealt damage, it deals that much damage to target opponent.${2}{R}, {T}: Brash Taunter fights another target creature.| +Brash Taunter|Duskmourn: House of Horror Commander|161|R|{4}{R}|Creature - Goblin|1|1|Indestructible$Whenever this creature is dealt damage, it deals that much damage to target opponent.${2}{R}, {T}: This creature fights another target creature.| Chaos Warp|Duskmourn: House of Horror Commander|162|R|{2}{R}|Instant|||The owner of target permanent shuffles it into their library, then reveals the top card of their library. If it's a permanent card, they put it onto the battlefield.| -Combustible Gearhulk|Duskmourn: House of Horror Commander|163|M|{4}{R}{R}|Artifact Creature - Construct|6|6|First strike$When Combustible Gearhulk enters, target opponent may have you draw three cards. If the player doesn't, you mill three cards, then Combustible Gearhulk deals damage to that player equal to the total mana value of those cards.| +Combustible Gearhulk|Duskmourn: House of Horror Commander|163|M|{4}{R}{R}|Artifact Creature - Construct|6|6|First strike$When this creature enters, target opponent may have you draw three cards. If the player doesn't, you mill three cards, then this creature deals damage to that player equal to the total mana value of those cards.| Enchanter's Bane|Duskmourn: House of Horror Commander|164|R|{1}{R}|Enchantment|||At the beginning of your end step, target enchantment deals damage equal to its mana value to its controller unless that player sacrifices it.| -Harsh Mentor|Duskmourn: House of Horror Commander|165|R|{1}{R}|Creature - Human Cleric|2|2|Whenever an opponent activates an ability of an artifact, creature, or land on the battlefield, if it isn't a mana ability, Harsh Mentor deals 2 damage to that player.| +Harsh Mentor|Duskmourn: House of Horror Commander|165|R|{1}{R}|Creature - Human Cleric|2|2|Whenever an opponent activates an ability of an artifact, creature, or land on the battlefield, if it isn't a mana ability, this creature deals 2 damage to that player.| Light Up the Stage|Duskmourn: House of Horror Commander|166|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.| -Rampaging Ferocidon|Duskmourn: House of Horror Commander|167|R|{2}{R}|Creature - Dinosaur|3|3|Menace$Players can't gain life.$Whenever another creature enters, Rampaging Ferocidon deals 1 damage to that creature's controller.| -Tectonic Giant|Duskmourn: House of Horror Commander|168|R|{2}{R}{R}|Creature - Elemental Giant|3|4|Whenever Tectonic Giant attacks or becomes the target of a spell an opponent controls, choose one --$* Tectonic Giant deals 3 damage to each opponent.$* Exile the top two cards of your library. Choose one of them. Until the end of your next turn, you may play that card.| +Rampaging Ferocidon|Duskmourn: House of Horror Commander|167|R|{2}{R}|Creature - Dinosaur|3|3|Menace$Players can't gain life.$Whenever another creature enters, this creature deals 1 damage to that creature's controller.| +Tectonic Giant|Duskmourn: House of Horror Commander|168|R|{2}{R}{R}|Creature - Elemental Giant|3|4|Whenever this creature attacks or becomes the target of a spell an opponent controls, choose one --$* This creature deals 3 damage to each opponent.$* Exile the top two cards of your library. Choose one of them. Until the end of your next turn, you may play that card.| Arachnogenesis|Duskmourn: House of Horror Commander|169|R|{2}{G}|Instant|||Create X 1/2 green Spider creature tokens with reach, where X is the number of creatures attacking you. Prevent all combat damage that would be dealt this turn by non-Spider creatures.| -Ashaya, Soul of the Wild|Duskmourn: House of Horror Commander|170|M|{3}{G}{G}|Legendary Creature - Elemental|*|*|Ashaya, Soul of the Wild's power and toughness are each equal to the number of lands you control.$Nontoken creatures you control are Forest lands in addition to their other types.| +Ashaya, Soul of the Wild|Duskmourn: House of Horror Commander|170|M|{3}{G}{G}|Legendary Creature - Elemental|*|*|Ashaya's power and toughness are each equal to the number of lands you control.$Nontoken creatures you control are Forest lands in addition to their other types.| Augur of Autumn|Duskmourn: House of Horror Commander|171|R|{1}{G}{G}|Creature - Human Druid|2|3|You may look at the top card of your library any time.$You may play lands from the top of your library.$Coven -- As long as you control three or more creatures with different powers, you may cast creature spells from the top of your library.| Beanstalk Giant|Duskmourn: House of Horror Commander|172|U|{6}{G}|Creature - Giant|*|*|Beanstalk Giant's power and toughness are each equal to the number of lands you control.| Fertile Footsteps|Duskmourn: House of Horror Commander|172|U|{2}{G}|Sorcery - Adventure|*|*|Search your library for a basic land card, put it onto the battlefield, then shuffle.| Crawling Sensation|Duskmourn: House of Horror Commander|173|U|{2}{G}|Enchantment|||At the beginning of your upkeep, you may mill two cards.$Whenever one or more land cards are put into your graveyard from anywhere for the first time each turn, create a 1/1 green Insect creature token.| Cultivate|Duskmourn: House of Horror Commander|174|C|{2}{G}|Sorcery|||Search your library for up to two basic land cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle.| -Deathcap Cultivator|Duskmourn: House of Horror Commander|175|R|{1}{G}|Creature - Human Druid|2|1|{T}: Add {B} or {G}.$Delirium -- Deathcap Cultivator has deathtouch as long as there are four or more card types among cards in your graveyard.| -Deathmist Raptor|Duskmourn: House of Horror Commander|176|M|{1}{G}{G}|Creature - Dinosaur Beast|3|3|Deathtouch$Whenever a permanent you control is turned face up, you may return Deathmist Raptor from your graveyard to the battlefield face up or face down.$Megamorph {4}{G}| +Deathcap Cultivator|Duskmourn: House of Horror Commander|175|R|{1}{G}|Creature - Human Druid|2|1|{T}: Add {B} or {G}.$Delirium -- This creature has deathtouch as long as there are four or more card types among cards in your graveyard.| +Deathmist Raptor|Duskmourn: House of Horror Commander|176|M|{1}{G}{G}|Creature - Dinosaur Beast|3|3|Deathtouch$Whenever a permanent you control is turned face up, you may return this card from your graveyard to the battlefield face up or face down.$Megamorph {4}{G}| Explosive Vegetation|Duskmourn: House of Horror Commander|177|U|{3}{G}|Sorcery|||Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle.| Ezuri's Predation|Duskmourn: House of Horror Commander|178|R|{5}{G}{G}{G}|Sorcery|||For each creature your opponents control, create a 4/4 green Phyrexian Beast creature token. Each of those tokens fights a different one of those creatures.| -Giant Adephage|Duskmourn: House of Horror Commander|179|M|{5}{G}{G}|Creature - Insect|7|7|Trample$Whenever Giant Adephage deals combat damage to a player, create a token that's a copy of Giant Adephage.| -Gnarlwood Dryad|Duskmourn: House of Horror Commander|180|U|{G}|Creature - Dryad Horror|1|1|Deathtouch$Delirium -- Gnarlwood Dryad gets +2/+2 as long as there are four or more card types among cards in your graveyard.| -Greater Tanuki|Duskmourn: House of Horror Commander|181|C|{4}{G}{G}|Enchantment Creature - Dog|6|5|Trample$Channel -- {2}{G}, Discard Greater Tanuki: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.| +Giant Adephage|Duskmourn: House of Horror Commander|179|M|{5}{G}{G}|Creature - Insect|7|7|Trample$Whenever this creature deals combat damage to a player, create a token that's a copy of this creature.| +Gnarlwood Dryad|Duskmourn: House of Horror Commander|180|U|{G}|Creature - Dryad Horror|1|1|Deathtouch$Delirium -- This creature gets +2/+2 as long as there are four or more card types among cards in your graveyard.| +Greater Tanuki|Duskmourn: House of Horror Commander|181|C|{4}{G}{G}|Enchantment Creature - Dog|6|5|Trample$Channel -- {2}{G}, Discard this card: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.| Harmonize|Duskmourn: House of Horror Commander|182|U|{2}{G}{G}|Sorcery|||Draw three cards.| Harrow|Duskmourn: House of Horror Commander|183|C|{2}{G}|Instant|||As an additional cost to cast this spell, sacrifice a land.$Search your library for up to two basic land cards, put them onto the battlefield, then shuffle.| -Hornet Queen|Duskmourn: House of Horror Commander|184|M|{4}{G}{G}{G}|Creature - Insect|2|2|Flying, deathtouch$When Hornet Queen enters, create four 1/1 green Insect creature tokens with flying and deathtouch.| -Hydra Omnivore|Duskmourn: House of Horror Commander|185|M|{4}{G}{G}|Creature - Hydra|8|8|Whenever Hydra Omnivore deals combat damage to an opponent, it deals that much damage to each other opponent.| +Hornet Queen|Duskmourn: House of Horror Commander|184|R|{4}{G}{G}{G}|Creature - Insect|2|2|Flying, deathtouch$When this creature enters, create four 1/1 green Insect creature tokens with flying and deathtouch.| +Hydra Omnivore|Duskmourn: House of Horror Commander|185|M|{4}{G}{G}|Creature - Hydra|8|8|Whenever this creature deals combat damage to an opponent, it deals that much damage to each other opponent.| Inscription of Abundance|Duskmourn: House of Horror Commander|186|R|{1}{G}|Instant|||Kicker {2}{G}$Choose one. If this spell was kicked, choose any number instead.$* Put two +1/+1 counters on target creature.$* Target player gains X life, where X is the greatest power among creatures they control.$* Target creature you control fights target creature you don't control.| -Ishkanah, Grafwidow|Duskmourn: House of Horror Commander|187|M|{4}{G}|Legendary Creature - Spider|3|5|Reach$Delirium -- When Ishkanah, Grafwidow enters, if there are four or more card types among cards in your graveyard, create three 1/2 green Spider creature tokens with reach.${6}{B}: Target opponent loses 1 life for each Spider you control.| -Moldgraf Millipede|Duskmourn: House of Horror Commander|188|C|{4}{G}|Creature - Insect Horror|2|2|When Moldgraf Millipede enters, mill three cards, then put a +1/+1 counter on Moldgraf Millipede for each creature card in your graveyard.| +Ishkanah, Grafwidow|Duskmourn: House of Horror Commander|187|M|{4}{G}|Legendary Creature - Spider|3|5|Reach$Delirium -- When Ishkanah enters, if there are four or more card types among cards in your graveyard, create three 1/2 green Spider creature tokens with reach.${6}{B}: Target opponent loses 1 life for each Spider you control.| +Moldgraf Millipede|Duskmourn: House of Horror Commander|188|C|{4}{G}|Creature - Insect Horror|2|2|When this creature enters, mill three cards, then put a +1/+1 counter on this creature for each creature card in your graveyard.| Mulch|Duskmourn: House of Horror Commander|189|C|{1}{G}|Sorcery|||Reveal the top four cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard.| -Multani, Yavimaya's Avatar|Duskmourn: House of Horror Commander|190|M|{4}{G}{G}|Legendary Creature - Elemental Avatar|0|0|Reach, trample$Multani, Yavimaya's Avatar gets +1/+1 for each land you control and each land card in your graveyard.${1}{G}, Return two lands you control to their owner's hand: Return Multani from your graveyard to your hand.| -Obsessive Skinner|Duskmourn: House of Horror Commander|191|U|{1}{G}|Creature - Human Rogue|1|1|When Obsessive Skinner enters, put a +1/+1 counter on target creature.$Delirium -- At the beginning of each opponent's upkeep, if there are four or more card types among cards in your graveyard, put a +1/+1 counter on target creature.| +Multani, Yavimaya's Avatar|Duskmourn: House of Horror Commander|190|M|{4}{G}{G}|Legendary Creature - Elemental Avatar|0|0|Reach, trample$Multani gets +1/+1 for each land you control and each land card in your graveyard.${1}{G}, Return two lands you control to their owner's hand: Return this card from your graveyard to your hand.| +Obsessive Skinner|Duskmourn: House of Horror Commander|191|U|{1}{G}|Creature - Human Rogue|1|1|When this creature enters, put a +1/+1 counter on target creature.$Delirium -- At the beginning of each opponent's upkeep, if there are four or more card types among cards in your graveyard, put a +1/+1 counter on target creature.| Overwhelming Stampede|Duskmourn: House of Horror Commander|192|R|{3}{G}{G}|Sorcery|||Until end of turn, creatures you control gain trample and get +X/+X, where X is the greatest power among creatures you control.| Rampant Growth|Duskmourn: House of Horror Commander|193|C|{1}{G}|Sorcery|||Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.| -Sakura-Tribe Elder|Duskmourn: House of Horror Commander|194|C|{1}{G}|Creature - Snake Shaman|1|1|Sacrifice Sakura-Tribe Elder: Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.| +Sakura-Tribe Elder|Duskmourn: House of Horror Commander|194|C|{1}{G}|Creature - Snake Shaman|1|1|Sacrifice this creature: Search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.| Sandwurm Convergence|Duskmourn: House of Horror Commander|195|R|{6}{G}{G}|Enchantment|||Creatures with flying can't attack you or planeswalkers you control.$At the beginning of your end step, create a 5/5 green Wurm creature token.| -Scavenging Ooze|Duskmourn: House of Horror Commander|196|R|{1}{G}|Creature - Ooze|2|2|{G}: Exile target card from a graveyard. If it was a creature card, put a +1/+1 counter on Scavenging Ooze and you gain 1 life.| -Scute Swarm|Duskmourn: House of Horror Commander|197|R|{2}{G}|Creature - Insect|1|1|Landfall -- Whenever a land you control enters, create a 1/1 green Insect creature token. If you control six or more lands, create a token that's a copy of Scute Swarm instead.| -Shigeki, Jukai Visionary|Duskmourn: House of Horror Commander|198|R|{1}{G}|Legendary Enchantment Creature - Snake Druid|1|3|{1}{G}, {T}, Return Shigeki, Jukai Visionary to its owner's hand: Reveal the top four cards of your library. You may put a land card from among them onto the battlefield tapped. Put the rest into your graveyard.$Channel -- {X}{X}{G}{G}, Discard Shigeki: Return X target nonlegendary cards from your graveyard to your hand.| +Scavenging Ooze|Duskmourn: House of Horror Commander|196|R|{1}{G}|Creature - Ooze|2|2|{G}: Exile target card from a graveyard. If it was a creature card, put a +1/+1 counter on this creature and you gain 1 life.| +Scute Swarm|Duskmourn: House of Horror Commander|197|R|{2}{G}|Creature - Insect|1|1|Landfall -- Whenever a land you control enters, create a 1/1 green Insect creature token. If you control six or more lands, create a token that's a copy of this creature instead.| +Shigeki, Jukai Visionary|Duskmourn: House of Horror Commander|198|R|{1}{G}|Legendary Enchantment Creature - Snake Druid|1|3|{1}{G}, {T}, Return Shigeki to its owner's hand: Reveal the top four cards of your library. You may put a land card from among them onto the battlefield tapped. Put the rest into your graveyard.$Channel -- {X}{X}{G}{G}, Discard this card: Return X target nonlegendary cards from your graveyard to your hand.| Skola Grovedancer|Duskmourn: House of Horror Commander|199|C|{1}{G}|Enchantment Creature - Satyr Druid|2|2|Whenever a land card is put into your graveyard from anywhere, you gain 1 life.${2}{G}: Mill a card.| -Temur War Shaman|Duskmourn: House of Horror Commander|200|R|{4}{G}{G}|Creature - Human Shaman|4|5|When Temur War Shaman enters, manifest the top card of your library.$Whenever a permanent you control is turned face up, if it's a creature, you may have it fight target creature you don't control.| -Thunderfoot Baloth|Duskmourn: House of Horror Commander|201|R|{4}{G}{G}|Creature - Beast|5|5|Trample$Lieutenant -- As long as you control your commander, Thunderfoot Baloth gets +2/+2 and other creatures you control get +2/+2 and have trample.| +Temur War Shaman|Duskmourn: House of Horror Commander|200|R|{4}{G}{G}|Creature - Human Shaman|4|5|When this creature enters, manifest the top card of your library.$Whenever a permanent you control is turned face up, if it's a creature, you may have it fight target creature you don't control.| +Thunderfoot Baloth|Duskmourn: House of Horror Commander|201|R|{4}{G}{G}|Creature - Beast|5|5|Trample$Lieutenant -- As long as you control your commander, this creature gets +2/+2 and other creatures you control get +2/+2 and have trample.| Titania, Nature's Force|Duskmourn: House of Horror Commander|202|M|{4}{G}{G}|Legendary Creature - Elemental|6|6|You may play Forests from your graveyard.$Whenever a Forest you control enters, create a 5/3 green Elemental creature token.$Whenever an Elemental you control dies, you may mill three cards.| Trail of Mystery|Duskmourn: House of Horror Commander|203|R|{1}{G}|Enchantment|||Whenever a face-down creature you control enters, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle.$Whenever a permanent you control is turned face up, if it's a creature, it gets +2/+2 until end of turn.| -Whisperwood Elemental|Duskmourn: House of Horror Commander|204|M|{3}{G}{G}|Creature - Elemental|4|4|At the beginning of your end step, manifest the top card of your library.$Sacrifice Whisperwood Elemental: Until end of turn, face-up nontoken creatures you control gain "When this creature dies, manifest the top card of your library."| +Whisperwood Elemental|Duskmourn: House of Horror Commander|204|M|{3}{G}{G}|Creature - Elemental|4|4|At the beginning of your end step, manifest the top card of your library.$Sacrifice this creature: Until end of turn, face-up nontoken creatures you control gain "When this creature dies, manifest the top card of your library."| Wilderness Reclamation|Duskmourn: House of Horror Commander|205|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.| -Worldspine Wurm|Duskmourn: House of Horror Commander|206|M|{8}{G}{G}{G}|Creature - Wurm|15|15|Trample$When Worldspine Wurm dies, create three 5/5 green Wurm creature tokens with trample.$When Worldspine Wurm is put into a graveyard from anywhere, shuffle it into its owner's library.| -Wrenn and Seven|Duskmourn: House of Horror Commander|207|M|{3}{G}{G}|Legendary Planeswalker - Wrenn|5|+1: Reveal the top four cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard.$0: Put any number of land cards from your hand onto the battlefield tapped.$-3: Create a green Treefolk creature token with reach and "This creature's power and toughness are each equal to the number of lands you control."$-8: Return all permanent cards from your graveyard to your hand. You get an emblem with "You have no maximum hand size."| -Yavimaya Elder|Duskmourn: House of Horror Commander|208|C|{1}{G}{G}|Creature - Human Druid|2|1|When Yavimaya Elder dies, you may search your library for up to two basic land cards, reveal them, put them into your hand, then shuffle.${2}, Sacrifice Yavimaya Elder: Draw a card.| +Worldspine Wurm|Duskmourn: House of Horror Commander|206|M|{8}{G}{G}{G}|Creature - Wurm|15|15|Trample$When this creature dies, create three 5/5 green Wurm creature tokens with trample.$When Worldspine Wurm is put into a graveyard from anywhere, shuffle it into its owner's library.| +Wrenn and Seven|Duskmourn: House of Horror Commander|207|M|{3}{G}{G}|Legendary Planeswalker - Wrenn|5|+1: Reveal the top four cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard.$0: Put any number of land cards from your hand onto the battlefield tapped.$-3: Create a green Treefolk creature token with reach and "This token's power and toughness are each equal to the number of lands you control."$-8: Return all permanent cards from your graveyard to your hand. You get an emblem with "You have no maximum hand size."| +Yavimaya Elder|Duskmourn: House of Horror Commander|208|C|{1}{G}{G}|Creature - Human Druid|2|1|When this creature dies, you may search your library for up to two basic land cards, reveal them, put them into your hand, then shuffle.${2}, Sacrifice this creature: Draw a card.| Yedora, Grave Gardener|Duskmourn: House of Horror Commander|209|U|{4}{G}|Legendary Creature - Treefolk Druid|5|5|Whenever another nontoken creature you control dies, you may return it to the battlefield face down under its owner's control. It's a Forest land.| Aesi, Tyrant of Gyre Strait|Duskmourn: House of Horror Commander|210|M|{4}{G}{U}|Legendary Creature - Serpent|5|5|You may play an additional land on each of your turns.$Landfall -- Whenever a land you control enters, you may draw a card.| -Arixmethes, Slumbering Isle|Duskmourn: House of Horror Commander|211|R|{2}{G}{U}|Legendary Creature - Kraken|12|12|Arixmethes, Slumbering Isle enters tapped with five slumber counters on it.$As long as Arixmethes has a slumber counter on it, it's a land.$Whenever you cast a spell, you may remove a slumber counter from Arixmethes.${T}: Add {G}{U}.| +Arixmethes, Slumbering Isle|Duskmourn: House of Horror Commander|211|R|{2}{G}{U}|Legendary Creature - Kraken|12|12|Arixmethes enters tapped with five slumber counters on it.$As long as Arixmethes has a slumber counter on it, it's a land.$Whenever you cast a spell, you may remove a slumber counter from Arixmethes.${T}: Add {G}{U}.| Athreos, Shroud-Veiled|Duskmourn: House of Horror Commander|212|M|{4}{W}{B}|Legendary Enchantment Creature - God|4|7|Indestructible$As long as your devotion to white and black is less than seven, Athreos isn't a creature.$At the beginning of your end step, put a coin counter on another target creature.$Whenever a creature with a coin counter on it dies or is put into exile, return that card to the battlefield under your control.| Binding the Old Gods|Duskmourn: House of Horror Commander|213|U|{2}{B}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- Destroy target nonland permanent an opponent controls.$II -- Search your library for a Forest card, put it onto the battlefield tapped, then shuffle.$III -- Creatures you control gain deathtouch until end of turn.| Biomass Mutation|Duskmourn: House of Horror Commander|214|R|{X}{G/U}{G/U}|Instant|||Creatures you control have base power and toughness X/X until end of turn.| -Deadbridge Chant|Duskmourn: House of Horror Commander|215|M|{4}{B}{G}|Enchantment|||When Deadbridge Chant enters, mill ten cards.$At the beginning of your upkeep, choose a card at random in your graveyard. If it's a creature card, return it to the battlefield. Otherwise, return it to your hand.| +Deadbridge Chant|Duskmourn: House of Horror Commander|215|M|{4}{B}{G}|Enchantment|||When this enchantment enters, mill ten cards.$At the beginning of your upkeep, choose a card at random in your graveyard. If it's a creature card, put it onto the battlefield. Otherwise, put it into your hand.| Eureka Moment|Duskmourn: House of Horror Commander|216|C|{2}{G}{U}|Instant|||Draw two cards. You may put a land card from your hand onto the battlefield.| -Florian, Voldaren Scion|Duskmourn: House of Horror Commander|217|R|{1}{B}{R}|Legendary Creature - Vampire Noble|3|3|First strike$At the beginning of your second main phase, look at the top X cards of your library, where X is the total amount of life your opponents lost this turn. Exile one of those cards and put the rest on the bottom of your library in a random order. You may play the exiled card this turn.| -Grim Flayer|Duskmourn: House of Horror Commander|218|R|{B}{G}|Creature - Human Warrior|2|2|Trample$Whenever Grim Flayer deals combat damage to a player, surveil 3.$Delirium -- Grim Flayer gets +2/+2 as long as there are four or more card types among cards in your graveyard.| +Florian, Voldaren Scion|Duskmourn: House of Horror Commander|217|R|{1}{B}{R}|Legendary Creature - Vampire Noble|3|3|First strike$At the beginning of each of your postcombat main phases, look at the top X cards of your library, where X is the total amount of life your opponents lost this turn. Exile one of those cards and put the rest on the bottom of your library in a random order. You may play the exiled card this turn.| +Grim Flayer|Duskmourn: House of Horror Commander|218|M|{B}{G}|Creature - Human Warrior|2|2|Trample$Whenever this creature deals combat damage to a player, surveil 3.$Delirium -- This creature gets +2/+2 as long as there are four or more card types among cards in your graveyard.| Grisly Salvage|Duskmourn: House of Horror Commander|219|C|{B}{G}|Instant|||Reveal the top five cards of your library. You may put a creature or land card from among them into your hand. Put the rest into your graveyard.| -Grist, the Hunger Tide|Duskmourn: House of Horror Commander|220|M|{1}{B}{G}|Legendary Planeswalker - Grist|3|As long as Grist, the Hunger Tide isn't on the battlefield, it's a 1/1 Insect creature in addition to its other types.$+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.$-2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.$-5: Each opponent loses life equal to the number of creature cards in your graveyard.| +Grist, the Hunger Tide|Duskmourn: House of Horror Commander|220|M|{1}{B}{G}|Legendary Planeswalker - Grist|3|As long as Grist isn't on the battlefield, it's a 1/1 Insect creature in addition to its other types.$+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.$-2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.$-5: Each opponent loses life equal to the number of creature cards in your graveyard.| Inkshield|Duskmourn: House of Horror Commander|221|R|{3}{W}{B}|Instant|||Prevent all combat damage that would be dealt to you this turn. For each 1 damage prevented this way, create a 2/1 white and black Inkling creature token with flying.| -Kaervek the Merciless|Duskmourn: House of Horror Commander|222|R|{5}{B}{R}|Legendary Creature - Human Shaman|5|4|Whenever an opponent casts a spell, Kaervek the Merciless deals damage equal to that spell's mana value to any target.| -Kardur, Doomscourge|Duskmourn: House of Horror Commander|223|U|{2}{B}{R}|Legendary Creature - Demon Berserker|4|3|When Kardur, Doomscourge enters, until your next turn, creatures your opponents control attack each combat if able and attack a player other than you if able.$Whenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.| +Kaervek the Merciless|Duskmourn: House of Horror Commander|222|R|{5}{B}{R}|Legendary Creature - Human Shaman|5|4|Whenever an opponent casts a spell, Kaervek deals damage equal to that spell's mana value to any target.| +Kardur, Doomscourge|Duskmourn: House of Horror Commander|223|U|{2}{B}{R}|Legendary Creature - Demon Berserker|4|3|When Kardur enters, until your next turn, creatures your opponents control attack each combat if able and attack a player other than you if able.$Whenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.| Life Insurance|Duskmourn: House of Horror Commander|224|R|{3}{W}{B}|Enchantment|||Extort$Whenever a nontoken creature dies, you lose 1 life and create a Treasure token.| -Mayhem Devil|Duskmourn: House of Horror Commander|225|U|{1}{B}{R}|Creature - Devil|3|3|Whenever a player sacrifices a permanent, Mayhem Devil deals 1 damage to any target.| -Nyx Weaver|Duskmourn: House of Horror Commander|226|U|{1}{B}{G}|Enchantment Creature - Spider|2|3|Reach$At the beginning of your upkeep, mill two cards.${1}{B}{G}, Exile Nyx Weaver: Return target card from your graveyard to your hand.| +Mayhem Devil|Duskmourn: House of Horror Commander|225|U|{1}{B}{R}|Creature - Devil|3|3|Whenever a player sacrifices a permanent, this creature deals 1 damage to any target.| +Nyx Weaver|Duskmourn: House of Horror Commander|226|U|{1}{B}{G}|Enchantment Creature - Spider|2|3|Reach$At the beginning of your upkeep, mill two cards.${1}{B}{G}, Exile this creature: Return target card from your graveyard to your hand.| Old Stickfingers|Duskmourn: House of Horror Commander|227|R|{X}{B}{G}|Legendary Creature - Horror|*|*|When you cast this spell, reveal cards from the top of your library until you reveal X creature cards. Put all creature cards revealed this way into your graveyard, then put the rest on the bottom of your library in a random order.$Old Stickfingers's power and toughness are each equal to the number of creature cards in your graveyard.| Oversimplify|Duskmourn: House of Horror Commander|228|R|{3}{G}{U}|Sorcery|||Exile all creatures. Each player creates a 0/0 green and blue Fractal creature token and puts a number of +1/+1 counters on it equal to the total power of creatures they controlled that were exiled this way.| Rakdos Charm|Duskmourn: House of Horror Commander|229|U|{B}{R}|Instant|||Choose one --$* Exile target player's graveyard.$* Destroy target artifact.$* Each creature deals 1 damage to its controller.| -Rakdos, Lord of Riots|Duskmourn: House of Horror Commander|230|M|{B}{B}{R}{R}|Legendary Creature - Demon|6|6|You can't cast this spell unless an opponent lost life this turn.$Flying, trample$Creature spells you cast cost {1} less to cast for each 1 life your opponents have lost this turn.| +Rakdos, Lord of Riots|Duskmourn: House of Horror Commander|230|M|{B}{B}{R}{R}|Legendary Creature - Demon|6|6|You can't cast Rakdos unless an opponent lost life this turn.$Flying, trample$Creature spells you cast cost {1} less to cast for each 1 life your opponents have lost this turn.| Rashmi, Eternities Crafter|Duskmourn: House of Horror Commander|231|M|{2}{G}{U}|Legendary Creature - Elf Druid|2|3|Whenever you cast your first spell each turn, reveal the top card of your library. You may cast it without paying its mana cost if it's a spell with lesser mana value. If you don't cast it, put it into your hand.| Spirit-Sister's Call|Duskmourn: House of Horror Commander|232|M|{3}{W}{B}|Enchantment|||At the beginning of your end step, choose target permanent card in your graveyard. You may sacrifice a permanent that shares a card type with the chosen card. If you do, return the chosen card from your graveyard to the battlefield and it gains "If this permanent would leave the battlefield, exile it instead of putting it anywhere else."| -Spiteful Visions|Duskmourn: House of Horror Commander|233|R|{2}{B/R}{B/R}|Enchantment|||At the beginning of each player's draw step, that player draws an additional card.$Whenever a player draws a card, Spiteful Visions deals 1 damage to that player.| +Spiteful Visions|Duskmourn: House of Horror Commander|233|R|{2}{B/R}{B/R}|Enchantment|||At the beginning of each player's draw step, that player draws an additional card.$Whenever a player draws a card, this enchantment deals 1 damage to that player.| Stormfist Crusader|Duskmourn: House of Horror Commander|234|R|{B}{R}|Creature - Human Knight|2|2|Menace$At the beginning of your upkeep, each player draws a card and loses 1 life.| Tatyova, Benthic Druid|Duskmourn: House of Horror Commander|235|U|{3}{G}{U}|Legendary Creature - Merfolk Druid|3|3|Landfall -- Whenever a land you control enters, you gain 1 life and draw a card.| -Theater of Horrors|Duskmourn: House of Horror Commander|236|R|{1}{B}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of your library.$During your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with Theater of Horrors.${3}{R}: Theater of Horrors deals 1 damage to target opponent or planeswalker.| +Theater of Horrors|Duskmourn: House of Horror Commander|236|R|{1}{B}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of your library.$During your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with this enchantment.${3}{R}: This enchantment deals 1 damage to target opponent or planeswalker.| Time Wipe|Duskmourn: House of Horror Commander|237|R|{2}{W}{W}{U}|Sorcery|||Return a creature you control to its owner's hand, then destroy all creatures.| -Trygon Predator|Duskmourn: House of Horror Commander|238|U|{1}{G}{U}|Creature - Beast|2|3|Flying$Whenever Trygon Predator deals combat damage to a player, you may destroy target artifact or enchantment that player controls.| -Vial Smasher the Fierce|Duskmourn: House of Horror Commander|239|M|{1}{B}{R}|Legendary Creature - Goblin Berserker|2|3|Whenever you cast your first spell each turn, choose an opponent at random. Vial Smasher the Fierce deals damage equal to that spell's mana value to that player or a planeswalker that player controls.$Partner| +Trygon Predator|Duskmourn: House of Horror Commander|238|U|{1}{G}{U}|Creature - Beast|2|3|Flying$Whenever this creature deals combat damage to a player, you may destroy target artifact or enchantment that player controls.| +Vial Smasher the Fierce|Duskmourn: House of Horror Commander|239|M|{1}{B}{R}|Legendary Creature - Goblin Berserker|2|3|Whenever you cast your first spell each turn, choose an opponent at random. Vial Smasher deals damage equal to that spell's mana value to that player or a planeswalker that player controls.$Partner| Azorius Signet|Duskmourn: House of Horror Commander|240|U|{2}|Artifact|||{1}, {T}: Add {W}{U}.| Basilisk Collar|Duskmourn: House of Horror Commander|241|R|{1}|Artifact - Equipment|||Equipped creature has deathtouch and lifelink.$Equip {2}| -Brainstone|Duskmourn: House of Horror Commander|242|U|{1}|Artifact|||{2}, {T}, Sacrifice Brainstone: Draw three cards, then put two cards from your hand on top of your library in any order.| -Burnished Hart|Duskmourn: House of Horror Commander|243|U|{3}|Artifact Creature - Elk|2|2|{3}, Sacrifice Burnished Hart: Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle.| -Commander's Sphere|Duskmourn: House of Horror Commander|244|C|{3}|Artifact|||{T}: Add one mana of any color in your commander's color identity.$Sacrifice Commander's Sphere: Draw a card.| +Brainstone|Duskmourn: House of Horror Commander|242|U|{1}|Artifact|||{2}, {T}, Sacrifice this artifact: Draw three cards, then put two cards from your hand on top of your library in any order.| +Burnished Hart|Duskmourn: House of Horror Commander|243|U|{3}|Artifact Creature - Elk|2|2|{3}, Sacrifice this creature: Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle.| +Commander's Sphere|Duskmourn: House of Horror Commander|244|C|{3}|Artifact|||{T}: Add one mana of any color in your commander's color identity.$Sacrifice this artifact: Draw a card.| Fellwar Stone|Duskmourn: House of Horror Commander|245|U|{2}|Artifact|||{T}: Add one mana of any color that a land an opponent controls could produce.| -Golgari Signet|Duskmourn: House of Horror Commander|246|C|{2}|Artifact|||{1}, {T}: Add {B}{G}.| -Haywire Mite|Duskmourn: House of Horror Commander|247|U|{1}|Artifact Creature - Insect|1|1|When Haywire Mite dies, you gain 2 life.${G}, Sacrifice Haywire Mite: Exile target noncreature artifact or noncreature enchantment.| -Mind Stone|Duskmourn: House of Horror Commander|248|U|{2}|Artifact|||{T}: Add {C}.${1}, {T}, Sacrifice Mind Stone: Draw a card.| +Golgari Signet|Duskmourn: House of Horror Commander|246|U|{2}|Artifact|||{1}, {T}: Add {B}{G}.| +Haywire Mite|Duskmourn: House of Horror Commander|247|U|{1}|Artifact Creature - Insect|1|1|When this creature dies, you gain 2 life.${G}, Sacrifice this creature: Exile target noncreature artifact or noncreature enchantment.| +Mind Stone|Duskmourn: House of Horror Commander|248|U|{2}|Artifact|||{T}: Add {C}.${1}, {T}, Sacrifice this artifact: Draw a card.| Orzhov Signet|Duskmourn: House of Horror Commander|249|U|{2}|Artifact|||{1}, {T}: Add {W}{B}.| Rakdos Signet|Duskmourn: House of Horror Commander|250|U|{2}|Artifact|||{1}, {T}: Add {B}{R}.| Scroll of Fate|Duskmourn: House of Horror Commander|251|R|{3}|Artifact|||{T}: Manifest a card from your hand.| Simic Signet|Duskmourn: House of Horror Commander|252|U|{2}|Artifact|||{1}, {T}: Add {G}{U}.| -Solemn Simulacrum|Duskmourn: House of Horror Commander|253|R|{4}|Artifact Creature - Golem|2|2|When Solemn Simulacrum enters, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.$When Solemn Simulacrum dies, you may draw a card.| -Talisman of Indulgence|Duskmourn: House of Horror Commander|254|U|{2}|Artifact|||{T}: Add {C}.${T}: Add {B} or {R}. Talisman of Indulgence deals 1 damage to you.| -Talisman of Resilience|Duskmourn: House of Horror Commander|255|U|{2}|Artifact|||{T}: Add {C}.${T}: Add {B} or {G}. Talisman of Resilience deals 1 damage to you.| -Thought Vessel|Duskmourn: House of Horror Commander|256|U|{2}|Artifact|||You have no maximum hand size.${T}: Add {C}.| +Solemn Simulacrum|Duskmourn: House of Horror Commander|253|R|{4}|Artifact Creature - Golem|2|2|When this creature enters, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.$When this creature dies, you may draw a card.| +Talisman of Indulgence|Duskmourn: House of Horror Commander|254|U|{2}|Artifact|||{T}: Add {C}.${T}: Add {B} or {R}. This artifact deals 1 damage to you.| +Talisman of Resilience|Duskmourn: House of Horror Commander|255|U|{2}|Artifact|||{T}: Add {C}.${T}: Add {B} or {G}. This artifact deals 1 damage to you.| +Thought Vessel|Duskmourn: House of Horror Commander|256|C|{2}|Artifact|||You have no maximum hand size.${T}: Add {C}.| Whispersilk Cloak|Duskmourn: House of Horror Commander|257|U|{3}|Artifact - Equipment|||Equipped creature can't be blocked and has shroud.$Equip {2}| -Adarkar Wastes|Duskmourn: House of Horror Commander|258|R||Land|||{T}: Add {C}.${T}: Add {W} or {U}. Adarkar Wastes deals 1 damage to you.| -Arcane Sanctum|Duskmourn: House of Horror Commander|259|U||Land|||Arcane Sanctum enters tapped.${T}: Add {W}, {U}, or {B}.| +Adarkar Wastes|Duskmourn: House of Horror Commander|258|R||Land|||{T}: Add {C}.${T}: Add {W} or {U}. This land deals 1 damage to you.| +Arcane Sanctum|Duskmourn: House of Horror Commander|259|U||Land|||This land enters tapped.${T}: Add {W}, {U}, or {B}.| Ash Barrens|Duskmourn: House of Horror Commander|260|C||Land|||{T}: Add {C}.$Basic landcycling {1}| -Azorius Chancery|Duskmourn: House of Horror Commander|261|U||Land|||Azorius Chancery enters tapped.$When Azorius Chancery enters, return a land you control to its owner's hand.${T}: Add {W}{U}.| -Barren Moor|Duskmourn: House of Horror Commander|262|U||Land|||Barren Moor enters tapped.${T}: Add {B}.$Cycling {B}| -Blackcleave Cliffs|Duskmourn: House of Horror Commander|263|R||Land|||Blackcleave Cliffs enters tapped unless you control two or fewer other lands.${T}: Add {B} or {R}.| -Bloodfell Caves|Duskmourn: House of Horror Commander|264|C||Land|||Bloodfell Caves enters tapped.$When Bloodfell Caves enters, you gain 1 life.${T}: Add {B} or {R}.| -Bojuka Bog|Duskmourn: House of Horror Commander|265|C||Land|||Bojuka Bog enters tapped.$When Bojuka Bog enters, exile target player's graveyard.${T}: Add {B}.| -Canyon Slough|Duskmourn: House of Horror Commander|266|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$Canyon Slough enters tapped.$Cycling {2}| -Castle Vantress|Duskmourn: House of Horror Commander|267|R||Land|||Castle Vantress enters tapped unless you control an Island.${T}: Add {U}.${2}{U}{U}, {T}: Scry 2.| -Caves of Koilos|Duskmourn: House of Horror Commander|268|R||Land|||{T}: Add {C}.${T}: Add {W} or {B}. Caves of Koilos deals 1 damage to you.| -Darkmoss Bridge|Duskmourn: House of Horror Commander|269|C||Artifact Land|||Darkmoss Bridge enters tapped.$Indestructible${T}: Add {B} or {G}.| -Dimir Aqueduct|Duskmourn: House of Horror Commander|270|U||Land|||Dimir Aqueduct enters tapped.$When Dimir Aqueduct enters, return a land you control to its owner's hand.${T}: Add {U}{B}.| -Dragonskull Summit|Duskmourn: House of Horror Commander|271|R||Land|||Dragonskull Summit enters tapped unless you control a Swamp or a Mountain.${T}: Add {B} or {R}.| -Drownyard Temple|Duskmourn: House of Horror Commander|272|R||Land|||{T}: Add {C}.${3}: Return Drownyard Temple from your graveyard to the battlefield tapped.| -Dryad Arbor|Duskmourn: House of Horror Commander|273|R||Land Creature - Forest Dryad|1|1|(Dryad Arbor isn't a spell, it's affected by summoning sickness, and it has "{T}: Add {G}.")| -Evolving Wilds|Duskmourn: House of Horror Commander|274|C||Land|||{T}, Sacrifice Evolving Wilds: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.| +Azorius Chancery|Duskmourn: House of Horror Commander|261|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {W}{U}.| +Barren Moor|Duskmourn: House of Horror Commander|262|U||Land|||This land enters tapped.${T}: Add {B}.$Cycling {B}| +Blackcleave Cliffs|Duskmourn: House of Horror Commander|263|R||Land|||This land enters tapped unless you control two or fewer other lands.${T}: Add {B} or {R}.| +Bloodfell Caves|Duskmourn: House of Horror Commander|264|C||Land|||This land enters tapped.$When this land enters, you gain 1 life.${T}: Add {B} or {R}.| +Bojuka Bog|Duskmourn: House of Horror Commander|265|C||Land|||This land enters tapped.$When this land enters, exile target player's graveyard.${T}: Add {B}.| +Canyon Slough|Duskmourn: House of Horror Commander|266|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$This land enters tapped.$Cycling {2}| +Castle Vantress|Duskmourn: House of Horror Commander|267|R||Land|||This land enters tapped unless you control an Island.${T}: Add {U}.${2}{U}{U}, {T}: Scry 2.| +Caves of Koilos|Duskmourn: House of Horror Commander|268|R||Land|||{T}: Add {C}.${T}: Add {W} or {B}. This land deals 1 damage to you.| +Darkmoss Bridge|Duskmourn: House of Horror Commander|269|C||Artifact Land|||This land enters tapped.$Indestructible${T}: Add {B} or {G}.| +Dimir Aqueduct|Duskmourn: House of Horror Commander|270|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {U}{B}.| +Dragonskull Summit|Duskmourn: House of Horror Commander|271|R||Land|||This land enters tapped unless you control a Swamp or a Mountain.${T}: Add {B} or {R}.| +Drownyard Temple|Duskmourn: House of Horror Commander|272|R||Land|||{T}: Add {C}.${3}: Return this card from your graveyard to the battlefield tapped.| +Dryad Arbor|Duskmourn: House of Horror Commander|273|R||Land Creature - Forest Dryad|1|1|(This land isn't a spell, it's affected by summoning sickness, and it has "{T}: Add {G}.")| +Evolving Wilds|Duskmourn: House of Horror Commander|274|C||Land|||{T}, Sacrifice this land: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.| Exotic Orchard|Duskmourn: House of Horror Commander|275|R||Land|||{T}: Add one mana of any color that a land an opponent controls could produce.| Flooded Grove|Duskmourn: House of Horror Commander|276|R||Land|||{T}: Add {C}.${G/U}, {T}: Add {G}{G}, {G}{U}, or {U}{U}.| -Foreboding Ruins|Duskmourn: House of Horror Commander|277|R||Land|||As Foreboding Ruins enters, you may reveal a Swamp or Mountain card from your hand. If you don't, Foreboding Ruins enters tapped.${T}: Add {B} or {R}.| -Geothermal Bog|Duskmourn: House of Horror Commander|278|C||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$Geothermal Bog enters tapped.| -Golgari Rot Farm|Duskmourn: House of Horror Commander|279|C||Land|||Golgari Rot Farm enters tapped.$When Golgari Rot Farm enters, return a land you control to its owner's hand.${T}: Add {B}{G}.| +Foreboding Ruins|Duskmourn: House of Horror Commander|277|R||Land|||As this land enters, you may reveal a Swamp or Mountain card from your hand. If you don't, this land enters tapped.${T}: Add {B} or {R}.| +Geothermal Bog|Duskmourn: House of Horror Commander|278|C||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$This land enters tapped.| +Golgari Rot Farm|Duskmourn: House of Horror Commander|279|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {B}{G}.| Graven Cairns|Duskmourn: House of Horror Commander|280|R||Land|||{T}: Add {C}.${B/R}, {T}: Add {B}{B}, {B}{R}, or {R}{R}.| Grim Backwoods|Duskmourn: House of Horror Commander|281|R||Land|||{T}: Add {C}.${2}{B}{G}, {T}, Sacrifice a creature: Draw a card.| -Halimar Depths|Duskmourn: House of Horror Commander|282|C||Land|||Halimar Depths enters tapped.$When Halimar Depths enters, look at the top three cards of your library, then put them back in any order.${T}: Add {U}.| +Halimar Depths|Duskmourn: House of Horror Commander|282|C||Land|||This land enters tapped.$When this land enters, look at the top three cards of your library, then put them back in any order.${T}: Add {U}.| Hall of Heliod's Generosity|Duskmourn: House of Horror Commander|283|R||Legendary Land|||{T}: Add {C}.${1}{W}, {T}: Put target enchantment card from your graveyard on top of your library.| -Hinterland Harbor|Duskmourn: House of Horror Commander|284|R||Land|||Hinterland Harbor enters tapped unless you control a Forest or an Island.${T}: Add {G} or {U}.| -Jungle Hollow|Duskmourn: House of Horror Commander|285|C||Land|||Jungle Hollow enters tapped.$When Jungle Hollow enters, you gain 1 life.${T}: Add {B} or {G}.| -Leechridden Swamp|Duskmourn: House of Horror Commander|286|U||Land - Swamp|||({T}: Add {B}.)$Leechridden Swamp enters tapped.${B}, {T}: Each opponent loses 1 life. Activate only if you control two or more black permanents.| -Llanowar Wastes|Duskmourn: House of Horror Commander|287|R||Land|||{T}: Add {C}.${T}: Add {B} or {G}. Llanowar Wastes deals 1 damage to you.| -Mosswort Bridge|Duskmourn: House of Horror Commander|288|R||Land|||Hideaway 4$Mosswort Bridge enters tapped.${T}: Add {G}.${G}, {T}: You may play the exiled card without paying its mana cost if creatures you control have total power 10 or greater.| -Myriad Landscape|Duskmourn: House of Horror Commander|289|U||Land|||Myriad Landscape enters tapped.${T}: Add {C}.${2}, {T}, Sacrifice Myriad Landscape: Search your library for up to two basic land cards that share a land type, put them onto the battlefield tapped, then shuffle.| -Necroblossom Snarl|Duskmourn: House of Horror Commander|290|R||Land|||As Necroblossom Snarl enters, you may reveal a Swamp or Forest card from your hand. If you don't, Necroblossom Snarl enters tapped.${T}: Add {B} or {G}.| -Obscura Storefront|Duskmourn: House of Horror Commander|291|C||Land|||When Obscura Storefront enters, sacrifice it. When you do, search your library for a basic Plains, Island, or Swamp card, put it onto the battlefield tapped, then shuffle and you gain 1 life.| -Orzhov Basilica|Duskmourn: House of Horror Commander|292|U||Land|||Orzhov Basilica enters tapped.$When Orzhov Basilica enters, return a land you control to its owner's hand.${T}: Add {W}{B}.| +Hinterland Harbor|Duskmourn: House of Horror Commander|284|R||Land|||This land enters tapped unless you control a Forest or an Island.${T}: Add {G} or {U}.| +Jungle Hollow|Duskmourn: House of Horror Commander|285|C||Land|||This land enters tapped.$When this land enters, you gain 1 life.${T}: Add {B} or {G}.| +Leechridden Swamp|Duskmourn: House of Horror Commander|286|U||Land - Swamp|||({T}: Add {B}.)$This land enters tapped.${B}, {T}: Each opponent loses 1 life. Activate only if you control two or more black permanents.| +Llanowar Wastes|Duskmourn: House of Horror Commander|287|R||Land|||{T}: Add {C}.${T}: Add {B} or {G}. This land deals 1 damage to you.| +Mosswort Bridge|Duskmourn: House of Horror Commander|288|R||Land|||Hideaway 4$This land enters tapped.${T}: Add {G}.${G}, {T}: You may play the exiled card without paying its mana cost if creatures you control have total power 10 or greater.| +Myriad Landscape|Duskmourn: House of Horror Commander|289|U||Land|||This land enters tapped.${T}: Add {C}.${2}, {T}, Sacrifice this land: Search your library for up to two basic land cards that share a land type, put them onto the battlefield tapped, then shuffle.| +Necroblossom Snarl|Duskmourn: House of Horror Commander|290|R||Land|||As this land enters, you may reveal a Swamp or Forest card from your hand. If you don't, this land enters tapped.${T}: Add {B} or {G}.| +Obscura Storefront|Duskmourn: House of Horror Commander|291|C||Land|||When this land enters, sacrifice it. When you do, search your library for a basic Plains, Island, or Swamp card, put it onto the battlefield tapped, then shuffle and you gain 1 life.| +Orzhov Basilica|Duskmourn: House of Horror Commander|292|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {W}{B}.| Overflowing Basin|Duskmourn: House of Horror Commander|293|R||Land|||{1}, {T}: Add {G}{U}.| -Quandrix Campus|Duskmourn: House of Horror Commander|294|C||Land|||Quandrix Campus enters tapped.${T}: Add {G} or {U}.${4}, {T}: Scry 1.| +Quandrix Campus|Duskmourn: House of Horror Commander|294|C||Land|||This land enters tapped.${T}: Add {G} or {U}.${4}, {T}: Scry 1.| Reliquary Tower|Duskmourn: House of Horror Commander|295|U||Land|||You have no maximum hand size.${T}: Add {C}.| Shadowblood Ridge|Duskmourn: House of Horror Commander|296|R||Land|||{1}, {T}: Add {B}{R}.| Shivan Gorge|Duskmourn: House of Horror Commander|297|R||Legendary Land|||{T}: Add {C}.${2}{R}, {T}: Shivan Gorge deals 1 damage to each opponent.| -Simic Growth Chamber|Duskmourn: House of Horror Commander|298|U||Land|||Simic Growth Chamber enters tapped.$When Simic Growth Chamber enters, return a land you control to its owner's hand.${T}: Add {G}{U}.| -Smoldering Marsh|Duskmourn: House of Horror Commander|299|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$Smoldering Marsh enters tapped unless you control two or more basic lands.| -Spinerock Knoll|Duskmourn: House of Horror Commander|300|R||Land|||Hideaway 4$Spinerock Knoll enters tapped.${T}: Add {R}.${R}, {T}: You may play the exiled card without paying its mana cost if an opponent was dealt 7 or more damage this turn.| -Sulfurous Springs|Duskmourn: House of Horror Commander|301|R||Land|||{T}: Add {C}.${T}: Add {B} or {R}. Sulfurous Springs deals 1 damage to you.| +Simic Growth Chamber|Duskmourn: House of Horror Commander|298|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {G}{U}.| +Smoldering Marsh|Duskmourn: House of Horror Commander|299|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$This land enters tapped unless you control two or more basic lands.| +Spinerock Knoll|Duskmourn: House of Horror Commander|300|R||Land|||Hideaway 4$This land enters tapped.${T}: Add {R}.${R}, {T}: You may play the exiled card without paying its mana cost if an opponent was dealt 7 or more damage this turn.| +Sulfurous Springs|Duskmourn: House of Horror Commander|301|R||Land|||{T}: Add {C}.${T}: Add {B} or {R}. This land deals 1 damage to you.| Tainted Field|Duskmourn: House of Horror Commander|302|U||Land|||{T}: Add {C}.${T}: Add {W} or {B}. Activate only if you control a Swamp.| Tainted Isle|Duskmourn: House of Horror Commander|303|U||Land|||{T}: Add {C}.${T}: Add {U} or {B}. Activate only if you control a Swamp.| Tainted Peak|Duskmourn: House of Horror Commander|304|U||Land|||{T}: Add {C}.${T}: Add {B} or {R}. Activate only if you control a Swamp.| Tainted Wood|Duskmourn: House of Horror Commander|305|U||Land|||{T}: Add {C}.${T}: Add {B} or {G}. Activate only if you control a Swamp.| -Tangled Islet|Duskmourn: House of Horror Commander|306|C||Land - Forest Island|||({T}: Add {G} or {U}.)$Tangled Islet enters tapped.| -Temple of Deceit|Duskmourn: House of Horror Commander|307|R||Land|||Temple of Deceit enters tapped.$When Temple of Deceit enters, scry 1.${T}: Add {U} or {B}.| -Temple of Enlightenment|Duskmourn: House of Horror Commander|308|R||Land|||Temple of Enlightenment enters tapped.$When Temple of Enlightenment enters, scry 1.${T}: Add {W} or {U}.| -Temple of Malady|Duskmourn: House of Horror Commander|309|R||Land|||Temple of Malady enters tapped.$When Temple of Malady enters, scry 1.${T}: Add {B} or {G}.| -Temple of Malice|Duskmourn: House of Horror Commander|310|R||Land|||Temple of Malice enters tapped.$When Temple of Malice enters, scry 1.${T}: Add {B} or {R}.| -Temple of Mystery|Duskmourn: House of Horror Commander|311|R||Land|||Temple of Mystery enters tapped.$When Temple of Mystery enters, scry 1.${T}: Add {G} or {U}.| -Temple of Silence|Duskmourn: House of Horror Commander|312|R||Land|||Temple of Silence enters tapped.$When Temple of Silence enters, scry 1.${T}: Add {W} or {B}.| +Tangled Islet|Duskmourn: House of Horror Commander|306|C||Land - Forest Island|||({T}: Add {G} or {U}.)$This land enters tapped.| +Temple of Deceit|Duskmourn: House of Horror Commander|307|R||Land|||This land enters tapped.$When this land enters, scry 1.${T}: Add {U} or {B}.| +Temple of Enlightenment|Duskmourn: House of Horror Commander|308|R||Land|||This land enters tapped.$When this land enters, scry 1.${T}: Add {W} or {U}.| +Temple of Malady|Duskmourn: House of Horror Commander|309|R||Land|||This land enters tapped.$When this land enters, scry 1.${T}: Add {B} or {G}.| +Temple of Malice|Duskmourn: House of Horror Commander|310|R||Land|||This land enters tapped.$When this land enters, scry 1.${T}: Add {B} or {R}.| +Temple of Mystery|Duskmourn: House of Horror Commander|311|R||Land|||This land enters tapped.$When this land enters, scry 1.${T}: Add {G} or {U}.| +Temple of Silence|Duskmourn: House of Horror Commander|312|R||Land|||This land enters tapped.$When this land enters, scry 1.${T}: Add {W} or {B}.| Temple of the False God|Duskmourn: House of Horror Commander|313|U||Land|||{T}: Add {C}{C}. Activate only if you control five or more lands.| -Thornwood Falls|Duskmourn: House of Horror Commander|314|C||Land|||Thornwood Falls enters tapped.$When Thornwood Falls enters, you gain 1 life.${T}: Add {G} or {U}.| -Thriving Heath|Duskmourn: House of Horror Commander|315|C||Land|||Thriving Heath enters tapped. As it enters, choose a color other than white.${T}: Add {W} or one mana of the chosen color.| -Thriving Isle|Duskmourn: House of Horror Commander|316|C||Land|||Thriving Isle enters tapped. As it enters, choose a color other than blue.${T}: Add {U} or one mana of the chosen color.| -Thriving Moor|Duskmourn: House of Horror Commander|317|C||Land|||Thriving Moor enters tapped. As it enters, choose a color other than black.${T}: Add {B} or one mana of the chosen color.| -Tranquil Thicket|Duskmourn: House of Horror Commander|318|C||Land|||Tranquil Thicket enters tapped.${T}: Add {G}.$Cycling {G}| +Thornwood Falls|Duskmourn: House of Horror Commander|314|C||Land|||This land enters tapped.$When this land enters, you gain 1 life.${T}: Add {G} or {U}.| +Thriving Heath|Duskmourn: House of Horror Commander|315|C||Land|||This land enters tapped. As it enters, choose a color other than white.${T}: Add {W} or one mana of the chosen color.| +Thriving Isle|Duskmourn: House of Horror Commander|316|C||Land|||This land enters tapped. As it enters, choose a color other than blue.${T}: Add {U} or one mana of the chosen color.| +Thriving Moor|Duskmourn: House of Horror Commander|317|C||Land|||This land enters tapped. As it enters, choose a color other than black.${T}: Add {B} or one mana of the chosen color.| +Tranquil Thicket|Duskmourn: House of Horror Commander|318|C||Land|||This land enters tapped.${T}: Add {G}.$Cycling {G}| Tree of Tales|Duskmourn: House of Horror Commander|319|C||Artifact Land|||{T}: Add {G}.| Twilight Mire|Duskmourn: House of Horror Commander|320|R||Land|||{T}: Add {C}.${B/G}, {T}: Add {B}{B}, {B}{G}, or {G}{G}.| -Underground River|Duskmourn: House of Horror Commander|321|R||Land|||{T}: Add {C}.${T}: Add {U} or {B}. Underground River deals 1 damage to you.| +Underground River|Duskmourn: House of Horror Commander|321|R||Land|||{T}: Add {C}.${T}: Add {U} or {B}. This land deals 1 damage to you.| Vault of Whispers|Duskmourn: House of Horror Commander|322|C||Artifact Land|||{T}: Add {B}.| -Vineglimmer Snarl|Duskmourn: House of Horror Commander|323|R||Land|||As Vineglimmer Snarl enters, you may reveal a Forest or Island card from your hand. If you don't, Vineglimmer Snarl enters tapped.${T}: Add {G} or {U}.| +Vineglimmer Snarl|Duskmourn: House of Horror Commander|323|R||Land|||As this land enters, you may reveal a Forest or Island card from your hand. If you don't, this land enters tapped.${T}: Add {G} or {U}.| Viridescent Bog|Duskmourn: House of Horror Commander|324|R||Land|||{1}, {T}: Add {B}{G}.| Witch's Clinic|Duskmourn: House of Horror Commander|325|R||Land|||{T}: Add {C}.${2}, {T}: Target commander gains lifelink until end of turn.| -Woodland Cemetery|Duskmourn: House of Horror Commander|326|R||Land|||Woodland Cemetery enters tapped unless you control a Swamp or a Forest.${T}: Add {B} or {G}.| -Yavimaya Coast|Duskmourn: House of Horror Commander|327|R||Land|||{T}: Add {C}.${T}: Add {G} or {U}. Yavimaya Coast deals 1 damage to you.| +Woodland Cemetery|Duskmourn: House of Horror Commander|326|R||Land|||This land enters tapped unless you control a Swamp or a Forest.${T}: Add {B} or {G}.| +Yavimaya Coast|Duskmourn: House of Horror Commander|327|R||Land|||{T}: Add {C}.${T}: Add {G} or {U}. This land deals 1 damage to you.| Crypt Ghast|Duskmourn: House of Horror Commander|368|M|{3}{B}|Creature - Spirit|2|2|Extort$Whenever you tap a Swamp for mana, add an additional {B}.| Damn|Duskmourn: House of Horror Commander|369|M|{B}{B}|Sorcery|||Destroy target creature. A creature destroyed this way can't be regenerated.$Overload {2}{W}{W}| Exhume|Duskmourn: House of Horror Commander|370|M|{1}{B}|Sorcery|||Each player puts a creature card from their graveyard onto the battlefield.| -Archon of Cruelty|Duskmourn: House of Horror Commander|371|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever Archon of Cruelty enters or attacks, target opponent sacrifices a creature or planeswalker, discards a card, and loses 3 life. You draw a card and gain 3 life.| +Archon of Cruelty|Duskmourn: House of Horror Commander|371|M|{6}{B}{B}|Creature - Archon|6|6|Flying$Whenever this creature enters or attacks, target opponent sacrifices a creature or planeswalker of their choice, discards a card, and loses 3 life. You draw a card and gain 3 life.| Goryo's Vengeance|Duskmourn: House of Horror Commander|372|M|{1}{B}|Instant - Arcane|||Return target legendary creature card from your graveyard to the battlefield. That creature gains haste. Exile it at the beginning of the next end step.$Splice onto Arcane {2}{B}| Living Death|Duskmourn: House of Horror Commander|373|M|{3}{B}{B}|Sorcery|||Each player exiles all creature cards from their graveyard, then sacrifices all creatures they control, then puts all cards they exiled this way onto the battlefield.| Celestial Vault|Alchemy: New Capenna|1|U|{1}{W}|Artifact|||{W}, {T}: Draft a card from Celestial Vault's spellbook and exile it face down.${1}, Sacrifice Celestial Vault: Put each card exiled with Celestial Vault into your hand.| @@ -60796,7 +60823,10 @@ Isilu, Carrier of Twilight|Lorwyn Eclipsed|13|M||Legendary Creature - Elemental Morningtide's Light|Lorwyn Eclipsed|27|M|{3}{W}|Sorcery|||Exile any number of target creatures. At the beginning of the next end step, return those cards to the battlefield tapped under their owners' control.$Until your next turn, prevent all damage that would be dealt to you.$Exile Morningtide's Light.| Sygg, Wanderwine Wisdom|Lorwyn Eclipsed|76|R|{1}{U}|Legendary Creature - Merfolk Wizard|2|2|Sygg can't be blocked.$Whenever this creature enters or transforms into Sygg, Wanderwine Wisdom, target creature gains "Whenever this creature deals combat damage to a player or planeswalker, draw a card" until end of turn.$At the beginning of your first main phase, you may pay {W}. If you do, transform Sygg.| Sygg, Wanderbrine Shield|Lorwyn Eclipsed|76|R||Legendary Creature - Merfolk Rogue|2|2|Sygg can't be blocked.$Whenever this creature transforms into Sygg, Wanderbrine Shield, target creature you control gains protection from each color until your next turn.$At the beginning of your first main phase, you may pay {U}. If you do, transform Sygg.| +Unexpected Assistance|Lorwyn Eclipsed|80|C|{3}{U}{U}|Instant|||Convoke$Draw three cards, then discard a card.| Bitterbloom Bearer|Lorwyn Eclipsed|88|M|{B}{B}|Creature - Faerie Rogue|1|1|Flash$Flying$At the beginning of your upkeep, you lose 1 life and create a 1/1 blue and black Faerie creature token with flying.| +Dose of Dawnglow|Lorwyn Eclipsed|100|U|{4}{B}|Instant|||Return target creature card from your graveyard to the battlefield. Then if it isn't your main phase, blight 2.| +Perfect Intimidation|Lorwyn Eclipsed|115|U|{3}{B}|Sorcery|||Choose one or both --$* Target opponent exiles two cards from their hand.$* Remove all counters from target creature.| Ashling, Rekindled|Lorwyn Eclipsed|124|R|{1}{R}|Legendary Creature - Elemental Sorcerer|1|3|Whenever this creature enters or transforms into Ashling, Rekindled, you may discard a card. If you do, draw a card.$At the beginning of your first main phase, you may pay {U}. If you do, transform Ashling.| Ashling, Rimebound|Lorwyn Eclipsed|124|R||Legendary Creature - Elemental Wizard|1|3|Whenever this creature transforms into Ashling, Rimebound and at the beginning of your first main phase, add two mana of any one color. Spend this mana only to cast spells with mana value 4 or greater.$At the beginning of your first main phase, you may pay {R}. If you do, transform Ashling.| Formidable Speaker|Lorwyn Eclipsed|176|R|{2}{G}|Creature - Elf Druid|2|4|When this creature enters, you may discard a card. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle.${1}, {T}: Untap another target permanent.| @@ -60805,6 +60835,8 @@ Ashling's Command|Lorwyn Eclipsed|205|R|{3}{U}{R}|Kindred Instant - Elemental||| Deceit|Lorwyn Eclipsed|212|M|{4}{U/B}{U/B}|Creature - Elemental Incarnation|5|5|When this creature enters, if {U}{U} was spent to cast it, return up to one other target nonland permanent to its owner's hand.$When this creature enters, if {B}{B} was spent to cast it, target opponent reveals their hand. You choose a nonland card from it. That player discards that card.$Evoke {U/B}{U/B}| Emptiness|Lorwyn Eclipsed|222|M|{4}{W/B}{W/B}|Creature - Elemental Incarnation|3|5|When this creature enters, if {W}{W} was spent to cast it, return target creature card with mana value 3 or less from your graveyard to the battlefield.$When this creature enters, if {B}{B} was spent to cast it, put three -1/-1 counters on up to one target creature.$Evoke {W/B}{W/B}| Figure of Fable|Lorwyn Eclipsed|224|R|{G/W}|Creature - Kithkin|1|1|{G/W}: This creature becomes a Kithkin Scout with base power and toughness 2/3.${1}{G/W}{G/W}: If this creature is a Scout, it becomes a Kithkin Soldier with base power and toughness 4/5.${3}{G/W}{G/W}{G/W}: If this creature is a Soldier, it becomes a Kithkin Avatar with base power and toughness 7/8 and protection from each of your opponents.| +High Perfect Morcant|Lorwyn Eclipsed|229|R|{2}{B}{G}|Legendary Creature - Elf Noble|4|4|Whenever High Perfect Morcant or another Elf you control enters, each opponent blights 1.$Tap three untapped Elves you control: Proliferate. Activate only as a sorcery.| +Kirol, Attentive First-Year|Lorwyn Eclipsed|231|R|{1}{R/W}{R/W}|Legendary Creature - Vampire Cleric|3|3|Tap two untapped creatures you control: Copy target triggered ability you control. You may choose new targets for the copy. Activate only once each turn.| Blood Crypt|Lorwyn Eclipsed|262|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Hallowed Fountain|Lorwyn Eclipsed|265|R||Land - Plains Island|||({T}: Add {W} or {U}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Overgrown Tomb|Lorwyn Eclipsed|266|R||Land - Swamp Forest|||({T}: Add {B} or {G}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| @@ -60823,13 +60855,20 @@ Bitterbloom Bearer|Lorwyn Eclipsed|310|M|{B}{B}|Creature - Faerie Rogue|1|1|Flas Mutable Explorer|Lorwyn Eclipsed|327|R|{2}{G}|Creature - Shapeshifter|1|1|Changeling$When this creature enters, create a tapped Mutavault token.| Ashling's Command|Lorwyn Eclipsed|330|R|{3}{U}{R}|Kindred Instant - Elemental|||Choose two --$* Create a token that's a copy of target Elemental you control.$* Target player draws two cards.$* Ashling's Command deals 2 damage to each creature target player controls.$* Target player creates two Treasure tokens.| Hallowed Fountain|Lorwyn Eclipsed|347|R||Land - Plains Island|||({T}: Add {W} or {U}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| +Hallowed Fountain|Lorwyn Eclipsed|347b|R||Land - Plains Island|||({T}: Add {W} or {U}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Steam Vents|Lorwyn Eclipsed|348|R||Land - Island Mountain|||({T}: Add {U} or {R}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| +Steam Vents|Lorwyn Eclipsed|348b|R||Land - Island Mountain|||({T}: Add {U} or {R}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Blood Crypt|Lorwyn Eclipsed|349|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| +Blood Crypt|Lorwyn Eclipsed|349b|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Overgrown Tomb|Lorwyn Eclipsed|350|R||Land - Swamp Forest|||({T}: Add {B} or {G}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| +Overgrown Tomb|Lorwyn Eclipsed|350b|R||Land - Swamp Forest|||({T}: Add {B} or {G}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Temple Garden|Lorwyn Eclipsed|351|R||Land - Forest Plains|||({T}: Add {G} or {W}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| +Temple Garden|Lorwyn Eclipsed|351b|R||Land - Forest Plains|||({T}: Add {G} or {W}.)$As this land enters, you may pay 2 life. If you don't, it enters tapped.| Bitterbloom Bearer|Lorwyn Eclipsed|352|M|{B}{B}|Creature - Faerie Rogue|1|1|Flash$Flying$At the beginning of your upkeep, you lose 1 life and create a 1/1 blue and black Faerie creature token with flying.| Formidable Speaker|Lorwyn Eclipsed|366|R|{2}{G}|Creature - Elf Druid|2|4|When this creature enters, you may discard a card. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle.${1}, {T}: Untap another target permanent.| Figure of Fable|Lorwyn Eclipsed|372|R|{G/W}|Creature - Kithkin|1|1|{G/W}: This creature becomes a Kithkin Scout with base power and toughness 2/3.${1}{G/W}{G/W}: If this creature is a Scout, it becomes a Kithkin Soldier with base power and toughness 4/5.${3}{G/W}{G/W}{G/W}: If this creature is a Soldier, it becomes a Kithkin Avatar with base power and toughness 7/8 and protection from each of your opponents.| +High Perfect Morcant|Lorwyn Eclipsed|373|R|{2}{B}{G}|Legendary Creature - Elf Noble|4|4|Whenever High Perfect Morcant or another Elf you control enters, each opponent blights 1.$Tap three untapped Elves you control: Proliferate. Activate only as a sorcery.| +Kirol, Attentive First-Year|Lorwyn Eclipsed|374|R|{1}{R/W}{R/W}|Legendary Creature - Vampire Cleric|3|3|Tap two untapped creatures you control: Copy target triggered ability you control. You may choose new targets for the copy. Activate only once each turn.| Greymond, Avacyn's Stalwart|Secret Lair Drop|143|M|{2}{W}{W}|Legendary Creature - Human Soldier|3|4|As Greymond, Avacyn's Stalwart enters, choose two abilities from among first strike, vigilance, and lifelink.$Humans you control have each of the chosen abilities.$As long as you control four or more Humans, Humans you control get +2/+2.| Hansk, Slayer Zealot|Secret Lair Drop|144|M|{2}{R}{G}|Legendary Creature - Human Archer|4|4|At the beginning of your upkeep, target opponent creates three Walker tokens.${T}: Hansk, Slayer Zealot deals 2 damage to target creature.$Whenever a Zombie an opponent controls dies, draw a card.| Gregor, Shrewd Magistrate|Secret Lair Drop|145|M|{1}{W}{U}|Legendary Creature - Human Advisor|1|3|Skulk$Whenever Gregor, Shrewd Magistrate deals combat damage to a player, draw cards equal to its power.| @@ -60930,3 +60969,29 @@ Donnie & April, Adorkable Duo|Teenage Mutant Ninja Turtles Eternal|111|R|{4}{U}| Raphael, Tag Team Tough|Teenage Mutant Ninja Turtles Eternal|118|M|{4}{R}{R}|Legendary Creature - Mutant Ninja Turtle|5|6|Menace$Whenever Raphael deals combat damage to a player for the first time each turn, untap all attacking creatures. After this combat phase, there is an additional combat phase.| Michelangelo, On the Scene|Teenage Mutant Ninja Turtles Eternal|124|M|{4}{G}{G}|Legendary Creature - Mutant Ninja Turtle|2|2|Trample$Michelangelo enters with a +1/+1 counter on him for each land you control.$When Michelangelo dies, return this card to your hand.| Dark Ritual|Teenage Mutant Ninja Turtles Eternal|131|M|{B}|Instant|||Add {B}{B}{B}.| +Captain America, Super-Soldier|Marvel Super Heroes|9|M|{1}{W}{W}|Legendary Creature - Human Soldier Hero|3|2|First strike$Captain America enters with a shield counter on him.$As long as Captain America has a shield counter on him, you and other Heroes you control have hexproof.| +The Sentry, Golden Guardian|Marvel Super Heroes|35|R|{3}{W}|Legendary Creature - Human Hero|5|5|Flying, vigilance, indestructible$When The Sentry enters, target opponent creates The Void, a legendary 5/5 black Horror Villain creature token with flying, indestructible, and "The Void attacks each combat if able."| +Attuma, Atlantean Warlord|Marvel Super Heroes|47|U|{2}{U}{U}|Legendary Creature - Merfolk Warrior Villain|3|4|Other Merfolk you control get +1/+1.$Whenever one or more Merfolk you control attack a player, draw a card.| +Bruce Banner|Marvel Super Heroes|49|M|{U}|Legendary Creature - Human Scientist Hero|1|1|{X}{X}, {T}: Draw X cards. Activate only as a sorcery.${2}{R}{R}{G}{G}: Transform Bruce Banner. Activate only as a sorcery.| +The Incredible Hulk|Marvel Super Heroes|49|M|{2}{R}{R}{G}{G}|1/1 Creature|8|8|Reach, trample$Enrage -- Whenever The Incredible Hulk is dealt damage, put a +1/+1 counter on him. If he's attacking, untap him and there is an additional combat phase after this phase.| +Namor the Sub-Mariner|Marvel Super Heroes|69|M|{1}{U}{U}|Legendary Creature - Mutant Merfolk Villain|*|4|Flying$Namor's power is equal to the number of Merfolk you control.$Whenever you cast a noncreature spell with one or more blue mana symbols in its mana cost, create that many 1/1 blue Merfolk creature tokens.| +Baron Helmut Zemo|Marvel Super Heroes|87|R|{B}{B}{B}|Legendary Creature - Human Noble Villain|3|3|Whenever you cast a black spell from your hand, Baron Helmut Zemo connives.$Boast -- Exile any number of black cards from your graveyard with fifteen or more black mana symbols among their mana costs: Copy those exiled cards. You may cast up to three of the copies without paying their mana costs.| +Doctor Doom|Marvel Super Heroes|95|M|{4}{B}{B}|Legendary Creature - Human Scientist Villain|3|3|When Doctor Doom enters, create two 3/3 colorless Robot Villain artifact creature tokens named Doombot.$As long as you control an artifact creature or a Plan, Doctor Doom has indestructible.$At the beginning of your end step, you draw a card and lose 1 life.| +Doom Reigns Supreme|Marvel Super Heroes|96|R|{1}{B}|Enchantment - Plan|||Whenever a Villain you control enters, each opponent loses 1 life and you gain 1 life. Put a plan counter on this enchantment.$When the fifth plan counter is put on this enchantment, sacrifice it. When you do, target opponent exiles the top five cards of their library. You may cast up to two spells from among the exiled cards without paying their mana costs.| +Super-Skrull|Marvel Super Heroes|115|R|{1}{B}{B}{B}|Legendary Creature - Skrull Shapeshifter Villain|4|5|Flying${2}{W}: Create a 0/4 colorless Wall creature token with defender.${3}{G}: Super-Skrull gets +4/+4 until end of turn.${4}{R}: Super-Skrull deals 4 damage to target creature.${5}{U}: Target player draws four cards.| +Thunderbolts Conspiracy|Marvel Super Heroes|117|R|{3}{B}|Enchantment|||Flash$Whenever a Villain you control dies, return it to the battlefield under its owner's control with a finality counter on it. That creature is a Hero in addition to its other types.| +Quicksilver, Brash Blur|Marvel Super Heroes|148|R|{R}|Legendary Creature - Mutant Hero|1|1|If Quicksilver, Brash Blur is in your opening hand, you may begin the game with him on the battlefield.$Haste$Power-up -- {4}{R}: Put a +1/+1 counter and a double strike counter on Quicksilver.| +World War Hulk|Marvel Super Heroes|197|R|{3}{G}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- The next red or green creature spell you cast this turn can be cast without paying its mana cost.$II -- Put three +1/+1 counters on target creature you control.$III -- Choose target creature you control. Until end of turn, double its power and toughness and it gains trample.| +The Coming of Galactus|Marvel Super Heroes|212|M|{2}{B}{B}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.)$I -- Destroy up to one target nonland permanent.$II, III -- Each opponent loses 2 life.$IV -- Create Galactus, a legendary 16/16 black Elder alien creature token with flying, trample, and "Whenever Galactus attacks, destroy target land."| +Moon Girl and Devil Dinosaur|Marvel Super Heroes|223|R|{1}{G}{U}|Legendary Creature - Human Dinosaur Hero|2|2|Whenever you draw your second card each turn, until end of turn, Moon Girl and Devil Dinosaur's base power and toughness become 6/6 and they gain trample.$Whenever an artifact you control enters, draw a card. This ability triggers only once each turn.| +World War Hulk|Marvel Super Heroes|304|R|{3}{G}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- The next red or green creature spell you cast this turn can be cast without paying its mana cost.$II -- Put three +1/+1 counters on target creature you control.$III -- Choose target creature you control. Until end of turn, double its power and toughness and it gains trample.| +The Coming of Galactus|Marvel Super Heroes|307|M|{2}{B}{B}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.)$I -- Destroy up to one target nonland permanent.$II, III -- Each opponent loses 2 life.$IV -- Create Galactus, a legendary 16/16 black Elder alien creature token with flying, trample, and "Whenever Galactus attacks, destroy target land."| +Captain America, Super-Soldier|Marvel Super Heroes|387|M|{1}{W}{W}|Legendary Creature - Human Soldier Hero|3|2|First strike$Captain America enters with a shield counter on him.$As long as Captain America has a shield counter on him, you and other Heroes you control have hexproof.| +Bruce Banner|Marvel Super Heroes|390|M|{U}|Legendary Creature - Human Scientist Hero|1|1|{X}{X}, {T}: Draw X cards. Activate only as a sorcery.${2}{R}{R}{G}{G}: Transform Bruce Banner. Activate only as a sorcery.| +The Incredible Hulk|Marvel Super Heroes|390|M|{2}{R}{R}{G}{G}|1/1 Creature|8|8|Reach, trample$Enrage -- Whenever The Incredible Hulk is dealt damage, put a +1/+1 counter on him. If he's attacking, untap him and there is an additional combat phase after this phase.| +Namor the Sub-Mariner|Marvel Super Heroes|391|M|{1}{U}{U}|Legendary Creature - Mutant Merfolk Villain|*|4|Flying$Namor's power is equal to the number of Merfolk you control.$Whenever you cast a noncreature spell with one or more blue mana symbols in its mana cost, create that many 1/1 blue Merfolk creature tokens.| +Doctor Doom|Marvel Super Heroes|394|M|{4}{B}{B}|Legendary Creature - Human Scientist Villain|3|3|When Doctor Doom enters, create two 3/3 colorless Robot Villain artifact creature tokens named Doombot.$As long as you control an artifact creature or a Plan, Doctor Doom has indestructible.$At the beginning of your end step, you draw a card and lose 1 life.| +Invisible Woman|Marvel Super Heroes Commander|1|M|{2}{W}|Legendary Creature - Human Hero|3|3|At the beginning of combat on your turn, if you've cast a noncreature spell this turn, create a 0/3 colorless Wall creature token with defender and reach.$Whenever you attack, you may pay {R}{G}{W}{U}. When you do, target creature gets +1/+0 until end of turn for each creature you control and can't be blocked this turn.| +Mister Fantastic|Marvel Super Heroes Commander|2|M|{2}{U}|Legendary Creature - Human Scientist Hero|2|4|Vigilance, reach$At the beginning of combat on your turn, if you've cast a noncreature spell this turn, draw a card.${R}{G}{W}{U}, {T}: Copy target triggered ability you control twice. You may choose new targets for the copies.| +Human Torch|Marvel Super Heroes Commander|3|M|{3}{R}|Legendary Creature - Human Hero|3|2|At the beginning of combat on your turn, if you've cast a noncreature spell this turn, Human Torch gains flying, double strike, and haste until end of turn.$Whenever Human Torch attacks, you may pay {R}{G}{W}{U}. If you do, until end of turn, whenever he deals combat damage to an opponent, he deals that much damage to each other opponent.| +The Thing|Marvel Super Heroes Commander|4|M|{5}{G}|Legendary Creature - Human Hero|5|5|Trample$At the beginning of combat on your turn, if you've cast a noncreature spell this turn, put four +1/+1 counters on The Thing.$Whenever The Thing attacks, you may pay {R}{G}{W}{U}. When you do, double the number of each kind of counter on any number of target permanents you control.| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index ba5e1cb23de..7f142477ea4 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -178,6 +178,8 @@ Masters 25|A25| Magic: The Gathering-Commander|CMD| Magic: The Gathering-Conspiracy|CNS| Media Inserts|MBP| +Marvel Super Heroes|MSH| +Marvel Super Heroes Commander|MSC| Marvel's Spider-Man|SPM| Marvel's Spider-Man Eternal|SPE| March of the Machine|MOM|