diff --git a/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java b/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java index 4bd3166cbe9..59ad366a3f5 100644 --- a/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java +++ b/Mage.Client/src/main/java/mage/client/components/tray/MageTray.java @@ -79,13 +79,15 @@ public enum MageTray { } catch (AWTException e) { log.error("TrayIcon could not be added: ", e); } - } catch (Exception e) { log.error(e); } } public synchronized void blink() { + if (trayIcon == null) + return; + if (state == 0) { synchronized (MageTray.class) { if (state == 0) { 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..d3e12a40808 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 @@ -616,8 +616,11 @@ public class ScryfallImageSupportCards { add("TLA"); // Avatar: The Last Airbender add("TLE"); // Avatar: The Last Airbender Eternal add("ECL"); // Lorwyn Eclipsed + add("ECC"); // Lorwyn Eclipsed Commander 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.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java index 7c3e4b0a507..0362852cb5b 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportTokens.java @@ -2889,12 +2889,12 @@ public class ScryfallImageSupportTokens { put("REX/Treasure", "https://api.scryfall.com/cards/trex/2?format=image"); // UGL - put("UGL/Goblin", "https://api.scryfall.com/cards/tugl/4?format=image"); - put("UGL/Pegasus", "https://api.scryfall.com/cards/tugl/1?format=image"); - put("UGL/Rabid Sheep", "https://api.scryfall.com/cards/tugl/5?format=image"); - put("UGL/Soldier", "https://api.scryfall.com/cards/tugl/2?format=image"); - put("UGL/Squirrel", "https://api.scryfall.com/cards/tugl/6?format=image"); - put("UGL/Zombie", "https://api.scryfall.com/cards/tugl/3?format=image"); + put("UGL/Goblin", "https://api.scryfall.com/cards/tugl/92?format=image"); + put("UGL/Pegasus", "https://api.scryfall.com/cards/tugl/89?format=image"); + put("UGL/Rabid Sheep", "https://api.scryfall.com/cards/tugl/93?format=image"); + put("UGL/Soldier", "https://api.scryfall.com/cards/tugl/90?format=image"); + put("UGL/Squirrel", "https://api.scryfall.com/cards/tugl/94?format=image"); + put("UGL/Zombie", "https://api.scryfall.com/cards/tugl/91?format=image"); // UST put("UST/Angel", "https://api.scryfall.com/cards/tust/1?format=image"); diff --git a/Mage.Sets/src/mage/cards/a/AbigaleEloquentFirstYear.java b/Mage.Sets/src/mage/cards/a/AbigaleEloquentFirstYear.java new file mode 100644 index 00000000000..d7fc71f1e19 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AbigaleEloquentFirstYear.java @@ -0,0 +1,67 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AbigaleEloquentFirstYear extends CardImpl { + + public AbigaleEloquentFirstYear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W/B}{W/B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.BIRD); + this.subtype.add(SubType.BARD); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When Abigale enters, up to one other target creature loses all abilities. Put a flying counter, a first strike counter, and a lifelink counter on that creature. + Ability ability = new EntersBattlefieldTriggeredAbility(new LoseAllAbilitiesTargetEffect(Duration.Custom) + .setText("up to one other target creature loses all abilities")); + ability.addEffect(new AddCountersTargetEffect(CounterType.FLYING.createInstance()) + .setText("Put a flying counter")); + ability.addEffect(new AddCountersTargetEffect(CounterType.FIRST_STRIKE.createInstance()) + .setText(", a first strike counter")); + ability.addEffect(new AddCountersTargetEffect(CounterType.FLYING.createInstance()) + .setText(", and a lifelink counter on that creature")); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); + this.addAbility(ability); + } + + private AbigaleEloquentFirstYear(final AbigaleEloquentFirstYear card) { + super(card); + } + + @Override + public AbigaleEloquentFirstYear copy() { + return new AbigaleEloquentFirstYear(this); + } +} 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/AbundantCountryside.java b/Mage.Sets/src/mage/cards/a/AbundantCountryside.java new file mode 100644 index 00000000000..8ec80737abe --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AbundantCountryside.java @@ -0,0 +1,65 @@ +package mage.cards.a; + +import java.util.UUID; + +import mage.ConditionalMana; +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.CreateTokenEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.abilities.mana.conditional.CreatureCastConditionalMana; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.HumanToken; +import mage.game.permanent.token.ShapeshifterColorlessToken; + +/** + * + * @author muz + */ +public final class AbundantCountryside extends CardImpl { + + public AbundantCountryside(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // {T}: Add {C}. + this.addAbility(new ColorlessManaAbility()); + + // {T}: Add one mana of any color. Spend this mana only to cast a creature spell. + this.addAbility(new ConditionalAnyColorManaAbility(1, new AbundantCountrysideManaBuilder())); + + // {6}, {T}: Create a 1/1 colorless Shapeshifter creature token with changeling. + Ability ability = new SimpleActivatedAbility( + new CreateTokenEffect(new ShapeshifterColorlessToken()), new ManaCostsImpl<>("{6}") + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + } + + private AbundantCountryside(final AbundantCountryside card) { + super(card); + } + + @Override + public AbundantCountryside copy() { + return new AbundantCountryside(this); + } +} + +class AbundantCountrysideManaBuilder extends ConditionalManaBuilder { + @Override + public ConditionalMana build(Object... options) { + return new CreatureCastConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to cast a creature spell"; + } +} diff --git a/Mage.Sets/src/mage/cards/a/AdantoTheFirstFort.java b/Mage.Sets/src/mage/cards/a/AdantoTheFirstFort.java deleted file mode 100644 index 287da954970..00000000000 --- a/Mage.Sets/src/mage/cards/a/AdantoTheFirstFort.java +++ /dev/null @@ -1,48 +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.CreateTokenEffect; -import mage.abilities.mana.WhiteManaAbility; -import mage.constants.SuperType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.game.permanent.token.IxalanVampireToken; - -/** - * - * @author TheElk801 - */ -public final class AdantoTheFirstFort extends CardImpl { - - public AdantoTheFirstFort(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - this.nightCard = true; - - // T: Add W. - this.addAbility(new WhiteManaAbility()); - - // 2W, T: Create a 1/1 white Vampire creature token with lifelink. - Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new IxalanVampireToken()), new ManaCostsImpl<>("{2}{W}")); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private AdantoTheFirstFort(final AdantoTheFirstFort card) { - super(card); - } - - @Override - public AdantoTheFirstFort copy() { - return new AdantoTheFirstFort(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AetherwingGoldenScaleFlagship.java b/Mage.Sets/src/mage/cards/a/AetherwingGoldenScaleFlagship.java deleted file mode 100644 index 2edb57f2800..00000000000 --- a/Mage.Sets/src/mage/cards/a/AetherwingGoldenScaleFlagship.java +++ /dev/null @@ -1,53 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; -import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; -import mage.abilities.keyword.CrewAbility; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AetherwingGoldenScaleFlagship extends CardImpl { - - public AetherwingGoldenScaleFlagship(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(0); - this.toughness = new MageInt(4); - this.color.setBlue(true); - this.color.setRed(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Aetherwing, Golden-Scale Flagship's power is equal to the number of artifacts you control. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, - new SetBasePowerSourceEffect(ArtifactYouControlCount.instance) - .setText("{this}'s power is equal to the number of artifacts you control") - )); - - // Crew 1 - this.addAbility(new CrewAbility(1)); - } - - private AetherwingGoldenScaleFlagship(final AetherwingGoldenScaleFlagship card) { - super(card); - } - - @Override - public AetherwingGoldenScaleFlagship copy() { - return new AetherwingGoldenScaleFlagship(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/AmbitiousFarmhand.java b/Mage.Sets/src/mage/cards/a/AmbitiousFarmhand.java new file mode 100644 index 00000000000..761eda04c28 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AmbitiousFarmhand.java @@ -0,0 +1,59 @@ +package mage.cards.a; + +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.CovenCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.hint.common.CovenHint; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AmbitiousFarmhand extends TransformingDoubleFacedCard { + + public AmbitiousFarmhand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.PEASANT}, "{1}{W}", + "Seasoned Cathar", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.KNIGHT}, "W"); + + // Ambitious Farmhand + this.getLeftHalfCard().setPT(1, 1); + + // When Ambitious Farmhand enters the battlefield, you may search your library for a basic Plains card, reveal it, put it into your hand, then shuffle. + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_PLAINS), true), true + )); + + // Coven—{1}{W}{W}: Transform Ambitious Farmhand. Activate only if you control three or more creatures with different powers. + this.getLeftHalfCard().addAbility(new ActivateIfConditionActivatedAbility( + new TransformSourceEffect(), new ManaCostsImpl<>("{1}{W}{W}"), CovenCondition.instance + ).setAbilityWord(AbilityWord.COVEN).addHint(CovenHint.instance)); + + // Seasoned Cathar + this.getRightHalfCard().setPT(3, 3); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + } + + private AmbitiousFarmhand(final AmbitiousFarmhand card) { + super(card); + } + + @Override + public AmbitiousFarmhand copy() { + return new AmbitiousFarmhand(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AncestorsEmbrace.java b/Mage.Sets/src/mage/cards/a/AncestorsEmbrace.java deleted file mode 100644 index ce046048700..00000000000 --- a/Mage.Sets/src/mage/cards/a/AncestorsEmbrace.java +++ /dev/null @@ -1,52 +0,0 @@ -package mage.cards.a; - -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.EnchantAbility; -import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AncestorsEmbrace extends CardImpl { - - public AncestorsEmbrace(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 lifelink. - this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( - LifelinkAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield - ))); - - // If Ancestor's Embrace would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private AncestorsEmbrace(final AncestorsEmbrace card) { - super(card); - } - - @Override - public AncestorsEmbrace copy() { - return new AncestorsEmbrace(this); - } -} 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/AppealToEirdu.java b/Mage.Sets/src/mage/cards/a/AppealToEirdu.java new file mode 100644 index 00000000000..20ab0669f85 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AppealToEirdu.java @@ -0,0 +1,36 @@ +package mage.cards.a; + +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AppealToEirdu extends CardImpl { + + public AppealToEirdu(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}"); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // One or two target creatures each get +2/+1 until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect(2, 1)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(1, 2)); + } + + private AppealToEirdu(final AppealToEirdu card) { + super(card); + } + + @Override + public AppealToEirdu copy() { + return new AppealToEirdu(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AquitectsDefenses.java b/Mage.Sets/src/mage/cards/a/AquitectsDefenses.java new file mode 100644 index 00000000000..6f64400f2ef --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AquitectsDefenses.java @@ -0,0 +1,55 @@ +package mage.cards.a; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AquitectsDefenses extends CardImpl { + + public AquitectsDefenses(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + + this.subtype.add(SubType.AURA); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.addAbility(new EnchantAbility(auraTarget)); + + // When this Aura enters, enchanted creature gains hexproof until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new GainAbilityAttachedEffect( + HexproofAbility.getInstance(), AttachmentType.AURA, Duration.EndOfTurn + ))); + + // Enchanted creature gets +1/+2. + this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(1, 2))); + } + + private AquitectsDefenses(final AquitectsDefenses card) { + super(card); + } + + @Override + public AquitectsDefenses copy() { + return new AquitectsDefenses(this); + } +} diff --git a/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java b/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java deleted file mode 100644 index 6698dcde482..00000000000 --- a/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.common.DamageControllerEffect; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.TapSourceEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.common.FilterControlledPermanent; - -import java.util.UUID; - -/** - * @author anonymous - */ -public final class ArchdemonOfGreed extends CardImpl { - - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.HUMAN, "Human"); - - public ArchdemonOfGreed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.DEMON); - this.color.setBlack(true); - - this.nightCard = true; - - this.power = new MageInt(9); - this.toughness = new MageInt(9); - - this.addAbility(FlyingAbility.getInstance()); - this.addAbility(TrampleAbility.getInstance()); - - // At the beginning of your upkeep, sacrifice a Human. If you can't, tap Archdemon of Greed and it deals 9 damage to you. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid( - null, new TapSourceEffect(), new SacrificeTargetCost(filter), false - ).addOtherwiseEffect(new DamageControllerEffect(9)) - .setText("sacrifice a Human. If you can't, tap {this} and it deals 9 damage to you"))); - } - - private ArchdemonOfGreed(final ArchdemonOfGreed card) { - super(card); - } - - @Override - public ArchdemonOfGreed copy() { - return new ArchdemonOfGreed(this); - } -} 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/ArchiveHaunt.java b/Mage.Sets/src/mage/cards/a/ArchiveHaunt.java deleted file mode 100644 index b4fac23a008..00000000000 --- a/Mage.Sets/src/mage/cards/a/ArchiveHaunt.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.DrawDiscardControllerEffect; -import mage.abilities.keyword.DisturbAbility; -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 ArchiveHaunt extends CardImpl { - - public ArchiveHaunt(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever Archive Haunt attacks, draw a card, then discard a card. - this.addAbility(new AttacksTriggeredAbility(new DrawDiscardControllerEffect(1, 1))); - - // If Archive Haunt would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private ArchiveHaunt(final ArchiveHaunt card) { - super(card); - } - - @Override - public ArchiveHaunt copy() { - return new ArchiveHaunt(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AshenReaper.java b/Mage.Sets/src/mage/cards/a/AshenReaper.java deleted file mode 100644 index 42bf48228ce..00000000000 --- a/Mage.Sets/src/mage/cards/a/AshenReaper.java +++ /dev/null @@ -1,88 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.WatcherScope; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; -import mage.watchers.Watcher; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AshenReaper extends CardImpl { - - public AshenReaper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ZOMBIE); - this.subtype.add(SubType.ELEMENTAL); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.color.setBlack(true); - this.color.setRed(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility(false)); - - // At the beginning of your end step, put a +1/+1 counter on Ashen Reaper if a permanent was put into a graveyard from the battlefield this turn. - this.addAbility(new BeginningOfEndStepTriggeredAbility( - new ConditionalOneShotEffect( - new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - AshenReaperCondition.instance, "put a +1/+1 counter on {this} " + - "if a permanent was put into a graveyard from the battlefield this turn" - ) - )); - } - - private AshenReaper(final AshenReaper card) { - super(card); - } - - @Override - public AshenReaper copy() { - return new AshenReaper(this); - } - - public static AshenReaperWatcher makeWatcher() { - return new AshenReaperWatcher(); - } -} - -enum AshenReaperCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return game.getState().getWatcher(AshenReaperWatcher.class).conditionMet(); - } -} - -class AshenReaperWatcher extends Watcher { - - AshenReaperWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE - && ((ZoneChangeEvent) event).isDiesEvent()) { - condition = true; - } - } -} 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/AshmouthBlade.java b/Mage.Sets/src/mage/cards/a/AshmouthBlade.java deleted file mode 100644 index 4fe8866988e..00000000000 --- a/Mage.Sets/src/mage/cards/a/AshmouthBlade.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.a; - -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.EquipAbility; -import mage.abilities.keyword.FirstStrikeAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class AshmouthBlade extends CardImpl { - - public AshmouthBlade(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - this.subtype.add(SubType.EQUIPMENT); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Equipped creature gets +3/+3 and has first strike. - Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 3)); - ability.addEffect(new GainAbilityAttachedEffect( - FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT - ).setText("and has first strike")); - this.addAbility(ability); - - // Equip {3} - this.addAbility(new EquipAbility(3, false)); - } - - private AshmouthBlade(final AshmouthBlade card) { - super(card); - } - - @Override - public AshmouthBlade copy() { - return new AshmouthBlade(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/AssertPerfection.java b/Mage.Sets/src/mage/cards/a/AssertPerfection.java new file mode 100644 index 00000000000..8077282c844 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AssertPerfection.java @@ -0,0 +1,36 @@ +package mage.cards.a; + +import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AssertPerfection extends CardImpl { + + public AssertPerfection(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); + + // Target creature you control gets +1/+0 until end of turn. It deals damage equal to its power to up to one target creature an opponent controls. + this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0)); + this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect("it")); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent()); + } + + private AssertPerfection(final AssertPerfection card) { + super(card); + } + + @Override + public AssertPerfection copy() { + return new AssertPerfection(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/AtzalCaveOfEternity.java b/Mage.Sets/src/mage/cards/a/AtzalCaveOfEternity.java deleted file mode 100644 index 73362456eba..00000000000 --- a/Mage.Sets/src/mage/cards/a/AtzalCaveOfEternity.java +++ /dev/null @@ -1,51 +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.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; -import mage.constants.Zone; -import mage.filter.StaticFilters; -import mage.target.common.TargetCardInYourGraveyard; - -/** - * - * @author LevelX2 - */ -public final class AtzalCaveOfEternity extends CardImpl { - - public AtzalCaveOfEternity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - this.nightCard = true; - - // (Transforms from Journey to Eternity.) - - // {t}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); - - // {3}{B}{G}, {T}: Return target creature card from your graveyard to the battlefield. - Ability ability = new SimpleActivatedAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl<>("{3}{B}{G}")); - ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); - this.addAbility(ability); - } - - private AtzalCaveOfEternity(final AtzalCaveOfEternity card) { - super(card); - } - - @Override - public AtzalCaveOfEternity copy() { - return new AtzalCaveOfEternity(this); - } -} diff --git a/Mage.Sets/src/mage/cards/a/AuntieOolCursewretch.java b/Mage.Sets/src/mage/cards/a/AuntieOolCursewretch.java new file mode 100644 index 00000000000..abfa1d6f50c --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AuntieOolCursewretch.java @@ -0,0 +1,115 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.WardAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.game.Controllable; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AuntieOolCursewretch extends CardImpl { + + public AuntieOolCursewretch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Ward--Blight 2. + this.addAbility(new WardAbility(new BlightCost(2))); + + // Whenever one or more -1/-1 counters are put on a creature, draw a card if you control that creature. If you don't control it, its controller loses 1 life. + this.addAbility(new AuntieOolCursewretchTriggeredAbility()); + } + + private AuntieOolCursewretch(final AuntieOolCursewretch card) { + super(card); + } + + @Override + public AuntieOolCursewretch copy() { + return new AuntieOolCursewretch(this); + } +} + +class AuntieOolCursewretchTriggeredAbility extends TriggeredAbilityImpl { + + AuntieOolCursewretchTriggeredAbility() { + super(Zone.BATTLEFIELD, new AuntieOolCursewretchEffect()); + setTriggerPhrase("Whenever one or more -1/-1 counters are put on a creature, "); + } + + private AuntieOolCursewretchTriggeredAbility(final AuntieOolCursewretchTriggeredAbility ability) { + super(ability); + } + + @Override + public AuntieOolCursewretchTriggeredAbility copy() { + return new AuntieOolCursewretchTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.COUNTERS_ADDED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (permanent == null + || !permanent.isCreature(game) + || !event.getData().equals(CounterType.M1M1.getName()) + || event.getAmount() < 1) { + return false; + } + this.getEffects().setValue("creature", permanent); + return true; + } +} + +class AuntieOolCursewretchEffect extends OneShotEffect { + + AuntieOolCursewretchEffect() { + super(Outcome.Benefit); + staticText = "draw a card if you control that creature. If you don't control it, its controller loses 1 life"; + } + + private AuntieOolCursewretchEffect(final AuntieOolCursewretchEffect effect) { + super(effect); + } + + @Override + public AuntieOolCursewretchEffect copy() { + return new AuntieOolCursewretchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return Optional + .ofNullable((Permanent) getValue("creature")) + .map(Controllable::getControllerId) + .map(game::getPlayer) + .map(player -> source.isControlledBy(player.getId()) + ? player.drawCards(1, source, game) + : player.loseLife(1, game, source, false)) + .filter(x -> x > 0) + .isPresent(); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AuroraAwakener.java b/Mage.Sets/src/mage/cards/a/AuroraAwakener.java new file mode 100644 index 00000000000..333d1ac4d01 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AuroraAwakener.java @@ -0,0 +1,92 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.*; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class AuroraAwakener extends CardImpl { + + public AuroraAwakener(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}"); + + this.subtype.add(SubType.GIANT); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Vivid -- When this creature enters, reveal cards from the top of your library until you reveal X permanent cards, where X is the number of colors among permanents you control. Put any number of those permanent cards onto the battlefield, then put the rest of the revealed cards on the bottom of your library in a random order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new AuroraAwakenerEffect()) + .setAbilityWord(AbilityWord.VIVID) + .addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private AuroraAwakener(final AuroraAwakener card) { + super(card); + } + + @Override + public AuroraAwakener copy() { + return new AuroraAwakener(this); + } +} + +class AuroraAwakenerEffect extends OneShotEffect { + + AuroraAwakenerEffect() { + super(Outcome.Benefit); + staticText = "reveal cards from the top of your library until you reveal X permanent cards, " + + "where X is the number of colors among permanents you control. " + + "Put any number of those permanent cards onto the battlefield, " + + "then put the rest of the revealed cards on the bottom of your library in a random order"; + } + + private AuroraAwakenerEffect(final AuroraAwakenerEffect effect) { + super(effect); + } + + @Override + public AuroraAwakenerEffect copy() { + return new AuroraAwakenerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + int count = ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.calculate(game, source, this); + if (player == null || count < 1) { + return false; + } + Cards cards = new CardsImpl(); + for (Card card : player.getLibrary().getCards(game)) { + cards.add(card); + if (cards.count(StaticFilters.FILTER_CARD_PERMANENT, game) >= count) { + break; + } + } + player.revealCards(source, cards, game); + TargetCard target = new TargetCardInLibrary(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_PERMANENTS); + player.choose(outcome, cards, target, source, game); + player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); + cards.retainZone(Zone.LIBRARY, game); + player.putCardsOnBottomOfLibrary(cards, game, source, false); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/a/AvatarAang.java b/Mage.Sets/src/mage/cards/a/AvatarAang.java index 71ddf626fc6..060ca7115a9 100644 --- a/Mage.Sets/src/mage/cards/a/AvatarAang.java +++ b/Mage.Sets/src/mage/cards/a/AvatarAang.java @@ -170,14 +170,14 @@ class AvatarAangWatcher extends Watcher { earthSet.clear(); airSet.clear(); fireSet.clear(); - earthSet.clear(); + waterSet.clear(); } private boolean checkPlayer(UUID playerId) { return earthSet.contains(playerId) && airSet.contains(playerId) && fireSet.contains(playerId) - && earthSet.contains(playerId); + && waterSet.contains(playerId); } static boolean checkPlayer(Game game, Ability source) { 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/AwakenTheMaelstrom.java b/Mage.Sets/src/mage/cards/a/AwakenTheMaelstrom.java deleted file mode 100644 index 3ff192f04d9..00000000000 --- a/Mage.Sets/src/mage/cards/a/AwakenTheMaelstrom.java +++ /dev/null @@ -1,128 +0,0 @@ -package mage.cards.a; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.*; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -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.TargetPlayer; -import mage.target.common.TargetControlledPermanent; -import mage.target.common.TargetCreaturePermanentAmount; -import mage.target.common.TargetPermanentAmount; -import mage.target.targetpointer.SecondTargetPointer; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AwakenTheMaelstrom extends CardImpl { - - public AwakenTheMaelstrom(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); - - this.nightCard = true; - - // Awaken the Maelstrom 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(Zone.ALL, new InfoEffect("{this} is all colors"))); - - // Target player draws two cards. - this.getSpellAbility().addEffect(new DrawCardTargetEffect(2)); - this.getSpellAbility().addTarget(new TargetPlayer().withChooseHint("to draw two cards")); - - // You may put an artifact card from your hand onto the battlefield. - this.getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_ARTIFACT_AN)); - - // Create a token that's a copy of a permanent you control. - // Distribute three +1/+1 counters among one, two, or three creatures you control. - this.getSpellAbility().addEffect(new AwakenTheMaelstromEffect()); - - // Destroy target permanent an opponent controls. - this.getSpellAbility().addEffect(new DestroyTargetEffect().setTargetPointer(new SecondTargetPointer())); - this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT).withChooseHint("to destroy")); - } - - private AwakenTheMaelstrom(final AwakenTheMaelstrom card) { - super(card); - } - - @Override - public AwakenTheMaelstrom copy() { - return new AwakenTheMaelstrom(this); - } -} - -class AwakenTheMaelstromEffect extends OneShotEffect { - - AwakenTheMaelstromEffect() { - super(Outcome.Benefit); - staticText = "Create a token that's a copy of a permanent you control. " + - "Distribute three +1/+1 counters among one, two, or three creatures you control."; - } - - private AwakenTheMaelstromEffect(final AwakenTheMaelstromEffect effect) { - super(effect); - } - - @Override - public AwakenTheMaelstromEffect copy() { - return new AwakenTheMaelstromEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - makeToken(player, game, source); - game.processAction(); - distributeCounters(player, game, source); - return true; - } - - private void makeToken(Player player, Game game, Ability source) { - TargetPermanent target = new TargetControlledPermanent(); - target.withNotTarget(true); - target.withChooseHint("to copy"); - if (!target.canChoose(player.getId(), source, game)) { - return; - } - player.choose(outcome, target, source, game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - new CreateTokenCopyTargetEffect().setSavedPermanent(permanent).apply(game, source); - } - } - - private void distributeCounters(Player player, Game game, Ability source) { - if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game) < 1) { - return; - } - TargetPermanentAmount target = new TargetCreaturePermanentAmount(3, StaticFilters.FILTER_CONTROLLED_CREATURE); - target.withNotTarget(true); - target.withChooseHint("to distribute counters"); - target.chooseTarget(outcome, player.getId(), source, game); - for (UUID targetId : target.getTargets()) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(target.getTargetAmount(targetId)), source, game); - } - } - } -} diff --git a/Mage.Sets/src/mage/cards/a/AwakenedSkyclave.java b/Mage.Sets/src/mage/cards/a/AwakenedSkyclave.java deleted file mode 100644 index 48e9a24dee8..00000000000 --- a/Mage.Sets/src/mage/cards/a/AwakenedSkyclave.java +++ /dev/null @@ -1,53 +0,0 @@ -package mage.cards.a; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.AddCardTypeSourceEffect; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.VigilanceAbility; -import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class AwakenedSkyclave extends CardImpl { - - public AwakenedSkyclave(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ELEMENTAL); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setGreen(true); - this.nightCard = true; - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // As long as Awakened Skyclave is on the battlefield, it's a land in addition to its other types. - this.addAbility(new SimpleStaticAbility(new AddCardTypeSourceEffect(Duration.WhileOnBattlefield, CardType.LAND) - .setText("as long as {this} is on the battlefield, it's a land in addition to its other types"))); - - // {T}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); - } - - private AwakenedSkyclave(final AwakenedSkyclave card) { - super(card); - } - - @Override - public AwakenedSkyclave copy() { - return new AwakenedSkyclave(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/BaneOfHanweir.java b/Mage.Sets/src/mage/cards/b/BaneOfHanweir.java deleted file mode 100644 index db8f96ac32a..00000000000 --- a/Mage.Sets/src/mage/cards/b/BaneOfHanweir.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.common.AttacksEachCombatStaticAbility; -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 BaneOfHanweir extends CardImpl { - - public BaneOfHanweir(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(5); - this.toughness = new MageInt(5); - - // Bane of Hanweir attacks each turn if able. - this.addAbility(new AttacksEachCombatStaticAbility()); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Bane of Hanweir. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private BaneOfHanweir(final BaneOfHanweir card) { - super(card); - } - - @Override - public BaneOfHanweir copy() { - return new BaneOfHanweir(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/BelligerentRegisaur.java b/Mage.Sets/src/mage/cards/b/BelligerentRegisaur.java deleted file mode 100644 index 030117c9ab4..00000000000 --- a/Mage.Sets/src/mage/cards/b/BelligerentRegisaur.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.keyword.IndestructibleAbility; -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 java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BelligerentRegisaur extends CardImpl { - - public BelligerentRegisaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.DINOSAUR); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - this.color.setGreen(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Whenever you cast a spell, Belligerent Regisaur gains indestructible until end of turn. - this.addAbility(new SpellCastControllerTriggeredAbility(new GainAbilitySourceEffect( - IndestructibleAbility.getInstance(), Duration.EndOfTurn - ), false)); - } - - private BelligerentRegisaur(final BelligerentRegisaur card) { - super(card); - } - - @Override - public BelligerentRegisaur copy() { - return new BelligerentRegisaur(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/Belonging.java b/Mage.Sets/src/mage/cards/b/Belonging.java new file mode 100644 index 00000000000..14ac82c5669 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Belonging.java @@ -0,0 +1,44 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.EncoreAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.ShapeshifterColorlessToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Belonging extends CardImpl { + + public Belonging(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // When this creature enters, create three 1/1 colorless Shapeshifter creature tokens with changeling. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ShapeshifterColorlessToken(), 3))); + + // Encore {6}{W}{W} + this.addAbility(new EncoreAbility(new ManaCostsImpl<>("{6}{W}{W}"))); + } + + private Belonging(final Belonging card) { + super(card); + } + + @Override + public Belonging copy() { + return new Belonging(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BenevolentGeist.java b/Mage.Sets/src/mage/cards/b/BenevolentGeist.java deleted file mode 100644 index 69c570a5580..00000000000 --- a/Mage.Sets/src/mage/cards/b/BenevolentGeist.java +++ /dev/null @@ -1,52 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.CantBeCounteredControlledEffect; -import mage.abilities.keyword.DisturbAbility; -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 BenevolentGeist extends CardImpl { - - public BenevolentGeist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Noncreature spells you control can't be countered. - this.addAbility(new SimpleStaticAbility(new CantBeCounteredControlledEffect( - StaticFilters.FILTER_SPELLS_NON_CREATURE, Duration.WhileOnBattlefield - ))); - - // If Benevolent Geist would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private BenevolentGeist(final BenevolentGeist card) { - super(card); - } - - @Override - public BenevolentGeist copy() { - return new BenevolentGeist(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BenevolentRiverSpirit.java b/Mage.Sets/src/mage/cards/b/BenevolentRiverSpirit.java index 25038e78824..6a4985504b2 100644 --- a/Mage.Sets/src/mage/cards/b/BenevolentRiverSpirit.java +++ b/Mage.Sets/src/mage/cards/b/BenevolentRiverSpirit.java @@ -2,8 +2,10 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.WaterbendCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.WardAbility; @@ -11,6 +13,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.Zone; import java.util.UUID; @@ -28,6 +31,9 @@ public final class BenevolentRiverSpirit extends CardImpl { // As an additional cost to cast this spell, waterbend {5}. this.getSpellAbility().addCost(new WaterbendCost(5)); + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}") + ).setRuleAtTheTop(true)); // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/b/BileVialBoggart.java b/Mage.Sets/src/mage/cards/b/BileVialBoggart.java new file mode 100644 index 00000000000..95c6fb0fa97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BileVialBoggart.java @@ -0,0 +1,43 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BileVialBoggart extends CardImpl { + + public BileVialBoggart(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When this creature dies, put a -1/-1 counter on up to one target creature. + Ability ability = new DiesSourceTriggeredAbility(new AddCountersTargetEffect(CounterType.M1M1.createInstance())); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.addAbility(ability); + } + + private BileVialBoggart(final BileVialBoggart card) { + super(card); + } + + @Override + public BileVialBoggart copy() { + return new BileVialBoggart(this); + } +} 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/BlightedBlackthorn.java b/Mage.Sets/src/mage/cards/b/BlightedBlackthorn.java new file mode 100644 index 00000000000..c957a51c085 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BlightedBlackthorn.java @@ -0,0 +1,43 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +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 BlightedBlackthorn extends CardImpl { + + public BlightedBlackthorn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.TREEFOLK); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(3); + this.toughness = new MageInt(7); + + // Whenever this creature enters or attacks, you may blight 2. If you do, you draw a card and lose 1 life. + this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1, true), new BlightCost(2) + ).addEffect(new LoseLifeSourceControllerEffect(1).setText("and lose 1 life")))); + } + + private BlightedBlackthorn(final BlightedBlackthorn card) { + super(card); + } + + @Override + public BlightedBlackthorn copy() { + return new BlightedBlackthorn(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/BloodlineBidding.java b/Mage.Sets/src/mage/cards/b/BloodlineBidding.java new file mode 100644 index 00000000000..6038f38b43e --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BloodlineBidding.java @@ -0,0 +1,82 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.choices.Choice; +import mage.choices.ChoiceCreatureType; +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 mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BloodlineBidding extends CardImpl { + + public BloodlineBidding(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{B}{B}"); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // Choose a creature type. Return all creature cards of the chosen type from your graveyard to the battlefield. + this.getSpellAbility().addEffect(new BloodlineBiddingEffect()); + } + + private BloodlineBidding(final BloodlineBidding card) { + super(card); + } + + @Override + public BloodlineBidding copy() { + return new BloodlineBidding(this); + } +} + +class BloodlineBiddingEffect extends OneShotEffect { + + BloodlineBiddingEffect() { + super(Outcome.Benefit); + staticText = "choose a creature type. Return all creature cards " + + "of the chosen type from your graveyard to the battlefield"; + } + + private BloodlineBiddingEffect(final BloodlineBiddingEffect effect) { + super(effect); + } + + @Override + public BloodlineBiddingEffect copy() { + return new BloodlineBiddingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Choice choice = new ChoiceCreatureType(game, source); + player.choose(outcome, choice, game); + SubType subType = SubType.fromString(choice.getChoice()); + if (subType == null) { + return false; + } + game.informPlayers(CardUtil.getSourceLogName(game, source) + ": " + player.getLogName() + " chooses " + subType); + Cards cards = new CardsImpl(player.getGraveyard().getCards(game)); + cards.removeIf(uuid -> !game.getCard(uuid).isCreature(game)); + cards.removeIf(uuid -> !game.getCard(uuid).hasSubtype(subType, game)); + return !cards.isEmpty() && player.moveCards(cards, Zone.BATTLEFIELD, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BloodsoakedReveler.java b/Mage.Sets/src/mage/cards/b/BloodsoakedReveler.java deleted file mode 100644 index 1c5d37419f5..00000000000 --- a/Mage.Sets/src/mage/cards/b/BloodsoakedReveler.java +++ /dev/null @@ -1,64 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.YouGainedLifeCondition; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.LoseLifeOpponentsEffect; -import mage.abilities.hint.ConditionHint; -import mage.abilities.hint.Hint; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; -import mage.game.permanent.token.BloodToken; -import mage.watchers.common.PlayerGainedLifeWatcher; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BloodsoakedReveler extends CardImpl { - - private static final Condition condition = new YouGainedLifeCondition(); - private static final Hint hint = new ConditionHint(condition, "You gained life this turn"); - - public BloodsoakedReveler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // At the beginning of your end step, if you gained life this turn, create a Blood token. - this.addAbility(new BeginningOfEndStepTriggeredAbility( - TargetController.YOU, new CreateTokenEffect(new BloodToken()), - false, condition - ).addHint(hint), new PlayerGainedLifeWatcher()); - - // {4}{B}: Each opponent loses 2 life and you gain 2 life. - Ability ability = new SimpleActivatedAbility( - new LoseLifeOpponentsEffect(2), new ManaCostsImpl<>("{4}{B}") - ); - ability.addEffect(new GainLifeEffect(2).concatBy("and")); - this.addAbility(ability); - } - - private BloodsoakedReveler(final BloodsoakedReveler card) { - super(card); - } - - @Override - public BloodsoakedReveler copy() { - return new BloodsoakedReveler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BloomTender.java b/Mage.Sets/src/mage/cards/b/BloomTender.java index ef4aa4345b1..a98cf4918bd 100644 --- a/Mage.Sets/src/mage/cards/b/BloomTender.java +++ b/Mage.Sets/src/mage/cards/b/BloomTender.java @@ -1,18 +1,11 @@ package mage.cards.b; import mage.MageInt; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.mana.ManaEffect; -import mage.abilities.mana.SimpleManaAbility; +import mage.abilities.mana.AddEachControlledColorManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; import java.util.UUID; @@ -29,8 +22,7 @@ public final class BloomTender extends CardImpl { this.toughness = new MageInt(1); // {T}: For each color among permanents you control, add one mana of that color. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new BloomTenderEffect(), new TapSourceCost())); - + this.addAbility(new AddEachControlledColorManaAbility()); } private BloomTender(final BloomTender card) { @@ -42,46 +34,3 @@ public final class BloomTender extends CardImpl { return new BloomTender(this); } } - -class BloomTenderEffect extends ManaEffect { - - BloomTenderEffect() { - super(); - staticText = "For each color among permanents you control, add one mana of that color"; - } - - private BloomTenderEffect(final BloomTenderEffect effect) { - super(effect); - } - - @Override - public BloomTenderEffect copy() { - return new BloomTenderEffect(this); - } - - @Override - public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); - if (game == null) { - return mana; - } - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) { - if (mana.getBlack() == 0 && permanent.getColor(game).isBlack()) { - mana.increaseBlack(); - } - if (mana.getBlue() == 0 && permanent.getColor(game).isBlue()) { - mana.increaseBlue(); - } - if (mana.getRed() == 0 && permanent.getColor(game).isRed()) { - mana.increaseRed(); - } - if (mana.getGreen() == 0 && permanent.getColor(game).isGreen()) { - mana.increaseGreen(); - } - if (mana.getWhite() == 0 && permanent.getColor(game).isWhite()) { - mana.increaseWhite(); - } - } - return mana; - } -} diff --git a/Mage.Sets/src/mage/cards/b/BloomwielderDryads.java b/Mage.Sets/src/mage/cards/b/BloomwielderDryads.java deleted file mode 100644 index e3782f4aedc..00000000000 --- a/Mage.Sets/src/mage/cards/b/BloomwielderDryads.java +++ /dev/null @@ -1,52 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.WardAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.counters.CounterType; -import mage.target.common.TargetControlledCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BloomwielderDryads extends CardImpl { - - public BloomwielderDryads(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.DRYAD); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.color.setGreen(true); - this.nightCard = true; - - // Ward {2} - this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"))); - - // At the beginning of your end step, put a +1/+1 counter on target creature you control. - Ability ability = new BeginningOfEndStepTriggeredAbility( - new AddCountersTargetEffect(CounterType.P1P1.createInstance()) - ); - ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); - } - - private BloomwielderDryads(final BloomwielderDryads card) { - super(card); - } - - @Override - public BloomwielderDryads copy() { - return new BloomwielderDryads(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/BoggartMischief.java b/Mage.Sets/src/mage/cards/b/BoggartMischief.java new file mode 100644 index 00000000000..f0c414f1ae8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BoggartMischief.java @@ -0,0 +1,52 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.permanent.token.BlackAndRedGoblinToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BoggartMischief extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(SubType.GOBLIN, "a Goblin creature you control"); + + public BoggartMischief(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.ENCHANTMENT}, "{2}{B}"); + + this.subtype.add(SubType.GOBLIN); + + // When this enchantment enters, you may blight 1. If you do, create two 1/1 black and red Goblin creature tokens. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DoIfCostPaid(new CreateTokenEffect(new BlackAndRedGoblinToken()), new BlightCost(1)) + )); + + // Whenever a Goblin creature you control dies, each opponent loses 1 life and you gain 1 life. + Ability ability = new DiesCreatureTriggeredAbility(new LoseLifeOpponentsEffect(1), false, filter); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); + this.addAbility(ability); + } + + private BoggartMischief(final BoggartMischief card) { + super(card); + } + + @Override + public BoggartMischief copy() { + return new BoggartMischief(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BoldwyrAggressor.java b/Mage.Sets/src/mage/cards/b/BoldwyrAggressor.java new file mode 100644 index 00000000000..b6d53e50b5e --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BoldwyrAggressor.java @@ -0,0 +1,48 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BoldwyrAggressor extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.GIANT, "Giants"); + + public BoldwyrAggressor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + + this.subtype.add(SubType.GIANT); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // Other Giants you control have double strike. + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + ))); + } + + private BoldwyrAggressor(final BoldwyrAggressor card) { + super(card); + } + + @Override + public BoldwyrAggressor copy() { + return new BoldwyrAggressor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BoneclubBerserker.java b/Mage.Sets/src/mage/cards/b/BoneclubBerserker.java new file mode 100644 index 00000000000..c038a27137f --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BoneclubBerserker.java @@ -0,0 +1,61 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.StaticValue; +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.filter.predicate.mageobject.AnotherPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BoneclubBerserker extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledPermanent(SubType.GOBLIN, "other Goblin you control"); + + static { + filter.add(AnotherPredicate.instance); + } + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, 2); + private static final Hint hint = new ValueHint( + "Other Goblins you control", new PermanentsOnBattlefieldCount(filter) + ); + + public BoneclubBerserker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // This creature gets +2/+0 for each other Goblin you control. + this.addAbility(new SimpleStaticAbility(new BoostSourceEffect( + xValue, StaticValue.get(0), Duration.WhileOnBattlefield + )).addHint(hint)); + } + + private BoneclubBerserker(final BoneclubBerserker card) { + super(card); + } + + @Override + public BoneclubBerserker copy() { + return new BoneclubBerserker(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/BraskasFinalAeon.java b/Mage.Sets/src/mage/cards/b/BraskasFinalAeon.java deleted file mode 100644 index a59cb3fc942..00000000000 --- a/Mage.Sets/src/mage/cards/b/BraskasFinalAeon.java +++ /dev/null @@ -1,61 +0,0 @@ -package mage.cards.b; - -import mage.MageInt; -import mage.abilities.common.SagaAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.SacrificeOpponentsEffect; -import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class BraskasFinalAeon extends CardImpl { - - public BraskasFinalAeon(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.NIGHTMARE); - this.power = new MageInt(7); - this.toughness = new MageInt(7); - this.nightCard = true; - this.color.setBlack(true); - - // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) - SagaAbility sagaAbility = new SagaAbility(this); - - // I, II -- Jecht Beam -- Each opponent discards a card and you draw a card. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, ability -> { - ability.addEffect(new DiscardEachPlayerEffect(TargetController.OPPONENT)); - ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and you")); - ability.withFlavorWord("Jecht Beam"); - }); - - // III -- Ultimate Jecht Shot -- Each opponent sacrifices two creatures of their choice. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> { - ability.addEffect(new SacrificeOpponentsEffect(2, StaticFilters.FILTER_PERMANENT_CREATURES)); - ability.withFlavorWord("Ultimate Jecht Shot"); - }); - this.addAbility(sagaAbility.withShowSacText(true)); - - // Menace - this.addAbility(new MenaceAbility()); - } - - private BraskasFinalAeon(final BraskasFinalAeon card) { - super(card); - } - - @Override - public BraskasFinalAeon copy() { - return new BraskasFinalAeon(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BrigidsCommand.java b/Mage.Sets/src/mage/cards/b/BrigidsCommand.java new file mode 100644 index 00000000000..1a27733899d --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BrigidsCommand.java @@ -0,0 +1,64 @@ +package mage.cards.b; + +import mage.abilities.Mode; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +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.game.permanent.token.KithkinGreenWhiteToken; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BrigidsCommand extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(SubType.KITHKIN); + + public BrigidsCommand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.SORCERY}, "{1}{G}{W}"); + + this.subtype.add(SubType.KITHKIN); + + // Choose two -- + this.getSpellAbility().getModes().setMinModes(2); + this.getSpellAbility().getModes().setMaxModes(2); + + // * Create a token that's a copy of target Kithkin you control. + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter).withChooseHint("to copy")); + + // * Target player creates a 1/1 green and white Kithkin creature token. + this.getSpellAbility().addMode(new Mode(new CreateTokenTargetEffect(new KithkinGreenWhiteToken())) + .addTarget(new TargetPlayer().withChooseHint("to create a token"))); + + // * Target creature you control gets +3/+3 until end of turn. + this.getSpellAbility().addMode(new Mode(new BoostTargetEffect(3, 3)) + .addTarget(new TargetControlledCreaturePermanent().withChooseHint("+3/+3"))); + + // * Target creature you control fights target creature an opponent controls. + this.getSpellAbility().addMode(new Mode(new FightTargetsEffect()) + .addTarget(new TargetControlledCreaturePermanent().withChooseHint("to fight")) + .addTarget(new TargetOpponentsCreaturePermanent().withChooseHint("to fight"))); + } + + private BrigidsCommand(final BrigidsCommand card) { + super(card); + } + + @Override + public BrigidsCommand copy() { + return new BrigidsCommand(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BristlebaneBattler.java b/Mage.Sets/src/mage/cards/b/BristlebaneBattler.java new file mode 100644 index 00000000000..eb38e813c5e --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BristlebaneBattler.java @@ -0,0 +1,64 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.WardAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BristlebaneBattler extends CardImpl { + + private static final Condition condition = new SourceHasCounterCondition(CounterType.M1M1); + + public BristlebaneBattler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Ward {2} + this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"))); + + // This creature enters with five -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance(5)), + "with five -1/-1 counters on it" + )); + + // Whenever another creature you control enters while this creature has a -1/-1 counter on it, remove a -1/-1 counter from this creature. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new RemoveCounterSourceEffect(CounterType.M1M1.createInstance()), + StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL + ).withTriggerCondition(condition)); + } + + private BristlebaneBattler(final BristlebaneBattler card) { + super(card); + } + + @Override + public BristlebaneBattler copy() { + return new BristlebaneBattler(this); + } +} 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/BugenhagenWiseElder.java b/Mage.Sets/src/mage/cards/b/BugenhagenWiseElder.java index 160bde643b4..102d2039927 100644 --- a/Mage.Sets/src/mage/cards/b/BugenhagenWiseElder.java +++ b/Mage.Sets/src/mage/cards/b/BugenhagenWiseElder.java @@ -30,7 +30,7 @@ public final class BugenhagenWiseElder extends CardImpl { = new FilterControlledCreaturePermanent("you control a creature with power 7 or greater"); static { - filter.add(new PowerPredicate(ComparisonType.MORE_THAN, 7)); + filter.add(new PowerPredicate(ComparisonType.OR_GREATER, 7)); } private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); diff --git a/Mage.Sets/src/mage/cards/b/BurdenedStoneback.java b/Mage.Sets/src/mage/cards/b/BurdenedStoneback.java new file mode 100644 index 00000000000..2c61e33f8b9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BurdenedStoneback.java @@ -0,0 +1,55 @@ +package mage.cards.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class BurdenedStoneback extends CardImpl { + + public BurdenedStoneback(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.GIANT); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // This creature enters with two -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), + null, "This creature enters with two -1/-1 counters on it.", "") + ); + + // {1}{W}, Remove a counter from this creature: Target creature gains indestructible until end of turn. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility(new GainAbilityTargetEffect(IndestructibleAbility.getInstance()), new ManaCostsImpl<>("{1}{W}")); + ability.addCost(new RemoveCountersSourceCost(1)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + } + + private BurdenedStoneback(final BurdenedStoneback card) { + super(card); + } + + @Override + public BurdenedStoneback copy() { + return new BurdenedStoneback(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BurningCuriosity.java b/Mage.Sets/src/mage/cards/b/BurningCuriosity.java new file mode 100644 index 00000000000..38f658860fc --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BurningCuriosity.java @@ -0,0 +1,43 @@ +package mage.cards.b; + +import mage.abilities.condition.common.BlightedCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; +import mage.abilities.keyword.BlightAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class BurningCuriosity extends CardImpl { + + public BurningCuriosity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); + + // As an additional cost to cast this spell, you may blight 1. + this.addAbility(new BlightAbility(1)); + + // Exile the top two cards of your library. If this spell's additional cost was paid, exile the top three cards instead. Until the end of your next turn, you may play those cards. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new ExileTopXMayPlayUntilEffect(3, Duration.UntilEndOfYourNextTurn), + new ExileTopXMayPlayUntilEffect(2, Duration.UntilEndOfYourNextTurn), + BlightedCondition.instance, "exile the top two cards of your library. " + + "If this spell's additional cost was paid, exile the top three cards instead. " + + "Until the end of your next turn, you may play those cards" + )); + } + + private BurningCuriosity(final BurningCuriosity card) { + super(card); + } + + @Override + public BurningCuriosity copy() { + return new BurningCuriosity(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/CacklingCulprit.java b/Mage.Sets/src/mage/cards/c/CacklingCulprit.java deleted file mode 100644 index c3cbc192ecf..00000000000 --- a/Mage.Sets/src/mage/cards/c/CacklingCulprit.java +++ /dev/null @@ -1,53 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.keyword.DeathtouchAbility; -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 CacklingCulprit extends CardImpl { - - public CacklingCulprit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ROGUE); - this.power = new MageInt(3); - this.toughness = new MageInt(5); - this.color.setBlack(true); - this.nightCard = true; - - // Whenever Cackling Culprit or another creature you control dies, you gain 1 life. - this.addAbility(new DiesThisOrAnotherTriggeredAbility( - new GainLifeEffect(1), false, StaticFilters.FILTER_CONTROLLED_CREATURE - )); - - // {1}{B}: Cackling Culprit gains deathtouch until end of turn. - this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect( - DeathtouchAbility.getInstance(), Duration.EndOfTurn - ), new ManaCostsImpl<>("{1}{B}"))); - } - - private CacklingCulprit(final CacklingCulprit card) { - super(card); - } - - @Override - public CacklingCulprit copy() { - return new CacklingCulprit(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CaetusSeaTyrantOfSegovia.java b/Mage.Sets/src/mage/cards/c/CaetusSeaTyrantOfSegovia.java deleted file mode 100644 index be5fd3a7870..00000000000 --- a/Mage.Sets/src/mage/cards/c/CaetusSeaTyrantOfSegovia.java +++ /dev/null @@ -1,63 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledSpellsEffect; -import mage.abilities.keyword.ConvokeAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.filter.common.FilterNonlandCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class CaetusSeaTyrantOfSegovia extends CardImpl { - - private static final FilterNonlandCard filter = new FilterNonlandCard("noncreature spells you cast"); - - static { - filter.add(Predicates.not(CardType.CREATURE.getPredicate())); - filter.add(Predicates.not(new AbilityPredicate(ConvokeAbility.class))); // So there are not redundant copies being added to each card - } - - public CaetusSeaTyrantOfSegovia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.SERPENT); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlue(true); - this.nightCard = true; - - // Noncreature spells you cast have convoke. - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledSpellsEffect(new ConvokeAbility(), filter))); - - // At the beginning of your end step, untap up to four target creatures. - Ability ability = new BeginningOfEndStepTriggeredAbility( - new UntapTargetEffect() - ); - ability.addTarget(new TargetCreaturePermanent(0, 4)); - this.addAbility(ability); - } - - private CaetusSeaTyrantOfSegovia(final CaetusSeaTyrantOfSegovia card) { - super(card); - } - - @Override - public CaetusSeaTyrantOfSegovia copy() { - return new CaetusSeaTyrantOfSegovia(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/CartoucheOfStrength.java b/Mage.Sets/src/mage/cards/c/CartoucheOfStrength.java index ba2f234c7de..62251146d16 100644 --- a/Mage.Sets/src/mage/cards/c/CartoucheOfStrength.java +++ b/Mage.Sets/src/mage/cards/c/CartoucheOfStrength.java @@ -2,12 +2,11 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.FightEnchantedTargetEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; @@ -15,8 +14,6 @@ import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent; @@ -24,14 +21,13 @@ import mage.target.common.TargetOpponentsCreaturePermanent; import java.util.UUID; /** - * * @author stravant */ public final class CartoucheOfStrength extends CardImpl { public CartoucheOfStrength(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); - + this.subtype.add(SubType.AURA, SubType.CARTOUCHE); // Enchant creature you control @@ -42,7 +38,8 @@ public final class CartoucheOfStrength extends CardImpl { this.addAbility(ability); // When Cartouche of Strength enters the battlefield, you may have enchanted creature fight target creature an opponent controls. - ability = new EntersBattlefieldTriggeredAbility(new FightEnchantedTargetEffect(), /* optional = */true); + ability = new EntersBattlefieldTriggeredAbility(new FightEnchantedTargetEffect() + .setText("enchanted creature fight target creature an opponent controls"), true); ability.addTarget(new TargetOpponentsCreaturePermanent()); this.addAbility(ability); @@ -63,49 +60,3 @@ public final class CartoucheOfStrength extends CardImpl { return new CartoucheOfStrength(this); } } - -/** - * - * @author stravant - */ -class FightEnchantedTargetEffect extends OneShotEffect { - - FightEnchantedTargetEffect() { - super(Outcome.Damage); - this.staticText = "you may have enchanted creature fight target creature an opponent controls. " + - "(Each deals damage equal to its power to the other.)"; - } - - private FightEnchantedTargetEffect(final FightEnchantedTargetEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent != null) { - Permanent originalCreature = game.getPermanentOrLKIBattlefield(sourcePermanent.getAttachedTo()); - if (originalCreature != null) { - Permanent enchantedCreature = game.getPermanent(sourcePermanent.getAttachedTo()); - // only if target is legal the effect will be applied - if (source.getTargets().get(0).isLegal(source, game)) { - Permanent creature1 = game.getPermanent(source.getTargets().get(0).getFirstTarget()); - // 20110930 - 701.10 - if (creature1 != null && enchantedCreature != null) { - if (creature1.isCreature(game) && enchantedCreature.isCreature(game)) { - return enchantedCreature.fight(creature1, source, game); - } - } - } - if (!game.isSimulation()) - game.informPlayers(originalCreature.getLogName() + ": Fighting effect has been fizzled."); - } - } - return false; - } - - @Override - public FightEnchantedTargetEffect copy() { - return new FightEnchantedTargetEffect(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/CaseOfTheShatteredPact.java b/Mage.Sets/src/mage/cards/c/CaseOfTheShatteredPact.java index 2aaf706104a..20d4cdf2f01 100644 --- a/Mage.Sets/src/mage/cards/c/CaseOfTheShatteredPact.java +++ b/Mage.Sets/src/mage/cards/c/CaseOfTheShatteredPact.java @@ -1,14 +1,13 @@ package mage.cards.c; -import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.CaseAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SolvedSourceCondition; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.hint.common.CaseSolvedHint; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; @@ -49,7 +48,7 @@ public final class CaseOfTheShatteredPact extends CardImpl { solvedAbility.addTarget(new TargetControlledCreaturePermanent()); this.addAbility(new CaseAbility(initialAbility, CaseOfTheShatteredPactCondition.instance, solvedAbility) - .addHint(new CaseOfTheShatteredPactHint(CaseOfTheShatteredPactCondition.instance))); + .addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); } private CaseOfTheShatteredPact(final CaseOfTheShatteredPact card) { @@ -67,13 +66,7 @@ enum CaseOfTheShatteredPactCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - ObjectColor color = new ObjectColor(""); - game.getBattlefield() - .getAllActivePermanents(source.getControllerId()) - .stream() - .map(permanent -> permanent.getColor(game)) - .forEach(color::addColor); - return color.getColorCount() == 5; + return ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.calculate(game, source, null) >= 5; } @Override @@ -81,30 +74,3 @@ enum CaseOfTheShatteredPactCondition implements Condition { return "There are five colors among permanents you control"; } } - -class CaseOfTheShatteredPactHint extends CaseSolvedHint { - - CaseOfTheShatteredPactHint(Condition condition) { - super(condition); - } - - CaseOfTheShatteredPactHint(final CaseOfTheShatteredPactHint hint) { - super(hint); - } - - @Override - public CaseOfTheShatteredPactHint copy() { - return new CaseOfTheShatteredPactHint(this); - } - - @Override - public String getConditionText(Game game, Ability ability) { - ObjectColor color = new ObjectColor(""); - game.getBattlefield() - .getAllActivePermanents(ability.getControllerId()) - .stream() - .map(permanent -> permanent.getColor(game)) - .forEach(color::addColor); - return "Colors: " + color.getColorCount() + " (need 5)."; - } -} diff --git a/Mage.Sets/src/mage/cards/c/CatlikeCuriosity.java b/Mage.Sets/src/mage/cards/c/CatlikeCuriosity.java deleted file mode 100644 index c741013939f..00000000000 --- a/Mage.Sets/src/mage/cards/c/CatlikeCuriosity.java +++ /dev/null @@ -1,58 +0,0 @@ -package mage.cards.c; - -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.keyword.DisturbAbility; -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 CatlikeCuriosity extends CardImpl { - - public CatlikeCuriosity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.AURA); - this.color.setBlue(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 "Whenever this creature deals combat damage to a player, draw a card." - this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( - new DealsCombatDamageToAPlayerTriggeredAbility( - new DrawCardSourceControllerEffect(1), false - ).setTriggerPhrase("Whenever this creature deals combat damage to a player, "), AttachmentType.AURA - ))); - - // If Catlike Curiosity would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private CatlikeCuriosity(final CatlikeCuriosity card) { - super(card); - } - - @Override - public CatlikeCuriosity copy() { - return new CatlikeCuriosity(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CausticExhale.java b/Mage.Sets/src/mage/cards/c/CausticExhale.java index e98d0568b03..f0cc9ac1646 100644 --- a/Mage.Sets/src/mage/cards/c/CausticExhale.java +++ b/Mage.Sets/src/mage/cards/c/CausticExhale.java @@ -1,11 +1,12 @@ package mage.cards.c; import mage.abilities.costs.OrCost; -import mage.abilities.costs.common.BeholdDragonCost; +import mage.abilities.costs.common.BeholdCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.common.TargetCreaturePermanent; @@ -22,7 +23,7 @@ public final class CausticExhale extends CardImpl { // As an additional cost to cast this spell, behold a Dragon or pay {1}. this.getSpellAbility().addCost(new OrCost( "behold a Dragon or pay {1}", - new BeholdDragonCost(), new GenericManaCost(1) + new BeholdCost(BeholdType.DRAGON), new GenericManaCost(1) )); // Target creature gets -3/-3 until end of turn. diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java b/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java new file mode 100644 index 00000000000..f89c1578fb5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChampionOfTheClachan.java @@ -0,0 +1,58 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.BeholdAndExileCost; +import mage.abilities.effects.common.ReturnExiledCardToHandEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ChampionOfTheClachan extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.KITHKIN, "Kithkin"); + + public ChampionOfTheClachan(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // As an additional cost to cast this spell, behold a Kithkin and exile it. + this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.KITHKIN)); + + // Other Kithkin you control get +1/+1. + this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( + 1, 1, Duration.WhileOnBattlefield, filter, true + ))); + + // When this creature leaves the battlefield, return the exiled card to its owner's hand. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnExiledCardToHandEffect())); + } + + private ChampionOfTheClachan(final ChampionOfTheClachan card) { + super(card); + } + + @Override + public ChampionOfTheClachan copy() { + return new ChampionOfTheClachan(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java b/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java new file mode 100644 index 00000000000..7b8ea6f6ed1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChampionOfTheWeird.java @@ -0,0 +1,55 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.costs.common.BeholdAndExileCost; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.ReturnExiledCardToHandEffect; +import mage.abilities.effects.keyword.BlightTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetOpponent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ChampionOfTheWeird extends CardImpl { + + public ChampionOfTheWeird(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // As an additional cost to cast this spell, behold a Goblin and exile it. + this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.GOBLIN)); + + // Pay 1 life, Blight 2: Target opponent blights 2. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility(new BlightTargetEffect(2), new PayLifeCost(1)); + ability.addCost(new BlightCost(2)); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + + // When this creature leaves the battlefield, return the exiled card to its owner's hand. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnExiledCardToHandEffect())); + } + + private ChampionOfTheWeird(final ChampionOfTheWeird card) { + super(card); + } + + @Override + public ChampionOfTheWeird copy() { + return new ChampionOfTheWeird(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java b/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java new file mode 100644 index 00000000000..f23deb5c4db --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChampionsOfThePerfect.java @@ -0,0 +1,52 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.common.BeholdAndExileCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnExiledCardToHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ChampionsOfThePerfect extends CardImpl { + + public ChampionsOfThePerfect(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // As an additional cost to cast this spell, behold an Elf and exile it. + this.getSpellAbility().addCost(new BeholdAndExileCost(BeholdType.ELF)); + + // Whenever you cast a creature spell, draw a card. + this.addAbility(new SpellCastControllerTriggeredAbility( + new DrawCardSourceControllerEffect(1), + StaticFilters.FILTER_SPELL_A_CREATURE, false + )); + + // When this creature leaves the battlefield, return the exiled card to its owner's hand. + this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnExiledCardToHandEffect())); + } + + private ChampionsOfThePerfect(final ChampionsOfThePerfect card) { + super(card); + } + + @Override + public ChampionsOfThePerfect copy() { + return new ChampionsOfThePerfect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChaosShrinesBlackCrystal.java b/Mage.Sets/src/mage/cards/c/ChaosShrinesBlackCrystal.java new file mode 100644 index 00000000000..fc69ca24cad --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChaosShrinesBlackCrystal.java @@ -0,0 +1,92 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.counters.Counters; +import mage.filter.StaticFilters; +import mage.game.ExileZone; +import mage.game.Game; +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 ChaosShrinesBlackCrystal extends CardImpl { + + public ChaosShrinesBlackCrystal(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + + // Whenever a nontoken creature you control dies, exile it. + this.addAbility(new DiesCreatureTriggeredAbility( + new ExileTargetForSourceEffect(), false, + StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN, true + )); + + // At the beginning of your upkeep, you may put a creature card exiled with Chaos Shrine's Black Crystal onto the battlefield under your control with a finality counter on it. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ChaosShrinesBlackCrystalEffect())); + } + + private ChaosShrinesBlackCrystal(final ChaosShrinesBlackCrystal card) { + super(card); + } + + @Override + public ChaosShrinesBlackCrystal copy() { + return new ChaosShrinesBlackCrystal(this); + } +} + +class ChaosShrinesBlackCrystalEffect extends OneShotEffect { + + ChaosShrinesBlackCrystalEffect() { + super(Outcome.Benefit); + staticText = "you may put a creature card exiled with {this} " + + "onto the battlefield under your control with a finality counter on it"; + } + + private ChaosShrinesBlackCrystalEffect(final ChaosShrinesBlackCrystalEffect effect) { + super(effect); + } + + @Override + public ChaosShrinesBlackCrystalEffect copy() { + return new ChaosShrinesBlackCrystalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + if (player == null || exileZone == null) { + return false; + } + TargetCard target = new TargetCardInExile( + 0, 1, StaticFilters.FILTER_CARD_CREATURE, exileZone.getId() + ); + player.choose(Outcome.PutCreatureInPlay, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return false; + } + game.setEnterWithCounters(card.getId(), new Counters(CounterType.FINALITY.createInstance())); + return player.moveCards(card, Zone.BATTLEFIELD, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChaosSpewer.java b/Mage.Sets/src/mage/cards/c/ChaosSpewer.java new file mode 100644 index 00000000000..8629a211d1d --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChaosSpewer.java @@ -0,0 +1,42 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.keyword.BlightControllerEffect; +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 ChaosSpewer extends CardImpl { + + public ChaosSpewer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // When this creature enters, you may pay {2}. If you don't, blight 2. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( + null, new BlightControllerEffect(2), new GenericManaCost(2) + ))); + } + + private ChaosSpewer(final ChaosSpewer card) { + super(card); + } + + @Override + public ChaosSpewer copy() { + return new ChaosSpewer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChaosTheEndless.java b/Mage.Sets/src/mage/cards/c/ChaosTheEndless.java deleted file mode 100644 index cb222c37a81..00000000000 --- a/Mage.Sets/src/mage/cards/c/ChaosTheEndless.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.common.DiesSourceTriggeredAbility; -import mage.abilities.effects.common.PutOnLibrarySourceEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ChaosTheEndless extends CardImpl { - - public ChaosTheEndless(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(5); - this.toughness = new MageInt(5); - this.color.setBlack(true); - this.color.setRed(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // When Chaos dies, put it on the bottom of its owner's library. - this.addAbility(new DiesSourceTriggeredAbility(new PutOnLibrarySourceEffect( - false, "put it on the bottom of its owner's library" - ), false)); - } - - private ChaosTheEndless(final ChaosTheEndless card) { - super(card); - } - - @Override - public ChaosTheEndless copy() { - return new ChaosTheEndless(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChillingChronicle.java b/Mage.Sets/src/mage/cards/c/ChillingChronicle.java deleted file mode 100644 index 12036ef2743..00000000000 --- a/Mage.Sets/src/mage/cards/c/ChillingChronicle.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.c; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.TapTargetEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.target.common.TargetNonlandPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ChillingChronicle extends CardImpl { - - public ChillingChronicle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.color.setBlue(true); - this.nightCard = true; - - // {1}, {T}: Tap target nonland permanent. Transform Chilling Chronicle. - Ability ability = new SimpleActivatedAbility(new TapTargetEffect(), new GenericManaCost(1)); - ability.addCost(new TapSourceCost()); - ability.addEffect(new TransformSourceEffect()); - ability.addTarget(new TargetNonlandPermanent()); - this.addAbility(ability); - } - - private ChillingChronicle(final ChillingChronicle card) { - super(card); - } - - @Override - public ChillingChronicle copy() { - return new ChillingChronicle(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChitinousGraspling.java b/Mage.Sets/src/mage/cards/c/ChitinousGraspling.java new file mode 100644 index 00000000000..dbedb4c430a --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChitinousGraspling.java @@ -0,0 +1,40 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.keyword.ChangelingAbility; +import mage.abilities.keyword.ReachAbility; +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 ChitinousGraspling extends CardImpl { + + public ChitinousGraspling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G/U}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // Reach + this.addAbility(ReachAbility.getInstance()); + } + + private ChitinousGraspling(final ChitinousGraspling card) { + super(card); + } + + @Override + public ChitinousGraspling copy() { + return new ChitinousGraspling(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/ChompingChangeling.java b/Mage.Sets/src/mage/cards/c/ChompingChangeling.java new file mode 100644 index 00000000000..2deb934719a --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChompingChangeling.java @@ -0,0 +1,46 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.ChangelingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ChompingChangeling extends CardImpl { + + public ChompingChangeling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // When this creature enters, destroy up to one target artifact or enchantment. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.addAbility(ability); + } + + private ChompingChangeling(final ChompingChangeling card) { + super(card); + } + + @Override + public ChompingChangeling copy() { + return new ChompingChangeling(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java b/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java index 75389e5015d..1475f3a214d 100644 --- a/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java +++ b/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java @@ -6,9 +6,10 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughManaEffect; -import mage.abilities.effects.common.DrawCardForEachColorAmongControlledPermanentsEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -19,14 +20,13 @@ import mage.players.ManaPoolItem; import java.util.UUID; /** - * * @author htrajan */ public final class ChromaticOrrery extends CardImpl { public ChromaticOrrery(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{7}"); - + this.supertype.add(SuperType.LEGENDARY); // You may spend mana as though it were mana of any color. @@ -36,9 +36,9 @@ public final class ChromaticOrrery extends CardImpl { this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(5), new TapSourceCost())); // {5}, {T}: Draw a card for each color among permanents you control. - Ability ability = new SimpleActivatedAbility(new DrawCardForEachColorAmongControlledPermanentsEffect(), new GenericManaCost(5)); + Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS), new GenericManaCost(5)); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.addAbility(ability.addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); } private ChromaticOrrery(final ChromaticOrrery card) { diff --git a/Mage.Sets/src/mage/cards/c/ChromeHostHulk.java b/Mage.Sets/src/mage/cards/c/ChromeHostHulk.java deleted file mode 100644 index 96aa262eeb4..00000000000 --- a/Mage.Sets/src/mage/cards/c/ChromeHostHulk.java +++ /dev/null @@ -1,57 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect; -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.FilterCreaturePermanent; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ChromeHostHulk extends CardImpl { - - private static final FilterPermanent filter = new FilterCreaturePermanent("other target creature"); - - static { - filter.add(AnotherPredicate.instance); - } - - public ChromeHostHulk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.TROLL); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.color.setBlue(true); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever Chrome Host Hulk attacks, up to one other target creature has base power and toughness 5/5 until end of turn. - Ability ability = new AttacksTriggeredAbility( - new SetBasePowerToughnessTargetEffect(5, 5, Duration.EndOfTurn) - ); - ability.addTarget(new TargetPermanent(0, 1, filter)); - this.addAbility(ability); - } - - private ChromeHostHulk(final ChromeHostHulk card) { - super(card); - } - - @Override - public ChromeHostHulk copy() { - return new ChromeHostHulk(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/ClachanFestival.java b/Mage.Sets/src/mage/cards/c/ClachanFestival.java new file mode 100644 index 00000000000..aee2747b88b --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ClachanFestival.java @@ -0,0 +1,42 @@ +package mage.cards.c; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.KithkinGreenWhiteToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ClachanFestival extends CardImpl { + + public ClachanFestival(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.KINDRED, CardType.ENCHANTMENT}, "{2}{W}"); + + this.subtype.add(SubType.KITHKIN); + + // When this enchantment enters, create two 1/1 green and white Kithkin creature tokens. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new KithkinGreenWhiteToken(), 2))); + + // {4}{W}: Create a 1/1 green and white Kithkin creature token. + this.addAbility(new SimpleActivatedAbility( + new CreateTokenEffect(new KithkinGreenWhiteToken()), new ManaCostsImpl<>("{4}{W}") + )); + } + + private ClachanFestival(final ClachanFestival card) { + super(card); + } + + @Override + public ClachanFestival copy() { + return new ClachanFestival(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ConcealingCurtains.java b/Mage.Sets/src/mage/cards/c/ConcealingCurtains.java index bb17274ce09..7ba82a0c253 100644 --- a/Mage.Sets/src/mage/cards/c/ConcealingCurtains.java +++ b/Mage.Sets/src/mage/cards/c/ConcealingCurtains.java @@ -8,6 +8,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.MenaceAbility; +import mage.cards.Card; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; @@ -15,6 +16,7 @@ import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.StaticFilters; +import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetOpponent; @@ -83,7 +85,7 @@ class RevealingEyeEffect extends OneShotEffect { } @Override - public boolean apply(mage.game.Game game, Ability source) { + public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player opponent = game.getPlayer(source.getFirstTarget()); if (controller == null || opponent == null) { @@ -95,7 +97,7 @@ class RevealingEyeEffect extends OneShotEffect { } TargetCard target = new TargetCard(0, 1, Zone.HAND, StaticFilters.FILTER_CARD_NON_LAND); controller.choose(outcome, opponent.getHand(), target, source, game); - mage.cards.Card card = game.getCard(target.getFirstTarget()); + Card card = game.getCard(target.getFirstTarget()); if (card == null) { return true; } diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java b/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java index 32539d56033..2e0877745c9 100644 --- a/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java +++ b/Mage.Sets/src/mage/cards/c/ConquerorsFlail.java @@ -1,12 +1,10 @@ package mage.cards.c; -import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; @@ -19,7 +17,6 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -35,8 +32,10 @@ public final class ConquerorsFlail extends CardImpl { // Equipped creature gets +1/+1 for each color among permanents you control. this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect( - ConquerorsFlailColorCount.instance, ConquerorsFlailColorCount.instance, Duration.WhileOnBattlefield - ))); + ColorsAmongControlledPermanentsCount.ALL_PERMANENTS, + ColorsAmongControlledPermanentsCount.ALL_PERMANENTS, + Duration.WhileOnBattlefield + )).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); // As long as Conqueror's Flail is attached to a creature, your opponents can't cast spells during your turn. this.addAbility(new SimpleStaticAbility(new ConquerorsFlailEffect())); @@ -55,36 +54,6 @@ public final class ConquerorsFlail extends CardImpl { } } -enum ConquerorsFlailColorCount implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - ObjectColor color = new ObjectColor(""); - game.getBattlefield() - .getAllActivePermanents(sourceAbility.getControllerId()) - .stream() - .map(permanent -> permanent.getColor(game)) - .forEach(color::addColor); - return color.getColorCount(); - } - - @Override - public String toString() { - return "1"; - } - - @Override - public String getMessage() { - return "color among permanents you control"; - } - - @Override - public ConquerorsFlailColorCount copy() { - return this; - } -} - class ConquerorsFlailEffect extends ContinuousRuleModifyingEffectImpl { ConquerorsFlailEffect() { 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/CrampedVentsAccessMaze.java b/Mage.Sets/src/mage/cards/c/CrampedVentsAccessMaze.java new file mode 100644 index 00000000000..acf6f770fb8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrampedVentsAccessMaze.java @@ -0,0 +1,169 @@ +package mage.cards.c; + +import mage.MageIdentifier; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.costs.Costs; +import mage.abilities.costs.CostsImpl; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.*; +import mage.game.Controllable; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetOpponentsCreaturePermanent; +import mage.util.CardUtil; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class CrampedVentsAccessMaze extends RoomCard { + + public CrampedVentsAccessMaze(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{3}{B}", "{5}{B}{B}"); + + // 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. + Ability ability = new UnlockThisDoorTriggeredAbility(new CrampedVentsEffect(), false, true); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + ability.addWatcher(new AccessMazeWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Access Maze + // 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. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new AccessMazeEffect()) + .setIdentifier(MageIdentifier.AccessMazeWatcher)); + } + + private CrampedVentsAccessMaze(final CrampedVentsAccessMaze card) { + super(card); + } + + @Override + public CrampedVentsAccessMaze copy() { + return new CrampedVentsAccessMaze(this); + } +} + +class CrampedVentsEffect extends OneShotEffect { + + CrampedVentsEffect() { + super(Outcome.Benefit); + staticText = "{this} deals 6 damage to target creature an opponent controls. " + + "You gain life equal to the excess damage dealt this way."; + } + + private CrampedVentsEffect(final CrampedVentsEffect effect) { + super(effect); + } + + @Override + public CrampedVentsEffect copy() { + return new CrampedVentsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + int excess = permanent.damageWithExcess(6, source, game); + if (excess > 0) { + Optional.ofNullable(source) + .map(Controllable::getControllerId) + .map(game::getPlayer) + .ifPresent(player -> player.gainLife(excess, game, source)); + } + return true; + } +} + +class AccessMazeEffect extends AsThoughEffectImpl { + + AccessMazeEffect() { + super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.PlayForFree); + staticText = "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"; + } + + private AccessMazeEffect(final AccessMazeEffect effect) { + super(effect); + } + + @Override + public AccessMazeEffect copy() { + return new AccessMazeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (!source.isControlledBy(affectedControllerId) || !game.isActivePlayer(source.getControllerId())) { + return false; + } + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourceObject = game.getPermanent(source.getSourceId()); + Card card = game.getCard(CardUtil.getMainCardId(game, objectId)); + if (controller == null || card == null || sourceObject == null + || !Zone.HAND.match(game.getState().getZone(card.getId())) + || AccessMazeWatcher.isAbilityUsed(new MageObjectReference(sourceObject, game), game)) { + return false; + } + Costs costs = new CostsImpl(); + costs.add(new PayLifeCost(card.getManaValue())); + controller.setCastSourceIdWithAlternateMana( + source.getSourceId(), null, costs, MageIdentifier.AccessMazeWatcher + ); + return true; + } +} + +class AccessMazeWatcher extends Watcher { + + private final Set usedFrom = new HashSet<>(); + + public AccessMazeWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SPELL_CAST + && event.hasApprovingIdentifier(MageIdentifier.AccessMazeWatcher)) { + usedFrom.add(event.getApprovingObject().getApprovingMageObjectReference()); + } + } + + @Override + public void reset() { + super.reset(); + usedFrom.clear(); + } + + static boolean isAbilityUsed(MageObjectReference mor, Game game) { + return game + .getState() + .getWatcher(AccessMazeWatcher.class) + .usedFrom + .contains(mor); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CrashingWave.java b/Mage.Sets/src/mage/cards/c/CrashingWave.java index e3695a1bebb..f4815dd3d1e 100644 --- a/Mage.Sets/src/mage/cards/c/CrashingWave.java +++ b/Mage.Sets/src/mage/cards/c/CrashingWave.java @@ -1,13 +1,16 @@ package mage.cards.c; import mage.abilities.Ability; -import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.WaterbendXCost; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterOpponentsCreaturePermanent; @@ -30,7 +33,10 @@ public final class CrashingWave extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{U}"); // As an additional cost to cast this spell, waterbend {X}. - this.getSpellAbility().addCost(new WaterbendCost("{X}")); + this.getSpellAbility().addCost(new WaterbendXCost()); + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {X}") + ).setRuleAtTheTop(true)); // Tap up to X target creatures, then distribute three stun counters among tapped creatures your opponents control. this.getSpellAbility().addEffect(new TapTargetEffect("tap up to X target creatures")); @@ -79,7 +85,7 @@ class CrashingWaveEffect extends OneShotEffect { } TargetPermanentAmount target = new TargetPermanentAmount(3, 1, filter); target.withNotTarget(true); - player.chooseTarget(outcome, target, source, game); + target.chooseTarget(outcome, player.getId(), source, game); for (UUID targetId : target.getTargets()) { Optional.ofNullable(targetId) .map(game::getPermanent) diff --git a/Mage.Sets/src/mage/cards/c/CreepingInn.java b/Mage.Sets/src/mage/cards/c/CreepingInn.java deleted file mode 100644 index 106c64a1076..00000000000 --- a/Mage.Sets/src/mage/cards/c/CreepingInn.java +++ /dev/null @@ -1,109 +0,0 @@ -package mage.cards.c; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PhaseOutSourceEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.game.ExileZone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author LePwnerer - */ -public final class CreepingInn extends CardImpl { - - public CreepingInn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.HORROR); - this.subtype.add(SubType.CONSTRUCT); - this.power = new MageInt(3); - this.toughness = new MageInt(7); - this.color.setBlack(true); - this.nightCard = true; - - // Whenever Creeping Inn attacks, you may exile a creature card from your graveyard. - // If you do, each opponent loses X life and you gain X life, - // where X is the number of creature cards exiled with Creeping Inn. - this.addAbility(new AttacksTriggeredAbility(new CreepingInnEffect())); - - // {4}: Creeping Inn phases out. - this.addAbility(new SimpleActivatedAbility(new PhaseOutSourceEffect(), new ManaCostsImpl<>("{4}"))); - } - - private CreepingInn(final CreepingInn card) { - super(card); - } - - @Override - public CreepingInn copy() { - return new CreepingInn(this); - } -} - -class CreepingInnEffect extends OneShotEffect { - - CreepingInnEffect() { - super(Outcome.Exile); - this.staticText = "you may exile a creature card from your graveyard. " + - "If you do, each opponent loses X life and you gain X life, " + - "where X is the number of creature cards exiled with {this}."; - } - - private CreepingInnEffect(final CreepingInnEffect effect) { - super(effect); - } - - @Override - public CreepingInnEffect copy() { - return new CreepingInnEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = source.getSourcePermanentOrLKI(game); - if (player != null && permanent != null) { - UUID exileId = CardUtil.getExileZoneId(game, source); - TargetCardInGraveyard target = new TargetCardInGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); - target.withNotTarget(true); - if (target.canChoose(player.getId(), source, game)) { - if (player.choose(Outcome.Exile, target, source, game)) { - Card cardChosen = game.getCard(target.getFirstTarget()); - if (cardChosen != null) { - int lifeAmount = 0; - player.moveCardsToExile(cardChosen, source, game, true, exileId, permanent.getName()); - ExileZone exile = game.getExile().getExileZone(exileId); - if (exile != null) { - for (UUID cardId : exile) { - lifeAmount++; - } - } - for (UUID playerId : game.getOpponents(source.getControllerId())) { - game.getPlayer(playerId).loseLife(lifeAmount, game, source, false); - } - player.gainLife(lifeAmount, game, source); - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/c/CribSwap.java b/Mage.Sets/src/mage/cards/c/CribSwap.java index 6de9284cf01..d41f88be905 100644 --- a/Mage.Sets/src/mage/cards/c/CribSwap.java +++ b/Mage.Sets/src/mage/cards/c/CribSwap.java @@ -8,7 +8,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.game.permanent.token.CribSwapShapeshifterWhiteToken; +import mage.game.permanent.token.ShapeshifterColorlessToken; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -26,7 +26,7 @@ public final class CribSwap extends CardImpl { this.addAbility(new ChangelingAbility()); // Exile target creature. Its controller creates a 1/1 colorless Shapeshifter creature token with changeling. this.getSpellAbility().addEffect(new ExileTargetEffect()); - this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new CribSwapShapeshifterWhiteToken())); + this.getSpellAbility().addEffect(new CreateTokenControllerTargetEffect(new ShapeshifterColorlessToken())); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } @@ -39,4 +39,4 @@ public final class CribSwap extends CardImpl { public CribSwap copy() { return new CribSwap(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/c/CrossroadsWatcher.java b/Mage.Sets/src/mage/cards/c/CrossroadsWatcher.java new file mode 100644 index 00000000000..bb01e242f52 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CrossroadsWatcher.java @@ -0,0 +1,47 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +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.Duration; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author muz + */ +public final class CrossroadsWatcher extends CardImpl { + + public CrossroadsWatcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.RANGER); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Whenever another creature you control enters, this creature gets +1/+0 until end of turn. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new BoostSourceEffect(1, 0, Duration.EndOfTurn), + StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL + )); + } + + private CrossroadsWatcher(final CrossroadsWatcher card) { + super(card); + } + + @Override + public CrossroadsWatcher copy() { + return new CrossroadsWatcher(this); + } +} 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/DarknessDescends.java b/Mage.Sets/src/mage/cards/d/DarknessDescends.java new file mode 100644 index 00000000000..8fd72141b5b --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DarknessDescends.java @@ -0,0 +1,34 @@ +package mage.cards.d; + +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DarknessDescends extends CardImpl { + + public DarknessDescends(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); + + // Put two -1/-1 counters on each creature. + this.getSpellAbility().addEffect(new AddCountersAllEffect( + CounterType.M1M1.createInstance(2), StaticFilters.FILTER_PERMANENT_CREATURE + )); + } + + private DarknessDescends(final DarknessDescends card) { + super(card); + } + + @Override + public DarknessDescends copy() { + return new DarknessDescends(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DawnhandEulogist.java b/Mage.Sets/src/mage/cards/d/DawnhandEulogist.java new file mode 100644 index 00000000000..d5c9e2b6db5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DawnhandEulogist.java @@ -0,0 +1,59 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CardsInControllerGraveyardCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.MillCardsControllerEffect; +import mage.abilities.hint.ConditionHint; +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.SubType; +import mage.filter.FilterCard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DawnhandEulogist extends CardImpl { + + private static final Condition condition = new CardsInControllerGraveyardCondition(1, new FilterCard(SubType.ELF)); + private static final Hint hint = new ConditionHint(condition, "There is an Elf card in your graveyard"); + + public DawnhandEulogist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Menace + this.addAbility(new MenaceAbility()); + + // When this creature enters, mill three cards. Then if there is an Elf card in your graveyard, each opponent loses 2 life and you gain 2 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new MillCardsControllerEffect(3)); + ability.addEffect(new ConditionalOneShotEffect( + new LoseLifeOpponentsEffect(2), condition, "then if there is an Elf " + + "card in your graveyard, each opponent loses 2 life and you gain 2 life" + ).addEffect(new GainLifeEffect(2))); + this.addAbility(ability.addHint(hint)); + } + + private DawnhandEulogist(final DawnhandEulogist card) { + super(card); + } + + @Override + public DawnhandEulogist copy() { + return new DawnhandEulogist(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DawnsLightArcher.java b/Mage.Sets/src/mage/cards/d/DawnsLightArcher.java new file mode 100644 index 00000000000..166ae73deaa --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DawnsLightArcher.java @@ -0,0 +1,41 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.ReachAbility; +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 DawnsLightArcher extends CardImpl { + + public DawnsLightArcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.ARCHER); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Reach + this.addAbility(ReachAbility.getInstance()); + } + + private DawnsLightArcher(final DawnsLightArcher card) { + super(card); + } + + @Override + public DawnsLightArcher copy() { + return new DawnsLightArcher(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/DefiantThundermaw.java b/Mage.Sets/src/mage/cards/d/DefiantThundermaw.java deleted file mode 100644 index 79190ed8b56..00000000000 --- a/Mage.Sets/src/mage/cards/d/DefiantThundermaw.java +++ /dev/null @@ -1,90 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.game.Game; -import mage.target.common.TargetAnyTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class DefiantThundermaw extends CardImpl { - - private static final FilterControlledCreaturePermanent filter - = new FilterControlledCreaturePermanent(SubType.DRAGON); - - public DefiantThundermaw(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()); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Whenever a Dragon you control attacks, it deals 2 damage to any target. - Ability ability = new AttacksCreatureYouControlTriggeredAbility( - new DefiantThundermawEffect(), false, filter - ); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); - } - - private DefiantThundermaw(final DefiantThundermaw card) { - super(card); - } - - @Override - public DefiantThundermaw copy() { - return new DefiantThundermaw(this); - } -} - -class DefiantThundermawEffect extends OneShotEffect { - - DefiantThundermawEffect() { - super(Outcome.Benefit); - staticText = "it deals 2 damage to any target"; - } - - private DefiantThundermawEffect(final DefiantThundermawEffect effect) { - super(effect); - } - - @Override - public DefiantThundermawEffect copy() { - return new DefiantThundermawEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - MageObjectReference mor = (MageObjectReference) getValue("attackerRef"); - if (mor == null) { - return false; - } - game.damagePlayerOrPermanent( - getTargetPointer().getFirst(game, source), 2, - mor.getSourceId(), source, game, false, true - ); - return true; - } -} 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/DelugeOfTheDead.java b/Mage.Sets/src/mage/cards/d/DelugeOfTheDead.java deleted file mode 100644 index a8c1e8478aa..00000000000 --- a/Mage.Sets/src/mage/cards/d/DelugeOfTheDead.java +++ /dev/null @@ -1,82 +0,0 @@ -package mage.cards.d; - -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.token.ZombieToken; -import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class DelugeOfTheDead extends CardImpl { - - public DelugeOfTheDead(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setBlack(true); - this.nightCard = true; - - // When Deluge of the Dead enters the battlefield, create two 2/2 black Zombie creature tokens. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ZombieToken(), 2))); - - // {2}{B}: Exile target card from a graveyard. If it was a creature card, create a 2/2 black Zombie creature token. - Ability ability = new SimpleActivatedAbility(new DelugeOfTheDeadEffect(), new ManaCostsImpl<>("{2}{B}")); - ability.addTarget(new TargetCardInGraveyard()); - this.addAbility(ability); - } - - private DelugeOfTheDead(final DelugeOfTheDead card) { - super(card); - } - - @Override - public DelugeOfTheDead copy() { - return new DelugeOfTheDead(this); - } -} - -class DelugeOfTheDeadEffect extends OneShotEffect { - - DelugeOfTheDeadEffect() { - super(Outcome.Benefit); - staticText = "exile target card from a graveyard. " + - "If it was a creature card, create a 2/2 black Zombie creature token"; - } - - private DelugeOfTheDeadEffect(final DelugeOfTheDeadEffect effect) { - super(effect); - } - - @Override - public DelugeOfTheDeadEffect copy() { - return new DelugeOfTheDeadEffect(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.EXILED, source, game); - if (card.isCreature(game)) { - new ZombieToken().putOntoBattlefield(1, game, source); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DemonPossessedWitch.java b/Mage.Sets/src/mage/cards/d/DemonPossessedWitch.java deleted file mode 100644 index ddfbb76f007..00000000000 --- a/Mage.Sets/src/mage/cards/d/DemonPossessedWitch.java +++ /dev/null @@ -1,46 +0,0 @@ - -package mage.cards.d; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class DemonPossessedWitch extends CardImpl { - - public DemonPossessedWitch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SHAMAN); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - this.color.setBlack(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // When this creature transforms into Demon-Possessed Witch, you may destroy target creature. - Ability ability = new TransformIntoSourceTriggeredAbility(new DestroyTargetEffect(), true); - ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); - } - - private DemonPossessedWitch(final DemonPossessedWitch card) { - super(card); - } - - @Override - public DemonPossessedWitch copy() { - return new DemonPossessedWitch(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/DionBahamutsDominant.java b/Mage.Sets/src/mage/cards/d/DionBahamutsDominant.java index a3e0809935c..1026ddb5fe7 100644 --- a/Mage.Sets/src/mage/cards/d/DionBahamutsDominant.java +++ b/Mage.Sets/src/mage/cards/d/DionBahamutsDominant.java @@ -3,22 +3,28 @@ package mage.cards.d; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SagaAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.counters.CounterType; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.game.permanent.token.WaylayToken; +import mage.target.TargetPermanent; import java.util.UUID; @@ -63,25 +69,25 @@ public final class DionBahamutsDominant extends TransformingDoubleFacedCard { this.getRightHalfCard().setPT(5, 5); // (As this Saga enters and after your draw step, add a lore counter.) - mage.abilities.common.SagaAbility sagaAbility = new mage.abilities.common.SagaAbility(this.getRightHalfCard()); + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); // I, II -- Wings of Light -- Put a +1/+1 counter on each other creature you control. Those creatures gain flying until end of turn. sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, ability3 -> { - ability3.addEffect(new mage.abilities.effects.common.counter.AddCountersAllEffect( - CounterType.P1P1.createInstance(), mage.filter.StaticFilters.FILTER_OTHER_CONTROLLED_CREATURE + ability3.addEffect(new AddCountersAllEffect( + CounterType.P1P1.createInstance(), StaticFilters.FILTER_OTHER_CONTROLLED_CREATURE )); - ability3.addEffect(new mage.abilities.effects.common.continuous.GainAbilityControlledEffect( + ability3.addEffect(new GainAbilityControlledEffect( FlyingAbility.getInstance(), Duration.EndOfTurn, - mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE + StaticFilters.FILTER_CONTROLLED_CREATURE ).setText("Those creatures gain flying until end of turn")); ability3.withFlavorWord("Wings of Light"); }); // III -- Gigaflare -- Destroy target permanent. Exile Bahamut, then return it to the battlefield. sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_III, ability4 -> { - ability4.addEffect(new mage.abilities.effects.common.DestroyTargetEffect()); - ability4.addEffect(new mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect()); - ability4.addTarget(new mage.target.TargetPermanent()); + ability4.addEffect(new DestroyTargetEffect()); + ability4.addEffect(new ExileSourceAndReturnFaceUpEffect()); + ability4.addTarget(new TargetPermanent()); ability4.withFlavorWord("Gigaflare"); }); this.getRightHalfCard().addAbility(sagaAbility); diff --git a/Mage.Sets/src/mage/cards/d/DireFlail.java b/Mage.Sets/src/mage/cards/d/DireFlail.java index 1b2412b1318..d4e1ab257c1 100644 --- a/Mage.Sets/src/mage/cards/d/DireFlail.java +++ b/Mage.Sets/src/mage/cards/d/DireFlail.java @@ -1,10 +1,13 @@ package mage.cards.d; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.Cost; import mage.abilities.costs.SacrificeCost; import mage.abilities.costs.UseAttachedCost; +import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.DamageWithPowerFromSourceToAnotherTargetEffect; import mage.abilities.effects.common.DoWhenCostPaid; @@ -116,7 +119,7 @@ class DireBlunderbussGainAbilityEffect extends ContinuousEffectImpl { new DamageWithPowerFromSourceToAnotherTargetEffect("this creature"), false ); reflexive.addTarget(new TargetCreaturePermanent()); - Ability grant = new mage.abilities.common.AttacksTriggeredAbility( + Ability grant = new AttacksTriggeredAbility( new DoWhenCostPaid( reflexive, new DireBlunderbussSacrificeCost(source, game), "Sacrifice an artifact other than the equipment?" @@ -129,7 +132,7 @@ class DireBlunderbussGainAbilityEffect extends ContinuousEffectImpl { class DireBlunderbussSacrificeCost extends UseAttachedCost implements SacrificeCost { - private final mage.abilities.costs.common.SacrificeTargetCost sacrificeCost; + private final SacrificeTargetCost sacrificeCost; private final mage.MageObjectReference mageObjectReference; DireBlunderbussSacrificeCost(Ability source, Game game) { @@ -137,7 +140,7 @@ class DireBlunderbussSacrificeCost extends UseAttachedCost implements SacrificeC this.mageObjectReference = new mage.MageObjectReference(source.getSourceObject(game), game); FilterControlledArtifactPermanent filter = new FilterControlledArtifactPermanent(); filter.add(Predicates.not(new MageObjectReferencePredicate(this.mageObjectReference))); - this.sacrificeCost = new mage.abilities.costs.common.SacrificeTargetCost(filter); + this.sacrificeCost = new SacrificeTargetCost(filter); } private DireBlunderbussSacrificeCost(final DireBlunderbussSacrificeCost cost) { @@ -152,7 +155,7 @@ class DireBlunderbussSacrificeCost extends UseAttachedCost implements SacrificeC } @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, mage.abilities.costs.Cost costToPay) { + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment == null) { return paid; 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/DisciplesOfTheInferno.java b/Mage.Sets/src/mage/cards/d/DisciplesOfTheInferno.java deleted file mode 100644 index 8344681452f..00000000000 --- a/Mage.Sets/src/mage/cards/d/DisciplesOfTheInferno.java +++ /dev/null @@ -1,113 +0,0 @@ -package mage.cards.d; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.keyword.ProwessAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.util.CardUtil; - -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class DisciplesOfTheInferno extends CardImpl { - - public DisciplesOfTheInferno(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.MONK); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setRed(true); - this.nightCard = true; - - // Prowess - this.addAbility(new ProwessAbility()); - - // If a noncreature source you control would deal damage to a creature, battle, or opponent, it deals that much damage plus 2 instead. - this.addAbility(new SimpleStaticAbility(new DisciplesOfTheInfernoEffect())); - } - - private DisciplesOfTheInferno(final DisciplesOfTheInferno card) { - super(card); - } - - @Override - public DisciplesOfTheInferno copy() { - return new DisciplesOfTheInferno(this); - } -} - -class DisciplesOfTheInfernoEffect extends ReplacementEffectImpl { - - DisciplesOfTheInfernoEffect() { - super(Duration.WhileOnBattlefield, Outcome.Damage); - this.staticText = "if a noncreature source you control would deal damage " + - "to a creature, battle, or opponent, it deals that much damage plus 2 instead"; - } - - private DisciplesOfTheInfernoEffect(final DisciplesOfTheInfernoEffect effect) { - super(effect); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(CardUtil.overflowInc(event.getAmount(), 2)); - return false; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - switch (event.getType()) { - case DAMAGE_PERMANENT: - case DAMAGE_PLAYER: - return true; - } - return false; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null || !controller.hasOpponent(event.getTargetId(), game) - && Optional - .of(event.getTargetId()) - .map(game::getPermanent) - .filter(Objects::nonNull) - .map(permanent -> !permanent.isCreature(game) && !permanent.isBattle(game)) - .orElse(true)) { - return false; - } - MageObject sourceObject; - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (sourcePermanent == null) { - sourceObject = game.getObject(event.getSourceId()); - } else { - sourceObject = sourcePermanent; - } - return sourceObject != null - && !sourceObject.isCreature(game) - && event.getAmount() > 0; - } - - @Override - public DisciplesOfTheInfernoEffect copy() { - return new DisciplesOfTheInfernoEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/d/DispellingExhale.java b/Mage.Sets/src/mage/cards/d/DispellingExhale.java index 074f5564df7..6d2ba706f5e 100644 --- a/Mage.Sets/src/mage/cards/d/DispellingExhale.java +++ b/Mage.Sets/src/mage/cards/d/DispellingExhale.java @@ -4,9 +4,10 @@ import mage.abilities.condition.common.BeheldDragonCondition; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.CounterUnlessPaysEffect; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.TargetSpell; @@ -21,7 +22,7 @@ public final class DispellingExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}"); // As an additional cost to cast this spell, you may behold a Dragon. - this.addAbility(new BeholdDragonAbility()); + this.addAbility(new BeholdAbility(BeholdType.DRAGON)); // Counter target spell unless its controller pays {2}. If a Dragon was beheld, counter that spell unless its controller pays {4} instead. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( diff --git a/Mage.Sets/src/mage/cards/d/DisruptorOfCurrents.java b/Mage.Sets/src/mage/cards/d/DisruptorOfCurrents.java new file mode 100644 index 00000000000..06483b00a01 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DisruptorOfCurrents.java @@ -0,0 +1,59 @@ +package mage.cards.d; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.TargetPermanent; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class DisruptorOfCurrents extends CardImpl { + + private static final FilterPermanent filter = new FilterNonlandPermanent("other target nonland permanent"); + + static { + filter.add(AnotherPredicate.instance); + } + + public DisruptorOfCurrents(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // When this creature enters, return up to one other target nonland permanent to its owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.addAbility(ability); + } + + private DisruptorOfCurrents(final DisruptorOfCurrents card) { + super(card); + } + + @Override + public DisruptorOfCurrents copy() { + return new DisruptorOfCurrents(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DistractingGeist.java b/Mage.Sets/src/mage/cards/d/DistractingGeist.java index 8baef404c8a..9abe93864d9 100644 --- a/Mage.Sets/src/mage/cards/d/DistractingGeist.java +++ b/Mage.Sets/src/mage/cards/d/DistractingGeist.java @@ -2,7 +2,10 @@ package mage.cards.d; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.DisturbAbility; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardSetInfo; @@ -44,21 +47,23 @@ public final class DistractingGeist extends TransformingDoubleFacedCard { ability.addTarget(new TargetPermanent(filter)); this.getLeftHalfCard().addAbility(ability); - // Disturb {4}{W} - this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{4}{W}")); // Clever Distraction // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getRightHalfCard().getSpellAbility().addTarget(auraTarget); - this.getRightHalfCard().getSpellAbility().addEffect(new mage.abilities.effects.common.AttachEffect(Outcome.BoostCreature)); + this.getRightHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); this.getRightHalfCard().addAbility(new EnchantAbility(auraTarget)); + // Disturb {4}{W} + // needs to be added after right half has spell ability target set + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{4}{W}")); + // Enchanted creature has "Whenever this creature attacks, tap target creature defending player controls." Ability ability2 = new AttacksTriggeredAbility(new TapTargetEffect()).setTriggerPhrase("Whenever this creature attacks, "); ability2.addTarget(new TargetPermanent(filter)); - this.getRightHalfCard().addAbility(new mage.abilities.common.SimpleStaticAbility(new mage.abilities.effects.common.continuous.GainAbilityAttachedEffect(ability2, AttachmentType.AURA))); + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect(ability2, AttachmentType.AURA))); // If Clever Distracting would be put into a graveyard from anywhere, exile it instead. this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); 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/DoranBesiegedByTime.java b/Mage.Sets/src/mage/cards/d/DoranBesiegedByTime.java new file mode 100644 index 00000000000..b180e9a3438 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DoranBesiegedByTime.java @@ -0,0 +1,131 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ToughnessGreaterThanPowerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DoranBesiegedByTime extends CardImpl { + + private static final FilterCard filter = new FilterCard("each creature spell you cast with toughness greater than its power"); + + static { + filter.add(ToughnessGreaterThanPowerPredicate.instance); + } + + public DoranBesiegedByTime(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{B}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.TREEFOLK); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(0); + this.toughness = new MageInt(5); + + // Each creature spell you cast with toughness greater than its power costs {1} less to cast. + this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever a creature you control attacks or blocks, it gets +X/+X until end of turn, where X is the difference between its power and toughness. + this.addAbility(new DoranBesiegedByTimeTriggeredAbility()); + } + + private DoranBesiegedByTime(final DoranBesiegedByTime card) { + super(card); + } + + @Override + public DoranBesiegedByTime copy() { + return new DoranBesiegedByTime(this); + } +} + +class DoranBesiegedByTimeTriggeredAbility extends TriggeredAbilityImpl { + + DoranBesiegedByTimeTriggeredAbility() { + super(Zone.BATTLEFIELD, new DoranBesiegedByTimeEffect()); + setTriggerPhrase("Whenever a creature you control attacks or blocks, "); + } + + private DoranBesiegedByTimeTriggeredAbility(final DoranBesiegedByTimeTriggeredAbility ability) { + super(ability); + } + + @Override + public DoranBesiegedByTimeTriggeredAbility copy() { + return new DoranBesiegedByTimeTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ATTACKER_DECLARED + || event.getType() == GameEvent.EventType.CREATURE_BLOCKS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent; + switch (event.getType()) { + case ATTACKER_DECLARED: + permanent = game.getPermanent(event.getSourceId()); + break; + case CREATURE_BLOCKS: + permanent = game.getPermanent(event.getTargetId()); + break; + default: + return false; + } + if (permanent == null || !permanent.isControlledBy(getControllerId())) { + return false; + } + this.getEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; + } +} + +class DoranBesiegedByTimeEffect extends OneShotEffect { + + DoranBesiegedByTimeEffect() { + super(Outcome.Benefit); + staticText = "it gets +X/+X until end of turn, where X is the difference between its power and toughness"; + } + + private DoranBesiegedByTimeEffect(final DoranBesiegedByTimeEffect effect) { + super(effect); + } + + @Override + public DoranBesiegedByTimeEffect copy() { + return new DoranBesiegedByTimeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + int diff = Math.abs(permanent.getToughness().getValue() - permanent.getPower().getValue()); + if (diff < 1) { + return false; + } + game.addEffect(new BoostTargetEffect(diff, diff).setTargetPointer(new FixedTarget(permanent, game)), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/d/DormantGrove.java b/Mage.Sets/src/mage/cards/d/DormantGrove.java index 17988a2eea7..b0bbfe62961 100644 --- a/Mage.Sets/src/mage/cards/d/DormantGrove.java +++ b/Mage.Sets/src/mage/cards/d/DormantGrove.java @@ -1,10 +1,13 @@ package mage.cards.d; import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; 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.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.VigilanceAbility; import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; @@ -12,6 +15,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; @@ -46,12 +50,12 @@ public final class DormantGrove extends TransformingDoubleFacedCard { this.getRightHalfCard().setPT(3, 6); // Vigilance - this.getRightHalfCard().addAbility(mage.abilities.keyword.VigilanceAbility.getInstance()); + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); // Other creatures you control have vigilance. - this.getRightHalfCard().addAbility(new mage.abilities.common.SimpleStaticAbility(new mage.abilities.effects.common.continuous.GainAbilityControlledEffect( - mage.abilities.keyword.VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, - mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES, true + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_PERMANENT_CREATURES, true ))); } diff --git a/Mage.Sets/src/mage/cards/d/DorotheaVengefulVictim.java b/Mage.Sets/src/mage/cards/d/DorotheaVengefulVictim.java index dd2319d0ce4..2987e7c54e2 100644 --- a/Mage.Sets/src/mage/cards/d/DorotheaVengefulVictim.java +++ b/Mage.Sets/src/mage/cards/d/DorotheaVengefulVictim.java @@ -1,11 +1,15 @@ package mage.cards.d; +import mage.abilities.Ability; import mage.abilities.common.AttacksOrBlocksTriggeredAbility; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.SacrificeTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.DisturbAbility; import mage.abilities.keyword.EnchantAbility; @@ -13,8 +17,12 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.token.DorotheasRetributionSpiritToken; +import mage.game.permanent.token.Token; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTargets; import java.util.UUID; @@ -40,8 +48,6 @@ public final class DorotheaVengefulVictim extends TransformingDoubleFacedCard { new AtTheEndOfCombatDelayedTriggeredAbility(new SacrificeSourceEffect()) ).setText("sacrifice it at end of combat"), false)); - // Disturb {1}{W}{U} - this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{1}{W}{U}")); // Dorothea's Retribution // Enchant creature @@ -50,9 +56,13 @@ public final class DorotheaVengefulVictim extends TransformingDoubleFacedCard { this.getRightHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); this.getRightHalfCard().addAbility(new EnchantAbility(auraTarget)); + // Disturb {1}{W}{U} + // needs to be added after right half has spell ability target set + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{1}{W}{U}")); + // Enchanted creature has "Whenever this creature attacks, create a 4/4 white Spirit creature token with flying that's tapped and attacking. Sacrifice that token at end of combat." this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( - new mage.abilities.common.AttacksTriggeredAbility(new DorotheasRetributionEffect()).setTriggerPhrase("Whenever this creature attacks, "), + new AttacksTriggeredAbility(new DorotheasRetributionEffect()).setTriggerPhrase("Whenever this creature attacks, "), AttachmentType.AURA ))); @@ -70,7 +80,7 @@ public final class DorotheaVengefulVictim extends TransformingDoubleFacedCard { } } -class DorotheasRetributionEffect extends mage.abilities.effects.OneShotEffect { +class DorotheasRetributionEffect extends OneShotEffect { DorotheasRetributionEffect() { super(Outcome.Benefit); @@ -87,12 +97,12 @@ class DorotheasRetributionEffect extends mage.abilities.effects.OneShotEffect { } @Override - public boolean apply(mage.game.Game game, mage.abilities.Ability source) { - mage.game.permanent.token.Token token = new mage.game.permanent.token.DorotheasRetributionSpiritToken(); + public boolean apply(Game game, Ability source) { + Token token = new DorotheasRetributionSpiritToken(); token.putOntoBattlefield(1, game, source, source.getControllerId(), true, true); game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility( - new mage.abilities.effects.common.SacrificeTargetEffect() - .setTargetPointer(new mage.target.targetpointer.FixedTargets(token, game)) + new SacrificeTargetEffect() + .setTargetPointer(new FixedTargets(token, game)) .setText("sacrifice that token") ), source); return true; 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/DowsingDagger.java b/Mage.Sets/src/mage/cards/d/DowsingDagger.java index e1325e4438f..6f3ff63dd5f 100644 --- a/Mage.Sets/src/mage/cards/d/DowsingDagger.java +++ b/Mage.Sets/src/mage/cards/d/DowsingDagger.java @@ -3,10 +3,15 @@ package mage.cards.d; import mage.abilities.Ability; import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.CreateTokenTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.keyword.EquipAbility; +import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; @@ -35,17 +40,17 @@ public final class DowsingDagger extends TransformingDoubleFacedCard { this.getLeftHalfCard().addAbility(ability); // Equipped creature gets +2/+1. - this.getLeftHalfCard().addAbility(new mage.abilities.common.SimpleStaticAbility(new BoostEquippedEffect(2, 1))); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 1))); // Whenever equipped creature deals combat damage to a player, you may transform Dowsing Dagger. this.getLeftHalfCard().addAbility(new DealsDamageToAPlayerAttachedTriggeredAbility(new TransformSourceEffect(), "equipped", true)); // Equip 2 - this.getLeftHalfCard().addAbility(new EquipAbility(Outcome.AddAbility, new mage.abilities.costs.mana.GenericManaCost(2), false)); + this.getLeftHalfCard().addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2), false)); // Lost Vale // T: Add three mana of any one color. - this.getRightHalfCard().addAbility(new mage.abilities.mana.SimpleManaAbility(new mage.abilities.effects.mana.AddManaOfAnyColorEffect(3), new mage.abilities.costs.common.TapSourceCost())); + this.getRightHalfCard().addAbility(new SimpleManaAbility(new AddManaOfAnyColorEffect(3), new TapSourceCost())); } private DowsingDagger(final DowsingDagger card) { diff --git a/Mage.Sets/src/mage/cards/d/DowsingDevice.java b/Mage.Sets/src/mage/cards/d/DowsingDevice.java index a8dcf8c9663..53025077ab2 100644 --- a/Mage.Sets/src/mage/cards/d/DowsingDevice.java +++ b/Mage.Sets/src/mage/cards/d/DowsingDevice.java @@ -1,15 +1,21 @@ package mage.cards.d; import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; 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.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.hint.common.ArtifactYouControlHint; import mage.abilities.keyword.HasteAbility; +import mage.abilities.mana.RedManaAbility; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; @@ -17,6 +23,7 @@ import mage.constants.ComparisonType; import mage.constants.SubType; import mage.filter.StaticFilters; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -52,16 +59,16 @@ public final class DowsingDevice extends TransformingDoubleFacedCard { // Geode Grotto // {T}: Add {R}. - this.getRightHalfCard().addAbility(new mage.abilities.mana.RedManaAbility()); + this.getRightHalfCard().addAbility(new RedManaAbility()); // {2}{R}, {T}: Until end of turn, target creature gains haste and gets +X/+0, where X is the number of artifacts you control. Activate only as a sorcery. - Ability ability2 = new mage.abilities.common.ActivateAsSorceryActivatedAbility(new GainAbilityTargetEffect(HasteAbility.getInstance()) - .setText("Until end of turn, target creature gains haste"), new mage.abilities.costs.mana.ManaCostsImpl<>("{2}{R}")); - ability2.addCost(new mage.abilities.costs.common.TapSourceCost()); - ability2.addEffect(new mage.abilities.effects.common.continuous.BoostTargetEffect( - mage.abilities.dynamicvalue.common.ArtifactYouControlCount.instance, mage.abilities.dynamicvalue.common.StaticValue.get(0) + Ability ability2 = new ActivateAsSorceryActivatedAbility(new GainAbilityTargetEffect(HasteAbility.getInstance()) + .setText("Until end of turn, target creature gains haste"), new ManaCostsImpl<>("{2}{R}")); + ability2.addCost(new TapSourceCost()); + ability2.addEffect(new BoostTargetEffect( + ArtifactYouControlCount.instance, StaticValue.get(0) ).setText("and gets +X/+0, where X is the number of artifacts you control")); - ability2.addTarget(new mage.target.common.TargetCreaturePermanent()); + ability2.addTarget(new TargetCreaturePermanent()); this.getRightHalfCard().addAbility(ability2.addHint(ArtifactYouControlHint.instance)); } 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/DreamSeizer.java b/Mage.Sets/src/mage/cards/d/DreamSeizer.java new file mode 100644 index 00000000000..f4b9774f337 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DreamSeizer.java @@ -0,0 +1,47 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DreamSeizer extends CardImpl { + + public DreamSeizer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.FAERIE); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, you may blight 1. If you do, each opponent discards a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( + new DiscardEachPlayerEffect(TargetController.OPPONENT), new BlightCost(1) + ))); + } + + private DreamSeizer(final DreamSeizer card) { + super(card); + } + + @Override + public DreamSeizer copy() { + return new DreamSeizer(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/d/DundoolinWeaver.java b/Mage.Sets/src/mage/cards/d/DundoolinWeaver.java new file mode 100644 index 00000000000..568bf935675 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DundoolinWeaver.java @@ -0,0 +1,53 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.hint.common.CreaturesYouControlHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DundoolinWeaver extends CardImpl { + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterControlledCreaturePermanent("you control three or more creatures"), + ComparisonType.MORE_THAN, 2 + ); + + public DundoolinWeaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // When this creature enters, if you control three or more creatures, return target permanent card from your graveyard to your hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()).withInterveningIf(condition); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_PERMANENT)); + this.addAbility(ability.addHint(CreaturesYouControlHint.instance)); + } + + private DundoolinWeaver(final DundoolinWeaver card) { + super(card); + } + + @Override + public DundoolinWeaver copy() { + return new DundoolinWeaver(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java b/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java index 7ae652dd555..23b20194dae 100644 --- a/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java +++ b/Mage.Sets/src/mage/cards/d/DuskwatchRecruiter.java @@ -2,16 +2,19 @@ package mage.cards.d; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.cards.CardSetInfo; import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.PutCards; import mage.constants.SubType; import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureCard; import java.util.UUID; @@ -43,8 +46,8 @@ public final class DuskwatchRecruiter extends TransformingDoubleFacedCard { this.getRightHalfCard().setPT(3, 3); // Creature spells you cast cost {1} less to cast. - this.getRightHalfCard().addAbility(new mage.abilities.common.SimpleStaticAbility( - new mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect(new mage.filter.common.FilterCreatureCard("creature spells"), 1) + this.getRightHalfCard().addAbility(new SimpleStaticAbility( + new SpellsCostReductionControllerEffect(new FilterCreatureCard("creature spells"), 1) )); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Krallenhorde Howler. diff --git a/Mage.Sets/src/mage/cards/e/EarthenAlly.java b/Mage.Sets/src/mage/cards/e/EarthenAlly.java index e2e6715fc0b..76a915c7fc4 100644 --- a/Mage.Sets/src/mage/cards/e/EarthenAlly.java +++ b/Mage.Sets/src/mage/cards/e/EarthenAlly.java @@ -1,29 +1,22 @@ package mage.cards.e; import mage.MageInt; -import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.keyword.EarthbendTargetEffect; -import mage.abilities.hint.Hint; 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 mage.target.common.TargetControlledLandPermanent; import java.util.UUID; -import java.util.stream.Collectors; /** * @author TheElk801 @@ -41,8 +34,8 @@ public final class EarthenAlly extends CardImpl { // This creature gets +1/+0 for each color among Allies you control. this.addAbility(new SimpleStaticAbility(new BoostSourceEffect( - EarthenAllyValue.instance, StaticValue.get(0), Duration.WhileOnBattlefield - )).addHint(EarthenAllyHint.instance)); + ColorsAmongControlledPermanentsCount.ALLIES, StaticValue.get(0), Duration.WhileOnBattlefield + )).addHint(ColorsAmongControlledPermanentsCount.ALLIES.getHint())); // {2}{W}{U}{B}{R}{G}: Earthbend 5. Ability ability = new SimpleActivatedAbility( @@ -61,59 +54,3 @@ public final class EarthenAlly extends CardImpl { return new EarthenAlly(this); } } - -enum EarthenAllyValue implements DynamicValue { - instance; - private static final FilterPermanent filter = new FilterControlledPermanent(SubType.ALLY); - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - return getColors(game, sourceAbility).getColorCount(); - } - - static ObjectColor getColors(Game game, Ability sourceAbility) { - return game.getBattlefield() - .getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility, game) - .stream() - .map(permanent -> permanent.getColor(game)) - .collect(Collectors.reducing((c1, c2) -> c1.union(c2))) - .orElseGet(ObjectColor::new); - } - - @Override - public EarthenAllyValue copy() { - return this; - } - - @Override - public String getMessage() { - return "color among Allies you control"; - } - - @Override - public String toString() { - return "1"; - } -} - -enum EarthenAllyHint implements Hint { - instance; - - @Override - public String getText(Game game, Ability ability) { - ObjectColor color = EarthenAllyValue.getColors(game, ability); - return "Colors among Allies you control: " + color.getColorCount() + - (color.getColorCount() > 0 - ? color - .getColors() - .stream() - .map(ObjectColor::getDescription) - .collect(Collectors.joining(", ", " (", ")")) - : ""); - } - - @Override - public Hint copy() { - return 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/EclipsedFlamekin.java b/Mage.Sets/src/mage/cards/e/EclipsedFlamekin.java new file mode 100644 index 00000000000..7627d0b3380 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EclipsedFlamekin.java @@ -0,0 +1,53 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.PutCards; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EclipsedFlamekin extends CardImpl { + + private static final FilterCard filter = new FilterCard("Elemental, Island, or Mountain card"); + + static { + filter.add(Predicates.or( + SubType.ELEMENTAL.getPredicate(), + SubType.ISLAND.getPredicate(), + SubType.MOUNTAIN.getPredicate() + )); + } + + public EclipsedFlamekin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U/R}{U/R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // When this creature enters, look at the top four cards of your library. You may reveal an Elemental, Island, or Mountain card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. + this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( + 4, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM + ))); + } + + private EclipsedFlamekin(final EclipsedFlamekin card) { + super(card); + } + + @Override + public EclipsedFlamekin copy() { + return new EclipsedFlamekin(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EdeaPossessedSorceress.java b/Mage.Sets/src/mage/cards/e/EdeaPossessedSorceress.java new file mode 100644 index 00000000000..8bef10d72c1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EdeaPossessedSorceress.java @@ -0,0 +1,73 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.WardAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EdeaPossessedSorceress extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("creature you control but don't own"); + + static { + filter.add(TargetController.NOT_YOU.getOwnerPredicate()); + } + + public EdeaPossessedSorceress(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // Ward {2} + this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"))); + + // At the beginning of combat on your turn, gain control of target creature an opponent controls until end of turn. Untap that creature. It gains haste until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new GainControlTargetEffect(Duration.EndOfTurn)); + ability.addEffect(new UntapTargetEffect("Untap that creature")); + ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance()).withTargetDescription("It")); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.addAbility(ability); + + // Whenever a creature you control but don't own dies, return it to the battlefield under its owner's control and you draw a card. + ability = new DiesCreatureTriggeredAbility( + new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) + .setText("return it to the battlefield under its owner's control"), + false, filter, true + ); + ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and you")); + this.addAbility(ability); + } + + private EdeaPossessedSorceress(final EdeaPossessedSorceress card) { + super(card); + } + + @Override + public EdeaPossessedSorceress copy() { + return new EdeaPossessedSorceress(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java b/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java index 23af1fe5d14..bc9dcbfd858 100644 --- a/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java +++ b/Mage.Sets/src/mage/cards/e/ElbrusTheBindingBlade.java @@ -7,6 +7,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.IntimidateAbility; @@ -98,7 +99,7 @@ class ElbrusTheBindingBladeEffect extends OneShotEffect { class WithengarUnboundTriggeredAbility extends TriggeredAbilityImpl { WithengarUnboundTriggeredAbility() { - super(Zone.BATTLEFIELD, new mage.abilities.effects.common.counter.AddCountersSourceEffect(CounterType.P1P1.createInstance(13)), false); + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(13)), false); setTriggerPhrase("Whenever a player loses the game, "); } diff --git a/Mage.Sets/src/mage/cards/e/ElderAuntie.java b/Mage.Sets/src/mage/cards/e/ElderAuntie.java new file mode 100644 index 00000000000..71756eeb587 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ElderAuntie.java @@ -0,0 +1,39 @@ +package mage.cards.e; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.constants.SubType; +import mage.game.permanent.token.BlackAndRedGoblinToken; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class ElderAuntie extends CardImpl { + + public ElderAuntie(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When this creature enters, create a 1/1 black and red Goblin creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BlackAndRedGoblinToken()))); + } + + private ElderAuntie(final ElderAuntie card) { + super(card); + } + + @Override + public ElderAuntie copy() { + return new ElderAuntie(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EmbodimentOfFlame.java b/Mage.Sets/src/mage/cards/e/EmbodimentOfFlame.java deleted file mode 100644 index c98e0c8cdb0..00000000000 --- a/Mage.Sets/src/mage/cards/e/EmbodimentOfFlame.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.e; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SpellControlledDealsDamageTriggeredAbility; -import mage.abilities.costs.common.RemoveCountersSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -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 mage.counters.CounterType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class EmbodimentOfFlame extends CardImpl { - - public EmbodimentOfFlame(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ELEMENTAL); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setRed(true); - this.nightCard = true; - - // Whenever a spell you control deals damage, put a flame counter on Embodiment of Flame. - this.addAbility(new SpellControlledDealsDamageTriggeredAbility(Zone.BATTLEFIELD, - new AddCountersSourceEffect(CounterType.FLAME.createInstance()), - StaticFilters.FILTER_SPELL, false - )); - - // {1}, Remove a flame counter from Embodiment of Flame: Exile the top card of your library. You may play that card this turn. - Ability ability = new SimpleActivatedAbility( - new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), - new GenericManaCost(1) - ); - ability.addCost(new RemoveCountersSourceCost(CounterType.FLAME.createInstance())); - this.addAbility(ability); - } - - private EmbodimentOfFlame(final EmbodimentOfFlame card) { - super(card); - } - - @Override - public EmbodimentOfFlame copy() { - return new EmbodimentOfFlame(this); - } -} diff --git a/Mage.Sets/src/mage/cards/e/EnragedFlamecaster.java b/Mage.Sets/src/mage/cards/e/EnragedFlamecaster.java new file mode 100644 index 00000000000..1a6d5bc038a --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EnragedFlamecaster.java @@ -0,0 +1,47 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EnragedFlamecaster extends CardImpl { + + public EnragedFlamecaster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.SORCERER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // Whenever you cast a spell with mana value 4 or greater, this creature deals 2 damage to each opponent. + this.addAbility(new SpellCastControllerTriggeredAbility( + new DamagePlayersEffect(2, TargetController.OPPONENT), + StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false + )); + } + + private EnragedFlamecaster(final EnragedFlamecaster card) { + super(card); + } + + @Override + public EnragedFlamecaster copy() { + return new EnragedFlamecaster(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/EpharaEverSheltering.java b/Mage.Sets/src/mage/cards/e/EpharaEverSheltering.java deleted file mode 100644 index 24431e2dee6..00000000000 --- a/Mage.Sets/src/mage/cards/e/EpharaEverSheltering.java +++ /dev/null @@ -1,81 +0,0 @@ -package mage.cards.e; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -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.ComparisonType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledEnchantmentPermanent; -import mage.filter.predicate.mageobject.AnotherPredicate; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class EpharaEverSheltering extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledEnchantmentPermanent("another enchantment"); - - static { - filter.add(AnotherPredicate.instance); - } - - private static final Condition condition = new PermanentsOnTheBattlefieldCondition( - filter, ComparisonType.MORE_THAN, 2, true - ); - private static final Hint hint = new ValueHint( - "Other enchantments you control", new PermanentsOnBattlefieldCount(filter) - ); - - public EpharaEverSheltering(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GOD); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setWhite(true); - this.color.setBlue(true); - this.nightCard = true; - - // Ephara, Ever-Sheltering has lifelink and indestructible as long as you control at least three other enchantments. - Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( - new GainAbilitySourceEffect(LifelinkAbility.getInstance()), - condition, "{this} has lifelink" - )); - ability.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect( - IndestructibleAbility.getInstance()), condition, - "and indestructible as long as you control at least three other enchantments" - )); - this.addAbility(ability.addHint(hint)); - - // Whenever another enchantment you control enters, draw a card. - this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new DrawCardSourceControllerEffect(1), filter)); - } - - private EpharaEverSheltering(final EpharaEverSheltering card) { - super(card); - } - - @Override - public EpharaEverSheltering copy() { - return new EpharaEverSheltering(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/EtchingOfKumano.java b/Mage.Sets/src/mage/cards/e/EtchingOfKumano.java deleted file mode 100644 index 8e28b53447d..00000000000 --- a/Mage.Sets/src/mage/cards/e/EtchingOfKumano.java +++ /dev/null @@ -1,88 +0,0 @@ -package mage.cards.e; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.constants.*; -import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; -import mage.watchers.common.DamagedByControlledWatcher; - -/** - * - * @author weirddan455 - */ -public final class EtchingOfKumano extends CardImpl { - - public EtchingOfKumano(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SHAMAN); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setRed(true); - this.nightCard = true; - - // Haste - this.addAbility(HasteAbility.getInstance()); - - // If a creature dealt damage this turn by a source you controlled would die, exile it instead. - this.addAbility(new SimpleStaticAbility(new EtchingOfKumanoReplacementEffect()), new DamagedByControlledWatcher()); - } - - private EtchingOfKumano(final EtchingOfKumano card) { - super(card); - } - - @Override - public EtchingOfKumano copy() { - return new EtchingOfKumano(this); - } -} - -class EtchingOfKumanoReplacementEffect extends ReplacementEffectImpl { - - EtchingOfKumanoReplacementEffect() { - super(Duration.WhileOnBattlefield, Outcome.Exile); - this.staticText = "If a creature dealt damage this turn by a source you controlled would die, exile it instead"; - } - - private EtchingOfKumanoReplacementEffect(final EtchingOfKumanoReplacementEffect effect) { - super(effect); - } - - @Override - public EtchingOfKumanoReplacementEffect copy() { - return new EtchingOfKumanoReplacementEffect(this); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - ((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) { - ZoneChangeEvent zce = (ZoneChangeEvent) event; - if (zce.isDiesEvent()) { - DamagedByControlledWatcher watcher = game.getState().getWatcher(DamagedByControlledWatcher.class, source.getControllerId()); - if (watcher != null) { - return watcher.wasDamaged(zce.getTarget(), game); - } - } - return false; - } -} 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/ExplosiveProdigy.java b/Mage.Sets/src/mage/cards/e/ExplosiveProdigy.java new file mode 100644 index 00000000000..0a7c9fe9af0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ExplosiveProdigy.java @@ -0,0 +1,48 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ExplosiveProdigy extends CardImpl { + + public ExplosiveProdigy(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.SORCERER); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Vivid -- When this creature enters, it deals X damage to target creature an opponent controls, where X is the number of colors among permanents you control. + Ability ability = new EntersBattlefieldTriggeredAbility( + new DamageTargetEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS) + .setText("it deals X damage to target creature an opponent controls, " + + "where X is the number of colors among permanents you control") + ); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.addAbility(ability.setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private ExplosiveProdigy(final ExplosiveProdigy card) { + super(card); + } + + @Override + public ExplosiveProdigy copy() { + return new ExplosiveProdigy(this); + } +} 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/FableOfTheMirrorBreaker.java b/Mage.Sets/src/mage/cards/f/FableOfTheMirrorBreaker.java index d2777c8eba9..a1eb74364d7 100644 --- a/Mage.Sets/src/mage/cards/f/FableOfTheMirrorBreaker.java +++ b/Mage.Sets/src/mage/cards/f/FableOfTheMirrorBreaker.java @@ -1,45 +1,74 @@ package mage.cards.f; +import mage.abilities.Ability; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.discard.DiscardAndDrawThatManyEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; 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.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; import mage.game.permanent.token.FableOfTheMirrorBreakerToken; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** * @author TheElk801 */ -public final class FableOfTheMirrorBreaker extends CardImpl { +public final class FableOfTheMirrorBreaker extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("another nonlegendary creature you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + } public FableOfTheMirrorBreaker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.r.ReflectionOfKikiJiki.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{R}", + "Reflection of Kiki-Jiki", + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.GOBLIN, SubType.SHAMAN}, "R" + ); + // Fable of the Mirror-Breaker // (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 — Create a 2/2 red Goblin Shaman creature token with "Whenever this creature attacks, create a Treasure token." - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new CreateTokenEffect(new FableOfTheMirrorBreakerToken())); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new CreateTokenEffect(new FableOfTheMirrorBreakerToken())); // II — You may discard up to two cards. If you do, draw that many cards. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new DiscardAndDrawThatManyEffect(2) + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new DiscardAndDrawThatManyEffect(2) .setText("you may discard up to two cards. If you do, draw that many cards")); // 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); + + // Reflection of Kiki-Jiki + this.getRightHalfCard().setPT(2, 2); + + // {1}, {T}: Create a token that's a copy of another target nonlegendary creature you control, except it has haste. Sacrifice it at the beginning of the next end step. + Ability ability = new SimpleActivatedAbility(new ReflectionOfKikiJikiEffect(), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetPermanent(filter)); + this.getRightHalfCard().addAbility(ability); } private FableOfTheMirrorBreaker(final FableOfTheMirrorBreaker card) { @@ -51,3 +80,35 @@ public final class FableOfTheMirrorBreaker extends CardImpl { return new FableOfTheMirrorBreaker(this); } } + +class ReflectionOfKikiJikiEffect extends OneShotEffect { + + ReflectionOfKikiJikiEffect() { + super(Outcome.Benefit); + staticText = "create a token that's a copy of another target nonlegendary creature you control, " + + "except it has haste. Sacrifice it at the beginning of the next end step"; + } + + private ReflectionOfKikiJikiEffect(final ReflectionOfKikiJikiEffect effect) { + super(effect); + } + + @Override + public ReflectionOfKikiJikiEffect copy() { + return new ReflectionOfKikiJikiEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); + if (permanent == null) { + return false; + } + + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, true); + effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); + effect.apply(game, source); + effect.sacrificeTokensCreatedAtNextEndStep(game, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FaeburrowElder.java b/Mage.Sets/src/mage/cards/f/FaeburrowElder.java index 4719ae68424..2beb94fb902 100644 --- a/Mage.Sets/src/mage/cards/f/FaeburrowElder.java +++ b/Mage.Sets/src/mage/cards/f/FaeburrowElder.java @@ -1,25 +1,16 @@ package mage.cards.f; 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.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.effects.mana.ManaEffect; import mage.abilities.keyword.VigilanceAbility; -import mage.abilities.mana.SimpleManaAbility; +import mage.abilities.mana.AddEachControlledColorManaAbility; 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 mage.game.Game; -import mage.game.permanent.Permanent; import java.util.UUID; @@ -41,11 +32,13 @@ public final class FaeburrowElder extends CardImpl { // Faeburrow Elder gets +1/+1 for each color among permanents you control. this.addAbility(new SimpleStaticAbility(new BoostSourceEffect( - FaeburrowElderValue.instance, FaeburrowElderValue.instance, Duration.WhileOnBattlefield + ColorsAmongControlledPermanentsCount.ALL_PERMANENTS, + ColorsAmongControlledPermanentsCount.ALL_PERMANENTS, + Duration.WhileOnBattlefield ))); // {T}: For each color among permanents you control, add one mana of that color. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new FaeburrowElderManaEffect(), new TapSourceCost())); + this.addAbility(new AddEachControlledColorManaAbility()); } private FaeburrowElder(final FaeburrowElder card) { @@ -57,76 +50,3 @@ public final class FaeburrowElder extends CardImpl { return new FaeburrowElder(this); } } - -enum FaeburrowElderValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - ObjectColor color = new ObjectColor(""); - game.getBattlefield() - .getAllActivePermanents(sourceAbility.getControllerId()) - .stream() - .map(permanent -> permanent.getColor(game)) - .forEach(color::addColor); - return color.getColorCount(); - } - - @Override - public FaeburrowElderValue copy() { - return instance; - } - - @Override - public String toString() { - return "1"; - } - - @Override - public String getMessage() { - return "color among permanents you control"; - } -} - -class FaeburrowElderManaEffect extends ManaEffect { - - FaeburrowElderManaEffect() { - super(); - staticText = "For each color among permanents you control, add one mana of that color"; - } - - private FaeburrowElderManaEffect(final FaeburrowElderManaEffect effect) { - super(effect); - } - - @Override - public FaeburrowElderManaEffect copy() { - return new FaeburrowElderManaEffect(this); - } - - @Override - public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); - if (game == null) { - return mana; - } - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) { - if (mana.getBlack() == 0 && permanent.getColor(game).isBlack()) { - mana.increaseBlack(); - } - if (mana.getBlue() == 0 && permanent.getColor(game).isBlue()) { - mana.increaseBlue(); - } - if (mana.getRed() == 0 && permanent.getColor(game).isRed()) { - mana.increaseRed(); - } - if (mana.getGreen() == 0 && permanent.getColor(game).isGreen()) { - mana.increaseGreen(); - } - if (mana.getWhite() == 0 && permanent.getColor(game).isWhite()) { - mana.increaseWhite(); - } - } - return mana; - } -} diff --git a/Mage.Sets/src/mage/cards/f/FangbladeBrigand.java b/Mage.Sets/src/mage/cards/f/FangbladeBrigand.java index e5f33e35fa3..4ed2b5a0af4 100644 --- a/Mage.Sets/src/mage/cards/f/FangbladeBrigand.java +++ b/Mage.Sets/src/mage/cards/f/FangbladeBrigand.java @@ -1,15 +1,16 @@ package mage.cards.f; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.keyword.DayboundAbility; import mage.abilities.keyword.FirstStrikeAbility; -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; @@ -19,16 +20,17 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class FangbladeBrigand extends CardImpl { +public final class FangbladeBrigand extends TransformingDoubleFacedCard { public FangbladeBrigand(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}", + "Fangblade Eviscerator", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.f.FangbladeEviscerator.class; + // Fangblade Brigand + this.getLeftHalfCard().setPT(3, 4); // {1}{R}: Fangblade Brigand gets +1/+0 and gains first strike until end of turn. Ability ability = new SimpleActivatedAbility(new BoostSourceEffect( @@ -37,10 +39,30 @@ public final class FangbladeBrigand extends CardImpl { ability.addEffect(new GainAbilitySourceEffect( FirstStrikeAbility.getInstance(), Duration.EndOfTurn ).setText("and gains first strike until end of turn")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Fangblade Eviscerator + this.getRightHalfCard().setPT(4, 5); + + // {1}{R}: Fangblade Eviscerator gets +1/+0 and gains first strike until end of turn. + ability = new SimpleActivatedAbility(new BoostSourceEffect( + 1, 0, Duration.EndOfTurn + ).setText("{this} gets +1/+0"), new ManaCostsImpl<>("{1}{R}")); + ability.addEffect(new GainAbilitySourceEffect( + FirstStrikeAbility.getInstance(), Duration.EndOfTurn + ).setText("and gains first strike until end of turn")); + this.getRightHalfCard().addAbility(ability); + + // {4}{R}: Creatures you control get +2/+0 until end of turn. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new BoostControlledEffect( + 2, 0, Duration.EndOfTurn + ), new ManaCostsImpl<>("{4}{R}"))); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private FangbladeBrigand(final FangbladeBrigand card) { diff --git a/Mage.Sets/src/mage/cards/f/FangbladeEviscerator.java b/Mage.Sets/src/mage/cards/f/FangbladeEviscerator.java deleted file mode 100644 index b9c7a4dabec..00000000000 --- a/Mage.Sets/src/mage/cards/f/FangbladeEviscerator.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.keyword.FirstStrikeAbility; -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 java.util.UUID; - -/** - * @author TheElk801 - */ -public final class FangbladeEviscerator extends CardImpl { - - public FangbladeEviscerator(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(5); - this.color.setRed(true); - this.nightCard = true; - - // {1}{R}: Fangblade Eviscerator gets +1/+0 and gains first strike until end of turn. - Ability ability = new SimpleActivatedAbility(new BoostSourceEffect( - 1, 0, Duration.EndOfTurn - ).setText("{this} gets +1/+0"), new ManaCostsImpl<>("{1}{R}")); - ability.addEffect(new GainAbilitySourceEffect( - FirstStrikeAbility.getInstance(), Duration.EndOfTurn - ).setText("and gains first strike until end of turn")); - this.addAbility(ability); - - // {4}{R}: Creatures you control get +2/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostControlledEffect( - 2, 0, Duration.EndOfTurn - ), new ManaCostsImpl<>("{4}{R}"))); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private FangbladeEviscerator(final FangbladeEviscerator card) { - super(card); - } - - @Override - public FangbladeEviscerator copy() { - return new FangbladeEviscerator(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/FearfulVillager.java b/Mage.Sets/src/mage/cards/f/FearfulVillager.java index 175c8feb31f..c54cbe8abbb 100644 --- a/Mage.Sets/src/mage/cards/f/FearfulVillager.java +++ b/Mage.Sets/src/mage/cards/f/FearfulVillager.java @@ -1,10 +1,10 @@ package mage.cards.f; -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 FearfulVillager extends CardImpl { +public final class FearfulVillager extends TransformingDoubleFacedCard { public FearfulVillager(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.WEREWOLF}, "{2}{R}", + "Fearsome Werewolf", + 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(3); - this.secondSideCardClazz = mage.cards.f.FearsomeWerewolf.class; + // Fearful Villager + 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()); + + // Fearsome Werewolf + this.getRightHalfCard().setPT(4, 3); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private FearfulVillager(final FearfulVillager card) { diff --git a/Mage.Sets/src/mage/cards/f/FearsomeWerewolf.java b/Mage.Sets/src/mage/cards/f/FearsomeWerewolf.java deleted file mode 100644 index 53a629eabc4..00000000000 --- a/Mage.Sets/src/mage/cards/f/FearsomeWerewolf.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.f; - -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 FearsomeWerewolf extends CardImpl { - - public FearsomeWerewolf(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(3); - this.color.setRed(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private FearsomeWerewolf(final FearsomeWerewolf card) { - super(card); - } - - @Override - public FearsomeWerewolf copy() { - return new FearsomeWerewolf(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/FlameChainMauler.java b/Mage.Sets/src/mage/cards/f/FlameChainMauler.java new file mode 100644 index 00000000000..82fd01d19f4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlameChainMauler.java @@ -0,0 +1,48 @@ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author muz + */ +public final class FlameChainMauler extends CardImpl { + + public FlameChainMauler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}{R}: This creature gets +1/+0 and gains menace until end of turn. + Ability ability = new SimpleActivatedAbility( + new BoostSourceEffect(1, 0, Duration.EndOfTurn).setText("{this} gets +1/+0"), + new ManaCostsImpl<>("{1}{R}") + ); + ability.addEffect(new GainAbilitySourceEffect(new MenaceAbility()).setText("and gains menace until end of turn")); + this.addAbility(ability); + } + + private FlameChainMauler(final FlameChainMauler card) { + super(card); + } + + @Override + public FlameChainMauler copy() { + return new FlameChainMauler(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlameChanneler.java b/Mage.Sets/src/mage/cards/f/FlameChanneler.java index 363d8c7c634..5f2e743ec30 100644 --- a/Mage.Sets/src/mage/cards/f/FlameChanneler.java +++ b/Mage.Sets/src/mage/cards/f/FlameChanneler.java @@ -1,14 +1,20 @@ package mage.cards.f; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellControlledDealsDamageTriggeredAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; 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.counters.CounterType; import mage.filter.StaticFilters; import java.util.UUID; @@ -16,22 +22,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class FlameChanneler extends CardImpl { +public final class FlameChanneler extends TransformingDoubleFacedCard { public FlameChanneler(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}", + "Embodiment of Flame", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL, SubType.WIZARD}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.e.EmbodimentOfFlame.class; + // Flame Channeler + this.getLeftHalfCard().setPT(2, 2); // When a spell you control deals damage, transform Flame Channeler. - this.addAbility(new TransformAbility()); - this.addAbility(new SpellControlledDealsDamageTriggeredAbility(Zone.BATTLEFIELD, + this.getLeftHalfCard().addAbility(new SpellControlledDealsDamageTriggeredAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), StaticFilters.FILTER_SPELL, false ).setTriggerPhrase("When a spell you control deals damage, ")); + + // Embodiment of Flame + this.getRightHalfCard().setPT(3, 3); + + // Whenever a spell you control deals damage, put a flame counter on Embodiment of Flame. + this.getRightHalfCard().addAbility(new SpellControlledDealsDamageTriggeredAbility(Zone.BATTLEFIELD, + new AddCountersSourceEffect(CounterType.FLAME.createInstance()), + StaticFilters.FILTER_SPELL, false + )); + + // {1}, Remove a flame counter from Embodiment of Flame: Exile the top card of your library. You may play that card this turn. + Ability ability = new SimpleActivatedAbility( + new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), + new GenericManaCost(1) + ); + ability.addCost(new RemoveCountersSourceCost(CounterType.FLAME.createInstance())); + this.getRightHalfCard().addAbility(ability); } private FlameChanneler(final FlameChanneler card) { diff --git a/Mage.Sets/src/mage/cards/f/Flamebraider.java b/Mage.Sets/src/mage/cards/f/Flamebraider.java new file mode 100644 index 00000000000..0181c544f28 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/Flamebraider.java @@ -0,0 +1,77 @@ +package mage.cards.f; + +import java.util.UUID; + +import mage.ConditionalMana; +import mage.MageInt; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.constants.SubType; +import mage.game.Game; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class Flamebraider extends CardImpl { + + public Flamebraider(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.BARD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {T}: Add two mana in any combination of colors. Spend this mana only to cast Elemental spells or activate abilities of Elemental sources. + this.addAbility(new ConditionalAnyColorManaAbility(2, new FlamebraiderManaBuilder())); + } + + private Flamebraider(final Flamebraider card) { + super(card); + } + + @Override + public Flamebraider copy() { + return new Flamebraider(this); + } +} + +class FlamebraiderManaBuilder extends ConditionalManaBuilder { + + @Override + public ConditionalMana build(Object... options) { + return new FlamebraiderConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to cast Elemental spells or activate abilities of Elemental sources"; + } +} + +class FlamebraiderConditionalMana extends ConditionalMana { + + public FlamebraiderConditionalMana(Mana mana) { + super(mana); + this.staticText = "Spend this mana only to cast Elemental spells or activate abilities of Elemental sources"; + addCondition(FlamebraiderManaCondition.instance); + } +} + +enum FlamebraiderManaCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + MageObject object = game.getObject(source); + return object != null && object.hasSubtype(SubType.ELEMENTAL, game); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlameheartWerewolf.java b/Mage.Sets/src/mage/cards/f/FlameheartWerewolf.java deleted file mode 100644 index 4da8cf33502..00000000000 --- a/Mage.Sets/src/mage/cards/f/FlameheartWerewolf.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.common.BlocksOrBlockedByCreatureSourceTriggeredAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.DamageTargetEffect; -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 FlameheartWerewolf extends CardImpl { - - public FlameheartWerewolf(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(2); - this.color.setRed(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Whenever Flameheart Werewolf blocks or becomes blocked by a creature, Flameheart Werewolf deals 2 damage to that creature. - this.addAbility(new BlocksOrBlockedByCreatureSourceTriggeredAbility(new DamageTargetEffect(2).withTargetDescription("that creature"))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Flameheart Werewolf. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private FlameheartWerewolf(final FlameheartWerewolf card) { - super(card); - } - - @Override - public FlameheartWerewolf copy() { - return new FlameheartWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/FlamekinGildweaver.java b/Mage.Sets/src/mage/cards/f/FlamekinGildweaver.java new file mode 100644 index 00000000000..41595eb2186 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlamekinGildweaver.java @@ -0,0 +1,43 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.TreasureToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FlamekinGildweaver extends CardImpl { + + public FlamekinGildweaver(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.SORCERER); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // When this creature enters, create a Treasure token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + } + + private FlamekinGildweaver(final FlamekinGildweaver card) { + super(card); + } + + @Override + public FlamekinGildweaver copy() { + return new FlamekinGildweaver(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlamewarBrashVeteran.java b/Mage.Sets/src/mage/cards/f/FlamewarBrashVeteran.java index 167a48fc486..345e693acc2 100644 --- a/Mage.Sets/src/mage/cards/f/FlamewarBrashVeteran.java +++ b/Mage.Sets/src/mage/cards/f/FlamewarBrashVeteran.java @@ -1,8 +1,8 @@ package mage.cards.f; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardHandCost; import mage.abilities.costs.common.SacrificeTargetCost; @@ -10,10 +10,11 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.LivingMetalAbility; +import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; +import mage.cards.*; import mage.constants.*; import mage.counters.CounterType; import mage.filter.common.FilterControlledArtifactPermanent; @@ -29,7 +30,7 @@ import java.util.stream.Collectors; /** * @author TheElk801 */ -public final class FlamewarBrashVeteran extends CardImpl { +public final class FlamewarBrashVeteran extends TransformingDoubleFacedCard { private static final FilterControlledPermanent filter = new FilterControlledArtifactPermanent("another artifact"); @@ -39,28 +40,46 @@ public final class FlamewarBrashVeteran extends CardImpl { } public FlamewarBrashVeteran(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{B}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{1}{B}{R}", + "Flamewar, Streetwise Operative", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "BR" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.f.FlamewarStreetwiseOperative.class; + // Flamewar, Brash Veteran + this.getLeftHalfCard().setPT(3, 2); // More Than Meets the Eye {B}{R} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{B}{R}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{B}{R}")); // Sacrifice another artifact: Put a +1/+1 counter on Flamewar and convert it. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new SacrificeTargetCost(filter) ); ability.addEffect(new TransformSourceEffect().setText("and convert it")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {1}, Discard your hand: Put all exiled cards you own with intel counters on them into your hand. ability = new SimpleActivatedAbility(new FlamewarBrashVeteranEffect(), new GenericManaCost(1)); ability.addCost(new DiscardHandCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Flamewar, Streetwise Operative + this.getRightHalfCard().setPT(2, 1); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Deathtouch + this.getRightHalfCard().addAbility(DeathtouchAbility.getInstance()); + + // Whenever Flamewar deals combat damage to a player, exile that many cards from the top of your library face down. Put an intel counter on each of them. Convert Flamewar. + Ability backAbility = new DealsCombatDamageToAPlayerTriggeredAbility(new FlamewarStreetwiseOperativeEffect(), false); + backAbility.addEffect(new TransformSourceEffect().setText("convert {this}")); + this.getRightHalfCard().addAbility(backAbility); } private FlamewarBrashVeteran(final FlamewarBrashVeteran card) { @@ -104,3 +123,38 @@ class FlamewarBrashVeteranEffect extends OneShotEffect { return !cards.isEmpty() && player.moveCards(cards, Zone.HAND, source, game); } } + +class FlamewarStreetwiseOperativeEffect extends OneShotEffect { + + FlamewarStreetwiseOperativeEffect() { + super(Outcome.Benefit); + staticText = "exile that many cards from the top of your library face down. " + + "Put an intel counter on each of them"; + } + + private FlamewarStreetwiseOperativeEffect(final FlamewarStreetwiseOperativeEffect effect) { + super(effect); + } + + @Override + public FlamewarStreetwiseOperativeEffect copy() { + return new FlamewarStreetwiseOperativeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + int damage = (Integer) getValue("damage"); + if (player == null || damage < 1) { + return false; + } + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, damage)); + player.moveCards(cards, Zone.EXILED, source, game); + cards.retainZone(Zone.EXILED, game); + cards.getCards(game).forEach(card -> { + card.setFaceDown(true, game); + card.addCounters(CounterType.INTEL.createInstance(), source, game); + }); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FlamewarStreetwiseOperative.java b/Mage.Sets/src/mage/cards/f/FlamewarStreetwiseOperative.java deleted file mode 100644 index 6541885896a..00000000000 --- a/Mage.Sets/src/mage/cards/f/FlamewarStreetwiseOperative.java +++ /dev/null @@ -1,96 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.DeathtouchAbility; -import mage.abilities.keyword.LivingMetalAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.constants.*; -import mage.counters.CounterType; -import mage.game.Game; -import mage.players.Player; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class FlamewarStreetwiseOperative extends CardImpl { - - public FlamewarStreetwiseOperative(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(1); - this.color.setRed(true); - this.color.setBlack(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Deathtouch - this.addAbility(DeathtouchAbility.getInstance()); - - // Whenever Flamewar deals combat damage to a player, exile that many cards from the top of your library face down. Put an intel counter on each of them. Convert Flamewar. - Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new FlamewarStreetwiseOperativeEffect(), false); - ability.addEffect(new TransformSourceEffect().setText("convert {this}")); - this.addAbility(ability); - } - - private FlamewarStreetwiseOperative(final FlamewarStreetwiseOperative card) { - super(card); - } - - @Override - public FlamewarStreetwiseOperative copy() { - return new FlamewarStreetwiseOperative(this); - } -} - -class FlamewarStreetwiseOperativeEffect extends OneShotEffect { - - FlamewarStreetwiseOperativeEffect() { - super(Outcome.Benefit); - staticText = "exile that many cards from the top of your library face down. " + - "Put an intel counter on each of them"; - } - - private FlamewarStreetwiseOperativeEffect(final FlamewarStreetwiseOperativeEffect effect) { - super(effect); - } - - @Override - public FlamewarStreetwiseOperativeEffect copy() { - return new FlamewarStreetwiseOperativeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - int damage = (Integer) getValue("damage"); - if (player == null || damage < 1) { - return false; - } - Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, damage)); - player.moveCards(cards, Zone.EXILED, source, game); - cards.retainZone(Zone.EXILED, game); - cards.getCards(game).stream().forEach(card -> { - card.setFaceDown(true, game); - card.addCounters(CounterType.INTEL.createInstance(), source, game); - }); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/f/FlockImpostor.java b/Mage.Sets/src/mage/cards/f/FlockImpostor.java new file mode 100644 index 00000000000..66e5acf465f --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FlockImpostor.java @@ -0,0 +1,54 @@ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.ChangelingAbility; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class FlockImpostor extends CardImpl { + + public FlockImpostor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, return up to one other target creature you control to its owner's hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); + this.addAbility(ability); + } + + private FlockImpostor(final FlockImpostor card) { + super(card); + } + + @Override + public FlockImpostor copy() { + return new FlockImpostor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FoggySwampVisions.java b/Mage.Sets/src/mage/cards/f/FoggySwampVisions.java index f1ad9b03694..72ac7cb4022 100644 --- a/Mage.Sets/src/mage/cards/f/FoggySwampVisions.java +++ b/Mage.Sets/src/mage/cards/f/FoggySwampVisions.java @@ -1,10 +1,12 @@ package mage.cards.f; import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.costs.common.WaterbendXCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.cards.*; import mage.constants.CardType; @@ -33,7 +35,10 @@ public final class FoggySwampVisions extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{B}"); // As an additional cost to cast this spell, waterbend {X}. - this.getSpellAbility().addCost(new WaterbendCost("{X}")); + this.getSpellAbility().addCost(new WaterbendXCost()); + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {X}") + ).setRuleAtTheTop(true)); // Exile X target creature cards from graveyards. For each creature card exiled this way, create a token that's a copy of it. At the beginning of your next end step, sacrifice those tokens. this.getSpellAbility().addEffect(new FoggySwampVisionsEffect()); diff --git a/Mage.Sets/src/mage/cards/f/ForebodingStatue.java b/Mage.Sets/src/mage/cards/f/ForebodingStatue.java index c9b454f25a3..a850e83d438 100644 --- a/Mage.Sets/src/mage/cards/f/ForebodingStatue.java +++ b/Mage.Sets/src/mage/cards/f/ForebodingStatue.java @@ -1,49 +1,57 @@ package mage.cards.f; -import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.UntapSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.mana.AnyColorManaAbility; -import mage.constants.SubType; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.TargetController; import mage.counters.CounterType; +import java.util.UUID; + /** * * @author weirddan455 */ -public final class ForebodingStatue extends CardImpl { +public final class ForebodingStatue extends TransformingDoubleFacedCard { public ForebodingStatue(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.CONSTRUCT}, "{3}", + "Forsaken Thresher", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.CONSTRUCT}, "" + ); - this.subtype.add(SubType.CONSTRUCT); - this.power = new MageInt(1); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.f.ForsakenThresher.class; + // Foreboding Statue + this.getLeftHalfCard().setPT(1, 2); // {T}: Add one mana of any color. Put an omen counter on Foreboding Statue. Ability ability = new AnyColorManaAbility(); ability.addEffect(new AddCountersSourceEffect(CounterType.OMEN.createInstance())); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of your end step, if there are three or more omen counters on Foreboding Statue, untap it, then transform it. - this.addAbility(new TransformAbility()); ability = new BeginningOfEndStepTriggeredAbility( TargetController.YOU, new UntapSourceEffect().setText("untap it,"), false, new SourceHasCounterCondition(CounterType.OMEN, 3) ); ability.addEffect(new TransformSourceEffect().setText("then transform it")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Forsaken Thresher + this.getRightHalfCard().setPT(5, 5); + + // At the beginning of your precombat main phase, add one mana of any color. + this.getRightHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility(new AddManaOfAnyColorEffect())); } private ForebodingStatue(final ForebodingStatue card) { 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/FrenziedTrapbreaker.java b/Mage.Sets/src/mage/cards/f/FrenziedTrapbreaker.java deleted file mode 100644 index 8da3b71319d..00000000000 --- a/Mage.Sets/src/mage/cards/f/FrenziedTrapbreaker.java +++ /dev/null @@ -1,67 +0,0 @@ -package mage.cards.f; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.SacrificeSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.DestroyTargetEffect; -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.FilterArtifactOrEnchantmentPermanent; -import mage.filter.predicate.permanent.DefendingPlayerControlsSourceAttackingPredicate; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class FrenziedTrapbreaker extends CardImpl { - - private static final FilterPermanent filter - = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment defending player controls"); - - static { - filter.add(DefendingPlayerControlsSourceAttackingPredicate.instance); - } - - public FrenziedTrapbreaker(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(3); - this.color.setGreen(true); - this.nightCard = true; - - // {1}, Sacrifice Frenzied Trapbreaker: Destroy target artifact or enchantment. - Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(1)); - ability.addCost(new SacrificeSourceCost()); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); - this.addAbility(ability); - - // Whenever Frenzied Trapbreaker attacks, destroy target artifact or enchantment defending player controls. - ability = new AttacksTriggeredAbility(new DestroyTargetEffect()); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private FrenziedTrapbreaker(final FrenziedTrapbreaker card) { - super(card); - } - - @Override - public FrenziedTrapbreaker copy() { - return new FrenziedTrapbreaker(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/GallantFowlknight.java b/Mage.Sets/src/mage/cards/g/GallantFowlknight.java new file mode 100644 index 00000000000..7415cddedb4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GallantFowlknight.java @@ -0,0 +1,51 @@ +package mage.cards.g; + +import java.util.UUID; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author muz + */ +public final class GallantFowlknight extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.KITHKIN, "Kithkin creatures"); + + public GallantFowlknight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // When this creature enters, creatures you control get +1/+0 until end of turn. Kithkin creatures you control also gain first strike until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new BoostControlledEffect(1, 0, Duration.EndOfTurn)); + ability.addEffect(new GainAbilityControlledEffect( + FirstStrikeAbility.getInstance(), Duration.EndOfTurn, + filter + ).setText("Kithkin creatures you control also gain first strike until end of turn")); + this.addAbility(ability); + } + + private GallantFowlknight(final GallantFowlknight card) { + super(card); + } + + @Override + public GallantFowlknight copy() { + return new GallantFowlknight(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GanglyStompling.java b/Mage.Sets/src/mage/cards/g/GanglyStompling.java new file mode 100644 index 00000000000..23dadd11a29 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GanglyStompling.java @@ -0,0 +1,40 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.keyword.ChangelingAbility; +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 GanglyStompling extends CardImpl { + + public GanglyStompling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + private GanglyStompling(final GanglyStompling card) { + super(card); + } + + @Override + public GanglyStompling copy() { + return new GanglyStompling(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GargantuanSlabhorn.java b/Mage.Sets/src/mage/cards/g/GargantuanSlabhorn.java deleted file mode 100644 index dd19a481a83..00000000000 --- a/Mage.Sets/src/mage/cards/g/GargantuanSlabhorn.java +++ /dev/null @@ -1,66 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.WardAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.TransformedPredicate; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GargantuanSlabhorn extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("transformed permanents"); - - static { - filter.add(TransformedPredicate.instance); - } - - public GargantuanSlabhorn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.BEAST); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setBlue(true); - this.color.setGreen(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Ward {2} - this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); - - // Other transformed permanents you control have trample and ward {2}. - Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter, true - )); - ability.addEffect(new GainAbilityControlledEffect( - new WardAbility(new GenericManaCost(2)), Duration.WhileOnBattlefield, filter, true - ).setText("and ward {2}")); - this.addAbility(ability); - } - - private GargantuanSlabhorn(final GargantuanSlabhorn card) { - super(card); - } - - @Override - public GargantuanSlabhorn copy() { - return new GargantuanSlabhorn(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java b/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java index 80580939181..b6d5a06f9a1 100644 --- a/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java +++ b/Mage.Sets/src/mage/cards/g/GarlandKnightOfCornelia.java @@ -1,16 +1,18 @@ package mage.cards.g; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutOnLibrarySourceEffect; import mage.abilities.effects.keyword.SurveilEffect; +import mage.abilities.keyword.FlyingAbility; 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.filter.StaticFilters; import mage.game.Game; @@ -22,29 +24,38 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class GarlandKnightOfCornelia extends CardImpl { +public final class GarlandKnightOfCornelia extends TransformingDoubleFacedCard { public GarlandKnightOfCornelia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.KNIGHT}, "{B}{R}", + "Chaos, the Endless", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "BR" + ); - this.secondSideCardClazz = mage.cards.c.ChaosTheEndless.class; - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.KNIGHT); - this.power = new MageInt(3); - this.toughness = new MageInt(2); + // Garland, Knight of Cornelia + this.getLeftHalfCard().setPT(3, 2); // Whenever you cast a noncreature spell, surveil 1. - this.addAbility(new SpellCastControllerTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( new SurveilEffect(1), StaticFilters.FILTER_SPELL_A_NON_CREATURE, false )); // {3}{B}{B}{R}{R}: Return this card from your graveyard to the battlefield transformed. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility( + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility( Zone.GRAVEYARD, new GarlandKnightOfCorneliaEffect(), new ManaCostsImpl<>("{3}{B}{B}{R}{R}") )); + + // Chaos, the Endless + this.getRightHalfCard().setPT(5, 5); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // When Chaos dies, put it on the bottom of its owner's library. + this.getRightHalfCard().addAbility(new DiesSourceTriggeredAbility(new PutOnLibrarySourceEffect( + false, "put it on the bottom of its owner's library" + ), false)); } private GarlandKnightOfCornelia(final GarlandKnightOfCornelia card) { 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/GarrukRelentless.java b/Mage.Sets/src/mage/cards/g/GarrukRelentless.java index b22ae5c3b93..c39b05e92e6 100644 --- a/Mage.Sets/src/mage/cards/g/GarrukRelentless.java +++ b/Mage.Sets/src/mage/cards/g/GarrukRelentless.java @@ -3,19 +3,29 @@ package mage.cards.g; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.StateTriggeredAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.permanent.token.WolfToken; +import mage.game.permanent.token.WolfTokenWithDeathtouch; +import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -23,29 +33,54 @@ import java.util.UUID; /** * @author nantuko */ -public final class GarrukRelentless extends CardImpl { +public final class GarrukRelentless extends TransformingDoubleFacedCard { + + private static final DynamicValue xValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE); public GarrukRelentless(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{G}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GARRUK); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.GARRUK}, "{3}{G}", + "Garruk, the Veil-Cursed", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.GARRUK}, "BG" + ); - this.secondSideCardClazz = mage.cards.g.GarrukTheVeilCursed.class; - - this.setStartingLoyalty(3); + // Garruk Relentless + this.getLeftHalfCard().setStartingLoyalty(3); // When Garruk Relentless has two or fewer loyalty counters on him, transform him. - this.addAbility(new TransformAbility()); - this.addAbility(new GarrukRelentlessStateTrigger()); + this.getLeftHalfCard().addAbility(new GarrukRelentlessStateTrigger()); - // 0: Garruk Relentless deals 3 damage to target creature. That creature deals damage equal to its power to him + // 0: Garruk Relentless deals 3 damage to target creature. That creature deals damage equal to its power to him. Ability ability = new LoyaltyAbility(new DamageTargetEffect(3), 0); ability.addEffect(new GarrukRelentlessDamageEffect()); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // 0: Create a 2/2 green Wolf creature token. - this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfToken()), 0)); + this.getLeftHalfCard().addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfToken()), 0)); + + // Garruk, the Veil-Cursed + // +1: Create a 1/1 black Wolf creature token with deathtouch. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfTokenWithDeathtouch()), 1)); + + // -1: Sacrifice a creature. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new DoIfCostPaid( + new SearchLibraryPutInHandEffect(new TargetCardInLibrary( + StaticFilters.FILTER_CARD_CREATURE_A + ), true), + null, + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE), + false + ), -1)); + + // -3: Creatures you control gain trample and get +X/+X until end of turn, where X is the number of creature cards in your graveyard. + Ability backAbility = new LoyaltyAbility(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("creatures you control gain trample"), -3); + backAbility.addEffect(new BoostControlledEffect( + xValue, xValue, Duration.EndOfTurn + ).setText("and get +X/+X until end of turn, where X is the number of creature cards in your graveyard")); + this.getRightHalfCard().addAbility(backAbility); } private GarrukRelentless(final GarrukRelentless card) { @@ -60,7 +95,7 @@ public final class GarrukRelentless extends CardImpl { class GarrukRelentlessStateTrigger extends StateTriggeredAbility { - public GarrukRelentlessStateTrigger() { + GarrukRelentlessStateTrigger() { super(Zone.BATTLEFIELD, new TransformSourceEffect()); } @@ -109,5 +144,4 @@ class GarrukRelentlessDamageEffect extends OneShotEffect { public GarrukRelentlessDamageEffect copy() { return new GarrukRelentlessDamageEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java b/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java deleted file mode 100644 index 4bd063d6f6f..00000000000 --- a/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java +++ /dev/null @@ -1,75 +0,0 @@ -package mage.cards.g; - -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -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 mage.game.permanent.token.WolfTokenWithDeathtouch; -import mage.target.common.TargetCardInLibrary; - -import java.util.UUID; - -/** - * @author nantuko - */ -public final class GarrukTheVeilCursed extends CardImpl { - - private static final DynamicValue xValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE); - - public GarrukTheVeilCursed(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GARRUK); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.color.setGreen(true); - this.color.setBlack(true); - - // +1 : Create a 1/1 black Wolf creature token with deathtouch. - this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WolfTokenWithDeathtouch()), 1)); - - // -1 : Sacrifice a creature. If you do, search your library for a creature card, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new LoyaltyAbility(new DoIfCostPaid( - new SearchLibraryPutInHandEffect(new TargetCardInLibrary( - StaticFilters.FILTER_CARD_CREATURE_A - ), true), - null, - new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE), - false - ), -1)); - - // -3 : Creatures you control gain trample and get +X/+X until end of turn, where X is the number of creature cards in your graveyard. - Ability ability = new LoyaltyAbility(new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURE - ).setText("creatures you control gain trample"), -3); - ability.addEffect(new BoostControlledEffect( - xValue, xValue, Duration.EndOfTurn - ).setText("and get +X/+X until end of turn, where X is the number of creature cards in your graveyard")); - this.addAbility(ability); - } - - private GarrukTheVeilCursed(final GarrukTheVeilCursed card) { - super(card); - } - - @Override - public GarrukTheVeilCursed copy() { - return new GarrukTheVeilCursed(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GatstafArsonists.java b/Mage.Sets/src/mage/cards/g/GatstafArsonists.java index 95ee3a5336b..52b343bda84 100644 --- a/Mage.Sets/src/mage/cards/g/GatstafArsonists.java +++ b/Mage.Sets/src/mage/cards/g/GatstafArsonists.java @@ -1,32 +1,42 @@ package mage.cards.g; -import java.util.UUID; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -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; +import mage.constants.SuperType; + +import java.util.UUID; /** - * * @author LevelX2 */ -public final class GatstafArsonists extends CardImpl { +public final class GatstafArsonists extends TransformingDoubleFacedCard { public GatstafArsonists(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(5); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{4}{R}", + "Gatstaf Ravagers", + new SuperType[]{}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.g.GatstafRavagers.class; + // Gatstaf Arsonists + this.getLeftHalfCard().setPT(5, 4); // At the beginning of each upkeep, if no spells were cast last turn, transform Gatstaf Arsonists. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Gatstaf Ravagers + this.getRightHalfCard().setPT(6, 5); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Gatstaf Ravagers. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private GatstafArsonists(final GatstafArsonists card) { diff --git a/Mage.Sets/src/mage/cards/g/GatstafHowler.java b/Mage.Sets/src/mage/cards/g/GatstafHowler.java deleted file mode 100644 index 3d98791e211..00000000000 --- a/Mage.Sets/src/mage/cards/g/GatstafHowler.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.keyword.IntimidateAbility; -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 GatstafHowler extends CardImpl { - - public GatstafHowler(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(3); - this.toughness = new MageInt(3); - - this.addAbility(IntimidateAbility.getInstance()); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Gatstaf Howler. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private GatstafHowler(final GatstafHowler card) { - super(card); - } - - @Override - public GatstafHowler copy() { - return new GatstafHowler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GatstafRavagers.java b/Mage.Sets/src/mage/cards/g/GatstafRavagers.java deleted file mode 100644 index fd2463f180d..00000000000 --- a/Mage.Sets/src/mage/cards/g/GatstafRavagers.java +++ /dev/null @@ -1,43 +0,0 @@ -package mage.cards.g; - -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 LevelX2 - */ -public final class GatstafRavagers extends CardImpl { - - public GatstafRavagers(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.setRed(true); - - 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 Gatstaf Ravagers. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private GatstafRavagers(final GatstafRavagers card) { - super(card); - } - - @Override - public GatstafRavagers copy() { - return new GatstafRavagers(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GatstafShepherd.java b/Mage.Sets/src/mage/cards/g/GatstafShepherd.java index c23426f4896..8e011cbfc28 100644 --- a/Mage.Sets/src/mage/cards/g/GatstafShepherd.java +++ b/Mage.Sets/src/mage/cards/g/GatstafShepherd.java @@ -1,10 +1,10 @@ package mage.cards.g; -import mage.MageInt; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.IntimidateAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,21 +13,29 @@ import java.util.UUID; /** * @author nantuko */ -public final class GatstafShepherd extends CardImpl { +public final class GatstafShepherd extends TransformingDoubleFacedCard { public GatstafShepherd(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}", + "Gatstaf Howler", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.g.GatstafHowler.class; - - this.power = new MageInt(2); - this.toughness = new MageInt(2); + // Gatstaf Shepherd + this.getLeftHalfCard().setPT(2, 2); // At the beginning of each upkeep, if no spells were cast last turn, transform Gatstaf Shepherd. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Gatstaf Howler + this.getRightHalfCard().setPT(3, 3); + + // Intimidate + this.getRightHalfCard().addAbility(IntimidateAbility.getInstance()); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Gatstaf Howler. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private GatstafShepherd(final GatstafShepherd card) { diff --git a/Mage.Sets/src/mage/cards/g/GeierReachBandit.java b/Mage.Sets/src/mage/cards/g/GeierReachBandit.java index 004e24bd542..2b2981a3248 100644 --- a/Mage.Sets/src/mage/cards/g/GeierReachBandit.java +++ b/Mage.Sets/src/mage/cards/g/GeierReachBandit.java @@ -1,37 +1,56 @@ package mage.cards.g; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import java.util.UUID; /** * @author LevelX2 */ -public final class GeierReachBandit extends CardImpl { +public final class GeierReachBandit extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterCreaturePermanent(SubType.WEREWOLF, "a Werewolf"); public GeierReachBandit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ROGUE); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ROGUE, SubType.WEREWOLF}, "{2}{R}", + "Vildin-Pack Alpha", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.v.VildinPackAlpha.class; + // Geier Reach Bandit + this.getLeftHalfCard().setPT(3, 2); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // At the beginning of each upkeep, if no spells were cast last turn, transform Geier Reach Bandit. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Vildin-Pack Alpha + this.getRightHalfCard().setPT(4, 3); + + // Whenever a Werewolf you control enters, you may transform it. + this.getRightHalfCard().addAbility(new EntersBattlefieldControlledTriggeredAbility( + Zone.BATTLEFIELD, new VildinPackAlphaEffect(), filter, + true, SetTargetPointer.PERMANENT + )); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Vildin-Pack Alpha. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private GeierReachBandit(final GeierReachBandit card) { @@ -42,4 +61,34 @@ public final class GeierReachBandit extends CardImpl { public GeierReachBandit copy() { return new GeierReachBandit(this); } -} \ No newline at end of file +} + +class VildinPackAlphaEffect extends OneShotEffect { + + VildinPackAlphaEffect() { + super(Outcome.Benefit); + this.staticText = "you may transform it"; + } + + private VildinPackAlphaEffect(final VildinPackAlphaEffect effect) { + super(effect); + } + + @Override + public VildinPackAlphaEffect copy() { + return new VildinPackAlphaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Permanent werewolf = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (werewolf != null) { + werewolf.transform(source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GeneralTazri.java b/Mage.Sets/src/mage/cards/g/GeneralTazri.java index a9d0c7dc56f..b8b479bfabb 100644 --- a/Mage.Sets/src/mage/cards/g/GeneralTazri.java +++ b/Mage.Sets/src/mage/cards/g/GeneralTazri.java @@ -1,33 +1,31 @@ - package mage.cards.g; -import java.util.UUID; import mage.MageInt; -import mage.ObjectColor; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class GeneralTazri extends CardImpl { private static final FilterCreatureCard filter = new FilterCreatureCard("an Ally creature card"); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent(SubType.ALLY, "Ally creatures"); static { filter.add(SubType.ALLY.getPredicate()); @@ -42,14 +40,20 @@ public final class GeneralTazri extends CardImpl { this.toughness = new MageInt(4); // When General Tazri enters the battlefield, you may search your library for an Ally creature card, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect( - new TargetCardInLibrary(filter), true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), true + )); + // {W}{U}{B}{R}{G}: Ally creatures you control get +X/+X until end of turn, where X is the number of colors among those creatures. - DynamicValue xValue = new GeneralTazriColorCount(); - BoostControlledEffect effect = new BoostControlledEffect(xValue, xValue, Duration.EndOfTurn, new FilterCreaturePermanent(SubType.ALLY, "Ally creatures"), false); this.addAbility(new SimpleActivatedAbility( - effect, - new ManaCostsImpl<>("{W}{U}{B}{R}{G}"))); + new BoostControlledEffect( + ColorsAmongControlledPermanentsCount.ALLIES, + ColorsAmongControlledPermanentsCount.ALLIES, + Duration.EndOfTurn, filter2, false + ).setText("Ally creatures you control get +X/+X until end of turn, " + + "where X is the number of colors among those creatures"), + new ManaCostsImpl<>("{W}{U}{B}{R}{G}") + ).addHint(ColorsAmongControlledPermanentsCount.ALLIES.getHint())); } @@ -62,51 +66,3 @@ public final class GeneralTazri extends CardImpl { return new GeneralTazri(this); } } - -class GeneralTazriColorCount implements DynamicValue { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); - - static { - filter.add(SubType.ALLY.getPredicate()); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - int count = 0; - boolean black = false; - boolean red = false; - boolean white = false; - boolean green = false; - boolean blue = false; - for (Permanent creature : game.getBattlefield().getAllActivePermanents(filter, sourceAbility.getControllerId(), game)) { - ObjectColor color = creature.getColor(game); - black |= color.isBlack(); - red |= color.isRed(); - white |= color.isWhite(); - green |= color.isGreen(); - blue |= color.isBlue(); - } - count += black ? 1 : 0; - count += red ? 1 : 0; - count += white ? 1 : 0; - count += green ? 1 : 0; - count += blue ? 1 : 0; - return count; - } - - @Override - public GeneralTazriColorCount copy() { - return new GeneralTazriColorCount(); - } - - @Override - public String getMessage() { - return "the number of colors among those creatures"; - } - - @Override - public String toString() { - return "X"; - } -} 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/GhastlyMimicry.java b/Mage.Sets/src/mage/cards/g/GhastlyMimicry.java deleted file mode 100644 index 85dce72078a..00000000000 --- a/Mage.Sets/src/mage/cards/g/GhastlyMimicry.java +++ /dev/null @@ -1,89 +0,0 @@ -package mage.cards.g; - -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.CreateTokenCopyTargetEffect; -import mage.abilities.keyword.DisturbAbility; -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.game.Game; -import mage.game.permanent.Permanent; -import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GhastlyMimicry extends CardImpl { - - public GhastlyMimicry(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.AURA); - this.color.setBlue(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)); - - // At the beginning of your upkeep, create a token that's a copy of enchanted creature, except it's a Spirit in addition to its other types. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GhastlyMimicryEffect())); - - // If Ghastly Mimicry would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private GhastlyMimicry(final GhastlyMimicry card) { - super(card); - } - - @Override - public GhastlyMimicry copy() { - return new GhastlyMimicry(this); - } -} - -class GhastlyMimicryEffect extends OneShotEffect { - - GhastlyMimicryEffect() { - super(Outcome.Benefit); - staticText = "create a token that's a copy of enchanted creature, " + - "except it's a Spirit in addition to its other types"; - } - - private GhastlyMimicryEffect(final GhastlyMimicryEffect effect) { - super(effect); - } - - @Override - public GhastlyMimicryEffect copy() { - return new GhastlyMimicryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = source.getSourcePermanentOrLKI(game); - if (permanent == null) { - return false; - } - Permanent attached = game.getPermanent(permanent.getAttachedTo()); - if (attached == null) { - return false; - } - CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); - effect.withAdditionalSubType(SubType.SPIRIT); - return effect.setTargetPointer(new FixedTarget(attached, game)).apply(game, source); - } -} 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/GideonBattleForged.java b/Mage.Sets/src/mage/cards/g/GideonBattleForged.java deleted file mode 100644 index a1158494564..00000000000 --- a/Mage.Sets/src/mage/cards/g/GideonBattleForged.java +++ /dev/null @@ -1,141 +0,0 @@ -package mage.cards.g; - -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.RequirementEffect; -import mage.abilities.effects.common.PreventAllDamageToSourceEffect; -import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.IndestructibleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.permanent.token.custom.CreatureToken; -import mage.target.common.TargetCreaturePermanent; -import mage.target.common.TargetOpponentsCreaturePermanent; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class GideonBattleForged extends CardImpl { - - public GideonBattleForged(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GIDEON); - - this.color.setWhite(true); - - this.nightCard = true; - - this.setStartingLoyalty(3); - - // +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able. - Ability ability = new LoyaltyAbility(new GideonBattleForgedEffect(), 2); - ability.addTarget(new TargetOpponentsCreaturePermanent(0, 1)); - this.addAbility(ability); - - // +1: Until your next turn, target creature gains indestructible. Untap that creature. - ability = new LoyaltyAbility(new GainAbilityTargetEffect( - IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn - ).setText("Until your next turn, target creature gains indestructible"), 1); - ability.addEffect(new UntapTargetEffect().setText("Untap that creature")); - ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); - - // 0: Until end of turn, Gideon, Battle-Forged becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn. - ability = new LoyaltyAbility(new BecomesCreatureSourceEffect(new CreatureToken( - 4, 4, "4/4 Human Soldier creature " + - "with indestructible", SubType.HUMAN, SubType.SOLDIER - ).withAbility(IndestructibleAbility.getInstance()), CardType.PLANESWALKER, Duration.EndOfTurn), 0); - ability.addEffect(new PreventAllDamageToSourceEffect(Duration.EndOfTurn) - .setText("Prevent all damage that would be dealt to him this turn")); - this.addAbility(ability); - } - - private GideonBattleForged(final GideonBattleForged card) { - super(card); - } - - @Override - public GideonBattleForged copy() { - return new GideonBattleForged(this); - } -} - -class GideonBattleForgedEffect extends RequirementEffect { - - protected MageObjectReference targetPermanentReference; - - GideonBattleForgedEffect() { - super(Duration.Custom); - staticText = "up to one target creature an opponent controls attacks {this} during its controller's next turn if able"; - } - - private GideonBattleForgedEffect(final GideonBattleForgedEffect effect) { - super(effect); - this.targetPermanentReference = effect.targetPermanentReference; - } - - @Override - public GideonBattleForgedEffect copy() { - return new GideonBattleForgedEffect(this); - } - - @Override - public boolean isInactive(Ability source, Game game) { - if (targetPermanentReference == null) { - return true; - } - Permanent targetPermanent = targetPermanentReference.getPermanent(game); - if (targetPermanent == null) { - return true; - } - return game.getTurnPhaseType() == TurnPhase.END && this.isYourNextTurn(game); // discard on end of their next turn - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - if (getTargetPointer().getFirst(game, source) == null) { - discard(); - } else { - targetPermanentReference = new MageObjectReference(getTargetPointer().getFirst(game, source), game); - } - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - if (!permanent.getId().equals(getTargetPointer().getFirst(game, source)) - || !game.isActivePlayer(permanent.getControllerId())) { - return false; - } - Permanent planeswalker = source.getSourcePermanentIfItStillExists(game); - if (planeswalker == null) { - discard(); - return false; - } - return true; - } - - @Override - public UUID mustAttackDefender(Ability source, Game game) { - return source.getSourceId(); - } - - @Override - public boolean mustAttack(Game game) { - return true; - } - - @Override - public boolean mustBlock(Game game) { - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GitaxianSpellstalker.java b/Mage.Sets/src/mage/cards/g/GitaxianSpellstalker.java deleted file mode 100644 index 787c07ab3d4..00000000000 --- a/Mage.Sets/src/mage/cards/g/GitaxianSpellstalker.java +++ /dev/null @@ -1,52 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.keyword.ProwessAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.WardAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GitaxianSpellstalker extends CardImpl { - - public GitaxianSpellstalker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.JACKAL); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlue(true); - this.color.setRed(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Ward {2} - this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); - - // Prowess - this.addAbility(new ProwessAbility()); - - // Prowess - this.addAbility(new ProwessAbility()); - } - - private GitaxianSpellstalker(final GitaxianSpellstalker card) { - super(card); - } - - @Override - public GitaxianSpellstalker copy() { - return new GitaxianSpellstalker(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GlamerGifter.java b/Mage.Sets/src/mage/cards/g/GlamerGifter.java new file mode 100644 index 00000000000..43f4ad2706a --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlamerGifter.java @@ -0,0 +1,56 @@ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAllCreatureTypesTargetEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author muz + */ +public final class GlamerGifter extends CardImpl { + + public GlamerGifter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.FAERIE); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, choose up to one other target creature. Until end of turn, that creature has base power and toughness 4/4 and gains all creature types. + Ability ability = new EntersBattlefieldTriggeredAbility( + new SetBasePowerToughnessTargetEffect(4, 4, Duration.EndOfTurn).setText("choose up to one other target creature. Until end of turn, that creature has base power and toughness 4/4") + ); + ability.addEffect(new GainAllCreatureTypesTargetEffect(Duration.EndOfTurn).setText("and gains all creature types")); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); + this.addAbility(ability); + } + + private GlamerGifter(final GlamerGifter card) { + super(card); + } + + @Override + public GlamerGifter copy() { + return new GlamerGifter(this); + } +} 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/GlisteningGoremonger.java b/Mage.Sets/src/mage/cards/g/GlisteningGoremonger.java deleted file mode 100644 index aa682247428..00000000000 --- a/Mage.Sets/src/mage/cards/g/GlisteningGoremonger.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.common.DiesSourceTriggeredAbility; -import mage.abilities.effects.common.SacrificeOpponentsEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GlisteningGoremonger extends CardImpl { - - public GlisteningGoremonger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.DEVIL); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.color.setBlack(true); - this.color.setRed(true); - this.nightCard = true; - - // When Glistening Goremonger dies, each opponent sacrifices an artifact or creature. - this.addAbility(new DiesSourceTriggeredAbility(new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE))); - } - - private GlisteningGoremonger(final GlisteningGoremonger card) { - super(card); - } - - @Override - public GlisteningGoremonger copy() { - return new GlisteningGoremonger(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GlisterBairn.java b/Mage.Sets/src/mage/cards/g/GlisterBairn.java new file mode 100644 index 00000000000..c8ca5bc513c --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GlisterBairn.java @@ -0,0 +1,47 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetControlledCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GlisterBairn extends CardImpl { + + public GlisterBairn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G/U}{G/U}{G/U}"); + + this.subtype.add(SubType.OUPHE); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Vivid -- At the beginning of combat on your turn, another target creature you control gets +X/+X until end of turn, where X is the number of colors among permanents you control. + Ability ability = new BeginningOfCombatTriggeredAbility(new BoostTargetEffect( + ColorsAmongControlledPermanentsCount.ALL_PERMANENTS, + ColorsAmongControlledPermanentsCount.ALL_PERMANENTS + ).setText("another target creature you control gets +X/+X until end of turn, " + + "where X is the number of colors among permanents you control")); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability.setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private GlisterBairn(final GlisterBairn card) { + super(card); + } + + @Override + public GlisterBairn copy() { + return new GlisterBairn(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GnarlbarkElm.java b/Mage.Sets/src/mage/cards/g/GnarlbarkElm.java new file mode 100644 index 00000000000..59dc8b77f80 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GnarlbarkElm.java @@ -0,0 +1,56 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GnarlbarkElm extends CardImpl { + + public GnarlbarkElm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.TREEFOLK); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // This creature enters with two -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), + "with two -1/-1 counters on it" + )); + + // {2}{B}, Remove two counters from this creature: Target creature gets -2/-2 until end of turn. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new BoostTargetEffect(-2, -2), new ManaCostsImpl<>("{2}{B}") + ); + ability.addCost(new RemoveCountersSourceCost(2)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private GnarlbarkElm(final GnarlbarkElm card) { + super(card); + } + + @Override + public GnarlbarkElm copy() { + return new GnarlbarkElm(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GnottvoldHermit.java b/Mage.Sets/src/mage/cards/g/GnottvoldHermit.java index f8410e520a0..c0902ea0a6e 100644 --- a/Mage.Sets/src/mage/cards/g/GnottvoldHermit.java +++ b/Mage.Sets/src/mage/cards/g/GnottvoldHermit.java @@ -1,33 +1,56 @@ package mage.cards.g; -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.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessTargetEffect; 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.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.TargetPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class GnottvoldHermit extends CardImpl { +public final class GnottvoldHermit extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterCreaturePermanent("other target creature"); + + static { + filter.add(AnotherPredicate.instance); + } public GnottvoldHermit(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.TROLL}, "{3}{G}", + "Chrome Host Hulk", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.TROLL}, "UG" + ); - this.subtype.add(SubType.TROLL); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.c.ChromeHostHulk.class; + // Gnottvold Hermit + this.getLeftHalfCard().setPT(4, 4); // {5}{U/P}: Transform Gnottvold Hermit. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{U/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{U/P}"))); + + // Chrome Host Hulk + this.getRightHalfCard().setPT(5, 5); + + // Whenever Chrome Host Hulk attacks, up to one other target creature has base power and toughness 5/5 until end of turn. + Ability ability = new AttacksTriggeredAbility( + new SetBasePowerToughnessTargetEffect(5, 5, Duration.EndOfTurn) + ); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.getRightHalfCard().addAbility(ability); } private GnottvoldHermit(final GnottvoldHermit card) { 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/GoldForgeGarrison.java b/Mage.Sets/src/mage/cards/g/GoldForgeGarrison.java deleted file mode 100644 index 5fd3930da98..00000000000 --- a/Mage.Sets/src/mage/cards/g/GoldForgeGarrison.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.g; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.mana.AddManaOfAnyColorEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.game.permanent.token.GoldForgeGarrisonGolemToken; - -/** - * - * @author LevelX2 - */ -public final class GoldForgeGarrison extends CardImpl { - - public GoldForgeGarrison(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.nightCard = true; - - // (Transforms from Golden Guardian.) - - // {T}: Add two mana of any one color. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost())); - - // {4}, {T}: Create a 4/4 colorless Golem artifact creature token. - Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new GoldForgeGarrisonGolemToken(), 1), new GenericManaCost(4)); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - - } - - private GoldForgeGarrison(final GoldForgeGarrison card) { - super(card); - } - - @Override - public GoldForgeGarrison copy() { - return new GoldForgeGarrison(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GoldbugHumanitysAlly.java b/Mage.Sets/src/mage/cards/g/GoldbugHumanitysAlly.java index 5b81a1d8090..2c99ca8339b 100644 --- a/Mage.Sets/src/mage/cards/g/GoldbugHumanitysAlly.java +++ b/Mage.Sets/src/mage/cards/g/GoldbugHumanitysAlly.java @@ -1,55 +1,76 @@ package mage.cards.g; -import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.CastSecondSpellTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CantBeCounteredControlledEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.PreventAllDamageToAllEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.LivingMetalAbility; import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -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.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterPermanent; +import mage.filter.FilterSpell; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.permanent.AttackingPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import java.util.Objects; import java.util.UUID; /** * @author TheElk801 */ -public final class GoldbugHumanitysAlly extends CardImpl { +public final class GoldbugHumanitysAlly extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledCreaturePermanent(SubType.HUMAN, "attacking Humans you control"); + private static final FilterSpell humanSpellFilter = new FilterSpell("Human spells"); + static { filter.add(AttackingPredicate.instance); + humanSpellFilter.add(SubType.HUMAN.getPredicate()); } public GoldbugHumanitysAlly(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W}{U}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{1}{W}{U}", + "Goldbug, Scrappy Scout", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "WU" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - - this.secondSideCardClazz = mage.cards.g.GoldbugScrappyScout.class; + // Goldbug, Humanity's Ally + this.getLeftHalfCard().setPT(3, 3); // More Than Meets the Eye {W}{U} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{W}{U}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{W}{U}")); // Prevent all combat damage that would be dealt to attacking Humans you control. - this.addAbility(new SimpleStaticAbility(new PreventAllDamageToAllEffect( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new PreventAllDamageToAllEffect( Duration.WhileOnBattlefield, filter, true ))); // Whenever you cast your second spell each turn, convert Goldbug. - this.addAbility(new CastSecondSpellTriggeredAbility(new TransformSourceEffect().setText("convert {this}"))); + this.getLeftHalfCard().addAbility(new CastSecondSpellTriggeredAbility(new TransformSourceEffect().setText("convert {this}"))); + + // Goldbug, Scrappy Scout + this.getRightHalfCard().setPT(1, 3); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Human spells you control can't be countered. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new CantBeCounteredControlledEffect( + humanSpellFilter, Duration.WhileOnBattlefield + ))); + + // Whenever Goldbug and at least one Human attack, draw a card and convert Goldbug. + this.getRightHalfCard().addAbility(new GoldbugScrappyScoutTriggeredAbility()); } private GoldbugHumanitysAlly(final GoldbugHumanitysAlly card) { @@ -61,3 +82,45 @@ public final class GoldbugHumanitysAlly extends CardImpl { return new GoldbugHumanitysAlly(this); } } + +class GoldbugScrappyScoutTriggeredAbility extends TriggeredAbilityImpl { + + GoldbugScrappyScoutTriggeredAbility() { + super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1)); + this.addEffect(new TransformSourceEffect()); + } + + private GoldbugScrappyScoutTriggeredAbility(final GoldbugScrappyScoutTriggeredAbility ability) { + super(ability); + } + + @Override + public GoldbugScrappyScoutTriggeredAbility copy() { + return new GoldbugScrappyScoutTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return game + .getCombat() + .getAttackers() + .contains(getSourceId()) + && game + .getCombat() + .getAttackers() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .anyMatch(permanent -> permanent.hasSubtype(SubType.HUMAN, game)); + } + + @Override + public String getRule() { + return "Whenever {this} and at least one Human attack, draw a card and convert {this}."; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GoldbugScrappyScout.java b/Mage.Sets/src/mage/cards/g/GoldbugScrappyScout.java deleted file mode 100644 index 4cd192a781e..00000000000 --- a/Mage.Sets/src/mage/cards/g/GoldbugScrappyScout.java +++ /dev/null @@ -1,104 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.CantBeCounteredControlledEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.LivingMetalAbility; -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 java.util.Objects; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GoldbugScrappyScout extends CardImpl { - - private static final FilterSpell filter = new FilterSpell("Human spells"); - - static { - filter.add(SubType.HUMAN.getPredicate()); - } - - public GoldbugScrappyScout(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(1); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.color.setBlue(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Human spells you control can't be countered. - this.addAbility(new SimpleStaticAbility(new CantBeCounteredControlledEffect( - filter, Duration.WhileOnBattlefield - ))); - - // Whenever Goldbug and at least one Human attack, draw a card and convert Goldbug. - this.addAbility(new GoldbugScrappyScoutTriggeredAbility()); - } - - private GoldbugScrappyScout(final GoldbugScrappyScout card) { - super(card); - } - - @Override - public GoldbugScrappyScout copy() { - return new GoldbugScrappyScout(this); - } -} - -class GoldbugScrappyScoutTriggeredAbility extends TriggeredAbilityImpl { - - GoldbugScrappyScoutTriggeredAbility() { - super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1)); - this.addEffect(new TransformSourceEffect()); - } - - private GoldbugScrappyScoutTriggeredAbility(final GoldbugScrappyScoutTriggeredAbility ability) { - super(ability); - } - - @Override - public GoldbugScrappyScoutTriggeredAbility copy() { - return new GoldbugScrappyScoutTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - return game - .getCombat() - .getAttackers() - .contains(getSourceId()) - && game - .getCombat() - .getAttackers() - .stream() - .map(game::getPermanent) - .filter(Objects::nonNull) - .anyMatch(permanent -> permanent.hasSubtype(SubType.HUMAN, game)); - } - - @Override - public String getRule() { - return "Whenever {this} and at least one Human attack, draw a card and convert {this}."; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GoldenGuardian.java b/Mage.Sets/src/mage/cards/g/GoldenGuardian.java index d30b0a5cf7a..c04f609ad9e 100644 --- a/Mage.Sets/src/mage/cards/g/GoldenGuardian.java +++ b/Mage.Sets/src/mage/cards/g/GoldenGuardian.java @@ -1,23 +1,27 @@ package mage.cards.g; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.FightTargetSourceEffect; +import mage.abilities.effects.mana.AddManaOfAnyColorEffect; import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.SimpleManaAbility; import mage.cards.Card; -import mage.cards.CardImpl; 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.token.GoldForgeGarrisonGolemToken; import mage.players.Player; import mage.target.TargetPermanent; @@ -26,26 +30,35 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class GoldenGuardian extends CardImpl { +public final class GoldenGuardian extends TransformingDoubleFacedCard { public GoldenGuardian(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "{4}", + "Gold-Forge Garrison", + new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); - this.subtype.add(SubType.GOLEM); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - - this.secondSideCardClazz = mage.cards.g.GoldForgeGarrison.class; + // Golden Guardian + this.getLeftHalfCard().setPT(4, 4); // Defender - this.addAbility(DefenderAbility.getInstance()); + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // {2}: Golden Guardian fights another target creature you control. When Golden Guardian dies this turn, return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new FightTargetSourceEffect(), new GenericManaCost(2)); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new GoldenGuardianDelayedTriggeredAbility(), false)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Gold-Forge Garrison + // {T}: Add two mana of any one color. + this.getRightHalfCard().addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(2), new TapSourceCost())); + + // {4}, {T}: Create a 4/4 colorless Golem artifact creature token. + Ability backAbility = new SimpleActivatedAbility(new CreateTokenEffect(new GoldForgeGarrisonGolemToken(), 1), new GenericManaCost(4)); + backAbility.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(backAbility); } private GoldenGuardian(final GoldenGuardian card) { @@ -60,7 +73,7 @@ public final class GoldenGuardian extends CardImpl { class GoldenGuardianDelayedTriggeredAbility extends DelayedTriggeredAbility { - public GoldenGuardianDelayedTriggeredAbility() { + GoldenGuardianDelayedTriggeredAbility() { super(new GoldenGuardianReturnTransformedEffect(), Duration.EndOfTurn); setTriggerPhrase("When {this} dies this turn, "); } diff --git a/Mage.Sets/src/mage/cards/g/GoldmeadowNomad.java b/Mage.Sets/src/mage/cards/g/GoldmeadowNomad.java new file mode 100644 index 00000000000..ba7be76786a --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoldmeadowNomad.java @@ -0,0 +1,47 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.ExileSourceFromGraveCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +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.KithkinGreenWhiteToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GoldmeadowNomad extends CardImpl { + + public GoldmeadowNomad(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {W}, Exile this card from your graveyard: Create a 1/1 green and white Kithkin creature token. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + Zone.GRAVEYARD, new CreateTokenEffect(new KithkinGreenWhiteToken()), new ManaCostsImpl<>("{W}") + ); + ability.addCost(new ExileSourceFromGraveCost()); + this.addAbility(ability); + } + + private GoldmeadowNomad(final GoldmeadowNomad card) { + super(card); + } + + @Override + public GoldmeadowNomad copy() { + return new GoldmeadowNomad(this); + } +} 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/GrandmotherRaviSengir.java b/Mage.Sets/src/mage/cards/g/GrandmotherRaviSengir.java deleted file mode 100644 index c535576b30f..00000000000 --- a/Mage.Sets/src/mage/cards/g/GrandmotherRaviSengir.java +++ /dev/null @@ -1,55 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DiesCreatureTriggeredAbility; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.counters.CounterType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GrandmotherRaviSengir extends CardImpl { - - public GrandmotherRaviSengir(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.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever a creature an opponent controls dies, put a +1/+1 counter on Grandmother Ravi Sengir and you gain 1 life. - Ability ability = new DiesCreatureTriggeredAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - false, StaticFilters.FILTER_OPPONENTS_PERMANENT_A_CREATURE - ); - ability.addEffect(new GainLifeEffect(1).concatBy("and")); - this.addAbility(ability); - } - - private GrandmotherRaviSengir(final GrandmotherRaviSengir card) { - super(card); - } - - @Override - public GrandmotherRaviSengir copy() { - return new GrandmotherRaviSengir(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GraspingShadows.java b/Mage.Sets/src/mage/cards/g/GraspingShadows.java index 9297ca57c2d..c73dc3f5752 100644 --- a/Mage.Sets/src/mage/cards/g/GraspingShadows.java +++ b/Mage.Sets/src/mage/cards/g/GraspingShadows.java @@ -2,18 +2,26 @@ package mage.cards.g; import mage.abilities.Ability; import mage.abilities.common.AttacksAloneControlledTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.BlackManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.counters.CounterType; import java.util.UUID; @@ -21,14 +29,18 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class GraspingShadows extends CardImpl { +public final class GraspingShadows extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.DREAD, 3); public GraspingShadows(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}"); - this.secondSideCardClazz = mage.cards.s.ShadowsLair.class; + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{3}{B}", + "Shadows' Lair", + new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{SubType.CAVE}, "" + ); + // Grasping Shadows // Whenever a creature you control attacks alone, it gains deathtouch and lifelink until end of turn. Put a dread counter on Grasping Shadows. Then if there are three or more dread counters on it, transform it. Ability ability = new AttacksAloneControlledTriggeredAbility( new GainAbilityTargetEffect(DeathtouchAbility.getInstance()) @@ -42,8 +54,20 @@ public final class GraspingShadows extends CardImpl { new TransformSourceEffect(), condition, "Then if there are three or more dread counters on it, transform it" )); - this.addAbility(new TransformAbility()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Shadows' Lair + // {T}: Add {B}. + this.getRightHalfCard().addAbility(new BlackManaAbility()); + + // {B}, {T}, Remove a dread counter from Shadows' Lair: You draw a card and you lose 1 life. + Ability backAbility = new SimpleActivatedAbility( + new DrawCardSourceControllerEffect(1, true), new ManaCostsImpl<>("{B}") + ); + backAbility.addCost(new TapSourceCost()); + backAbility.addCost(new RemoveCountersSourceCost(CounterType.DREAD.createInstance())); + backAbility.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); + this.getRightHalfCard().addAbility(backAbility); } private GraspingShadows(final GraspingShadows card) { diff --git a/Mage.Sets/src/mage/cards/g/GravelgillScoundrel.java b/Mage.Sets/src/mage/cards/g/GravelgillScoundrel.java new file mode 100644 index 00000000000..ec14998cc2e --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GravelgillScoundrel.java @@ -0,0 +1,58 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.permanent.TappedPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GravelgillScoundrel extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("another untapped creature you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(TappedPredicate.UNTAPPED); + } + + public GravelgillScoundrel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Whenever this creature attacks, you may tap another untapped creature you control. If you do, this creature can't be blocked this turn. + this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( + new CantBeBlockedSourceEffect(Duration.EndOfTurn), new TapTargetCost(filter) + ))); + } + + private GravelgillScoundrel(final GravelgillScoundrel card) { + super(card); + } + + @Override + public GravelgillScoundrel copy() { + return new GravelgillScoundrel(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GraveyardGlutton.java b/Mage.Sets/src/mage/cards/g/GraveyardGlutton.java deleted file mode 100644 index 5d6f60ee957..00000000000 --- a/Mage.Sets/src/mage/cards/g/GraveyardGlutton.java +++ /dev/null @@ -1,99 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; -import mage.abilities.costs.common.DiscardCardCost; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.abilities.keyword.WardAbility; -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.constants.Zone; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.players.Player; -import mage.target.common.TargetCardInGraveyard; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GraveyardGlutton extends CardImpl { - - public GraveyardGlutton(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; - - // Ward—Discard a card. - this.addAbility(new WardAbility(new DiscardCardCost(), false)); - - // Whenever Graveyard Glutton enters the battlefield or attacks, exile up to two target cards from graveyards. For each creature card exiled this way, each opponent loses 1 life and you gain 1 life. - Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new GraveyardGluttonEffect()); - ability.addTarget(new TargetCardInGraveyard(0, 2)); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private GraveyardGlutton(final GraveyardGlutton card) { - super(card); - } - - @Override - public GraveyardGlutton copy() { - return new GraveyardGlutton(this); - } -} - -class GraveyardGluttonEffect extends OneShotEffect { - - GraveyardGluttonEffect() { - super(Outcome.Benefit); - staticText = "exile up to two target cards from graveyards. " + - "For each creature card exiled this way, each opponent loses 1 life and you gain 1 life"; - } - - private GraveyardGluttonEffect(final GraveyardGluttonEffect effect) { - super(effect); - } - - @Override - public GraveyardGluttonEffect copy() { - return new GraveyardGluttonEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source)); - if (player == null || cards.isEmpty()) { - return false; - } - player.moveCards(cards, Zone.EXILED, source, game); - int amount = cards.count(StaticFilters.FILTER_CARD_CREATURE, game); - if (amount < 1) { - return true; - } - player.gainLife(amount, game, source); - for (UUID opponentId : game.getOpponents(source.getControllerId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - opponent.loseLife(amount, game, source, false); - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GraveyardTrespasser.java b/Mage.Sets/src/mage/cards/g/GraveyardTrespasser.java index 1e3f1f865e2..7ad4f57b6ac 100644 --- a/Mage.Sets/src/mage/cards/g/GraveyardTrespasser.java +++ b/Mage.Sets/src/mage/cards/g/GraveyardTrespasser.java @@ -1,16 +1,16 @@ package mage.cards.g; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; import mage.abilities.keyword.WardAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -25,27 +25,42 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class GraveyardTrespasser extends CardImpl { +public final class GraveyardTrespasser extends TransformingDoubleFacedCard { public GraveyardTrespasser(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}", + "Graveyard Glutton", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "B" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.g.GraveyardGlutton.class; + // Graveyard Trespasser + this.getLeftHalfCard().setPT(3, 3); // Ward—Discard a card. - this.addAbility(new WardAbility(new DiscardCardCost(), false)); + this.getLeftHalfCard().addAbility(new WardAbility(new DiscardCardCost(), false)); // Whenever Graveyard Trespasser enters the battlefield or attacks, exile up to one target card from a graveyard. If a creature card was exiled this way, each opponent loses 1 life and you gain 1 life. Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new GraveyardTrespasserEffect()); ability.addTarget(new TargetCardInGraveyard(0, 1)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Graveyard Glutton + this.getRightHalfCard().setPT(4, 4); + + // Ward—Discard a card. + this.getRightHalfCard().addAbility(new WardAbility(new DiscardCardCost(), false)); + + // Whenever Graveyard Glutton enters the battlefield or attacks, exile up to two target cards from graveyards. For each creature card exiled this way, each opponent loses 1 life and you gain 1 life. + Ability backAbility = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new GraveyardGluttonEffect()); + backAbility.addTarget(new TargetCardInGraveyard(0, 2)); + this.getRightHalfCard().addAbility(backAbility); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private GraveyardTrespasser(final GraveyardTrespasser card) { @@ -98,3 +113,43 @@ class GraveyardTrespasserEffect extends OneShotEffect { return true; } } + +class GraveyardGluttonEffect extends OneShotEffect { + + GraveyardGluttonEffect() { + super(Outcome.Benefit); + staticText = "exile up to two target cards from graveyards. " + + "For each creature card exiled this way, each opponent loses 1 life and you gain 1 life"; + } + + private GraveyardGluttonEffect(final GraveyardGluttonEffect effect) { + super(effect); + } + + @Override + public GraveyardGluttonEffect copy() { + return new GraveyardGluttonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source)); + if (player == null || cards.isEmpty()) { + return false; + } + player.moveCards(cards, Zone.EXILED, source, game); + int amount = cards.count(StaticFilters.FILTER_CARD_CREATURE, game); + if (amount < 1) { + return true; + } + player.gainLife(amount, game, source); + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null) { + opponent.loseLife(amount, game, source, false); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/g/GreatForestDruid.java b/Mage.Sets/src/mage/cards/g/GreatForestDruid.java new file mode 100644 index 00000000000..6706f5aec14 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GreatForestDruid.java @@ -0,0 +1,37 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.mana.AnyColorManaAbility; +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 GreatForestDruid extends CardImpl { + + public GreatForestDruid(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.TREEFOLK); + this.subtype.add(SubType.DRUID); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // {T}: Add one mana of any color. + this.addAbility(new AnyColorManaAbility()); + } + + private GreatForestDruid(final GreatForestDruid card) { + super(card); + } + + @Override + public GreatForestDruid copy() { + return new GreatForestDruid(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/GrimlockDinobotLeader.java b/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java index bbc81909820..4e5d938eae5 100644 --- a/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java +++ b/Mage.Sets/src/mage/cards/g/GrimlockDinobotLeader.java @@ -1,61 +1,71 @@ - package mage.cards.g; -import java.util.UUID; -import mage.MageInt; +import mage.MageObject; 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.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.constants.SuperType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AbilityPredicate; import mage.filter.predicate.permanent.TransformedPredicate; +import java.util.UUID; /** - * * @author Saga */ -public final class GrimlockDinobotLeader extends CardImpl{ - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaurs and Vehicles"); +public final class GrimlockDinobotLeader extends TransformingDoubleFacedCard { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaurs and Vehicles you control"); static { - filter.add(Predicates.or(SubType.DINOSAUR.getPredicate(), SubType.VEHICLE.getPredicate())); + filter.add(Predicates.or( + SubType.DINOSAUR.getPredicate(), + SubType.VEHICLE.getPredicate()) + ); } - + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Transformers creatures"); static { filter2.add(Predicates.not(SubType.DINOSAUR.getPredicate())); filter2.add(Predicates.not(SubType.VEHICLE.getPredicate())); filter2.add(Predicates.or(new AbilityPredicate(TransformAbility.class), TransformedPredicate.instance)); } - - public GrimlockDinobotLeader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT,CardType.CREATURE}, "{1}{R}{G}{W}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AUTOBOT); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.g.GrimlockFerociousKing.class; + public GrimlockDinobotLeader(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.AUTOBOT}, "{1}{R}{G}{W}", + "Grimlock, Ferocious King", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.DINOSAUR}, "RGW" + ); + + // Grimlock, Dinobot Leader + this.getLeftHalfCard().setPT(4, 4); // Dinosaurs, Vehicles and other Transformers creatures you control get +2/+0. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield, filter, false))); - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield, filter2, true))); - + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield, filter, false))); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield, filter2, true))); + // {2}: Grimlock, Dinobot Leader becomes Grimlock, Ferocious King. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{2}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{2}"))); + + // Grimlock, Ferocious King + this.getRightHalfCard().setPT(8, 8); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // {2}: Grimlock, Ferocious King becomes Grimlock, Dinobot Leader. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{2}"))); } private GrimlockDinobotLeader(final GrimlockDinobotLeader card) { @@ -66,5 +76,4 @@ public final class GrimlockDinobotLeader extends CardImpl{ public GrimlockDinobotLeader copy() { return new GrimlockDinobotLeader(this); } - } diff --git a/Mage.Sets/src/mage/cards/g/GrimlockFerociousKing.java b/Mage.Sets/src/mage/cards/g/GrimlockFerociousKing.java deleted file mode 100644 index f24ff1b75e6..00000000000 --- a/Mage.Sets/src/mage/cards/g/GrimlockFerociousKing.java +++ /dev/null @@ -1,53 +0,0 @@ - -package mage.cards.g; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.TransformSourceEffect; -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.SubType; -import mage.constants.SuperType; -import mage.constants.Zone; - -/** - * - * @author Saga - */ -public final class GrimlockFerociousKing extends CardImpl{ - - public GrimlockFerociousKing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.DINOSAUR); - this.power = new MageInt(8); - this.toughness = new MageInt(8); - this.color.setRed(true); - this.color.setGreen(true); - this.color.setWhite(true); - - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // {2}: Grimlock, Ferocious King becomes Grimlock, Dinobot Leader. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{2}"))); - } - - private GrimlockFerociousKing(final GrimlockFerociousKing card) { - super(card); - } - - @Override - public GrimlockFerociousKing copy() { - return new GrimlockFerociousKing(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/g/GrislyAnglerfish.java b/Mage.Sets/src/mage/cards/g/GrislyAnglerfish.java deleted file mode 100644 index a8eace0c588..00000000000 --- a/Mage.Sets/src/mage/cards/g/GrislyAnglerfish.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect; -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 fireshoes - */ -public final class GrislyAnglerfish extends CardImpl { - - public GrislyAnglerfish(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.FISH); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - - // this card is the second face of double-faced card - this.nightCard = true; - - // {6}: Creatures your opponents control attack this turn if able. - this.addAbility(new SimpleActivatedAbility(new AttacksIfAbleAllEffect( - StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, Duration.EndOfTurn - ), new ManaCostsImpl<>("{6}"))); - } - - private GrislyAnglerfish(final GrislyAnglerfish card) { - super(card); - } - - @Override - public GrislyAnglerfish copy() { - return new GrislyAnglerfish(this); - } -} 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/g/GristleGlutton.java b/Mage.Sets/src/mage/cards/g/GristleGlutton.java new file mode 100644 index 00000000000..07f5f95d947 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GristleGlutton.java @@ -0,0 +1,47 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GristleGlutton extends CardImpl { + + public GristleGlutton(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // {T}, Blight 1: Discard a card. If you do, draw a card. + Ability ability = new SimpleActivatedAbility(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1), new DiscardCardCost(), null, false + ), new TapSourceCost()); + ability.addCost(new BlightCost(1)); + this.addAbility(ability); + } + + private GristleGlutton(final GristleGlutton card) { + super(card); + } + + @Override + public GristleGlutton copy() { + return new GristleGlutton(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GrizzledAngler.java b/Mage.Sets/src/mage/cards/g/GrizzledAngler.java index ac856108974..0753f9ef08e 100644 --- a/Mage.Sets/src/mage/cards/g/GrizzledAngler.java +++ b/Mage.Sets/src/mage/cards/g/GrizzledAngler.java @@ -1,20 +1,22 @@ package mage.cards.g; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.CardsInControllerGraveyardCondition; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.MillCardsControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; 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.mageobject.ColorlessPredicate; @@ -23,7 +25,7 @@ import java.util.UUID; /** * @author fireshoes */ -public final class GrizzledAngler extends CardImpl { +public final class GrizzledAngler extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterCreatureCard(); @@ -34,21 +36,30 @@ public final class GrizzledAngler extends CardImpl { private static final Condition condition = new CardsInControllerGraveyardCondition(1, filter); public GrizzledAngler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); - this.subtype.add(SubType.HUMAN); - this.power = new MageInt(2); - this.toughness = new MageInt(3); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN}, "{2}{U}", + "Grisly Anglerfish", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.FISH}, "" + ); - this.secondSideCardClazz = mage.cards.g.GrislyAnglerfish.class; + // Grizzled Angler + this.getLeftHalfCard().setPT(2, 3); // {T}: Put the top two cards of your library into your graveyard. Then if there is a colorless creature card in your graveyard, transform Grizzled Angler. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new MillCardsControllerEffect(2), new TapSourceCost()); ability.addEffect(new ConditionalOneShotEffect( new TransformSourceEffect(), condition, "Then if there is a colorless creature card in your graveyard, transform {this}" )); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Grisly Anglerfish + this.getRightHalfCard().setPT(4, 5); + + // {6}: Creatures your opponents control attack this turn if able. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new AttacksIfAbleAllEffect( + StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURES, Duration.EndOfTurn + ), new ManaCostsImpl<>("{6}"))); } private GrizzledAngler(final GrizzledAngler card) { diff --git a/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java b/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java index ab0bcf6566e..3c8ba3067e0 100644 --- a/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java +++ b/Mage.Sets/src/mage/cards/g/GrizzledOutcasts.java @@ -1,33 +1,38 @@ package mage.cards.g; -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; +import mage.constants.SuperType; import java.util.UUID; /** * @author nantuko */ -public final class GrizzledOutcasts extends CardImpl { +public final class GrizzledOutcasts extends TransformingDoubleFacedCard { public GrizzledOutcasts(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{4}{G}", + "Krallenhorde Wantons", + new SuperType[]{}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.k.KrallenhordeWantons.class; - - this.power = new MageInt(4); - this.toughness = new MageInt(4); + // Grizzled Outcasts + this.getLeftHalfCard().setPT(4, 4); // At the beginning of each upkeep, if no spells were cast last turn, transform Grizzled Outcasts. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Krallenhorde Wantons + this.getRightHalfCard().setPT(7, 7); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Krallenhorde Wantons. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private GrizzledOutcasts(final GrizzledOutcasts card) { diff --git a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java index cbc80fc495e..3969690b886 100644 --- a/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java +++ b/Mage.Sets/src/mage/cards/g/GrowingRitesOfItlimoc.java @@ -1,19 +1,19 @@ package mage.cards.g; +import mage.Mana; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.common.CreaturesYouControlHint; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.DynamicManaAbility; +import mage.abilities.mana.GreenManaAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.PutCards; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; @@ -22,7 +22,7 @@ import java.util.UUID; /** * @author JRHerlehy */ -public final class GrowingRitesOfItlimoc extends CardImpl { +public final class GrowingRitesOfItlimoc extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledCreaturePermanent("you control four or more creatures"), @@ -30,23 +30,30 @@ public final class GrowingRitesOfItlimoc extends CardImpl { ); public GrowingRitesOfItlimoc(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{2}{G}", + "Itlimoc, Cradle of the Sun", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.i.ItlimocCradleOfTheSun.class; - - // When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. - // You may reveal a creature card from among them and put it into your hand. - // Put the rest on the bottom of your library in any order. - this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( + // Growing Rites of Itlimoc + // When Growing Rites of Itlimoc enters the battlefield, look at the top four cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in any order. + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( 4, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_ANY ))); // At the beginning of your end step, if you control four or more creatures, transform Growing Rites of Itlimoc. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()) + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect()) .withInterveningIf(condition).addHint(CreaturesYouControlHint.instance)); + + // Itlimoc, Cradle of the Sun + // {T}: Add {G}. + this.getRightHalfCard().addAbility(new GreenManaAbility()); + + // {T}: Add {G} for each creature you control. + this.getRightHalfCard().addAbility(new DynamicManaAbility( + Mana.GreenMana(1), CreaturesYouControlCount.SINGULAR + ).addHint(CreaturesYouControlHint.instance)); } private GrowingRitesOfItlimoc(final GrowingRitesOfItlimoc card) { diff --git a/Mage.Sets/src/mage/cards/g/GrubStoriedMatriarch.java b/Mage.Sets/src/mage/cards/g/GrubStoriedMatriarch.java new file mode 100644 index 00000000000..c3ec9826eeb --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GrubStoriedMatriarch.java @@ -0,0 +1,112 @@ +package mage.cards.g; + +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.TransformsOrEntersTriggeredAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; +import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GrubStoriedMatriarch extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard(SubType.GOBLIN); + + public GrubStoriedMatriarch(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOBLIN, SubType.WARLOCK}, "{2}{B}", + "Grub, Notorious Auntie", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOBLIN, SubType.WARRIOR}, "R" + ); + this.getLeftHalfCard().setPT(2, 1); + this.getRightHalfCard().setPT(2, 1); + + // Menace + this.getLeftHalfCard().addAbility(new MenaceAbility()); + + // Whenever this creature enters or transforms into Grub, Storied Matriarch, return up to one target Goblin card from your graveyard to your hand. + Ability ability = new TransformsOrEntersTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), false); + ability.addTarget(new TargetCardInYourGraveyard(0, 1, filter)); + this.getLeftHalfCard().addAbility(ability); + + // At the beginning of your first main phase, you may pay {R}. If you do, transform Grub. + this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{R}")) + )); + + // Grub, Notorious Auntie + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // Whenever Grub attacks, you may blight 1. If you do, create a tapped and attacking token that's a copy of the blighted creature, except it has "At the beginning of the end step, sacrifice this token." + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new GrubStoriedMatriarchEffect())); + + // At the beginning of your first main phase, you may pay {B}. If you do, transform Grub. + this.getRightHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{B}")) + )); + } + + private GrubStoriedMatriarch(final GrubStoriedMatriarch card) { + super(card); + } + + @Override + public GrubStoriedMatriarch copy() { + return new GrubStoriedMatriarch(this); + } +} + +class GrubStoriedMatriarchEffect extends OneShotEffect { + + GrubStoriedMatriarchEffect() { + super(Outcome.Benefit); + staticText = "you may blight 1. If you do, create a tapped and attacking token that's a copy of " + + "the blighted creature, except it has \"At the beginning of the end step, sacrifice this token.\""; + } + + private GrubStoriedMatriarchEffect(final GrubStoriedMatriarchEffect effect) { + super(effect); + } + + @Override + public GrubStoriedMatriarchEffect copy() { + return new GrubStoriedMatriarchEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null + || !BlightCost.canBlight(player.getId(), game, source) + || !player.chooseUse(outcome, "Blight 1?", source, game)) { + return false; + } + Permanent permanent = BlightCost.doBlight(player, 1, game, source); + return permanent != null + && new CreateTokenCopyTargetEffect(null, null, false, 1, true, true) + .setSavedPermanent(permanent) + .addAdditionalAbilities(new BeginningOfEndStepTriggeredAbility(new SacrificeSourceEffect())) + .apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GuidestoneCompass.java b/Mage.Sets/src/mage/cards/g/GuidestoneCompass.java deleted file mode 100644 index 7b7d39633ca..00000000000 --- a/Mage.Sets/src/mage/cards/g/GuidestoneCompass.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.g; - -import mage.abilities.Ability; -import mage.abilities.common.ActivateAsSorceryActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.keyword.ExploreTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.target.common.TargetControlledCreaturePermanent; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class GuidestoneCompass extends CardImpl { - - public GuidestoneCompass(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.nightCard = true; - this.color.setBlue(true); - - // {1}, {T}: Target creature you control explores. Activate only as a sorcery. - Ability ability = new ActivateAsSorceryActivatedAbility( - new ExploreTargetEffect(), - new GenericManaCost(1) - ); - ability.addTarget(new TargetControlledCreaturePermanent()); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private GuidestoneCompass(final GuidestoneCompass card) { - super(card); - } - - @Override - public GuidestoneCompass copy() { - return new GuidestoneCompass(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GuildpactParagon.java b/Mage.Sets/src/mage/cards/g/GuildpactParagon.java deleted file mode 100644 index c0dd3510078..00000000000 --- a/Mage.Sets/src/mage/cards/g/GuildpactParagon.java +++ /dev/null @@ -1,63 +0,0 @@ -package mage.cards.g; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.PutCards; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.FilterSpell; -import mage.filter.predicate.Predicate; -import mage.game.Game; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GuildpactParagon extends CardImpl { - - private static final FilterSpell filter = new FilterSpell("a spell that's exactly two colors"); - private static final FilterCard filter2 = new FilterCard("a card that's exactly two colors"); - - static { - filter.add(GuildpactParagonPredicate.instance); - filter2.add(GuildpactParagonPredicate.instance); - } - - public GuildpactParagon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.CONSTRUCT); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.nightCard = true; - - // Whenever you cast a spell that's exactly two colors, look at the top six cards of your library. You may reveal a card that's exactly two colors from among them and put it into your hand. Put the rest on the bottom of your library in a random order. - this.addAbility(new SpellCastControllerTriggeredAbility(new LookLibraryAndPickControllerEffect( - 6, 1, filter2, PutCards.HAND, PutCards.BOTTOM_RANDOM - ), filter, false)); - } - - private GuildpactParagon(final GuildpactParagon card) { - super(card); - } - - @Override - public GuildpactParagon copy() { - return new GuildpactParagon(this); - } -} - -enum GuildpactParagonPredicate implements Predicate { - instance; - - @Override - public boolean apply(MageObject input, Game game) { - return input.getColor(game).getColorCount() == 2; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GutsplitterGang.java b/Mage.Sets/src/mage/cards/g/GutsplitterGang.java new file mode 100644 index 00000000000..8315d987c0e --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GutsplitterGang.java @@ -0,0 +1,42 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility; +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 GutsplitterGang extends CardImpl { + + public GutsplitterGang(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // At the beginning of your first main phase, you may blight 2. If you don't, you lose 3 life. + this.addAbility(new BeginningOfFirstMainTriggeredAbility(new DoIfCostPaid( + null, new LoseLifeOpponentsEffect(3), new BlightCost(2) + ))); + } + + private GutsplitterGang(final GutsplitterGang card) { + super(card); + } + + @Override + public GutsplitterGang copy() { + return new GutsplitterGang(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GutterShortcut.java b/Mage.Sets/src/mage/cards/g/GutterShortcut.java deleted file mode 100644 index bfb716b5d02..00000000000 --- a/Mage.Sets/src/mage/cards/g/GutterShortcut.java +++ /dev/null @@ -1,71 +0,0 @@ -package mage.cards.g; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; -import mage.abilities.decorator.ConditionalRestrictionEffect; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.combat.CantBeBlockedAttachedEffect; -import mage.abilities.keyword.DisturbAbility; -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.game.Game; -import mage.game.permanent.Permanent; -import mage.target.TargetPermanent; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class GutterShortcut extends CardImpl { - - public GutterShortcut(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.AURA); - this.color.setBlue(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 can't be blocked as long as it's attacking alone. - this.addAbility(new SimpleStaticAbility(new ConditionalRestrictionEffect( - new CantBeBlockedAttachedEffect(AttachmentType.AURA), GutterShortcutCondition.instance, - "enchanted creature can't be blocked as long as it's attacking alone" - ))); - - // If Gutter Shortcut would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private GutterShortcut(final GutterShortcut card) { - super(card); - } - - @Override - public GutterShortcut copy() { - return new GutterShortcut(this); - } -} - -enum GutterShortcutCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = source.getSourcePermanentIfItStillExists(game); - return permanent != null && game.getCombat().attacksAlone() - && game.getCombat().getAttackers().contains(permanent.getAttachedTo()); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GutterSkulker.java b/Mage.Sets/src/mage/cards/g/GutterSkulker.java index 674a82f29b8..ec68e6828b0 100644 --- a/Mage.Sets/src/mage/cards/g/GutterSkulker.java +++ b/Mage.Sets/src/mage/cards/g/GutterSkulker.java @@ -1,42 +1,68 @@ package mage.cards.g; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceAttackingAloneCondition; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalRestrictionEffect; +import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; import mage.abilities.keyword.DisturbAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.EnchantAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.SubType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class GutterSkulker extends CardImpl { +public final class GutterSkulker extends TransformingDoubleFacedCard { public GutterSkulker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "{3}{U}", + "Gutter Shortcut", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "U" + ); - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.g.GutterShortcut.class; + // Gutter Skulker + this.getLeftHalfCard().setPT(3, 3); // Gutter Skulker can't be blocked as long as it's attacking alone. - this.addAbility(new SimpleStaticAbility(new ConditionalRestrictionEffect( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new ConditionalRestrictionEffect( new CantBeBlockedSourceEffect(Duration.WhileOnBattlefield), SourceAttackingAloneCondition.instance, "{this} can't be blocked as long as it's attacking alone" ))); + // Gutter Shortcut + // 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)); + // Disturb {3}{U} - this.addAbility(new DisturbAbility(this, "{3}{U}")); + // needs to be added after right half has spell ability target set + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{3}{U}")); + + // Enchanted creature can't be blocked as long as it's attacking alone. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new ConditionalRestrictionEffect( + new CantBeBlockedSourceEffect(), GutterShortcutCondition.instance, + "enchanted creature can't be blocked as long as it's attacking alone" + ))); + + // If Gutter Shortcut would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private GutterSkulker(final GutterSkulker card) { @@ -48,3 +74,14 @@ public final class GutterSkulker extends CardImpl { return new GutterSkulker(this); } } + +enum GutterShortcutCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + return permanent != null && game.getCombat().attacksAlone() + && game.getCombat().getAttackers().contains(permanent.getAttachedTo()); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HadanasClimb.java b/Mage.Sets/src/mage/cards/h/HadanasClimb.java index a1d27468050..319731b1df4 100644 --- a/Mage.Sets/src/mage/cards/h/HadanasClimb.java +++ b/Mage.Sets/src/mage/cards/h/HadanasClimb.java @@ -1,41 +1,60 @@ - package mage.cards.h; -import java.util.UUID; - import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.common.TargetHasCounterCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.mana.AnyColorManaAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; 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.game.Game; +import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** * @author LevelX2 */ -public final class HadanasClimb extends CardImpl { +public final class HadanasClimb extends TransformingDoubleFacedCard { public HadanasClimb(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{U}"); - - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.w.WingedTempleOfOrazca.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{1}{G}{U}", + "Winged Temple of Orazca", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Hadana's Climb // At the beginning of combat on your turn, put a +1/+1 counter on target creature you control. Then if that creature has three or more +1/+1 counters on it, transform Hadana's Climb. - this.addAbility(new TransformAbility()); Ability ability = new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); ability.addEffect(new ConditionalOneShotEffect(new TransformSourceEffect(), new TargetHasCounterCondition(CounterType.P1P1, 3, Integer.MAX_VALUE), "Then if that creature has three or more +1/+1 counters on it, transform {this}")); ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Winged Temple of Orazca + // {T}: Add one mana of any color. + this.getRightHalfCard().addAbility(new AnyColorManaAbility()); + + // {1}{G}{U}, {T}: Target creature you control gains flying and gets +X/+X until end of turn, where X is its power. + Ability backAbility = new SimpleActivatedAbility(new WingedTempleOfOrazcaEffect(), new ManaCostsImpl<>("{1}{G}{U}")); + backAbility.addCost(new TapSourceCost()); + backAbility.addTarget(new TargetControlledCreaturePermanent()); + this.getRightHalfCard().addAbility(backAbility); } private HadanasClimb(final HadanasClimb card) { @@ -47,3 +66,35 @@ public final class HadanasClimb extends CardImpl { return new HadanasClimb(this); } } + +class WingedTempleOfOrazcaEffect extends OneShotEffect { + + WingedTempleOfOrazcaEffect() { + super(Outcome.Benefit); + this.staticText = "target creature you control gains flying and gets +X/+X until end of turn, where X is its power"; + } + + private WingedTempleOfOrazcaEffect(final WingedTempleOfOrazcaEffect effect) { + super(effect); + } + + @Override + public WingedTempleOfOrazcaEffect copy() { + return new WingedTempleOfOrazcaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (creature != null && creature.isCreature(game)) { + int pow = creature.getPower().getValue(); + ContinuousEffect effect = new BoostTargetEffect(pow, pow, Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(creature, game)); + game.addEffect(effect, source); + effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(creature, game)); + game.addEffect(effect, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HamaTheBloodbender.java b/Mage.Sets/src/mage/cards/h/HamaTheBloodbender.java index 034e8a07f6e..03786bc5c92 100644 --- a/Mage.Sets/src/mage/cards/h/HamaTheBloodbender.java +++ b/Mage.Sets/src/mage/cards/h/HamaTheBloodbender.java @@ -3,10 +3,10 @@ package mage.cards.h; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.Costs; -import mage.abilities.costs.CostsImpl; import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MillCardsTargetEffect; @@ -20,6 +20,7 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; @@ -42,6 +43,7 @@ public final class HamaTheBloodbender extends CardImpl { // When Hama enters, target opponent mills three cards. Exile up to one noncreature, nonland card from that player's graveyard. For as long as you control Hama, you may cast the exiled card during your turn by waterbending {X} rather than paying its mana cost, where X is its mana value. Ability ability = new EntersBattlefieldTriggeredAbility(new MillCardsTargetEffect(3)); ability.addEffect(new HamaTheBloodbenderExileEffect()); + ability.addTarget(new TargetOpponent()); this.addAbility(ability); } @@ -143,10 +145,9 @@ class HamaTheBloodbenderCastEffect extends AsThoughEffectImpl { if (player == null) { return false; } - Costs newCosts = new CostsImpl<>(); - newCosts.add(new WaterbendCost(card.getManaValue())); - newCosts.addAll(card.getSpellAbility().getCosts()); - player.setCastSourceIdWithAlternateMana(card.getId(), null, newCosts); + ManaCosts manaCosts = new ManaCostsImpl<>("{0}"); + manaCosts.add(new WaterbendCost(card.getManaValue())); + player.setCastSourceIdWithAlternateMana(card.getId(), manaCosts, card.getSpellAbility().getCosts()); return true; } } diff --git a/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java b/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java index a6bb769ba9c..39db9ab604e 100644 --- a/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java +++ b/Mage.Sets/src/mage/cards/h/HanweirMilitiaCaptain.java @@ -1,25 +1,30 @@ package mage.cards.h; -import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; import mage.abilities.hint.common.CreaturesYouControlHint; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -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.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.permanent.token.HumanClericToken; import java.util.UUID; /** * @author fireshoes */ -public final class HanweirMilitiaCaptain extends CardImpl { +public final class HanweirMilitiaCaptain extends TransformingDoubleFacedCard { private static final Condition condition = new PermanentsOnTheBattlefieldCondition( new FilterControlledCreaturePermanent("you control four or more creatures"), @@ -27,18 +32,27 @@ public final class HanweirMilitiaCaptain extends CardImpl { ); public HanweirMilitiaCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SOLDIER}, "{1}{W}", + "Westvale Cult Leader", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CLERIC}, "W" + ); - this.secondSideCardClazz = mage.cards.w.WestvaleCultLeader.class; + // Hanweir Militia Captain + this.getLeftHalfCard().setPT(2, 2); // At the beginning of your upkeep, if you control four or more creatures, transform Hanweir Militia Captain. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect()) + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect()) .withInterveningIf(condition).addHint(CreaturesYouControlHint.instance)); + + // Westvale Cult Leader + // Westvale Cult Leader's power and toughness are each equal to the number of creatures you control. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(Zone.ALL, + new SetBasePowerToughnessSourceEffect(CreaturesYouControlCount.PLURAL)) + .addHint(CreaturesYouControlHint.instance)); + + // At the beginning of your end step, create a 1/1 white and black Human Cleric creature token. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new HumanClericToken()))); } private HanweirMilitiaCaptain(final HanweirMilitiaCaptain card) { diff --git a/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java b/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java index 85997f17d36..3919e5c1f4e 100644 --- a/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java +++ b/Mage.Sets/src/mage/cards/h/HanweirWatchkeep.java @@ -1,11 +1,11 @@ package mage.cards.h; -import mage.MageInt; +import mage.abilities.common.AttacksEachCombatStaticAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; 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.SubType; @@ -14,23 +14,32 @@ import java.util.UUID; /** * @author nantuko */ -public final class HanweirWatchkeep extends CardImpl { +public final class HanweirWatchkeep extends TransformingDoubleFacedCard { public HanweirWatchkeep(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{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}, "{2}{R}", + "Bane of Hanweir", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.b.BaneOfHanweir.class; + // Hanweir Watchkeep + this.getLeftHalfCard().setPT(1, 5); - this.power = new MageInt(1); - this.toughness = new MageInt(5); + // Defender + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); - this.addAbility(DefenderAbility.getInstance()); // At the beginning of each upkeep, if no spells were cast last turn, transform Hanweir Watchkeep. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Bane of Hanweir + this.getRightHalfCard().setPT(5, 5); + + // Bane of Hanweir attacks each turn if able. + this.getRightHalfCard().addAbility(new AttacksEachCombatStaticAbility()); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Bane of Hanweir. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private HanweirWatchkeep(final HanweirWatchkeep card) { diff --git a/Mage.Sets/src/mage/cards/h/HarmonizedCrescendo.java b/Mage.Sets/src/mage/cards/h/HarmonizedCrescendo.java new file mode 100644 index 00000000000..e27ef7ec1d1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HarmonizedCrescendo.java @@ -0,0 +1,83 @@ +package mage.cards.h; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.Choice; +import mage.choices.ChoiceCreatureType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HarmonizedCrescendo extends CardImpl { + + public HarmonizedCrescendo(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}"); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // Choose a creature type. Draw a card for each permanent you control of that type. + this.getSpellAbility().addEffect(new HarmonizedCrescendoEffect()); + } + + private HarmonizedCrescendo(final HarmonizedCrescendo card) { + super(card); + } + + @Override + public HarmonizedCrescendo copy() { + return new HarmonizedCrescendo(this); + } +} + +class HarmonizedCrescendoEffect extends OneShotEffect { + + HarmonizedCrescendoEffect() { + super(Outcome.Benefit); + staticText = "choose a creature type. Draw a card for each permanent you control of that type"; + } + + private HarmonizedCrescendoEffect(final HarmonizedCrescendoEffect effect) { + super(effect); + } + + @Override + public HarmonizedCrescendoEffect copy() { + return new HarmonizedCrescendoEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Choice choice = new ChoiceCreatureType(game, source); + player.choose(outcome, choice, game); + SubType subType = SubType.fromString(choice.getChoice()); + if (subType == null) { + return false; + } + game.informPlayers(CardUtil.getSourceLogName(game, source) + ": " + player.getLogName() + " chooses " + subType); + int count = game + .getBattlefield() + .getActivePermanents(StaticFilters.FILTER_CONTROLLED_PERMANENT, source.getControllerId(), source, game) + .stream() + .filter(permanent -> permanent.hasSubtype(subType, game)) + .mapToInt(x -> 1) + .sum(); + return count > 0 && player.drawCards(count, source, game) > 0; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HarriedArtisan.java b/Mage.Sets/src/mage/cards/h/HarriedArtisan.java index f9ca5ca64a8..24126b3e162 100644 --- a/Mage.Sets/src/mage/cards/h/HarriedArtisan.java +++ b/Mage.Sets/src/mage/cards/h/HarriedArtisan.java @@ -1,13 +1,12 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.HasteAbility; -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; @@ -16,23 +15,32 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class HarriedArtisan extends CardImpl { +public final class HarriedArtisan extends TransformingDoubleFacedCard { public HarriedArtisan(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.ARTIFICER}, "{2}{R}", + "Phyrexian Skyflayer", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.ARTIFICER}, "WR" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ARTIFICER); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.p.PhyrexianSkyflayer.class; + // Harried Artisan + this.getLeftHalfCard().setPT(2, 3); // Haste - this.addAbility(HasteAbility.getInstance()); + this.getLeftHalfCard().addAbility(HasteAbility.getInstance()); // {3}{W/P}: Transform Harried Artisan. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{W/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{W/P}"))); + + // Phyrexian Skyflayer + this.getRightHalfCard().setPT(3, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); } private HarriedArtisan(final HarriedArtisan card) { diff --git a/Mage.Sets/src/mage/cards/h/HarvestHand.java b/Mage.Sets/src/mage/cards/h/HarvestHand.java index 4b55e43df98..ad517955f58 100644 --- a/Mage.Sets/src/mage/cards/h/HarvestHand.java +++ b/Mage.Sets/src/mage/cards/h/HarvestHand.java @@ -1,18 +1,21 @@ package mage.cards.h; -import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.EquippedHasSubtypeCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.game.Game; import mage.players.Player; @@ -21,19 +24,36 @@ import java.util.UUID; /** * @author halljared */ -public final class HarvestHand extends CardImpl { +public final class HarvestHand extends TransformingDoubleFacedCard { + + private static final Condition condition = new EquippedHasSubtypeCondition(SubType.HUMAN); public HarvestHand(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); - this.subtype.add(SubType.SCARECROW); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.SCARECROW}, "{3}", + "Scrounged Scythe", + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.EQUIPMENT}, "" + ); - this.secondSideCardClazz = mage.cards.s.ScroungedScythe.class; + // Harvest Hand + this.getLeftHalfCard().setPT(2, 2); // When Harvest Hand dies, return it to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesSourceTriggeredAbility(new HarvestHandReturnTransformedEffect())); + this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new HarvestHandReturnTransformedEffect())); + + // Scrounged Scythe + // Equipped creature gets +1/+1. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 1))); + + // As long as equipped creature is a Human, it has menace. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilityAttachedEffect(new MenaceAbility(false), AttachmentType.EQUIPMENT), + condition, "As long as equipped creature is a Human, it has menace. " + + "(It can't be blocked except by two or more creatures.)" + ))); + + // Equip {2} + this.getRightHalfCard().addAbility(new EquipAbility(2, false)); } private HarvestHand(final HarvestHand card) { diff --git a/Mage.Sets/src/mage/cards/h/HarvesttideAssailant.java b/Mage.Sets/src/mage/cards/h/HarvesttideAssailant.java deleted file mode 100644 index c1d10320d80..00000000000 --- a/Mage.Sets/src/mage/cards/h/HarvesttideAssailant.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.keyword.NightboundAbility; -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 HarvesttideAssailant extends CardImpl { - - public HarvesttideAssailant(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.setRed(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private HarvesttideAssailant(final HarvesttideAssailant card) { - super(card); - } - - @Override - public HarvesttideAssailant copy() { - return new HarvesttideAssailant(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HarvesttideInfiltrator.java b/Mage.Sets/src/mage/cards/h/HarvesttideInfiltrator.java index f6258d61b69..3777b180973 100644 --- a/Mage.Sets/src/mage/cards/h/HarvesttideInfiltrator.java +++ b/Mage.Sets/src/mage/cards/h/HarvesttideInfiltrator.java @@ -1,10 +1,10 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; import mage.abilities.keyword.TrampleAbility; -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 HarvesttideInfiltrator extends CardImpl { +public final class HarvesttideInfiltrator extends TransformingDoubleFacedCard { public HarvesttideInfiltrator(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.WEREWOLF}, "{2}{R}", + "Harvesttide Assailant", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.h.HarvesttideAssailant.class; + // Harvesttide Infiltrator + this.getLeftHalfCard().setPT(3, 2); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Harvesttide Assailant + this.getRightHalfCard().setPT(4, 4); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private HarvesttideInfiltrator(final HarvesttideInfiltrator card) { diff --git a/Mage.Sets/src/mage/cards/h/HaukensInsight.java b/Mage.Sets/src/mage/cards/h/HaukensInsight.java deleted file mode 100644 index d2b944a5f9e..00000000000 --- a/Mage.Sets/src/mage/cards/h/HaukensInsight.java +++ /dev/null @@ -1,202 +0,0 @@ -package mage.cards.h; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -import mage.MageIdentifier; -import mage.MageObject; -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.constants.*; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.game.ExileZone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; -import mage.watchers.Watcher; - -/** - * - * @author weirddan455 - */ -public final class HaukensInsight extends CardImpl { - - public HaukensInsight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.color.setBlue(true); - // Back half of Jacob Hauken, Inspector - this.nightCard = true; - - // At the beginning of your upkeep, exile the top card of your library face down. You may look at that card for as long as it remains exiled. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new HaukensInsightExileEffect())); - - // Once during each of your turns, you may play a land or cast a spell from among the cards exiled with this permanent without paying its mana cost. - this.addAbility(new SimpleStaticAbility(new HaukensInsightPlayEffect()) - .setIdentifier(MageIdentifier.HaukensInsightWatcher), - new HaukensInsightWatcher()); - } - - private HaukensInsight(final HaukensInsight card) { - super(card); - } - - @Override - public HaukensInsight copy() { - return new HaukensInsight(this); - } -} - -class HaukensInsightExileEffect extends OneShotEffect { - - HaukensInsightExileEffect() { - super(Outcome.Benefit); - staticText = "exile the top card of your library face down. You may look at that card for as long as it remains exiled"; - } - - private HaukensInsightExileEffect(final HaukensInsightExileEffect effect) { - super(effect); - } - - @Override - public HaukensInsightExileEffect copy() { - return new HaukensInsightExileEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Card card = controller.getLibrary().getFromTop(game); - if (card != null) { - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getStackMomentSourceZCC()); - MageObject sourceObject = source.getSourceObject(game); - String exileName = sourceObject == null ? null : sourceObject.getIdName(); - card.setFaceDown(true, game); - controller.moveCardsToExile(card, source, game, false, exileId, exileName); - if (game.getState().getZone(card.getId()) == Zone.EXILED) { - card.setFaceDown(true, game); - HaukensInsightLookEffect effect = new HaukensInsightLookEffect(controller.getId()); - effect.setTargetPointer(new FixedTarget(card, game)); - game.addEffect(effect, source); - return true; - } - } - } - return false; - } -} - -class HaukensInsightLookEffect extends AsThoughEffectImpl { - - private final UUID authorizedPlayerId; - - public HaukensInsightLookEffect(UUID authorizedPlayerId) { - super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit); - this.authorizedPlayerId = authorizedPlayerId; - } - - private HaukensInsightLookEffect(final HaukensInsightLookEffect effect) { - super(effect); - this.authorizedPlayerId = effect.authorizedPlayerId; - } - - @Override - public HaukensInsightLookEffect copy() { - return new HaukensInsightLookEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - UUID cardId = getTargetPointer().getFirst(game, source); - if (cardId == null) { - this.discard(); // card is no longer in the origin zone, effect can be discarded - } - return affectedControllerId.equals(authorizedPlayerId) - && objectId.equals(cardId); - } -} - -class HaukensInsightPlayEffect extends AsThoughEffectImpl { - - HaukensInsightPlayEffect() { - super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.PlayForFree); - staticText = "Once during each of your turns, you may play a land or cast a spell from among the cards exiled with this permanent without paying its mana cost"; - } - - private HaukensInsightPlayEffect(final HaukensInsightPlayEffect effect) { - super(effect); - } - - @Override - public HaukensInsightPlayEffect copy() { - return new HaukensInsightPlayEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (affectedControllerId.equals(source.getControllerId()) && game.isActivePlayer(source.getControllerId())) { - Player controller = game.getPlayer(source.getControllerId()); - HaukensInsightWatcher watcher = game.getState().getWatcher(HaukensInsightWatcher.class); - Permanent sourceObject = game.getPermanent(source.getSourceId()); - if (controller != null && watcher != null && sourceObject != null && !watcher.isAbilityUsed(new MageObjectReference(sourceObject, game))) { - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId())); - ExileZone exileZone = game.getExile().getExileZone(exileId); - if (exileZone != null && exileZone.contains(CardUtil.getMainCardId(game, objectId))) { - allowCardToPlayWithoutMana(objectId, source, affectedControllerId, MageIdentifier.HaukensInsightWatcher, game); - return true; - } - } - } - return false; - } -} - -class HaukensInsightWatcher extends Watcher { - - private final Set usedFrom = new HashSet<>(); - - public HaukensInsightWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED) { - if (event.hasApprovingIdentifier(MageIdentifier.HaukensInsightWatcher)) { - usedFrom.add(event.getApprovingObject().getApprovingMageObjectReference()); - } - } - } - - @Override - public void reset() { - super.reset(); - usedFrom.clear(); - } - - public boolean isAbilityUsed(MageObjectReference mor) { - return usedFrom.contains(mor); - } -} 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/HavengulLaboratory.java b/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java index 766da704cd2..b95a4204275 100644 --- a/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java +++ b/Mage.Sets/src/mage/cards/h/HavengulLaboratory.java @@ -1,53 +1,79 @@ package mage.cards.h; +import mage.MageObjectReference; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.condition.Condition; +import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.keyword.InvestigateEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.ColorlessManaAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +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.players.Player; +import mage.target.common.TargetCardInYourGraveyard; import mage.util.CardUtil; import mage.watchers.Watcher; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; /** * @author TheElk801 */ -public final class HavengulLaboratory extends CardImpl { +public final class HavengulLaboratory extends TransformingDoubleFacedCard { public HavengulLaboratory(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.h.HavengulMystery.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "", + "Havengul Mystery", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Havengul Laboratory // {T}: Add {C}. - this.addAbility(new ColorlessManaAbility()); + this.getLeftHalfCard().addAbility(new ColorlessManaAbility()); // {4}, {T}: Investigate. Ability ability = new SimpleActivatedAbility(new InvestigateEffect(), new GenericManaCost(4)); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of your end step, if you sacrificed three or more Clues this turn, transform Havengul Laboratory. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility( + Ability transformAbility = new BeginningOfEndStepTriggeredAbility( TargetController.YOU, new TransformSourceEffect(), false, HavengulLaboratoryCondition.instance - ), new HavengulLaboratoryWatcher()); + ); + transformAbility.addWatcher(new HavengulLaboratoryWatcher()); + this.getLeftHalfCard().addAbility(transformAbility); + + // Havengul Mystery + // When this land transforms into Havengul Mystery, return target creature card from your graveyard to the battlefield. + Ability backAbility = new TransformIntoSourceTriggeredAbility(new HavengulMysteryEffect()) + .setTriggerPhrase("When this land transforms into {this}, "); + backAbility.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getRightHalfCard().addAbility(backAbility); + + // When the creature put onto the battlefield with Havengul Mystery leaves the battlefield, transform Havengul Mystery. + this.getRightHalfCard().addAbility(new HavengulMysteryLeavesAbility()); + + // {T}, Pay 1 life: Add {B}. + Ability manaAbility = new BlackManaAbility(); + manaAbility.addCost(new PayLifeCost(1)); + this.getRightHalfCard().addAbility(manaAbility); } private HavengulLaboratory(final HavengulLaboratory card) { @@ -108,3 +134,89 @@ class HavengulLaboratoryWatcher extends Watcher { .getOrDefault(playerId, 0) >= 3; } } + +class HavengulMysteryEffect extends OneShotEffect { + + HavengulMysteryEffect() { + super(Outcome.Benefit); + staticText = "return target creature card from your graveyard to the battlefield"; + } + + private HavengulMysteryEffect(final HavengulMysteryEffect effect) { + super(effect); + } + + @Override + public HavengulMysteryEffect copy() { + return new HavengulMysteryEffect(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); + Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); + if (permanent == null) { + return false; + } + String key = HavengulMysteryLeavesAbility.makeKey(source, game); + Set morSet; + if (game.getState().getValue(key) != null) { + morSet = (Set) game.getState().getValue(key); + } else { + morSet = new HashSet<>(); + game.getState().setValue(key, morSet); + } + morSet.add(new MageObjectReference(permanent, game)); + return true; + } +} + +class HavengulMysteryLeavesAbility extends TriggeredAbilityImpl { + + HavengulMysteryLeavesAbility() { + super(Zone.BATTLEFIELD, new TransformSourceEffect()); + setLeavesTheBattlefieldTrigger(true); + } + + private HavengulMysteryLeavesAbility(final HavengulMysteryLeavesAbility ability) { + super(ability); + } + + @Override + public HavengulMysteryLeavesAbility copy() { + return new HavengulMysteryLeavesAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() != Zone.BATTLEFIELD) { + return false; + } + + String key = makeKey(this, game); + Set morSet = (Set) game.getState().getValue(key); + return morSet != null + && !morSet.isEmpty() + && morSet.stream().anyMatch(mor -> mor.refersTo(zEvent.getTarget(), game)); + } + + @Override + public String getRule() { + return "When the creature put onto the battlefield with {this} leaves the battlefield, transform {this}."; + } + + static String makeKey(Ability source, Game game) { + return "HavengulMystery_" + source.getSourceId() + '_' + CardUtil.getActualSourceObjectZoneChangeCounter(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HavengulMystery.java b/Mage.Sets/src/mage/cards/h/HavengulMystery.java deleted file mode 100644 index 24cca60c3b1..00000000000 --- a/Mage.Sets/src/mage/cards/h/HavengulMystery.java +++ /dev/null @@ -1,150 +0,0 @@ -package mage.cards.h; - -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.costs.common.PayLifeCost; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.mana.BlackManaAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SuperType; -import mage.constants.Zone; -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.players.Player; -import mage.target.common.TargetCardInYourGraveyard; -import mage.util.CardUtil; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class HavengulMystery extends CardImpl { - - public HavengulMystery(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - - // When this land transforms into Havengul Mystery, return target creature card from your graveyard to the battlefield. - Ability ability = new TransformIntoSourceTriggeredAbility(new HavengulMysteryEffect()) - .setTriggerPhrase("When this land transforms into {this}, "); - ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); - this.addAbility(ability); - - // When the creature put onto the battlefield with Havengul Mystery leaves the battlefield, transform Havengul Mystery. - this.addAbility(new HavengulMysteryLeavesAbility()); - - // {T}, Pay 1 life: Add {B}. - Ability ability2 = new BlackManaAbility(); - ability2.addCost(new PayLifeCost(1)); - this.addAbility(ability2); - } - - private HavengulMystery(final HavengulMystery card) { - super(card); - } - - @Override - public HavengulMystery copy() { - return new HavengulMystery(this); - } - - static String makeKey(Ability source, Game game) { - return "HavengulMystery_" + source.getSourceId() + '_' + CardUtil.getActualSourceObjectZoneChangeCounter(game, source); - } -} - -class HavengulMysteryEffect extends OneShotEffect { - - HavengulMysteryEffect() { - super(Outcome.Benefit); - staticText = "return target creature card from your graveyard to the battlefield"; - } - - private HavengulMysteryEffect(final HavengulMysteryEffect effect) { - super(effect); - } - - @Override - public HavengulMysteryEffect copy() { - return new HavengulMysteryEffect(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); - Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); - if (permanent == null) { - return false; - } - String key = HavengulMystery.makeKey(source, game); - Set morSet; - if (game.getState().getValue(key) != null) { - morSet = (Set) game.getState().getValue(key); - } else { - morSet = new HashSet<>(); - game.getState().setValue(key, morSet); - } - morSet.add(new MageObjectReference(permanent, game)); - return true; - } -} - -class HavengulMysteryLeavesAbility extends TriggeredAbilityImpl { - - HavengulMysteryLeavesAbility() { - super(Zone.BATTLEFIELD, new TransformSourceEffect()); - setLeavesTheBattlefieldTrigger(true); - } - - private HavengulMysteryLeavesAbility(final HavengulMysteryLeavesAbility ability) { - super(ability); - } - - @Override - public HavengulMysteryLeavesAbility copy() { - return new HavengulMysteryLeavesAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() != Zone.BATTLEFIELD) { - return false; - } - - String key = HavengulMystery.makeKey(this, game); - Set morSet = (Set) game.getState().getValue(key); - return morSet != null - && !morSet.isEmpty() - && morSet.stream().anyMatch(mor -> mor.refersTo(zEvent.getTarget(), game)); - } - - @Override - public String getRule() { - return "When the creature put onto the battlefield with {this} leaves the battlefield, transform {this}."; - } -} diff --git a/Mage.Sets/src/mage/cards/h/HeirOfFalkenrath.java b/Mage.Sets/src/mage/cards/h/HeirOfFalkenrath.java index 2074046e6be..36ffd9f815c 100644 --- a/Mage.Sets/src/mage/cards/h/HeirOfFalkenrath.java +++ b/Mage.Sets/src/mage/cards/h/HeirOfFalkenrath.java @@ -1,35 +1,41 @@ - package mage.cards.h; -import java.util.UUID; -import mage.MageInt; import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.effects.common.TransformSourceEffect; -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 HeirOfFalkenrath extends CardImpl { +public final class HeirOfFalkenrath extends TransformingDoubleFacedCard { public HeirOfFalkenrath(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(2); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE}, "{1}{B}", + "Heir to the Night", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE, SubType.BERSERKER}, "B" + ); - this.secondSideCardClazz = mage.cards.h.HeirToTheNight.class; + // Heir of Falkenrath + this.getLeftHalfCard().setPT(2, 1); // Discard a card: Transform Heir of Falkenrath. Activate this ability only once each turn. - this.addAbility(new TransformAbility()); - this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new DiscardCardCost())); + this.getLeftHalfCard().addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new DiscardCardCost())); + + // Heir to the Night + this.getRightHalfCard().setPT(3, 2); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); } private HeirOfFalkenrath(final HeirOfFalkenrath card) { diff --git a/Mage.Sets/src/mage/cards/h/HeirToTheNight.java b/Mage.Sets/src/mage/cards/h/HeirToTheNight.java deleted file mode 100644 index ca92f5f234e..00000000000 --- a/Mage.Sets/src/mage/cards/h/HeirToTheNight.java +++ /dev/null @@ -1,41 +0,0 @@ - -package mage.cards.h; - -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 HeirToTheNight extends CardImpl { - - public HeirToTheNight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.VAMPIRE); - this.subtype.add(SubType.BERSERKER); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.color.setBlack(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - } - - private HeirToTheNight(final HeirToTheNight card) { - super(card); - } - - @Override - public HeirToTheNight copy() { - return new HeirToTheNight(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HeirloomAuntie.java b/Mage.Sets/src/mage/cards/h/HeirloomAuntie.java new file mode 100644 index 00000000000..515c05d1a5c --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeirloomAuntie.java @@ -0,0 +1,55 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HeirloomAuntie extends CardImpl { + + public HeirloomAuntie(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // This creature enters with two -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), + "with two -1/-1 counters on it" + )); + + // Whenever another creature you control dies, surveil 1, then remove a -1/-1 counter from this creature. + Ability ability = new DiesCreatureTriggeredAbility( + new SurveilEffect(1), false, + StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL + ); + ability.addEffect(new RemoveCounterSourceEffect(CounterType.M1M1.createInstance()).concatBy(", then")); + this.addAbility(ability); + } + + private HeirloomAuntie(final HeirloomAuntie card) { + super(card); + } + + @Override + public HeirloomAuntie copy() { + return new HeirloomAuntie(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HeirloomMirror.java b/Mage.Sets/src/mage/cards/h/HeirloomMirror.java index 69323e07bc4..75d8f78e3e6 100644 --- a/Mage.Sets/src/mage/cards/h/HeirloomMirror.java +++ b/Mage.Sets/src/mage/cards/h/HeirloomMirror.java @@ -2,40 +2,44 @@ package mage.cards.h; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.MillCardsControllerEffect; -import mage.abilities.effects.common.RemoveAllCountersSourceEffect; -import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.*; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -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.target.common.TargetCardInGraveyard; import java.util.UUID; /** * @author TheElk801 */ -public final class HeirloomMirror extends CardImpl { +public final class HeirloomMirror extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.RITUAL, 3); public HeirloomMirror(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{B}"); - - this.secondSideCardClazz = mage.cards.i.InheritedFiend.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{B}", + "Inherited Fiend", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "B" + ); + // Heirloom Mirror // {1}, {T}, Pay 1 life, Discard a card: Draw a card, mill a card, then put a ritual counter on Heirloom Mirror. Then if it has 3 or more ritual counters on it, remove them and transform it. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); ability.addCost(new PayLifeCost(1)); @@ -44,9 +48,21 @@ public final class HeirloomMirror extends CardImpl { ability.addEffect(new AddCountersSourceEffect(CounterType.RITUAL.createInstance()).concatBy(", then")); ability.addEffect(new ConditionalOneShotEffect( new RemoveAllCountersSourceEffect(CounterType.RITUAL), condition, - "Then if it has 3 or more ritual counters on it, remove them and transform it" + "Then if it has three or more ritual counters on it, remove them and transform it" ).addEffect(new TransformSourceEffect())); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Inherited Fiend + this.getRightHalfCard().setPT(4, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // {2}{B}: Exile target creature card from a graveyard. Put a +1/+1 counter on Inherited Fiend. + Ability backAbility = new SimpleActivatedAbility(new ExileTargetEffect(), new ManaCostsImpl<>("{2}{B}")); + backAbility.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()).concatBy(".")); + backAbility.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_A_GRAVEYARD)); + this.getRightHalfCard().addAbility(backAbility); } private HeirloomMirror(final HeirloomMirror card) { diff --git a/Mage.Sets/src/mage/cards/h/HeliodTheRadiantDawn.java b/Mage.Sets/src/mage/cards/h/HeliodTheRadiantDawn.java index 992a028c466..ca94d277ff9 100644 --- a/Mage.Sets/src/mage/cards/h/HeliodTheRadiantDawn.java +++ b/Mage.Sets/src/mage/cards/h/HeliodTheRadiantDawn.java @@ -1,49 +1,66 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.SpellAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; 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.FilterCard; import mage.filter.common.FilterEnchantmentCard; +import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.Predicates; +import mage.game.Game; import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; +import mage.watchers.common.CardsDrawnThisTurnWatcher; import java.util.UUID; -public class HeliodTheRadiantDawn extends CardImpl { +public class HeliodTheRadiantDawn extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterEnchantmentCard("enchantment card that isn't a God"); + private static final FilterCard flashFilter = new FilterNonlandCard("spells"); static { filter.add(Predicates.not(SubType.GOD.getPredicate())); } public HeliodTheRadiantDawn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{W}{W}"); - this.supertype.add(SuperType.LEGENDARY); - this.addSubType(SubType.GOD); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.h.HeliodTheWarpedEclipse.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.GOD}, "{2}{W}{W}", + "Heliod, the Warped Eclipse", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.GOD}, "WU" + ); + + // Heliod, the Radiant Dawn + this.getLeftHalfCard().setPT(4, 4); // When Heliod, the Radiant Dawn enters the battlefield, return target enchantment card that isn't a God from your graveyard to your hand. Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()); ability.addTarget(new TargetCardInYourGraveyard(filter)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {3}{U/P}: Transform Heliod, the Radiant Dawn. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{U/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{U/P}"))); + + // Heliod, the Warped Eclipse + this.getRightHalfCard().setPT(4, 6); + + // You may cast spells as though they had flash. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new CastAsThoughItHadFlashAllEffect(Duration.WhileOnBattlefield, flashFilter))); + + // Spells you cast cost {1} less to cast for each card your opponents have drawn this turn. + Ability ability2 = new SimpleStaticAbility(new HeliodTheWarpedEclipseEffect()); + ability2.addWatcher(new CardsDrawnThisTurnWatcher()); + this.getRightHalfCard().addAbility(ability2); } private HeliodTheRadiantDawn(final HeliodTheRadiantDawn card) { @@ -55,3 +72,45 @@ public class HeliodTheRadiantDawn extends CardImpl { return new HeliodTheRadiantDawn(this); } } + +class HeliodTheWarpedEclipseEffect extends CostModificationEffectImpl { + + HeliodTheWarpedEclipseEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "spells you cast cost {1} less to cast for each card your opponents have drawn this turn"; + } + + private HeliodTheWarpedEclipseEffect(final HeliodTheWarpedEclipseEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + CardsDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsDrawnThisTurnWatcher.class); + if (watcher == null) { + return false; + } + int amount = game + .getOpponents(source.getControllerId()) + .stream() + .mapToInt(watcher::getCardsDrawnThisTurn) + .sum(); + if (amount < 1) { + return false; + } + CardUtil.adjustCost((SpellAbility) abilityToModify, amount); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + return abilityToModify instanceof SpellAbility + && game.getCard(abilityToModify.getSourceId()) != null + && abilityToModify.isControlledBy(source.getControllerId()); + } + + @Override + public HeliodTheWarpedEclipseEffect copy() { + return new HeliodTheWarpedEclipseEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HeliodTheWarpedEclipse.java b/Mage.Sets/src/mage/cards/h/HeliodTheWarpedEclipse.java deleted file mode 100644 index 712aa244fb9..00000000000 --- a/Mage.Sets/src/mage/cards/h/HeliodTheWarpedEclipse.java +++ /dev/null @@ -1,92 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.SpellAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect; -import mage.abilities.effects.common.cost.CostModificationEffectImpl; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterCard; -import mage.filter.common.FilterNonlandCard; -import mage.game.Game; -import mage.util.CardUtil; -import mage.watchers.common.CardsDrawnThisTurnWatcher; - -import java.util.UUID; - -public class HeliodTheWarpedEclipse extends CardImpl { - - private static final FilterCard filter = new FilterNonlandCard("spells"); - - public HeliodTheWarpedEclipse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - this.color.setWhite(true); - this.color.setBlue(true); - this.supertype.add(SuperType.LEGENDARY); - this.addSubType(SubType.PHYREXIAN); - this.addSubType(SubType.GOD); - this.power = new MageInt(4); - this.toughness = new MageInt(6); - this.nightCard = true; - - // You may cast spells as though they had flash. - this.addAbility(new SimpleStaticAbility(new CastAsThoughItHadFlashAllEffect(Duration.WhileOnBattlefield, filter))); - - // Spells you cast cost {1} less to cast for each card your opponents have drawn this turn. - this.addAbility(new SimpleStaticAbility(new HeliodTheWarpedEclipseEffect())); - } - - private HeliodTheWarpedEclipse(final HeliodTheWarpedEclipse card) { - super(card); - } - - @Override - public HeliodTheWarpedEclipse copy() { - return new HeliodTheWarpedEclipse(this); - } -} - -class HeliodTheWarpedEclipseEffect extends CostModificationEffectImpl { - - HeliodTheWarpedEclipseEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); - staticText = "spells you cast cost {1} less to cast for each card your opponents have drawn this turn"; - } - - private HeliodTheWarpedEclipseEffect(final HeliodTheWarpedEclipseEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source, Ability abilityToModify) { - CardsDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsDrawnThisTurnWatcher.class); - if (watcher == null) { - return false; - } - int amount = game - .getOpponents(source.getControllerId()) - .stream() - .mapToInt(watcher::getCardsDrawnThisTurn) - .sum(); - if (amount < 1) { - return false; - } - CardUtil.adjustCost((SpellAbility) abilityToModify, amount); - return true; - } - - @Override - public boolean applies(Ability abilityToModify, Ability source, Game game) { - return abilityToModify instanceof SpellAbility - && game.getCard(abilityToModify.getSourceId()) != null - && abilityToModify.isControlledBy(source.getControllerId()); - } - - @Override - public HeliodTheWarpedEclipseEffect copy() { - return new HeliodTheWarpedEclipseEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HenrikaDomnathi.java b/Mage.Sets/src/mage/cards/h/HenrikaDomnathi.java index 2b2b78e162c..c85473cec50 100644 --- a/Mage.Sets/src/mage/cards/h/HenrikaDomnathi.java +++ b/Mage.Sets/src/mage/cards/h/HenrikaDomnathi.java @@ -1,41 +1,57 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; import mage.abilities.effects.common.SacrificeAllEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; import mage.abilities.hint.common.ModesAlreadyUsedHint; +import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.LifelinkAbility; +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.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; import java.util.UUID; /** * @author TheElk801 */ -public final class HenrikaDomnathi extends CardImpl { +public final class HenrikaDomnathi extends TransformingDoubleFacedCard { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each creature you control with flying, deathtouch, and/or lifelink"); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + filter.add(Predicates.or( + new AbilityPredicate(FlyingAbility.class), + new AbilityPredicate(DeathtouchAbility.class), + new AbilityPredicate(LifelinkAbility.class) + )); + } public HenrikaDomnathi(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.VAMPIRE}, "{2}{B}{B}", + "Henrika, Infernal Seer", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE}, "B" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.h.HenrikaInfernalSeer.class; + // Henrika Domnathi + this.getLeftHalfCard().setPT(1, 3); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // At the beginning of combat on your turn, choose one that hasn't been chosen — // • Each player sacrifices a creature. @@ -51,10 +67,26 @@ public final class HenrikaDomnathi extends CardImpl { // • Transform Henrika Domnathi. ability.addMode(new Mode(new TransformSourceEffect()).setModeTag("transform")); - this.addAbility(new TransformAbility()); ability.addHint(ModesAlreadyUsedHint.instance); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Henrika, Infernal Seer + this.getRightHalfCard().setPT(3, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Deathtouch + this.getRightHalfCard().addAbility(DeathtouchAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // {1}{B}{B}: Each creature you control with flying, deathtouch, and/or lifelink gets +1/+0 until end of turn. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new BoostAllEffect( + 1, 0, Duration.EndOfTurn, filter, false + ), new ManaCostsImpl<>("{1}{B}{B}"))); } private HenrikaDomnathi(final HenrikaDomnathi card) { diff --git a/Mage.Sets/src/mage/cards/h/HenrikaInfernalSeer.java b/Mage.Sets/src/mage/cards/h/HenrikaInfernalSeer.java deleted file mode 100644 index fce0036801d..00000000000 --- a/Mage.Sets/src/mage/cards/h/HenrikaInfernalSeer.java +++ /dev/null @@ -1,68 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.continuous.BoostAllEffect; -import mage.abilities.keyword.DeathtouchAbility; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AbilityPredicate; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class HenrikaInfernalSeer extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each creature you control with flying, deathtouch, and/or lifelink"); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - filter.add(Predicates.or( - new AbilityPredicate(FlyingAbility.class), - new AbilityPredicate(DeathtouchAbility.class), - new AbilityPredicate(LifelinkAbility.class) - )); - } - - public HenrikaInfernalSeer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Deathtouch - this.addAbility(DeathtouchAbility.getInstance()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - - // {1}{B}{B}: Each creature you control with flying, deathtouch, and/or lifelink gets +1/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostAllEffect( - 1, 0, Duration.EndOfTurn, filter, false - ), new ManaCostsImpl<>("{1}{B}{B}"))); - } - - private HenrikaInfernalSeer(final HenrikaInfernalSeer card) { - super(card); - } - - @Override - public HenrikaInfernalSeer copy() { - return new HenrikaInfernalSeer(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HerbologyInstructor.java b/Mage.Sets/src/mage/cards/h/HerbologyInstructor.java index 826ab7f6688..4b3be096b87 100644 --- a/Mage.Sets/src/mage/cards/h/HerbologyInstructor.java +++ b/Mage.Sets/src/mage/cards/h/HerbologyInstructor.java @@ -1,39 +1,55 @@ package mage.cards.h; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; +import mage.target.common.TargetOpponentsCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class HerbologyInstructor extends CardImpl { +public final class HerbologyInstructor extends TransformingDoubleFacedCard { public HerbologyInstructor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.TREEFOLK, SubType.DRUID}, "{1}{G}", + "Malady Invoker", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.TREEFOLK}, "BG" + ); - this.subtype.add(SubType.TREEFOLK); - this.subtype.add(SubType.DRUID); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.m.MaladyInvoker.class; + // Herbology Instructor + this.getLeftHalfCard().setPT(1, 3); // When Herbology Instructor enters the battlefield, you gain 3 life. - this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(3))); // {6}{B/P}: Transform Herbology Instructor. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{6}{B/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{6}{B/P}"))); + + // Malady Invoker + this.getRightHalfCard().setPT(3, 3); + + // When this creature transforms into Malady Invoker, target creature an opponent controls gets -0/-X until end of turn, where X is Malady Invoker's power. + Ability ability = new TransformIntoSourceTriggeredAbility(new BoostTargetEffect( + StaticValue.get(0), new SignInversionDynamicValue(SourcePermanentPowerValue.NOT_NEGATIVE), Duration.EndOfTurn + ).setText("target creature an opponent controls gets -0/-X until end of turn, where X is {this}'s power")); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.getRightHalfCard().addAbility(ability); } private HerbologyInstructor(final HerbologyInstructor card) { diff --git a/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java b/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java index ede6c5f95e4..f041fc3c33a 100644 --- a/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java +++ b/Mage.Sets/src/mage/cards/h/HermitOfTheNatterknolls.java @@ -1,13 +1,12 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -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.filter.StaticFilters; @@ -17,25 +16,36 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class HermitOfTheNatterknolls extends CardImpl { +public final class HermitOfTheNatterknolls extends TransformingDoubleFacedCard { public HermitOfTheNatterknolls(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(3); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{2}{G}", + "Lone Wolf of the Natterknolls", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.l.LoneWolfOfTheNatterknolls.class; + // Hermit of the Natterknolls + this.getLeftHalfCard().setPT(2, 3); // Whenever an opponent casts a spell during your turn, draw a card. - this.addAbility(new SpellCastOpponentTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastOpponentTriggeredAbility( new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_SPELL_A, false ).withTriggerCondition(MyTurnCondition.instance)); // At the beginning of each upkeep, if no spells were cast last turn, transform Hermit of the Natterknolls. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Lone Wolf of the Natterknolls + this.getRightHalfCard().setPT(3, 5); + + // Whenever an opponent cast a spell during your turn, draw two cards. + this.getRightHalfCard().addAbility(new SpellCastOpponentTriggeredAbility( + new DrawCardSourceControllerEffect(2), StaticFilters.FILTER_SPELL_A, false + ).withTriggerCondition(MyTurnCondition.instance)); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Lone Wolf of the Natterknolls. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private HermitOfTheNatterknolls(final HermitOfTheNatterknolls card) { diff --git a/Mage.Sets/src/mage/cards/h/HexParasite.java b/Mage.Sets/src/mage/cards/h/HexParasite.java index 6e85c817548..69f7ff286c0 100644 --- a/Mage.Sets/src/mage/cards/h/HexParasite.java +++ b/Mage.Sets/src/mage/cards/h/HexParasite.java @@ -4,16 +4,18 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.RemoveUpToAmountCountersEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.util.CardUtil; import java.util.UUID; @@ -64,40 +66,16 @@ class HexParasiteEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - TargetPermanent target = (TargetPermanent) source.getTargets().get(0); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (permanent == null || controller == null) { + int removed = RemoveUpToAmountCountersEffect.doRemoval( + GetXValue.instance.calculate(game, source, this), + getTargetPointer().getFirst(game, source), + game.getPlayer(source.getControllerId()), + game, source + ); + if (removed < 1) { return false; } - - int toRemove = CardUtil.getSourceCostsTag(game, source, "X", 0); - if (toRemove == 0) { - return true; - } - - int removed = 0; - String[] counterNames = permanent.getCounters(game).keySet().toArray(new String[0]); - for (String counterName : counterNames) { - if (controller.chooseUse(Outcome.Neutral, "Remove " + counterName + " counters?", source, game)) { - if (permanent.getCounters(game).get(counterName).getCount() == 1 || (toRemove - removed == 1)) { - permanent.removeCounters(counterName, 1, source, game); - removed++; - } else { - int amount = controller.getAmount(1, Math.min(permanent.getCounters(game).get(counterName).getCount(), toRemove - removed), "How many?", source, game); - if (amount > 0) { - removed += amount; - permanent.removeCounters(counterName, amount, source, game); - } - } - } - if (removed >= toRemove) { - break; - } - } - if (removed > 0) { - game.addEffect(new BoostSourceEffect(removed, 0, Duration.EndOfTurn), source); - } + game.addEffect(new BoostSourceEffect(removed, 0, Duration.EndOfTurn), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/h/HexingSquelcher.java b/Mage.Sets/src/mage/cards/h/HexingSquelcher.java new file mode 100644 index 00000000000..bcd1f274aaf --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HexingSquelcher.java @@ -0,0 +1,60 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.common.CantBeCounteredSourceAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.CantBeCounteredControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.WardAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreatureSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HexingSquelcher extends CardImpl { + + private static final FilterSpell filter = new FilterCreatureSpell("creature spells you control"); + + public HexingSquelcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.SORCERER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); + + // Ward--Pay 2 life. + this.addAbility(new WardAbility(new PayLifeCost(2))); + + // Spells you control can't be countered. + this.addAbility(new SimpleStaticAbility(new CantBeCounteredControlledEffect(filter, Duration.WhileOnBattlefield))); + + // Other creatures you control have "Ward--Pay 2 life." + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + new WardAbility(new PayLifeCost(2)), Duration.WhileOnBattlefield, + StaticFilters.FILTER_PERMANENT_CREATURES, true + ))); + } + + private HexingSquelcher(final HexingSquelcher card) { + super(card); + } + + @Override + public HexingSquelcher copy() { + return new HexingSquelcher(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/HideousFleshwheeler.java b/Mage.Sets/src/mage/cards/h/HideousFleshwheeler.java deleted file mode 100644 index f7b1017e7d3..00000000000 --- a/Mage.Sets/src/mage/cards/h/HideousFleshwheeler.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.common.FilterPermanentCard; -import mage.filter.predicate.mageobject.ManaValuePredicate; -import mage.target.common.TargetCardInGraveyard; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class HideousFleshwheeler extends CardImpl { - - private static final FilterCard filter - = new FilterPermanentCard("permanent card with mana value 2 or less from a graveyard"); - - static { - filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3)); - } - - public HideousFleshwheeler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.RAT); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.color.setWhite(true); - this.color.setBlack(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility()); - - // When this creature transforms into Hideous FleshwheelerHideous Fleshwheeler, put target permanent card with mana value 2 or less from a graveyard onto the battlefield under your control. - Ability ability = new TransformIntoSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()); - ability.addTarget(new TargetCardInGraveyard(filter)); - this.addAbility(ability); - } - - private HideousFleshwheeler(final HideousFleshwheeler card) { - super(card); - } - - @Override - public HideousFleshwheeler copy() { - return new HideousFleshwheeler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HidetsuguConsumesAll.java b/Mage.Sets/src/mage/cards/h/HidetsuguConsumesAll.java index 16e6ba35dc0..8b01a26e62e 100644 --- a/Mage.Sets/src/mage/cards/h/HidetsuguConsumesAll.java +++ b/Mage.Sets/src/mage/cards/h/HidetsuguConsumesAll.java @@ -1,26 +1,38 @@ package mage.cards.h; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageSourceTriggeredAbility; +import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.condition.Condition; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.LoseGameTargetPlayerEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.SagaChapter; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; /** * @author TheElk801 */ -public final class HidetsuguConsumesAll extends CardImpl { +public final class HidetsuguConsumesAll extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterNonlandPermanent(); @@ -29,26 +41,41 @@ public final class HidetsuguConsumesAll extends CardImpl { } public HidetsuguConsumesAll(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{R}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.v.VesselOfTheAllConsuming.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{B}{R}", + "Vessel of the All-Consuming", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.OGRE, SubType.SHAMAN}, "BR" + ); + // Hidetsugu Consumes All // (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 each nonland permanent with mana value 1 or less. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new DestroyAllEffect(filter) + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new DestroyAllEffect(filter) .setText("destroy each nonland permanent with mana value 1 or less")); // II — Exile all graveyards. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new ExileGraveyardAllPlayersEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new ExileGraveyardAllPlayersEffect()); // 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()); + sagaAbility.addWatcher(VesselOfTheAllConsumingWatcher.makeWatcher()); + this.getLeftHalfCard().addAbility(sagaAbility); - this.addAbility(sagaAbility, mage.cards.v.VesselOfTheAllConsuming.makeWatcher()); + // Vessel of the All-Consuming + this.getRightHalfCard().setPT(3, 3); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Whenever Vessel of the All-Consuming deals damage, put a +1/+1 counter on it. + this.getRightHalfCard().addAbility(new DealsDamageSourceTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))); + + // Whenever Vessel of the All-Consuming deals damage to a player, if it has dealt 10 or more damage to that player this turn, they lose the game. + this.getRightHalfCard().addAbility(new DealsDamageToAPlayerTriggeredAbility( + new LoseGameTargetPlayerEffect().setText("they lose the game"), false, true + ).withInterveningIf(VesselOfTheAllConsumingCondition.instance)); } private HidetsuguConsumesAll(final HidetsuguConsumesAll card) { @@ -60,3 +87,60 @@ public final class HidetsuguConsumesAll extends CardImpl { return new HidetsuguConsumesAll(this); } } + +enum VesselOfTheAllConsumingCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return VesselOfTheAllConsumingWatcher.checkPermanent(game, source); + } + + @Override + public String toString() { + return "it has dealt 10 or more damage to that player this turn"; + } +} + +class VesselOfTheAllConsumingWatcher extends Watcher { + + private final Map, Integer> morMap = new HashMap<>(); + + VesselOfTheAllConsumingWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.DAMAGED_PLAYER) { + return; + } + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent != null) { + int damage = event.getAmount(); + morMap.compute(new AbstractMap.SimpleImmutableEntry(new MageObjectReference(permanent, game), event.getTargetId()), + (u, i) -> i == null ? damage : Integer.sum(i, damage)); + } + } + + @Override + public void reset() { + super.reset(); + morMap.clear(); + } + + static Watcher makeWatcher() { + return new VesselOfTheAllConsumingWatcher(); + } + + static boolean checkPermanent(Game game, Ability source) { + VesselOfTheAllConsumingWatcher watcher = game.getState().getWatcher(VesselOfTheAllConsumingWatcher.class); + if (watcher == null) { + return false; + } + AbstractMap.SimpleImmutableEntry key = new AbstractMap.SimpleImmutableEntry<>( + new MageObjectReference(game.getPermanent(source.getSourceId()), game), + source.getEffects().get(0).getTargetPointer().getFirst(game, source)); + return watcher.morMap.getOrDefault(key, 0) >= 10; + } +} 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..4095763b875 --- /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.BlightCost; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.ProliferateEffect; +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); + BlightCost.doBlight(opponent, 1, game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HinterlandHermit.java b/Mage.Sets/src/mage/cards/h/HinterlandHermit.java index e376e0ebdea..12fe9a552e1 100644 --- a/Mage.Sets/src/mage/cards/h/HinterlandHermit.java +++ b/Mage.Sets/src/mage/cards/h/HinterlandHermit.java @@ -1,11 +1,13 @@ package mage.cards.h; -import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SubType; import java.util.UUID; @@ -13,21 +15,29 @@ import java.util.UUID; /** * @author BetaSteward */ -public final class HinterlandHermit extends CardImpl { +public final class HinterlandHermit extends TransformingDoubleFacedCard { public HinterlandHermit(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}", + "Hinterland Scourge", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.h.HinterlandScourge.class; - - this.power = new MageInt(2); - this.toughness = new MageInt(1); + // Hinterland Hermit + this.getLeftHalfCard().setPT(2, 1); // At the beginning of each upkeep, if no spells were cast last turn, transform Hinterland Hermit. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Hinterland Scourge + this.getRightHalfCard().setPT(3, 2); + + // Hinterland Scourge must be blocked if able. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new MustBeBlockedByAtLeastOneSourceEffect(Duration.WhileOnBattlefield))); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Hinterland Scourge. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private HinterlandHermit(final HinterlandHermit card) { diff --git a/Mage.Sets/src/mage/cards/h/HinterlandScourge.java b/Mage.Sets/src/mage/cards/h/HinterlandScourge.java deleted file mode 100644 index cd0c9e0c8ba..00000000000 --- a/Mage.Sets/src/mage/cards/h/HinterlandScourge.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect; -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 BetaSteward - */ -public final class HinterlandScourge extends CardImpl { - - public HinterlandScourge(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 of Hinterland Hermit - this.nightCard = true; - - this.power = new MageInt(3); - this.toughness = new MageInt(2); - - // Hinterland Scourge must be blocked if able. - this.addAbility(new SimpleStaticAbility(new MustBeBlockedByAtLeastOneSourceEffect(Duration.WhileOnBattlefield))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Hinterland Scourge. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private HinterlandScourge(final HinterlandScourge card) { - super(card); - } - - @Override - public HinterlandScourge copy() { - return new HinterlandScourge(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HolyFrazzleCannon.java b/Mage.Sets/src/mage/cards/h/HolyFrazzleCannon.java deleted file mode 100644 index 60301909b4f..00000000000 --- a/Mage.Sets/src/mage/cards/h/HolyFrazzleCannon.java +++ /dev/null @@ -1,82 +0,0 @@ -package mage.cards.h; - -import mage.abilities.Ability; -import mage.abilities.common.AttacksAttachedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.EquipAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class HolyFrazzleCannon extends CardImpl { - - public HolyFrazzleCannon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.subtype.add(SubType.EQUIPMENT); - this.color.setWhite(true); - this.color.setBlack(true); - this.nightCard = true; - - // Whenever equipped creature attacks, put a +1/+1 counter on that creature and each other creature you control that shares a creature type with it. - this.addAbility(new AttacksAttachedTriggeredAbility( - new HolyFrazzleCannonEffect(), AttachmentType.EQUIPMENT, - false, SetTargetPointer.PERMANENT - )); - - // Equip {1} - this.addAbility(new EquipAbility(1, false)); - } - - private HolyFrazzleCannon(final HolyFrazzleCannon card) { - super(card); - } - - @Override - public HolyFrazzleCannon copy() { - return new HolyFrazzleCannon(this); - } -} - -class HolyFrazzleCannonEffect extends OneShotEffect { - - HolyFrazzleCannonEffect() { - super(Outcome.Benefit); - staticText = "put a +1/+1 counter on that creature and " + - "each other creature you control that shares a creature type with it"; - } - - private HolyFrazzleCannonEffect(final HolyFrazzleCannonEffect effect) { - super(effect); - } - - @Override - public HolyFrazzleCannonEffect copy() { - return new HolyFrazzleCannonEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent == null) { - return false; - } - for (Permanent creature : game.getBattlefield().getActivePermanents( - StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source, game - )) { - if (creature.equals(permanent) || permanent.shareCreatureTypes(game, creature)) { - creature.addCounters(CounterType.P1P1.createInstance(), source, game); - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/h/HookhandMariner.java b/Mage.Sets/src/mage/cards/h/HookhandMariner.java index c2fc61ab523..dd34f90a2eb 100644 --- a/Mage.Sets/src/mage/cards/h/HookhandMariner.java +++ b/Mage.Sets/src/mage/cards/h/HookhandMariner.java @@ -1,9 +1,10 @@ package mage.cards.h; -import mage.MageInt; +import mage.abilities.keyword.DauntAbility; 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,19 +13,29 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class HookhandMariner extends CardImpl { +public final class HookhandMariner extends TransformingDoubleFacedCard { public HookhandMariner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{3}{G}", + "Riphook Raider", + 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(4); - this.secondSideCardClazz = mage.cards.r.RiphookRaider.class; + // Hookhand Mariner + this.getLeftHalfCard().setPT(4, 4); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Riphook Raider + this.getRightHalfCard().setPT(6, 4); + + // Riphook Raider can't be blocked by creatures with power 2 or less. + this.getRightHalfCard().addAbility(new DauntAbility()); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private HookhandMariner(final HookhandMariner card) { diff --git a/Mage.Sets/src/mage/cards/h/HostileHostel.java b/Mage.Sets/src/mage/cards/h/HostileHostel.java index 8e8a5a156c4..8538da2f36c 100644 --- a/Mage.Sets/src/mage/cards/h/HostileHostel.java +++ b/Mage.Sets/src/mage/cards/h/HostileHostel.java @@ -2,42 +2,57 @@ package mage.cards.h; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.AttacksTriggeredAbility; +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.OneShotEffect; +import mage.abilities.effects.common.PhaseOutSourceEffect; import mage.abilities.effects.common.RemoveAllCountersSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.UntapSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; import mage.abilities.mana.ColorlessManaAbility; -import mage.cards.CardImpl; +import mage.cards.Card; 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.filter.StaticFilters; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; +import mage.util.CardUtil; import java.util.UUID; /** * @author LePwnerer */ -public final class HostileHostel extends CardImpl { +public final class HostileHostel extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.SOUL, 3); public HostileHostel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.secondSideCardClazz = mage.cards.c.CreepingInn.class; + super(ownerId, setInfo, + new CardType[]{CardType.LAND}, new SubType[]{}, "", + "Creeping Inn", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.HORROR, SubType.CONSTRUCT}, "B" + ); + // Hostile Hostel // {T}: Add {C}. - this.addAbility(new ColorlessManaAbility()); + this.getLeftHalfCard().addAbility(new ColorlessManaAbility()); // {1}, {T}, Sacrifice a creature: Put a soul counter on Hostile Hostel. Then if there are three or more soul counters on it, remove those counters, transform it, then untap it. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility(new AddCountersSourceEffect(CounterType.SOUL.createInstance()), new ManaCostsImpl<>("{1}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE)); @@ -45,7 +60,17 @@ public final class HostileHostel extends CardImpl { new RemoveAllCountersSourceEffect(CounterType.SOUL), condition, "Then if there are three " + "or more soul counters on it, remove those counters, transform it, then untap it" ).addEffect(new TransformSourceEffect()).addEffect(new UntapSourceEffect())); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Creeping Inn + this.getRightHalfCard().setPT(3, 7); + + // Whenever Creeping Inn attacks, you may exile a creature card from your graveyard. + // If you do, each opponent loses X life and you gain X life, where X is the number of creature cards exiled with Creeping Inn. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new CreepingInnEffect())); + + // {4}: Creeping Inn phases out. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new PhaseOutSourceEffect(), new ManaCostsImpl<>("{4}"))); } private HostileHostel(final HostileHostel card) { @@ -57,3 +82,54 @@ public final class HostileHostel extends CardImpl { return new HostileHostel(this); } } + +class CreepingInnEffect extends OneShotEffect { + + CreepingInnEffect() { + super(Outcome.Exile); + this.staticText = "you may exile a creature card from your graveyard. " + + "If you do, each opponent loses X life and you gain X life, " + + "where X is the number of creature cards exiled with {this}."; + } + + private CreepingInnEffect(final CreepingInnEffect effect) { + super(effect); + } + + @Override + public CreepingInnEffect copy() { + return new CreepingInnEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = source.getSourcePermanentOrLKI(game); + if (player != null && permanent != null) { + UUID exileId = CardUtil.getExileZoneId(game, source); + TargetCardInGraveyard target = new TargetCardInGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); + target.withNotTarget(true); + if (target.canChoose(player.getId(), source, game)) { + if (player.choose(Outcome.Exile, target, source, game)) { + Card cardChosen = game.getCard(target.getFirstTarget()); + if (cardChosen != null) { + int lifeAmount = 0; + player.moveCardsToExile(cardChosen, source, game, true, exileId, permanent.getName()); + ExileZone exile = game.getExile().getExileZone(exileId); + if (exile != null) { + for (UUID cardId : exile) { + lifeAmount++; + } + } + for (UUID playerId : game.getOpponents(source.getControllerId())) { + game.getPlayer(playerId).loseLife(lifeAmount, game, source, false); + } + player.gainLife(lifeAmount, game, source); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/h/HoundTamer.java b/Mage.Sets/src/mage/cards/h/HoundTamer.java index 925be3abf19..c546be35ee4 100644 --- a/Mage.Sets/src/mage/cards/h/HoundTamer.java +++ b/Mage.Sets/src/mage/cards/h/HoundTamer.java @@ -1,17 +1,22 @@ package mage.cards.h; -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.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; import mage.abilities.keyword.TrampleAbility; -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.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -19,29 +24,60 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class HoundTamer extends CardImpl { +public final class HoundTamer extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterPermanent("Wolves and Werewolves"); + + static { + filter.add(Predicates.or( + SubType.WOLF.getPredicate(), + SubType.WEREWOLF.getPredicate() + )); + } public HoundTamer(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}", + "Untamed Pup", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.u.UntamedPup.class; + // Hound Tamer + this.getLeftHalfCard().setPT(3, 3); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // {3}{G}: Put a +1/+1 counter on target creature. Ability ability = new SimpleActivatedAbility( new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{3}{G}") ); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Untamed Pup + this.getRightHalfCard().setPT(4, 4); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Other Wolves and Werewolves you control have trample. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + ))); + + // {3}{G}: Put a +1/+1 counter on target creature. + Ability backAbility = new SimpleActivatedAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{3}{G}") + ); + backAbility.addTarget(new TargetCreaturePermanent()); + this.getRightHalfCard().addAbility(backAbility); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private HoundTamer(final HoundTamer card) { diff --git a/Mage.Sets/src/mage/cards/h/HovelHurler.java b/Mage.Sets/src/mage/cards/h/HovelHurler.java new file mode 100644 index 00000000000..fae4b978de3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HovelHurler.java @@ -0,0 +1,60 @@ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class HovelHurler extends CardImpl { + + public HovelHurler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}"); + + this.subtype.add(SubType.GIANT); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(6); + this.toughness = new MageInt(7); + + // This creature enters with two -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), + "with two -1/-1 counters on it" + )); + + // {R/W}{R/W}, Remove a counter from this creature: Another target creature you control gets +1/+0 and gains flying until end of turn. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new BoostTargetEffect(1, 0) + .setText("another target creature you control gets +1/+0"), + new ManaCostsImpl<>("{R/W}{R/W}") + ); + ability.addCost(new RemoveCountersSourceCost(1)); + ability.addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance()) + .setText("and gains flying until end of turn")); + this.addAbility(ability); + } + + private HovelHurler(final HovelHurler card) { + super(card); + } + + @Override + public HovelHurler copy() { + return new HovelHurler(this); + } +} 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/HowlpackAlpha.java b/Mage.Sets/src/mage/cards/h/HowlpackAlpha.java deleted file mode 100644 index 2acb47d31d8..00000000000 --- a/Mage.Sets/src/mage/cards/h/HowlpackAlpha.java +++ /dev/null @@ -1,66 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.game.permanent.token.WolfToken; - -import java.util.UUID; - -/** - * @author North, noxx - */ -public final class HowlpackAlpha extends CardImpl { - - private static final FilterCreaturePermanent filter - = new FilterCreaturePermanent("each other creature you control that's a Werewolf or a Wolf"); - - static { - filter.add(Predicates.or( - SubType.WEREWOLF.getPredicate(), - SubType.WOLF.getPredicate() - )); - } - - public HowlpackAlpha(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.color.setGreen(true); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - - // Other Werewolf and Wolf creatures you control get +1/+1. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( - 1, 1, Duration.WhileOnBattlefield, filter, true - ))); - - // At the beginning of your end step, create a 2/2 green Wolf creature token. - this.addAbility(new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new WolfToken()))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Howlpack Alpha. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private HowlpackAlpha(final HowlpackAlpha card) { - super(card); - } - - @Override - public HowlpackAlpha copy() { - return new HowlpackAlpha(this); - } -} diff --git a/Mage.Sets/src/mage/cards/h/HowlpackAvenger.java b/Mage.Sets/src/mage/cards/h/HowlpackAvenger.java deleted file mode 100644 index f0ee5d31421..00000000000 --- a/Mage.Sets/src/mage/cards/h/HowlpackAvenger.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.h; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DealtDamageAnyTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.common.SavedDamageValue; -import mage.abilities.effects.common.DamageTargetEffect; -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.SetTargetPointer; -import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.target.common.TargetAnyTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class HowlpackAvenger extends CardImpl { - - public HowlpackAvenger(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.setRed(true); - this.nightCard = true; - - // Whenever a permanent you control is dealt damage, Howlpack Avenger deals that much damage to any target. - Ability ability = new DealtDamageAnyTriggeredAbility(new DamageTargetEffect(SavedDamageValue.MUCH), - StaticFilters.FILTER_CONTROLLED_A_PERMANENT, SetTargetPointer.NONE, false); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); - - // {1}{R}: Howlpack Avenger gets +2/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect( - 2, 0, Duration.EndOfTurn - ), new ManaCostsImpl<>("{1}{R}"))); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private HowlpackAvenger(final HowlpackAvenger card) { - super(card); - } - - @Override - public HowlpackAvenger copy() { - return new HowlpackAvenger(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/HowlpackPiper.java b/Mage.Sets/src/mage/cards/h/HowlpackPiper.java index 577c869a305..1cd474f789b 100644 --- a/Mage.Sets/src/mage/cards/h/HowlpackPiper.java +++ b/Mage.Sets/src/mage/cards/h/HowlpackPiper.java @@ -1,20 +1,19 @@ package mage.cards.h; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.CantBeCounteredSourceAbility; +import mage.abilities.common.TransformsOrEntersTriggeredAbility; 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.keyword.DayboundAbility; +import mage.abilities.keyword.NightboundAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; @@ -28,29 +27,41 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class HowlpackPiper extends CardImpl { +public final class HowlpackPiper extends TransformingDoubleFacedCard { public HowlpackPiper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{3}{G}", + "Wildsong Howler", + 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(2); - this.secondSideCardClazz = mage.cards.w.WildsongHowler.class; + // Howlpack Piper + this.getLeftHalfCard().setPT(2, 2); // This spell can't be countered. - this.addAbility(new CantBeCounteredSourceAbility()); + this.getLeftHalfCard().addAbility(new CantBeCounteredSourceAbility()); // {1}{G}, {T}: You may put a creature card from your hand onto the battlefield. If it's a Wolf or Werewolf, untap Howlpack Piper. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility( new HowlpackPiperEffect(), new ManaCostsImpl<>("{1}{G}") ); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Wildsong Howler + this.getRightHalfCard().setPT(4, 4); + + // Whenever this creature enters the battlefield or transforms into Wildsong Howler, look at the top six cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. + this.getRightHalfCard().addAbility(new TransformsOrEntersTriggeredAbility( + new LookLibraryAndPickControllerEffect(6, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM), + false)); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private HowlpackPiper(final HowlpackPiper card) { diff --git a/Mage.Sets/src/mage/cards/h/HuatliPoetOfUnity.java b/Mage.Sets/src/mage/cards/h/HuatliPoetOfUnity.java index 83e01945e95..1d5c124a1b3 100644 --- a/Mage.Sets/src/mage/cards/h/HuatliPoetOfUnity.java +++ b/Mage.Sets/src/mage/cards/h/HuatliPoetOfUnity.java @@ -1,20 +1,28 @@ package mage.cards.h; -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.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.abilities.mana.RedManaAbility; +import mage.abilities.mana.WhiteManaAbility; 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.filter.FilterCard; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.game.permanent.token.DinosaurVanillaToken; import mage.target.common.TargetCardInLibrary; import java.util.UUID; @@ -22,30 +30,74 @@ import java.util.UUID; /** * @author Susucr */ -public final class HuatliPoetOfUnity extends CardImpl { +public final class HuatliPoetOfUnity extends TransformingDoubleFacedCard { + + private static final FilterCard filterCard = new FilterCard("Dinosaur card"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.DINOSAUR, "Dinosaurs you control"); + + static { + filterCard.add(SubType.DINOSAUR.getPredicate()); + } public HuatliPoetOfUnity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARRIOR, SubType.BARD}, "{2}{G}", + "Roar of the Fifth People", + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "RGW" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARRIOR); - this.subtype.add(SubType.BARD); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.r.RoarOfTheFifthPeople.class; + // Huatli, Poet of Unity + this.getLeftHalfCard().setPT(2, 3); // When Huatli, Poet of Unity enters the battlefield, search your library for a basic land card, reveal it, put it into your hand, then shuffle. TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true), false)); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true), false)); // {3}{R/W}{R/W}: Exile Huatli, then return her to the battlefield transformed under her owner's control. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{3}{R/W}{R/W}") ); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Roar of the Fifth People + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard(), SagaChapter.CHAPTER_IV); + + // I -- Create two 3/3 green Dinosaur creature tokens. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, new CreateTokenEffect(new DinosaurVanillaToken(), 2)); + + // II -- {this} gains "Creatures you control have '{T}: Add {R}, {G}, or {W}.'" + Ability gainedAbility = new SimpleStaticAbility(new GainAbilityControlledEffect( + new RedManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES, false + ).setText("Creatures you control have '{T}: Add {R}")); + gainedAbility.addEffect(new GainAbilityControlledEffect( + new GreenManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES, false + ).setText(", {G}")); + gainedAbility.addEffect(new GainAbilityControlledEffect( + new WhiteManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES, false + ).setText(", or {W}.'")); + + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_II, + new GainAbilitySourceEffect(gainedAbility, Duration.WhileOnBattlefield) + .setText("{this} gains \"Creatures you control have '{T}: Add {R}, {G}, or {W}.'\"")); + + // III -- Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle. + TargetCardInLibrary target2 = new TargetCardInLibrary(filterCard); + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_III, new SearchLibraryPutInHandEffect(target2, true)); + + // IV -- Dinosaurs you control gain double strike and trample until end of turn. + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_IV, + new GainAbilityControlledEffect( + DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, filter + ).setText("Dinosaurs you control gain double strike"), + new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn, filter + ).setText("and trample until end of turn") + ); + + this.getRightHalfCard().addAbility(sagaAbility); } private HuatliPoetOfUnity(final HuatliPoetOfUnity card) { 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/IcebergTitan.java b/Mage.Sets/src/mage/cards/i/IcebergTitan.java deleted file mode 100644 index b5422ca61da..00000000000 --- a/Mage.Sets/src/mage/cards/i/IcebergTitan.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.i; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.MayTapOrUntapTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class IcebergTitan extends CardImpl { - - public IcebergTitan(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.GOLEM); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.nightCard = true; - this.color.setBlue(true); - - // Whenever Iceberg Titan attacks, you may tap or untap target artifact or creature. - Ability ability = new AttacksTriggeredAbility(new MayTapOrUntapTargetEffect()); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); - this.addAbility(ability); - } - - private IcebergTitan(final IcebergTitan card) { - super(card); - } - - @Override - public IcebergTitan copy() { - return new IcebergTitan(this); - } -} diff --git a/Mage.Sets/src/mage/cards/i/IdolOfTheDeepKing.java b/Mage.Sets/src/mage/cards/i/IdolOfTheDeepKing.java index c76243b2c49..13abd8dc05f 100644 --- a/Mage.Sets/src/mage/cards/i/IdolOfTheDeepKing.java +++ b/Mage.Sets/src/mage/cards/i/IdolOfTheDeepKing.java @@ -1,13 +1,18 @@ package mage.cards.i; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAttachToTarget; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.CraftAbility; +import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.FlashAbility; -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 java.util.UUID; @@ -15,22 +20,36 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class IdolOfTheDeepKing extends CardImpl { +public final class IdolOfTheDeepKing extends TransformingDoubleFacedCard { public IdolOfTheDeepKing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{R}"); - this.secondSideCardClazz = mage.cards.s.SovereignsMacuahuitl.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}{R}", + "Sovereign's Macuahuitl", + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.EQUIPMENT}, "R" + ); + // Idol of the Deep King // Flash - this.addAbility(FlashAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlashAbility.getInstance()); // When Idol of the Deep King enters the battlefield, it deals 2 damage to any target. Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(2)); ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Craft with artifact {2}{R} - this.addAbility(new CraftAbility("{2}{R}")); + this.getLeftHalfCard().addAbility(new CraftAbility("{2}{R}")); + + // Sovereign's Macuahuitl + // When Sovereign's Macuahuitl enters the battlefield, attach it to target creature you control. + this.getRightHalfCard().addAbility(new EntersBattlefieldAttachToTarget()); + + // Equipped creature gets +2/+0. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 0))); + + // Equip {2} + this.getRightHalfCard().addAbility(new EquipAbility(2)); } private IdolOfTheDeepKing(final IdolOfTheDeepKing card) { diff --git a/Mage.Sets/src/mage/cards/i/IllTemperedLoner.java b/Mage.Sets/src/mage/cards/i/IllTemperedLoner.java index 08b861d29d1..2c789994b55 100644 --- a/Mage.Sets/src/mage/cards/i/IllTemperedLoner.java +++ b/Mage.Sets/src/mage/cards/i/IllTemperedLoner.java @@ -1,7 +1,7 @@ package mage.cards.i; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.DealtDamageAnyTriggeredAbility; import mage.abilities.common.DealtDamageToSourceTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -9,11 +9,14 @@ import mage.abilities.dynamicvalue.common.SavedDamageValue; import mage.abilities.effects.common.DamageTargetEffect; 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.SetTargetPointer; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.target.common.TargetAnyTarget; import java.util.UUID; @@ -21,30 +24,48 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class IllTemperedLoner extends CardImpl { +public final class IllTemperedLoner extends TransformingDoubleFacedCard { public IllTemperedLoner(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{2}{R}{R}", + "Howlpack Avenger", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.h.HowlpackAvenger.class; + // Ill-Tempered Loner + this.getLeftHalfCard().setPT(3, 3); // Whenever Ill-Tempered Loner is dealt damage, it deals that much damage to any target. Ability ability = new DealtDamageToSourceTriggeredAbility( new DamageTargetEffect(SavedDamageValue.MUCH, "it"), false); ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {1}{R}: Ill-Tempered Loner gets +2/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(new BoostSourceEffect( + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new BoostSourceEffect( 2, 0, Duration.EndOfTurn ), new ManaCostsImpl<>("{1}{R}"))); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Howlpack Avenger + this.getRightHalfCard().setPT(4, 4); + + // Whenever a permanent you control is dealt damage, Howlpack Avenger deals that much damage to any target. + Ability backAbility = new DealtDamageAnyTriggeredAbility(new DamageTargetEffect(SavedDamageValue.MUCH), + StaticFilters.FILTER_CONTROLLED_A_PERMANENT, SetTargetPointer.NONE, false); + backAbility.addTarget(new TargetAnyTarget()); + this.getRightHalfCard().addAbility(backAbility); + + // {1}{R}: Howlpack Avenger gets +2/+0 until end of turn. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new BoostSourceEffect( + 2, 0, Duration.EndOfTurn + ), new ManaCostsImpl<>("{1}{R}"))); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private IllTemperedLoner(final IllTemperedLoner card) { diff --git a/Mage.Sets/src/mage/cards/i/ImpoliteEntrance.java b/Mage.Sets/src/mage/cards/i/ImpoliteEntrance.java new file mode 100644 index 00000000000..49ffc1fb54e --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/ImpoliteEntrance.java @@ -0,0 +1,40 @@ +package mage.cards.i; + +import java.util.UUID; + +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author muz + */ +public final class ImpoliteEntrance extends CardImpl { + + public ImpoliteEntrance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); + + // Target creature gains trample and haste until end of turn. + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()).setText("target creature gains trample")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance()).setText("and haste until end of turn.")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
")); + } + + private ImpoliteEntrance(final ImpoliteEntrance card) { + super(card); + } + + @Override + public ImpoliteEntrance copy() { + return new ImpoliteEntrance(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/Impulsivity.java b/Mage.Sets/src/mage/cards/i/Impulsivity.java new file mode 100644 index 00000000000..b703a77b8f5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/Impulsivity.java @@ -0,0 +1,51 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.MayCastTargetCardEffect; +import mage.abilities.keyword.EncoreAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.CastManaAdjustment; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Impulsivity extends CardImpl { + + public Impulsivity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(7); + this.toughness = new MageInt(5); + + // When this creature enters, you may cast target instant or sorcery card from a graveyard without paying its mana cost. If that spell would be put into a graveyard, exile it instead. + Ability ability = new EntersBattlefieldTriggeredAbility( + new MayCastTargetCardEffect(CastManaAdjustment.WITHOUT_PAYING_MANA_COST, true) + ); + ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY)); + this.addAbility(ability); + + // Encore {7}{R}{R} + this.addAbility(new EncoreAbility(new ManaCostsImpl<>("{7}{R}{R}"))); + } + + private Impulsivity(final Impulsivity card) { + super(card); + } + + @Override + public Impulsivity copy() { + return new Impulsivity(this); + } +} 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/InfestationExpert.java b/Mage.Sets/src/mage/cards/i/InfestationExpert.java index b5bd768744e..726d58f041d 100644 --- a/Mage.Sets/src/mage/cards/i/InfestationExpert.java +++ b/Mage.Sets/src/mage/cards/i/InfestationExpert.java @@ -1,11 +1,11 @@ package mage.cards.i; -import mage.MageInt; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; 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.game.permanent.token.InsectToken; @@ -15,24 +15,36 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InfestationExpert extends CardImpl { +public final class InfestationExpert extends TransformingDoubleFacedCard { public InfestationExpert(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}", + "Infested Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.i.InfestedWerewolf.class; + // Infestation Expert + this.getLeftHalfCard().setPT(3, 4); // Whenever Infestation Expert enters the battlefield or attacks, create a 1/1 green Insect creature token. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( new CreateTokenEffect(new InsectToken()) )); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Infested Werewolf + this.getRightHalfCard().setPT(4, 5); + + // Whenever Infested Werewolf enters the battlefield or attacks, create two 1/1 green Insect creature token. + this.getRightHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( + new CreateTokenEffect(new InsectToken(), 2) + )); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private InfestationExpert(final InfestationExpert card) { diff --git a/Mage.Sets/src/mage/cards/i/InfestedWerewolf.java b/Mage.Sets/src/mage/cards/i/InfestedWerewolf.java deleted file mode 100644 index 96f815e0c32..00000000000 --- a/Mage.Sets/src/mage/cards/i/InfestedWerewolf.java +++ /dev/null @@ -1,46 +0,0 @@ -package mage.cards.i; - -import mage.MageInt; -import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.game.permanent.token.InsectToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class InfestedWerewolf extends CardImpl { - - public InfestedWerewolf(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(5); - this.color.setGreen(true); - this.nightCard = true; - - // Whenever Infested Werewolf enters the battlefield or attacks, create two 1/1 green Insect creature token. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility( - new CreateTokenEffect(new InsectToken(), 2) - )); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private InfestedWerewolf(final InfestedWerewolf card) { - super(card); - } - - @Override - public InfestedWerewolf copy() { - return new InfestedWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/i/InheritedFiend.java b/Mage.Sets/src/mage/cards/i/InheritedFiend.java deleted file mode 100644 index 22343bddfb5..00000000000 --- a/Mage.Sets/src/mage/cards/i/InheritedFiend.java +++ /dev/null @@ -1,52 +0,0 @@ -package mage.cards.i; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.counters.CounterType; -import mage.filter.StaticFilters; -import mage.target.common.TargetCardInGraveyard; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class InheritedFiend extends CardImpl { - - public InheritedFiend(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.DEMON); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // {2}{B}: Exile target creature card from a graveyard. Put a +1/+1 counter on Inherited Fiend. - Ability ability = new SimpleActivatedAbility(new ExileTargetEffect(), new ManaCostsImpl<>("{2}{B}")); - ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()).concatBy(".")); - ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_A_GRAVEYARD)); - this.addAbility(ability); - } - - private InheritedFiend(final InheritedFiend card) { - super(card); - } - - @Override - public InheritedFiend copy() { - return new InheritedFiend(this); - } -} diff --git a/Mage.Sets/src/mage/cards/i/InnocentTraveler.java b/Mage.Sets/src/mage/cards/i/InnocentTraveler.java index 76e0b94422b..3987e659882 100644 --- a/Mage.Sets/src/mage/cards/i/InnocentTraveler.java +++ b/Mage.Sets/src/mage/cards/i/InnocentTraveler.java @@ -1,13 +1,20 @@ package mage.cards.i; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.OpponentControlsPermanentCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.FlyingAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterPermanent; @@ -22,19 +29,36 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InnocentTraveler extends CardImpl { +public final class InnocentTraveler extends TransformingDoubleFacedCard { + + private static final FilterPermanent humanFilter = new FilterPermanent(SubType.HUMAN, "an opponent controls a Human"); + private static final Condition condition = new OpponentControlsPermanentCondition(humanFilter); + private static final Hint hint = new ConditionHint(condition, "An opponent controls a Human"); public InnocentTraveler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN}, "{2}{B}{B}", + "Malicious Invader", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE}, "B" + ); - this.subtype.add(SubType.HUMAN); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.m.MaliciousInvader.class; + // Innocent Traveler + this.getLeftHalfCard().setPT(1, 3); // At the beginning of your upkeep, any opponent may sacrifice a creature. If no one does, transform Innocent Traveler. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new InnocentTravelerEffect())); + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new InnocentTravelerEffect())); + + // Malicious Invader + this.getRightHalfCard().setPT(3, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Malicious Invader gets +2/+0 as long as an opponent controls a Human. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(2, 0, Duration.WhileOnBattlefield), + condition, "{this} gets +2/+0 as long as an opponent controls a Human" + )).addHint(hint)); } private InnocentTraveler(final InnocentTraveler card) { diff --git a/Mage.Sets/src/mage/cards/i/InstigatorGang.java b/Mage.Sets/src/mage/cards/i/InstigatorGang.java index a88e96462f2..cfd163c2d97 100644 --- a/Mage.Sets/src/mage/cards/i/InstigatorGang.java +++ b/Mage.Sets/src/mage/cards/i/InstigatorGang.java @@ -1,12 +1,12 @@ package mage.cards.i; -import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.effects.common.continuous.BoostControlledEffect; -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.SubType; @@ -17,27 +17,41 @@ import java.util.UUID; /** * @author nantuko */ -public final class InstigatorGang extends CardImpl { +public final class InstigatorGang extends TransformingDoubleFacedCard { public InstigatorGang(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{3}{R}", + "Wildblood Pack", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.w.WildbloodPack.class; - - this.power = new MageInt(2); - this.toughness = new MageInt(3); + // Instigator Gang + this.getLeftHalfCard().setPT(2, 3); // Attacking creatures you control get +1/+0. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect( 1, 0, Duration.WhileOnBattlefield, StaticFilters.FILTER_ATTACKING_CREATURES ))); // At the beginning of each upkeep, if no spells were cast last turn, transform Instigator Gang. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Wildblood Pack + this.getRightHalfCard().setPT(5, 5); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Attacking creatures you control get +3/+0. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect( + 3, 0, Duration.WhileOnBattlefield, + StaticFilters.FILTER_ATTACKING_CREATURES, false + ))); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Wildblood Pack. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private InstigatorGang(final InstigatorGang card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfAlara.java b/Mage.Sets/src/mage/cards/i/InvasionOfAlara.java index fd2160e9b63..cb0cb01ab51 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfAlara.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfAlara.java @@ -3,17 +3,27 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; import mage.cards.*; 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.Permanent; import mage.players.Player; import mage.target.TargetCard; +import mage.target.TargetPermanent; +import mage.target.TargetPlayer; import mage.target.common.TargetCardInExile; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanentAmount; +import mage.target.common.TargetPermanentAmount; +import mage.target.targetpointer.SecondTargetPointer; import mage.util.CardUtil; import java.util.UUID; @@ -21,21 +31,43 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfAlara extends CardImpl { +public final class InvasionOfAlara extends TransformingDoubleFacedCard { public InvasionOfAlara(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{W}{U}{B}{R}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{W}{U}{B}{R}{G}", + "Awaken the Maelstrom", + new CardType[]{CardType.SORCERY}, new SubType[]{}, "WUBRG" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(7); - this.secondSideCardClazz = mage.cards.a.AwakenTheMaelstrom.class; + // Invasion of Alara + this.getLeftHalfCard().setStartingDefense(7); - Ability ability = new SiegeAbility(); - ability.setRuleVisible(false); - this.addAbility(ability); + Ability siegeAbility = new SiegeAbility(); + siegeAbility.setRuleVisible(false); + this.getLeftHalfCard().addAbility(siegeAbility); // When Invasion of Alara enters the battlefield, exile cards from the top of your library until you exile two nonland cards with mana value 4 or less. You may cast one of those two cards without paying its mana cost. Put one of them into your hand. Then put the other cards exiled this way on the bottom of your library in a random order. - this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfAlaraEffect())); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfAlaraEffect())); + + // Awaken the Maelstrom + // Awaken the Maelstrom is all colors. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("{this} is all colors"))); + + // Target player draws two cards. + this.getRightHalfCard().getSpellAbility().addEffect(new DrawCardTargetEffect(2)); + this.getRightHalfCard().getSpellAbility().addTarget(new TargetPlayer().withChooseHint("to draw two cards")); + + // You may put an artifact card from your hand onto the battlefield. + this.getRightHalfCard().getSpellAbility().addEffect(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_ARTIFACT_AN)); + + // Create a token that's a copy of a permanent you control. + // Distribute three +1/+1 counters among one, two, or three creatures you control. + this.getRightHalfCard().getSpellAbility().addEffect(new AwakenTheMaelstromEffect()); + + // Destroy target permanent an opponent controls. + this.getRightHalfCard().getSpellAbility().addEffect(new DestroyTargetEffect().setTargetPointer(new SecondTargetPointer())); + this.getRightHalfCard().getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT).withChooseHint("to destroy")); } private InvasionOfAlara(final InvasionOfAlara card) { @@ -101,3 +133,63 @@ class InvasionOfAlaraEffect extends OneShotEffect { return true; } } + +class AwakenTheMaelstromEffect extends OneShotEffect { + + AwakenTheMaelstromEffect() { + super(Outcome.Benefit); + staticText = "Create a token that's a copy of a permanent you control. " + + "Distribute three +1/+1 counters among one, two, or three creatures you control."; + } + + private AwakenTheMaelstromEffect(final AwakenTheMaelstromEffect effect) { + super(effect); + } + + @Override + public AwakenTheMaelstromEffect copy() { + return new AwakenTheMaelstromEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + makeToken(player, game, source); + game.processAction(); + distributeCounters(player, game, source); + return true; + } + + private void makeToken(Player player, Game game, Ability source) { + TargetPermanent target = new TargetControlledPermanent(); + target.withNotTarget(true); + target.withChooseHint("to copy"); + if (!target.canChoose(player.getId(), source, game)) { + return; + } + player.choose(outcome, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent != null) { + new CreateTokenCopyTargetEffect().setSavedPermanent(permanent).apply(game, source); + } + } + + private void distributeCounters(Player player, Game game, Ability source) { + if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game) < 1) { + return; + } + TargetPermanentAmount target = new TargetCreaturePermanentAmount(3, StaticFilters.FILTER_CONTROLLED_CREATURE); + target.withNotTarget(true); + target.withChooseHint("to distribute counters"); + target.chooseTarget(outcome, player.getId(), source, game); + for (UUID targetId : target.getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(target.getTargetAmount(targetId)), source, game); + } + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfAmonkhet.java b/Mage.Sets/src/mage/cards/i/InvasionOfAmonkhet.java index 804e097c03a..9d15910563e 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfAmonkhet.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfAmonkhet.java @@ -1,33 +1,47 @@ package mage.cards.i; +import mage.MageObject; +import mage.ObjectColor; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CopyEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.MillCardsEachPlayerEffect; import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInGraveyard; +import mage.util.functions.CopyApplier; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfAmonkhet extends CardImpl { +public final class InvasionOfAmonkhet extends TransformingDoubleFacedCard { public InvasionOfAmonkhet(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{U}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{1}{U}{B}", + "Lazotep Convert", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ZOMBIE}, "UB" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.l.LazotepConvert.class; + // Invasion of Amonkhet + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Amonkhet enters the battlefield, each player mills three cards, then each opponent discards a card and you draw a card. Ability ability = new EntersBattlefieldTriggeredAbility( @@ -35,7 +49,13 @@ public final class InvasionOfAmonkhet extends CardImpl { ); ability.addEffect(new DiscardEachPlayerEffect(TargetController.OPPONENT).concatBy(", then")); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and you")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Lazotep Convert + this.getRightHalfCard().setPT(4, 4); + + // You may have Lazotep Convert enter the battlefield as a copy of any creature card in a graveyard, except it's a 4/4 black Zombie in addition to its other types. + this.getRightHalfCard().addAbility(new EntersBattlefieldAbility(new LazotepConvertCopyEffect(), true)); } private InvasionOfAmonkhet(final InvasionOfAmonkhet card) { @@ -47,3 +67,59 @@ public final class InvasionOfAmonkhet extends CardImpl { return new InvasionOfAmonkhet(this); } } + +class LazotepConvertCopyEffect extends OneShotEffect { + + private static final CopyApplier applier = new CopyApplier() { + + @Override + public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) { + blueprint.removePTCDA(); + blueprint.getPower().setModifiedBaseValue(4); + blueprint.getToughness().setModifiedBaseValue(4); + blueprint.addSubType(SubType.ZOMBIE); + blueprint.getColor().addColor(ObjectColor.BLACK); + return true; + } + }; + + private static final FilterCard filter = new FilterCreatureCard("creature card in a graveyard"); + + public LazotepConvertCopyEffect() { + super(Outcome.Copy); + this.staticText = "as a copy of any creature card in a graveyard, " + + "except it's a 4/4 black Zombie in addition to its other colors and types"; + } + + private LazotepConvertCopyEffect(final LazotepConvertCopyEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Target target = new TargetCardInGraveyard(0, 1, filter); + target.withNotTarget(true); + player.choose(outcome, target, source, game); + Card copyFromCard = game.getCard(target.getFirstTarget()); + if (copyFromCard == null) { + return true; + } + Card modifiedCopy = copyFromCard.copy(); + //Appliers must be applied before CopyEffect, its applier setting is just for copies of copies + // TODO: research applier usage, why it here + applier.apply(game, modifiedCopy, source, source.getSourceId()); + game.addEffect(new CopyEffect( + Duration.Custom, modifiedCopy, source.getSourceId() + ).setApplier(applier), source); + return true; + } + + @Override + public LazotepConvertCopyEffect copy() { + return new LazotepConvertCopyEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfArcavios.java b/Mage.Sets/src/mage/cards/i/InvasionOfArcavios.java index 5e9b57214d3..7937789e674 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfArcavios.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfArcavios.java @@ -3,16 +3,22 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.WishEffect; import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; -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.constants.Zone; +import mage.filter.FilterSpell; import mage.filter.StaticFilters; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.filter.predicate.card.CastFromZonePredicate; import mage.game.Game; +import mage.game.stack.Spell; import mage.players.Player; import java.util.UUID; @@ -20,20 +26,36 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfArcavios extends CardImpl { +public final class InvasionOfArcavios extends TransformingDoubleFacedCard { + + private static final FilterSpell filter + = new FilterInstantOrSorcerySpell("an instant or sorcery spell from your hand"); + + static { + filter.add(new CastFromZonePredicate(Zone.HAND)); + } public InvasionOfArcavios(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{U}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{U}{U}", + "Invocation of the Founders", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "U" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(7); - this.secondSideCardClazz = mage.cards.i.InvocationOfTheFounders.class; + // Invasion of Arcavios + this.getLeftHalfCard().setStartingDefense(7); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Arcavios enters the battlefield, search your library, graveyard, and/or outside the game for an instant or sorcery card you own, reveal it, and put it into your hand. If you search your library this way, shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfArcaviosEffect())); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfArcaviosEffect())); + + // Invocation of the Founders + // Whenever you cast an instant or sorcery spell from your hand, you may copy that spell. You may choose new targets for the copy. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new InvocationOfTheFoundersEffect(), filter, true + )); } private InvasionOfArcavios(final InvasionOfArcavios card) { @@ -78,3 +100,30 @@ class InvasionOfArcaviosEffect extends OneShotEffect { ).apply(game, source); } } + +class InvocationOfTheFoundersEffect extends OneShotEffect { + + InvocationOfTheFoundersEffect() { + super(Outcome.Benefit); + staticText = "copy that spell. You may choose new targets for the copy"; + } + + private InvocationOfTheFoundersEffect(final InvocationOfTheFoundersEffect effect) { + super(effect); + } + + @Override + public InvocationOfTheFoundersEffect copy() { + return new InvocationOfTheFoundersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Spell spell = (Spell) getValue("spellCast"); + if (spell != null) { + spell.createCopyOnStack(game, source, source.getControllerId(), true); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfAzgol.java b/Mage.Sets/src/mage/cards/i/InvasionOfAzgol.java index 4e01acdf485..b7f157d7d19 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfAzgol.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfAzgol.java @@ -3,32 +3,45 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.abilities.effects.common.SacrificeEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardSetInfo; -import mage.cards.a.AshenReaper; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.WatcherScope; +import mage.counters.CounterType; import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; import mage.target.TargetPlayer; +import mage.watchers.Watcher; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfAzgol extends CardImpl { +public final class InvasionOfAzgol extends TransformingDoubleFacedCard { public InvasionOfAzgol(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{B}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{B}{R}", + "Ashen Reaper", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ZOMBIE, SubType.ELEMENTAL}, "BR" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.a.AshenReaper.class; + // Invasion of Azgol + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Azgol enters the battlefield, target player sacrifices a creature or planeswalker and loses 1 life. Ability ability = new EntersBattlefieldTriggeredAbility(new SacrificeEffect( @@ -36,7 +49,23 @@ public final class InvasionOfAzgol extends CardImpl { )); ability.addEffect(new LoseLifeTargetEffect(1).setText("and loses 1 life")); ability.addTarget(new TargetPlayer()); - this.addAbility(ability, AshenReaper.makeWatcher()); + ability.addWatcher(new AshenReaperWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Ashen Reaper + this.getRightHalfCard().setPT(2, 1); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // At the beginning of your end step, put a +1/+1 counter on Ashen Reaper if a permanent was put into a graveyard from the battlefield this turn. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility( + new ConditionalOneShotEffect( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), + AshenReaperCondition.instance, "put a +1/+1 counter on {this} " + + "if a permanent was put into a graveyard from the battlefield this turn" + ) + )); } private InvasionOfAzgol(final InvasionOfAzgol card) { @@ -48,3 +77,27 @@ public final class InvasionOfAzgol extends CardImpl { return new InvasionOfAzgol(this); } } + +enum AshenReaperCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return game.getState().getWatcher(AshenReaperWatcher.class).conditionMet(); + } +} + +class AshenReaperWatcher extends Watcher { + + AshenReaperWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ZONE_CHANGE + && ((ZoneChangeEvent) event).isDiesEvent()) { + condition = true; + } + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfDominaria.java b/Mage.Sets/src/mage/cards/i/InvasionOfDominaria.java index be85c55fce3..0a4a3619e4c 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfDominaria.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfDominaria.java @@ -5,8 +5,10 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -15,22 +17,34 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfDominaria extends CardImpl { +public final class InvasionOfDominaria extends TransformingDoubleFacedCard { public InvasionOfDominaria(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{W}", + "Serra Faithkeeper", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ANGEL}, "W" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.s.SerraFaithkeeper.class; + // Invasion of Dominaria + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Dominaria enters the battlefield, you gain 4 life and draw a card. Ability ability = new EntersBattlefieldTriggeredAbility(new GainLifeEffect(4)); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Serra Faithkeeper + this.getRightHalfCard().setPT(4, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); } private InvasionOfDominaria(final InvasionOfDominaria card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfEldraine.java b/Mage.Sets/src/mage/cards/i/InvasionOfEldraine.java index c42444b31d7..1a13b1e4fe7 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfEldraine.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfEldraine.java @@ -3,11 +3,15 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CardsInHandCondition; +import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.target.common.TargetOpponent; import java.util.UUID; @@ -15,22 +19,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfEldraine extends CardImpl { +public final class InvasionOfEldraine extends TransformingDoubleFacedCard { + + private static final Condition condition = new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, TargetController.ACTIVE); public InvasionOfEldraine(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{B}", + "Prickle Faeries", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.FAERIE}, "B" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.p.PrickleFaeries.class; + // Invasion of Eldraine + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Eldraine enters the battlefield, target opponent discards two cards. Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(2)); ability.addTarget(new TargetOpponent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Prickle Faeries + this.getRightHalfCard().setPT(2, 2); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Prickle Faeries deals 2 damage to them. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility( + Zone.BATTLEFIELD, TargetController.OPPONENT, + new DamageTargetEffect(2).withTargetDescription("them"), false + ).withInterveningIf(condition)); } private InvasionOfEldraine(final InvasionOfEldraine card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfErgamon.java b/Mage.Sets/src/mage/cards/i/InvasionOfErgamon.java index 4a7e2e63e7f..2fdafc9c45e 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfErgamon.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfErgamon.java @@ -7,33 +7,60 @@ import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetCardInLibrary; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfErgamon extends CardImpl { +public final class InvasionOfErgamon extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard("a land or battle card"); + + static { + filter.add(Predicates.or(CardType.LAND.getPredicate(), CardType.BATTLE.getPredicate())); + } public InvasionOfErgamon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{R}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{R}{G}", + "Truga Cliffcharger", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.RHINO}, "RG" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.t.TrugaCliffcharger.class; + // Invasion of Ergamon + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Ergamon enters the battlefield, create a Treasure token. Then you may discard a card. If you do, draw a card. Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken())); ability.addEffect(new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost()).concatBy("Then")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Truga Cliffcharger + this.getRightHalfCard().setPT(3, 4); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // When Truga Cliffcharger enters the battlefield, you may discard a card. If you do, search your library for a land or battle card, reveal it, put it into your hand, then shuffle. + this.getRightHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( + new DoIfCostPaid(new SearchLibraryPutInHandEffect( + new TargetCardInLibrary(filter), true + ), new DiscardCardCost()) + )); } private InvasionOfErgamon(final InvasionOfErgamon card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java b/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java index 339488dbb37..df1a598c3de 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfFiora.java @@ -2,53 +2,94 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.Mode; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.condition.Condition; import mage.abilities.effects.common.DestroyAllEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.counter.RemoveAllCountersPermanentTargetEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; -import mage.cards.m.MarchesaResoluteMonarch; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; +import mage.constants.WatcherScope; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.events.DamagedEvent; +import mage.game.events.GameEvent; +import mage.target.TargetPermanent; +import mage.watchers.Watcher; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfFiora extends CardImpl { +public final class InvasionOfFiora extends TransformingDoubleFacedCard { - private static final FilterPermanent filter = new FilterCreaturePermanent("legendary creatures"); - private static final FilterPermanent filter2 = new FilterCreaturePermanent("nonlegendary creatures"); + private static final FilterPermanent filterLegend = new FilterCreaturePermanent("legendary creatures"); + private static final FilterPermanent filterNonLegend = new FilterCreaturePermanent("nonlegendary creatures"); static { - filter.add(SuperType.LEGENDARY.getPredicate()); - filter2.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); + filterLegend.add(SuperType.LEGENDARY.getPredicate()); + filterNonLegend.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); } public InvasionOfFiora(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{B}{B}"); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{4}{B}{B}", + "Marchesa, Resolute Monarch", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE}, "B" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.m.MarchesaResoluteMonarch.class; + // Invasion of Fiora + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Fiora enters the battlefield, choose one or both -- + // * Destroy all legendary creatures. - Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter)); + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filterLegend)); ability.getModes().setMinModes(1); ability.getModes().setMaxModes(2); // * Destroy all nonlegendary creatures. - ability.addMode(new Mode(new DestroyAllEffect(filter2))); - this.addAbility(ability, MarchesaResoluteMonarch.makeWatcher()); + ability.addMode(new Mode(new DestroyAllEffect(filterNonLegend))); + ability.addWatcher(new MarchesaResoluteMonarchWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Marchesa, Resolute Monarch + this.getRightHalfCard().setPT(3, 6); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Deathtouch + this.getRightHalfCard().addAbility(DeathtouchAbility.getInstance()); + + // Whenever Marchesa, Resolute Monarch attacks, remove all counters from up to one target permanent. + Ability attackAbility = new AttacksTriggeredAbility(new RemoveAllCountersPermanentTargetEffect()); + attackAbility.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT)); + this.getRightHalfCard().addAbility(attackAbility); + + // At the beginning of your upkeep, if you haven't been dealt combat damage since your last turn, you draw a card and you lose 1 life. + Ability upkeepAbility = new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1, true)) + .withInterveningIf(MarchesaResoluteMonarchCondition.instance); + upkeepAbility.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); + this.getRightHalfCard().addAbility(upkeepAbility); } private InvasionOfFiora(final InvasionOfFiora card) { @@ -60,3 +101,49 @@ public final class InvasionOfFiora extends CardImpl { return new InvasionOfFiora(this); } } + +enum MarchesaResoluteMonarchCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return MarchesaResoluteMonarchWatcher.checkPlayer(game, source); + } + + @Override + public String toString() { + return "you haven't been dealt combat damage since your last turn"; + } +} + +class MarchesaResoluteMonarchWatcher extends Watcher { + + private final Set players = new HashSet<>(); + + MarchesaResoluteMonarchWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + switch (event.getType()) { + case DAMAGED_PLAYER: + if (((DamagedEvent) event).isCombatDamage()) { + players.add(event.getTargetId()); + } + return; + case END_TURN_STEP_POST: + players.remove(game.getActivePlayerId()); + return; + + } + } + + static boolean checkPlayer(Game game, Ability source) { + return !game + .getState() + .getWatcher(MarchesaResoluteMonarchWatcher.class) + .players + .contains(source.getControllerId()); + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfGobakhan.java b/Mage.Sets/src/mage/cards/i/InvasionOfGobakhan.java index d44cf14a51b..c507c2a5339 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfGobakhan.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfGobakhan.java @@ -5,18 +5,25 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.counters.CounterType; 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.TargetCardInHand; import mage.target.common.TargetOpponent; import mage.util.CardUtil; import mage.watchers.common.AttackedThisTurnWatcher; @@ -26,22 +33,42 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfGobakhan extends CardImpl { +public final class InvasionOfGobakhan extends TransformingDoubleFacedCard { public InvasionOfGobakhan(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{1}{W}", + "Lightshield Array", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "W" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(3); - this.secondSideCardClazz = mage.cards.l.LightshieldArray.class; + // Invasion of Gobakhan + this.getLeftHalfCard().setStartingDefense(3); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Gobakhan enters the battlefield, look at target opponent's hand. You may exile a nonland card from it. For as long as that card remains exiled, its owner may play it. A spell cast this way costs {2} more to cast. Ability ability = new EntersBattlefieldTriggeredAbility(new InvasionOfGobakhanEffect()); ability.addTarget(new TargetOpponent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Lightshield Array + // At the beginning of your end step, put a +1/+1 counter on each creature that attacked this turn. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new LightshieldArrayEffect())); + + // Sacrifice Lightshield Array: Creatures you control gain hexproof and indestructible until end of turn. + Ability rightAbility = new SimpleActivatedAbility( + new GainAbilityControlledEffect( + HexproofAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("creatures you control gain hexproof"), new SacrificeSourceCost() + ); + rightAbility.addEffect(new GainAbilityControlledEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("and indestructible until end of turn")); + this.getRightHalfCard().addAbility(rightAbility); } private InvasionOfGobakhan(final InvasionOfGobakhan card) { @@ -96,7 +123,7 @@ class InvasionOfGobakhanCastEffect extends AsThoughEffectImpl { private final MageObjectReference mor; - public InvasionOfGobakhanCastEffect(Card card, Game game) { + InvasionOfGobakhanCastEffect(Card card, Game game) { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); this.mor = new MageObjectReference(card, game); } @@ -123,8 +150,7 @@ class InvasionOfGobakhanCastEffect extends AsThoughEffectImpl { discard(); return false; } - return mor.refersTo(CardUtil.getMainCardId(game, sourceId), game) - && card.isOwnedBy(affectedControllerId); + return mor.refersTo(CardUtil.getMainCardId(game, sourceId), game) && card.isOwnedBy(affectedControllerId); } } @@ -153,10 +179,10 @@ class InvasionOfGobakhanCostEffect extends CostModificationEffectImpl { if (!(abilityToModify instanceof SpellAbility)) { return false; } - if (game.inCheckPlayableState()) { // during playable check, the card is still in exile zone, the zcc is one less - UUID cardtoCheckId = CardUtil.getMainCardId(game, abilityToModify.getSourceId()); - return mor.getSourceId().equals(cardtoCheckId) - && mor.getZoneChangeCounter() == game.getState().getZoneChangeCounter(cardtoCheckId) + 1; + if (game.inCheckPlayableState()) { + UUID cardToCheckId = CardUtil.getMainCardId(game, abilityToModify.getSourceId()); + return mor.getSourceId().equals(cardToCheckId) + && mor.getZoneChangeCounter() == game.getState().getZoneChangeCounter(cardToCheckId) + 1; } else { return mor.refersTo(CardUtil.getMainCardId(game, abilityToModify.getSourceId()), game); } @@ -167,3 +193,34 @@ class InvasionOfGobakhanCostEffect extends CostModificationEffectImpl { return new InvasionOfGobakhanCostEffect(this); } } + +class LightshieldArrayEffect extends OneShotEffect { + + LightshieldArrayEffect() { + super(Outcome.Benefit); + staticText = "put a +1/+1 counter on each creature that attacked this turn"; + } + + private LightshieldArrayEffect(final LightshieldArrayEffect effect) { + super(effect); + } + + @Override + public LightshieldArrayEffect copy() { + return new LightshieldArrayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (MageObjectReference mor : game + .getState() + .getWatcher(AttackedThisTurnWatcher.class) + .getAttackedThisTurnCreatures()) { + Permanent permanent = mor.getPermanent(game); + if (permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(), source, game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java b/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java index babbe2657ba..6f71ad803ce 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfIkoria.java @@ -1,27 +1,32 @@ package mage.cards.i; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.GetXValue; +import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.common.search.SearchLibraryGraveyardPutOntoBattlefieldEffect; +import mage.abilities.keyword.ReachAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.Predicates; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfIkoria extends CardImpl { +public final class InvasionOfIkoria extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterCreatureCard("non-Human creature card with mana value X or less"); @@ -31,17 +36,29 @@ public final class InvasionOfIkoria extends CardImpl { } public InvasionOfIkoria(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{X}{G}{G}"); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{X}{G}{G}", + "Zilortha, Apex of Ikoria", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DINOSAUR}, "G" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(6); - this.secondSideCardClazz = mage.cards.z.ZilorthaApexOfIkoria.class; + // Invasion of Ikoria + this.getLeftHalfCard().setStartingDefense(6); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Ikoria enters the battlefield, search your library and/or graveyard for a non-Human creature card with mana value X or less and put it onto the battlefield. If you search your library this way, shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutOntoBattlefieldEffect(filter))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutOntoBattlefieldEffect(filter))); + + // Zilortha, Apex of Ikoria + this.getRightHalfCard().setPT(8, 8); + + // Reach + this.getRightHalfCard().addAbility(ReachAbility.getInstance()); + + // For each non-Human creature you control, you may have that creature assign its combat damage as though it weren't blocked. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new ZilorthaApexOfIkoriaEffect())); } private InvasionOfIkoria(final InvasionOfIkoria card) { @@ -59,7 +76,41 @@ enum InvasionOfIkoriaPredicate implements ObjectSourcePlayerPredicate { @Override public boolean apply(ObjectSourcePlayer input, Game game) { - return input.getObject().getManaValue() - <= GetXValue.instance.calculate(game, input.getSource(), null); + return input.getObject().getManaValue() <= GetXValue.instance.calculate(game, input.getSource(), null); } -} \ No newline at end of file +} + +class ZilorthaApexOfIkoriaEffect extends AsThoughEffectImpl { + + ZilorthaApexOfIkoriaEffect() { + super(AsThoughEffectType.DAMAGE_NOT_BLOCKED, Duration.WhileOnBattlefield, Outcome.Damage); + this.staticText = "for each non-Human creature you control, you may have that " + + "creature assign its combat damage as though it weren't blocked"; + } + + private ZilorthaApexOfIkoriaEffect(ZilorthaApexOfIkoriaEffect effect) { + super(effect); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(sourceId); + return controller != null + && permanent != null + && permanent.isControlledBy(controller.getId()) + && !permanent.hasSubtype(SubType.HUMAN, game) + && controller.chooseUse(Outcome.Damage, "Have " + permanent.getLogName() + + " assign damage as though it weren't blocked?", source, game); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ZilorthaApexOfIkoriaEffect copy() { + return new ZilorthaApexOfIkoriaEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfInnistrad.java b/Mage.Sets/src/mage/cards/i/InvasionOfInnistrad.java index 5505e05ceae..de4ac0e8e43 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfInnistrad.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfInnistrad.java @@ -3,12 +3,23 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.keyword.FlashAbility; -import mage.cards.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; +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.game.permanent.token.ZombieToken; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetOpponentsCreaturePermanent; import java.util.UUID; @@ -16,25 +27,37 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfInnistrad extends CardImpl { +public final class InvasionOfInnistrad extends TransformingDoubleFacedCard { public InvasionOfInnistrad(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{B}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{B}{B}", + "Deluge of the Dead", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "B" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.d.DelugeOfTheDead.class; + // Invasion of Innistrad + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // Flash - this.addAbility(FlashAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlashAbility.getInstance()); // When Invasion of Innistrad enters the battlefield, target creature an opponent controls gets -13/-13 until end of turn. Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(-13, -13)); ability.addTarget(new TargetOpponentsCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Deluge of the Dead + // When Deluge of the Dead enters the battlefield, create two 2/2 black Zombie creature tokens. + this.getRightHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ZombieToken(), 2))); + + // {2}{B}: Exile target card from a graveyard. If it was a creature card, create a 2/2 black Zombie creature token. + Ability rightAbility = new SimpleActivatedAbility(new DelugeOfTheDeadEffect(), new ManaCostsImpl<>("{2}{B}")); + rightAbility.addTarget(new TargetCardInGraveyard()); + this.getRightHalfCard().addAbility(rightAbility); } private InvasionOfInnistrad(final InvasionOfInnistrad card) { @@ -46,3 +69,35 @@ public final class InvasionOfInnistrad extends CardImpl { return new InvasionOfInnistrad(this); } } + +class DelugeOfTheDeadEffect extends OneShotEffect { + + DelugeOfTheDeadEffect() { + super(Outcome.Benefit); + staticText = "exile target card from a graveyard. " + + "If it was a creature card, create a 2/2 black Zombie creature token"; + } + + private DelugeOfTheDeadEffect(final DelugeOfTheDeadEffect effect) { + super(effect); + } + + @Override + public DelugeOfTheDeadEffect copy() { + return new DelugeOfTheDeadEffect(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.EXILED, source, game); + if (card.isCreature(game)) { + new ZombieToken().putOntoBattlefield(1, game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfIxalan.java b/Mage.Sets/src/mage/cards/i/InvasionOfIxalan.java index e9f5063c2d7..127c4ec565c 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfIxalan.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfIxalan.java @@ -2,10 +2,15 @@ package mage.cards.i; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.PutCards; import mage.constants.SubType; import mage.filter.StaticFilters; @@ -15,23 +20,37 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfIxalan extends CardImpl { +public final class InvasionOfIxalan extends TransformingDoubleFacedCard { public InvasionOfIxalan(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{1}{G}", + "Belligerent Regisaur", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DINOSAUR}, "G" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.b.BelligerentRegisaur.class; + // Invasion of Ixalan + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Ixalan enters the battlefield, look at the top five cards of your library. You may reveal a permanent card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. - this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( 5, 1, StaticFilters.FILTER_CARD_A_PERMANENT, PutCards.HAND, PutCards.BOTTOM_RANDOM ))); + + // Belligerent Regisaur + this.getRightHalfCard().setPT(4, 3); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Whenever you cast a spell, Belligerent Regisaur gains indestructible until end of turn. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility(new GainAbilitySourceEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn + ), false)); } private InvasionOfIxalan(final InvasionOfIxalan card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfKaladesh.java b/Mage.Sets/src/mage/cards/i/InvasionOfKaladesh.java index c4ed5fb6da3..47779abf9b8 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfKaladesh.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfKaladesh.java @@ -2,11 +2,18 @@ package mage.cards.i; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; import mage.abilities.effects.common.CreateTokenEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; import mage.game.permanent.token.ThopterColorlessToken; import java.util.UUID; @@ -14,20 +21,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfKaladesh extends CardImpl { +public final class InvasionOfKaladesh extends TransformingDoubleFacedCard { public InvasionOfKaladesh(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{U}{R}"); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{U}{R}", + "Aetherwing, Golden-Scale Flagship", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "UR" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.a.AetherwingGoldenScaleFlagship.class; + // Invasion of Kaladesh + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Kaladesh enters the battlefield, create a 1/1 colorless Thopter artifact creature token with flying. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ThopterColorlessToken()))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ThopterColorlessToken()))); + + // Aetherwing, Golden-Scale Flagship + this.getRightHalfCard().setPT(0, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Aetherwing, Golden-Scale Flagship's power is equal to the number of artifacts you control. + this.getRightHalfCard().addAbility(new SimpleStaticAbility( + Zone.ALL, + new SetBasePowerSourceEffect(ArtifactYouControlCount.instance) + .setText("{this}'s power is equal to the number of artifacts you control") + )); + + // Crew 1 + this.getRightHalfCard().addAbility(new CrewAbility(1)); } private InvasionOfKaladesh(final InvasionOfKaladesh card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfKaldheim.java b/Mage.Sets/src/mage/cards/i/InvasionOfKaldheim.java index b43d0aa8575..b8db517a142 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfKaldheim.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfKaldheim.java @@ -3,11 +3,19 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; import mage.cards.*; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetCardInHand; import mage.util.CardUtil; import java.util.UUID; @@ -15,20 +23,38 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfKaldheim extends CardImpl { +public final class InvasionOfKaldheim extends TransformingDoubleFacedCard { public InvasionOfKaldheim(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{R}", + "Pyre of the World Tree", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "R" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.p.PyreOfTheWorldTree.class; + // Invasion of Kaldheim + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Kaldheim enters the battlefield, exile all cards from your hand, then draw that many cards. Until the end of your next turn, you may play cards exiled this way. - this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfKaldheimEffect())); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfKaldheimEffect())); + + // Pyre of the World Tree + // Discard a land card: Pyre of the World Tree deals 2 damage to any target. + Ability ability = new SimpleActivatedAbility( + new DamageTargetEffect(2), + new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_LAND_A)) + ); + ability.addTarget(new TargetAnyTarget()); + this.getRightHalfCard().addAbility(ability); + + // Whenever you discard a land card, exile the top card of your library. You may play that card this turn. + this.getRightHalfCard().addAbility(new DiscardCardControllerTriggeredAbility( + new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), + false, StaticFilters.FILTER_CARD_LAND_A + )); } private InvasionOfKaldheim(final InvasionOfKaldheim card) { @@ -45,8 +71,7 @@ class InvasionOfKaldheimEffect extends OneShotEffect { InvasionOfKaldheimEffect() { super(Outcome.Benefit); - staticText = "exile all cards from your hand, then draw that many cards. " + - "Until the end of your next turn, you may play cards exiled this way"; + staticText = "exile all cards from your hand, then draw that many cards. Until the end of your next turn, you may play cards exiled this way"; } private InvasionOfKaldheimEffect(final InvasionOfKaldheimEffect effect) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfKamigawa.java b/Mage.Sets/src/mage/cards/i/InvasionOfKamigawa.java index fbbba61f607..8c4b1b8f77b 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfKamigawa.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfKamigawa.java @@ -1,12 +1,15 @@ package mage.cards.i; import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerOrBattleTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -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; @@ -18,23 +21,36 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfKamigawa extends CardImpl { +public final class InvasionOfKamigawa extends TransformingDoubleFacedCard { public InvasionOfKamigawa(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{U}", + "Rooftop Saboteurs", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.MOONFOLK, SubType.NINJA}, "U" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.r.RooftopSaboteurs.class; + // Invasion of Kamigawa + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); + Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); // When Invasion of Kamigawa enters the battlefield, tap target artifact or creature an opponent controls and put a stun counter on it. - Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance()).setText("and put a stun counter on it")); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Rooftop Saboteurs + this.getRightHalfCard().setPT(2, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever Rooftop Saboteurs deals combat damage to a player or battle, draw a card. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerOrBattleTriggeredAbility( + new DrawCardSourceControllerEffect(1), false)); } private InvasionOfKamigawa(final InvasionOfKamigawa card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfKarsus.java b/Mage.Sets/src/mage/cards/i/InvasionOfKarsus.java index 3e0ad498ef9..2321710b2a7 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfKarsus.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfKarsus.java @@ -2,11 +2,16 @@ package mage.cards.i; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.DamageAllEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.keyword.WardAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.TargetController; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; @@ -15,24 +20,35 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfKarsus extends CardImpl { +public final class InvasionOfKarsus extends TransformingDoubleFacedCard { - private static final FilterPermanent filter - = new FilterCreatureOrPlaneswalkerPermanent("creature and each planeswalker"); + private static final FilterPermanent filter = new FilterCreatureOrPlaneswalkerPermanent("creature and each planeswalker"); public InvasionOfKarsus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{R}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{R}{R}", + "Refraction Elemental", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL}, "R" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.r.RefractionElemental.class; + // Invasion of Karsus + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); - // When Invasion of Karsus enters the battlefield, it deals 3 damage to each creature and each planeswalker. - this.addAbility(new EntersBattlefieldTriggeredAbility( - new DamageAllEffect(3, "it", filter) + // When this Siege enters, it deals 3 damage to each creature and each planeswalker. + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(3, "it", filter))); + + // Refraction Elemental + this.getRightHalfCard().setPT(4, 4); + + // Ward—Pay 2 life. + this.getRightHalfCard().addAbility(new WardAbility(new PayLifeCost(2), false)); + + // Whenever you cast a spell, Refraction Elemental deals 2 damage to each opponent. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new DamagePlayersEffect(2, TargetController.OPPONENT), false )); } diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfKylem.java b/Mage.Sets/src/mage/cards/i/InvasionOfKylem.java index 9fe9458f3a3..5670eb9d905 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfKylem.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfKylem.java @@ -3,14 +3,16 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; 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.SubType; +import mage.game.permanent.token.ValorsReachTagTeamToken; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -18,17 +20,19 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfKylem extends CardImpl { +public final class InvasionOfKylem extends TransformingDoubleFacedCard { public InvasionOfKylem(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{R}{W}"); - - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.v.ValorsReachTagTeam.class; + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{R}{W}", + "Valor's Reach Tag Team", + new CardType[]{CardType.SORCERY}, new SubType[]{}, "RW" + ); + // Invasion of Kylem + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Kylem enters the battlefield, up to two target creatures each get +2/+0 and gain vigilance and haste until end of turn. Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0) @@ -38,7 +42,11 @@ public final class InvasionOfKylem extends CardImpl { ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance()) .setText("and haste until end of turn")); ability.addTarget(new TargetCreaturePermanent(0, 2)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Valor's Reach Tag Team + // Create two 3/2 red and white Warrior creature tokens with "Whenever this creature and at least one other creature token attack, put a +1/+1 counter on this creature." + this.getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new ValorsReachTagTeamToken(), 2)); } private InvasionOfKylem(final InvasionOfKylem card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfLorwyn.java b/Mage.Sets/src/mage/cards/i/InvasionOfLorwyn.java index 128f73733a2..0da2e27ff23 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfLorwyn.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfLorwyn.java @@ -3,12 +3,16 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.LandsYouControlCount; import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; import mage.abilities.hint.common.LandsYouControlHint; -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.FilterPermanent; import mage.filter.StaticFilters; import mage.filter.common.FilterOpponentsCreaturePermanent; @@ -24,7 +28,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfLorwyn extends CardImpl { +public final class InvasionOfLorwyn extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent( "non-Elf creature an opponent controls with power X or less, where X is the number of lands you control" @@ -36,19 +40,30 @@ public final class InvasionOfLorwyn extends CardImpl { } public InvasionOfLorwyn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{B}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{4}{B}{G}", + "Winnowing Forces", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELF, SubType.WARRIOR}, "BG" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.w.WinnowingForces.class; + // Invasion of Lorwyn + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Lorwyn enters the battlefield, destroy target non-Elf creature an opponent controls with power X or less, where X is the number of lands you control. Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability.addHint(LandsYouControlHint.instance)); + this.getLeftHalfCard().addAbility(ability.addHint(LandsYouControlHint.instance)); + + // Winnowing Forces + this.getRightHalfCard().setPT(0, 0); + + // Winnowing Forces's power and toughness are each equal to the number of lands you control. + this.getRightHalfCard().addAbility(new SimpleStaticAbility( + Zone.ALL, new SetBasePowerToughnessSourceEffect(LandsYouControlCount.instance) + )); } private InvasionOfLorwyn(final InvasionOfLorwyn card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfMercadia.java b/Mage.Sets/src/mage/cards/i/InvasionOfMercadia.java index fc5c4e94077..19bb6ae49a0 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfMercadia.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfMercadia.java @@ -1,34 +1,64 @@ package mage.cards.i; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HasteAbility; 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 mage.game.permanent.token.Elemental11BlueRedToken; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfMercadia extends CardImpl { +public final class InvasionOfMercadia extends TransformingDoubleFacedCard { public InvasionOfMercadia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{1}{R}", + "Kyren Flamewright", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOBLIN, SubType.SPELLSHAPER}, "R" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.k.KyrenFlamewright.class; + // Invasion of Mercadia + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Mercadia enters the battlefield, you may discard a card. If you do, draw two cards. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new DrawCardSourceControllerEffect(2), new DiscardCardCost()))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new DrawCardSourceControllerEffect(2), new DiscardCardCost()))); + + // Kyren Flamewright + this.getRightHalfCard().setPT(3, 3); + + // {2}{R}, {T}, Discard a card: Create two 1/1 blue and red Elemental creature tokens. Creatures you control get +1/+0 and gain haste until end of turn. + Ability ability = new SimpleActivatedAbility( + new CreateTokenEffect(new Elemental11BlueRedToken(), 2), new ManaCostsImpl<>("{2}{R}") + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new DiscardCardCost()); + ability.addEffect(new BoostControlledEffect(1, 0, Duration.EndOfTurn) + .setText("creatures you control get +1/+0")); + ability.addEffect(new GainAbilityControlledEffect( + HasteAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES + ).setText("and gain haste until end of turn")); + this.getRightHalfCard().addAbility(ability); } private InvasionOfMercadia(final InvasionOfMercadia card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfMoag.java b/Mage.Sets/src/mage/cards/i/InvasionOfMoag.java index 00f81345e85..8b396921c48 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfMoag.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfMoag.java @@ -1,36 +1,58 @@ package mage.cards.i; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.WardAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; 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.target.common.TargetControlledCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfMoag extends CardImpl { +public final class InvasionOfMoag extends TransformingDoubleFacedCard { public InvasionOfMoag(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{G}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{G}{W}", + "Bloomwielder Dryads", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DRYAD}, "GW" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.b.BloomwielderDryads.class; + // Invasion of Moag + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Moag enters the battlefield, put a +1/+1 counter on each creature you control. - this.addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new AddCountersAllEffect( CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE ))); + + // Bloomwielder Dryads + this.getRightHalfCard().setPT(3, 3); + + // Ward {2} + this.getRightHalfCard().addAbility(new WardAbility(new ManaCostsImpl<>("{2}"))); + + // At the beginning of your end step, put a +1/+1 counter on target creature you control. + Ability ability = new BeginningOfEndStepTriggeredAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance()) + ); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.getRightHalfCard().addAbility(ability); } private InvasionOfMoag(final InvasionOfMoag card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfMuraganda.java b/Mage.Sets/src/mage/cards/i/InvasionOfMuraganda.java index 6c312f0611b..3e6c7b295a3 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfMuraganda.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfMuraganda.java @@ -4,10 +4,14 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.cards.CardImpl; +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.counters.CounterType; import mage.filter.StaticFilters; @@ -19,27 +23,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfMuraganda extends CardImpl { +public final class InvasionOfMuraganda extends TransformingDoubleFacedCard { public InvasionOfMuraganda(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{4}{G}", + "Primordial Plasm", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.OOZE}, "G" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(6); - this.secondSideCardClazz = mage.cards.p.PrimordialPlasm.class; + // Invasion of Muraganda + this.getLeftHalfCard().setStartingDefense(6); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Muraganda enters the battlefield, put a +1/+1 counter on target creature you control. Then that creature fights up to one target creature you don't control. - Ability ability = new EntersBattlefieldTriggeredAbility( - new AddCountersTargetEffect(CounterType.P1P1.createInstance()) - ); - ability.addEffect(new FightTargetsEffect() - .setText("Then that creature fights up to one target creature you don't control")); + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + ability.addEffect(new FightTargetsEffect().setText("Then that creature fights up to one target creature you don't control")); ability.addTarget(new TargetControlledCreaturePermanent()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Primordial Plasm + this.getRightHalfCard().setPT(4, 4); + + // At the beginning of combat on your turn, another target creature gets +2/+2 and loses all abilities until end of turn. + Ability combatAbility = new BeginningOfCombatTriggeredAbility( + new BoostTargetEffect(2, 2).setText("another target creature gets +2/+2") + ); + combatAbility.addEffect(new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn) + .setText("and loses all abilities until end of turn")); + combatAbility.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); + this.getRightHalfCard().addAbility(combatAbility); } private InvasionOfMuraganda(final InvasionOfMuraganda card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfNewCapenna.java b/Mage.Sets/src/mage/cards/i/InvasionOfNewCapenna.java index a63d9651ffc..ce1de7da376 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfNewCapenna.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfNewCapenna.java @@ -1,17 +1,22 @@ package mage.cards.i; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAttachedTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.effects.common.ExileTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.EquipAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.counters.CounterType; import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import java.util.UUID; @@ -19,26 +24,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfNewCapenna extends CardImpl { +public final class InvasionOfNewCapenna extends TransformingDoubleFacedCard { public InvasionOfNewCapenna(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{W}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{W}{B}", + "Holy Frazzle-Cannon", + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.EQUIPMENT}, "WB" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.h.HolyFrazzleCannon.class; + // Invasion of New Capenna + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of New Capenna enters the battlefield, you may sacrifice an artifact or creature. When you do, exile target artifact or creature an opponent controls. - ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ExileTargetEffect(), false); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE)); - this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( - ability, + ReflexiveTriggeredAbility ref = new ReflexiveTriggeredAbility(new ExileTargetEffect(), false); + ref.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE)); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( + ref, new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE), - "Sacrifice and artifact or creature?" + "Sacrifice an artifact or creature?" ))); + + // Holy Frazzle-Cannon + // Whenever equipped creature attacks, put a +1/+1 counter on that creature and each other creature you control that shares a creature type with it. + this.getRightHalfCard().addAbility(new AttacksAttachedTriggeredAbility( + new HolyFrazzleCannonEffect(), AttachmentType.EQUIPMENT, + false, SetTargetPointer.PERMANENT + )); + + // Equip {1} + this.getRightHalfCard().addAbility(new EquipAbility(1, false)); } private InvasionOfNewCapenna(final InvasionOfNewCapenna card) { @@ -50,3 +68,37 @@ public final class InvasionOfNewCapenna extends CardImpl { return new InvasionOfNewCapenna(this); } } + +class HolyFrazzleCannonEffect extends OneShotEffect { + + HolyFrazzleCannonEffect() { + super(Outcome.Benefit); + staticText = "put a +1/+1 counter on that creature and " + + "each other creature you control that shares a creature type with it"; + } + + private HolyFrazzleCannonEffect(final HolyFrazzleCannonEffect effect) { + super(effect); + } + + @Override + public HolyFrazzleCannonEffect copy() { + return new HolyFrazzleCannonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + for (Permanent creature : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_CREATURE, source.getControllerId(), source, game + )) { + if (creature.equals(permanent) || permanent.shareCreatureTypes(game, creature)) { + creature.addCounters(CounterType.P1P1.createInstance(), source, game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfNewPhyrexia.java b/Mage.Sets/src/mage/cards/i/InvasionOfNewPhyrexia.java index 314ce51080c..3d962924ae3 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfNewPhyrexia.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfNewPhyrexia.java @@ -1,34 +1,70 @@ package mage.cards.i; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.dynamicvalue.common.GetXValue; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +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.ManaValuePredicate; +import mage.game.Game; +import mage.game.command.emblems.TeferiAkosaOfZhalfirEmblem; +import mage.game.permanent.Permanent; import mage.game.permanent.token.KnightWhiteBlueToken; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInHand; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfNewPhyrexia extends CardImpl { +public final class InvasionOfNewPhyrexia extends TransformingDoubleFacedCard { public InvasionOfNewPhyrexia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{X}{W}{U}"); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{X}{W}{U}", + "Teferi Akosa of Zhalfir", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.TEFERI}, "WU" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(6); - this.secondSideCardClazz = mage.cards.t.TeferiAkosaOfZhalfir.class; + // Invasion of New Phyrexia + this.getLeftHalfCard().setStartingDefense(6); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of New Phyrexia enters the battlefield, create X 2/2 white and blue Knight creature tokens with vigilance. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new KnightWhiteBlueToken(), GetXValue.instance))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new KnightWhiteBlueToken(), GetXValue.instance))); + + // Teferi Akosa of Zhalfir + this.getRightHalfCard().setStartingLoyalty(4); + + // +1: Draw two cards. Then discard two cards unless you discard a creature card. + Ability ability = new LoyaltyAbility(new DrawCardSourceControllerEffect(2), 1); + ability.addEffect(new DoIfCostPaid( + null, new DiscardControllerEffect(2), + new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)) + .setText("discard a creature card instead of discarding two cards") + ).setText("Then discard two cards unless you discard a creature card")); + this.getRightHalfCard().addAbility(ability); + + // -2: You get an emblem with "Knights you control get +1/+0 and have ward {1}." + this.getRightHalfCard().addAbility(new LoyaltyAbility(new GetEmblemEffect(new TeferiAkosaOfZhalfirEmblem()), -2)); + + // -3: Tap any number of untapped creatures you control. When you do, shuffle target nonland permanent an opponent controls with mana value X or less into its owner's library, where X is the number of creatures tapped this way. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new TeferiAkosaOfZhalfirEffect(), -3)); } private InvasionOfNewPhyrexia(final InvasionOfNewPhyrexia card) { @@ -40,3 +76,50 @@ public final class InvasionOfNewPhyrexia extends CardImpl { return new InvasionOfNewPhyrexia(this); } } + +class TeferiAkosaOfZhalfirEffect extends OneShotEffect { + + TeferiAkosaOfZhalfirEffect() { + super(Outcome.Benefit); + staticText = "tap any number of untapped creatures you control. When you do, " + + "shuffle target nonland permanent an opponent controls with mana value X or less " + + "into its owner's library, where X is the number of creatures tapped this way"; + } + + private TeferiAkosaOfZhalfirEffect(final TeferiAkosaOfZhalfirEffect effect) { + super(effect); + } + + @Override + public TeferiAkosaOfZhalfirEffect copy() { + return new TeferiAkosaOfZhalfirEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetPermanent target = new TargetPermanent( + 0, Integer.MAX_VALUE, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES, true + ); + player.choose(Outcome.Tap, target, source, game); + int count = 0; + for (UUID targetId : target.getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null && permanent.tap(source, game)) { + count++; + } + } + FilterPermanent filter = new FilterNonlandPermanent("nonland permanent an opponent controls with mana value " + count + " or less"); + filter.add(TargetController.OPPONENT.getControllerPredicate()); + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, count + 1)); + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ShuffleIntoLibraryTargetEffect() + .setText("shuffle target nonland permanent an opponent controls with mana value X or less " + + "into its owner's library, where X is the number of creatures tapped this way"), false); + ability.addTarget(new TargetPermanent(filter)); + game.fireReflexiveTriggeredAbility(ability, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfPyrulea.java b/Mage.Sets/src/mage/cards/i/InvasionOfPyrulea.java index 0c7368ae308..7845112de81 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfPyrulea.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfPyrulea.java @@ -3,11 +3,20 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.keyword.WardAbility; import mage.cards.*; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.TransformedPredicate; import mage.game.Game; import mage.players.Player; @@ -16,20 +25,43 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfPyrulea extends CardImpl { +public final class InvasionOfPyrulea extends TransformingDoubleFacedCard { public InvasionOfPyrulea(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{G}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{G}{U}", + "Gargantuan Slabhorn", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.BEAST}, "GU" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.g.GargantuanSlabhorn.class; + // Invasion of Pyrulea + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Pyrulea enters the battlefield, scry 3, then reveal the top card of your library. If it's a land or double-faced card, draw a card. - this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfPyruleaEffect())); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfPyruleaEffect())); + + // Gargantuan Slabhorn + this.getRightHalfCard().setPT(4, 4); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Ward {2} + this.getRightHalfCard().addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); + + // Other transformed permanents you control have trample and ward {2}. + FilterPermanent filter = new FilterPermanent("transformed permanents"); + filter.add(TransformedPredicate.instance); + Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter, true + )); + ability.addEffect(new GainAbilityControlledEffect( + new WardAbility(new GenericManaCost(2)), Duration.WhileOnBattlefield, filter, true + ).setText("and ward {2}")); + this.getRightHalfCard().addAbility(ability); } private InvasionOfPyrulea(final InvasionOfPyrulea card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfRavnica.java b/Mage.Sets/src/mage/cards/i/InvasionOfRavnica.java index 49b3a60b26f..26ffe207513 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfRavnica.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfRavnica.java @@ -1,15 +1,21 @@ package mage.cards.i; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.common.ExileTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.PutCards; import mage.constants.SubType; import mage.constants.TargetController; +import mage.filter.FilterCard; import mage.filter.FilterPermanent; +import mage.filter.FilterSpell; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.Predicate; import mage.game.Game; @@ -21,7 +27,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfRavnica extends CardImpl { +public final class InvasionOfRavnica extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanent an opponent controls that isn't exactly two colors"); @@ -30,20 +36,38 @@ public final class InvasionOfRavnica extends CardImpl { filter.add(InvasionOfRavnicaPredicate.instance); } + private static final FilterSpell spellFilter = new FilterSpell("a spell that's exactly two colors"); + private static final FilterCard cardFilter = new FilterCard("a card that's exactly two colors"); + + static { + spellFilter.add(GuildpactParagonPredicate.instance); + cardFilter.add(GuildpactParagonPredicate.instance); + } + public InvasionOfRavnica(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{5}"); - - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.g.GuildpactParagon.class; + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{5}", + "Guildpact Paragon", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.CONSTRUCT}, "" + ); + // Invasion of Ravnica + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Ravnica enters the battlefield, exile target nonland permanent an opponent controls that isn't exactly two colors. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect()); ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Guildpact Paragon + this.getRightHalfCard().setPT(5, 5); + + // Whenever you cast a spell that's exactly two colors, look at the top six cards of your library. You may reveal a card that's exactly two colors from among them and put it into your hand. Put the rest on the bottom of your library in a random order. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility(new LookLibraryAndPickControllerEffect( + 6, 1, cardFilter, PutCards.HAND, PutCards.BOTTOM_RANDOM + ), spellFilter, false)); } private InvasionOfRavnica(final InvasionOfRavnica card) { @@ -64,3 +88,12 @@ enum InvasionOfRavnicaPredicate implements Predicate { return input.getColor(game).getColorCount() != 2; } } + +enum GuildpactParagonPredicate implements Predicate { + instance; + + @Override + public boolean apply(MageObject input, Game game) { + return input.getColor(game).getColorCount() == 2; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfRegatha.java b/Mage.Sets/src/mage/cards/i/InvasionOfRegatha.java index 4f7ff4dda05..b8ef97f2586 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfRegatha.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfRegatha.java @@ -1,26 +1,39 @@ package mage.cards.i; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DamageTargetAndTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.ProwessAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterOpponent; import mage.filter.common.FilterBattlePermanent; import mage.filter.common.FilterPermanentOrPlayer; import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetPermanentOrPlayer; +import mage.util.CardUtil; +import java.util.Objects; +import java.util.Optional; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfRegatha extends CardImpl { +public final class InvasionOfRegatha extends TransformingDoubleFacedCard { private static final FilterPermanentOrPlayer filter = new FilterPermanentOrPlayer( "another target battle or opponent", @@ -32,20 +45,31 @@ public final class InvasionOfRegatha extends CardImpl { } public InvasionOfRegatha(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{R}"); - - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.d.DisciplesOfTheInferno.class; + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{R}", + "Disciples of the Inferno", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.MONK}, "R" + ); + // Invasion of Regatha + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Regatha enters the battlefield, it deals 4 damage to another target battle or opponent and 1 damage to up to one target creature. Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetAndTargetEffect(4, 1)); ability.addTarget(new TargetPermanentOrPlayer(filter).setTargetTag(1)); ability.addTarget(new TargetCreaturePermanent(0, 1).setTargetTag(2)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Disciples of the Inferno + this.getRightHalfCard().setPT(4, 4); + + // Prowess + this.getRightHalfCard().addAbility(new ProwessAbility()); + + // If a noncreature source you control would deal damage to a creature, battle, or opponent, it deals that much damage plus 2 instead. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new DisciplesOfTheInfernoEffect())); } private InvasionOfRegatha(final InvasionOfRegatha card) { @@ -57,3 +81,61 @@ public final class InvasionOfRegatha extends CardImpl { return new InvasionOfRegatha(this); } } + +class DisciplesOfTheInfernoEffect extends ReplacementEffectImpl { + + DisciplesOfTheInfernoEffect() { + super(Duration.WhileOnBattlefield, Outcome.Damage); + this.staticText = "if a noncreature source you control would deal damage " + + "to a creature, battle, or opponent, it deals that much damage plus 2 instead"; + } + + private DisciplesOfTheInfernoEffect(final DisciplesOfTheInfernoEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.overflowInc(event.getAmount(), 2)); + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + switch (event.getType()) { + case DAMAGE_PERMANENT: + case DAMAGE_PLAYER: + return true; + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || !controller.hasOpponent(event.getTargetId(), game) + && Optional + .of(event.getTargetId()) + .map(game::getPermanent) + .filter(Objects::nonNull) + .map(permanent -> !permanent.isCreature(game) && !permanent.isBattle(game)) + .orElse(true)) { + return false; + } + MageObject sourceObject; + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (sourcePermanent == null) { + sourceObject = game.getObject(event.getSourceId()); + } else { + sourceObject = sourcePermanent; + } + return sourceObject != null + && !sourceObject.isCreature(game) + && event.getAmount() > 0; + } + + @Override + public DisciplesOfTheInfernoEffect copy() { + return new DisciplesOfTheInfernoEffect(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfSegovia.java b/Mage.Sets/src/mage/cards/i/InvasionOfSegovia.java index fee4ad0287b..4b44e712ab9 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfSegovia.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfSegovia.java @@ -1,33 +1,65 @@ package mage.cards.i; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.CreateTokenEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledSpellsEffect; +import mage.abilities.keyword.ConvokeAbility; +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.filter.common.FilterNonlandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; import mage.game.permanent.token.Kraken11Token; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfSegovia extends CardImpl { +public final class InvasionOfSegovia extends TransformingDoubleFacedCard { + + private static final FilterNonlandCard filter = new FilterNonlandCard("noncreature spells you cast"); + + static { + filter.add(Predicates.not(CardType.CREATURE.getPredicate())); + filter.add(Predicates.not(new AbilityPredicate(ConvokeAbility.class))); + } public InvasionOfSegovia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{U}"); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{U}", + "Caetus, Sea Tyrant of Segovia", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SERPENT}, "U" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.c.CaetusSeaTyrantOfSegovia.class; + // Invasion of Segovia + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Segovia enters the battlefield, create two 1/1 blue Kraken creature tokens with trample. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new Kraken11Token(), 2))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new Kraken11Token(), 2))); + + // Caetus, Sea Tyrant of Segovia + this.getRightHalfCard().setPT(3, 3); + + // Noncreature spells you cast have convoke. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledSpellsEffect(new ConvokeAbility(), filter))); + + // At the beginning of your end step, untap up to four target creatures. + Ability ability = new BeginningOfEndStepTriggeredAbility(new UntapTargetEffect()); + ability.addTarget(new TargetCreaturePermanent(0, 4)); + this.getRightHalfCard().addAbility(ability); } private InvasionOfSegovia(final InvasionOfSegovia card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfShandalar.java b/Mage.Sets/src/mage/cards/i/InvasionOfShandalar.java index c1d9fa06b7a..b16c4ffcacb 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfShandalar.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfShandalar.java @@ -3,9 +3,11 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; -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; @@ -16,22 +18,31 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfShandalar extends CardImpl { +public final class InvasionOfShandalar extends TransformingDoubleFacedCard { public InvasionOfShandalar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{G}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{G}{G}", + "Leyline Surge", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "G" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.l.LeylineSurge.class; + // Invasion of Shandalar + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Shandalar enters the battlefield, return up to three target permanent cards from your graveyard to your hand. Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect()); ability.addTarget(new TargetCardInYourGraveyard(0, 3, StaticFilters.FILTER_CARD_PERMANENTS)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Leyline Surge + // At the beginning of your upkeep, you may put a permanent card from your hand onto the battlefield. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect( + StaticFilters.FILTER_CARD_A_PERMANENT + ))); } private InvasionOfShandalar(final InvasionOfShandalar card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfTarkir.java b/Mage.Sets/src/mage/cards/i/InvasionOfTarkir.java index c75e07bea0f..e13393a4eee 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfTarkir.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfTarkir.java @@ -1,25 +1,31 @@ package mage.cards.i; +import mage.MageObjectReference; import mage.abilities.Ability; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardSetInfo; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.common.FilterAnyTarget; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterPermanentOrPlayer; import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; +import mage.target.common.TargetAnyTarget; import mage.target.common.TargetCardInHand; import mage.target.common.TargetPermanentOrPlayer; @@ -28,20 +34,37 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfTarkir extends CardImpl { +public final class InvasionOfTarkir extends TransformingDoubleFacedCard { public InvasionOfTarkir(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{1}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{1}{R}", + "Defiant Thundermaw", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DRAGON}, "R" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.d.DefiantThundermaw.class; + // Invasion of Tarkir + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Tarkir enters the battlefield, reveal any number of Dragon cards from your hand. When you do, Invasion of Tarkir deals X plus 2 damage to any other target, where X is the number of cards revealed this way. - this.addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfTarkirEffect())); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfTarkirEffect())); + + // Defiant Thundermaw + this.getRightHalfCard().setPT(4, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Whenever a Dragon you control attacks, it deals 2 damage to any target. + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new DefiantThundermawEffect(), false, new FilterControlledCreaturePermanent(SubType.DRAGON)); + ability.addTarget(new TargetAnyTarget()); + this.getRightHalfCard().addAbility(ability); } private InvasionOfTarkir(final InvasionOfTarkir card) { @@ -66,8 +89,7 @@ class InvasionOfTarkirEffect extends OneShotEffect { InvasionOfTarkirEffect() { super(Outcome.Benefit); - staticText = "reveal any number of Dragon cards from your hand. When you do, " + - "{this} deals X plus 2 damage to any other target, where X is the number of cards revealed this way"; + staticText = "reveal any number of Dragon cards from your hand. When you do, {this} deals X plus 2 damage to any other target, where X is the number of cards revealed this way"; } private InvasionOfTarkirEffect(final InvasionOfTarkirEffect effect) { @@ -97,3 +119,33 @@ class InvasionOfTarkirEffect extends OneShotEffect { return true; } } + +class DefiantThundermawEffect extends OneShotEffect { + + DefiantThundermawEffect() { + super(Outcome.Benefit); + staticText = "it deals 2 damage to any target"; + } + + private DefiantThundermawEffect(final DefiantThundermawEffect effect) { + super(effect); + } + + @Override + public DefiantThundermawEffect copy() { + return new DefiantThundermawEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + MageObjectReference mor = (MageObjectReference) getValue("attackerRef"); + if (mor == null) { + return false; + } + game.damagePlayerOrPermanent( + getTargetPointer().getFirst(game, source), 2, + mor.getSourceId(), source, game, false, true + ); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfTheros.java b/Mage.Sets/src/mage/cards/i/InvasionOfTheros.java index 91f8f74d716..44671b41d9f 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfTheros.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfTheros.java @@ -1,14 +1,32 @@ package mage.cards.i; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.cards.CardImpl; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.IndestructibleAbility; +import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.ComparisonType; import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledEnchantmentPermanent; import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.target.common.TargetCardInLibrary; import java.util.UUID; @@ -16,9 +34,10 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfTheros extends CardImpl { +public final class InvasionOfTheros extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterCard("an Aura, God, or Demigod card"); + private static final FilterPermanent epharaFilter = new FilterControlledEnchantmentPermanent("another enchantment"); static { filter.add(Predicates.or( @@ -26,22 +45,55 @@ public final class InvasionOfTheros extends CardImpl { SubType.GOD.getPredicate(), SubType.DEMIGOD.getPredicate() )); + epharaFilter.add(AnotherPredicate.instance); } - public InvasionOfTheros(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}"); + static { + } - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.e.EpharaEverSheltering.class; + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + epharaFilter, ComparisonType.MORE_THAN, 2, true + ); + private static final Hint epharaHint = new ValueHint( + "Other enchantments you control", new PermanentsOnBattlefieldCount(epharaFilter) + ); + + public InvasionOfTheros(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{W}", + "Ephara, Ever-Sheltering", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.GOD}, "WU" + ); + + // Invasion of Theros + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Theros enters the battlefield, search your library for an Aura, God, or Demigod card, reveal it, put it into your hand, then shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true) )); + + // Ephara, Ever-Sheltering + this.getRightHalfCard().setPT(4, 4); + + // Ephara, Ever-Sheltering has lifelink and indestructible as long as you control at least three other enchantments. + Ability staticAbility = new SimpleStaticAbility(new ConditionalContinuousEffect( + new GainAbilitySourceEffect(LifelinkAbility.getInstance()), + condition, "{this} has lifelink" + )); + staticAbility.addEffect(new ConditionalContinuousEffect(new GainAbilitySourceEffect( + IndestructibleAbility.getInstance()), condition, + "and indestructible as long as you control at least three other enchantments" + )); + this.getRightHalfCard().addAbility(staticAbility.addHint(epharaHint)); + + // Whenever another enchantment you control enters, draw a card. + this.getRightHalfCard().addAbility(new EntersBattlefieldControlledTriggeredAbility( + new DrawCardSourceControllerEffect(1), epharaFilter + )); } private InvasionOfTheros(final InvasionOfTheros card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfTolvada.java b/Mage.Sets/src/mage/cards/i/InvasionOfTolvada.java index ed40650ae77..c618967a88c 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfTolvada.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfTolvada.java @@ -3,14 +3,24 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.LifelinkAbility; +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.filter.FilterCard; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.WhiteBlackSpiritToken; import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -18,7 +28,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfTolvada extends CardImpl { +public final class InvasionOfTolvada extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterPermanentCard("nonbattle permanent card from your graveyard"); @@ -26,20 +36,44 @@ public final class InvasionOfTolvada extends CardImpl { filter.add(Predicates.not(CardType.BATTLE.getPredicate())); } - public InvasionOfTolvada(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{W}{B}"); + private static final FilterCreaturePermanent tokenFilter = new FilterCreaturePermanent("creature tokens"); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.t.TheBrokenSky.class; + static { + tokenFilter.add(TokenPredicate.TRUE); + } + + public InvasionOfTolvada(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{W}{B}", + "The Broken Sky", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "WB" + ); + + // Invasion of Tolvada + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Tolvada enters the battlefield, return target nonbattle permanent card from your graveyard to the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()); ability.addTarget(new TargetCardInYourGraveyard(filter)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // The Broken Sky + // Creature tokens you control get +1/+0 and have lifelink. + Ability staticAbility = new SimpleStaticAbility(new BoostControlledEffect( + 1, 0, Duration.WhileOnBattlefield, tokenFilter + )); + staticAbility.addEffect(new GainAbilityControlledEffect( + LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, tokenFilter + ).setText("and have lifelink")); + this.getRightHalfCard().addAbility(staticAbility); + + // At the beginning of your end step, create a 1/1 white and black Spirit creature token with flying. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility( + new CreateTokenEffect(new WhiteBlackSpiritToken()) + )); } private InvasionOfTolvada(final InvasionOfTolvada card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfUlgrotha.java b/Mage.Sets/src/mage/cards/i/InvasionOfUlgrotha.java index f9c523ca427..2325d7277b8 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfUlgrotha.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfUlgrotha.java @@ -1,14 +1,20 @@ package mage.cards.i; import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.filter.common.FilterAnyTarget; import mage.filter.common.FilterPermanentOrPlayer; import mage.filter.predicate.mageobject.AnotherPredicate; @@ -19,7 +25,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfUlgrotha extends CardImpl { +public final class InvasionOfUlgrotha extends TransformingDoubleFacedCard { private static final FilterPermanentOrPlayer filter = new FilterAnyTarget("any other target"); @@ -28,20 +34,37 @@ public final class InvasionOfUlgrotha extends CardImpl { } public InvasionOfUlgrotha(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{4}{B}"); + super(ownerId, setInfo, + new SuperType[]{}, new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{4}{B}", + "Grandmother Ravi Sengir", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "B" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(5); - this.secondSideCardClazz = mage.cards.g.GrandmotherRaviSengir.class; + // Invasion of Ulgrotha + this.getLeftHalfCard().setStartingDefense(5); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Ulgrotha enters the battlefield, it deals 3 damage to any other target and you gain 3 life. Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(3, "it")); ability.addEffect(new GainLifeEffect(3).concatBy("and")); ability.addTarget(new TargetPermanentOrPlayer(filter)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Grandmother Ravi Sengir + this.getRightHalfCard().setPT(3, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever a creature an opponent controls dies, put a +1/+1 counter on Grandmother Ravi Sengir and you gain 1 life. + Ability diesAbility = new DiesCreatureTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), + false, StaticFilters.FILTER_OPPONENTS_PERMANENT_A_CREATURE + ); + diesAbility.addEffect(new GainLifeEffect(1).concatBy("and")); + this.getRightHalfCard().addAbility(diesAbility); } private InvasionOfUlgrotha(final InvasionOfUlgrotha card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfVryn.java b/Mage.Sets/src/mage/cards/i/InvasionOfVryn.java index c4107e3b0fe..69ccb87ab25 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfVryn.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfVryn.java @@ -1,32 +1,60 @@ package mage.cards.i; +import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CopyTargetStackObjectEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterSpell; +import mage.target.TargetSpell; import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfVryn extends CardImpl { +public final class InvasionOfVryn extends TransformingDoubleFacedCard { + + private static final FilterSpell filter = new FilterSpell("spell you control"); + + static { + filter.add(TargetController.YOU.getControllerPredicate()); + } public InvasionOfVryn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{U}", + "Overloaded Mage-Ring", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "U" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.o.OverloadedMageRing.class; + // Invasion of Vryn + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Vryn enters the battlefield, draw three cards, then discard a card. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(3, 1))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(3, 1))); + + // Overloaded Mage-Ring + // {1}, {T}, Sacrifice Overloaded Mage-Ring: Copy target spell you control. You may choose new targets for the copy. + Ability ability = new SimpleActivatedAbility( + new CopyTargetStackObjectEffect(false, false, true), new GenericManaCost(1) + ); + ability.addCost(new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetSpell(filter)); + this.getRightHalfCard().addAbility(ability); } private InvasionOfVryn(final InvasionOfVryn card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfXerex.java b/Mage.Sets/src/mage/cards/i/InvasionOfXerex.java index fa5253a7bc9..d93de2b2ccc 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfXerex.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfXerex.java @@ -3,11 +3,16 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; +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 mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -15,22 +20,34 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfXerex extends CardImpl { +public final class InvasionOfXerex extends TransformingDoubleFacedCard { public InvasionOfXerex(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{W}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{W}{U}", + "Vertex Paladin", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ANGEL, SubType.KNIGHT}, "WU" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(4); - this.secondSideCardClazz = mage.cards.v.VertexPaladin.class; + // Invasion of Xerex + this.getLeftHalfCard().setStartingDefense(4); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); // When Invasion of Xerex enters the battlefield, return up to one target creature to its owner's hand. Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()); ability.addTarget(new TargetCreaturePermanent(0, 1)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Vertex Paladin + this.getRightHalfCard().setPT(0, 0); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Vertex Paladin's power and toughness are each equal to the number of creatures you control. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CreaturesYouControlCount.PLURAL))); } private InvasionOfXerex(final InvasionOfXerex card) { diff --git a/Mage.Sets/src/mage/cards/i/InvasionOfZendikar.java b/Mage.Sets/src/mage/cards/i/InvasionOfZendikar.java index 5f83a364830..f0b3955c634 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionOfZendikar.java +++ b/Mage.Sets/src/mage/cards/i/InvasionOfZendikar.java @@ -2,10 +2,16 @@ package mage.cards.i; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SiegeAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.AddCardTypeSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.cards.CardImpl; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.mana.AnyColorManaAbility; 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 mage.target.common.TargetCardInLibrary; @@ -15,22 +21,41 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InvasionOfZendikar extends CardImpl { +public final class InvasionOfZendikar extends TransformingDoubleFacedCard { public InvasionOfZendikar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{3}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{3}{G}", + "Awakened Skyclave", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELEMENTAL}, "G" + ); - this.subtype.add(SubType.SIEGE); - this.setStartingDefense(3); - this.secondSideCardClazz = mage.cards.a.AwakenedSkyclave.class; + // Invasion of Zendikar + this.getLeftHalfCard().setStartingDefense(3); // (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.) - this.addAbility(new SiegeAbility()); + this.getLeftHalfCard().addAbility(new SiegeAbility()); - // When Invasion of Zendikar enters the battlefield, search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary( + // When Invasion of Zendikar enters the battlefield, you may search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary( 0, 2, StaticFilters.FILTER_CARD_BASIC_LANDS ), true))); + + // Awakened Skyclave + this.getRightHalfCard().setPT(4, 4); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // As long as Awakened Skyclave is on the battlefield, it's a land in addition to its other types. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new AddCardTypeSourceEffect(Duration.WhileOnBattlefield, CardType.LAND) + .setText("as long as {this} is on the battlefield, it's a land in addition to its other types"))); + + // {T}: Add one mana of any color. + this.getRightHalfCard().addAbility(new AnyColorManaAbility()); } private InvasionOfZendikar(final InvasionOfZendikar card) { diff --git a/Mage.Sets/src/mage/cards/i/InventiveIteration.java b/Mage.Sets/src/mage/cards/i/InventiveIteration.java index 01b9469198f..95379ab1c8e 100644 --- a/Mage.Sets/src/mage/cards/i/InventiveIteration.java +++ b/Mage.Sets/src/mage/cards/i/InventiveIteration.java @@ -1,17 +1,22 @@ package mage.cards.i; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; -import mage.cards.CardImpl; 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.stack.Spell; import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInYourGraveyard; @@ -23,31 +28,41 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class InventiveIteration extends CardImpl { +public final class InventiveIteration extends TransformingDoubleFacedCard { public InventiveIteration(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.l.LivingBreakthrough.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{3}{U}", + "Living Breakthrough", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.MOONFOLK}, "U" + ); + // Inventive Iteration // (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 — Return up to one target creature or planeswalker to its owner's hand. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_I, new ReturnToHandTargetEffect(), new TargetCreatureOrPlaneswalker(0, 1) ); // II — Return an artifact card from your graveyard to your hand. If you can't, draw a card. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new InventiveIterationEffect()); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new InventiveIterationEffect()); // 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); + + // Living Breakthrough + this.getRightHalfCard().setPT(3, 3); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever you cast a spell, your opponents can't cast spells with the same mana value as that spell until your next turn. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility(new LivingBreakthroughEffect(), false)); } private InventiveIteration(final InventiveIteration card) { @@ -102,3 +117,56 @@ class InventiveIterationEffect extends OneShotEffect { return true; } } + +class LivingBreakthroughEffect extends ContinuousRuleModifyingEffectImpl { + + private int manaValue = -1; + + LivingBreakthroughEffect() { + super(Duration.UntilYourNextTurn, Outcome.Benefit); + staticText = "your opponents can't cast spells with the same mana value as that spell until your next turn"; + } + + private LivingBreakthroughEffect(final LivingBreakthroughEffect effect) { + super(effect); + this.manaValue = effect.manaValue; + } + + @Override + public LivingBreakthroughEffect copy() { + return new LivingBreakthroughEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + Spell spell = (Spell) getValue("spellCast"); + if (spell != null) { + this.manaValue = spell.getManaValue(); + } + } + + @Override + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source); + if (mageObject != null) { + return "You can't cast spells with mana value " + manaValue + + " this turn (" + mageObject.getIdName() + ")."; + } + return null; + } + + @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) { + if (!game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + return false; + } + Spell spell = game.getStack().getSpell(event.getTargetId()); + return spell != null && spell.getManaValue() == this.manaValue; + } +} diff --git a/Mage.Sets/src/mage/cards/i/InvertedIceberg.java b/Mage.Sets/src/mage/cards/i/InvertedIceberg.java index 0a4c7d497d3..28419263d17 100644 --- a/Mage.Sets/src/mage/cards/i/InvertedIceberg.java +++ b/Mage.Sets/src/mage/cards/i/InvertedIceberg.java @@ -1,32 +1,49 @@ package mage.cards.i; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.MayTapOrUntapTargetEffect; import mage.abilities.effects.common.MillCardsControllerEffect; import mage.abilities.keyword.CraftAbility; -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 mage.target.TargetPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class InvertedIceberg extends CardImpl { +public final class InvertedIceberg extends TransformingDoubleFacedCard { public InvertedIceberg(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{U}"); - this.secondSideCardClazz = mage.cards.i.IcebergTitan.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{U}", + "Iceberg Titan", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "U" + ); + // Inverted Iceberg // When Inverted Iceberg enters the battlefield, mill a card, then draw a card. Ability ability = new EntersBattlefieldTriggeredAbility(new MillCardsControllerEffect(1)); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy(", then")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Craft with artifact {4}{U}{U} - this.addAbility(new CraftAbility("{4}{U}{U}")); + this.getLeftHalfCard().addAbility(new CraftAbility("{4}{U}{U}")); + + // Iceberg Titan + this.getRightHalfCard().setPT(6, 6); + + // Whenever Iceberg Titan attacks, you may tap or untap target artifact or creature. + Ability atkAbility = new AttacksTriggeredAbility(new MayTapOrUntapTargetEffect()); + atkAbility.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); + this.getRightHalfCard().addAbility(atkAbility); } private InvertedIceberg(final InvertedIceberg card) { 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/InvocationOfTheFounders.java b/Mage.Sets/src/mage/cards/i/InvocationOfTheFounders.java deleted file mode 100644 index 798d94dea5f..00000000000 --- a/Mage.Sets/src/mage/cards/i/InvocationOfTheFounders.java +++ /dev/null @@ -1,78 +0,0 @@ -package mage.cards.i; - -import mage.abilities.Ability; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterSpell; -import mage.filter.common.FilterInstantOrSorcerySpell; -import mage.filter.predicate.card.CastFromZonePredicate; -import mage.game.Game; -import mage.game.stack.Spell; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class InvocationOfTheFounders extends CardImpl { - - private static final FilterSpell filter - = new FilterInstantOrSorcerySpell("an instant or sorcery spell from your hand"); - - static { - filter.add(new CastFromZonePredicate(Zone.HAND)); - } - - public InvocationOfTheFounders(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setBlue(true); - this.nightCard = true; - - // Whenever you cast an instant or sorcery spell from your hand, you may copy that spell. You may choose new targets for the copy. - this.addAbility(new SpellCastControllerTriggeredAbility( - new InvocationOfTheFoundersEffect(), filter, true - )); - } - - private InvocationOfTheFounders(final InvocationOfTheFounders card) { - super(card); - } - - @Override - public InvocationOfTheFounders copy() { - return new InvocationOfTheFounders(this); - } -} - -class InvocationOfTheFoundersEffect extends OneShotEffect { - - InvocationOfTheFoundersEffect() { - super(Outcome.Benefit); - staticText = "copy that spell. You may choose new targets for the copy"; - } - - private InvocationOfTheFoundersEffect(final InvocationOfTheFoundersEffect effect) { - super(effect); - } - - @Override - public InvocationOfTheFoundersEffect copy() { - return new InvocationOfTheFoundersEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Spell spell = (Spell) getValue("spellCast"); - if (spell != null) { - spell.createCopyOnStack(game, source, source.getControllerId(), true); - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/i/IronShieldElf.java b/Mage.Sets/src/mage/cards/i/IronShieldElf.java new file mode 100644 index 00000000000..952edca4ed3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IronShieldElf.java @@ -0,0 +1,47 @@ +package mage.cards.i; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class IronShieldElf extends CardImpl { + + public IronShieldElf(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Discard a card: This creature gains indestructible until end of turn. Tap it. + Ability ability = new SimpleActivatedAbility(new GainAbilitySourceEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn + ), new DiscardCardCost()); + ability.addEffect(new TapSourceEffect().setText("tap it")); + this.addAbility(ability); + } + + private IronShieldElf(final IronShieldElf card) { + super(card); + } + + @Override + public IronShieldElf copy() { + return new IronShieldElf(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/i/ItThatRidesAsOne.java b/Mage.Sets/src/mage/cards/i/ItThatRidesAsOne.java deleted file mode 100644 index c5105c31ff9..00000000000 --- a/Mage.Sets/src/mage/cards/i/ItThatRidesAsOne.java +++ /dev/null @@ -1,46 +0,0 @@ - -package mage.cards.i; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.keyword.FirstStrikeAbility; -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; - -/** - * - * @author fireshoes - */ -public final class ItThatRidesAsOne extends CardImpl { - - public ItThatRidesAsOne(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ELDRAZI); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - - // this card is the second face of double-faced card - this.nightCard = true; - - // First strike - this.addAbility(FirstStrikeAbility.getInstance()); - // Trample - this.addAbility(TrampleAbility.getInstance()); - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - } - - private ItThatRidesAsOne(final ItThatRidesAsOne card) { - super(card); - } - - @Override - public ItThatRidesAsOne copy() { - return new ItThatRidesAsOne(this); - } -} diff --git a/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java b/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java deleted file mode 100644 index 30411803120..00000000000 --- a/Mage.Sets/src/mage/cards/i/ItlimocCradleOfTheSun.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.i; - -import mage.Mana; -import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; -import mage.abilities.hint.common.CreaturesYouControlHint; -import mage.abilities.mana.DynamicManaAbility; -import mage.abilities.mana.GreenManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; - -import java.util.UUID; - -/** - * @author JRHerlehy - */ -public final class ItlimocCradleOfTheSun extends CardImpl { - - public ItlimocCradleOfTheSun(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - // (Transforms from Growing Rites of Itlimoc.)/ - this.nightCard = true; - - // {T}: Add {G}. - this.addAbility(new GreenManaAbility()); - - // {T}: Add {G} for each creature you control. - this.addAbility(new DynamicManaAbility( - Mana.GreenMana(1), CreaturesYouControlCount.SINGULAR - ).addHint(CreaturesYouControlHint.instance)); - } - - private ItlimocCradleOfTheSun(final ItlimocCradleOfTheSun card) { - super(card); - } - - @Override - public ItlimocCradleOfTheSun copy() { - return new ItlimocCradleOfTheSun(this); - } -} diff --git a/Mage.Sets/src/mage/cards/j/JaceTelepathUnbound.java b/Mage.Sets/src/mage/cards/j/JaceTelepathUnbound.java deleted file mode 100644 index 66e1b793d62..00000000000 --- a/Mage.Sets/src/mage/cards/j/JaceTelepathUnbound.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.j; - -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.MayCastTargetCardEffect; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -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 mage.game.command.emblems.JaceTelepathUnboundEmblem; -import mage.target.common.TargetCardInYourGraveyard; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class JaceTelepathUnbound extends CardImpl { - - public JaceTelepathUnbound(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.JACE); - - this.color.setBlue(true); - this.nightCard = true; - - this.setStartingLoyalty(5); - - // +1: Up to one target creature gets -2/-0 until your next turn. - Ability ability = new LoyaltyAbility(new BoostTargetEffect( - -2, 0, Duration.UntilYourNextTurn - ).setText("Up to one target creature gets -2/-0 until your next turn"), 1); - ability.addTarget(new TargetCreaturePermanent(0, 1)); - this.addAbility(ability); - - // -3: You may cast target instant or sorcery card from your graveyard this turn. If that card would be put into your graveyard this turn, exile it instead. - ability = new LoyaltyAbility(new MayCastTargetCardEffect(Duration.EndOfTurn, true), -3); - ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD)); - this.addAbility(ability); - - // −9: You get an emblem with "Whenever you cast a spell, target opponent mills five cards." - this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new JaceTelepathUnboundEmblem()), -9)); - } - - private JaceTelepathUnbound(final JaceTelepathUnbound card) { - super(card); - } - - @Override - public JaceTelepathUnbound copy() { - return new JaceTelepathUnbound(this); - } -} diff --git a/Mage.Sets/src/mage/cards/j/JaceVrynsProdigy.java b/Mage.Sets/src/mage/cards/j/JaceVrynsProdigy.java index 7c8eb721011..3e2d9e76ffa 100644 --- a/Mage.Sets/src/mage/cards/j/JaceVrynsProdigy.java +++ b/Mage.Sets/src/mage/cards/j/JaceVrynsProdigy.java @@ -1,7 +1,7 @@ package mage.cards.j; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.CardsInControllerGraveyardCondition; @@ -9,39 +9,61 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.MayCastTargetCardEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.command.emblems.JaceTelepathUnboundEmblem; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author LevelX2 */ -public final class JaceVrynsProdigy extends CardImpl { +public final class JaceVrynsProdigy extends TransformingDoubleFacedCard { private static final Condition condition = new CardsInControllerGraveyardCondition(5); public JaceVrynsProdigy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(0); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{1}{U}", + "Jace, Telepath Unbound", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.JACE}, "U"); - this.secondSideCardClazz = mage.cards.j.JaceTelepathUnbound.class; + // Jace, Vryn's Prodigy (front) + this.getLeftHalfCard().setPT(0, 2); - // {T}: Draw a card, then discard a card. If there are five or more cards in your graveyard, exile Jace, Vryn's Prodigy, then return him to the battefield transformed under his owner's control. - this.addAbility(new TransformAbility()); + // {T}: Draw a card, then discard a card. If there are five or more cards in your graveyard, exile Jace, Vryn's Prodigy, then return him to the battlefield transformed under his owner's control. Ability ability = new SimpleActivatedAbility( new DrawDiscardControllerEffect(1, 1), new TapSourceCost() ); ability.addEffect(new ConditionalOneShotEffect( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.HE), condition )); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Jace, Telepath Unbound (back) + this.getRightHalfCard().setStartingLoyalty(5); + + // +1: Up to one target creature gets -2/-0 until your next turn. + Ability pwAbility = new LoyaltyAbility(new BoostTargetEffect( + -2, 0, Duration.UntilYourNextTurn + ).setText("Up to one target creature gets -2/-0 until your next turn"), 1); + pwAbility.addTarget(new TargetCreaturePermanent(0, 1)); + this.getRightHalfCard().addAbility(pwAbility); + + // -3: You may cast target instant or sorcery card from your graveyard this turn. If that card would be put into your graveyard this turn, exile it instead. + pwAbility = new LoyaltyAbility(new MayCastTargetCardEffect(Duration.EndOfTurn, true), -3); + pwAbility.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD)); + this.getRightHalfCard().addAbility(pwAbility); + + // −9: You get an emblem with "Whenever you cast a spell, target opponent mills five cards." (emblem class unchanged) + this.getRightHalfCard().addAbility(new LoyaltyAbility(new GetEmblemEffect(new JaceTelepathUnboundEmblem()), -9)); } private JaceVrynsProdigy(final JaceVrynsProdigy card) { diff --git a/Mage.Sets/src/mage/cards/j/JacobHaukenInspector.java b/Mage.Sets/src/mage/cards/j/JacobHaukenInspector.java index c71aedd5f2c..de6b8119722 100644 --- a/Mage.Sets/src/mage/cards/j/JacobHaukenInspector.java +++ b/Mage.Sets/src/mage/cards/j/JacobHaukenInspector.java @@ -1,49 +1,65 @@ package mage.cards.j; -import java.util.UUID; -import mage.MageInt; +import mage.MageIdentifier; import mage.MageObject; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.Card; -import mage.constants.*; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.game.ExileZone; import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInHand; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** - * * @author weirddan455 */ -public final class JacobHaukenInspector extends CardImpl { +public final class JacobHaukenInspector extends TransformingDoubleFacedCard { public JacobHaukenInspector(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.HUMAN, SubType.ADVISOR}, "{1}{U}", + "Hauken's Insight", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "U"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ADVISOR); - this.power = new MageInt(0); - this.toughness = new MageInt(2); - - this.secondSideCardClazz = mage.cards.h.HaukensInsight.class; + // Jacob Hauken, Inspector + this.getLeftHalfCard().setPT(0, 2); // {T}: Draw a card, then exile a card from your hand face down. You may look at that card for as long as it remains exiled. You may pay {4}{U}{U}. If you do, transform Jacob Hauken, Inspector. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new JacobHaukenInspectorExileEffect(), new TapSourceCost()); ability.addEffect(new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{U}{U}"))); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Hauken's Insight + + // At the beginning of your upkeep, exile the top card of your library face down. You may look at that card for as long as it remains exiled. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new HaukensInsightExileEffect())); + + // Once during each of your turns, you may play a land or cast a spell from among the cards exiled with this permanent without paying its mana cost. + Ability playAbility = new SimpleStaticAbility(new HaukensInsightPlayEffect()) + .setIdentifier(MageIdentifier.HaukensInsightWatcher); + playAbility.addWatcher(new HaukensInsightWatcher()); + this.getRightHalfCard().addAbility(playAbility); } private JacobHaukenInspector(final JacobHaukenInspector card) { @@ -135,3 +151,146 @@ class JacobHaukenInspectorLookEffect extends AsThoughEffectImpl { && objectId.equals(cardId); } } + +class HaukensInsightExileEffect extends OneShotEffect { + + HaukensInsightExileEffect() { + super(Outcome.Benefit); + staticText = "exile the top card of your library face down. You may look at that card for as long as it remains exiled"; + } + + private HaukensInsightExileEffect(final HaukensInsightExileEffect effect) { + super(effect); + } + + @Override + public HaukensInsightExileEffect copy() { + return new HaukensInsightExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getStackMomentSourceZCC()); + MageObject sourceObject = source.getSourceObject(game); + String exileName = sourceObject == null ? null : sourceObject.getIdName(); + card.setFaceDown(true, game); + controller.moveCardsToExile(card, source, game, false, exileId, exileName); + if (game.getState().getZone(card.getId()) == Zone.EXILED) { + card.setFaceDown(true, game); + HaukensInsightLookEffect effect = new HaukensInsightLookEffect(controller.getId()); + effect.setTargetPointer(new FixedTarget(card, game)); + game.addEffect(effect, source); + return true; + } + } + } + return false; + } +} + +class HaukensInsightLookEffect extends AsThoughEffectImpl { + + private final UUID authorizedPlayerId; + + public HaukensInsightLookEffect(UUID authorizedPlayerId) { + super(AsThoughEffectType.LOOK_AT_FACE_DOWN, Duration.EndOfGame, Outcome.Benefit); + this.authorizedPlayerId = authorizedPlayerId; + } + + private HaukensInsightLookEffect(final HaukensInsightLookEffect effect) { + super(effect); + this.authorizedPlayerId = effect.authorizedPlayerId; + } + + @Override + public HaukensInsightLookEffect copy() { + return new HaukensInsightLookEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + UUID cardId = getTargetPointer().getFirst(game, source); + if (cardId == null) { + this.discard(); // card is no longer in the origin zone, effect can be discarded + } + return affectedControllerId.equals(authorizedPlayerId) + && objectId.equals(cardId); + } +} + +class HaukensInsightPlayEffect extends AsThoughEffectImpl { + + HaukensInsightPlayEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.PlayForFree); + staticText = "Once during each of your turns, you may play a land or cast a spell from among the cards exiled with this permanent without paying its mana cost"; + } + + private HaukensInsightPlayEffect(final HaukensInsightPlayEffect effect) { + super(effect); + } + + @Override + public HaukensInsightPlayEffect copy() { + return new HaukensInsightPlayEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (affectedControllerId.equals(source.getControllerId()) && game.isActivePlayer(source.getControllerId())) { + Player controller = game.getPlayer(source.getControllerId()); + HaukensInsightWatcher watcher = game.getState().getWatcher(HaukensInsightWatcher.class); + Permanent sourceObject = game.getPermanent(source.getSourceId()); + if (controller != null && watcher != null && sourceObject != null && !watcher.isAbilityUsed(new MageObjectReference(sourceObject, game))) { + UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId())); + ExileZone exileZone = game.getExile().getExileZone(exileId); + if (exileZone != null && exileZone.contains(CardUtil.getMainCardId(game, objectId))) { + allowCardToPlayWithoutMana(objectId, source, affectedControllerId, MageIdentifier.HaukensInsightWatcher, game); + return true; + } + } + } + return false; + } +} + +class HaukensInsightWatcher extends Watcher { + + private final Set usedFrom = new HashSet<>(); + + public HaukensInsightWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SPELL_CAST || event.getType() == GameEvent.EventType.LAND_PLAYED) { + if (event.hasApprovingIdentifier(MageIdentifier.HaukensInsightWatcher)) { + usedFrom.add(event.getApprovingObject().getApprovingMageObjectReference()); + } + } + } + + @Override + public void reset() { + super.reset(); + usedFrom.clear(); + } + + public boolean isAbilityUsed(MageObjectReference mor) { + return usedFrom.contains(mor); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JadeSeedstones.java b/Mage.Sets/src/mage/cards/j/JadeSeedstones.java index 55cde970259..0d67cd34d26 100644 --- a/Mage.Sets/src/mage/cards/j/JadeSeedstones.java +++ b/Mage.Sets/src/mage/cards/j/JadeSeedstones.java @@ -1,36 +1,55 @@ package mage.cards.j; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +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.CardImpl; +import mage.cards.Card; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.StaticFilters; +import mage.game.ExileZone; +import mage.game.Game; import mage.target.common.TargetCreaturePermanentAmount; +import mage.util.CardUtil; import java.util.UUID; /** * @author TheElk801 */ -public final class JadeSeedstones extends CardImpl { +public final class JadeSeedstones extends TransformingDoubleFacedCard { public JadeSeedstones(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{G}"); - this.secondSideCardClazz = mage.cards.j.JadeheartAttendant.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{3}{G}", + "Jadeheart Attendant", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "G"); + + // Jade Seedstones // When Jade Seedstones enters the battlefield, distribute three +1/+1 counters among one, two, or three target creatures you control. Ability ability = new EntersBattlefieldTriggeredAbility(new DistributeCountersEffect()); ability.addTarget(new TargetCreaturePermanentAmount(3, StaticFilters.FILTER_CONTROLLED_CREATURES)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Craft with creature {5}{G}{G} - this.addAbility(new CraftAbility( - "{5}{G}{G}", "creature", "another creature you control " + - "or a creature card in your graveyard", CardType.CREATURE.getPredicate()) + this.getLeftHalfCard().addAbility(new CraftAbility( + "{5}{G}{G}", "creature", "another creature you control or a creature card in your graveyard", CardType.CREATURE.getPredicate()) ); + + // Jadeheart Attendant + this.getRightHalfCard().setPT(7, 7); + + // When Jadeheart Attendant enters the battlefield, you gain life equal to the mana value of the exiled card used to craft it. + this.getRightHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(JadeheartAttendantValue.instance) + .setText("you gain life equal to the mana value of the exiled card used to craft it"))); } private JadeSeedstones(final JadeSeedstones card) { @@ -42,3 +61,42 @@ public final class JadeSeedstones extends CardImpl { return new JadeSeedstones(this); } } + +enum JadeheartAttendantValue 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().getMainCard().getId(), + sourceCard.getMainCard().getZoneChangeCounter(game) - 1)); + return exileZone != null + ? exileZone + .getCards(game) + .stream() + .mapToInt(MageObject::getManaValue) + .sum() + : 0; + } + + @Override + public JadeheartAttendantValue copy() { + return this; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "1"; + } +} diff --git a/Mage.Sets/src/mage/cards/j/JadeheartAttendant.java b/Mage.Sets/src/mage/cards/j/JadeheartAttendant.java deleted file mode 100644 index fddf0981f84..00000000000 --- a/Mage.Sets/src/mage/cards/j/JadeheartAttendant.java +++ /dev/null @@ -1,80 +0,0 @@ -package mage.cards.j; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.GainLifeEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.game.ExileZone; -import mage.game.Game; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class JadeheartAttendant extends CardImpl { - - public JadeheartAttendant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.GOLEM); - this.power = new MageInt(7); - this.toughness = new MageInt(7); - this.nightCard = true; - this.color.setGreen(true); - - // When Jadeheart Attendant enters the battlefield, you gain life equal to the mana value of the exiled card used to craft it. - this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(JadeheartAttendantValue.instance) - .setText("you gain life equal to the mana value of the exiled card used to craft it"))); - } - - private JadeheartAttendant(final JadeheartAttendant card) { - super(card); - } - - @Override - public JadeheartAttendant copy() { - return new JadeheartAttendant(this); - } -} - -enum JadeheartAttendantValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - ExileZone exileZone = game - .getExile() - .getExileZone(CardUtil.getExileZoneId(game, sourceAbility, -2)); - return exileZone != null - ? exileZone - .getCards(game) - .stream() - .mapToInt(MageObject::getManaValue) - .sum() - : 0; - } - - @Override - public JadeheartAttendantValue copy() { - return this; - } - - @Override - public String getMessage() { - return ""; - } - - @Override - public String toString() { - return "1"; - } -} 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/JechtReluctantGuardian.java b/Mage.Sets/src/mage/cards/j/JechtReluctantGuardian.java index 5cb0bcea09c..79a0a08458f 100644 --- a/Mage.Sets/src/mage/cards/j/JechtReluctantGuardian.java +++ b/Mage.Sets/src/mage/cards/j/JechtReluctantGuardian.java @@ -1,43 +1,64 @@ package mage.cards.j; -import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.SagaAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.SacrificeOpponentsEffect; +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.constants.CardType; -import mage.constants.PutCards; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.filter.StaticFilters; import java.util.UUID; /** * @author TheElk801 */ -public final class JechtReluctantGuardian extends CardImpl { +public final class JechtReluctantGuardian extends TransformingDoubleFacedCard { public JechtReluctantGuardian(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARRIOR}, "{3}{B}", + "Braska's Final Aeon", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SAGA, SubType.NIGHTMARE}, "B"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(4); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.b.BraskasFinalAeon.class; + // Jecht, Reluctant Guardian + this.getLeftHalfCard().setPT(4, 3); // Menace - this.addAbility(new MenaceAbility()); + this.getLeftHalfCard().addAbility(new MenaceAbility()); // Whenever Jecht deals combat damage to a player, you may exile it, then return it to the battlefield transformed under its owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + this.getLeftHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED) .setText("exile it, then return it to the battlefield transformed under its owner's control"), true )); + + // Braska's Final Aeon + this.getRightHalfCard().setPT(7, 7); + + // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I, II -- Jecht Beam -- Each opponent discards a card and you draw a card. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, ability -> { + ability.addEffect(new DiscardEachPlayerEffect(TargetController.OPPONENT)); + ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and you")); + ability.withFlavorWord("Jecht Beam"); + }); + + // III -- Ultimate Jecht Shot -- Each opponent sacrifices two creatures of their choice. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_III, ability -> { + ability.addEffect(new SacrificeOpponentsEffect(2, StaticFilters.FILTER_PERMANENT_CREATURES)); + ability.withFlavorWord("Ultimate Jecht Shot"); + }); + this.getRightHalfCard().addAbility(sagaAbility.withShowSacText(true)); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); } private JechtReluctantGuardian(final JechtReluctantGuardian card) { diff --git a/Mage.Sets/src/mage/cards/j/JerrenCorruptedBishop.java b/Mage.Sets/src/mage/cards/j/JerrenCorruptedBishop.java index 606bec7fe1e..1c3ece7ad3e 100644 --- a/Mage.Sets/src/mage/cards/j/JerrenCorruptedBishop.java +++ b/Mage.Sets/src/mage/cards/j/JerrenCorruptedBishop.java @@ -1,24 +1,23 @@ package mage.cards.j; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; +import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.*; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -33,35 +32,45 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class JerrenCorruptedBishop extends CardImpl { +public final class JerrenCorruptedBishop extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledPermanent(SubType.HUMAN); public JerrenCorruptedBishop(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.CLERIC}, "{2}{B}", + "Ormendahl, the Corrupter", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "B"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.o.OrmendahlTheCorrupter.class; + // Jerren, Corrupted Bishop + this.getLeftHalfCard().setPT(2, 3); // Whenever Jerren, Corrupted Bishop enters the battlefield or another nontoken Human you control dies, you lose 1 life and create a 1/1 white Human creature token. - this.addAbility(new JerrenCorruptedBishopTriggeredAbility()); + this.getLeftHalfCard().addAbility(new JerrenCorruptedBishopTriggeredAbility()); // {2}: Target Human you control gains lifelink until end of turn. Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect( LifelinkAbility.getInstance(), Duration.EndOfTurn ), new GenericManaCost(2)); ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - - // At the beginning of your end step, if you have exactly 13 life, you may pay {4}{B}{B}. If you do, transform Jerren. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility(TargetController.YOU, new DoIfCostPaid( + this.getLeftHalfCard().addAbility(ability); + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(TargetController.YOU, new DoIfCostPaid( new TransformSourceEffect(), new ManaCostsImpl<>("{4}{B}{B}") ), false, JerrenCorruptedBishopCondition.instance)); + + // Ormendahl, the Corrupter + this.getRightHalfCard().setPT(6, 6); + + // Flying, Trample, Lifelink + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // Sacrifice another creature: Draw a card. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility( + new DrawCardSourceControllerEffect(1), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) + )); } private JerrenCorruptedBishop(final JerrenCorruptedBishop card) { @@ -125,7 +134,6 @@ class JerrenCorruptedBishopTriggeredAbility extends TriggeredAbilityImpl { && zEvent.getTarget().isControlledBy(getControllerId()) && !(zEvent.getTarget() instanceof PermanentToken) && zEvent.getTarget().hasSubtype(SubType.HUMAN, game); - default: return false; } diff --git a/Mage.Sets/src/mage/cards/j/JetfireAirGuardian.java b/Mage.Sets/src/mage/cards/j/JetfireAirGuardian.java deleted file mode 100644 index 4b13db01518..00000000000 --- a/Mage.Sets/src/mage/cards/j/JetfireAirGuardian.java +++ /dev/null @@ -1,58 +0,0 @@ -package mage.cards.j; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.keyword.AdaptEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.LivingMetalAbility; -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 JetfireAirGuardian extends CardImpl { - - public JetfireAirGuardian(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(4); - this.color.setBlue(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // {U}{U}{U}: Convert Jetfire, then adapt 3. - Ability ability = new SimpleActivatedAbility( - new TransformSourceEffect() - .setText("convert {this}"), - new ManaCostsImpl<>("{U}{U}{U}") - ); - ability.addEffect(new AdaptEffect(3).concatBy(", then")); - this.addAbility(ability); - } - - private JetfireAirGuardian(final JetfireAirGuardian card) { - super(card); - } - - @Override - public JetfireAirGuardian copy() { - return new JetfireAirGuardian(this); - } -} diff --git a/Mage.Sets/src/mage/cards/j/JetfireIngeniousScientist.java b/Mage.Sets/src/mage/cards/j/JetfireIngeniousScientist.java index 14fe70380a6..e3280a8e28d 100644 --- a/Mage.Sets/src/mage/cards/j/JetfireIngeniousScientist.java +++ b/Mage.Sets/src/mage/cards/j/JetfireIngeniousScientist.java @@ -1,18 +1,20 @@ package mage.cards.j; -import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.VariableCost; import mage.abilities.costs.common.RemoveVariableCountersTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.keyword.AdaptEffect; import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LivingMetalAbility; import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; import mage.abilities.mana.builder.ConditionalManaBuilder; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -30,22 +32,22 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class JetfireIngeniousScientist extends CardImpl { +public final class JetfireIngeniousScientist extends TransformingDoubleFacedCard { public JetfireIngeniousScientist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{U}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{4}{U}", + "Jetfire, Air Guardian", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "U"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.j.JetfireAirGuardian.class; + // Jetfire, Ingenious Scientist + this.getLeftHalfCard().setPT(3, 4); // More Than Meets the Eye {3}{U} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{3}{U}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{3}{U}")); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Remove one or more +1/+1 counters from among artifacts you control: Target player adds that much {C}. This mana can't be spent to cast nonartifact spells. Convert Jetfire. Ability ability = new SimpleActivatedAbility( @@ -57,7 +59,25 @@ public final class JetfireIngeniousScientist extends CardImpl { ); ability.addEffect(new TransformSourceEffect().setText("convert {this}")); ability.addTarget(new TargetPlayer()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Jetfire, Air Guardian + this.getRightHalfCard().setPT(3, 4); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // {U}{U}{U}: Convert Jetfire, then adapt 3. + Ability backAbility = new SimpleActivatedAbility( + new TransformSourceEffect() + .setText("convert {this}"), + new ManaCostsImpl<>("{U}{U}{U}") + ); + backAbility.addEffect(new AdaptEffect(3).concatBy(", then")); + this.getRightHalfCard().addAbility(backAbility); } private JetfireIngeniousScientist(final JetfireIngeniousScientist card) { diff --git a/Mage.Sets/src/mage/cards/j/JillShivasDominant.java b/Mage.Sets/src/mage/cards/j/JillShivasDominant.java index c115eba3121..7f4874f9200 100644 --- a/Mage.Sets/src/mage/cards/j/JillShivasDominant.java +++ b/Mage.Sets/src/mage/cards/j/JillShivasDominant.java @@ -1,61 +1,82 @@ package mage.cards.j; -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.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.TapAllEffect; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; 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.filter.FilterPermanent; +import mage.filter.common.FilterLandPermanent; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class JillShivasDominant extends CardImpl { +public final class JillShivasDominant extends TransformingDoubleFacedCard { - private static final FilterPermanent filter = new FilterNonlandPermanent("other target nonland permanent"); + private static final FilterPermanent filterFront = new FilterNonlandPermanent("other target nonland permanent"); + private static final FilterPermanent filterLandsOpponents = new FilterLandPermanent("lands your opponents control"); static { - filter.add(AnotherPredicate.instance); + filterFront.add(AnotherPredicate.instance); + filterLandsOpponents.add(TargetController.OPPONENT.getControllerPredicate()); } public JillShivasDominant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE, SubType.WARRIOR}, "{2}{U}", + "Shiva, Warden of Ice", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SAGA, SubType.ELEMENTAL}, "U"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.s.ShivaWardenOfIce.class; + // Jill, Shiva's Dominant (front) + this.getLeftHalfCard().setPT(2, 2); // When Jill enters, return up to one other target nonland permanent to its owner's hand. Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()); - ability.addTarget(new TargetPermanent(0, 1, filter)); - this.addAbility(ability); + ability.addTarget(new TargetPermanent(0, 1, filterFront)); + this.getLeftHalfCard().addAbility(ability); // {3}{U}{U}, {T}: Exile Jill, then return it to the battlefield transformed under its owner's control. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - ability = new ActivateAsSorceryActivatedAbility( + Ability transformAbility = new ActivateAsSorceryActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{3}{U}{U}") ); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); + transformAbility.addCost(new TapSourceCost()); + this.getLeftHalfCard().addAbility(transformAbility); + + // Shiva, Warden of Ice (back) + this.getRightHalfCard().setPT(4, 5); + + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I, II -- Mesmerize -- Target creature can't be blocked this turn. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, sagaChapterAbility -> { + sagaChapterAbility.addEffect(new CantBeBlockedTargetEffect(Duration.EndOfTurn)); + sagaChapterAbility.addTarget(new TargetCreaturePermanent()); + sagaChapterAbility.withFlavorWord("Mesmerize"); + }); + + // III -- Cold Snap -- Tap all lands your opponents control. Exile Shiva, then return it to the battlefield. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_III, sagaChapterAbility -> { + sagaChapterAbility.addEffect(new TapAllEffect(filterLandsOpponents)); + sagaChapterAbility.addEffect(new ExileSourceAndReturnFaceUpEffect()); + sagaChapterAbility.withFlavorWord("Cold Snap"); + }); + this.getRightHalfCard().addAbility(sagaAbility); } private JillShivasDominant(final JillShivasDominant card) { diff --git a/Mage.Sets/src/mage/cards/j/JinGitaxias.java b/Mage.Sets/src/mage/cards/j/JinGitaxias.java index 6fd9909cef0..4bf0fed7d17 100644 --- a/Mage.Sets/src/mage/cards/j/JinGitaxias.java +++ b/Mage.Sets/src/mage/cards/j/JinGitaxias.java @@ -1,58 +1,92 @@ package mage.cards.j; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.SagaAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.condition.common.CardsInHandCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; +import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; +import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; import mage.abilities.keyword.WardAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterSpell; +import mage.filter.StaticFilters; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; import java.util.UUID; -public class JinGitaxias extends CardImpl { +public class JinGitaxias extends TransformingDoubleFacedCard { private static final FilterSpell filter = new FilterSpell("a noncreature spell with mana value 3 or greater"); + private static final FilterCreaturePermanent filterNonPhyrexian = new FilterCreaturePermanent("non-Phyrexian creatures"); static { filter.add(Predicates.not(CardType.CREATURE.getPredicate())); filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 2)); + filterNonPhyrexian.add(Predicates.not(SubType.PHYREXIAN.getPredicate())); } public JinGitaxias(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); - this.supertype.add(SuperType.LEGENDARY); - this.addSubType(SubType.PHYREXIAN); - this.addSubType(SubType.PRAETOR); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.secondSideCardClazz = mage.cards.t.TheGreatSynthesis.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.PRAETOR}, "{3}{U}{U}", + "The Great Synthesis", + new SuperType[]{}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "U"); - //Ward {2} - this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); + // Jin-Gitaxias + this.getLeftHalfCard().setPT(5, 5); - //Whenever you cast a noncreature spell with mana value 3 or greater, draw a card. - this.addAbility(new SpellCastControllerTriggeredAbility( - new DrawCardSourceControllerEffect(1), - filter, false + // Ward {2} + this.getLeftHalfCard().addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); + + // Whenever you cast a noncreature spell with mana value 3 or greater, draw a card. + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new DrawCardSourceControllerEffect(1), filter, false )); - //{3}{U}: Exile Jin-Gitaxias, then return it to the battlefield transformed under its owner’s control. Activate - //only as a sorcery and only if you have seven or more cards in hand. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateIfConditionActivatedAbility( + // {3}{U}: Exile Jin-Gitaxias, then return it to the battlefield transformed under its owner’s control. Activate only as a sorcery and only if you have seven or more cards in hand. + this.getLeftHalfCard().addAbility(new ActivateIfConditionActivatedAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{3}{U}"), new CardsInHandCondition(ComparisonType.MORE_THAN, 6) ).setTiming(TimingRule.SORCERY)); + + // The Great Synthesis + + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I — Draw cards equal to the number of cards in your hand. You have no maximum hand size for as long as you control The Great Synthesis. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, + new DrawCardSourceControllerEffect(CardsInControllerHandCount.ANY) + .setText("draw cards equal to the number of cards in your hand"), + new MaximumHandSizeControllerEffect(Integer.MAX_VALUE, Duration.WhileOnBattlefield, + MaximumHandSizeControllerEffect.HandSizeModification.SET) + .setText("you have no maximum hand size for as long as you control {this}")); + + // II — Return all non-Phyrexian creatures to their owners' hands. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_II, new ReturnToHandFromBattlefieldAllEffect(filterNonPhyrexian)); + + // III — You may cast any number of spells from your hand without paying their mana cost. Exile The Great Synthesis, then return it to the battlefield (front face up). + sagaAbility.addChapterEffect( + this.getRightHalfCard(), SagaChapter.CHAPTER_III, + new TheGreatSynthesisCastEffect(), + new ExileSourceAndReturnFaceUpEffect() + ); + this.getRightHalfCard().addAbility(sagaAbility); } private JinGitaxias(final JinGitaxias card) { @@ -64,3 +98,30 @@ public class JinGitaxias extends CardImpl { return new JinGitaxias(this); } } + +class TheGreatSynthesisCastEffect extends OneShotEffect { + public TheGreatSynthesisCastEffect() { + super(Outcome.PlayForFree); + this.staticText = "you may cast any number of spells from your hand without paying their mana costs"; + } + + private TheGreatSynthesisCastEffect(final TheGreatSynthesisCastEffect effect) { + super(effect); + } + + @Override + public TheGreatSynthesisCastEffect copy() { + return new TheGreatSynthesisCastEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Cards cards = controller.getHand(); + CardUtil.castMultipleWithAttributeForFree(controller, source, game, cards, StaticFilters.FILTER_CARD); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/j/JinSakaiGhostOfTsushima.java b/Mage.Sets/src/mage/cards/j/JinSakaiGhostOfTsushima.java new file mode 100644 index 00000000000..4839a8ce934 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JinSakaiGhostOfTsushima.java @@ -0,0 +1,116 @@ +package mage.cards.j; + +import mage.MageInt; +import mage.MageItem; +import mage.abilities.Mode; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +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.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.Objects; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class JinSakaiGhostOfTsushima extends CardImpl { + + public JinSakaiGhostOfTsushima(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{U}{B}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SAMURAI); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Whenever Jin Sakai deals combat damage to a player, draw a card. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1))); + + // Whenever a creature you control attacks a player, if no other creatures are attacking that player, choose one -- + // * Standoff -- It gains double strike until end of turn. + // * Ghost -- It can't be blocked this turn. + this.addAbility(new JinSakaiGhostOfTsushimaTriggeredAbility()); + } + + private JinSakaiGhostOfTsushima(final JinSakaiGhostOfTsushima card) { + super(card); + } + + @Override + public JinSakaiGhostOfTsushima copy() { + return new JinSakaiGhostOfTsushima(this); + } +} + +class JinSakaiGhostOfTsushimaTriggeredAbility extends TriggeredAbilityImpl { + + JinSakaiGhostOfTsushimaTriggeredAbility() { + super(Zone.BATTLEFIELD, new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance()).withTargetDescription("it")); + this.withFirstModeFlavorWord("Standoff"); + this.addMode(new Mode(new CantBeBlockedTargetEffect().withTargetDescription("it")).withFlavorWord("Ghost")); + this.setTriggerPhrase("Whenever a creature you control attacks a player, if no other creatures are attacking that player, "); + } + + private JinSakaiGhostOfTsushimaTriggeredAbility(final JinSakaiGhostOfTsushimaTriggeredAbility ability) { + super(ability); + } + + @Override + public JinSakaiGhostOfTsushimaTriggeredAbility copy() { + return new JinSakaiGhostOfTsushimaTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ATTACKER_DECLARED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null + || !permanent.isControlledBy(getControllerId()) + || game.getPlayer(game.getCombat().getDefenderId(permanent.getId())) == null) { + return false; + } + this.getAllEffects().setTargetPointer(new FixedTarget(permanent, game)); + return true; + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return this + .getAllEffects() + .stream() + .map(Effect::getTargetPointer) + .map(targetPointer -> targetPointer.getFirst(game, this)) + .map(game::getPermanent) + .filter(Objects::nonNull) + .findAny() + .map(MageItem::getId) + .map(game.getCombat()::getDefenderId) + .filter(defenderId -> game + .getCombat() + .getAttackers() + .stream() + .map(game.getCombat()::getDefenderId) + .filter(defenderId::equals) + .count() == 1) + .isPresent(); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JoshuaPhoenixsDominant.java b/Mage.Sets/src/mage/cards/j/JoshuaPhoenixsDominant.java index bcc50be49c0..9db4bba6ead 100644 --- a/Mage.Sets/src/mage/cards/j/JoshuaPhoenixsDominant.java +++ b/Mage.Sets/src/mage/cards/j/JoshuaPhoenixsDominant.java @@ -1,49 +1,82 @@ package mage.cards.j; -import mage.MageInt; +import mage.MageObject; 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.common.DamagePlayersEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.discard.DiscardAndDrawThatManyEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.LifelinkAbility; 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.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.target.common.TargetCardInYourGraveyard; +import mage.util.CardUtil; +import java.util.Objects; +import java.util.Set; import java.util.UUID; /** * @author TheElk801 */ -public final class JoshuaPhoenixsDominant extends CardImpl { +public final class JoshuaPhoenixsDominant extends TransformingDoubleFacedCard { public JoshuaPhoenixsDominant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{W}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE, SubType.WIZARD}, "{1}{R}{W}", + "Phoenix, Warden of Fire", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.SAGA, SubType.PHOENIX}, "RW"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.NOBLE); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.p.PhoenixWardenOfFire.class; + // Joshua, Phoenix's Dominant + this.getLeftHalfCard().setPT(3, 4); // When Joshua enters, discard up to two cards, then draw that many cards. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DiscardAndDrawThatManyEffect(2))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DiscardAndDrawThatManyEffect(2))); // {3}{R}{W}, {T}: Exile Joshua, 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<>("{3}{R}{W}") ); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Phoenix, Warden of Fire + this.getRightHalfCard().setPT(4, 4); + + // (As this Saga enters and after your draw step, add a lore counter.) + SagaAbility sagaAbility = new SagaAbility(this.getRightHalfCard()); + + // I, II -- Rising Flames -- Phoenix deals 2 damage to each opponent. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, chapter -> { + chapter.addEffect(new DamagePlayersEffect(2, TargetController.OPPONENT)); + chapter.withFlavorWord("Rising Flames"); + }); + + // III -- Flames of Rebirth -- Return any number of target creature cards with total mana value 6 or less from your graveyard to the battlefield. Exile Phoenix, then return it to the battlefield. + sagaAbility.addChapterEffect(this.getRightHalfCard(), SagaChapter.CHAPTER_III, chapter -> { + chapter.addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); + chapter.addEffect(new ExileSourceAndReturnFaceUpEffect()); + chapter.addTarget(new PhoenixWardenOfFireTarget()); + chapter.withFlavorWord("Flames of Rebirth"); + }); + this.getRightHalfCard().addAbility(sagaAbility); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); } private JoshuaPhoenixsDominant(final JoshuaPhoenixsDominant card) { @@ -55,3 +88,53 @@ public final class JoshuaPhoenixsDominant extends CardImpl { return new JoshuaPhoenixsDominant(this); } } + +class PhoenixWardenOfFireTarget extends TargetCardInYourGraveyard { + + private static final FilterCard filterStatic = new FilterCreatureCard( + "creature cards with total mana value 6 or less from your graveyard" + ); + + PhoenixWardenOfFireTarget() { + super(0, Integer.MAX_VALUE, filterStatic, false); + } + + private PhoenixWardenOfFireTarget(final PhoenixWardenOfFireTarget target) { + super(target); + } + + @Override + public PhoenixWardenOfFireTarget copy() { + return new PhoenixWardenOfFireTarget(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, 6, game + ); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) { + return CardUtil.checkPossibleTargetsTotalValueLimit( + this.getTargets(), + super.possibleTargets(sourceControllerId, source, game), + MageObject::getManaValue, 6, 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/j/JourneyToEternity.java b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java index f3759a3341d..132be3c70e8 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java +++ b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java @@ -3,47 +3,60 @@ package mage.cards.j; import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; +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.AttachEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.AnyColorManaAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; /** * @author LevelX2 */ -public final class JourneyToEternity extends CardImpl { +public final class JourneyToEternity extends TransformingDoubleFacedCard { public JourneyToEternity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "{1}{B}{G}", + "Atzal, Cave of Eternity", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AURA); - - this.secondSideCardClazz = mage.cards.a.AtzalCaveOfEternity.class; - - // Enchant creature you control + // Journey to Eternity TargetPermanent auraTarget = new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED); - this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - this.addAbility(new EnchantAbility(auraTarget)); + this.getLeftHalfCard().getSpellAbility().addTarget(auraTarget); + this.getLeftHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getLeftHalfCard().addAbility(new EnchantAbility(auraTarget)); // When enchanted creature dies, return it to the battlefield under your control, then return Journey to Eternity to the battlefield transformed under your control. - this.addAbility(new TransformAbility()); Ability ability = new DiesAttachedTriggeredAbility(new ReturnToBattlefieldUnderYourControlAttachedEffect("it"), "enchanted creature"); ability.addEffect(new JourneyToEternityReturnTransformedSourceEffect()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + // Atzal, Cave of Eternity + + // {T}: Add one mana of any color. + this.getRightHalfCard().addAbility(new AnyColorManaAbility()); + + // {3}{B}{G}, {T}: Return target creature card from your graveyard to the battlefield. + Ability backAbility = new SimpleActivatedAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl<>("{3}{B}{G}")); + backAbility.addCost(new TapSourceCost()); + backAbility.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getRightHalfCard().addAbility(backAbility); } private JourneyToEternity(final JourneyToEternity card) { diff --git a/Mage.Sets/src/mage/cards/j/Jubilation.java b/Mage.Sets/src/mage/cards/j/Jubilation.java new file mode 100644 index 00000000000..63d1c991416 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/Jubilation.java @@ -0,0 +1,55 @@ +package mage.cards.j; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.EncoreAbility; +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 Jubilation extends CardImpl { + + public Jubilation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // When this creature enters, creatures you control get +2/+2 and gain trample until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new BoostControlledEffect( + 2, 2, Duration.EndOfTurn + ).setText("creatures you control get +2/+2")); + ability.addEffect(new GainAbilityControlledEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_CONTROLLED_CREATURE + ).setText("and gain trample until end of turn")); + this.addAbility(ability); + + // Encore {7}{G}{G} + this.addAbility(new EncoreAbility(new ManaCostsImpl<>("{7}{G}{G}"))); + } + + private Jubilation(final Jubilation card) { + super(card); + } + + @Override + public Jubilation copy() { + return new Jubilation(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JudgmentOfAlexander.java b/Mage.Sets/src/mage/cards/j/JudgmentOfAlexander.java new file mode 100644 index 00000000000..5dece809bf6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JudgmentOfAlexander.java @@ -0,0 +1,122 @@ +package mage.cards.j; + +import mage.abilities.Ability; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.PreventionEffectData; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.CommanderPredicate; +import mage.game.Game; +import mage.game.events.DamagePlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class JudgmentOfAlexander extends CardImpl { + + public JudgmentOfAlexander(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); + + // Prevent all damage that would be dealt to you this turn by sources your opponents control. Whenever damage from a creature is prevented this way, each commander creature you control deals damage equal to its power to that creature. + this.getSpellAbility().addEffect(new JudgmentOfAlexanderPreventionEffect()); + } + + private JudgmentOfAlexander(final JudgmentOfAlexander card) { + super(card); + } + + @Override + public JudgmentOfAlexander copy() { + return new JudgmentOfAlexander(this); + } +} + +class JudgmentOfAlexanderPreventionEffect extends PreventionEffectImpl { + + JudgmentOfAlexanderPreventionEffect() { + super(Duration.EndOfTurn, Integer.MAX_VALUE, false, false); + staticText = "prevent all damage that would be dealt to you this turn by sources your opponents control. " + + "Whenever damage from a creature is prevented this way, each commander creature you control " + + "deals damage equal to its power to that creature"; + } + + private JudgmentOfAlexanderPreventionEffect(final JudgmentOfAlexanderPreventionEffect effect) { + super(effect); + } + + @Override + public JudgmentOfAlexanderPreventionEffect copy() { + return new JudgmentOfAlexanderPreventionEffect(this); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return super.applies(event, source, game) + && event instanceof DamagePlayerEvent + && event.getAmount() >= 1 + && source.isControlledBy(event.getTargetId()) + && game.getOpponents(source.getControllerId()) + .contains(game.getControllerId(event.getSourceId())); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + PreventionEffectData data = preventDamageAction(event, source, game); + if (data.getPreventedDamage() <1) { + return false; + } + Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (permanent != null && permanent.isCreature(game)) { + game.fireReflexiveTriggeredAbility(new ReflexiveTriggeredAbility(new JudgmentOfAlexanderDamageEffect(permanent, game), false), source); + } + return false; + } +} + +class JudgmentOfAlexanderDamageEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(CommanderPredicate.instance); + } + + JudgmentOfAlexanderDamageEffect(Permanent permanent, Game game) { + super(Outcome.Benefit); + this.setTargetPointer(new FixedTarget(permanent, game)); + staticText = "each commander creature you control deals damage equal to its power to that creature"; + } + + private JudgmentOfAlexanderDamageEffect(final JudgmentOfAlexanderDamageEffect effect) { + super(effect); + } + + @Override + public JudgmentOfAlexanderDamageEffect copy() { + return new JudgmentOfAlexanderDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + for (Permanent commander : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)) { + permanent.damage(commander.getPower().getValue(), commander.getId(), source, game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/j/JuganDefendsTheTemple.java b/Mage.Sets/src/mage/cards/j/JuganDefendsTheTemple.java index 0ccc1720602..39115c686df 100644 --- a/Mage.Sets/src/mage/cards/j/JuganDefendsTheTemple.java +++ b/Mage.Sets/src/mage/cards/j/JuganDefendsTheTemple.java @@ -1,51 +1,104 @@ package mage.cards.j; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCost; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; 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.counters.CounterType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.ModifiedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; import mage.game.permanent.token.HumanMonkToken; +import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** * @author TheElk801 */ -public final class JuganDefendsTheTemple extends CardImpl { +public final class JuganDefendsTheTemple extends TransformingDoubleFacedCard { + + private static final FilterPermanent filterModified = new FilterControlledCreaturePermanent(); + + static { + filterModified.add(ModifiedPredicate.instance); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filterModified, ComparisonType.MORE_THAN, 4); + private static final Hint hint = new ValueHint("Modified creatures you control", new PermanentsOnBattlefieldCount(filterModified)); public JuganDefendsTheTemple(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{2}{G}", + "Remnant of the Rising Star", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.DRAGON, SubType.SPIRIT}, "G"); - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.r.RemnantOfTheRisingStar.class; + // Jugan Defends the Temple // (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 — Create a 1/1 green Human Monk creature token with "{T}: Add {G}." - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new CreateTokenEffect(new HumanMonkToken())); + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new CreateTokenEffect(new HumanMonkToken())); // II — Put a +1/+1 counter on each of up to two target creatures. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_II, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TargetPermanent(0, 2, StaticFilters.FILTER_PERMANENT_CREATURES) ); // 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.getLeftHalfCard().addAbility(sagaAbility); - this.addAbility(sagaAbility); + // Remnant of the Rising Star + this.getRightHalfCard().setPT(2, 2); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever another creature you control enters, you may pay {X}. When you do, put X +1/+1 counters on that creature. + this.getRightHalfCard().addAbility(new EntersBattlefieldControlledTriggeredAbility( + new RemnantOfTheRisingStarEffect(), StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE + )); + + // As long as you control five or more modified creatures, Remnant of the Rising Star gets +5/+5 and has trample. + Ability staticAbility = new SimpleStaticAbility(new ConditionalContinuousEffect( + new BoostSourceEffect(5, 5, Duration.WhileOnBattlefield), + condition, "as long as you control five or more modified creatures, {this} gets +5/+5" + )); + staticAbility.addEffect(new ConditionalContinuousEffect( + new GainAbilitySourceEffect(TrampleAbility.getInstance()), condition, "and has trample" + )); + this.getRightHalfCard().addAbility(staticAbility.addHint(hint)); } private JuganDefendsTheTemple(final JuganDefendsTheTemple card) { @@ -57,3 +110,45 @@ public final class JuganDefendsTheTemple extends CardImpl { return new JuganDefendsTheTemple(this); } } + +class RemnantOfTheRisingStarEffect extends OneShotEffect { + + RemnantOfTheRisingStarEffect() { + super(Outcome.Benefit); + staticText = "you may pay {X}. When you do, put X +1/+1 counters on that creature"; + } + + private RemnantOfTheRisingStarEffect(final RemnantOfTheRisingStarEffect effect) { + super(effect); + } + + @Override + public RemnantOfTheRisingStarEffect copy() { + return new RemnantOfTheRisingStarEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + ManaCosts cost = new ManaCostsImpl<>("{X}"); + if (player == null || !player.chooseUse( + Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game + )) { + return false; + } + int xValue = player.announceX(0, Integer.MAX_VALUE, "Announce the value for {X} (pay to add counters)", game, source, true); + cost.add(new GenericManaCost(xValue)); + if (!cost.pay(source, game, source, source.getControllerId(), false, null)) { + return false; + } + Permanent permanent = (Permanent) getValue("permanentEnteringBattlefield"); + if (permanent == null) { + return false; + } + game.fireReflexiveTriggeredAbility(new ReflexiveTriggeredAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance(xValue)) + .setTargetPointer(new FixedTarget(permanent, game)), false + ), source); + return true; + } +} 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/KaslemsStonetree.java b/Mage.Sets/src/mage/cards/k/KaslemsStonetree.java index 7826274a53c..1c3efd9f7cf 100644 --- a/Mage.Sets/src/mage/cards/k/KaslemsStonetree.java +++ b/Mage.Sets/src/mage/cards/k/KaslemsStonetree.java @@ -3,8 +3,8 @@ package mage.cards.k; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.PutCards; import mage.constants.SubType; @@ -15,23 +15,30 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class KaslemsStonetree extends CardImpl { +public final class KaslemsStonetree extends TransformingDoubleFacedCard { public KaslemsStonetree(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{G}"); - this.secondSideCardClazz = mage.cards.k.KaslemsStrider.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}{G}", + "Kaslem's Strider", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "G" + ); + // Kaslem's Stonetree // When Kaslem's Stonetree enters the battlefield, look at the top six cards of your library. You may put a land card from among them onto the battlefield tapped. Put the rest on the bottom in a random order. - this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect( 6, 1, StaticFilters.FILTER_CARD_LAND_A, PutCards.BATTLEFIELD_TAPPED, PutCards.BOTTOM_RANDOM ))); // Craft with Cave {5}{G} - this.addAbility(new CraftAbility( + this.getLeftHalfCard().addAbility(new CraftAbility( "{5}{G}", "Cave", "another Cave you " + "control or a Cave card in your graveyard", SubType.CAVE.getPredicate() )); + + // Kaslem's Strider + this.getRightHalfCard().setPT(5, 5); } private KaslemsStonetree(final KaslemsStonetree card) { diff --git a/Mage.Sets/src/mage/cards/k/KaslemsStrider.java b/Mage.Sets/src/mage/cards/k/KaslemsStrider.java deleted file mode 100644 index 2bc73f92442..00000000000 --- a/Mage.Sets/src/mage/cards/k/KaslemsStrider.java +++ /dev/null @@ -1,34 +0,0 @@ -package mage.cards.k; - -import mage.MageInt; -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 KaslemsStrider extends CardImpl { - - public KaslemsStrider(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(5); - this.nightCard = true; - this.color.setGreen(true); - } - - private KaslemsStrider(final KaslemsStrider card) { - super(card); - } - - @Override - public KaslemsStrider copy() { - return new KaslemsStrider(this); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java b/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java index d637cb6b178..c8e25cc4cf0 100644 --- a/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java +++ b/Mage.Sets/src/mage/cards/k/KataraWaterTribesHope.java @@ -5,8 +5,7 @@ import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.MyTurnCondition; -import mage.abilities.costs.common.WaterbendCost; -import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.costs.common.WaterbendXCost; import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.InfoEffect; @@ -20,7 +19,6 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.StaticFilters; import mage.game.permanent.token.AllyToken; -import mage.util.CardUtil; import java.util.UUID; @@ -49,9 +47,8 @@ public final class KataraWaterTribesHope extends CardImpl { Ability ability = new ActivateIfConditionActivatedAbility(new SetBasePowerToughnessAllEffect( GetXValue.instance, GetXValue.instance, Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURES - ), new WaterbendCost("{X}"), MyTurnCondition.instance); + ), new WaterbendXCost(1), MyTurnCondition.instance); ability.addEffect(new InfoEffect("X can't be 0")); - CardUtil.castStream(ability.getCosts(), VariableManaCost.class).forEach(cost -> cost.setMinX(1)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KatildaDawnhartMartyr.java b/Mage.Sets/src/mage/cards/k/KatildaDawnhartMartyr.java index 3a042a3aad7..b4d523c3ded 100644 --- a/Mage.Sets/src/mage/cards/k/KatildaDawnhartMartyr.java +++ b/Mage.Sets/src/mage/cards/k/KatildaDawnhartMartyr.java @@ -1,29 +1,31 @@ package mage.cards.k; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.DisturbAbility; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.ProtectionAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.*; 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.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class KatildaDawnhartMartyr extends CardImpl { +public final class KatildaDawnhartMartyr extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterPermanent(SubType.VAMPIRE, "Vampires"); @@ -41,31 +43,56 @@ public final class KatildaDawnhartMartyr extends CardImpl { private static final Hint hint = new ValueHint("Spirits and enchantments you control", xValue); public KatildaDawnhartMartyr(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.SPIRIT, SubType.WARLOCK}, "{1}{W}{W}", + "Katilda's Rising Dawn", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "W" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.WARLOCK); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.secondSideCardClazz = mage.cards.k.KatildasRisingDawn.class; + // Katilda, Dawnhart Martyr + this.getLeftHalfCard().setPT(0, 0); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Lifelink - this.addAbility(LifelinkAbility.getInstance()); + this.getLeftHalfCard().addAbility(LifelinkAbility.getInstance()); // Protection from Vampires - this.addAbility(new ProtectionAbility(filter)); + this.getLeftHalfCard().addAbility(new ProtectionAbility(filter)); // Katilda, Dawnhart Martyr's power and toughness are each equal to the number of permanents you control that are Spirits and/or enchantments. - this.addAbility(new SimpleStaticAbility( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility( Zone.ALL, new SetBasePowerToughnessSourceEffect(xValue) ).addHint(hint)); + // 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)); + // Disturb {3}{W}{W} - this.addAbility(new DisturbAbility(this, "{3}{W}{W}")); + // needs to be added after right half has spell ability target set + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{3}{W}{W}")); + + // Katilda's Rising Dawn + // Enchanted creature has flying, lifelink, and protection from Vampires, and it gets +X/+X where X is the number of permanents you control that are Spirits and/or enchantments. + Ability ability = new SimpleStaticAbility(new GainAbilityAttachedEffect( + FlyingAbility.getInstance(), AttachmentType.AURA + )); + ability.addEffect(new GainAbilityAttachedEffect( + LifelinkAbility.getInstance(), AttachmentType.AURA + ).setText(", lifelink")); + ability.addEffect(new GainAbilityAttachedEffect( + new ProtectionAbility(filter), AttachmentType.AURA + ).setText(", and protection from Vampires")); + ability.addEffect(new BoostEquippedEffect(xValue, xValue) + .setText(", and it gets +X/+X, where X is the number of permanents you control that are Spirits and/or enchantments")); + this.getRightHalfCard().addAbility(ability.addHint(hint)); + + // If Katilda's Rising Dawn would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private KatildaDawnhartMartyr(final KatildaDawnhartMartyr card) { diff --git a/Mage.Sets/src/mage/cards/k/KatildasRisingDawn.java b/Mage.Sets/src/mage/cards/k/KatildasRisingDawn.java deleted file mode 100644 index dc2907dacea..00000000000 --- a/Mage.Sets/src/mage/cards/k/KatildasRisingDawn.java +++ /dev/null @@ -1,84 +0,0 @@ -package mage.cards.k; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.continuous.BoostEquippedEffect; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.*; -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 mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class KatildasRisingDawn extends CardImpl { - - private static final FilterPermanent filter - = new FilterPermanent(SubType.VAMPIRE, "Vampires"); - private static final FilterPermanent filter2 - = new FilterControlledPermanent("permanents you control that are Spirits and/or enchantments"); - - static { - filter2.add(Predicates.or( - SubType.SPIRIT.getPredicate(), - CardType.ENCHANTMENT.getPredicate() - )); - } - - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter2); - private static final Hint hint = new ValueHint("Spirits and enchantments you control", xValue); - - public KatildasRisingDawn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.supertype.add(SuperType.LEGENDARY); - 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 flying, lifelink, and protection from Vampires, and it gets +X/+X where X is the number of permanents you control that are Spirits and/or enchantments. - Ability ability = new SimpleStaticAbility(new GainAbilityAttachedEffect( - FlyingAbility.getInstance(), AttachmentType.AURA - )); - ability.addEffect(new GainAbilityAttachedEffect( - LifelinkAbility.getInstance(), AttachmentType.AURA - ).setText(", lifelink")); - ability.addEffect(new GainAbilityAttachedEffect( - new ProtectionAbility(filter), AttachmentType.AURA - ).setText(", and protection from Vampires")); - ability.addEffect(new BoostEquippedEffect(xValue, xValue) - .setText(", and it gets +X/+X, where X is the number of permanents you control that are Spirits and/or enchantments")); - this.addAbility(ability.addHint(hint)); - - // If Katilda's Rising Dawn would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private KatildasRisingDawn(final KatildasRisingDawn card) { - super(card); - } - - @Override - public KatildasRisingDawn copy() { - return new KatildasRisingDawn(this); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KefkaCourtMage.java b/Mage.Sets/src/mage/cards/k/KefkaCourtMage.java index 041856fd2c3..7b08db32161 100644 --- a/Mage.Sets/src/mage/cards/k/KefkaCourtMage.java +++ b/Mage.Sets/src/mage/cards/k/KefkaCourtMage.java @@ -1,19 +1,19 @@ package mage.cards.k; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.common.LoseLifeTriggeredAbility; +import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.SavedLifeLossValue; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.SacrificeOpponentsEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.FlyingAbility; import mage.cards.*; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Controllable; import mage.game.Game; @@ -25,28 +25,38 @@ import java.util.*; /** * @author TheElk801 */ -public final class KefkaCourtMage extends CardImpl { +public final class KefkaCourtMage extends TransformingDoubleFacedCard { public KefkaCourtMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{2}{U}{B}{R}", + "Kefka, Ruler of Ruin", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.AVATAR, SubType.WIZARD}, "UBR"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.secondSideCardClazz = mage.cards.k.KefkaRulerOfRuin.class; + // Kefka, Court Mage + this.getLeftHalfCard().setPT(4, 5); // Whenever Kefka enters or attacks, each player discards a card. Then you draw a card for each card type among cards discarded this way. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new KefkaCourtMageEffect())); + this.getLeftHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new KefkaCourtMageEffect())); // {8}: Each opponent sacrifices a permanent of their choice. Transform Kefka. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility( new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT), new GenericManaCost(8) ); ability.addEffect(new TransformSourceEffect()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Kefka, Ruler of Ruin + this.getRightHalfCard().setPT(5, 7); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever an opponent loses life during your turn, you draw that many cards. + this.getRightHalfCard().addAbility(new LoseLifeTriggeredAbility( + new DrawCardSourceControllerEffect(SavedLifeLossValue.MANY, true), + TargetController.OPPONENT, false, false + ).withTriggerCondition(MyTurnCondition.instance)); } private KefkaCourtMage(final KefkaCourtMage card) { diff --git a/Mage.Sets/src/mage/cards/k/KefkaRulerOfRuin.java b/Mage.Sets/src/mage/cards/k/KefkaRulerOfRuin.java deleted file mode 100644 index aa642b63b2b..00000000000 --- a/Mage.Sets/src/mage/cards/k/KefkaRulerOfRuin.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.cards.k; - -import mage.MageInt; -import mage.abilities.common.LoseLifeTriggeredAbility; -import mage.abilities.condition.common.MyTurnCondition; -import mage.abilities.dynamicvalue.common.SavedLifeLossValue; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.TargetController; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class KefkaRulerOfRuin extends CardImpl { - - public KefkaRulerOfRuin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AVATAR); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(5); - this.toughness = new MageInt(7); - this.nightCard = true; - this.color.setBlue(true); - this.color.setBlack(true); - this.color.setRed(true); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever an opponent loses life during your turn, you draw that many cards. - this.addAbility(new LoseLifeTriggeredAbility( - new DrawCardSourceControllerEffect(SavedLifeLossValue.MANY, true), - TargetController.OPPONENT, false, false - ).withTriggerCondition(MyTurnCondition.instance)); - } - - private KefkaRulerOfRuin(final KefkaRulerOfRuin card) { - super(card); - } - - @Override - public KefkaRulerOfRuin copy() { - return new KefkaRulerOfRuin(this); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KessigForgemaster.java b/Mage.Sets/src/mage/cards/k/KessigForgemaster.java index 9ac344d5b16..1fbcff3d8d2 100644 --- a/Mage.Sets/src/mage/cards/k/KessigForgemaster.java +++ b/Mage.Sets/src/mage/cards/k/KessigForgemaster.java @@ -1,37 +1,48 @@ package mage.cards.k; -import mage.MageInt; import mage.abilities.common.BlocksOrBlockedByCreatureSourceTriggeredAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; -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.filter.StaticFilters; import java.util.UUID; /** * @author LevelX2 */ -public final class KessigForgemaster extends CardImpl { +public final class KessigForgemaster extends TransformingDoubleFacedCard { public KessigForgemaster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); - this.subtype.add(SubType.HUMAN, SubType.SHAMAN, SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SHAMAN, SubType.WEREWOLF}, "{1}{R}", + "Flameheart Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R"); - this.secondSideCardClazz = mage.cards.f.FlameheartWerewolf.class; + // Kessig Forgemaster + this.getLeftHalfCard().setPT(2, 1); // Whenever Kessig Forgemaster blocks or becomes blocked by a creature, Kessig Forgemaster deals 1 damage to that creature. - this.addAbility(new BlocksOrBlockedByCreatureSourceTriggeredAbility(new DamageTargetEffect(1).withTargetDescription("that creature"))); + this.getLeftHalfCard().addAbility(new BlocksOrBlockedByCreatureSourceTriggeredAbility( + new DamageTargetEffect(1).withTargetDescription("that creature") + )); // At the beginning of each upkeep, if no spells were cast last turn, transform Kessig Forgemaster. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Flameheart Werewolf + this.getRightHalfCard().setPT(3, 2); + + // Whenever Flameheart Werewolf blocks or becomes blocked by a creature, Flameheart Werewolf deals 2 damage to that creature. + this.getRightHalfCard().addAbility(new BlocksOrBlockedByCreatureSourceTriggeredAbility( + new DamageTargetEffect(2).withTargetDescription("that creature") + )); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Flameheart Werewolf. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private KessigForgemaster(final KessigForgemaster card) { diff --git a/Mage.Sets/src/mage/cards/k/KessigNaturalist.java b/Mage.Sets/src/mage/cards/k/KessigNaturalist.java index 9fef85ab25d..6715ed7b487 100644 --- a/Mage.Sets/src/mage/cards/k/KessigNaturalist.java +++ b/Mage.Sets/src/mage/cards/k/KessigNaturalist.java @@ -1,16 +1,21 @@ package mage.cards.k; -import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; 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.Outcome; import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; import mage.game.Game; import mage.players.Player; @@ -19,23 +24,45 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class KessigNaturalist extends CardImpl { +public final class KessigNaturalist extends TransformingDoubleFacedCard { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Wolves and Werewolves"); + + static { + filter.add(Predicates.or( + SubType.WOLF.getPredicate(), + SubType.WEREWOLF.getPredicate() + )); + } public KessigNaturalist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{R}{G}", + "Lord of the Ulvenwald", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "RG"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - this.secondSideCardClazz = mage.cards.l.LordOfTheUlvenwald.class; + // Kessig Naturalist + this.getLeftHalfCard().setPT(2, 2); // Whenever Kessig Naturalist attacks, add {R} or {G}. Until end of turn, you don't lose this mana as steps and phases end. - this.addAbility(new AttacksTriggeredAbility(new KessigNaturalistEffect())); + this.getLeftHalfCard().addAbility(new AttacksTriggeredAbility(new KessigNaturalistEffect())); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Lord of the Ulvenwald + this.getRightHalfCard().setPT(3, 3); + + // Other Wolves and Werewolves you control get +1/+1. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect( + 1, 1, Duration.WhileOnBattlefield, filter, true + ))); + + // Whenever Lord of the Ulvenwald attacks, add {R} or {G}. Until end of turn, you don't lose this mana as steps and phases end. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new KessigNaturalistEffect())); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private KessigNaturalist(final KessigNaturalist card) { diff --git a/Mage.Sets/src/mage/cards/k/KessigProwler.java b/Mage.Sets/src/mage/cards/k/KessigProwler.java index 0a0ddad939d..c04224886ec 100644 --- a/Mage.Sets/src/mage/cards/k/KessigProwler.java +++ b/Mage.Sets/src/mage/cards/k/KessigProwler.java @@ -1,36 +1,39 @@ - package mage.cards.k; -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.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneSourceEffect; 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 KessigProwler extends CardImpl { +public final class KessigProwler extends TransformingDoubleFacedCard { public KessigProwler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); - this.subtype.add(SubType.WEREWOLF); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(2); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF, SubType.HORROR}, "{G}", + "Sinuous Predator", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.WEREWOLF}, ""); - this.secondSideCardClazz = mage.cards.s.SinuousPredator.class; + // Kessig Prowler + this.getLeftHalfCard().setPT(2, 1); // {4}{G}: Transform Kessig Prowler. - this.addAbility(new TransformAbility()); - this.addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{G}"))); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{4}{G}"))); + + // Sinuous Predator + this.getRightHalfCard().setPT(4, 4); + + // Sinuous Predator can't be blocked by more than one creature. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneSourceEffect())); } private KessigProwler(final KessigProwler card) { diff --git a/Mage.Sets/src/mage/cards/k/KhenraSpellspear.java b/Mage.Sets/src/mage/cards/k/KhenraSpellspear.java index c7f6e66c63d..3edbc3a41f4 100644 --- a/Mage.Sets/src/mage/cards/k/KhenraSpellspear.java +++ b/Mage.Sets/src/mage/cards/k/KhenraSpellspear.java @@ -1,14 +1,13 @@ package mage.cards.k; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.ProwessAbility; import mage.abilities.keyword.TrampleAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.WardAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -17,26 +16,38 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class KhenraSpellspear extends CardImpl { +public final class KhenraSpellspear extends TransformingDoubleFacedCard { public KhenraSpellspear(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.JACKAL, SubType.WARRIOR}, "{1}{R}", + "Gitaxian Spellstalker", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.JACKAL}, "UR"); - this.subtype.add(SubType.JACKAL); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.g.GitaxianSpellstalker.class; + // Khenra Spellspear + this.getLeftHalfCard().setPT(2, 2); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // Prowess - this.addAbility(new ProwessAbility()); + this.getLeftHalfCard().addAbility(new ProwessAbility()); // {3}{U/P}: Transform Khenra Spellspear. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{U/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{U/P}"))); + + // Gitaxian Spellstalker + this.getRightHalfCard().setPT(3, 3); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Ward {2} + this.getRightHalfCard().addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); + + // Prowess, Prowess + this.getRightHalfCard().addAbility(new ProwessAbility()); + this.getRightHalfCard().addAbility(new ProwessAbility()); } private KhenraSpellspear(final KhenraSpellspear card) { diff --git a/Mage.Sets/src/mage/cards/k/KindlyAncestor.java b/Mage.Sets/src/mage/cards/k/KindlyAncestor.java index a9b64514a7a..d1f923b021b 100644 --- a/Mage.Sets/src/mage/cards/k/KindlyAncestor.java +++ b/Mage.Sets/src/mage/cards/k/KindlyAncestor.java @@ -1,34 +1,54 @@ package mage.cards.k; -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.EnchantAbility; import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class KindlyAncestor extends CardImpl { +public final class KindlyAncestor extends TransformingDoubleFacedCard { public KindlyAncestor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "{2}{W}", + "Ancestor's Embrace", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "W"); - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.a.AncestorsEmbrace.class; + // Kindly Ancestor + this.getLeftHalfCard().setPT(2, 3); // Lifelink - this.addAbility(LifelinkAbility.getInstance()); + this.getLeftHalfCard().addAbility(LifelinkAbility.getInstance()); + + // Ancestor's Embrace + // 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)); // Disturb {1}{W} - this.addAbility(new DisturbAbility(this, "{1}{W}")); + // needs to be added after right half has spell ability target set + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{1}{W}")); + + // Enchanted creature has lifelink. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + LifelinkAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield + ))); + + // If Ancestor's Embrace would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private KindlyAncestor(final KindlyAncestor card) { diff --git a/Mage.Sets/src/mage/cards/k/KindlyStranger.java b/Mage.Sets/src/mage/cards/k/KindlyStranger.java index 8a07ada2da8..cf934f64ecf 100644 --- a/Mage.Sets/src/mage/cards/k/KindlyStranger.java +++ b/Mage.Sets/src/mage/cards/k/KindlyStranger.java @@ -1,38 +1,48 @@ package mage.cards.k; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.condition.common.DeliriumCondition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; +import mage.abilities.effects.common.DestroyTargetEffect; 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.AbilityWord; import mage.constants.CardType; import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author fireshoes */ -public final class KindlyStranger extends CardImpl { +public final class KindlyStranger extends TransformingDoubleFacedCard { public KindlyStranger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); - this.subtype.add(SubType.HUMAN); - this.power = new MageInt(2); - this.toughness = new MageInt(3); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN}, "{2}{B}", + "Demon-Possessed Witch", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SHAMAN}, "B"); - this.secondSideCardClazz = mage.cards.d.DemonPossessedWitch.class; + // Kindly Stranger + this.getLeftHalfCard().setPT(2, 3); - // Delirium — {2}{B}: Transform Kindly Stranger. Activate this ability only if there are four or more card types among cards in your graveyard. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateIfConditionActivatedAbility( + // Delirium — {2}{B}: Transform Kindly Stranger. Activate only if there are four or more card types among cards in your graveyard. + this.getLeftHalfCard().addAbility(new ActivateIfConditionActivatedAbility( new TransformSourceEffect(), new ManaCostsImpl<>("{2}{B}"), DeliriumCondition.instance ).setAbilityWord(AbilityWord.DELIRIUM).addHint(CardTypesInGraveyardCount.YOU.getHint())); + + // Demon-Possessed Witch + this.getRightHalfCard().setPT(4, 3); + + // When this creature transforms into Demon-Possessed Witch, you may destroy target creature. + Ability ability = new TransformIntoSourceTriggeredAbility(new DestroyTargetEffect(), true); + ability.addTarget(new TargetCreaturePermanent()); + this.getRightHalfCard().addAbility(ability); } private KindlyStranger(final KindlyStranger card) { diff --git a/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java b/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java new file mode 100644 index 00000000000..5398c187847 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KinsbaileAspirant.java @@ -0,0 +1,52 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.costs.OrCost; +import mage.abilities.costs.common.BeholdCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +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 KinsbaileAspirant extends CardImpl { + + public KinsbaileAspirant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.CITIZEN); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // As an additional cost to cast this spell, behold a Kithkin or pay {2}. + this.getSpellAbility().addCost(new OrCost( + "behold a Kithkin or pay {2}", new BeholdCost(BeholdType.KITHKIN), new GenericManaCost(2) + )); + + // Whenever another creature you control enters, this creature gets +1/+1 until end of turn. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + new BoostSourceEffect(1, 1, Duration.EndOfTurn), + StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL + )); + } + + private KinsbaileAspirant(final KinsbaileAspirant card) { + super(card); + } + + @Override + public KinsbaileAspirant copy() { + return new KinsbaileAspirant(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/Kithkeeper.java b/Mage.Sets/src/mage/cards/k/Kithkeeper.java new file mode 100644 index 00000000000..3e6115efbd8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/Kithkeeper.java @@ -0,0 +1,61 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.game.permanent.token.KithkinGreenWhiteToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Kithkeeper extends CardImpl { + + public Kithkeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{W}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Vivid -- When this creature enters, create X 1/1 green and white Kithkin creature tokens, where X is the number of colors among permanents you control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect( + new KithkinGreenWhiteToken(), ColorsAmongControlledPermanentsCount.ALL_PERMANENTS + )).setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + + // Tap three untapped creatures you control: This creature gets +3/+0 and gains flying until end of turn. + Ability ability = new SimpleActivatedAbility( + new BoostSourceEffect(3, 0, Duration.EndOfTurn) + .setText("{this} gets +3/+0"), + new TapTargetCost(3, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES) + ); + ability.addEffect(new GainAbilitySourceEffect( + FlyingAbility.getInstance(), Duration.EndOfTurn + ).setText("and gains flying until end of turn")); + this.addAbility(ability); + } + + private Kithkeeper(final Kithkeeper card) { + super(card); + } + + @Override + public Kithkeeper copy() { + return new Kithkeeper(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/k/KrallenhordeWantons.java b/Mage.Sets/src/mage/cards/k/KrallenhordeWantons.java deleted file mode 100644 index dc8e2624601..00000000000 --- a/Mage.Sets/src/mage/cards/k/KrallenhordeWantons.java +++ /dev/null @@ -1,40 +0,0 @@ -package mage.cards.k; - -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 KrallenhordeWantons extends CardImpl { - - public KrallenhordeWantons(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(7); - this.toughness = new MageInt(7); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Krallenhorde Wantons. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private KrallenhordeWantons(final KrallenhordeWantons card) { - super(card); - } - - @Override - public KrallenhordeWantons copy() { - return new KrallenhordeWantons(this); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KrothussLordOfTheDeep.java b/Mage.Sets/src/mage/cards/k/KrothussLordOfTheDeep.java deleted file mode 100644 index d58282aa09e..00000000000 --- a/Mage.Sets/src/mage/cards/k/KrothussLordOfTheDeep.java +++ /dev/null @@ -1,98 +0,0 @@ -package mage.cards.k; - -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.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.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterAttackingCreature; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class KrothussLordOfTheDeep extends CardImpl { - - private static final FilterPermanent filter = new FilterAttackingCreature("another attacking creature"); - - static { - filter.add(AnotherPredicate.instance); - } - - public KrothussLordOfTheDeep(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.KRAKEN); - this.subtype.add(SubType.HORROR); - this.power = new MageInt(3); - this.toughness = new MageInt(5); - this.color.setBlue(true); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever Krothuss, Lord of the Deep attacks, create a tapped and attacking token that's a copy of another target attacking creature. If that creature is a Kraken, Leviathan, Octopus, or Serpent, create two of those tokens instead. - Ability ability = new AttacksTriggeredAbility(new KrothussLordOfTheDeepEffect()); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - } - - private KrothussLordOfTheDeep(final KrothussLordOfTheDeep card) { - super(card); - } - - @Override - public KrothussLordOfTheDeep copy() { - return new KrothussLordOfTheDeep(this); - } -} - -class KrothussLordOfTheDeepEffect extends OneShotEffect { - - KrothussLordOfTheDeepEffect() { - super(Outcome.Benefit); - staticText = "create a tapped and attacking token that's a copy of another target attacking creature. " + - "If that creature is a Kraken, Leviathan, Octopus, or Serpent, create two of those tokens instead"; - } - - private KrothussLordOfTheDeepEffect(final KrothussLordOfTheDeepEffect effect) { - super(effect); - } - - @Override - public KrothussLordOfTheDeepEffect copy() { - return new KrothussLordOfTheDeepEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent == null) { - return false; - } - int count = permanent.hasSubtype(SubType.KRAKEN, game) - || permanent.hasSubtype(SubType.LEVIATHAN, game) - || permanent.hasSubtype(SubType.OCTOPUS, game) - || permanent.hasSubtype(SubType.SERPENT, game) ? 2 : 1; - return new CreateTokenCopyTargetEffect( - null, null, - false, count, true, true - ).apply(game, source); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KruinOutlaw.java b/Mage.Sets/src/mage/cards/k/KruinOutlaw.java index 71b48621976..73705a0f0b0 100644 --- a/Mage.Sets/src/mage/cards/k/KruinOutlaw.java +++ b/Mage.Sets/src/mage/cards/k/KruinOutlaw.java @@ -1,36 +1,56 @@ package mage.cards.k; -import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility; -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.Duration; import mage.constants.SubType; +import mage.filter.FilterPermanent; import java.util.UUID; /** * @author North */ -public final class KruinOutlaw extends CardImpl { +public final class KruinOutlaw extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterPermanent(SubType.WEREWOLF, "Werewolves"); public KruinOutlaw(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ROGUE); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ROGUE, SubType.WEREWOLF}, "{1}{R}{R}", + "Terror of Kruin Pass", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R"); - this.secondSideCardClazz = mage.cards.t.TerrorOfKruinPass.class; + // Kruin Outlaw + this.getLeftHalfCard().setPT(2, 2); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + // First strike + this.getLeftHalfCard().addAbility(FirstStrikeAbility.getInstance()); - this.addAbility(FirstStrikeAbility.getInstance()); // At the beginning of each upkeep, if no spells were cast last turn, transform Kruin Outlaw. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Terror of Kruin Pass + this.getRightHalfCard().setPT(3, 3); + + // Double strike + this.getRightHalfCard().addAbility(DoubleStrikeAbility.getInstance()); + + // Werewolves you control have menace. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + new MenaceAbility(), Duration.WhileOnBattlefield, filter, false + ))); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Terror of Kruin Pass. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private KruinOutlaw(final KruinOutlaw card) { diff --git a/Mage.Sets/src/mage/cards/k/KujaGenomeSorcerer.java b/Mage.Sets/src/mage/cards/k/KujaGenomeSorcerer.java index 6784c390e47..6abd2425003 100644 --- a/Mage.Sets/src/mage/cards/k/KujaGenomeSorcerer.java +++ b/Mage.Sets/src/mage/cards/k/KujaGenomeSorcerer.java @@ -1,48 +1,46 @@ package mage.cards.k; -import java.util.UUID; -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.decorator.ConditionalOneShotEffect; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.constants.ComparisonType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.token.BlackWizardToken; +import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; /** * @author balazskristof */ -public final class KujaGenomeSorcerer extends CardImpl { +public final class KujaGenomeSorcerer extends TransformingDoubleFacedCard { private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.WIZARD); private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.OR_GREATER, 4); private static final Hint hint = new ValueHint("Wizards you control", new PermanentsOnBattlefieldCount(filter)); public KujaGenomeSorcerer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}"); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.MUTANT); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(4); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.MUTANT, SubType.WIZARD}, "{2}{B}{R}", + "Trance Kuja, Fate Defied", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.AVATAR, SubType.WIZARD}, "BR"); - this.secondSideCardClazz = mage.cards.t.TranceKujaFateDefied.class; + // Kuja, Genome Sorcerer + this.getLeftHalfCard().setPT(3, 4); // At the beginning of your end step, create a tapped 0/1 black Wizard creature token with "Whenever you cast a noncreature spell, this token deals 1 damage to each opponent.", Then if you control four or more Wizards, transform Kuja. Ability ability = new BeginningOfEndStepTriggeredAbility( @@ -54,8 +52,13 @@ public final class KujaGenomeSorcerer extends CardImpl { "if you control four or more Wizards, transform {this}" ).concatBy("Then")); ability.addHint(hint); - this.addAbility(ability); - this.addAbility(new TransformAbility()); + this.getLeftHalfCard().addAbility(ability); + + // Trance Kuja, Fate Defied + this.getRightHalfCard().setPT(4, 6); + + // Flame Star -- If a Wizard you control would deal damage to a permanent or player, it deals double that damage instead. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new TranceKujaFateDefiedEffect()).withFlavorWord("Flare Star")); } private KujaGenomeSorcerer(final KujaGenomeSorcerer card) { @@ -67,3 +70,40 @@ public final class KujaGenomeSorcerer extends CardImpl { return new KujaGenomeSorcerer(this); } } + +class TranceKujaFateDefiedEffect extends ReplacementEffectImpl { + + TranceKujaFateDefiedEffect() { + super(Duration.WhileOnBattlefield, Outcome.Damage); + staticText = "If a Wizard you control would deal damage to a permanent or player, it deals double that damage instead."; + } + + private TranceKujaFateDefiedEffect(final TranceKujaFateDefiedEffect effect) { + super(effect); + } + + @Override + public TranceKujaFateDefiedEffect copy() { + return new TranceKujaFateDefiedEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER) + || event.getType().equals(GameEvent.EventType.DAMAGE_PERMANENT); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return game.getControllerId(event.getSourceId()).equals(source.getControllerId()) + && Optional.ofNullable(game.getObject(event.getSourceId())) + .map(object -> object.hasSubtype(SubType.WIZARD, game)) + .orElse(false); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + event.setAmount(CardUtil.overflowMultiply(event.getAmount(), 2)); + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/k/KulrathMystic.java b/Mage.Sets/src/mage/cards/k/KulrathMystic.java new file mode 100644 index 00000000000..0df37c2d071 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KulrathMystic.java @@ -0,0 +1,48 @@ +package mage.cards.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author muz + */ +public final class KulrathMystic extends CardImpl { + + public KulrathMystic(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Whenever you cast a spell with mana value 4 or greater, this creature gets +2/+0 and gains vigilance until end of turn. + Ability ability = new SpellCastControllerTriggeredAbility( + new BoostSourceEffect(2, 0, Duration.EndOfTurn).setText("this creature gets +2/+0"), + StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false + ); + ability.addEffect(new GainAbilitySourceEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn).setText("and gains vigilance until end of turn")); + this.addAbility(ability); + } + + private KulrathMystic(final KulrathMystic card) { + super(card); + } + + @Override + public KulrathMystic copy() { + return new KulrathMystic(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KulrathZealot.java b/Mage.Sets/src/mage/cards/k/KulrathZealot.java new file mode 100644 index 00000000000..c07763aea8a --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KulrathZealot.java @@ -0,0 +1,44 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; +import mage.abilities.keyword.BasicLandcyclingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KulrathZealot extends CardImpl { + + public KulrathZealot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(6); + this.toughness = new MageInt(5); + + // When this creature enters, exile the top card of your library. Until the end of your next turn, you may play that card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ExileTopXMayPlayUntilEffect(1, Duration.UntilEndOfYourNextTurn))); + + // Basic landcycling {1}{R} + this.addAbility(new BasicLandcyclingAbility(new ManaCostsImpl<>("{1}{R}"))); + } + + private KulrathZealot(final KulrathZealot card) { + super(card); + } + + @Override + public KulrathZealot copy() { + return new KulrathZealot(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java b/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java index b5008af8aa6..3bb5fe4b68f 100644 --- a/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java +++ b/Mage.Sets/src/mage/cards/k/KumanoFacesKakkazan.java @@ -1,27 +1,31 @@ package mage.cards.k; +import mage.abilities.Ability; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.AddCounterNextSpellDelayedTriggeredAbility; +import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DamageAllEffect; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +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.common.FilterPlaneswalkerPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.watchers.common.DamagedByControlledWatcher; import java.util.UUID; /** * @author weirddan455 */ -public final class KumanoFacesKakkazan extends CardImpl { +public final class KumanoFacesKakkazan extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterPlaneswalkerPermanent(); @@ -30,31 +34,42 @@ public final class KumanoFacesKakkazan extends CardImpl { } public KumanoFacesKakkazan(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.e.EtchingOfKumano.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{R}", + "Etching of Kumano", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SHAMAN}, "R"); + // Kumano Faces Kakkazan // (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 — Kumano Faces Kakkazan deals 1 damage to each opponent and each planeswalker they control. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, + sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_I, new DamagePlayersEffect(1, TargetController.OPPONENT), new DamageAllEffect(1, filter).setText("and each planeswalker they control") ); // II — When you cast your next creature spell this turn, that creature enters the battlefield with an additional +1/+1 counter on it. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_II, new CreateDelayedTriggeredAbilityEffect(new AddCounterNextSpellDelayedTriggeredAbility()) ); // 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); + + // Etching of Kumano + this.getRightHalfCard().setPT(2, 2); + + // Haste + this.getRightHalfCard().addAbility(HasteAbility.getInstance()); + + // If a creature dealt damage this turn by a source you controlled would die, exile it instead. + Ability ability = new SimpleStaticAbility(new EtchingOfKumanoReplacementEffect()); + ability.addWatcher(new DamagedByControlledWatcher()); + this.getRightHalfCard().addAbility(ability); } private KumanoFacesKakkazan(final KumanoFacesKakkazan card) { @@ -66,3 +81,43 @@ public final class KumanoFacesKakkazan extends CardImpl { return new KumanoFacesKakkazan(this); } } + +class EtchingOfKumanoReplacementEffect extends ReplacementEffectImpl { + + EtchingOfKumanoReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Exile); + this.staticText = "If a creature dealt damage this turn by a source you controlled would die, exile it instead"; + } + + private EtchingOfKumanoReplacementEffect(final EtchingOfKumanoReplacementEffect effect) { + super(effect); + } + + @Override + public EtchingOfKumanoReplacementEffect copy() { + return new EtchingOfKumanoReplacementEffect(this); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ((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) { + ZoneChangeEvent zce = (ZoneChangeEvent) event; + if (zce.isDiesEvent()) { + DamagedByControlledWatcher watcher = game.getState().getWatcher(DamagedByControlledWatcher.class, source.getControllerId()); + if (watcher != null) { + return watcher.wasDamaged(zce.getTarget(), game); + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/k/KyrenFlamewright.java b/Mage.Sets/src/mage/cards/k/KyrenFlamewright.java deleted file mode 100644 index a0e95b8626e..00000000000 --- a/Mage.Sets/src/mage/cards/k/KyrenFlamewright.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.k; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.DiscardCardCost; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -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.StaticFilters; -import mage.game.permanent.token.Elemental11BlueRedToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class KyrenFlamewright extends CardImpl { - - public KyrenFlamewright(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.GOBLIN); - this.subtype.add(SubType.SPELLSHAPER); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setRed(true); - this.nightCard = true; - - // {2}{R}, {T}, Discard a card: Create two 1/1 blue and red Elemental creature tokens. Creatures you control get +1/+0 and gain haste until end of turn. - Ability ability = new SimpleActivatedAbility( - new CreateTokenEffect(new Elemental11BlueRedToken(), 2), new ManaCostsImpl<>("{2}{R}") - ); - ability.addCost(new TapSourceCost()); - ability.addCost(new DiscardCardCost()); - ability.addEffect(new BoostControlledEffect(1, 0, Duration.EndOfTurn) - .setText("creatures you control get +1/+0")); - ability.addEffect(new GainAbilityControlledEffect( - HasteAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES - ).setText("and gain haste until end of turn")); - this.addAbility(ability); - } - - private KyrenFlamewright(final KyrenFlamewright card) { - super(card); - } - - @Override - public KyrenFlamewright copy() { - return new KyrenFlamewright(this); - } -} diff --git a/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java b/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java index 56c4872994e..44418fa3597 100644 --- a/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java +++ b/Mage.Sets/src/mage/cards/k/KytheonHeroOfAkros.java @@ -1,19 +1,27 @@ package mage.cards.k; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.EndOfCombatTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.PreventAllDamageToSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.IndestructibleAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.custom.CreatureToken; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; import mage.watchers.common.AttackedOrBlockedThisCombatWatcher; import java.util.UUID; @@ -21,30 +29,53 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class KytheonHeroOfAkros extends CardImpl { +public final class KytheonHeroOfAkros extends TransformingDoubleFacedCard { public KytheonHeroOfAkros(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(2); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SOLDIER}, "{W}", + "Gideon, Battle-Forged", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.GIDEON}, "W"); - this.secondSideCardClazz = mage.cards.g.GideonBattleForged.class; + // Kytheon, Hero of Akros + this.getLeftHalfCard().setPT(2, 1); - // At end of combat, if Kytheon, Hero of Akros and at least two other creatures attacked this combat, exile Kytheon, - // then return him to the battlefield transformed under his owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new EndOfCombatTriggeredAbility( + // At end of combat, if Kytheon, Hero of Akros and at least two other creatures attacked this combat, exile Kytheon, then return him to the battlefield transformed under his owner's control. + Ability kytheonAbility = new EndOfCombatTriggeredAbility( new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.HE), false - ).withInterveningIf(KytheonHeroOfAkrosCondition.instance), new AttackedOrBlockedThisCombatWatcher()); + ).withInterveningIf(KytheonHeroOfAkrosCondition.instance); + kytheonAbility.addWatcher(new AttackedOrBlockedThisCombatWatcher()); + this.getLeftHalfCard().addAbility(kytheonAbility); // {2}{W}: Kytheon gains indestructible until end of turn. - this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect( + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn ), new ManaCostsImpl<>("{2}{W}"))); + // Gideon, Battle-Forged + this.getRightHalfCard().setStartingLoyalty(3); + + // +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able. + Ability ability = new LoyaltyAbility(new GideonBattleForgedEffect(), 2); + ability.addTarget(new TargetOpponentsCreaturePermanent(0, 1)); + this.getRightHalfCard().addAbility(ability); + + // +1: Until your next turn, target creature gains indestructible. Untap that creature. + ability = new LoyaltyAbility(new GainAbilityTargetEffect( + IndestructibleAbility.getInstance(), Duration.UntilYourNextTurn + ).setText("Until your next turn, target creature gains indestructible"), 1); + ability.addEffect(new UntapTargetEffect().setText("Untap that creature")); + ability.addTarget(new TargetCreaturePermanent()); + this.getRightHalfCard().addAbility(ability); + + // 0: Until end of turn, Gideon, Battle-Forged becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn. + ability = new LoyaltyAbility(new BecomesCreatureSourceEffect(new CreatureToken( + 4, 4, "4/4 Human Soldier creature " + + "with indestructible", SubType.HUMAN, SubType.SOLDIER + ).withAbility(IndestructibleAbility.getInstance()), CardType.PLANESWALKER, Duration.EndOfTurn), 0); + ability.addEffect(new PreventAllDamageToSourceEffect(Duration.EndOfTurn) + .setText("Prevent all damage that would be dealt to him this turn")); + this.getRightHalfCard().addAbility(ability); } private KytheonHeroOfAkros(final KytheonHeroOfAkros card) { @@ -78,3 +109,74 @@ enum KytheonHeroOfAkrosCondition implements Condition { return "if {this} and at least two other creatures attacked this combat"; } } + +class GideonBattleForgedEffect extends RequirementEffect { + + protected mage.MageObjectReference targetPermanentReference; + + GideonBattleForgedEffect() { + super(Duration.Custom); + staticText = "up to one target creature an opponent controls attacks {this} during its controller's next turn if able"; + } + + private GideonBattleForgedEffect(final GideonBattleForgedEffect effect) { + super(effect); + this.targetPermanentReference = effect.targetPermanentReference; + } + + @Override + public GideonBattleForgedEffect copy() { + return new GideonBattleForgedEffect(this); + } + + @Override + public boolean isInactive(Ability source, Game game) { + if (targetPermanentReference == null) { + return true; + } + Permanent targetPermanent = targetPermanentReference.getPermanent(game); + if (targetPermanent == null) { + return true; + } + return game.getTurnPhaseType() == TurnPhase.END && this.isYourNextTurn(game); // discard on end of their next turn + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + if (getTargetPointer().getFirst(game, source) == null) { + discard(); + } else { + targetPermanentReference = new mage.MageObjectReference(getTargetPointer().getFirst(game, source), game); + } + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + if (!permanent.getId().equals(getTargetPointer().getFirst(game, source)) + || !game.isActivePlayer(permanent.getControllerId())) { + return false; + } + Permanent planeswalker = source.getSourcePermanentIfItStillExists(game); + if (planeswalker == null) { + discard(); + return false; + } + return true; + } + + @Override + public UUID mustAttackDefender(Ability source, Game game) { + return source.getSourceId(); + } + + @Override + public boolean mustAttack(Game game) { + return true; + } + + @Override + public boolean mustBlock(Game game) { + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/l/LambholtElder.java b/Mage.Sets/src/mage/cards/l/LambholtElder.java index 9706367e69e..205a4edfa76 100644 --- a/Mage.Sets/src/mage/cards/l/LambholtElder.java +++ b/Mage.Sets/src/mage/cards/l/LambholtElder.java @@ -1,10 +1,11 @@ package mage.cards.l; -import mage.MageInt; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -13,21 +14,31 @@ import java.util.UUID; /** * @author Loki */ -public final class LambholtElder extends CardImpl { +public final class LambholtElder extends TransformingDoubleFacedCard { public LambholtElder(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}", + "Silverpelt Werewolf", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.power = new MageInt(1); - this.toughness = new MageInt(2); - - this.secondSideCardClazz = mage.cards.s.SilverpeltWerewolf.class; + // Lambholt Elder + this.getLeftHalfCard().setPT(1, 2); // At the beginning of each upkeep, if no spells were cast last turn, transform Lambholt Elder. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Silverpelt Werewolf + this.getRightHalfCard().setPT(4, 5); + + // Whenever Silverpelt Werewolf deals combat damage to a player, draw a card. + this.getRightHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + new DrawCardSourceControllerEffect(1), false + )); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Silverpelt Werewolf. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private LambholtElder(final LambholtElder card) { diff --git a/Mage.Sets/src/mage/cards/l/LambholtRaconteur.java b/Mage.Sets/src/mage/cards/l/LambholtRaconteur.java index 8c0b060799b..fa26a1a5e3b 100644 --- a/Mage.Sets/src/mage/cards/l/LambholtRaconteur.java +++ b/Mage.Sets/src/mage/cards/l/LambholtRaconteur.java @@ -1,11 +1,11 @@ package mage.cards.l; -import mage.MageInt; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.common.DamagePlayersEffect; 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.TargetController; @@ -16,25 +16,38 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class LambholtRaconteur extends CardImpl { +public final class LambholtRaconteur extends TransformingDoubleFacedCard { public LambholtRaconteur(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}", + "Lambholt Ravager", + 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(4); - this.secondSideCardClazz = mage.cards.l.LambholtRavager.class; + // Lambholt Raconteur + this.getLeftHalfCard().setPT(2, 4); // Whenever you cast a noncreature spell, Lambholt Raconteur deals 1 damage to each opponent. - this.addAbility(new SpellCastControllerTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( new DamagePlayersEffect(1, TargetController.OPPONENT), StaticFilters.FILTER_SPELL_A_NON_CREATURE, false )); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Lambholt Ravager + this.getRightHalfCard().setPT(4, 4); + + // Whenever you cast a noncreature spell, Lambholt Ravager deals 2 damage to each opponent. + this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility( + new DamagePlayersEffect(2, TargetController.OPPONENT), + StaticFilters.FILTER_SPELL_A_NON_CREATURE, false + )); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private LambholtRaconteur(final LambholtRaconteur card) { diff --git a/Mage.Sets/src/mage/cards/l/LambholtRavager.java b/Mage.Sets/src/mage/cards/l/LambholtRavager.java deleted file mode 100644 index 36eabbf2986..00000000000 --- a/Mage.Sets/src/mage/cards/l/LambholtRavager.java +++ /dev/null @@ -1,48 +0,0 @@ -package mage.cards.l; - -import mage.MageInt; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LambholtRavager extends CardImpl { - - public LambholtRavager(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.setRed(true); - this.nightCard = true; - - // Whenever you cast a noncreature spell, Lambholt Ravager deals 2 damage to each opponent. - this.addAbility(new SpellCastControllerTriggeredAbility( - new DamagePlayersEffect(2, TargetController.OPPONENT), - StaticFilters.FILTER_SPELL_A_NON_CREATURE, false - )); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private LambholtRavager(final LambholtRavager card) { - super(card); - } - - @Override - public LambholtRavager copy() { - return new LambholtRavager(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/Lamentation.java b/Mage.Sets/src/mage/cards/l/Lamentation.java new file mode 100644 index 00000000000..f343f91e6e8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/Lamentation.java @@ -0,0 +1,49 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.EncoreAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Lamentation extends CardImpl { + + public Lamentation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // When this creature enters, destroy target creature an opponent controls. You gain 3 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); + ability.addEffect(new GainLifeEffect(3)); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.addAbility(ability); + + // Encore {6}{B}{B} + this.addAbility(new EncoreAbility(new ManaCostsImpl<>("{6}{B}{B}"))); + } + + private Lamentation(final Lamentation card) { + super(card); + } + + @Override + public Lamentation copy() { + return new Lamentation(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LanternBearer.java b/Mage.Sets/src/mage/cards/l/LanternBearer.java index 4f44b1d854d..632d677f587 100644 --- a/Mage.Sets/src/mage/cards/l/LanternBearer.java +++ b/Mage.Sets/src/mage/cards/l/LanternBearer.java @@ -1,34 +1,61 @@ package mage.cards.l; -import mage.MageInt; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.DisturbAbility; +import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class LanternBearer extends CardImpl { +public final class LanternBearer extends TransformingDoubleFacedCard { public LanternBearer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "{U}", + "Lanterns' Lift", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "U" + ); - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.l.LanternsLift.class; + // Lantern Bearer + this.getLeftHalfCard().setPT(1, 1); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); + + // Lanterns' Lift + // 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)); // Disturb {2}{U} - this.addAbility(new DisturbAbility(this, "{2}{U}")); + // needs to be added after right half has spell ability target set + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{2}{U}")); + + // Enchanted creature gets +1/+1 and has flying. + Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect( + 1, 1, Duration.WhileOnBattlefield + )); + ability.addEffect(new GainAbilityAttachedEffect( + FlyingAbility.getInstance(), AttachmentType.AURA + ).setText("and has flying")); + this.getRightHalfCard().addAbility(ability); + + // If Lanterns' Lift would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private LanternBearer(final LanternBearer card) { diff --git a/Mage.Sets/src/mage/cards/l/LastingTarfire.java b/Mage.Sets/src/mage/cards/l/LastingTarfire.java new file mode 100644 index 00000000000..57e5b85c084 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LastingTarfire.java @@ -0,0 +1,99 @@ +package mage.cards.l; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LastingTarfire extends CardImpl { + + public LastingTarfire(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + + // At the beginning of each end step, if you put a counter on a creature this turn, this enchantment deals 2 damage to each opponent. + this.addAbility(new BeginningOfEndStepTriggeredAbility( + TargetController.ANY, new DamagePlayersEffect(2, TargetController.OPPONENT), + false, LastingTarfireCondition.instance + ).addHint(LastingTarfireCondition.getHint()), new LastingTarfireWatcher()); + } + + private LastingTarfire(final LastingTarfire card) { + super(card); + } + + @Override + public LastingTarfire copy() { + return new LastingTarfire(this); + } +} + +enum LastingTarfireCondition 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 LastingTarfireWatcher.checkPlayer(source.getControllerId(), game); + } + + @Override + public String toString() { + return "you put a counter on a creature this turn"; + } +} + +class LastingTarfireWatcher extends Watcher { + + private final Set set = new HashSet<>(); + + LastingTarfireWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() != GameEvent.EventType.COUNTER_ADDED || event.getAmount() < 1) { + return; + } + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent != null && permanent.isCreature(game)) { + set.add(event.getPlayerId()); + } + } + + @Override + public void reset() { + super.reset(); + set.clear(); + } + + static boolean checkPlayer(UUID playerId, Game game) { + return game + .getState() + .getWatcher(LastingTarfireWatcher.class) + .set + .contains(playerId); + } +} diff --git a/Mage.Sets/src/mage/cards/l/Lavaleaper.java b/Mage.Sets/src/mage/cards/l/Lavaleaper.java new file mode 100644 index 00000000000..76c2f6e0b17 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/Lavaleaper.java @@ -0,0 +1,61 @@ +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.TapForManaAllTriggeredManaAbility; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.effects.mana.AddManaOfAnyTypeProducedEffect; +import mage.abilities.keyword.HasteAbility; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SetTargetPointer; + +/** + * + * @author muz + */ +public final class Lavaleaper extends CardImpl { + + private static final FilterPermanent filter = new FilterLandPermanent("basic lands"); + + static { + filter.add(SuperType.BASIC.getPredicate()); + } + + public Lavaleaper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // All creatures have haste. + this.addAbility(new SimpleStaticAbility( + new GainAbilityAllEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_CREATURES) + )); + + // Whenever a player taps a basic land for mana, that player adds one mana of any type that land produced. + this.addAbility(new TapForManaAllTriggeredManaAbility( + new AddManaOfAnyTypeProducedEffect(), + filter, + SetTargetPointer.PERMANENT + )); + } + + private Lavaleaper(final Lavaleaper card) { + super(card); + } + + @Override + public Lavaleaper copy() { + return new Lavaleaper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LazotepConvert.java b/Mage.Sets/src/mage/cards/l/LazotepConvert.java deleted file mode 100644 index 6c6bf532331..00000000000 --- a/Mage.Sets/src/mage/cards/l/LazotepConvert.java +++ /dev/null @@ -1,110 +0,0 @@ -package mage.cards.l; - -import mage.MageInt; -import mage.MageObject; -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CopyEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.common.FilterCreatureCard; -import mage.game.Game; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInGraveyard; -import mage.util.functions.CopyApplier; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LazotepConvert extends CardImpl { - - public LazotepConvert(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ZOMBIE); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setBlue(true); - this.color.setBlack(true); - this.nightCard = true; - - // You may have Lazotep Convert enter the battlefield as a copy of any creature card in a graveyard, except it's a 4/4 black Zombie in addition to its other types. - this.addAbility(new EntersBattlefieldAbility(new LazotepConvertCopyEffect(), true)); - } - - private LazotepConvert(final LazotepConvert card) { - super(card); - } - - @Override - public LazotepConvert copy() { - return new LazotepConvert(this); - } -} - -class LazotepConvertCopyEffect extends OneShotEffect { - - private static final CopyApplier applier = new CopyApplier() { - - @Override - public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) { - blueprint.removePTCDA(); - blueprint.getPower().setModifiedBaseValue(4); - blueprint.getToughness().setModifiedBaseValue(4); - blueprint.addSubType(SubType.ZOMBIE); - blueprint.getColor().addColor(ObjectColor.BLACK); - return true; - } - }; - - private static final FilterCard filter = new FilterCreatureCard("creature card in a graveyard"); - - public LazotepConvertCopyEffect() { - super(Outcome.Copy); - this.staticText = "as a copy of any creature card in a graveyard, " + - "except it's a 4/4 black Zombie in addition to its other types"; - } - - private LazotepConvertCopyEffect(final LazotepConvertCopyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Target target = new TargetCardInGraveyard(0, 1, filter); - target.withNotTarget(true); - player.choose(outcome, target, source, game); - Card copyFromCard = game.getCard(target.getFirstTarget()); - if (copyFromCard == null) { - return true; - } - Card modifiedCopy = copyFromCard.copy(); - //Appliers must be applied before CopyEffect, its applier setting is just for copies of copies - // TODO: research applier usage, why it here - applier.apply(game, modifiedCopy, source, source.getSourceId()); - game.addEffect(new CopyEffect( - Duration.Custom, modifiedCopy, source.getSourceId() - ).setApplier(applier), source); - return true; - } - - @Override - public LazotepConvertCopyEffect copy() { - return new LazotepConvertCopyEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LegionsLanding.java b/Mage.Sets/src/mage/cards/l/LegionsLanding.java index 7051affd2a3..3df75b5c68e 100644 --- a/Mage.Sets/src/mage/cards/l/LegionsLanding.java +++ b/Mage.Sets/src/mage/cards/l/LegionsLanding.java @@ -1,14 +1,18 @@ - package mage.cards.l; +import mage.abilities.Ability; import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.WhiteManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.game.permanent.token.IxalanVampireToken; @@ -17,21 +21,31 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class LegionsLanding extends CardImpl { +public final class LegionsLanding extends TransformingDoubleFacedCard { public LegionsLanding(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); - - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.a.AdantoTheFirstFort.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{W}", + "Adanto, the First Fort", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Legion's Landing // When Legion's Landing enters the battlefield, create a 1/1 white Vampire creature token with lifelink. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new IxalanVampireToken()))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new IxalanVampireToken()))); // When you attack with three or more creatures, transform Legion's Landing. - this.addAbility(new TransformAbility()); - this.addAbility(new AttacksWithCreaturesTriggeredAbility(new TransformSourceEffect(), 3).setTriggerPhrase("When you attack with three or more creatures, ")); + this.getLeftHalfCard().addAbility(new AttacksWithCreaturesTriggeredAbility(new TransformSourceEffect(), 3) + .setTriggerPhrase("When you attack with three or more creatures, ")); + + // Adanto, the First Fort + // {T}: Add {W}. + this.getRightHalfCard().addAbility(new WhiteManaAbility()); + + // {2}{W}, {T}: Create a 1/1 white Vampire creature token with lifelink. + Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new IxalanVampireToken()), new ManaCostsImpl<>("{2}{W}")); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability); } private LegionsLanding(final LegionsLanding card) { diff --git a/Mage.Sets/src/mage/cards/l/LeonardoSewerSamurai.java b/Mage.Sets/src/mage/cards/l/LeonardoSewerSamurai.java new file mode 100644 index 00000000000..f92e54269b1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LeonardoSewerSamurai.java @@ -0,0 +1,120 @@ +package mage.cards.l; + +import mage.MageIdentifier; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.common.counter.AddCounterEnteringCreatureEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.SneakAbility; +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.players.Player; +import mage.watchers.Watcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LeonardoSewerSamurai extends CardImpl { + + public LeonardoSewerSamurai(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.MUTANT); + this.subtype.add(SubType.NINJA); + this.subtype.add(SubType.TURTLE); + this.subtype.add(SubType.SAMURAI); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Sneak {2}{W}{W} + this.addAbility(new SneakAbility(this, "{2}{W}{W}")); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // During your turn, you may cast creature spells with power or toughness 1 or less from your graveyard. If you cast a spell this way, that creature enters with a finality counter on it. + this.addAbility(new SimpleStaticAbility(new LeonardoSewerSamuraiEffect()) + .setIdentifier(MageIdentifier.LeonardoSewerSamuraiAlternateCast), new LeonardoSewerSamuraiWatcher()); + } + + private LeonardoSewerSamurai(final LeonardoSewerSamurai card) { + super(card); + } + + @Override + public LeonardoSewerSamurai copy() { + return new LeonardoSewerSamurai(this); + } +} + +class LeonardoSewerSamuraiEffect extends AsThoughEffectImpl { + + LeonardoSewerSamuraiEffect() { + super(AsThoughEffectType.CAST_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.AIDontUseIt); + staticText = "during your turn, you may cast creature spells with power or toughness 1 or less " + + "from your graveyard. If you cast a spell this way, that creature enters with a finality counter on it"; + } + + private LeonardoSewerSamuraiEffect(final LeonardoSewerSamuraiEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public LeonardoSewerSamuraiEffect copy() { + return new LeonardoSewerSamuraiEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (!source.isControlledBy(affectedControllerId)) { + return false; + } + Card card = game.getCard(objectId); + Player player = game.getPlayer(affectedControllerId); + return card != null + && player != null + && card.isOwnedBy(affectedControllerId) + && game.getState().getZone(objectId).match(Zone.GRAVEYARD) + && card.isCreature(game) + && (card.getPower().getValue() <= 1 || card.getToughness().getValue() <= 1); + } +} + +class LeonardoSewerSamuraiWatcher extends Watcher { + + LeonardoSewerSamuraiWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (!GameEvent.EventType.SPELL_CAST.equals(event.getType()) + || !event.hasApprovingIdentifier(MageIdentifier.LeonardoSewerSamuraiAlternateCast)) { + return; + } + Spell target = game.getSpell(event.getTargetId()); + if (target != null) { + game.getState().addEffect(new AddCounterEnteringCreatureEffect( + new MageObjectReference(target.getCard(), game), + CounterType.FINALITY.createInstance(), Outcome.UnboostCreature + ), target.getSpellAbility()); + } + } +} diff --git a/Mage.Sets/src/mage/cards/l/LeylineSurge.java b/Mage.Sets/src/mage/cards/l/LeylineSurge.java deleted file mode 100644 index 42a10f256e7..00000000000 --- a/Mage.Sets/src/mage/cards/l/LeylineSurge.java +++ /dev/null @@ -1,37 +0,0 @@ -package mage.cards.l; - -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LeylineSurge extends CardImpl { - - public LeylineSurge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setGreen(true); - this.nightCard = true; - - // At the beginning of your upkeep, you may put a permanent card from your hand onto the battlefield. - this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_A_PERMANENT) - )); - } - - private LeylineSurge(final LeylineSurge card) { - super(card); - } - - @Override - public LeylineSurge copy() { - return new LeylineSurge(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java b/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java index 265927d6274..758cccf71b1 100644 --- a/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java +++ b/Mage.Sets/src/mage/cards/l/LifeOfToshiroUmezawa.java @@ -1,13 +1,17 @@ package mage.cards.l; +import mage.Mana; +import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.SagaAbility; +import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.ConditionalColoredManaAbility; +import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SagaChapter; import mage.constants.SubType; @@ -18,23 +22,25 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class LifeOfToshiroUmezawa extends CardImpl { +public final class LifeOfToshiroUmezawa extends TransformingDoubleFacedCard { public LifeOfToshiroUmezawa(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.m.MemoryOfToshiro.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{B}", + "Memory of Toshiro", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SAMURAI}, "B" + ); + // Life of Toshiro Umezawa // (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 — Choose one — // • Target creature gets +2/+2 until end of turn. // • Target creature gets -1/-1 until end of turn. // • You gain 2 life. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, false, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, false, ability -> { ability.addEffect(new BoostTargetEffect(2, 2)); ability.addTarget(new TargetCreaturePermanent()); @@ -45,10 +51,16 @@ public final class LifeOfToshiroUmezawa 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.getLeftHalfCard().addAbility(sagaAbility); - this.addAbility(sagaAbility); + // Memory of Toshiro + this.getRightHalfCard().setPT(2, 3); + + // {T}, Pay 1 life: Add {B}. Spend this mana only to cast an instant or sorcery spell. + Ability ability = new ConditionalColoredManaAbility(Mana.BlackMana(1), new InstantOrSorcerySpellManaBuilder()); + ability.addCost(new PayLifeCost(1)); + this.getRightHalfCard().addAbility(ability); } private LifeOfToshiroUmezawa(final LifeOfToshiroUmezawa card) { diff --git a/Mage.Sets/src/mage/cards/l/LightshieldArray.java b/Mage.Sets/src/mage/cards/l/LightshieldArray.java deleted file mode 100644 index 45076095e12..00000000000 --- a/Mage.Sets/src/mage/cards/l/LightshieldArray.java +++ /dev/null @@ -1,92 +0,0 @@ -package mage.cards.l; - -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.SacrificeSourceCost; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.HexproofAbility; -import mage.abilities.keyword.IndestructibleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.counters.CounterType; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.watchers.common.AttackedThisTurnWatcher; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LightshieldArray extends CardImpl { - - public LightshieldArray(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setWhite(true); - this.nightCard = true; - - // At the beginning of your end step, put a +1/+1 counter on each creature that attacked this turn. - this.addAbility(new BeginningOfEndStepTriggeredAbility( - new LightshieldArrayEffect() - )); - - // Sacrifice Lightshield Array: Creatures you control gain hexproof and indestructible until end of turn. - Ability ability = new SimpleActivatedAbility(new GainAbilityControlledEffect( - HexproofAbility.getInstance(), Duration.EndOfTurn, - StaticFilters.FILTER_CONTROLLED_CREATURE - ).setText("creatures you control gain hexproof"), new SacrificeSourceCost()); - ability.addEffect(new GainAbilityControlledEffect( - IndestructibleAbility.getInstance(), Duration.EndOfTurn, - StaticFilters.FILTER_CONTROLLED_CREATURE - ).setText("and indestructible until end of turn")); - this.addAbility(ability); - } - - private LightshieldArray(final LightshieldArray card) { - super(card); - } - - @Override - public LightshieldArray copy() { - return new LightshieldArray(this); - } -} - -class LightshieldArrayEffect extends OneShotEffect { - - LightshieldArrayEffect() { - super(Outcome.Benefit); - staticText = "put a +1/+1 counter on each creature that attacked this turn"; - } - - private LightshieldArrayEffect(final LightshieldArrayEffect effect) { - super(effect); - } - - @Override - public LightshieldArrayEffect copy() { - return new LightshieldArrayEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (MageObjectReference mor : game - .getState() - .getWatcher(AttackedThisTurnWatcher.class) - .getAttackedThisTurnCreatures()) { - Permanent permanent = mor.getPermanent(game); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(), source, game); - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java b/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java deleted file mode 100644 index a4250a436d0..00000000000 --- a/Mage.Sets/src/mage/cards/l/LilianaDefiantNecromancer.java +++ /dev/null @@ -1,63 +0,0 @@ -package mage.cards.l; - -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.Predicates; -import mage.game.command.emblems.LilianaDefiantNecromancerEmblem; -import mage.target.common.TargetCardInYourGraveyard; -import mage.target.targetadjustment.XManaValueTargetAdjuster; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class LilianaDefiantNecromancer extends CardImpl { - - private static final FilterCreatureCard filter = new FilterCreatureCard("nonlegendary creature card with mana value X from your graveyard"); - - static { - filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); - } - - public LilianaDefiantNecromancer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.LILIANA); - this.color.setBlack(true); - - this.nightCard = true; - - this.setStartingLoyalty(3); - - // +2: Each player discards a card. - this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(1, false), 2)); - - // -X: Return target nonlegendary creature with converted mana cost X from your graveyard to the battlefield. - Ability ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()); - ability.addTarget(new TargetCardInYourGraveyard(filter)); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); - this.addAbility(ability); - - //-8: You get an emblem with "Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step."; - this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new LilianaDefiantNecromancerEmblem()), -8)); - } - - private LilianaDefiantNecromancer(final LilianaDefiantNecromancer card) { - super(card); - } - - @Override - public LilianaDefiantNecromancer copy() { - return new LilianaDefiantNecromancer(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LilianaHereticalHealer.java b/Mage.Sets/src/mage/cards/l/LilianaHereticalHealer.java index 2f3557624a4..560727083e3 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaHereticalHealer.java +++ b/Mage.Sets/src/mage/cards/l/LilianaHereticalHealer.java @@ -1,52 +1,76 @@ package mage.cards.l; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AnotherPredicate; import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.command.emblems.LilianaDefiantNecromancerEmblem; import mage.game.permanent.token.ZombieToken; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.XManaValueTargetAdjuster; import java.util.UUID; /** * @author LevelX2 */ -public final class LilianaHereticalHealer extends CardImpl { +public final class LilianaHereticalHealer extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another nontoken creature you control"); + private static final FilterCreatureCard graveyardFilter = new FilterCreatureCard("nonlegendary creature card with mana value X from your graveyard"); static { filter.add(AnotherPredicate.instance); filter.add(TokenPredicate.FALSE); + graveyardFilter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); } public LilianaHereticalHealer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(2); - this.toughness = new MageInt(3); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CLERIC}, "{1}{B}{B}", + "Liliana, Defiant Necromancer", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.LILIANA}, "B" + ); - this.secondSideCardClazz = mage.cards.l.LilianaDefiantNecromancer.class; - this.addAbility(new TransformAbility()); + // Liliana, Heretical Healer + this.getLeftHalfCard().setPT(2, 3); // Lifelink - this.addAbility(LifelinkAbility.getInstance()); + this.getLeftHalfCard().addAbility(LifelinkAbility.getInstance()); // Whenever another nontoken creature you control dies, exile Liliana Heretical Healer, then return her to the battlefield transformed under her owner's control. If you do, create a 2/2 black Zombie creature token. - this.addAbility(new DiesCreatureTriggeredAbility(new ExileAndReturnSourceEffect( + this.getLeftHalfCard().addAbility(new DiesCreatureTriggeredAbility(new ExileAndReturnSourceEffect( PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.SHE, false, new CreateTokenEffect(new ZombieToken()) ), false, filter)); + + // Liliana, Defiant Necromancer + this.getRightHalfCard().setStartingLoyalty(3); + + // +2: Each player discards a card. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(1, false), 2)); + + // -X: Return target nonlegendary creature with mana value X from your graveyard to the battlefield. + Ability ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()); + ability.addTarget(new TargetCardInYourGraveyard(graveyardFilter)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); + this.getRightHalfCard().addAbility(ability); + + // -8: You get an emblem with "Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step." + this.getRightHalfCard().addAbility(new LoyaltyAbility(new GetEmblemEffect(new LilianaDefiantNecromancerEmblem()), -8)); } private LilianaHereticalHealer(final LilianaHereticalHealer card) { diff --git a/Mage.Sets/src/mage/cards/l/LiminalHold.java b/Mage.Sets/src/mage/cards/l/LiminalHold.java new file mode 100644 index 00000000000..4e42eca2114 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LiminalHold.java @@ -0,0 +1,39 @@ +package mage.cards.l; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; + +/** + * + * @author muz + */ +public final class LiminalHold extends CardImpl { + + public LiminalHold(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // When this enchantment enters, exile up to one target nonland permanent an opponent controls until this enchantment leaves the battlefield. You gain 2 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); + ability.addEffect(new GainLifeEffect(2)); + this.addAbility(ability); + } + + private LiminalHold(final LiminalHold card) { + super(card); + } + + @Override + public LiminalHold copy() { + return new LiminalHold(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LivingBreakthrough.java b/Mage.Sets/src/mage/cards/l/LivingBreakthrough.java deleted file mode 100644 index 861156384e3..00000000000 --- a/Mage.Sets/src/mage/cards/l/LivingBreakthrough.java +++ /dev/null @@ -1,103 +0,0 @@ -package mage.cards.l; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.Spell; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LivingBreakthrough extends CardImpl { - - public LivingBreakthrough(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.MOONFOLK); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever you cast a spell, your opponents can't cast spells with the same mana value as that spell until your next turn. - this.addAbility(new SpellCastControllerTriggeredAbility(new LivingBreakthroughEffect(), false)); - } - - private LivingBreakthrough(final LivingBreakthrough card) { - super(card); - } - - @Override - public LivingBreakthrough copy() { - return new LivingBreakthrough(this); - } -} - -class LivingBreakthroughEffect extends ContinuousRuleModifyingEffectImpl { - - private int manaValue = -1; - - LivingBreakthroughEffect() { - super(Duration.UntilYourNextTurn, Outcome.Benefit); - staticText = "your opponents can't cast spells with the same mana value as that spell until your next turn"; - } - - private LivingBreakthroughEffect(final LivingBreakthroughEffect effect) { - super(effect); - this.manaValue = effect.manaValue; - } - - @Override - public LivingBreakthroughEffect copy() { - return new LivingBreakthroughEffect(this); - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - Spell spell = (Spell) getValue("spellCast"); - if (spell != null) { - this.manaValue = spell.getManaValue(); - } - } - - @Override - public String getInfoMessage(Ability source, GameEvent event, Game game) { - MageObject mageObject = game.getObject(source); - if (mageObject != null) { - return "You can't cast spells with mana value " + manaValue - + " this turn (" + mageObject.getIdName() + ")."; - } - return null; - } - - @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) { - if (!game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - return false; - } - Spell spell = game.getStack().getSpell(event.getTargetId()); - return spell != null && spell.getManaValue() == this.manaValue; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LochMare.java b/Mage.Sets/src/mage/cards/l/LochMare.java new file mode 100644 index 00000000000..d57a16fbd67 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LochMare.java @@ -0,0 +1,64 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LochMare extends CardImpl { + + public LochMare(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.HORSE); + this.subtype.add(SubType.SERPENT); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // This creature enters with three -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance(3)), + "with three -1/-1 counters on it" + )); + + // {1}{U}, Remove a counter from this creature: Draw a card. + Ability ability = new SimpleActivatedAbility( + new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}{U}") + ); + ability.addCost(new RemoveCountersSourceCost(1)); + this.addAbility(ability); + + // {2}{U}, Remove two counters from this creature: Tap target creature. Put a stun counter on it. + ability = new SimpleActivatedAbility(new TapTargetEffect(), new ManaCostsImpl<>("{2}{U}")); + ability.addCost(new RemoveCountersSourceCost(2)); + ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance()).withTargetDescription("it")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private LochMare(final LochMare card) { + super(card); + } + + @Override + public LochMare copy() { + return new LochMare(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/l/LodestoneNeedle.java b/Mage.Sets/src/mage/cards/l/LodestoneNeedle.java index a68ba5a2eb1..3a04293fad3 100644 --- a/Mage.Sets/src/mage/cards/l/LodestoneNeedle.java +++ b/Mage.Sets/src/mage/cards/l/LodestoneNeedle.java @@ -1,41 +1,58 @@ package mage.cards.l; import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.keyword.ExploreTargetEffect; import mage.abilities.keyword.CraftAbility; import mage.abilities.keyword.FlashAbility; -import mage.cards.CardImpl; 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.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; import java.util.UUID; /** * @author Susucr */ -public final class LodestoneNeedle extends CardImpl { +public final class LodestoneNeedle extends TransformingDoubleFacedCard { public LodestoneNeedle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{U}"); - this.secondSideCardClazz = mage.cards.g.GuidestoneCompass.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{1}{U}", + "Guidestone Compass", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "U" + ); + // Lodestone Needle // Flash - this.addAbility(FlashAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlashAbility.getInstance()); // When Lodestone Needle enters the battlefield, tap up to one target artifact or creature and put two stun counters on it. Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance(2)) .setText("and put two stun counters on it")); ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Craft with artifact {2}{U} - this.addAbility(new CraftAbility("{2}{U}")); + this.getLeftHalfCard().addAbility(new CraftAbility("{2}{U}")); + + // Guidestone Compass + // {1}, {T}: Target creature you control explores. Activate only as a sorcery. + Ability compassAbility = new ActivateAsSorceryActivatedAbility(new ExploreTargetEffect(), new GenericManaCost(1)); + compassAbility.addTarget(new TargetControlledCreaturePermanent()); + compassAbility.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(compassAbility); } private LodestoneNeedle(final LodestoneNeedle card) { diff --git a/Mage.Sets/src/mage/cards/l/LanternsLift.java b/Mage.Sets/src/mage/cards/l/LoftyDreams.java similarity index 60% rename from Mage.Sets/src/mage/cards/l/LanternsLift.java rename to Mage.Sets/src/mage/cards/l/LoftyDreams.java index 7cb53c9d83e..e49e395f998 100644 --- a/Mage.Sets/src/mage/cards/l/LanternsLift.java +++ b/Mage.Sets/src/mage/cards/l/LoftyDreams.java @@ -1,16 +1,21 @@ package mage.cards.l; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.keyword.DisturbAbility; +import mage.abilities.keyword.ConvokeAbility; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +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; @@ -19,14 +24,15 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class LanternsLift extends CardImpl { +public final class LoftyDreams extends CardImpl { - public LanternsLift(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); + public LoftyDreams(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}"); this.subtype.add(SubType.AURA); - this.color.setBlue(true); - this.nightCard = true; + + // Convoke + this.addAbility(new ConvokeAbility()); // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -34,25 +40,23 @@ public final class LanternsLift extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); this.addAbility(new EnchantAbility(auraTarget)); - // Enchanted creature gets +1/+1 and has flying. - Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect( - 1, 1, Duration.WhileOnBattlefield - )); + // When this Aura enters, draw a card. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); + + // Enchanted creature gets +2/+2 and has flying. + Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(2, 2)); ability.addEffect(new GainAbilityAttachedEffect( FlyingAbility.getInstance(), AttachmentType.AURA ).setText("and has flying")); this.addAbility(ability); - - // If Lanterns' Lift would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); } - private LanternsLift(final LanternsLift card) { + private LoftyDreams(final LoftyDreams card) { super(card); } @Override - public LanternsLift copy() { - return new LanternsLift(this); + public LoftyDreams copy() { + return new LoftyDreams(this); } } diff --git a/Mage.Sets/src/mage/cards/l/LoneRider.java b/Mage.Sets/src/mage/cards/l/LoneRider.java index c6450c5473a..848c4ff6282 100644 --- a/Mage.Sets/src/mage/cards/l/LoneRider.java +++ b/Mage.Sets/src/mage/cards/l/LoneRider.java @@ -1,16 +1,16 @@ package mage.cards.l; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.condition.Condition; import mage.abilities.condition.common.YouGainedLifeCondition; import mage.abilities.dynamicvalue.common.ControllerGainedLifeCount; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.keyword.TrampleAbility; 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; @@ -22,30 +22,46 @@ import java.util.UUID; /** * @author fireshoes */ -public final class LoneRider extends CardImpl { +public final class LoneRider extends TransformingDoubleFacedCard { private static final Condition condition = new YouGainedLifeCondition(ComparisonType.MORE_THAN, 2); public LoneRider(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.KNIGHT); - this.power = new MageInt(1); - this.toughness = new MageInt(1); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.KNIGHT}, "{1}{W}", + "It That Rides as One", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDRAZI, SubType.HORROR}, "" + ); - this.secondSideCardClazz = mage.cards.i.ItThatRidesAsOne.class; + // Lone Rider + this.getLeftHalfCard().setPT(1, 1); // First strike - this.addAbility(FirstStrikeAbility.getInstance()); + this.getLeftHalfCard().addAbility(FirstStrikeAbility.getInstance()); // Lifelink - this.addAbility(LifelinkAbility.getInstance()); + this.getLeftHalfCard().addAbility(LifelinkAbility.getInstance()); // At the beginning of the end step, if you gained 3 or more life this turn, transform Lone Rider. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility( - TargetController.NEXT, new TransformSourceEffect(), false - ).withInterveningIf(condition).addHint(ControllerGainedLifeCount.getHint()), new PlayerGainedLifeWatcher()); + Ability ability = new BeginningOfEndStepTriggeredAbility( + TargetController.NEXT, new TransformSourceEffect(), false) + .withInterveningIf(condition) + .addHint(ControllerGainedLifeCount.getHint() + ); + ability.addWatcher(new PlayerGainedLifeWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // It That Rides as One + this.getRightHalfCard().setPT(4, 4); + + // First strike + this.getRightHalfCard().addAbility(FirstStrikeAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); } private LoneRider(final LoneRider card) { diff --git a/Mage.Sets/src/mage/cards/l/LoneWolfOfTheNatterknolls.java b/Mage.Sets/src/mage/cards/l/LoneWolfOfTheNatterknolls.java deleted file mode 100644 index 76c89b0d922..00000000000 --- a/Mage.Sets/src/mage/cards/l/LoneWolfOfTheNatterknolls.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.l; - -import mage.MageInt; -import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.condition.common.MyTurnCondition; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class LoneWolfOfTheNatterknolls extends CardImpl { - - public LoneWolfOfTheNatterknolls(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(5); - this.color.setGreen(true); - - this.nightCard = true; - - // Whenever an opponent cast a spell during your turn, draw two cards. - this.addAbility(new SpellCastOpponentTriggeredAbility( - new DrawCardSourceControllerEffect(2), StaticFilters.FILTER_SPELL_A, false - ).withTriggerCondition(MyTurnCondition.instance)); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Lone Wolf of the Natterknolls. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private LoneWolfOfTheNatterknolls(final LoneWolfOfTheNatterknolls card) { - super(card); - } - - @Override - public LoneWolfOfTheNatterknolls copy() { - return new LoneWolfOfTheNatterknolls(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LordOfTheUlvenwald.java b/Mage.Sets/src/mage/cards/l/LordOfTheUlvenwald.java deleted file mode 100644 index 7fed8fc3c0f..00000000000 --- a/Mage.Sets/src/mage/cards/l/LordOfTheUlvenwald.java +++ /dev/null @@ -1,100 +0,0 @@ -package mage.cards.l; - -import mage.MageInt; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.keyword.NightboundAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.players.Player; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LordOfTheUlvenwald extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Wolves and Werewolves"); - - static { - filter.add(Predicates.or( - SubType.WOLF.getPredicate(), - SubType.WEREWOLF.getPredicate() - )); - } - - public LordOfTheUlvenwald(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(3); - - this.color.setRed(true); - this.color.setGreen(true); - this.nightCard = true; - - // Other Wolves and Werewolves you control get +1/+1. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( - 1, 1, Duration.WhileOnBattlefield, filter, true - ))); - - // Whenever Lord of the Ulvenwald attacks, add {R} or {G}. Until end of turn, you don't lose this mana as steps and phases end. - this.addAbility(new AttacksTriggeredAbility(new LordOfTheUlvenwaldEffect())); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private LordOfTheUlvenwald(final LordOfTheUlvenwald card) { - super(card); - } - - @Override - public LordOfTheUlvenwald copy() { - return new LordOfTheUlvenwald(this); - } -} - -class LordOfTheUlvenwaldEffect extends OneShotEffect { - - LordOfTheUlvenwaldEffect() { - super(Outcome.Benefit); - staticText = "add {R} or {G}. Until end of turn, you don't lose this mana as steps and phases end"; - } - - private LordOfTheUlvenwaldEffect(final LordOfTheUlvenwaldEffect effect) { - super(effect); - } - - @Override - public LordOfTheUlvenwaldEffect copy() { - return new LordOfTheUlvenwaldEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - Mana mana = player.chooseUse( - Outcome.Neutral, "Choose red or green", null, - "Red", "Green", source, game - ) ? Mana.RedMana(1) : Mana.GreenMana(1); - player.getManaPool().addMana(mana, game, source, true); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LoyalCathar.java b/Mage.Sets/src/mage/cards/l/LoyalCathar.java index b6c4857f69d..41bb3659fc3 100644 --- a/Mage.Sets/src/mage/cards/l/LoyalCathar.java +++ b/Mage.Sets/src/mage/cards/l/LoyalCathar.java @@ -1,10 +1,7 @@ - package mage.cards.l; -import java.util.UUID; - -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.CantBlockAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; @@ -12,8 +9,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -22,26 +19,31 @@ import mage.game.Game; import mage.players.Player; import mage.target.targetpointer.FixedTarget; -/** - * @author BetaSteward - */ -public final class LoyalCathar extends CardImpl { +import java.util.UUID; + +public final class LoyalCathar extends TransformingDoubleFacedCard { public LoyalCathar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SOLDIER); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SOLDIER}, "{W}{W}", + "Unhallowed Cathar", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ZOMBIE, SubType.SOLDIER}, "B" + ); - this.secondSideCardClazz = mage.cards.u.UnhallowedCathar.class; + // Loyal Cathar + this.getLeftHalfCard().setPT(2, 2); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - this.addAbility(VigilanceAbility.getInstance()); + // Vigilance + this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance()); // When Loyal Cathar dies, return it to the battlefield transformed under your control at the beginning of the next end step. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesSourceTriggeredAbility(new LoyalCatharEffect())); + this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new LoyalCatharEffect())); + + // Unhallowed Cathar + this.getRightHalfCard().setPT(2, 1); + + // Unhallowed Cathar can't block. + this.getRightHalfCard().addAbility(new CantBlockAbility()); } private LoyalCathar(final LoyalCathar card) { diff --git a/Mage.Sets/src/mage/cards/l/LudevicNecrogenius.java b/Mage.Sets/src/mage/cards/l/LudevicNecrogenius.java index dae5e612be0..0dd0cd31069 100644 --- a/Mage.Sets/src/mage/cards/l/LudevicNecrogenius.java +++ b/Mage.Sets/src/mage/cards/l/LudevicNecrogenius.java @@ -1,53 +1,66 @@ package mage.cards.l; -import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.ExileXFromYourGraveCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CopyEffect; import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.MillCardsControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.cards.*; +import mage.constants.*; import mage.filter.StaticFilters; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentCard; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInExile; import mage.util.CardUtil; +import mage.util.functions.CopyApplier; import java.util.UUID; /** * @author TheElk801 */ -public final class LudevicNecrogenius extends CardImpl { +public final class LudevicNecrogenius extends TransformingDoubleFacedCard { public LudevicNecrogenius(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{U}{B}", + "Olag, Ludevic's Hubris", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ZOMBIE}, "UB" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.o.OlagLudevicsHubris.class; + // Ludevic, Necrogenius + this.getLeftHalfCard().setPT(2, 3); // Whenever Ludevic, Necrogenius enters the battlefield or attacks, mill a card. - this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new MillCardsControllerEffect(1))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new MillCardsControllerEffect(1))); // {X}{U}{U}{B}{B}, Exile X creature cards from your graveyard: Transform Ludevic, Necrogenius. X can't be zero. Activate only as a sorcery. - this.addAbility(new TransformAbility()); Ability ability = new ActivateAsSorceryActivatedAbility( new TransformSourceEffect(), new ManaCostsImpl<>("{X}{U}{U}{B}{B}") ); ability.addEffect(new InfoEffect("X can't be 0")); ability.addCost(new ExileXFromYourGraveCost(StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD)); CardUtil.castStream(ability.getCosts().stream(), VariableManaCost.class).forEach(cost -> cost.setMinX(1)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Olag, Ludevic's Hubris + this.getRightHalfCard().setPT(4, 4); + + // As this creature transforms in Olag, Ludevic's Hubris, it becomes a copy of a creature card exiled with it, except its name is Olag, Ludevic's Hubris, it's 4/4, and it's a legendary blue and black Zombie in addition to its other colors and types. Put a number of +1/+1 counters on Olag equal to the number of creature cards exiled with it. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new OlagLudevicsHubrisEffect())); } private LudevicNecrogenius(final LudevicNecrogenius card) { @@ -59,3 +72,92 @@ public final class LudevicNecrogenius extends CardImpl { return new LudevicNecrogenius(this); } } + + +class OlagLudevicsHubrisEffect extends ReplacementEffectImpl { + + OlagLudevicsHubrisEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "as this creature transforms into {this}, it becomes a copy of a creature card exiled with it, " + + "except its name is Olag, Ludevic's Hubris, it's 4/4, and it's a legendary blue and black " + + "Zombie in addition to its other colors and types. Put a number of +1/+1 counters on {this} " + + "equal to the number of creature cards exiled with it"; + } + + private OlagLudevicsHubrisEffect(final OlagLudevicsHubrisEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + if (exileZone == null) { + return false; + } + + Cards cards = new CardsImpl(exileZone); + cards.removeIf(uuid -> !game.getCard(uuid).isCreature(game)); + if (cards.isEmpty()) { + return false; + } + + Card copyFromCard = getCard(cards, source, game); + if (copyFromCard == null) { + return false; + } + Permanent newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game); + newBluePrint.assignNewId(); + CopyApplier applier = new OlagLudevicsHubrisCopyApplier(); + applier.apply(game, newBluePrint, source, source.getSourceId()); + CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, source.getSourceId()); + copyEffect.setApplier(applier); + Ability newAbility = source.copy(); + copyEffect.init(newAbility, game); + game.addEffect(copyEffect, newAbility); + return false; + } + + private Card getCard(Cards cards, Ability source, Game game) { + if (cards.size() == 1) { + return cards.getRandom(game); + } + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return cards.getRandom(game); + } + TargetCard target = new TargetCardInExile(StaticFilters.FILTER_CARD); + player.choose(outcome, target, source, game); + return cards.get(target.getFirstTarget(), game); + } + + @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; + } + + @Override + public OlagLudevicsHubrisEffect copy() { + return new OlagLudevicsHubrisEffect(this); + } +} + +class OlagLudevicsHubrisCopyApplier extends CopyApplier { + + @Override + public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) { + blueprint.setName("Olag, Ludevic's Hubris"); + blueprint.addSuperType(SuperType.LEGENDARY); + blueprint.addSubType(SubType.ZOMBIE); + blueprint.getColor().setBlue(true); + blueprint.getColor().setBlack(true); + blueprint.getPower().setModifiedBaseValue(4); + blueprint.getToughness().setModifiedBaseValue(4); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/l/LudevicsAbomination.java b/Mage.Sets/src/mage/cards/l/LudevicsAbomination.java deleted file mode 100644 index dcfe9517ef7..00000000000 --- a/Mage.Sets/src/mage/cards/l/LudevicsAbomination.java +++ /dev/null @@ -1,41 +0,0 @@ - -package mage.cards.l; - -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 North - */ -public final class LudevicsAbomination extends CardImpl { - - public LudevicsAbomination(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.LIZARD); - this.subtype.add(SubType.HORROR); - this.color.setBlue(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(13); - this.toughness = new MageInt(13); - - this.addAbility(TrampleAbility.getInstance()); - } - - private LudevicsAbomination(final LudevicsAbomination card) { - super(card); - } - - @Override - public LudevicsAbomination copy() { - return new LudevicsAbomination(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LudevicsTestSubject.java b/Mage.Sets/src/mage/cards/l/LudevicsTestSubject.java index 4dd297875f1..57512b0ec94 100644 --- a/Mage.Sets/src/mage/cards/l/LudevicsTestSubject.java +++ b/Mage.Sets/src/mage/cards/l/LudevicsTestSubject.java @@ -1,6 +1,5 @@ package mage.cards.l; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; @@ -11,9 +10,9 @@ 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.TrampleAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; @@ -23,23 +22,24 @@ import java.util.UUID; /** * @author Loki */ -public final class LudevicsTestSubject extends CardImpl { +public final class LudevicsTestSubject extends TransformingDoubleFacedCard { private static final Condition condition = new SourceHasCounterCondition(CounterType.HATCHLING, 5); public LudevicsTestSubject(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); - this.subtype.add(SubType.LIZARD, SubType.EGG); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.LIZARD, SubType.EGG}, "{1}{U}", + "Ludevic's Abomination", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.LIZARD, SubType.HORROR}, "U" + ); - this.power = new MageInt(0); - this.toughness = new MageInt(3); + // Ludevic's Test Subject + this.getLeftHalfCard().setPT(0, 3); - this.secondSideCardClazz = mage.cards.l.LudevicsAbomination.class; - - this.addAbility(DefenderAbility.getInstance()); + // Defender + this.getLeftHalfCard().addAbility(DefenderAbility.getInstance()); // {1}{U}: Put a hatchling counter on Ludevic's Test Subject. Then if there are five or more hatchling counters on it, remove all of them and transform it. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.HATCHLING.createInstance()), new ManaCostsImpl<>("{1}{U}") ); @@ -47,7 +47,13 @@ public final class LudevicsTestSubject extends CardImpl { new RemoveAllCountersSourceEffect(CounterType.HATCHLING), condition, "Then if there are five or more hatchling counters on it, remove all of them and transform it" ).addEffect(new TransformSourceEffect())); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Ludevic's Abomination + this.getRightHalfCard().setPT(13, 13); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); } private LudevicsTestSubject(final LudevicsTestSubject card) { diff --git a/Mage.Sets/src/mage/cards/l/Luminollusk.java b/Mage.Sets/src/mage/cards/l/Luminollusk.java new file mode 100644 index 00000000000..483c646b909 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/Luminollusk.java @@ -0,0 +1,45 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.DeathtouchAbility; +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 TheElk801 + */ +public final class Luminollusk extends CardImpl { + + public Luminollusk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Vivid -- When this creature enters, you gain life equal to the number of colors among permanents you control. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new GainLifeEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS) + ).setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private Luminollusk(final Luminollusk card) { + super(card); + } + + @Override + public Luminollusk copy() { + return new Luminollusk(this); + } +} diff --git a/Mage.Sets/src/mage/cards/l/LuminousPhantom.java b/Mage.Sets/src/mage/cards/l/LuminousPhantom.java deleted file mode 100644 index 123b2665457..00000000000 --- a/Mage.Sets/src/mage/cards/l/LuminousPhantom.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.l; - -import mage.MageInt; -import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.keyword.DisturbAbility; -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 java.util.UUID; - -/** - * @author TheElk801 - */ -public final class LuminousPhantom extends CardImpl { - - public LuminousPhantom(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.color.setWhite(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever another creature you control leaves the battlefield, you gain 1 life. - this.addAbility(new LeavesBattlefieldAllTriggeredAbility(new GainLifeEffect(1), StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL)); - - // If Luminous Phantom would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private LuminousPhantom(final LuminousPhantom card) { - super(card); - } - - @Override - public LuminousPhantom copy() { - return new LuminousPhantom(this); - } -} diff --git a/Mage.Sets/src/mage/cards/l/LunarchVeteran.java b/Mage.Sets/src/mage/cards/l/LunarchVeteran.java index 22eb68fa555..d96df1d99ae 100644 --- a/Mage.Sets/src/mage/cards/l/LunarchVeteran.java +++ b/Mage.Sets/src/mage/cards/l/LunarchVeteran.java @@ -1,12 +1,12 @@ package mage.cards.l; -import mage.MageInt; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.keyword.DisturbAbility; -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.filter.StaticFilters; @@ -16,24 +16,39 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class LunarchVeteran extends CardImpl { +public final class LunarchVeteran extends TransformingDoubleFacedCard { public LunarchVeteran(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CLERIC}, "{W}", + "Luminous Phantom", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT, SubType.CLERIC}, "W" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.l.LuminousPhantom.class; + // Lunarch Veteran + this.getLeftHalfCard().setPT(1, 1); // Whenever another creature you control enters, you gain 1 life. - this.addAbility(new EntersBattlefieldControlledTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldControlledTriggeredAbility( new GainLifeEffect(1), StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE )); // Disturb {1}{W} - this.addAbility(new DisturbAbility(this, "{1}{W}")); + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{1}{W}")); + + // Luminous Phantom + this.getRightHalfCard().setPT(1, 1); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever another creature you control leaves the battlefield, you gain 1 life. + this.getRightHalfCard().addAbility(new LeavesBattlefieldAllTriggeredAbility( + new GainLifeEffect(1), StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL + )); + + // If Luminous Phantom would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private LunarchVeteran(final LunarchVeteran card) { diff --git a/Mage.Sets/src/mage/cards/l/LysAlanaInformant.java b/Mage.Sets/src/mage/cards/l/LysAlanaInformant.java new file mode 100644 index 00000000000..f631cd5e6b8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LysAlanaInformant.java @@ -0,0 +1,39 @@ + +package mage.cards.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldOrDiesSourceTriggeredAbility; +import mage.abilities.effects.keyword.SurveilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author muz + */ +public final class LysAlanaInformant extends CardImpl { + + public LysAlanaInformant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.SCOUT); + + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // When this creature enters or dies, surveil 1. + this.addAbility(new EntersBattlefieldOrDiesSourceTriggeredAbility(new SurveilEffect(1), false)); + } + + private LysAlanaInformant(final LysAlanaInformant card) { + super(card); + } + + @Override + public LysAlanaInformant copy() { + return new LysAlanaInformant(this); + } +} 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/MaladyInvoker.java b/Mage.Sets/src/mage/cards/m/MaladyInvoker.java deleted file mode 100644 index 3a6813d19d4..00000000000 --- a/Mage.Sets/src/mage/cards/m/MaladyInvoker.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; -import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue; -import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.target.common.TargetOpponentsCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class MaladyInvoker extends CardImpl { - - private static final DynamicValue xValue = new SignInversionDynamicValue(SourcePermanentPowerValue.NOT_NEGATIVE); - - public MaladyInvoker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.TREEFOLK); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.color.setGreen(true); - this.nightCard = true; - - // When this creature transforms into Malady Invoker, target creature an opponent controls gets -0/-X until end of turn, where X is Malady Invoker's power. - Ability ability = new TransformIntoSourceTriggeredAbility(new BoostTargetEffect( - StaticValue.get(0), xValue, Duration.EndOfTurn - ).setText("target creature an opponent controls gets -0/-X until end of turn, where X is {this}'s power")); - ability.addTarget(new TargetOpponentsCreaturePermanent()); - this.addAbility(ability); - } - - private MaladyInvoker(final MaladyInvoker card) { - super(card); - } - - @Override - public MaladyInvoker copy() { - return new MaladyInvoker(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MalevolentHermit.java b/Mage.Sets/src/mage/cards/m/MalevolentHermit.java index 85c609a4651..3ab9ba10c19 100644 --- a/Mage.Sets/src/mage/cards/m/MalevolentHermit.java +++ b/Mage.Sets/src/mage/cards/m/MalevolentHermit.java @@ -1,16 +1,19 @@ package mage.cards.m; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CantBeCounteredControlledEffect; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.abilities.keyword.DisturbAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; 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 mage.target.TargetSpell; @@ -20,16 +23,17 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class MalevolentHermit extends CardImpl { +public final class MalevolentHermit extends TransformingDoubleFacedCard { public MalevolentHermit(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.WIZARD}, "{1}{U}", + "Benevolent Geist", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT, SubType.WIZARD}, "U" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.b.BenevolentGeist.class; + // Malevolent Hermit + this.getLeftHalfCard().setPT(2, 1); // {U}, Sacrifice Malevolent Hermit: Counter target noncreature spell unless its controller pays {3}. Ability ability = new SimpleActivatedAbility( @@ -37,10 +41,24 @@ public final class MalevolentHermit extends CardImpl { ); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_NON_CREATURE)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Disturb {2}{U} - this.addAbility(new DisturbAbility(this, "{2}{U}")); + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{2}{U}")); + + // Benevolent Geist + this.getRightHalfCard().setPT(2, 2); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Noncreature spells you control can't be countered. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new CantBeCounteredControlledEffect( + StaticFilters.FILTER_SPELLS_NON_CREATURE, Duration.WhileOnBattlefield + ))); + + // If Benevolent Geist would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private MalevolentHermit(final MalevolentHermit card) { diff --git a/Mage.Sets/src/mage/cards/m/MaliciousInvader.java b/Mage.Sets/src/mage/cards/m/MaliciousInvader.java deleted file mode 100644 index a86263bc19f..00000000000 --- a/Mage.Sets/src/mage/cards/m/MaliciousInvader.java +++ /dev/null @@ -1,59 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.OpponentControlsPermanentCondition; -import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.hint.ConditionHint; -import mage.abilities.hint.Hint; -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.TargetController; -import mage.filter.FilterPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class MaliciousInvader extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent(SubType.HUMAN, "an opponent controls a Human"); - - private static final Condition condition = new OpponentControlsPermanentCondition(filter); - private static final Hint hint = new ConditionHint(condition, "An opponent controls a Human"); - - public MaliciousInvader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Malicious Invader gets +2/+0 as long as an opponent controls a Human. - this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( - new BoostSourceEffect(2, 0, Duration.WhileOnBattlefield), - condition, "{this} gets +2/+0 as long as an opponent controls a Human" - )).addHint(hint)); - } - - private MaliciousInvader(final MaliciousInvader card) { - super(card); - } - - @Override - public MaliciousInvader copy() { - return new MaliciousInvader(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MarchesaResoluteMonarch.java b/Mage.Sets/src/mage/cards/m/MarchesaResoluteMonarch.java deleted file mode 100644 index 37cea498d81..00000000000 --- a/Mage.Sets/src/mage/cards/m/MarchesaResoluteMonarch.java +++ /dev/null @@ -1,122 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.effects.common.counter.RemoveAllCountersPermanentTargetEffect; -import mage.abilities.keyword.DeathtouchAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -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.filter.StaticFilters; -import mage.game.Game; -import mage.game.events.DamagedEvent; -import mage.game.events.GameEvent; -import mage.target.TargetPermanent; -import mage.watchers.Watcher; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class MarchesaResoluteMonarch extends CardImpl { - - public MarchesaResoluteMonarch(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(3); - this.toughness = new MageInt(6); - this.color.setBlack(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Deathtouch - this.addAbility(DeathtouchAbility.getInstance()); - - // Whenever Marchesa, Resolute Monarch attacks, remove all counters from up to one target permanent. - Ability ability = new AttacksTriggeredAbility(new RemoveAllCountersPermanentTargetEffect()); - ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT)); - this.addAbility(ability); - - // At the beginning of your upkeep, if you haven't been dealt combat damage since your last turn, you draw a card and you lose 1 life. - ability = new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1, true)) - .withInterveningIf(MarchesaResoluteMonarchCondition.instance); - ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); - this.addAbility(ability); - } - - private MarchesaResoluteMonarch(final MarchesaResoluteMonarch card) { - super(card); - } - - @Override - public MarchesaResoluteMonarch copy() { - return new MarchesaResoluteMonarch(this); - } - - public static MarchesaResoluteMonarchWatcher makeWatcher() { - return new MarchesaResoluteMonarchWatcher(); - } -} - -enum MarchesaResoluteMonarchCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return MarchesaResoluteMonarchWatcher.checkPlayer(game, source); - } - - @Override - public String toString() { - return "you haven't been dealt combat damage since your last turn"; - } -} - -class MarchesaResoluteMonarchWatcher extends Watcher { - - private final Set players = new HashSet<>(); - - MarchesaResoluteMonarchWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - switch (event.getType()) { - case DAMAGED_PLAYER: - if (((DamagedEvent) event).isCombatDamage()) { - players.add(event.getTargetId()); - } - return; - case END_TURN_STEP_POST: - players.remove(game.getActivePlayerId()); - return; - - } - } - - static boolean checkPlayer(Game game, Ability source) { - return !game - .getState() - .getWatcher(MarchesaResoluteMonarchWatcher.class) - .players - .contains(source.getControllerId()); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MaskedVandal.java b/Mage.Sets/src/mage/cards/m/MaskedVandal.java index 8905b48c8ad..b609dc7371d 100644 --- a/Mage.Sets/src/mage/cards/m/MaskedVandal.java +++ b/Mage.Sets/src/mage/cards/m/MaskedVandal.java @@ -46,7 +46,7 @@ public final class MaskedVandal extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility( new DoIfCostPaid(new ExileTargetEffect(), new ExileFromGraveCost( new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_A) - )) + ).withSourceExileZone(false)) ); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); 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/MastersGuideMural.java b/Mage.Sets/src/mage/cards/m/MastersGuideMural.java index b53450a195c..47afffa7ba5 100644 --- a/Mage.Sets/src/mage/cards/m/MastersGuideMural.java +++ b/Mage.Sets/src/mage/cards/m/MastersGuideMural.java @@ -1,29 +1,56 @@ package mage.cards.m; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; import mage.abilities.keyword.CraftAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.WatcherScope; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.game.permanent.token.GolemWhiteBlueToken; +import mage.watchers.Watcher; -import java.util.UUID; +import java.util.*; /** * @author Susucr */ -public final class MastersGuideMural extends CardImpl { +public final class MastersGuideMural extends TransformingDoubleFacedCard { public MastersGuideMural(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}{W}{U}"); - this.secondSideCardClazz = mage.cards.m.MastersManufactory.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{3}{W}{U}", + "Master's Manufactory", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "WU" + ); + // Master's Guide-Mural // When Master's Guide-Mural enters the battlefield, create a 4/4 white and blue Golem artifact creature token. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemWhiteBlueToken()))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GolemWhiteBlueToken()))); // Craft with artifact {4}{W}{W}{U} - this.addAbility(new CraftAbility("{4}{W}{W}{U}")); + this.getLeftHalfCard().addAbility(new CraftAbility("{4}{W}{W}{U}")); + + // Master's Manufactory + // {T}: Create a 4/4 white and blue Golem artifact creature token. Activate only if Master's Manufactory or another artifact entered the battlefield under your control this turn. + Ability ability = new ActivateIfConditionActivatedAbility( + new CreateTokenEffect(new GolemWhiteBlueToken()), new TapSourceCost(), MastersManufactoryCondition.instance + ); + ability.addHint(MastersManufactoryCondition.getHint()); + ability.addWatcher(new MastersManufactoryWatcher()); + this.getRightHalfCard().addAbility(ability); } private MastersGuideMural(final MastersGuideMural card) { @@ -35,3 +62,60 @@ public final class MastersGuideMural extends CardImpl { return new MastersGuideMural(this); } } + +enum MastersManufactoryCondition 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) { + Permanent permanent = game.getPermanent(source.getSourceId()); + MastersManufactoryWatcher watcher = game.getState().getWatcher(MastersManufactoryWatcher.class); + return watcher != null && permanent != null + && watcher.check(source.getControllerId(), new MageObjectReference(permanent, game)); + } + + @Override + public String toString() { + return "{this} or another artifact entered the battlefield under your control this turn"; + } +} + +class MastersManufactoryWatcher extends Watcher { + + private final Set playerHadArtifactEnter = new HashSet<>(); + private final Map> allEnteredThisTurn = new HashMap<>(); + + MastersManufactoryWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent.isArtifact(game)) { + playerHadArtifactEnter.add(event.getPlayerId()); + } + allEnteredThisTurn + .computeIfAbsent(event.getPlayerId(), k -> new HashSet<>()) + .add(new MageObjectReference(permanent, game)); + } + } + + @Override + public void reset() { + super.reset(); + playerHadArtifactEnter.clear(); + allEnteredThisTurn.clear(); + } + + boolean check(UUID playerId, MageObjectReference mor) { + return playerHadArtifactEnter.contains(playerId) + || allEnteredThisTurn.getOrDefault(playerId, Collections.emptySet()).contains(mor); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MastersManufactory.java b/Mage.Sets/src/mage/cards/m/MastersManufactory.java deleted file mode 100644 index ed3f49799fa..00000000000 --- a/Mage.Sets/src/mage/cards/m/MastersManufactory.java +++ /dev/null @@ -1,112 +0,0 @@ -package mage.cards.m; - -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.common.CreateTokenEffect; -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.WatcherScope; -import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.permanent.token.GolemWhiteBlueToken; -import mage.watchers.Watcher; - -import java.util.*; - -/** - * @author Susucr - */ -public final class MastersManufactory extends CardImpl { - - public MastersManufactory(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - this.nightCard = true; - this.color.setBlue(true); - this.color.setWhite(true); - - // {T}: Create a 4/4 white and blue Golem artifact creature token. Activate only if Master's Manufactory or another artifact entered the battlefield under your control this turn. - this.addAbility(new ActivateIfConditionActivatedAbility( - new CreateTokenEffect(new GolemWhiteBlueToken()), - new TapSourceCost(), MastersManufactoryCondition.instance - ).addHint(MastersManufactoryCondition.getHint()), new MastersManufactoryWatcher()); - } - - private MastersManufactory(final MastersManufactory card) { - super(card); - } - - @Override - public MastersManufactory copy() { - return new MastersManufactory(this); - } -} - -enum MastersManufactoryCondition 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) { - Permanent permanent = game.getPermanent(source.getSourceId()); - MastersManufactoryWatcher watcher = game.getState().getWatcher(MastersManufactoryWatcher.class); - return watcher != null && permanent != null - && watcher.check(source.getControllerId(), new MageObjectReference(permanent, game)); - } - - @Override - public String toString() { - return "{this} or another artifact entered the battlefield under your control this turn"; - } -} - -class MastersManufactoryWatcher extends Watcher { - - // player -> an artifact entered this turn - private final Set playerHadArtifactEnter = new HashSet<>(); - // We need to store a lot for edges cases: - // -> Master's Manufactory could have entered as a non-artifact - // -> Another permanent could gain Manufactory's ability (copy effect), and we need to have tracked if it entered - // player -> set of all MOR of permanents that entered this turn under that player's control - private final Map> allEnteredThisTurn = new HashMap<>(); - - MastersManufactoryWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) { - Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); - if (permanent.isArtifact(game)) { - playerHadArtifactEnter.add(event.getPlayerId()); - } - allEnteredThisTurn - .computeIfAbsent(event.getPlayerId(), k -> new HashSet<>()) - .add(new MageObjectReference(permanent, game)); - } - } - - @Override - public void reset() { - super.reset(); - playerHadArtifactEnter.clear(); - allEnteredThisTurn.clear(); - } - - boolean check(UUID playerId, MageObjectReference mor) { - return playerHadArtifactEnter.contains(playerId) - || allEnteredThisTurn.getOrDefault(playerId, Collections.emptySet()).contains(mor); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MatzalantliTheGreatDoor.java b/Mage.Sets/src/mage/cards/m/MatzalantliTheGreatDoor.java index 04f0ff0b214..2bd9cba7af3 100644 --- a/Mage.Sets/src/mage/cards/m/MatzalantliTheGreatDoor.java +++ b/Mage.Sets/src/mage/cards/m/MatzalantliTheGreatDoor.java @@ -1,23 +1,25 @@ package mage.cards.m; +import mage.Mana; import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.IntCompareCondition; +import mage.abilities.condition.common.DescendCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.DynamicManaAbility; 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.StaticFilters; import mage.game.Game; import mage.players.Player; @@ -28,29 +30,40 @@ import java.util.stream.Collectors; /** * @author Susucr */ -public final class MatzalantliTheGreatDoor extends CardImpl { +public final class MatzalantliTheGreatDoor extends TransformingDoubleFacedCard { private static final Hint hint = new ValueHint("Permanent types in graveyard", MatzalantliTheGreatDoorValue.instance); + private static final DynamicValue xValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_PERMANENT); public MatzalantliTheGreatDoor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); - this.secondSideCardClazz = mage.cards.t.TheCore.class; - - this.supertype.add(SuperType.LEGENDARY); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{3}", + "The Core", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Matzalantli, the Great Door // {T}: Draw a card, then discard a card. - this.addAbility(new SimpleActivatedAbility(new DrawDiscardControllerEffect(), new TapSourceCost())); + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility(new DrawDiscardControllerEffect(), new TapSourceCost())); // {4}, {T}: Transform Matzalantli, the Great Door. Activate only if there are four or more permanent types among cards in your graveyard. - this.addAbility(new TransformAbility()); Ability ability = new ActivateIfConditionActivatedAbility( - new TransformSourceEffect(), - new GenericManaCost(4), - new MatzalantliTheGreatDoorCondition() + new TransformSourceEffect(), new GenericManaCost(4), new MatzalantliTheGreatDoorCondition() ); ability.addCost(new TapSourceCost()); ability.addHint(hint); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // The Core + // Fathomless descent -- {T}: Add X mana of any one color, where X is the number of permanent cards in your graveyard. + this.getRightHalfCard().addSuperType(SuperType.LEGENDARY); + Ability manaAbility = new DynamicManaAbility( + Mana.AnyMana(1), xValue, new TapSourceCost(), + "Add X mana of any one color, where X is the number of permanent cards in your graveyard.", true + ); + manaAbility.setAbilityWord(AbilityWord.FATHOMLESS_DESCENT); + manaAbility.addHint(DescendCondition.getHint()); + this.getRightHalfCard().addAbility(manaAbility); } private MatzalantliTheGreatDoor(final MatzalantliTheGreatDoor card) { @@ -83,9 +96,6 @@ class MatzalantliTheGreatDoorCondition extends IntCompareCondition { enum MatzalantliTheGreatDoorValue implements DynamicValue { instance; - MatzalantliTheGreatDoorValue() { - } - @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { Player controller = game.getPlayer(sourceAbility.getControllerId()); diff --git a/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java b/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java index f9f11c93350..460350bce16 100644 --- a/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java +++ b/Mage.Sets/src/mage/cards/m/MayorOfAvabruck.java @@ -1,49 +1,66 @@ package mage.cards.m; -import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -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.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.game.permanent.token.WolfToken; import java.util.UUID; /** * @author North, noxx */ -public final class MayorOfAvabruck extends CardImpl { +public final class MayorOfAvabruck extends TransformingDoubleFacedCard { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Human creatures"); + private static final FilterCreaturePermanent howlpackFilter = new FilterCreaturePermanent("each other creature you control that's a Werewolf or a Wolf"); static { filter.add(SubType.HUMAN.getPredicate()); + howlpackFilter.add(Predicates.or(SubType.WEREWOLF.getPredicate(), SubType.WOLF.getPredicate())); } public MayorOfAvabruck(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ADVISOR); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ADVISOR, SubType.WEREWOLF}, "{1}{G}", + "Howlpack Alpha", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G" + ); - this.secondSideCardClazz = mage.cards.h.HowlpackAlpha.class; - - this.power = new MageInt(1); - this.toughness = new MageInt(1); + // Mayor of Avabruck + this.getLeftHalfCard().setPT(1, 1); // Other Human creatures you control get +1/+1. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect( 1, 1, Duration.WhileOnBattlefield, filter, true ))); // At the beginning of each upkeep, if no spells were cast last turn, transform Mayor of Avabruck. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Howlpack Alpha + this.getRightHalfCard().setPT(3, 3); + + // Other Werewolf and Wolf creatures you control get +1/+1. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostControlledEffect( + 1, 1, Duration.WhileOnBattlefield, howlpackFilter, true + ))); + + // At the beginning of your end step, create a 2/2 green Wolf creature token. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new WolfToken()))); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Howlpack Alpha. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private MayorOfAvabruck(final MayorOfAvabruck card) { 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/MeekAttack.java b/Mage.Sets/src/mage/cards/m/MeekAttack.java new file mode 100644 index 00000000000..559dcc60db5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MeekAttack.java @@ -0,0 +1,55 @@ +package mage.cards.m; + +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.PutCardIntoPlayWithHasteAndSacrificeEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicate; +import mage.game.Game; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MeekAttack extends CardImpl { + + private static final FilterCard filter = new FilterCreatureCard("creature card with total power and toughness 5 or less"); + + static { + filter.add(MeekAttackPredicate.instance); + } + + public MeekAttack(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + + // {1}{R}: You may put a creature card with total power and toughness 5 or less from your hand onto the battlefield. That creature gains haste. At the beginning of the next end step, sacrifice that creature. + this.addAbility(new SimpleActivatedAbility(new PutCardIntoPlayWithHasteAndSacrificeEffect( + filter, Duration.Custom, "That creature", "the creature" + ), new ManaCostsImpl<>("{1}{R}"))); + } + + private MeekAttack(final MeekAttack card) { + super(card); + } + + @Override + public MeekAttack copy() { + return new MeekAttack(this); + } +} + +enum MeekAttackPredicate implements Predicate { + instance; + + @Override + public boolean apply(Card input, Game game) { + return input.getToughness().getValue() + input.getPower().getValue() <= 5; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MegatronDestructiveForce.java b/Mage.Sets/src/mage/cards/m/MegatronDestructiveForce.java deleted file mode 100644 index 7b718d6efbd..00000000000 --- a/Mage.Sets/src/mage/cards/m/MegatronDestructiveForce.java +++ /dev/null @@ -1,147 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.delayed.ReflexiveTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.hint.StaticHint; -import mage.abilities.keyword.LivingMetalAbility; -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.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; -import mage.target.common.TargetSacrifice; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class MegatronDestructiveForce extends CardImpl { - public MegatronDestructiveForce(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(5); - this.color.setRed(true); - this.color.setWhite(true); - this.color.setBlack(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Whenever Megatron attacks, you may sacrifice another artifact. When you do, Megatron deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert Megatron. - this.addAbility(new AttacksTriggeredAbility(new MegatronDestructiveForceEffect())); - } - - private MegatronDestructiveForce(final MegatronDestructiveForce card) { - super(card); - } - - @Override - public MegatronDestructiveForce copy() { - return new MegatronDestructiveForce(this); - } -} - -class MegatronDestructiveForceEffect extends OneShotEffect { - - MegatronDestructiveForceEffect() { - super(Outcome.Benefit); - staticText = "you may sacrifice another artifact. When you do, {this} deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert {this}."; - } - - private MegatronDestructiveForceEffect(final MegatronDestructiveForceEffect effect) { - super(effect); - } - - @Override - public MegatronDestructiveForceEffect copy() { - return new MegatronDestructiveForceEffect(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, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_ARTIFACT - ); - player.choose(outcome, target, source, game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent == null) { - return false; - } - - int manaValue = Math.max(permanent.getManaValue(), 0); - if (!permanent.sacrifice(source, game)) { - return false; - } - - ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( - new MegatronDestructiveForceReflexiveEffect(manaValue), false - ); - ability.addHint(new StaticHint("Sacrificed artifact mana value: " + manaValue)); - ability.addTarget(new TargetCreaturePermanent()); - game.fireReflexiveTriggeredAbility(ability, source); - return true; - } -} - -class MegatronDestructiveForceReflexiveEffect extends OneShotEffect { - - private final int value; - - MegatronDestructiveForceReflexiveEffect(int value) { - super(Outcome.Damage); - staticText = "{this} deals damage equal to the sacrificed artifact's mana value to target " + - "creature. If excess damage would be dealt to that creature this way, instead that damage " + - "is dealt to that creature's controller and you convert {this}."; - this.value = value; - } - - private MegatronDestructiveForceReflexiveEffect(final MegatronDestructiveForceReflexiveEffect effect) { - super(effect); - this.value = effect.value; - } - - @Override - public MegatronDestructiveForceReflexiveEffect copy() { - return new MegatronDestructiveForceReflexiveEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (value < 1) { - return false; - } - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent == null) { - return false; - } - int excess = permanent.damageWithExcess(value, source, game); - if (excess < 1) { - return true; - } - Player player = game.getPlayer(permanent.getControllerId()); - if (player != null) { - player.damage(excess, source, game); - } - new TransformSourceEffect().apply(game, source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MegatronTyrant.java b/Mage.Sets/src/mage/cards/m/MegatronTyrant.java index 967a92f1f22..93aabd1b4a5 100644 --- a/Mage.Sets/src/mage/cards/m/MegatronTyrant.java +++ b/Mage.Sets/src/mage/cards/m/MegatronTyrant.java @@ -1,44 +1,54 @@ package mage.cards.m; -import mage.MageInt; import mage.MageObject; import mage.Mana; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; -import mage.abilities.triggers.BeginningOfPostcombatMainTriggeredAbility; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.dynamicvalue.common.OpponentsLostLifeCount; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.mana.DynamicManaEffect; +import mage.abilities.hint.StaticHint; +import mage.abilities.keyword.LivingMetalAbility; import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfPostcombatMainTriggeredAbility; 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.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; /** * @author Susucr */ -public final class MegatronTyrant extends CardImpl { +public final class MegatronTyrant extends TransformingDoubleFacedCard { public MegatronTyrant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{R}{W}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{3}{R}{W}{B}", + "Megatron, Destructive Force", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "RWB" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(7); - this.toughness = new MageInt(5); - this.secondSideCardClazz = mage.cards.m.MegatronDestructiveForce.class; + // Megatron, Tyrant + this.getLeftHalfCard().setPT(7, 5); // More Than Meets the Eye {1}{R}{W}{B} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{1}{R}{W}{B}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{1}{R}{W}{B}")); // Your opponents can't cast spells during combat. - this.addAbility(new SimpleStaticAbility(new MegatronTyrantCantCastSpellsEffect())); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new MegatronTyrantCantCastSpellsEffect())); // At the beginning of your postcombat main phase, you may convert Megatron. If you do, add {C} for each 1 life your opponents have lost this turn. TriggeredAbility trigger = new BeginningOfPostcombatMainTriggeredAbility( @@ -46,14 +56,22 @@ public final class MegatronTyrant extends CardImpl { true ); trigger.addEffect( - new DynamicManaEffect( - Mana.ColorlessMana(1), - OpponentsLostLifeCount.instance, - "add {C} for each 1 life your opponents have lost this turn" - ).concatBy("If you do,") + new DynamicManaEffect( + Mana.ColorlessMana(1), + OpponentsLostLifeCount.instance, + "add {C} for each 1 life your opponents have lost this turn" + ).concatBy("If you do,") ); + this.getLeftHalfCard().addAbility(trigger); - this.addAbility(trigger); + // Megatron, Destructive Force + this.getRightHalfCard().setPT(4, 5); + + // Living Metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Whenever Megatron attacks, you may sacrifice another artifact. When you do, Megatron deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert Megatron. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new MegatronDestructiveForceEffect())); } private MegatronTyrant(final MegatronTyrant card) { @@ -99,7 +117,98 @@ class MegatronTyrantCantCastSpellsEffect extends ContinuousRuleModifyingEffectIm @Override public boolean applies(GameEvent event, Ability source, Game game) { return game.getOpponents(source.getControllerId()).contains(event.getPlayerId()) - && game.getTurnPhaseType() == TurnPhase.COMBAT; + && game.getTurnPhaseType() == TurnPhase.COMBAT; + } +} + +class MegatronDestructiveForceEffect extends OneShotEffect { + + MegatronDestructiveForceEffect() { + super(Outcome.Benefit); + staticText = "you may sacrifice another artifact. When you do, {this} deals damage equal to the sacrificed artifact's mana value " + + "to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller " + + "and you convert {this}."; } + private MegatronDestructiveForceEffect(final MegatronDestructiveForceEffect effect) { + super(effect); + } + + @Override + public MegatronDestructiveForceEffect copy() { + return new MegatronDestructiveForceEffect(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, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_ARTIFACT + ); + player.choose(outcome, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent == null) { + return false; + } + + int manaValue = Math.max(permanent.getManaValue(), 0); + if (!permanent.sacrifice(source, game)) { + return false; + } + + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new MegatronDestructiveForceReflexiveEffect(manaValue), false + ); + ability.addHint(new StaticHint("Sacrificed artifact mana value: " + manaValue)); + ability.addTarget(new TargetCreaturePermanent()); + game.fireReflexiveTriggeredAbility(ability, source); + return true; + } +} + +class MegatronDestructiveForceReflexiveEffect extends OneShotEffect { + + private final int value; + + MegatronDestructiveForceReflexiveEffect(int value) { + super(Outcome.Damage); + staticText = "{this} deals damage equal to the sacrificed artifact's mana value to target " + + "creature. If excess damage would be dealt to that creature this way, instead that damage " + + "is dealt to that creature's controller and you convert {this}."; + this.value = value; + } + + private MegatronDestructiveForceReflexiveEffect(final MegatronDestructiveForceReflexiveEffect effect) { + super(effect); + this.value = effect.value; + } + + @Override + public MegatronDestructiveForceReflexiveEffect copy() { + return new MegatronDestructiveForceReflexiveEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (value < 1) { + return false; + } + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent == null) { + return false; + } + int excess = permanent.damageWithExcess(value, source, game); + if (excess < 1) { + return true; + } + Player player = game.getPlayer(permanent.getControllerId()); + if (player != null) { + player.damage(excess, source, game); + } + new TransformSourceEffect().apply(game, source); + return true; + } } diff --git a/Mage.Sets/src/mage/cards/m/MeltstridersResolve.java b/Mage.Sets/src/mage/cards/m/MeltstridersResolve.java index 88fbff5be93..20a88112d62 100644 --- a/Mage.Sets/src/mage/cards/m/MeltstridersResolve.java +++ b/Mage.Sets/src/mage/cards/m/MeltstridersResolve.java @@ -3,8 +3,8 @@ package mage.cards.m; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.FightEnchantedTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneAttachedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; @@ -14,13 +14,10 @@ import mage.constants.AttachmentType; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent; -import java.util.Optional; import java.util.UUID; /** @@ -40,7 +37,7 @@ public final class MeltstridersResolve extends CardImpl { this.addAbility(new EnchantAbility(auraTarget)); // When this Aura enters, enchanted creature fights up to one target creature an opponent controls. - Ability ability = new EntersBattlefieldTriggeredAbility(new MeltstridersResolveEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility(new FightEnchantedTargetEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent(0, 1)); this.addAbility(ability); @@ -60,31 +57,3 @@ public final class MeltstridersResolve extends CardImpl { return new MeltstridersResolve(this); } } - -class MeltstridersResolveEffect extends OneShotEffect { - - MeltstridersResolveEffect() { - super(Outcome.Benefit); - staticText = "enchanted creature fights up to one target creature an opponent controls"; - } - - private MeltstridersResolveEffect(final MeltstridersResolveEffect effect) { - super(effect); - } - - @Override - public MeltstridersResolveEffect copy() { - return new MeltstridersResolveEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = Optional - .ofNullable(source.getSourcePermanentOrLKI(game)) - .map(Permanent::getAttachedTo) - .map(game::getPermanent) - .orElse(null); - Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); - return permanent != null && creature != null && permanent.fight(creature, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MemoryOfToshiro.java b/Mage.Sets/src/mage/cards/m/MemoryOfToshiro.java deleted file mode 100644 index 31ad7b29957..00000000000 --- a/Mage.Sets/src/mage/cards/m/MemoryOfToshiro.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.costs.common.PayLifeCost; -import mage.abilities.mana.ConditionalColoredManaAbility; -import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder; -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 MemoryOfToshiro extends CardImpl { - - public MemoryOfToshiro(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(2); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // {T}, Pay 1 life: Add {B}. Spend this mana only to cast an instant or sorcery spell. - Ability ability = new ConditionalColoredManaAbility(Mana.BlackMana(1), new InstantOrSorcerySpellManaBuilder()); - ability.addCost(new PayLifeCost(1)); - this.addAbility(ability); - } - - private MemoryOfToshiro(final MemoryOfToshiro card) { - super(card); - } - - @Override - public MemoryOfToshiro copy() { - return new MemoryOfToshiro(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MercilessPredator.java b/Mage.Sets/src/mage/cards/m/MercilessPredator.java deleted file mode 100644 index 9ea43ac8cd2..00000000000 --- a/Mage.Sets/src/mage/cards/m/MercilessPredator.java +++ /dev/null @@ -1,40 +0,0 @@ -package mage.cards.m; - -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 MercilessPredator extends CardImpl { - - public MercilessPredator(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(2); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Merciless Predator. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private MercilessPredator(final MercilessPredator card) { - super(card); - } - - @Override - public MercilessPredator copy() { - return new MercilessPredator(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MerrowSkyswimmer.java b/Mage.Sets/src/mage/cards/m/MerrowSkyswimmer.java new file mode 100644 index 00000000000..66e1485292e --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MerrowSkyswimmer.java @@ -0,0 +1,51 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.ConvokeAbility; +import mage.abilities.keyword.FlyingAbility; +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.MerfolkWhiteBlueToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MerrowSkyswimmer extends CardImpl { + + public MerrowSkyswimmer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W/U}{W/U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // When this creature enters, create a 1/1 white and blue Merfolk creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MerfolkWhiteBlueToken()))); + } + + private MerrowSkyswimmer(final MerrowSkyswimmer card) { + super(card); + } + + @Override + public MerrowSkyswimmer copy() { + return new MerrowSkyswimmer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java b/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java deleted file mode 100644 index 8ff50743a8a..00000000000 --- a/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java +++ /dev/null @@ -1,92 +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.OneShotEffect; -import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SuperType; -import mage.constants.TargetController; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.util.RandomUtil; -import mage.watchers.common.AttackedThisTurnWatcher; - -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; - -/** - * @author LevelX2 - */ -public final class MetzaliTowerOfTriumph extends CardImpl { - - public MetzaliTowerOfTriumph(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.nightCard = true; - - // (Transforms from Path of Mettle.) - - // {t}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); - - // {1}{R}, {T}: Metzali, Tower of Triumph deals 2 damage to each opponent. - Ability ability = new SimpleActivatedAbility(new DamagePlayersEffect(2, TargetController.OPPONENT), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - - // {2}{W}, {T}: Choose a creature at random that attacked this turn. Destroy that creature. - ability = new SimpleActivatedAbility(new MetzaliTowerOfTriumphEffect(), new ManaCostsImpl<>("{2}{W}")); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private MetzaliTowerOfTriumph(final MetzaliTowerOfTriumph card) { - super(card); - } - - @Override - public MetzaliTowerOfTriumph copy() { - return new MetzaliTowerOfTriumph(this); - } - -} - -class MetzaliTowerOfTriumphEffect extends OneShotEffect { - - MetzaliTowerOfTriumphEffect() { - super(Outcome.DestroyPermanent); - this.staticText = "choose a creature at random that attacked this turn. Destroy that creature"; - } - - private MetzaliTowerOfTriumphEffect(final MetzaliTowerOfTriumphEffect effect) { - super(effect); - } - - @Override - public MetzaliTowerOfTriumphEffect copy() { - return new MetzaliTowerOfTriumphEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = RandomUtil.randomFromCollection( - game.getState() - .getWatcher(AttackedThisTurnWatcher.class) - .getAttackedThisTurnCreatures() - .stream() - .map(mor -> mor.getPermanent(game)) - .filter(Objects::nonNull) - .collect(Collectors.toSet()) - ); - return permanent != null && permanent.destroy(source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MichelangeloOnTheScene.java b/Mage.Sets/src/mage/cards/m/MichelangeloOnTheScene.java new file mode 100644 index 00000000000..90f5e9ec789 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MichelangeloOnTheScene.java @@ -0,0 +1,55 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.dynamicvalue.common.LandsYouControlCount; +import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.hint.common.LandsYouControlHint; +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 mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MichelangeloOnTheScene extends CardImpl { + + public MichelangeloOnTheScene(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.MUTANT); + this.subtype.add(SubType.NINJA); + this.subtype.add(SubType.TURTLE); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Michelangelo enters with a +1/+1 counter on him for each land you control. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect( + CounterType.P1P1.createInstance(0), LandsYouControlCount.instance + ), "with a +1/+1 counter on him for each land you control").addHint(LandsYouControlHint.instance)); + + // When Michelangelo dies, return this card to your hand. + this.addAbility(new DiesSourceTriggeredAbility(new ReturnSourceFromGraveyardToHandEffect())); + } + + private MichelangeloOnTheScene(final MichelangeloOnTheScene card) { + super(card); + } + + @Override + public MichelangeloOnTheScene copy() { + return new MichelangeloOnTheScene(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MichikosReignOfTruth.java b/Mage.Sets/src/mage/cards/m/MichikosReignOfTruth.java index 5bd75ba5f7c..1dafc0881e8 100644 --- a/Mage.Sets/src/mage/cards/m/MichikosReignOfTruth.java +++ b/Mage.Sets/src/mage/cards/m/MichikosReignOfTruth.java @@ -1,13 +1,14 @@ package mage.cards.m; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; 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.Duration; import mage.constants.SagaChapter; @@ -20,24 +21,26 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class MichikosReignOfTruth extends CardImpl { +public final class MichikosReignOfTruth extends TransformingDoubleFacedCard { private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( StaticFilters.FILTER_PERMANENT_CONTROLLED_ARTIFACT_OR_ENCHANTMENT ); public MichikosReignOfTruth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); - - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.p.PortraitOfMichiko.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{1}{W}", + "Portrait of Michiko", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.NOBLE}, "W" + ); + // Michiko's Reign of Truth // (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 — Target creature gets +1/+1 until end of turn for each artifact and/or enchantment you control. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn) .setText("target creature gets +1/+1 until end of turn " + "for each artifact and/or enchantment you control"), @@ -45,10 +48,16 @@ public final class MichikosReignOfTruth 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.getLeftHalfCard().addAbility(sagaAbility); - this.addAbility(sagaAbility); + // Portrait of Michiko + this.getRightHalfCard().setPT(0, 0); + + // Portrait of Michiko gets +1/+1 for each artifact and/or enchantment you control. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new BoostSourceEffect(xValue, xValue, Duration.WhileOnBattlefield) + .setText("{this} gets +1/+1 for each artifact and/or enchantment you control")) + ); } private MichikosReignOfTruth(final MichikosReignOfTruth card) { diff --git a/Mage.Sets/src/mage/cards/m/MidnightTilling.java b/Mage.Sets/src/mage/cards/m/MidnightTilling.java new file mode 100644 index 00000000000..e32478776af --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MidnightTilling.java @@ -0,0 +1,31 @@ +package mage.cards.m; + +import mage.abilities.effects.common.MillThenPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MidnightTilling extends CardImpl { + + public MidnightTilling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Mill four cards, then you may return a permanent card from among them to your hand. + this.getSpellAbility().addEffect(new MillThenPutInHandEffect(4, StaticFilters.FILTER_CARD_PERMANENT)); + } + + private MidnightTilling(final MidnightTilling card) { + super(card); + } + + @Override + public MidnightTilling copy() { + return new MidnightTilling(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/Mirrorform.java b/Mage.Sets/src/mage/cards/m/Mirrorform.java new file mode 100644 index 00000000000..2dfc98dae2a --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/Mirrorform.java @@ -0,0 +1,79 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +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.StaticFilters; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.functions.EmptyCopyApplier; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Mirrorform extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("non-Aura permanent"); + + static { + filter.add(Predicates.not(SubType.AURA.getPredicate())); + } + + public Mirrorform(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}{U}"); + + // Each nonland permanent you control becomes a copy of target non-Aura permanent. + this.getSpellAbility().addEffect(new MirrorformEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + private Mirrorform(final Mirrorform card) { + super(card); + } + + @Override + public Mirrorform copy() { + return new Mirrorform(this); + } +} + +class MirrorformEffect extends OneShotEffect { + + MirrorformEffect() { + super(Outcome.Benefit); + staticText = "each nonland permanent you control becomes a copy of target non-Aura permanent"; + } + + private MirrorformEffect(final MirrorformEffect effect) { + super(effect); + } + + @Override + public MirrorformEffect copy() { + return new MirrorformEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (targetPermanent == null) { + return false; + } + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND, + source.getControllerId(), source, game + )) { + game.copyPermanent(targetPermanent, permanent.getId(), source, new EmptyCopyApplier()); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/m/MirrorhallMimic.java b/Mage.Sets/src/mage/cards/m/MirrorhallMimic.java index b067aeded81..16b91dec7da 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorhallMimic.java +++ b/Mage.Sets/src/mage/cards/m/MirrorhallMimic.java @@ -1,18 +1,26 @@ package mage.cards.m; -import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.CopyPermanentEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.DisturbAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; 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.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; import mage.util.functions.CopyApplier; import java.util.UUID; @@ -20,24 +28,40 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class MirrorhallMimic extends CardImpl { +public final class MirrorhallMimic extends TransformingDoubleFacedCard { public MirrorhallMimic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT}, "{3}{U}", + "Ghastly Mimicry", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "U" + ); - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.secondSideCardClazz = mage.cards.g.GhastlyMimicry.class; + // Mirrorhall Mimic + this.getLeftHalfCard().setPT(0, 0); // You may have Mirrorhall Mimic enter the battlefield as a copy of any creature on the battlefield, except it's a Spirit in addition to its other types. - this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect( + this.getLeftHalfCard().addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect( StaticFilters.FILTER_PERMANENT_CREATURE, new MirrorhallMimicApplier() - ), true, null, "You may have {this} enter the battlefield as a copy of " - + "any creature on the battlefield, except it's a Spirit in addition to its other types.", null)); + ), true, null, "You may have {this} enter as a copy of any creature on the battlefield, except it's a Spirit in addition to its other types.", null)); + + + // Ghastly Mimicry + // 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)); // Disturb {3}{U}{U} - this.addAbility(new DisturbAbility(this, "{3}{U}{U}")); + // needs to be added after enchant ability is set for target + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{3}{U}{U}")); + + // At the beginning of your upkeep, create a token that's a copy of enchanted creature, except it's a Spirit in addition to its other types. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new GhastlyMimicryEffect())); + + // If Ghastly Mimicry would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private MirrorhallMimic(final MirrorhallMimic card) { @@ -58,3 +82,36 @@ class MirrorhallMimicApplier extends CopyApplier { return true; } } + +class GhastlyMimicryEffect extends OneShotEffect { + + GhastlyMimicryEffect() { + super(Outcome.Benefit); + staticText = "create a token that's a copy of enchanted creature, " + + "except it's a Spirit in addition to its other types"; + } + + private GhastlyMimicryEffect(final GhastlyMimicryEffect effect) { + super(effect); + } + + @Override + public GhastlyMimicryEffect copy() { + return new GhastlyMimicryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentOrLKI(game); + if (permanent == null) { + return false; + } + Permanent attached = game.getPermanent(permanent.getAttachedTo()); + if (attached == null) { + return false; + } + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); + effect.withAdditionalSubType(SubType.SPIRIT); + return effect.setTargetPointer(new FixedTarget(attached, game)).apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MischievousCatgeist.java b/Mage.Sets/src/mage/cards/m/MischievousCatgeist.java index 2f3a7ac6a8f..6071a0a11a1 100644 --- a/Mage.Sets/src/mage/cards/m/MischievousCatgeist.java +++ b/Mage.Sets/src/mage/cards/m/MischievousCatgeist.java @@ -1,38 +1,64 @@ package mage.cards.m; -import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.DisturbAbility; -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 MischievousCatgeist extends CardImpl { +public final class MischievousCatgeist extends TransformingDoubleFacedCard { public MischievousCatgeist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.CAT, SubType.SPIRIT}, "{1}{U}", + "Catlike Curiosity", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "U" + ); - this.subtype.add(SubType.CAT); - this.subtype.add(SubType.SPIRIT); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.c.CatlikeCuriosity.class; + // Mischievous Catgeist + this.getLeftHalfCard().setPT(1, 1); // Whenever Mischievous Catgeist deals combat damage to a player, draw card. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( + this.getLeftHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility( new DrawCardSourceControllerEffect(1), false )); + + // Catlike Curiosity + // 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)); + // Disturb {2}{U} - this.addAbility(new DisturbAbility(this, "{2}{U}")); + // needs to be added after enchant ability is set for target + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{2}{U}")); + + // Enchanted creature has "Whenever this creature deals combat damage to a player, draw a card." + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + new DealsCombatDamageToAPlayerTriggeredAbility( + new DrawCardSourceControllerEffect(1), false + ).setTriggerPhrase("Whenever this creature deals combat damage to a player, "), AttachmentType.AURA + ))); + + // If Catlike Curiosity would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private MischievousCatgeist(final MischievousCatgeist card) { 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/MoiraAndTeshar.java b/Mage.Sets/src/mage/cards/m/MoiraAndTeshar.java index 7af8132d513..6de25477cd8 100644 --- a/Mage.Sets/src/mage/cards/m/MoiraAndTeshar.java +++ b/Mage.Sets/src/mage/cards/m/MoiraAndTeshar.java @@ -18,6 +18,7 @@ import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -32,6 +33,10 @@ public final class MoiraAndTeshar extends CardImpl { private static final FilterPermanentCard targetFilter = new FilterPermanentCard( "nonland permanent card from your graveyard"); + static { + targetFilter.add(Predicates.not(CardType.LAND.getPredicate())); + } + public MoiraAndTeshar(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{B}"); 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/MoltenExhale.java b/Mage.Sets/src/mage/cards/m/MoltenExhale.java index 723885c7f30..f9022131811 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenExhale.java +++ b/Mage.Sets/src/mage/cards/m/MoltenExhale.java @@ -2,14 +2,12 @@ package mage.cards.m; import mage.abilities.Ability; import mage.abilities.common.PayMoreToCastAsThoughtItHadFlashAbility; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.abilities.costs.CostsImpl; -import mage.abilities.costs.common.BeholdDragonCost; +import mage.abilities.costs.common.BeholdCost; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.Target; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -25,7 +23,7 @@ public final class MoltenExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}"); // You may cast this spell as though it had flash if you behold a Dragon as an additional cost to cast it. - Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new BeholdDragonCost(), + Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new BeholdCost(BeholdType.DRAGON), "you may cast this spell as though it had flash if you behold a Dragon as an additional cost to cast it."); Target target = new TargetCreatureOrPlaneswalker(); Effect effect = new DamageTargetEffect(4); diff --git a/Mage.Sets/src/mage/cards/m/MondronenShaman.java b/Mage.Sets/src/mage/cards/m/MondronenShaman.java index 8683524fe7d..dca147c4d8d 100644 --- a/Mage.Sets/src/mage/cards/m/MondronenShaman.java +++ b/Mage.Sets/src/mage/cards/m/MondronenShaman.java @@ -1,34 +1,48 @@ package mage.cards.m; -import mage.MageInt; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.common.WerewolfBackTriggeredAbility; import mage.abilities.common.WerewolfFrontTriggeredAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.SetTargetPointer; import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.StaticFilters; import java.util.UUID; /** * @author North */ -public final class MondronenShaman extends CardImpl { +public final class MondronenShaman extends TransformingDoubleFacedCard { public MondronenShaman(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); - 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}, "{3}{R}", + "Tovolar's Magehunter", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - - this.secondSideCardClazz = mage.cards.t.TovolarsMagehunter.class; + // Mondronen Shaman + this.getLeftHalfCard().setPT(3, 2); // At the beginning of each upkeep, if no spells were cast last turn, transform Mondronen Shaman. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Tovolar's Magehunter + this.getRightHalfCard().setPT(5, 5); + + // Whenever an opponent casts a spell, Tovolar's Magehunter deals 2 damage to that player. + this.getRightHalfCard().addAbility(new SpellCastOpponentTriggeredAbility( + Zone.BATTLEFIELD, new DamageTargetEffect(2).withTargetDescription("that player"), + StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.PLAYER + )); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Tovolar's Magehunter. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private MondronenShaman(final MondronenShaman card) { 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/MoongloveExtractor.java b/Mage.Sets/src/mage/cards/m/MoongloveExtractor.java new file mode 100644 index 00000000000..1b41db59302 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MoongloveExtractor.java @@ -0,0 +1,42 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +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 MoongloveExtractor extends CardImpl { + + public MoongloveExtractor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Whenever this creature attacks, you draw a card and lose 1 life. + Ability ability = new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1)); + ability.addEffect(new LoseLifeSourceControllerEffect(1).setText("and lose 1 life")); + this.addAbility(ability); + } + + private MoongloveExtractor(final MoongloveExtractor card) { + super(card); + } + + @Override + public MoongloveExtractor copy() { + return new MoongloveExtractor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MoonlitAmbusher.java b/Mage.Sets/src/mage/cards/m/MoonlitAmbusher.java deleted file mode 100644 index ee33eed54c2..00000000000 --- a/Mage.Sets/src/mage/cards/m/MoonlitAmbusher.java +++ /dev/null @@ -1,38 +0,0 @@ -package mage.cards.m; - -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 MoonlitAmbusher extends CardImpl { - - public MoonlitAmbusher(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(3); - this.color.setGreen(true); - this.nightCard = true; - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private MoonlitAmbusher(final MoonlitAmbusher card) { - super(card); - } - - @Override - public MoonlitAmbusher copy() { - return new MoonlitAmbusher(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/MorningApparition.java b/Mage.Sets/src/mage/cards/m/MorningApparition.java deleted file mode 100644 index 22db5e1d308..00000000000 --- a/Mage.Sets/src/mage/cards/m/MorningApparition.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.keyword.DisturbAbility; -import mage.abilities.keyword.FlyingAbility; -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 MorningApparition extends CardImpl { - - public MorningApparition(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.SPIRIT); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.color.setWhite(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - - // If Morning Apparition would be put into a graveyard from anywhere, exile it instead. - this.addAbility(DisturbAbility.makeBackAbility()); - } - - private MorningApparition(final MorningApparition card) { - super(card); - } - - @Override - public MorningApparition copy() { - return new MorningApparition(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MourningPatrol.java b/Mage.Sets/src/mage/cards/m/MourningPatrol.java index d04ce198bd0..0dc7e48038b 100644 --- a/Mage.Sets/src/mage/cards/m/MourningPatrol.java +++ b/Mage.Sets/src/mage/cards/m/MourningPatrol.java @@ -1,11 +1,10 @@ package mage.cards.m; -import mage.MageInt; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.keyword.DisturbAbility; +import mage.abilities.keyword.FlyingAbility; 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; @@ -14,22 +13,35 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class MourningPatrol extends CardImpl { +public final class MourningPatrol extends TransformingDoubleFacedCard { public MourningPatrol(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.SOLDIER}, "{2}{W}", + "Morning Apparition", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT, SubType.SOLDIER}, "W" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.SOLDIER); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.m.MorningApparition.class; + // Mourning Patrol + this.getLeftHalfCard().setPT(2, 3); // Vigilance - this.addAbility(VigilanceAbility.getInstance()); + this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance()); // Disturb {3}{W} - this.addAbility(new DisturbAbility(this, "{3}{W}")); + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{3}{W}")); + + // Morning Apparition + this.getRightHalfCard().setPT(2, 1); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.getRightHalfCard().addAbility(VigilanceAbility.getInstance()); + + // If Morning Apparition would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private MourningPatrol(final MourningPatrol card) { diff --git a/Mage.Sets/src/mage/cards/m/MudbuttonCursetosser.java b/Mage.Sets/src/mage/cards/m/MudbuttonCursetosser.java new file mode 100644 index 00000000000..aab45cbcaed --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MudbuttonCursetosser.java @@ -0,0 +1,66 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.costs.OrCost; +import mage.abilities.costs.common.BeholdCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MudbuttonCursetosser extends CardImpl { + + private static final FilterPermanent filter = new FilterOpponentsCreaturePermanent("creature an opponent controls with power 2 or less"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public MudbuttonCursetosser(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // As an additional cost to cast this spell, behold a Goblin or pay {2}. + this.getSpellAbility().addCost(new OrCost( + "behold a Goblin or pay {2}", + new BeholdCost(BeholdType.GOBLIN), new GenericManaCost(2) + )); + + // This creature can't block. + this.addAbility(new CantBlockAbility()); + + // When this creature dies, destroy target creature an opponent controls with power 2 or less. + Ability ability = new DiesSourceTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private MudbuttonCursetosser(final MudbuttonCursetosser card) { + super(card); + } + + @Override + public MudbuttonCursetosser copy() { + return new MudbuttonCursetosser(this); + } +} 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/m/MysteriousTome.java b/Mage.Sets/src/mage/cards/m/MysteriousTome.java index 100d607c828..2ec392d7ace 100644 --- a/Mage.Sets/src/mage/cards/m/MysteriousTome.java +++ b/Mage.Sets/src/mage/cards/m/MysteriousTome.java @@ -5,32 +5,42 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TapTargetEffect; 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.TargetNonlandPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class MysteriousTome extends CardImpl { +public final class MysteriousTome extends TransformingDoubleFacedCard { public MysteriousTome(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}"); - - this.secondSideCardClazz = mage.cards.c.ChillingChronicle.class; - - // {2}, {T}: Draw a card. Transform Mysterious Tome. - this.addAbility(new TransformAbility()); - Ability ability = new SimpleActivatedAbility( - new DrawCardSourceControllerEffect(1), new GenericManaCost(2) + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}{U}", + "Chilling Chronicle", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "U" ); + + // Mysterious Tome + // {2}, {T}: Draw a card. Transform Mysterious Tome. + Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); ability.addEffect(new TransformSourceEffect()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Chilling Chronicle + // {1}, {T}: Tap target nonland permanent. Transform Chilling Chronicle. + Ability backAbility = new SimpleActivatedAbility(new TapTargetEffect(), new GenericManaCost(1)); + backAbility.addCost(new TapSourceCost()); + backAbility.addEffect(new TransformSourceEffect()); + backAbility.addTarget(new TargetNonlandPermanent()); + this.getRightHalfCard().addAbility(backAbility); } private MysteriousTome(final MysteriousTome card) { diff --git a/Mage.Sets/src/mage/cards/m/MysticMonstrosity.java b/Mage.Sets/src/mage/cards/m/MysticMonstrosity.java deleted file mode 100644 index 3ba9014ef37..00000000000 --- a/Mage.Sets/src/mage/cards/m/MysticMonstrosity.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.m; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.mana.AnyColorManaAbility; -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 MysticMonstrosity extends CardImpl { - - public MysticMonstrosity(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.CONSTRUCT); - this.power = new MageInt(5); - this.toughness = new MageInt(6); - this.nightCard = true; - - // Lands you control have "{T}: Add one mana of any color." - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( - new AnyColorManaAbility(), Duration.WhileOnBattlefield, - StaticFilters.FILTER_LANDS, false - ))); - } - - private MysticMonstrosity(final MysticMonstrosity card) { - super(card); - } - - @Override - public MysticMonstrosity copy() { - return new MysticMonstrosity(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MysticSkull.java b/Mage.Sets/src/mage/cards/m/MysticSkull.java index e9a14a86354..8554136f024 100644 --- a/Mage.Sets/src/mage/cards/m/MysticSkull.java +++ b/Mage.Sets/src/mage/cards/m/MysticSkull.java @@ -2,37 +2,51 @@ package mage.cards.m; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.mana.AnyColorManaAbility; -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 MysticSkull extends CardImpl { +public final class MysticSkull extends TransformingDoubleFacedCard { public MysticSkull(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - - this.secondSideCardClazz = mage.cards.m.MysticMonstrosity.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{2}", + "Mystic Monstrosity", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.CONSTRUCT}, "" + ); + // Mystic Skull // {1}, {T}: Add one mana of any color. Ability ability = new AnyColorManaAbility(new GenericManaCost(1)); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // {5}, {T}: Transform Mystic Skull. - this.addAbility(new TransformAbility()); ability = new SimpleActivatedAbility(new TransformSourceEffect(), new GenericManaCost(5)); ability.addCost(new TapSourceCost()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Mystic Monstrosity + this.getRightHalfCard().setPT(5, 6); + + // Lands you control have "{T}: Add one mana of any color." + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + new AnyColorManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_LANDS, false + ))); } private MysticSkull(final MysticSkull card) { 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/NathanDrakeTreasureHunter.java b/Mage.Sets/src/mage/cards/n/NathanDrakeTreasureHunter.java new file mode 100644 index 00000000000..357256402c1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NathanDrakeTreasureHunter.java @@ -0,0 +1,140 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.AsThoughManaEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.*; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.ManaPoolItem; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInExile; +import mage.util.CardUtil; + +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class NathanDrakeTreasureHunter extends CardImpl { + + public NathanDrakeTreasureHunter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{B}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // You may spend mana as though it were mana of any color to cast spells you don't own or to activate abilities of permanents you control but don't own. + this.addAbility(new SimpleStaticAbility(new NathanDrakeTreasureHunterManaEffect())); + + // Whenever Nathan Drake attacks, exile the top card of each player's library. You may cast a spell from among those cards. + this.addAbility(new AttacksTriggeredAbility(new NathanDrakeTreasureHunterCastEffect())); + } + + private NathanDrakeTreasureHunter(final NathanDrakeTreasureHunter card) { + super(card); + } + + @Override + public NathanDrakeTreasureHunter copy() { + return new NathanDrakeTreasureHunter(this); + } +} + +class NathanDrakeTreasureHunterManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { + + NathanDrakeTreasureHunterManaEffect() { + super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit); + staticText = "you may spend mana as though it were mana of any color to cast spells you don't own " + + "or to activate abilities of permanents you control but don't own"; + } + + private NathanDrakeTreasureHunterManaEffect(final NathanDrakeTreasureHunterManaEffect effect) { + super(effect); + } + + @Override + public NathanDrakeTreasureHunterManaEffect copy() { + return new NathanDrakeTreasureHunterManaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + Card card = game.getCard(CardUtil.getMainCardId(game, objectId)); + return card != null && !card.isOwnedBy(affectedControllerId); + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); + } +} + +class NathanDrakeTreasureHunterCastEffect extends OneShotEffect { + + NathanDrakeTreasureHunterCastEffect() { + super(Outcome.Benefit); + staticText = "exile the top card of each player's library. You may cast a spell from among those cards"; + } + + private NathanDrakeTreasureHunterCastEffect(final NathanDrakeTreasureHunterCastEffect effect) { + super(effect); + } + + @Override + public NathanDrakeTreasureHunterCastEffect copy() { + return new NathanDrakeTreasureHunterCastEffect(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::getLibrary) + .map(library -> library.getFromTop(game)) + .collect(Collectors.toSet())); + if (cards.isEmpty()) { + return false; + } + player.moveCards(cards, Zone.EXILED, source, game); + cards.removeIf(uuid -> CardUtil.getCastableComponents( + game.getCard(uuid), StaticFilters.FILTER_CARD, + source, player, game, null, false + ).isEmpty()); + TargetCard target = new TargetCardInExile(0, 1, StaticFilters.FILTER_CARD); + target.withChooseHint("to cast"); + target.withNotTarget(true); + player.choose(Outcome.DrawCard, cards, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + CardUtil.castSingle(player, source, game, card); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java b/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java index 9fa4c5d6e11..12f0e7564f6 100644 --- a/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java +++ b/Mage.Sets/src/mage/cards/n/NeglectedHeirloom.java @@ -1,13 +1,16 @@ package mage.cards.n; +import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EquipAbility; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.AttachmentType; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; @@ -21,23 +24,35 @@ import java.util.UUID; /** * @author halljared */ -public final class NeglectedHeirloom extends CardImpl { +public final class NeglectedHeirloom extends TransformingDoubleFacedCard { public NeglectedHeirloom(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); - this.subtype.add(SubType.EQUIPMENT); - - this.secondSideCardClazz = mage.cards.a.AshmouthBlade.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.EQUIPMENT}, "{1}", + "Ashmouth Blade", + new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.EQUIPMENT}, "" + ); // Equipped creature gets +1/+1. - this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 1))); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 1))); // When equipped creature transforms, transform Neglected Heirloom. - this.addAbility(new TransformAbility()); - this.addAbility(new NeglectedHeirloomTriggeredAbility()); + this.getLeftHalfCard().addAbility(new NeglectedHeirloomTriggeredAbility()); // Equip {1} - this.addAbility(new EquipAbility(1, false)); + this.getLeftHalfCard().addAbility(new EquipAbility(1, false)); + + // Ashmouth Blade + + // Equipped creature gets +3/+3 and has first strike. + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 3)); + ability.addEffect(new GainAbilityAttachedEffect( + FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has first strike")); + this.getRightHalfCard().addAbility(ability); + + // Equip {3} + this.getRightHalfCard().addAbility(new EquipAbility(3, false)); } private NeglectedHeirloom(final NeglectedHeirloom card) { diff --git a/Mage.Sets/src/mage/cards/n/NezumiFreewheeler.java b/Mage.Sets/src/mage/cards/n/NezumiFreewheeler.java index 1c1a0cd081d..3b8b4570297 100644 --- a/Mage.Sets/src/mage/cards/n/NezumiFreewheeler.java +++ b/Mage.Sets/src/mage/cards/n/NezumiFreewheeler.java @@ -1,44 +1,68 @@ package mage.cards.n; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.MillCardsEachPlayerEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.MenaceAbility; -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.constants.TargetController; +import mage.filter.FilterCard; +import mage.filter.common.FilterPermanentCard; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.target.common.TargetCardInGraveyard; import java.util.UUID; /** * @author TheElk801 */ -public final class NezumiFreewheeler extends CardImpl { +public final class NezumiFreewheeler extends TransformingDoubleFacedCard { + + private static final FilterCard filter + = new FilterPermanentCard("permanent card with mana value 2 or less from a graveyard"); + + static { + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3)); + } public NezumiFreewheeler(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.RAT, SubType.SAMURAI}, "{3}{B}", + "Hideous Fleshwheeler", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.RAT}, "WB" + ); - this.subtype.add(SubType.RAT); - this.subtype.add(SubType.SAMURAI); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.h.HideousFleshwheeler.class; + // Nezumi Freewheeler + this.getLeftHalfCard().setPT(3, 3); // Menace - this.addAbility(new MenaceAbility(false)); + this.getLeftHalfCard().addAbility(new MenaceAbility(false)); // When Nezumi Freewheeler enters the battlefield, each player mills three cards. - this.addAbility(new EntersBattlefieldTriggeredAbility(new MillCardsEachPlayerEffect(3, TargetController.EACH_PLAYER))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new MillCardsEachPlayerEffect(3, TargetController.EACH_PLAYER))); // {5}{W/P}: Transform Nezumi Freewheeler. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{W/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{W/P}"))); + + // Hideous Fleshwheeler + this.getRightHalfCard().setPT(4, 5); + + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility()); + + // When this creature transforms into Hideous Fleshwheeler, Hideous Fleshwheeler, put target permanent card with mana value 2 or less from a graveyard onto the battlefield under your control. + Ability ability = new TransformIntoSourceTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()); + ability.addTarget(new TargetCardInGraveyard(filter)); + this.getRightHalfCard().addAbility(ability); } private NezumiFreewheeler(final NezumiFreewheeler card) { diff --git a/Mage.Sets/src/mage/cards/n/NezumiRoadCaptain.java b/Mage.Sets/src/mage/cards/n/NezumiRoadCaptain.java deleted file mode 100644 index c3a6420efa2..00000000000 --- a/Mage.Sets/src/mage/cards/n/NezumiRoadCaptain.java +++ /dev/null @@ -1,50 +0,0 @@ -package mage.cards.n; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -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.FilterPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class NezumiRoadCaptain extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent(SubType.VEHICLE, "Vehicles"); - - public NezumiRoadCaptain(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.RAT); - this.subtype.add(SubType.ROGUE); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setBlack(true); - this.nightCard = true; - - // Menace - this.addAbility(new MenaceAbility(false)); - - // Vehicles you control have menace. - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( - new MenaceAbility(true), Duration.WhileOnBattlefield, filter - ))); - } - - private NezumiRoadCaptain(final NezumiRoadCaptain card) { - super(card); - } - - @Override - public NezumiRoadCaptain copy() { - return new NezumiRoadCaptain(this); - } -} diff --git a/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java b/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java index 08ea929dc27..144122c860e 100644 --- a/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java +++ b/Mage.Sets/src/mage/cards/n/NicolBolasGodPharaoh.java @@ -2,7 +2,6 @@ package mage.cards.n; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ExileAllEffect; @@ -21,7 +20,6 @@ import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetOpponent; import mage.target.common.TargetPermanentOrPlayer; -import mage.target.targetpointer.FixedTarget; import java.util.HashMap; import java.util.Map; @@ -164,15 +162,15 @@ class NicolBolasGodPharaohPlusTwoEffect extends OneShotEffect { if (card == null) { break; } - if (!opponent.moveCards(card, Zone.EXILED, source, game)) { - break; - } if (card.isLand(game)) { + if (!opponent.moveCards(card, Zone.EXILED, source, game)) { + break; + } continue; } - ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, TargetController.YOU, Duration.EndOfTurn, true); - effect.setTargetPointer(new FixedTarget(card, game)); - game.addEffect(effect, source); + PlayFromNotOwnHandZoneTargetEffect.exileAndPlayFromExile( + game, source, card, TargetController.YOU, Duration.EndOfTurn, true, false, true + ); break; } while (library.hasCards()); return true; diff --git a/Mage.Sets/src/mage/cards/n/NicolBolasTheArisen.java b/Mage.Sets/src/mage/cards/n/NicolBolasTheArisen.java deleted file mode 100644 index 48b0c44bf0b..00000000000 --- a/Mage.Sets/src/mage/cards/n/NicolBolasTheArisen.java +++ /dev/null @@ -1,107 +0,0 @@ -package mage.cards.n; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetPlayer; -import mage.target.common.TargetCardInGraveyard; -import mage.target.common.TargetCreatureOrPlaneswalker; - -/** - * - * @author TheElk801 - */ -public final class NicolBolasTheArisen extends CardImpl { - - private static final FilterCard filter = new FilterCard("creature or planeswalker card from a graveyard"); - - static { - filter.add(Predicates.or( - CardType.CREATURE.getPredicate(), - CardType.PLANESWALKER.getPredicate() - )); - } - - public NicolBolasTheArisen(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.BOLAS); - - this.color.setBlue(true); - this.color.setBlack(true); - this.color.setRed(true); - this.nightCard = true; - - this.setStartingLoyalty(7); - - // +2: Draw two cards. - this.addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(2), 2)); - - // −3: Nicol Bolas, the Arisen deals 10 damage to target creature or planeswalker. - Ability ability = new LoyaltyAbility(new DamageTargetEffect(10), -3); - ability.addTarget(new TargetCreatureOrPlaneswalker()); - this.addAbility(ability); - - // −4: Put target creature or planeswalker card from a graveyard onto the battlefield under your control. - ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), -4); - ability.addTarget(new TargetCardInGraveyard(filter)); - this.addAbility(ability); - - // −12: Exile all but the bottom card of target player's library. - ability = new LoyaltyAbility(new NicolBolasTheArisenEffect(), -12); - ability.addTarget(new TargetPlayer()); - this.addAbility(ability); - } - - private NicolBolasTheArisen(final NicolBolasTheArisen card) { - super(card); - } - - @Override - public NicolBolasTheArisen copy() { - return new NicolBolasTheArisen(this); - } -} - -class NicolBolasTheArisenEffect extends OneShotEffect { - - NicolBolasTheArisenEffect() { - super(Outcome.Benefit); - this.staticText = "Exile all but the bottom card of target player's library."; - } - - private NicolBolasTheArisenEffect(final NicolBolasTheArisenEffect effect) { - super(effect); - } - - @Override - public NicolBolasTheArisenEffect copy() { - return new NicolBolasTheArisenEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (targetPlayer == null || controller == null) { - return false; - } - return controller.moveCards(targetPlayer.getLibrary().getTopCards(game, targetPlayer.getLibrary().size() - 1), Zone.EXILED, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/n/NicolBolasTheRavager.java b/Mage.Sets/src/mage/cards/n/NicolBolasTheRavager.java index 9d63d936ede..100a81578e7 100644 --- a/Mage.Sets/src/mage/cards/n/NicolBolasTheRavager.java +++ b/Mage.Sets/src/mage/cards/n/NicolBolasTheRavager.java @@ -1,50 +1,89 @@ package mage.cards.n; -import java.util.UUID; -import mage.MageInt; -import mage.constants.Pronoun; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.constants.*; 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.*; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetCreatureOrPlaneswalker; + +import java.util.UUID; /** * * @author TheElk801 */ -public final class NicolBolasTheRavager extends CardImpl { +public final class NicolBolasTheRavager extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard("creature or planeswalker card from a graveyard"); + + static { + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.PLANESWALKER.getPredicate() + )); + } public NicolBolasTheRavager(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELDER, SubType.DRAGON}, "{1}{U}{B}{R}", + "Nicol Bolas, the Arisen", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.BOLAS}, "UBR" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ELDER); - this.subtype.add(SubType.DRAGON); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - - this.secondSideCardClazz = mage.cards.n.NicolBolasTheArisen.class; + // Nicol Bolas, the Ravager + this.getLeftHalfCard().setPT(4, 4); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // When Nicol Bolas, the Ravager enters the battlefield, each opponent discards a card. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(StaticValue.get(1), false, TargetController.OPPONENT))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DiscardEachPlayerEffect(StaticValue.get(1), false, TargetController.OPPONENT))); // {4}{U}{B}{R}: Exile Nicol Bolas, the Ravager, then return him to the battlefield transformed under his owner's control. Activate this ability only any time you could cast a sorcerry. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility( + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility( Zone.BATTLEFIELD, - new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED,Pronoun.HE), + new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.HE), new ManaCostsImpl<>("{4}{U}{B}{R}") )); + + // Nicol Bolas, the Arisen + this.getRightHalfCard().setStartingLoyalty(7); + + // +2: Draw two cards. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(2), 2)); + + // −3: Nicol Bolas, the Arisen deals 10 damage to target creature or planeswalker. + Ability ability = new LoyaltyAbility(new DamageTargetEffect(10), -3); + ability.addTarget(new TargetCreatureOrPlaneswalker()); + this.getRightHalfCard().addAbility(ability); + + // −4: Put target creature or planeswalker card from a graveyard onto the battlefield under your control. + ability = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), -4); + ability.addTarget(new TargetCardInGraveyard(filter)); + this.getRightHalfCard().addAbility(ability); + + // −12: Exile all but the bottom card of target player's library. + ability = new LoyaltyAbility(new NicolBolasTheArisenEffect(), -12); + ability.addTarget(new TargetPlayer()); + this.getRightHalfCard().addAbility(ability); } private NicolBolasTheRavager(final NicolBolasTheRavager card) { @@ -56,3 +95,30 @@ public final class NicolBolasTheRavager extends CardImpl { return new NicolBolasTheRavager(this); } } + +class NicolBolasTheArisenEffect extends OneShotEffect { + + NicolBolasTheArisenEffect() { + super(Outcome.Benefit); + this.staticText = "Exile all but the bottom card of target player's library."; + } + + private NicolBolasTheArisenEffect(final NicolBolasTheArisenEffect effect) { + super(effect); + } + + @Override + public NicolBolasTheArisenEffect copy() { + return new NicolBolasTheArisenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (targetPlayer == null || controller == null) { + return false; + } + return controller.moveCards(targetPlayer.getLibrary().getTopCards(game, targetPlayer.getLibrary().size() - 1), Zone.EXILED, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java b/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java deleted file mode 100644 index 4d65ecdf45c..00000000000 --- a/Mage.Sets/src/mage/cards/n/NissaSageAnimist.java +++ /dev/null @@ -1,128 +0,0 @@ -package mage.cards.n; - -import java.util.UUID; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.CardsImpl; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.game.permanent.token.NissaSageAnimistToken; -import mage.game.permanent.token.custom.CreatureToken; -import mage.players.Player; -import mage.target.common.TargetLandPermanent; -import mage.target.targetpointer.FixedTarget; - -/** - * - * @author emerald000 - */ -public final class NissaSageAnimist extends CardImpl { - - public NissaSageAnimist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.NISSA); - this.color.setGreen(true); - - this.nightCard = true; - - this.setStartingLoyalty(3); - - // +1: Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand. - this.addAbility(new LoyaltyAbility(new NissaSageAnimistPlusOneEffect(), 1)); - - // -2: Create a legendary 4/4 green Elemental creature token named Ashaya, the Awoken World. - this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new NissaSageAnimistToken()), -2)); - - // -7: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. - Ability ability = new LoyaltyAbility(new UntapTargetEffect(), -7); - ability.addTarget(new TargetLandPermanent(0, 6)); - ability.addEffect(new NissaSageAnimistMinusAnimateEffect()); - this.addAbility(ability); - } - - private NissaSageAnimist(final NissaSageAnimist card) { - super(card); - } - - @Override - public NissaSageAnimist copy() { - return new NissaSageAnimist(this); - } -} - -class NissaSageAnimistPlusOneEffect extends OneShotEffect { - - NissaSageAnimistPlusOneEffect() { - super(Outcome.Benefit); - this.staticText = "Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand."; - } - - private NissaSageAnimistPlusOneEffect(final NissaSageAnimistPlusOneEffect effect) { - super(effect); - } - - @Override - public NissaSageAnimistPlusOneEffect copy() { - return new NissaSageAnimistPlusOneEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (sourceObject != null && controller != null && controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().getFromTop(game); - if (card == null) { - return false; - } - controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); - Zone targetZone = Zone.HAND; - if (card.isLand(game)) { - targetZone = Zone.BATTLEFIELD; - } - return controller.moveCards(card, targetZone, source, game); - } - return true; - } -} - -class NissaSageAnimistMinusAnimateEffect extends OneShotEffect { - - NissaSageAnimistMinusAnimateEffect() { - super(Outcome.BecomeCreature); - this.staticText = "They become 6/6 Elemental creatures. They're still lands"; - } - - private NissaSageAnimistMinusAnimateEffect(final NissaSageAnimistMinusAnimateEffect effect) { - super(effect); - } - - @Override - public NissaSageAnimistMinusAnimateEffect copy() { - return new NissaSageAnimistMinusAnimateEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (UUID permanentId : this.getTargetPointer().getTargets(game, source)) { - Permanent permanent = game.getPermanent(permanentId); - if (permanent != null) { - ContinuousEffectImpl effect = new BecomesCreatureTargetEffect(new CreatureToken(6, 6, "", SubType.ELEMENTAL), false, true, Duration.Custom); - effect.setTargetPointer(new FixedTarget(permanent, game)); - game.addEffect(effect, source); - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/n/NissaVastwoodSeer.java b/Mage.Sets/src/mage/cards/n/NissaVastwoodSeer.java index 01b027d210d..19a00564534 100644 --- a/Mage.Sets/src/mage/cards/n/NissaVastwoodSeer.java +++ b/Mage.Sets/src/mage/cards/n/NissaVastwoodSeer.java @@ -1,27 +1,42 @@ package mage.cards.n; -import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LandfallAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -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.*; import mage.filter.FilterCard; import mage.filter.common.FilterBasicCard; import mage.filter.common.FilterLandPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.NissaSageAnimistToken; +import mage.game.permanent.token.custom.CreatureToken; +import mage.players.Player; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetLandPermanent; +import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** * @author emerald000 */ -public final class NissaVastwoodSeer extends CardImpl { +public final class NissaVastwoodSeer extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterBasicCard(SubType.FOREST); @@ -31,25 +46,39 @@ public final class NissaVastwoodSeer extends CardImpl { ); public NissaVastwoodSeer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ELF); - this.subtype.add(SubType.SCOUT); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELF, SubType.SCOUT}, "{2}{G}", + "Nissa, Sage Animist", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.PLANESWALKER}, new SubType[]{SubType.NISSA}, "G" + ); - this.secondSideCardClazz = mage.cards.n.NissaSageAnimist.class; + // Nissa, Vastwood Seer + this.getLeftHalfCard().setPT(2, 2); // When Nissa, Vastwood Seer enters the battlefield, you may search your library for a basic Forest card, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility( + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility( new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), true )); // Whenever a land you control enters, if you control seven or more lands, exile Nissa, then return her to the battlefield transformed under her owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new LandfallAbility(new ExileAndReturnSourceEffect( + this.getLeftHalfCard().addAbility(new LandfallAbility(new ExileAndReturnSourceEffect( PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.SHE )).withInterveningIf(condition).setAbilityWord(null)); + + // Nissa, Sage Animist + this.getRightHalfCard().setStartingLoyalty(3); + + // +1: Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new NissaSageAnimistPlusOneEffect(), 1)); + + // -2: Create a legendary 4/4 green Elemental creature token named Ashaya, the Awoken World. + this.getRightHalfCard().addAbility(new LoyaltyAbility(new CreateTokenEffect(new NissaSageAnimistToken()), -2)); + + // -7: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. + Ability ability = new LoyaltyAbility(new UntapTargetEffect(), -7); + ability.addTarget(new TargetLandPermanent(0, 6)); + ability.addEffect(new NissaSageAnimistMinusAnimateEffect()); + this.getRightHalfCard().addAbility(ability); } private NissaVastwoodSeer(final NissaVastwoodSeer card) { @@ -61,3 +90,69 @@ public final class NissaVastwoodSeer extends CardImpl { return new NissaVastwoodSeer(this); } } + +class NissaSageAnimistPlusOneEffect extends OneShotEffect { + + NissaSageAnimistPlusOneEffect() { + super(Outcome.Benefit); + this.staticText = "Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand."; + } + + private NissaSageAnimistPlusOneEffect(final NissaSageAnimistPlusOneEffect effect) { + super(effect); + } + + @Override + public NissaSageAnimistPlusOneEffect copy() { + return new NissaSageAnimistPlusOneEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source); + if (sourceObject != null && controller != null && controller.getLibrary().hasCards()) { + Card card = controller.getLibrary().getFromTop(game); + if (card == null) { + return false; + } + controller.revealCards(sourceObject.getIdName(), new CardsImpl(card), game); + Zone targetZone = Zone.HAND; + if (card.isLand(game)) { + targetZone = Zone.BATTLEFIELD; + } + return controller.moveCards(card, targetZone, source, game); + } + return true; + } +} + +class NissaSageAnimistMinusAnimateEffect extends OneShotEffect { + + NissaSageAnimistMinusAnimateEffect() { + super(Outcome.BecomeCreature); + this.staticText = "They become 6/6 Elemental creatures. They're still lands"; + } + + private NissaSageAnimistMinusAnimateEffect(final NissaSageAnimistMinusAnimateEffect effect) { + super(effect); + } + + @Override + public NissaSageAnimistMinusAnimateEffect copy() { + return new NissaSageAnimistMinusAnimateEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID permanentId : this.getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(permanentId); + if (permanent != null) { + ContinuousEffectImpl effect = new BecomesCreatureTargetEffect(new CreatureToken(6, 6, "", SubType.ELEMENTAL), false, true, Duration.Custom); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } + } + return true; + } +} 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/n/NoggleRobber.java b/Mage.Sets/src/mage/cards/n/NoggleRobber.java new file mode 100644 index 00000000000..f517958cc72 --- /dev/null +++ b/Mage.Sets/src/mage/cards/n/NoggleRobber.java @@ -0,0 +1,39 @@ +package mage.cards.n; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldOrDiesSourceTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.TreasureToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class NoggleRobber extends CardImpl { + + public NoggleRobber(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R/G}{R/G}"); + + this.subtype.add(SubType.NOGGLE); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When this creature enters or dies, create a Treasure token. + this.addAbility(new EntersBattlefieldOrDiesSourceTriggeredAbility(new CreateTokenEffect(new TreasureToken()), false)); + } + + private NoggleRobber(final NoggleRobber card) { + super(card); + } + + @Override + public NoggleRobber copy() { + return new NoggleRobber(this); + } +} 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/OakshadeStalker.java b/Mage.Sets/src/mage/cards/o/OakshadeStalker.java index ca4969bf919..f78a0ac4bac 100644 --- a/Mage.Sets/src/mage/cards/o/OakshadeStalker.java +++ b/Mage.Sets/src/mage/cards/o/OakshadeStalker.java @@ -1,11 +1,11 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.PayMoreToCastAsThoughtItHadFlashAbility; import mage.abilities.costs.mana.ManaCostsImpl; 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; @@ -14,23 +14,28 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class OakshadeStalker extends CardImpl { +public final class OakshadeStalker extends TransformingDoubleFacedCard { public OakshadeStalker(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.RANGER, SubType.WEREWOLF}, "{2}{G}", + "Moonlit Ambusher", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.RANGER); - this.subtype.add(SubType.WEREWOLF); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.m.MoonlitAmbusher.class; + // Oakshade Stalker + this.getLeftHalfCard().setPT(3, 3); // You may cast this spell as though it had flash if you pay {2} more to cast it. - this.addAbility(new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl<>("{2}"))); + this.getLeftHalfCard().addAbility(new PayMoreToCastAsThoughtItHadFlashAbility(this.getLeftHalfCard(), new ManaCostsImpl<>("{2}"))); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Moonlit Ambusher + this.getRightHalfCard().setPT(6, 3); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private OakshadeStalker(final OakshadeStalker card) { diff --git a/Mage.Sets/src/mage/cards/o/OdiousWitch.java b/Mage.Sets/src/mage/cards/o/OdiousWitch.java deleted file mode 100644 index 253b38f0029..00000000000 --- a/Mage.Sets/src/mage/cards/o/OdiousWitch.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SetTargetPointer; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class OdiousWitch extends CardImpl { - - public OdiousWitch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WARLOCK); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.nightCard = true; - - // Whenever Odious Witch attacks, defending player loses 1 life and you gain 1 life. - Ability ability = new AttacksTriggeredAbility( - new LoseLifeTargetEffect(1) - .setText("defending player loses 1 life"), - false, null, SetTargetPointer.PLAYER - ); - ability.addEffect(new GainLifeEffect(1).concatBy("and")); - this.addAbility(ability); - } - - private OdiousWitch(final OdiousWitch card) { - super(card); - } - - @Override - public OdiousWitch copy() { - return new OdiousWitch(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OftNabbedGoat.java b/Mage.Sets/src/mage/cards/o/OftNabbedGoat.java new file mode 100644 index 00000000000..78ecf60ea67 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OftNabbedGoat.java @@ -0,0 +1,143 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author PurpleCrowbar + */ +public final class OftNabbedGoat extends CardImpl { + + public OftNabbedGoat(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + this.subtype.add(SubType.GOAT); + this.power = new MageInt(0); + this.toughness = new MageInt(5); + + // {1}: Draw a card. Gain control of this creature and put a -1/-1 counter on it. Only your opponents may activate this ability and only as a sorcery. + ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility( + new DrawCardSourceControllerEffect(1).setText("Draw a card"), new GenericManaCost(1) + ); + ability.addEffect(new OftNabbedGoatGainControlEffect()); + ability.addEffect(new AddCountersSourceEffect(CounterType.M1M1.createInstance()).setText("and put a -1/-1 counter on it")); + ability.setMayActivate(TargetController.OPPONENT); + this.addAbility(ability); + + // When this creature dies, if it had one or more -1/-1 counters on it, its owner draws that many cards and each other player loses that much life. + this.addAbility(new DiesSourceTriggeredAbility(new OftNabbedGoatOwnerDrawsEffect()).withInterveningIf(OftNabbedGoatCondition.instance)); + } + + private OftNabbedGoat(final OftNabbedGoat card) { + super(card); + } + + @Override + public OftNabbedGoat copy() { + return new OftNabbedGoat(this); + } +} + +class OftNabbedGoatGainControlEffect extends OneShotEffect { + + OftNabbedGoatGainControlEffect() { + super(Outcome.GainControl); + staticText = "Gain control of this creature"; + } + + private OftNabbedGoatGainControlEffect(final OftNabbedGoatGainControlEffect effect) { + super(effect); + } + + @Override + public OftNabbedGoatGainControlEffect copy() { + return new OftNabbedGoatGainControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player abilityController = game.getPlayer(source.getControllerId()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (abilityController == null || permanent == null) { + return false; + } + + game.addEffect(new GainControlTargetEffect( + Duration.Custom, true, abilityController.getId() + ).setTargetPointer(new FixedTarget(permanent, game)), source); + return true; + } +} + +enum OftNabbedGoatCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return CardUtil + .getEffectValueFromAbility(source, "permanentLeftBattlefield", Permanent.class) + .filter(permanent -> permanent.getCounters(game).getCount(CounterType.M1M1) >= 1) + .isPresent(); + } + + @Override + public String toString() { + return "if it had one or more -1/-1 counters on it"; + } +} + +class OftNabbedGoatOwnerDrawsEffect extends OneShotEffect { + + OftNabbedGoatOwnerDrawsEffect() { + super(Outcome.DrawCard); + staticText = "its owner draws that many cards and each other player loses that much life"; + } + + private OftNabbedGoatOwnerDrawsEffect(final OftNabbedGoatOwnerDrawsEffect effect) { + super(effect); + } + + @Override + public OftNabbedGoatOwnerDrawsEffect copy() { + return new OftNabbedGoatOwnerDrawsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentOrLKI(game); + if (permanent == null) { + return false; + } + Player owner = game.getPlayer(permanent.getOwnerId()); + if (owner == null) { + return false; + } + int counterCount = permanent.getCounters(game).getCount(CounterType.M1M1); + owner.drawCards(counterCount, source, game); + for (UUID opponentId : game.getOpponents(owner.getId())) { + Player player = game.getPlayer(opponentId); + if (player != null) { + player.loseLife(counterCount, game, source, false); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java b/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java index a4640a9186d..8c7bbe6e8bd 100644 --- a/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java +++ b/Mage.Sets/src/mage/cards/o/OjerAxonilDeepestMight.java @@ -1,50 +1,74 @@ package mage.cards.o; -import mage.MageInt; + import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.hint.Hint; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.RedManaAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; import mage.game.Controllable; import mage.game.Game; +import mage.game.command.CommandObject; import mage.game.events.DamageEvent; +import mage.game.events.DamagedEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; import mage.players.Player; +import mage.watchers.Watcher; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; /** * @author Susucr */ -public final class OjerAxonilDeepestMight extends CardImpl { +public final class OjerAxonilDeepestMight extends TransformingDoubleFacedCard { public OjerAxonilDeepestMight(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); - this.secondSideCardClazz = mage.cards.t.TempleOfPower.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{2}{R}{R}", + "Temple of Power", + new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GOD); - this.power = new MageInt(4); - this.toughness = new MageInt(4); + // Ojer Axonil, Deepest Might + this.getLeftHalfCard().setPT(4, 4); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // If a red source you control would deal an amount of noncombat damage less than Ojer Axonil's power to an opponent, that source deals damage equal to Ojer Axonil's power instead. - this.addAbility(new SimpleStaticAbility(new OjerAxonilDeepestMightReplacementEffect())); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new OjerAxonilDeepestMightReplacementEffect())); // When Ojer Axonil dies, return it to the battlefield tapped and transformed under its owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesSourceTriggeredAbility(new OjerAxonilDeepestMightTransformEffect())); + this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerAxonilDeepestMightTransformEffect())); + + // Temple of Power + // {T}: Add {R}. + this.getRightHalfCard().addAbility(new RedManaAbility()); + + // {2}{R}, {T}: Transform Temple of Power. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery. + Ability ability = new ActivateIfConditionActivatedAbility( + new TransformSourceEffect(), new ManaCostsImpl<>("{2}{R}"), TempleOfPowerCondition.instance + ).setTiming(TimingRule.SORCERY); + ability.addCost(new TapSourceCost()); + ability.addWatcher(new TempleOfPowerWatcher()); + this.getRightHalfCard().addAbility(ability.addHint(TempleOfPowerHint.instance)); } private OjerAxonilDeepestMight(final OjerAxonilDeepestMight card) { @@ -155,3 +179,100 @@ class OjerAxonilDeepestMightReplacementEffect extends ReplacementEffectImpl { && event.getAmount() < ojer.getPower().getValue(); } } + +enum TempleOfPowerCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class); + return watcher != null + && 4 <= watcher.damageForPlayer(source.getControllerId()); + } + + @Override + public String toString() { + return "red sources you controlled dealt 4 or more noncombat damage this turn"; + } +} + +enum TempleOfPowerHint implements Hint { + instance; + + @Override + public String getText(Game game, Ability ability) { + TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class); + if (watcher == null) { + return ""; + } + + return "Non-combat damage from red source: " + + watcher.damageForPlayer(ability.getControllerId()); + } + + @Override + public TempleOfPowerHint copy() { + return instance; + } +} + +class TempleOfPowerWatcher extends Watcher { + + // player -> total non combat damage from red source controlled by that player dealt this turn. + private final Map damageMap = new HashMap<>(); + + public TempleOfPowerWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER + || event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) { + DamagedEvent dmgEvent = (DamagedEvent) event; + + // watch only non combat damage events. + if (dmgEvent == null || dmgEvent.isCombatDamage()) { + return; + } + + MageObject sourceObject; + UUID sourceControllerId = null; + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (sourcePermanent != null) { + // source is a permanent. + sourceObject = sourcePermanent; + sourceControllerId = sourcePermanent.getControllerId(); + } else { + sourceObject = game.getSpellOrLKIStack(event.getSourceId()); + if (sourceObject != null) { + // source is a spell. + sourceControllerId = ((StackObject) sourceObject).getControllerId(); + } else { + sourceObject = game.getObject(event.getSourceId()); + if (sourceObject instanceof CommandObject) { + // source is a Command Object. For instance Emblem + sourceControllerId = ((CommandObject) sourceObject).getControllerId(); + } + } + } + + // watch only red sources dealing damage + if (sourceObject == null || sourceControllerId == null || !sourceObject.getColor().isRed()) { + return; + } + + damageMap.compute(sourceControllerId, (k, i) -> (i == null ? 0 : i) + event.getAmount()); + } + } + + @Override + public void reset() { + damageMap.clear(); + super.reset(); + } + + int damageForPlayer(UUID playerId) { + return damageMap.getOrDefault(playerId, 0); + } +} diff --git a/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java b/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java index 67222a03623..6538489b745 100644 --- a/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java +++ b/Mage.Sets/src/mage/cards/o/OjerKaslemDeepestGrowth.java @@ -1,15 +1,23 @@ package mage.cards.o; -import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DiesSourceTriggeredAbility; +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.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.hint.common.PermanentsYouControlHint; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.GreenManaAbility; import mage.cards.*; +import mage.cards.g.GishathSunsAvatar; import mage.constants.*; +import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; @@ -20,26 +28,39 @@ import java.util.UUID; /** * @author Susucr */ -public final class OjerKaslemDeepestGrowth extends CardImpl { +public final class OjerKaslemDeepestGrowth extends TransformingDoubleFacedCard { public OjerKaslemDeepestGrowth(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); - this.secondSideCardClazz = mage.cards.t.TempleOfCultivation.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{3}{G}{G}", + "Temple of Cultivation", + new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GOD); - this.power = new MageInt(6); - this.toughness = new MageInt(5); + // Ojer Kaslem, Deepest Growth + this.getLeftHalfCard().setPT(6, 5); // Trample - this.addAbility(TrampleAbility.getInstance()); + this.getLeftHalfCard().addAbility(TrampleAbility.getInstance()); // Whenever Ojer Kaslem deals combat damage to a player, reveal that many cards from the top of your library. You may put a creature card and/or a land card from among them onto the battlefield. Put the rest on the bottom in a random order. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new OjerKaslemDeepestGrowthEffect(), false, true)); + this.getLeftHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new OjerKaslemDeepestGrowthEffect(), false, true)); // When Ojer Kaslem dies, return it to the battlefield tapped and transformed under its owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesSourceTriggeredAbility(new OjerKaslemDeepestGrowthTransformEffect())); + this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerKaslemDeepestGrowthTransformEffect())); + + // Temple of Cultivation + // {T}: Add {G}. + this.getRightHalfCard().addAbility(new GreenManaAbility()); + + // {2}{G}, {T}: Transform Temple of Cultivation. Activate only if you control ten or more permanents and only as a sorcery. + Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterControlledPermanent("you control ten or more permanents"), ComparisonType.MORE_THAN, 9 + ); + Ability ability = new ActivateIfConditionActivatedAbility( + new TransformSourceEffect(), new ManaCostsImpl<>("{2}{G}"), condition + ).setTiming(TimingRule.SORCERY); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability.addHint(PermanentsYouControlHint.instance)); } private OjerKaslemDeepestGrowth(final OjerKaslemDeepestGrowth card) { @@ -82,7 +103,7 @@ class OjerKaslemDeepestGrowthTransformEffect extends OneShotEffect { } /** - * Inspired by {@link mage.cards.g.GishathSunsAvatar} + * Inspired by {@link GishathSunsAvatar} */ class OjerKaslemDeepestGrowthEffect extends OneShotEffect { @@ -116,7 +137,7 @@ class OjerKaslemDeepestGrowthEffect extends OneShotEffect { controller.choose(Outcome.PutCardInPlay, cards, target, source, game); Cards toBattlefield = new CardsImpl(target.getTargets()); cards.removeAll(toBattlefield); - controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, false, false, false, null); + controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game); controller.putCardsOnBottomOfLibrary(cards, game, source, false); } return true; diff --git a/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java b/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java index c302c5a021f..73a4be11c49 100644 --- a/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java +++ b/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java @@ -1,18 +1,25 @@ package mage.cards.o; -import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.DiesSourceTriggeredAbility; 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.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ReboundAbility; import mage.abilities.keyword.TransformAbility; +import mage.abilities.mana.BlueManaAbility; import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; +import mage.cards.n.NarsetTranscendent; import mage.constants.*; import mage.counters.CounterType; import mage.counters.Counters; @@ -26,35 +33,48 @@ import java.util.UUID; /** * @author Susucr */ -public final class OjerPakpatiqDeepestEpoch extends CardImpl { +public final class OjerPakpatiqDeepestEpoch extends TransformingDoubleFacedCard { private static final FilterSpell filter = new FilterSpell("an instant spell"); + private static final Condition condition = new SourceHasCounterCondition(CounterType.TIME, ComparisonType.EQUAL_TO, 0); static { filter.add(CardType.INSTANT.getPredicate()); } public OjerPakpatiqDeepestEpoch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); - this.secondSideCardClazz = mage.cards.t.TempleOfCyclicalTime.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{2}{U}{U}", + "Temple of Cyclical Time", + new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GOD); - this.power = new MageInt(4); - this.toughness = new MageInt(3); + // Ojer Pakpatiq, Deepest Epoch + this.getLeftHalfCard().setPT(4, 3); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // Whenever you cast an instant spell from your hand, it gains rebound. - this.addAbility(new SpellCastControllerTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( Zone.BATTLEFIELD, new OjerPakpatiqDeepestEpochGainReboundEffect(), filter, false, SetTargetPointer.SPELL, Zone.HAND )); // When Ojer Pakpatiq dies, return it to the battlefield tapped and transformed under its owner's control with three time counters on it. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesSourceTriggeredAbility(new OjerPakpatiqDeepestEpochTrigger())); + this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerPakpatiqDeepestEpochTrigger())); + + // Temple of Cyclical Time + // {T}: Add {U}. Remove a time counter from Temple of Cyclical Time. + Ability ability = new BlueManaAbility(); + ability.addEffect(new RemoveCounterSourceEffect(CounterType.TIME.createInstance())); + this.getRightHalfCard().addAbility(ability); + + // {2}{U}, {T}: Transform Temple of Cyclical Time. Activate only if it has no time counters on it and only as a sorcery. + ability = new ActivateIfConditionActivatedAbility( + new TransformSourceEffect(), new ManaCostsImpl<>("{2}{U}"), condition + ).setTiming(TimingRule.SORCERY); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability); } private OjerPakpatiqDeepestEpoch(final OjerPakpatiqDeepestEpoch card) { @@ -68,7 +88,7 @@ public final class OjerPakpatiqDeepestEpoch extends CardImpl { } /** - * Inspired by {@link mage.cards.n.NarsetTranscendent} + * Inspired by {@link NarsetTranscendent} */ class OjerPakpatiqDeepestEpochGainReboundEffect extends ContinuousEffectImpl { diff --git a/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java b/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java index 21ff3486692..1241a2425e7 100644 --- a/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java +++ b/Mage.Sets/src/mage/cards/o/OjerTaqDeepestFoundation.java @@ -1,48 +1,64 @@ package mage.cards.o; -import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.mana.WhiteManaAbility; 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.CreateTokenEvent; import mage.game.events.GameEvent; import mage.players.Player; +import mage.watchers.common.PlayerAttackedWatcher; import java.util.UUID; /** * @author Susucr */ -public final class OjerTaqDeepestFoundation extends CardImpl { +public final class OjerTaqDeepestFoundation extends TransformingDoubleFacedCard { public OjerTaqDeepestFoundation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); - this.secondSideCardClazz = mage.cards.t.TempleOfCivilization.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{4}{W}{W}", + "Temple of Civilization", + new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, ""); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.GOD); - this.power = new MageInt(6); - this.toughness = new MageInt(6); + // Ojer Taq, Deepest Foundation + this.getLeftHalfCard().setPT(6, 6); // Vigilance - this.addAbility(VigilanceAbility.getInstance()); + this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance()); // If one or more creature tokens would be created under your control, three times that many of those tokens are created instead. - this.addAbility(new SimpleStaticAbility(new OjerTaqDeepestFoundationTriplingEffect())); + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new OjerTaqDeepestFoundationTriplingEffect())); // When Ojer Taq dies, return it to the battlefield tapped and transformed under its owner's control. - this.addAbility(new TransformAbility()); - this.addAbility(new DiesSourceTriggeredAbility(new OjerTaqDeepestFoundationTransformEffect())); + this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerTaqDeepestFoundationTransformEffect())); + + // Temple of Civilization + // {T}: Add {W}. + this.getRightHalfCard().addAbility(new WhiteManaAbility()); + + // {2}{W}, {T}: Transform Temple of Civilization. Activate only if you attacked with three or more creatures this turn and only as a sorcery. + Ability ability = new ActivateIfConditionActivatedAbility( + new TransformSourceEffect(), new ManaCostsImpl<>("{2}{W}"), TempleOfCivilizationCondition.instance + ).setTiming(TimingRule.SORCERY); + ability.addCost(new TapSourceCost()); + ability.addWatcher(new PlayerAttackedWatcher()); + this.getRightHalfCard().addAbility(ability); } private OjerTaqDeepestFoundation(final OjerTaqDeepestFoundation card) { @@ -124,3 +140,18 @@ class OjerTaqDeepestFoundationTriplingEffect extends ReplacementEffectImpl { return false; } } + +enum TempleOfCivilizationCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + PlayerAttackedWatcher watcher = game.getState().getWatcher(PlayerAttackedWatcher.class); + return watcher != null && watcher.getNumberOfAttackersCurrentTurn(source.getControllerId()) >= 3; + } + + @Override + public String toString() { + return "you attacked with three or more creatures this turn"; + } +} diff --git a/Mage.Sets/src/mage/cards/o/OkibaReckonerRaid.java b/Mage.Sets/src/mage/cards/o/OkibaReckonerRaid.java index ef5f69bdea1..988e0b33893 100644 --- a/Mage.Sets/src/mage/cards/o/OkibaReckonerRaid.java +++ b/Mage.Sets/src/mage/cards/o/OkibaReckonerRaid.java @@ -1,36 +1,45 @@ package mage.cards.o; import mage.abilities.common.SagaAbility; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effects; import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LoseLifeOpponentsEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +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.FilterPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class OkibaReckonerRaid extends CardImpl { +public final class OkibaReckonerRaid extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterPermanent(SubType.VEHICLE, "Vehicles"); public OkibaReckonerRaid(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{B}", + "Nezumi Road Captain", + new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.RAT, SubType.ROGUE}, "B"); - this.subtype.add(SubType.SAGA); - this.secondSideCardClazz = mage.cards.n.NezumiRoadCaptain.class; + // Okiba Reckoner Raid + this.getRightHalfCard().setPT(2, 2); // (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 loses 1 life and you gain 1 life. sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, + this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new Effects( new LoseLifeOpponentsEffect(1), new GainLifeEffect(1).concatBy("and") @@ -38,10 +47,18 @@ public final class OkibaReckonerRaid 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); + + // Nezumi Road Captain + // Menace + this.getRightHalfCard().addAbility(new MenaceAbility(false)); + + // Vehicles you control have menace. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + new MenaceAbility(true), Duration.WhileOnBattlefield, filter) + )); } private OkibaReckonerRaid(final OkibaReckonerRaid card) { diff --git a/Mage.Sets/src/mage/cards/o/OlagLudevicsHubris.java b/Mage.Sets/src/mage/cards/o/OlagLudevicsHubris.java deleted file mode 100644 index 9b9a6abc671..00000000000 --- a/Mage.Sets/src/mage/cards/o/OlagLudevicsHubris.java +++ /dev/null @@ -1,141 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.CopyEffect; -import mage.cards.*; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.game.ExileZone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.permanent.PermanentCard; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInExile; -import mage.util.CardUtil; -import mage.util.functions.CopyApplier; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class OlagLudevicsHubris extends CardImpl { - - public OlagLudevicsHubris(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ZOMBIE); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setBlue(true); - this.color.setBlack(true); - this.nightCard = true; - - // As this creature transforms in Olag, Ludevic's Hubris, it becomes a copy of a creature card exiled with it, except its name is Olag, Ludevic's Hubris, it's 4/4, and it's a legendary blue and black Zombie in addition to its other colors and types. Put a number of +1/+1 counters on Olag equal to the number of creature cards exiled with it. - this.addAbility(new SimpleStaticAbility(new OlagLudevicsHubrisEffect())); - } - - private OlagLudevicsHubris(final OlagLudevicsHubris card) { - super(card); - } - - @Override - public OlagLudevicsHubris copy() { - return new OlagLudevicsHubris(this); - } -} - -class OlagLudevicsHubrisEffect extends ReplacementEffectImpl { - - OlagLudevicsHubrisEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "as this creature transforms into {this}, it becomes a copy of a creature card exiled with it, " + - "except its name is Olag, Ludevic's Hubris, it's 4/4, and it's a legendary blue and black " + - "Zombie in addition to its other colors and types. Put a number of +1/+1 counters on {this} " + - "equal to the number of creature cards exiled with it"; - } - - private OlagLudevicsHubrisEffect(final OlagLudevicsHubrisEffect effect) { - super(effect); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); - if (exileZone == null) { - return false; - } - - Cards cards = new CardsImpl(exileZone); - cards.removeIf(uuid -> !game.getCard(uuid).isCreature(game)); - if (cards.isEmpty()) { - return false; - } - - Card copyFromCard = getCard(cards, source, game); - if (copyFromCard == null) { - return false; - } - Permanent newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game); - newBluePrint.assignNewId(); - CopyApplier applier = new OlagLudevicsHubrisCopyApplier(); - applier.apply(game, newBluePrint, source, source.getSourceId()); - CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, source.getSourceId()); - copyEffect.setApplier(applier); - Ability newAbility = source.copy(); - copyEffect.init(newAbility, game); - game.addEffect(copyEffect, newAbility); - return false; - } - - private Card getCard(Cards cards, Ability source, Game game) { - if (cards.size() == 1) { - return cards.getRandom(game); - } - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return cards.getRandom(game); - } - TargetCard target = new TargetCardInExile(StaticFilters.FILTER_CARD); - player.choose(outcome, target, source, game); - return cards.get(target.getFirstTarget(), game); - } - - @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; - } - - @Override - public OlagLudevicsHubrisEffect copy() { - return new OlagLudevicsHubrisEffect(this); - } -} - -class OlagLudevicsHubrisCopyApplier extends CopyApplier { - - @Override - public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) { - blueprint.setName("Olag, Ludevic's Hubris"); - blueprint.addSuperType(SuperType.LEGENDARY); - blueprint.addSubType(SubType.ZOMBIE); - blueprint.getColor().setBlue(true); - blueprint.getColor().setBlack(true); - blueprint.getPower().setModifiedBaseValue(4); - blueprint.getToughness().setModifiedBaseValue(4); - 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/OrderOfTheAlabasterHost.java b/Mage.Sets/src/mage/cards/o/OrderOfTheAlabasterHost.java deleted file mode 100644 index 32745385bf8..00000000000 --- a/Mage.Sets/src/mage/cards/o/OrderOfTheAlabasterHost.java +++ /dev/null @@ -1,41 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -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 OrderOfTheAlabasterHost extends CardImpl { - - public OrderOfTheAlabasterHost(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.KNIGHT); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setWhite(true); - this.color.setBlue(true); - this.nightCard = true; - - // Whenever Order of the Alabaster Host becomes blocked by a creature, that creature gets -1/-1 until end of turn. - this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new BoostTargetEffect(-1, -1).setText("that creature gets -1/-1 until end of turn"), false)); - } - - private OrderOfTheAlabasterHost(final OrderOfTheAlabasterHost card) { - super(card); - } - - @Override - public OrderOfTheAlabasterHost copy() { - return new OrderOfTheAlabasterHost(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OrderOfTheMirror.java b/Mage.Sets/src/mage/cards/o/OrderOfTheMirror.java index f76a36fd9d0..e5956a031da 100644 --- a/Mage.Sets/src/mage/cards/o/OrderOfTheMirror.java +++ b/Mage.Sets/src/mage/cards/o/OrderOfTheMirror.java @@ -1,12 +1,12 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; 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.BoostTargetEffect; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; @@ -15,20 +15,25 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class OrderOfTheMirror extends CardImpl { +public final class OrderOfTheMirror extends TransformingDoubleFacedCard { public OrderOfTheMirror(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.KNIGHT}, "{1}{U}", + "Order of the Alabaster Host", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.KNIGHT}, "WU"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.KNIGHT); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.o.OrderOfTheAlabasterHost.class; + // Order of the Mirror + this.getLeftHalfCard().setPT(2, 1); // {3}{W/P}: Transform Order of the Mirror. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{W/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{W/P}"))); + + // Order of the Alabaster Host + this.getRightHalfCard().setPT(3, 3); + + // Whenever Order of the Alabaster Host becomes blocked by a creature, that creature gets -1/-1 until end of turn. + this.getRightHalfCard().addAbility(new BecomesBlockedByCreatureTriggeredAbility(new BoostTargetEffect(-1, -1).setText("the blocking creature gets -1/-1 until end of turn"), false)); } private OrderOfTheMirror(final OrderOfTheMirror card) { 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/o/OrmendahlTheCorrupter.java b/Mage.Sets/src/mage/cards/o/OrmendahlTheCorrupter.java deleted file mode 100644 index 146362a66fb..00000000000 --- a/Mage.Sets/src/mage/cards/o/OrmendahlTheCorrupter.java +++ /dev/null @@ -1,59 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.keyword.FlyingAbility; -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 mage.filter.StaticFilters; -import mage.target.common.TargetControlledPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class OrmendahlTheCorrupter extends CardImpl { - - public OrmendahlTheCorrupter(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(6); - this.toughness = new MageInt(6); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - - // Sacrifice another creature: Draw a card. - this.addAbility(new SimpleActivatedAbility( - new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - )); - } - - private OrmendahlTheCorrupter(final OrmendahlTheCorrupter card) { - super(card); - } - - @Override - public OrmendahlTheCorrupter copy() { - return new OrmendahlTheCorrupter(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OsseousExhale.java b/Mage.Sets/src/mage/cards/o/OsseousExhale.java index 5323451fb8a..8c58f52df89 100644 --- a/Mage.Sets/src/mage/cards/o/OsseousExhale.java +++ b/Mage.Sets/src/mage/cards/o/OsseousExhale.java @@ -4,9 +4,10 @@ import mage.abilities.condition.common.BeheldDragonCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.common.TargetAttackingOrBlockingCreature; @@ -21,7 +22,7 @@ public final class OsseousExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // As an additional cost to cast this spell, you may behold a Dragon. - this.addAbility(new BeholdDragonAbility()); + this.addAbility(new BeholdAbility(BeholdType.DRAGON)); // Osseous Exhale deals 5 damage to target attacking or blocking creature. If a Dragon was beheld, you gain 2 life. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/o/OteclanLandmark.java b/Mage.Sets/src/mage/cards/o/OteclanLandmark.java index 214752e856a..664238f4970 100644 --- a/Mage.Sets/src/mage/cards/o/OteclanLandmark.java +++ b/Mage.Sets/src/mage/cards/o/OteclanLandmark.java @@ -1,28 +1,60 @@ package mage.cards.o; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.keyword.CraftAbility; -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.filter.FilterPermanent; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.target.TargetPermanent; import java.util.UUID; /** * @author TheElk801 */ -public final class OteclanLandmark extends CardImpl { +public final class OteclanLandmark extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterAttackingCreature("attacking creature without flying"); + + static { + filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } public OteclanLandmark(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{W}"); - this.secondSideCardClazz = mage.cards.o.OteclanLevitator.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{W}", + "Oteclan Levitator", + new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "W"); + + // Oteclan Landmark + this.getRightHalfCard().setPT(1, 4); // When Oteclan Landmark enters the battlefield, scry 2. - this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2))); // Craft with artifact {2}{W} - this.addAbility(new CraftAbility("{2}{W}")); + this.getLeftHalfCard().addAbility(new CraftAbility("{2}{W}")); + + // Oteclan Levitator + this.getRightHalfCard().setPT(1, 4); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever Oteclan Levitator attacks, target attacking creature without flying gains flying until end of turn. + Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance())); + ability.addTarget(new TargetPermanent(filter)); + this.getRightHalfCard().addAbility(ability); } private OteclanLandmark(final OteclanLandmark card) { diff --git a/Mage.Sets/src/mage/cards/o/OteclanLevitator.java b/Mage.Sets/src/mage/cards/o/OteclanLevitator.java deleted file mode 100644 index d017143a0fa..00000000000 --- a/Mage.Sets/src/mage/cards/o/OteclanLevitator.java +++ /dev/null @@ -1,57 +0,0 @@ -package mage.cards.o; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterAttackingCreature; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AbilityPredicate; -import mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class OteclanLevitator extends CardImpl { - - private static final FilterPermanent filter = new FilterAttackingCreature("attacking creature without flying"); - - static { - filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); - } - - public OteclanLevitator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.GOLEM); - this.power = new MageInt(1); - this.toughness = new MageInt(4); - this.nightCard = true; - this.color.setWhite(true); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever Oteclan Levitator attacks, target attacking creature without flying gains flying until end of turn. - Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance())); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - } - - private OteclanLevitator(final OteclanLevitator card) { - super(card); - } - - @Override - public OteclanLevitator copy() { - return new OteclanLevitator(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OutlandLiberator.java b/Mage.Sets/src/mage/cards/o/OutlandLiberator.java index bed09388e24..ae9a21801a1 100644 --- a/Mage.Sets/src/mage/cards/o/OutlandLiberator.java +++ b/Mage.Sets/src/mage/cards/o/OutlandLiberator.java @@ -1,17 +1,21 @@ package mage.cards.o; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DestroyTargetEffect; 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.FilterArtifactOrEnchantmentPermanent; +import mage.filter.predicate.permanent.DefendingPlayerControlsSourceAttackingPredicate; import mage.target.TargetPermanent; import java.util.UUID; @@ -19,25 +23,49 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class OutlandLiberator extends CardImpl { +public final class OutlandLiberator extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter + = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment defending player controls"); + + static { + filter.add(DefendingPlayerControlsSourceAttackingPredicate.instance); + } public OutlandLiberator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{1}{G}", + "Frenzied Trapbreaker", + 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(2); - this.secondSideCardClazz = mage.cards.f.FrenziedTrapbreaker.class; + // Outland Liberator + this.getLeftHalfCard().setPT(2, 2); // {1}, Sacrifice Outland Liberator: Destroy target artifact or enchantment. Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(1)); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Frenzied Trapbreaker + this.getRightHalfCard().setPT(3, 3); + + // {1}, Sacrifice Frenzied Trapbreaker: Destroy target artifact or enchantment. + ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(1)); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getRightHalfCard().addAbility(ability); + + // Whenever Frenzied Trapbreaker attacks, destroy target artifact or enchantment defending player controls. + ability = new AttacksTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetPermanent(filter)); + this.getRightHalfCard().addAbility(ability); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private OutlandLiberator(final OutlandLiberator card) { diff --git a/Mage.Sets/src/mage/cards/o/OverloadedMageRing.java b/Mage.Sets/src/mage/cards/o/OverloadedMageRing.java deleted file mode 100644 index 65100d111e6..00000000000 --- a/Mage.Sets/src/mage/cards/o/OverloadedMageRing.java +++ /dev/null @@ -1,53 +0,0 @@ -package mage.cards.o; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.SacrificeSourceCost; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -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.FilterSpell; -import mage.target.TargetSpell; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class OverloadedMageRing extends CardImpl { - - private static final FilterSpell filter = new FilterSpell("spell you control"); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - } - - public OverloadedMageRing(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.color.setBlue(true); - this.nightCard = true; - - // {1}, {T}, Sacrifice Overloaded Mage-Ring: Copy target spell you control. You may choose new targets for the copy. - Ability ability = new SimpleActivatedAbility( - new CopyTargetStackObjectEffect(false, false, true), new GenericManaCost(1) - ); - ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeSourceCost()); - ability.addTarget(new TargetSpell(filter)); - this.addAbility(ability); - } - - private OverloadedMageRing(final OverloadedMageRing card) { - super(card); - } - - @Override - public OverloadedMageRing copy() { - return new OverloadedMageRing(this); - } -} diff --git a/Mage.Sets/src/mage/cards/o/OverwhelmedArchivist.java b/Mage.Sets/src/mage/cards/o/OverwhelmedArchivist.java index 22e968cb057..38d597fa611 100644 --- a/Mage.Sets/src/mage/cards/o/OverwhelmedArchivist.java +++ b/Mage.Sets/src/mage/cards/o/OverwhelmedArchivist.java @@ -1,12 +1,12 @@ package mage.cards.o; -import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.keyword.DisturbAbility; -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; @@ -15,22 +15,34 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class OverwhelmedArchivist extends CardImpl { +public final class OverwhelmedArchivist extends TransformingDoubleFacedCard { public OverwhelmedArchivist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{2}{U}", + "Archive Haunt", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT, SubType.WIZARD}, "U"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(3); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.a.ArchiveHaunt.class; + // Overwhelmed Archivist + this.getLeftHalfCard().setPT(3, 2); // When Overwhelmed Archivist enters the battlefield, draw a card, then discard a card. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1))); // Disturb {3}{U} - this.addAbility(new DisturbAbility(this, "{3}{U}")); + this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{3}{U}")); + + // Archive Haunt + this.getRightHalfCard().setPT(2, 1); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever Archive Haunt attacks, draw a card, then discard a card. + this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new DrawDiscardControllerEffect(1, 1))); + + // If Archive Haunt would be put into a graveyard from anywhere, exile it instead. + this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility()); } private OverwhelmedArchivist(final OverwhelmedArchivist card) { 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/PanickedBystander.java b/Mage.Sets/src/mage/cards/p/PanickedBystander.java index fc914a322bb..ddbd9211755 100644 --- a/Mage.Sets/src/mage/cards/p/PanickedBystander.java +++ b/Mage.Sets/src/mage/cards/p/PanickedBystander.java @@ -1,20 +1,20 @@ package mage.cards.p; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.YouGainedLifeCondition; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.ControllerGainedLifeCount; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.SubType; -import mage.constants.TargetController; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.StaticFilters; import mage.watchers.common.PlayerGainedLifeWatcher; @@ -23,30 +23,45 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class PanickedBystander extends CardImpl { +public final class PanickedBystander extends TransformingDoubleFacedCard { private static final Condition condition = new YouGainedLifeCondition(ComparisonType.MORE_THAN, 2); public PanickedBystander(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.PEASANT}, "{1}{W}", + "Cackling Culprit", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ROGUE}, "B" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.PEASANT); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.secondSideCardClazz = mage.cards.c.CacklingCulprit.class; + // Panicked Bystander + this.getLeftHalfCard().setPT(2, 2); // Whenever Panicked Bystander or another creature you control dies, you gain 1 life. - this.addAbility(new DiesThisOrAnotherTriggeredAbility( + this.getLeftHalfCard().addAbility(new DiesThisOrAnotherTriggeredAbility( new GainLifeEffect(1), false, StaticFilters.FILTER_CONTROLLED_CREATURE )); // At the beginning of your end step, if you gained 3 or more life this turn, transform Panicked Bystander. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility( + Ability ability = new BeginningOfEndStepTriggeredAbility( TargetController.YOU, new TransformSourceEffect(), false, condition - ).addHint(ControllerGainedLifeCount.getHint()), new PlayerGainedLifeWatcher()); + ).addHint(ControllerGainedLifeCount.getHint()); + ability.addWatcher(new PlayerGainedLifeWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Cackling Culprit + this.getRightHalfCard().setPT(3, 5); + + // Whenever Cackling Culprit or another creature you control dies, you gain 1 life. + this.getRightHalfCard().addAbility(new DiesThisOrAnotherTriggeredAbility( + new GainLifeEffect(1), false, StaticFilters.FILTER_CONTROLLED_CREATURE + )); + + // {1}{B}: Cackling Culprit gains deathtouch until end of turn. + this.getRightHalfCard().addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect( + DeathtouchAbility.getInstance(), Duration.EndOfTurn + ), new ManaCostsImpl<>("{1}{B}"))); } private PanickedBystander(final PanickedBystander card) { diff --git a/Mage.Sets/src/mage/cards/p/PathOfMettle.java b/Mage.Sets/src/mage/cards/p/PathOfMettle.java index df91c7112e3..d1b90ba4071 100644 --- a/Mage.Sets/src/mage/cards/p/PathOfMettle.java +++ b/Mage.Sets/src/mage/cards/p/PathOfMettle.java @@ -1,28 +1,39 @@ package mage.cards.p; -import java.util.UUID; - +import mage.abilities.Ability; import mage.abilities.common.AttacksWithCreaturesTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +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.DamageAllEffect; +import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.AnyColorManaAbility; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SuperType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.RandomUtil; +import mage.watchers.common.AttackedThisTurnWatcher; + +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; /** * @author LevelX2 */ -public final class PathOfMettle extends CardImpl { +public final class PathOfMettle extends TransformingDoubleFacedCard { private static final FilterCreaturePermanent filterDamage = new FilterCreaturePermanent("creature that doesn't have first strike, double strike, vigilance, or haste"); private static final FilterCreaturePermanent filterTransform = new FilterCreaturePermanent("creatures that have first strike, double strike, vigilance, and/or haste"); @@ -45,18 +56,32 @@ public final class PathOfMettle extends CardImpl { } public PathOfMettle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{W}"); - - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.m.MetzaliTowerOfTriumph.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{R}{W}", + "Metzali, Tower of Triumph", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "" + ); + // Path of Mettle // When Path of Mettle enters the battlefield, it deals 1 damage to each creature that doesn't have first strike, double strike, vigilance, or haste. - this.addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(1, "it", filterDamage))); + this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(1, "it", filterDamage))); // Whenever you attack with at least two creatures that have first strike, double strike, vigilance, and/or haste, transform Path of Mettle. - this.addAbility(new TransformAbility()); - this.addAbility(new AttacksWithCreaturesTriggeredAbility(new TransformSourceEffect(), 2, filterTransform).setTriggerPhrase(triggerPhrase)); + this.getLeftHalfCard().addAbility(new AttacksWithCreaturesTriggeredAbility(new TransformSourceEffect(), 2, filterTransform).setTriggerPhrase(triggerPhrase)); + + // Metzali, Tower of Triumph + // {t}: Add one mana of any color. + this.getRightHalfCard().addAbility(new AnyColorManaAbility()); + + // {1}{R}, {T}: Metzali, Tower of Triumph deals 2 damage to each opponent. + Ability ability = new SimpleActivatedAbility(new DamagePlayersEffect(2, TargetController.OPPONENT), new ManaCostsImpl<>("{1}{R}")); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability); + + // {2}{W}, {T}: Choose a creature at random that attacked this turn. Destroy that creature. + ability = new SimpleActivatedAbility(new MetzaliTowerOfTriumphDestroyEffect(), new ManaCostsImpl<>("{2}{W}")); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability); } private PathOfMettle(final PathOfMettle card) { @@ -68,3 +93,34 @@ public final class PathOfMettle extends CardImpl { return new PathOfMettle(this); } } + +class MetzaliTowerOfTriumphDestroyEffect extends OneShotEffect { + + MetzaliTowerOfTriumphDestroyEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "choose a creature at random that attacked this turn. Destroy that creature"; + } + + private MetzaliTowerOfTriumphDestroyEffect(final MetzaliTowerOfTriumphDestroyEffect effect) { + super(effect); + } + + @Override + public MetzaliTowerOfTriumphDestroyEffect copy() { + return new MetzaliTowerOfTriumphDestroyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = RandomUtil.randomFromCollection( + game.getState() + .getWatcher(AttackedThisTurnWatcher.class) + .getAttackedThisTurnCreatures() + .stream() + .map(mor -> mor.getPermanent(game)) + .filter(Objects::nonNull) + .collect(Collectors.toSet()) + ); + return permanent != null && permanent.destroy(source, game); + } +} 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..6095f5afecf --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PerfectIntimidation.java @@ -0,0 +1,44 @@ +package mage.cards.p; + +import mage.abilities.Mode; +import mage.abilities.effects.common.ExileFromZoneTargetEffect; +import mage.abilities.effects.common.counter.RemoveAllCountersPermanentTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +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 ExileFromZoneTargetEffect( + Zone.HAND, StaticFilters.FILTER_CARD_CARDS, 2, false + )); + 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); + } +} diff --git a/Mage.Sets/src/mage/cards/p/Personify.java b/Mage.Sets/src/mage/cards/p/Personify.java new file mode 100644 index 00000000000..11e418dbf33 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/Personify.java @@ -0,0 +1,36 @@ +package mage.cards.p; + +import java.util.UUID; + +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.ShapeshifterColorlessToken; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author muz + */ +public final class Personify extends CardImpl { + + public Personify(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); + + // Exile target creature you control, then return that card to the battlefield under its owner's control. Create a 1/1 colorless Shapeshifter creature token with changeling. + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, true)); + this.getSpellAbility().addEffect(new CreateTokenEffect(new ShapeshifterColorlessToken())); + } + + private Personify(final Personify card) { + super(card); + } + + @Override + public Personify copy() { + return new Personify(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PesteredWellguard.java b/Mage.Sets/src/mage/cards/p/PesteredWellguard.java new file mode 100644 index 00000000000..383ba82bbbd --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PesteredWellguard.java @@ -0,0 +1,39 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.common.BecomesTappedSourceTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.FaerieBlueBlackToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PesteredWellguard extends CardImpl { + + public PesteredWellguard(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever this creature becomes tapped, create a 1/1 blue and black Faerie creature token with flying. + this.addAbility(new BecomesTappedSourceTriggeredAbility(new CreateTokenEffect(new FaerieBlueBlackToken()))); + } + + private PesteredWellguard(final PesteredWellguard card) { + super(card); + } + + @Override + public PesteredWellguard copy() { + return new PesteredWellguard(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PhoenixWardenOfFire.java b/Mage.Sets/src/mage/cards/p/PhoenixWardenOfFire.java deleted file mode 100644 index 9a9ff1da417..00000000000 --- a/Mage.Sets/src/mage/cards/p/PhoenixWardenOfFire.java +++ /dev/null @@ -1,125 +0,0 @@ -package mage.cards.p; - -import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterCard; -import mage.filter.common.FilterCreatureCard; -import mage.game.Game; -import mage.target.common.TargetCardInYourGraveyard; -import mage.util.CardUtil; - -import java.util.Objects; -import java.util.Set; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PhoenixWardenOfFire extends CardImpl { - - public PhoenixWardenOfFire(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.PHOENIX); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.nightCard = true; - this.color.setRed(true); - this.color.setWhite(true); - - // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); - - // I, II -- Rising Flames -- Phoenix deals 2 damage to each opponent. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, ability -> { - ability.addEffect(new DamagePlayersEffect(2, TargetController.OPPONENT)); - ability.withFlavorWord("Rising Flames"); - }); - - // III -- Flames of Rebirth -- Return any number of target creature cards with total mana value 6 or less from your graveyard to the battlefield. Exile Phoenix, then return it to the battlefield. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> { - ability.addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); - ability.addEffect(new ExileSourceAndReturnFaceUpEffect()); - ability.addTarget(new PhoenixWardenOfFireTarget()); - ability.withFlavorWord("Flames of Rebirth"); - }); - this.addAbility(sagaAbility); - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - } - - private PhoenixWardenOfFire(final PhoenixWardenOfFire card) { - super(card); - } - - @Override - public PhoenixWardenOfFire copy() { - return new PhoenixWardenOfFire(this); - } -} - -class PhoenixWardenOfFireTarget extends TargetCardInYourGraveyard { - - private static final FilterCard filterStatic = new FilterCreatureCard( - "creature cards with total mana value 6 or less from your graveyard" - ); - - PhoenixWardenOfFireTarget() { - super(0, Integer.MAX_VALUE, filterStatic, false); - } - - private PhoenixWardenOfFireTarget(final PhoenixWardenOfFireTarget target) { - super(target); - } - - @Override - public PhoenixWardenOfFireTarget copy() { - return new PhoenixWardenOfFireTarget(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, 6, game - ); - } - - @Override - public Set possibleTargets(UUID sourceControllerId, Ability source, Game game) { - return CardUtil.checkPossibleTargetsTotalValueLimit( - this.getTargets(), - super.possibleTargets(sourceControllerId, source, game), - MageObject::getManaValue, 6, 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/p/PhyrexianSkyflayer.java b/Mage.Sets/src/mage/cards/p/PhyrexianSkyflayer.java deleted file mode 100644 index 765afc12b0d..00000000000 --- a/Mage.Sets/src/mage/cards/p/PhyrexianSkyflayer.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.p; - -import mage.MageInt; -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.SubType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PhyrexianSkyflayer extends CardImpl { - - public PhyrexianSkyflayer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.ARTIFICER); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.color.setWhite(true); - this.color.setRed(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Haste - this.addAbility(HasteAbility.getInstance()); - } - - private PhyrexianSkyflayer(final PhyrexianSkyflayer card) { - super(card); - } - - @Override - public PhyrexianSkyflayer copy() { - return new PhyrexianSkyflayer(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/PiercingExhale.java b/Mage.Sets/src/mage/cards/p/PiercingExhale.java index b9a1ef912a0..a6d0987b099 100644 --- a/Mage.Sets/src/mage/cards/p/PiercingExhale.java +++ b/Mage.Sets/src/mage/cards/p/PiercingExhale.java @@ -4,9 +4,10 @@ import mage.abilities.condition.common.BeheldDragonCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect; import mage.abilities.effects.keyword.SurveilEffect; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.BeholdType; import mage.constants.CardType; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -22,7 +23,7 @@ public final class PiercingExhale extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); // As an additional cost to cast this spell, you may behold a Dragon. - this.addAbility(new BeholdDragonAbility()); + this.addAbility(new BeholdAbility(BeholdType.DRAGON)); // Target creature you control deals damage equal to its power to target creature or planeswalker. If a Dragon was beheld, surveil 2. this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/p/PiousEvangel.java b/Mage.Sets/src/mage/cards/p/PiousEvangel.java index 1de94395713..54abaf03580 100644 --- a/Mage.Sets/src/mage/cards/p/PiousEvangel.java +++ b/Mage.Sets/src/mage/cards/p/PiousEvangel.java @@ -1,57 +1,69 @@ package mage.cards.p; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; 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.constants.Zone; +import mage.constants.TargetController; import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; 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 PiousEvangel extends CardImpl { +public final class PiousEvangel extends TransformingDoubleFacedCard { private static final FilterControlledPermanent filter2 = new FilterControlledPermanent("another permanent"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); static { filter2.add(AnotherPredicate.instance); + filter.add(TargetController.YOU.getControllerPredicate()); } public PiousEvangel(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(2); - this.toughness = new MageInt(2); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CLERIC}, "{2}{W}", + "Wayward Disciple", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.CLERIC}, "B" + ); - this.secondSideCardClazz = mage.cards.w.WaywardDisciple.class; + // Pious Evangel + this.getLeftHalfCard().setPT(2, 2); // Whenever Pious Evangel or another creature you control enters, you gain 1 life. - this.addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility(new GainLifeEffect(1), + this.getLeftHalfCard().addAbility(new EntersBattlefieldThisOrAnotherTriggeredAbility(new GainLifeEffect(1), StaticFilters.FILTER_PERMANENT_CREATURE, false, true)); // {2}, {T}, Sacrifice another permanent: Transform Pious Evangel. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new TransformSourceEffect(), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeTargetCost(filter2)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Wayward Disciple + this.getRightHalfCard().setPT(2, 4); + + // Whenever Wayward Disciple or another creature you control dies, target opponent loses 1 life and you gain 1 life. + Ability abilityBack = new DiesThisOrAnotherTriggeredAbility(new LoseLifeTargetEffect(1), false, filter); + abilityBack.addEffect(new GainLifeEffect(1).concatBy("and")); + abilityBack.addTarget(new TargetOpponent()); + this.getRightHalfCard().addAbility(abilityBack); } private PiousEvangel(final PiousEvangel card) { diff --git a/Mage.Sets/src/mage/cards/p/PitilessFists.java b/Mage.Sets/src/mage/cards/p/PitilessFists.java new file mode 100644 index 00000000000..a41322763c4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PitilessFists.java @@ -0,0 +1,54 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.FightEnchantedTargetEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PitilessFists extends CardImpl { + + public PitilessFists(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + + this.subtype.add(SubType.AURA); + + // Enchant creature you control + TargetPermanent auraTarget = new TargetControlledCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.addAbility(new EnchantAbility(auraTarget)); + + // When this Aura enters, enchanted creature fights up to one target creature an opponent controls. + Ability ability = new EntersBattlefieldTriggeredAbility(new FightEnchantedTargetEffect()); + ability.addTarget(new TargetOpponentsCreaturePermanent(0, 1)); + this.addAbility(ability); + + // Enchanted creature gets +2/+2. + this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(2, 2))); + } + + private PitilessFists(final PitilessFists card) { + super(card); + } + + @Override + public PitilessFists copy() { + return new PitilessFists(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PollutedCisternDimOubliette.java b/Mage.Sets/src/mage/cards/p/PollutedCisternDimOubliette.java new file mode 100644 index 00000000000..747c2a46bb0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PollutedCisternDimOubliette.java @@ -0,0 +1,153 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.UnlockThisDoorTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.effects.common.MillCardsControllerEffect; +import mage.cards.Card; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeGroupEvent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.Collection; +import java.util.Set; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PollutedCisternDimOubliette extends RoomCard { + + public PollutedCisternDimOubliette(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{1}{B}", "{4}{B}"); + + // 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. + this.getLeftHalfCard().addAbility(new PollutedCisternTriggeredAbility()); + + // Dim Oubliette + // When you unlock this door, mill three cards, then return a creature card from your graveyard to the battlefield. + Ability ability = new UnlockThisDoorTriggeredAbility(new MillCardsControllerEffect(3), false, false); + ability.addEffect(new DimOublietteEffect()); + this.getRightHalfCard().addAbility(ability); + } + + private PollutedCisternDimOubliette(final PollutedCisternDimOubliette card) { + super(card); + } + + @Override + public PollutedCisternDimOubliette copy() { + return new PollutedCisternDimOubliette(this); + } +} + +class PollutedCisternTriggeredAbility extends TriggeredAbilityImpl { + + private enum PollutedCisternValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Set cards = (Set) effect.getValue("cards"); + return cards != null + ? cards + .stream() + .map(card -> card.getCardType(game)) + .flatMap(Collection::stream) + .distinct() + .mapToInt(x -> 1) + .sum() + : 0; + } + + @Override + public PollutedCisternValue copy() { + return this; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "1"; + } + } + + PollutedCisternTriggeredAbility() { + super(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(PollutedCisternValue.instance) + .setText("each opponent loses 1 life for each card type among those cards")); + this.setTriggerPhrase("Whenever one or more cards are put into your graveyard from your library, "); + } + + private PollutedCisternTriggeredAbility(final PollutedCisternTriggeredAbility ability) { + super(ability); + } + + @Override + public PollutedCisternTriggeredAbility copy() { + return new PollutedCisternTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE_GROUP; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeGroupEvent zEvent = (ZoneChangeGroupEvent) event; + if (!Zone.GRAVEYARD.match(zEvent.getToZone()) + || !Zone.LIBRARY.match(zEvent.getFromZone()) + || !isControlledBy(zEvent.getPlayerId())) { + return false; + } + this.getAllEffects().setValue("cards", zEvent.getCards()); + return true; + } +} + +class DimOublietteEffect extends OneShotEffect { + + DimOublietteEffect() { + super(Outcome.Benefit); + staticText = ", then return a creature card from your graveyard to the battlefield"; + } + + private DimOublietteEffect(final DimOublietteEffect effect) { + super(effect); + } + + @Override + public DimOublietteEffect copy() { + return new DimOublietteEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null || player.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game) < 1) { + return false; + } + TargetCard target = new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD); + target.withNotTarget(true); + player.choose(outcome, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + return card != null && player.moveCards(card, Zone.BATTLEFIELD, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PolukranosEngineOfRuin.java b/Mage.Sets/src/mage/cards/p/PolukranosEngineOfRuin.java deleted file mode 100644 index a1489a1f9cf..00000000000 --- a/Mage.Sets/src/mage/cards/p/PolukranosEngineOfRuin.java +++ /dev/null @@ -1,65 +0,0 @@ -package mage.cards.p; - -import mage.MageInt; -import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.ReachAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.permanent.token.PhyrexianHydraWithLifelinkToken; -import mage.game.permanent.token.PhyrexianHydraWithReachToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PolukranosEngineOfRuin extends CardImpl { - - private static final FilterPermanent filter - = new FilterControlledPermanent(SubType.HYDRA, "nontoken Hydra you control"); - - static { - filter.add(TokenPredicate.FALSE); - } - - public PolukranosEngineOfRuin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.HYDRA); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - this.color.setWhite(true); - this.color.setGreen(true); - this.nightCard = true; - - // Reach - this.addAbility(ReachAbility.getInstance()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - - // Whenever Polukranos, Engine of Ruin or another nontoken Hydra you control dies, create a 3/3 green and white Phyrexian Hydra creature token with reach and a 3/3 green and white Phyrexian Hydra creature token with lifelink. - this.addAbility(new DiesThisOrAnotherTriggeredAbility( - new CreateTokenEffect(new PhyrexianHydraWithReachToken()).withAdditionalTokens(new PhyrexianHydraWithLifelinkToken()), false, filter - )); - } - - private PolukranosEngineOfRuin(final PolukranosEngineOfRuin card) { - super(card); - } - - @Override - public PolukranosEngineOfRuin copy() { - return new PolukranosEngineOfRuin(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/PolukranosReborn.java b/Mage.Sets/src/mage/cards/p/PolukranosReborn.java index 5b28e453528..41de09e41e7 100644 --- a/Mage.Sets/src/mage/cards/p/PolukranosReborn.java +++ b/Mage.Sets/src/mage/cards/p/PolukranosReborn.java @@ -1,39 +1,65 @@ package mage.cards.p; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.ReachAbility; -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.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.PhyrexianHydraWithLifelinkToken; +import mage.game.permanent.token.PhyrexianHydraWithReachToken; import java.util.UUID; /** * @author TheElk801 */ -public final class PolukranosReborn extends CardImpl { +public final class PolukranosReborn extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter + = new FilterControlledPermanent(SubType.HYDRA, "nontoken Hydra you control"); + + static { + filter.add(TokenPredicate.FALSE); + } public PolukranosReborn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{G}{G}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HYDRA}, "{G}{G}{G}", + "Polukranos, Engine of Ruin", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.HYDRA}, "GW"); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.HYDRA); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.secondSideCardClazz = mage.cards.p.PolukranosEngineOfRuin.class; + // Polukranos Reborn + this.getLeftHalfCard().setPT(4, 5); // Reach - this.addAbility(ReachAbility.getInstance()); + this.getLeftHalfCard().addAbility(ReachAbility.getInstance()); // {6}{W/P}: Transform Polukranos Reborn. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{6}{W/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{6}{W/P}"))); + + // Polukranos, Engine of Ruin + this.getRightHalfCard().setPT(6, 6); + + // Reach + this.getRightHalfCard().addAbility(ReachAbility.getInstance()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // Whenever Polukranos, Engine of Ruin or another nontoken Hydra you control dies, create a 3/3 green and white Phyrexian Hydra creature token with reach and a 3/3 green and white Phyrexian Hydra creature token with lifelink. + this.getRightHalfCard().addAbility(new DiesThisOrAnotherTriggeredAbility( + new CreateTokenEffect(new PhyrexianHydraWithReachToken()).withAdditionalTokens(new PhyrexianHydraWithLifelinkToken()), false, filter + )); } private PolukranosReborn(final PolukranosReborn card) { diff --git a/Mage.Sets/src/mage/cards/p/PoppetFactory.java b/Mage.Sets/src/mage/cards/p/PoppetFactory.java deleted file mode 100644 index 6f43a33be51..00000000000 --- a/Mage.Sets/src/mage/cards/p/PoppetFactory.java +++ /dev/null @@ -1,101 +0,0 @@ -package mage.cards.p; - -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PoppetFactory extends CardImpl { - - public PoppetFactory(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.color.setBlue(true); - this.nightCard = true; - - // Creature tokens you control lose all abilities and have base power and toughness 3/3. - this.addAbility(new SimpleStaticAbility(new PoppetFactoryEffect())); - - // At the beginning of your upkeep, you may transform Poppet Factory. - this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new TransformSourceEffect(), true - )); - } - - private PoppetFactory(final PoppetFactory card) { - super(card); - } - - @Override - public PoppetFactory copy() { - return new PoppetFactory(this); - } -} - -class PoppetFactoryEffect extends ContinuousEffectImpl { - - private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); - - static { - filter.add(TokenPredicate.TRUE); - } - - PoppetFactoryEffect() { - super(Duration.WhileOnBattlefield, Outcome.LoseAbility); - staticText = "creature tokens you control lose all abilities and have base power and toughness 3/3"; - } - - private PoppetFactoryEffect(final PoppetFactoryEffect effect) { - super(effect); - } - - @Override - public PoppetFactoryEffect copy() { - return new PoppetFactoryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { - for (Permanent permanent : game.getBattlefield().getActivePermanents( - filter, source.getControllerId(), source, game - )) { - switch (layer) { - case AbilityAddingRemovingEffects_6: - permanent.removeAllAbilities(source.getSourceId(), game); - break; - case PTChangingEffects_7: - if (sublayer == SubLayer.SetPT_7b) { - permanent.getPower().setModifiedBaseValue(3); - permanent.getToughness().setModifiedBaseValue(3); - } - break; - } - } - return true; - } - - @Override - public boolean hasLayer(Layer layer) { - return layer == Layer.PTChangingEffects_7 - || layer == Layer.AbilityAddingRemovingEffects_6; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PoppetStitcher.java b/Mage.Sets/src/mage/cards/p/PoppetStitcher.java index 00b952d09a7..5fc530c84bf 100644 --- a/Mage.Sets/src/mage/cards/p/PoppetStitcher.java +++ b/Mage.Sets/src/mage/cards/p/PoppetStitcher.java @@ -1,25 +1,27 @@ package mage.cards.p; -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; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.Hint; import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.TransformAbility; import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.SubType; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; import mage.game.permanent.token.ZombieDecayedToken; import java.util.UUID; @@ -27,7 +29,7 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class PoppetStitcher extends CardImpl { +public final class PoppetStitcher extends TransformingDoubleFacedCard { private static final FilterPermanent filter = new FilterControlledPermanent("you control three or more creature tokens"); @@ -41,25 +43,32 @@ public final class PoppetStitcher extends CardImpl { ); public PoppetStitcher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{2}{U}", + "Poppet Factory", + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "U"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - - this.secondSideCardClazz = mage.cards.p.PoppetFactory.class; + // Poppet Stitcher + this.getLeftHalfCard().setPT(2, 3); // Whenever you cast an instant or sorcery spell, create a 2/2 black Zombie creature token with decayed. - this.addAbility(new SpellCastControllerTriggeredAbility( + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility( new CreateTokenEffect(new ZombieDecayedToken()), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false )); // At the beginning of your upkeep, if you control three or more creature tokens, you may transform Poppet Sticher. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(), true) + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(), true) .withInterveningIf(condition).addHint(hint)); + + // Poppet Factory + // Creature tokens you control lose all abilities and have base power and toughness 3/3. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new PoppetFactoryEffect())); + + // At the beginning of your upkeep, you may transform Poppet Factory. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility( + new TransformSourceEffect(), true + )); } private PoppetStitcher(final PoppetStitcher card) { @@ -71,3 +80,57 @@ public final class PoppetStitcher extends CardImpl { return new PoppetStitcher(this); } } + +class PoppetFactoryEffect extends ContinuousEffectImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(TokenPredicate.TRUE); + } + + PoppetFactoryEffect() { + super(Duration.WhileOnBattlefield, Outcome.LoseAbility); + staticText = "creature tokens you control lose all abilities and have base power and toughness 3/3"; + } + + private PoppetFactoryEffect(final PoppetFactoryEffect effect) { + super(effect); + } + + @Override + public PoppetFactoryEffect copy() { + return new PoppetFactoryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + for (Permanent permanent : game.getBattlefield().getActivePermanents( + filter, source.getControllerId(), source, game + )) { + switch (layer) { + case AbilityAddingRemovingEffects_6: + permanent.removeAllAbilities(source.getSourceId(), game); + break; + case PTChangingEffects_7: + if (sublayer == SubLayer.SetPT_7b) { + permanent.getPower().setModifiedBaseValue(3); + permanent.getToughness().setModifiedBaseValue(3); + } + break; + } + } + return true; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.PTChangingEffects_7 + || layer == Layer.AbilityAddingRemovingEffects_6; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PortraitOfMichiko.java b/Mage.Sets/src/mage/cards/p/PortraitOfMichiko.java deleted file mode 100644 index 305f77ab110..00000000000 --- a/Mage.Sets/src/mage/cards/p/PortraitOfMichiko.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.p; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -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.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PortraitOfMichiko extends CardImpl { - - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - StaticFilters.FILTER_PERMANENT_CONTROLLED_ARTIFACT_OR_ENCHANTMENT - ); - - public PortraitOfMichiko(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(0); - this.toughness = new MageInt(0); - this.color.setWhite(true); - this.nightCard = true; - - // Portrait of Michiko gets +1/+1 for each artifact and/or enchantment you control. - this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(xValue, xValue, Duration.WhileOnBattlefield) - .setText("{this} gets +1/+1 for each artifact and/or enchantment you control"))); - } - - private PortraitOfMichiko(final PortraitOfMichiko card) { - super(card); - } - - @Override - public PortraitOfMichiko copy() { - return new PortraitOfMichiko(this); - } -} 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/p/PrickleFaeries.java b/Mage.Sets/src/mage/cards/p/PrickleFaeries.java deleted file mode 100644 index 331dcf20681..00000000000 --- a/Mage.Sets/src/mage/cards/p/PrickleFaeries.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.p; - -import mage.MageInt; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.CardsInHandCondition; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PrickleFaeries extends CardImpl { - - private static final Condition condition = new CardsInHandCondition(ComparisonType.FEWER_THAN, 3, TargetController.ACTIVE); - - public PrickleFaeries(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.FAERIE); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setBlack(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand, Prickle Faeries deals 2 damage to them. - this.addAbility(new BeginningOfUpkeepTriggeredAbility( - Zone.BATTLEFIELD, TargetController.OPPONENT, - new DamageTargetEffect(2).withTargetDescription("them"), false - ).withInterveningIf(condition)); - } - - private PrickleFaeries(final PrickleFaeries card) { - super(card); - } - - @Override - public PrickleFaeries copy() { - return new PrickleFaeries(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/PridefulFeastling.java b/Mage.Sets/src/mage/cards/p/PridefulFeastling.java new file mode 100644 index 00000000000..cd7158ac697 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PridefulFeastling.java @@ -0,0 +1,40 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.keyword.ChangelingAbility; +import mage.abilities.keyword.LifelinkAbility; +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 PridefulFeastling extends CardImpl { + + public PridefulFeastling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + } + + private PridefulFeastling(final PridefulFeastling card) { + super(card); + } + + @Override + public PridefulFeastling copy() { + return new PridefulFeastling(this); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrimalAmulet.java b/Mage.Sets/src/mage/cards/p/PrimalAmulet.java index fcf75d1ecbf..d4a7aec5b9e 100644 --- a/Mage.Sets/src/mage/cards/p/PrimalAmulet.java +++ b/Mage.Sets/src/mage/cards/p/PrimalAmulet.java @@ -1,30 +1,40 @@ package mage.cards.p; import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CopyTargetStackObjectEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.AnyColorManaAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.StaticFilters; +import mage.filter.common.FilterInstantOrSorcerySpell; import mage.filter.predicate.Predicates; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.stack.Spell; import mage.players.Player; +import mage.target.targetpointer.FixedTarget; import java.util.UUID; /** * @author TheElk801 */ -public final class PrimalAmulet extends CardImpl { +public final class PrimalAmulet extends TransformingDoubleFacedCard { private static final FilterCard filter = new FilterCard("instant and sorcery spells"); @@ -36,20 +46,31 @@ public final class PrimalAmulet extends CardImpl { } public PrimalAmulet(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); - this.secondSideCardClazz = mage.cards.p.PrimalWellspring.class; + super(ownerId, setInfo, + new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{4}", + "Primal Wellspring", + new CardType[]{CardType.LAND}, new SubType[]{}, ""); + // Primal Amulet // 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, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it. - this.addAbility(new TransformAbility()); Ability ability = new SpellCastControllerTriggeredAbility( new AddCountersSourceEffect(CounterType.CHARGE.createInstance()), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, false ); ability.addEffect(new PrimalAmuletEffect()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Primal Wellspring + // Add one mana of any color. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy. + Ability manaAbility = new AnyColorManaAbility(); + manaAbility.addEffect(new CreateDelayedTriggeredAbilityEffect(new PrimalWellspringTriggeredAbility( + new CopyTargetStackObjectEffect(true) + .setText("copy that spell and you may choose new targets for the copy")) + )); + this.getRightHalfCard().addAbility(manaAbility); } private PrimalAmulet(final PrimalAmulet card) { @@ -94,3 +115,58 @@ class PrimalAmuletEffect extends OneShotEffect { return true; } } + +class PrimalWellspringTriggeredAbility extends DelayedTriggeredAbility { + + private static final FilterInstantOrSorcerySpell filter = new FilterInstantOrSorcerySpell(); + + + public PrimalWellspringTriggeredAbility(Effect effect) { + super(effect, Duration.Custom, true, false); + setTriggerPhrase("When that mana is spent to cast an instant or sorcery spell, "); + } + + private PrimalWellspringTriggeredAbility(final PrimalWellspringTriggeredAbility ability) { + super(ability); + } + + @Override + public PrimalWellspringTriggeredAbility copy() { + return new PrimalWellspringTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.MANA_PAID; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getSourceId().equals(getSourceId())) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && filter.match(spell, getControllerId(), this, game)) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + } + return false; + } + + @Override + public boolean isInactive(Game game) { + if (super.isInactive(game)) { + return true; + } + + // must remove effect on empty mana pool to fix accumulate bug + Player player = game.getPlayer(this.getControllerId()); + if (player == null) { + return true; + } + + // if no mana in pool then it can be discarded + return player.getManaPool().getManaItems().stream().noneMatch(m -> m.getSourceId().equals(getSourceId())); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java deleted file mode 100644 index 024e7274a48..00000000000 --- a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java +++ /dev/null @@ -1,91 +0,0 @@ -package mage.cards.p; - -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.CopyTargetStackObjectEffect; -import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Zone; -import mage.filter.common.FilterInstantOrSorcerySpell; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.stack.Spell; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PrimalWellspring extends CardImpl { - - public PrimalWellspring(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.nightCard = true; - - // Add one mana of any color. - Ability ability = new AnyColorManaAbility(); - this.addAbility(ability); - - // When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy. - this.addAbility(new PrimalWellspringTriggeredAbility( - ability.getOriginalId(), new CopyTargetStackObjectEffect(true) - .setText("copy that spell and you may choose new targets for the copy") - )); - } - - private PrimalWellspring(final PrimalWellspring card) { - super(card); - } - - @Override - public PrimalWellspring copy() { - return new PrimalWellspring(this); - } -} - -class PrimalWellspringTriggeredAbility extends TriggeredAbilityImpl { - - private static final FilterInstantOrSorcerySpell filter = new FilterInstantOrSorcerySpell(); - - String abilityOriginalId; - - public PrimalWellspringTriggeredAbility(UUID abilityOriginalId, Effect effect) { - super(Zone.ALL, effect, false); - this.abilityOriginalId = abilityOriginalId.toString(); - setTriggerPhrase("When that mana is used to cast an instant or sorcery spell, "); - } - - private PrimalWellspringTriggeredAbility(final PrimalWellspringTriggeredAbility ability) { - super(ability); - this.abilityOriginalId = ability.abilityOriginalId; - } - - @Override - public PrimalWellspringTriggeredAbility copy() { - return new PrimalWellspringTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.MANA_PAID; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getData().equals(abilityOriginalId)) { - Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && filter.match(spell, getControllerId(), this, game)) { - for (Effect effect : getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); - } - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PrimordialPlasm.java b/Mage.Sets/src/mage/cards/p/PrimordialPlasm.java deleted file mode 100644 index bae0d2e9ea0..00000000000 --- a/Mage.Sets/src/mage/cards/p/PrimordialPlasm.java +++ /dev/null @@ -1,51 +0,0 @@ -package mage.cards.p; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.continuous.LoseAllAbilitiesTargetEffect; -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 mage.target.TargetPermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PrimordialPlasm extends CardImpl { - - public PrimordialPlasm(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.OOZE); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setGreen(true); - this.nightCard = true; - - // At the beginning of combat on your turn, another target creature gets +2/+2 and loses all abilities until end of turn. - Ability ability = new BeginningOfCombatTriggeredAbility( - new BoostTargetEffect(2, 2) - .setText("another target creature gets +2/+2") - ); - ability.addEffect(new LoseAllAbilitiesTargetEffect(Duration.EndOfTurn) - .setText("and loses all abilities until end of turn")); - ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); - this.addAbility(ability); - } - - private PrimordialPlasm(final PrimordialPlasm card) { - super(card); - } - - @Override - public PrimordialPlasm copy() { - return new PrimordialPlasm(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java index 881bab6e555..5f9011a72f0 100644 --- a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java +++ b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java @@ -1,19 +1,25 @@ - package mage.cards.p; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.mana.AnyColorManaAbility; +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.filter.StaticFilters; +import mage.game.ExileZone; import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInExile; import mage.target.common.TargetCreaturePermanent; import mage.util.CardUtil; @@ -23,24 +29,32 @@ import java.util.UUID; /** * @author LevelX2 */ -public final class ProfaneProcession extends CardImpl { +public final class ProfaneProcession extends TransformingDoubleFacedCard { public ProfaneProcession(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{B}"); - - this.supertype.add(SuperType.LEGENDARY); - - this.secondSideCardClazz = mage.cards.t.TombOfTheDuskRose.class; + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ENCHANTMENT}, new SubType[]{}, "{1}{W}{B}", + "Tomb of the Dusk Rose", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, ""); + // Profane Procession // {3}{W}{B}: Exile target creature. Then if there are three or more cards exiled with Profane Procession, transform it. - this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{3}{W}{B}")); ability.addEffect(new ConditionalOneShotEffect( new TransformSourceEffect(), ProfaneProcessionCondition.instance, "Then if there are three or more cards exiled with {this}, transform it" )); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Tomb of the Dusk Rose + // {T}: Add one mana of any color. + this.getRightHalfCard().addAbility(new AnyColorManaAbility()); + + // {2}{W}{B},{T} : Put a creature card exiled with this permanent onto the battlefield under your control. + ability = new SimpleActivatedAbility(new TombOfTheDuskRoseEffect(), new ManaCostsImpl<>("{2}{W}{B}")); + ability.addCost(new TapSourceCost()); + this.getRightHalfCard().addAbility(ability); } private ProfaneProcession(final ProfaneProcession card) { @@ -64,3 +78,37 @@ enum ProfaneProcessionCondition implements Condition { .isPresent(); } } + +class TombOfTheDuskRoseEffect extends OneShotEffect { + + TombOfTheDuskRoseEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "put a creature card exiled with this permanent onto the battlefield under your control"; + } + + private TombOfTheDuskRoseEffect(final TombOfTheDuskRoseEffect effect) { + super(effect); + } + + @Override + public TombOfTheDuskRoseEffect copy() { + return new TombOfTheDuskRoseEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + if (exileZone == null || exileZone.count(StaticFilters.FILTER_CARD_CREATURE, game) < 1) { + return false; + } + TargetCard targetCard = new TargetCardInExile(StaticFilters.FILTER_CARD_CREATURE, exileZone.getId()); + targetCard.withNotTarget(true); + controller.choose(outcome, targetCard, source, game); + Card card = game.getCard(targetCard.getFirstTarget()); + return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PucasEye.java b/Mage.Sets/src/mage/cards/p/PucasEye.java new file mode 100644 index 00000000000..6309fe6469c --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PucasEye.java @@ -0,0 +1,111 @@ +package mage.cards.p; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PucasEye extends CardImpl { + + public PucasEye(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // When this artifact enters, draw a card, then choose a color. This artifact becomes the chosen color. + Ability ability = new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)); + ability.addEffect(new PucasEyeConditionEffect()); + this.addAbility(ability); + + // {3}, {T}: Draw a card. Activate only if there are five colors among permanents you control. + ability = new ActivateIfConditionActivatedAbility( + new DrawCardSourceControllerEffect(1), + new GenericManaCost(3), PucasEyeCondition.instance + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability.addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private PucasEye(final PucasEye card) { + super(card); + } + + @Override + public PucasEye copy() { + return new PucasEye(this); + } +} + +enum PucasEyeCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.calculate(game, source, null) == 5; + } + + @Override + public String toString() { + return "there are five colors among permanents you control"; + } +} + +class PucasEyeConditionEffect extends OneShotEffect { + + PucasEyeConditionEffect() { + super(Outcome.Benefit); + staticText = ", then choose a color. {this} becomes the chosen color"; + } + + private PucasEyeConditionEffect(final PucasEyeConditionEffect effect) { + super(effect); + } + + @Override + public PucasEyeConditionEffect copy() { + return new PucasEyeConditionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + ChoiceColor choice = new ChoiceColor(true); + player.choose(outcome, choice, game); + ObjectColor color = choice.getColor(); + if (color == null) { + return false; + } + game.informPlayers(CardUtil.getSourceLogName(game, source) + ": " + player.getLogName() + " chooses " + color.getDescription()); + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent == null) { + return false; + } + game.addEffect(new BecomesColorTargetEffect(color, false, Duration.Custom) + .setTargetPointer(new FixedTarget(permanent, game)), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PyreOfTheWorldTree.java b/Mage.Sets/src/mage/cards/p/PyreOfTheWorldTree.java deleted file mode 100644 index 860d255f500..00000000000 --- a/Mage.Sets/src/mage/cards/p/PyreOfTheWorldTree.java +++ /dev/null @@ -1,53 +0,0 @@ -package mage.cards.p; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.DiscardTargetCost; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.DiscardCardControllerTriggeredAbility; -import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.filter.StaticFilters; -import mage.target.common.TargetAnyTarget; -import mage.target.common.TargetCardInHand; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class PyreOfTheWorldTree extends CardImpl { - - public PyreOfTheWorldTree(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setRed(true); - this.nightCard = true; - - // Discard a land card: Pyre of the World Tree deals 2 damage to any target. - Ability ability = new SimpleActivatedAbility( - new DamageTargetEffect(2), - new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_LAND_A)) - ); - ability.addTarget(new TargetAnyTarget()); - this.addAbility(ability); - - // Whenever you discard a land card, exile the top card of your library. You may play that card this turn. - this.addAbility(new DiscardCardControllerTriggeredAbility( - new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), - false, StaticFilters.FILTER_CARD_LAND_A - )); - } - - private PyreOfTheWorldTree(final PyreOfTheWorldTree card) { - super(card); - } - - @Override - public PyreOfTheWorldTree copy() { - return new PyreOfTheWorldTree(this); - } -} diff --git a/Mage.Sets/src/mage/cards/p/PyreticPrankster.java b/Mage.Sets/src/mage/cards/p/PyreticPrankster.java index 0263319fa17..a8d94117d1f 100644 --- a/Mage.Sets/src/mage/cards/p/PyreticPrankster.java +++ b/Mage.Sets/src/mage/cards/p/PyreticPrankster.java @@ -1,33 +1,40 @@ package mage.cards.p; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DiesSourceTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.SacrificeOpponentsEffect; 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.filter.StaticFilters; import java.util.UUID; /** * @author TheElk801 */ -public final class PyreticPrankster extends CardImpl { +public final class PyreticPrankster extends TransformingDoubleFacedCard { public PyreticPrankster(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEVIL}, "{1}{R}", + "Glistening Goremonger", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.DEVIL}, "BR"); - this.subtype.add(SubType.DEVIL); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.g.GlisteningGoremonger.class; + // Pyretic Prankster + this.getLeftHalfCard().setPT(2, 1); // {3}{B/P}: Transform Pyretic Prankster. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{B/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{B/P}"))); + + // Glistening Goremonger + this.getRightHalfCard().setPT(3, 2); + + // When Glistening Goremonger dies, each opponent sacrifices an artifact or creature. + this.getRightHalfCard().addAbility(new DiesSourceTriggeredAbility(new SacrificeOpponentsEffect(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE))); } private PyreticPrankster(final PyreticPrankster card) { 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/RadiantGrace.java b/Mage.Sets/src/mage/cards/r/RadiantGrace.java index b725e33f23a..ae2c6055941 100644 --- a/Mage.Sets/src/mage/cards/r/RadiantGrace.java +++ b/Mage.Sets/src/mage/cards/r/RadiantGrace.java @@ -5,18 +5,21 @@ import mage.abilities.common.DiesAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TransformAbility; import mage.abilities.keyword.VigilanceAbility; -import mage.cards.Card; -import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.DoubleFacedCardHalf; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.TargetPlayer; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetOpponent; @@ -25,34 +28,52 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class RadiantGrace extends CardImpl { +public final class RadiantGrace extends TransformingDoubleFacedCard { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creatures enchanted player controls"); + + static { + filter.add(TargetController.ENCHANTED.getControllerPredicate()); + } public RadiantGrace(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); - - this.subtype.add(SubType.AURA); - this.secondSideCardClazz = mage.cards.r.RadiantRestraints.class; + super(ownerId, setInfo, + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA}, "{W}", + "Radiant Restraints", + new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.AURA, SubType.CURSE}, "W" + ); + // Radiant Grace // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); - this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - this.addAbility(new EnchantAbility(auraTarget)); + this.getLeftHalfCard().getSpellAbility().addTarget(auraTarget); + this.getLeftHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getLeftHalfCard().addAbility(new EnchantAbility(auraTarget)); // Enchanted creature gets +1/+0 and has vigilance. Ability ability = new SimpleStaticAbility(new BoostEnchantedEffect(1, 0)); ability.addEffect(new GainAbilityAttachedEffect( VigilanceAbility.getInstance(), AttachmentType.AURA ).setText("and has vigilance")); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // When enchanted creature dies, return Radiant Grace to the battlefield transformed under your control attached to target opponent. - this.addAbility(new TransformAbility()); ability = new DiesAttachedTriggeredAbility( new RadiantGraceEffect(), "enchanted creature", false ); ability.addTarget(new TargetOpponent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); + + // Radiant Restraints + // Enchant player + TargetPlayer auraTarget2 = new TargetPlayer(); + this.getRightHalfCard().getSpellAbility().addTarget(auraTarget2); + this.getRightHalfCard().getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getRightHalfCard().addAbility(new EnchantAbility(auraTarget2)); + + // Creatures enchanted player controls enter the battlefield tapped. + this.getRightHalfCard().addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(filter))); } private RadiantGrace(final RadiantGrace card) { @@ -90,13 +111,13 @@ class RadiantGraceEffect 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(), player.getId()); + game.getState().setValue("attachTo:" + card.getOtherSide().getId(), player.getId()); if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { player.addAttachment(card.getId(), source, game); } diff --git a/Mage.Sets/src/mage/cards/r/RadiantRestraints.java b/Mage.Sets/src/mage/cards/r/RadiantRestraints.java deleted file mode 100644 index 9fa133903b2..00000000000 --- a/Mage.Sets/src/mage/cards/r/RadiantRestraints.java +++ /dev/null @@ -1,56 +0,0 @@ -package mage.cards.r; - -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect; -import mage.abilities.keyword.EnchantAbility; -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.common.FilterCreaturePermanent; -import mage.target.TargetPlayer; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class RadiantRestraints extends CardImpl { - - private static final FilterCreaturePermanent filter - = new FilterCreaturePermanent("creatures enchanted player controls"); - - static { - filter.add(TargetController.ENCHANTED.getControllerPredicate()); - } - - public RadiantRestraints(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.subtype.add(SubType.AURA); - this.subtype.add(SubType.CURSE); - this.color.setWhite(true); - this.nightCard = true; - - // Enchant player - TargetPlayer auraTarget = new TargetPlayer(); - this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - this.addAbility(new EnchantAbility(auraTarget)); - - // Creatures enchanted player controls enter the battlefield tapped. - this.addAbility(new SimpleStaticAbility(new PermanentsEnterBattlefieldTappedEffect(filter))); - } - - private RadiantRestraints(final RadiantRestraints card) { - super(card); - } - - @Override - public RadiantRestraints copy() { - return new RadiantRestraints(this); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RaggedRecluse.java b/Mage.Sets/src/mage/cards/r/RaggedRecluse.java index 0f6e003e7ce..fbdd9a94619 100644 --- a/Mage.Sets/src/mage/cards/r/RaggedRecluse.java +++ b/Mage.Sets/src/mage/cards/r/RaggedRecluse.java @@ -1,40 +1,54 @@ package mage.cards.r; -import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.condition.common.ControllerDiscardedThisTurnCondition; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.common.ControllerDiscardedHint; -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.SetTargetPointer; import mage.constants.SubType; import mage.constants.TargetController; -import mage.watchers.common.DiscardedCardWatcher; import java.util.UUID; /** * @author TheElk801 */ -public final class RaggedRecluse extends CardImpl { +public final class RaggedRecluse extends TransformingDoubleFacedCard { public RaggedRecluse(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.PEASANT}, "{1}{B}", + "Odious Witch", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WARLOCK}, "B" + ); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.PEASANT); - this.power = new MageInt(2); - this.toughness = new MageInt(1); - this.secondSideCardClazz = mage.cards.o.OdiousWitch.class; + // Ragged Recluse + this.getLeftHalfCard().setPT(2, 1); // At the beginning of your end step, if you discarded a card this turn, transform Ragged Recluse. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfEndStepTriggeredAbility( + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility( TargetController.YOU, new TransformSourceEffect(), false, ControllerDiscardedThisTurnCondition.instance - ).addHint(ControllerDiscardedHint.instance), new DiscardedCardWatcher()); + ).addHint(ControllerDiscardedHint.instance)); + + // Odious Witch + this.getRightHalfCard().setPT(3, 3); + + // Whenever Odious Witch attacks, defending player loses 1 life and you gain 1 life. + Ability ability = new AttacksTriggeredAbility( + new LoseLifeTargetEffect(1) + .setText("defending player loses 1 life"), + false, null, SetTargetPointer.PLAYER + ); + ability.addEffect(new GainLifeEffect(1).concatBy("and")); + this.getRightHalfCard().addAbility(ability); } private RaggedRecluse(final RaggedRecluse card) { diff --git a/Mage.Sets/src/mage/cards/r/RainSlickedCopse.java b/Mage.Sets/src/mage/cards/r/RainSlickedCopse.java new file mode 100644 index 00000000000..1de1f6006e7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RainSlickedCopse.java @@ -0,0 +1,45 @@ +package mage.cards.r; + +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.CyclingAbility; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.mana.GreenManaAbility; +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 RainSlickedCopse extends CardImpl { + + public RainSlickedCopse(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add(SubType.FOREST); + this.subtype.add(SubType.ISLAND); + + // ({T}: Add {G} or {U}.) + this.addAbility(new GreenManaAbility()); + this.addAbility(new BlueManaAbility()); + + // This land enters tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // Cycling {2} + this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private RainSlickedCopse(final RainSlickedCopse card) { + super(card); + } + + @Override + public RainSlickedCopse copy() { + return new RainSlickedCopse(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/RaphaelTagTeamTough.java b/Mage.Sets/src/mage/cards/r/RaphaelTagTeamTough.java new file mode 100644 index 00000000000..92e837b15af --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RaphaelTagTeamTough.java @@ -0,0 +1,116 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.AdditionalCombatPhaseEffect; +import mage.abilities.effects.common.UntapAllEffect; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RaphaelTagTeamTough extends CardImpl { + + public RaphaelTagTeamTough(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.MUTANT); + this.subtype.add(SubType.NINJA); + this.subtype.add(SubType.TURTLE); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Menace + this.addAbility(new MenaceAbility()); + + // 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. + this.addAbility(new RaphaelTagTeamToughTriggeredAbility()); + } + + private RaphaelTagTeamTough(final RaphaelTagTeamTough card) { + super(card); + } + + @Override + public RaphaelTagTeamTough copy() { + return new RaphaelTagTeamTough(this); + } +} + +class RaphaelTagTeamToughTriggeredAbility extends TriggeredAbilityImpl { + + RaphaelTagTeamToughTriggeredAbility() { + super(Zone.BATTLEFIELD, new UntapAllEffect(StaticFilters.FILTER_ATTACKING_CREATURES)); + this.addEffect(new AdditionalCombatPhaseEffect().setText("After this combat phase, there is an additional combat phase")); + this.setTriggerPhrase("Whenever {this} deals combat damage to a player for the first time each turn, "); + this.addWatcher(new RaphaelTagTeamToughWatcher()); + } + + private RaphaelTagTeamToughTriggeredAbility(final RaphaelTagTeamToughTriggeredAbility ability) { + super(ability); + } + + @Override + public RaphaelTagTeamToughTriggeredAbility copy() { + return new RaphaelTagTeamToughTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return RaphaelTagTeamToughWatcher.checkEvent(event, this, game); + } +} + +class RaphaelTagTeamToughWatcher extends Watcher { + + private final Map map = new HashMap<>(); + + RaphaelTagTeamToughWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER + && ((DamagedPlayerEvent) event).isCombatDamage()) { + map.putIfAbsent(new MageObjectReference(event.getSourceId(), game), event.getId()); + } + } + + @Override + public void reset() { + super.reset(); + map.clear(); + } + + static boolean checkEvent(GameEvent event, Ability source, Game game) { + return Objects.equals( + event.getId(), + game.getState() + .getWatcher(RaphaelTagTeamToughWatcher.class) + .map + .get(new MageObjectReference(source.getSourceId(), game)) + ); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RatchetFieldMedic.java b/Mage.Sets/src/mage/cards/r/RatchetFieldMedic.java index e28788178e3..79abf17bf60 100644 --- a/Mage.Sets/src/mage/cards/r/RatchetFieldMedic.java +++ b/Mage.Sets/src/mage/cards/r/RatchetFieldMedic.java @@ -1,23 +1,28 @@ package mage.cards.r; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.GainLifeControllerTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.LivingMetalAbility; import mage.abilities.keyword.MoreThanMeetsTheEyeAbility; import mage.cards.Card; -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.constants.SuperType; import mage.filter.FilterCard; +import mage.filter.FilterPermanent; import mage.filter.common.FilterArtifactCard; +import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.predicate.Predicate; +import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetCardInYourGraveyard; @@ -28,27 +33,51 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class RatchetFieldMedic extends CardImpl { +public final class RatchetFieldMedic extends TransformingDoubleFacedCard { + + private static final FilterPermanent filterNontokenArtifacts = new FilterControlledArtifactPermanent(); + + static { + filterNontokenArtifacts.add(TokenPredicate.FALSE); + } public RatchetFieldMedic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{W}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{2}{W}", + "Ratchet, Rescue Racer", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "W" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.ROBOT); - this.power = new MageInt(2); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.r.RatchetRescueRacer.class; + // Ratchet, Field Medic + this.getLeftHalfCard().setPT(2, 4); // More Than Meets the Eye {1}{W} - this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{1}{W}")); + this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{1}{W}")); // Lifelink - this.addAbility(LifelinkAbility.getInstance()); + this.getLeftHalfCard().addAbility(LifelinkAbility.getInstance()); // Whenever you gain life, you may convert Ratchet. When you do, return target artifact card with mana value less than or equal to the amount of life you gained this turn from your graveyard to the battlefield tapped. - this.addAbility(new GainLifeControllerTriggeredAbility( + Ability ability = new GainLifeControllerTriggeredAbility( new RatchetFieldMedicEffect(), true - ), new PlayerGainedLifeWatcher()); + ); + ability.addWatcher(new PlayerGainedLifeWatcher()); + this.getLeftHalfCard().addAbility(ability); + + // Ratchet, Rescue Racer + this.getRightHalfCard().setPT(1, 4); + + // Living metal + this.getRightHalfCard().addAbility(new LivingMetalAbility()); + + // Lifelink + this.getRightHalfCard().addAbility(LifelinkAbility.getInstance()); + + // Whenever one or more nontoken artifacts you control are put into a graveyard from the battlefield, convert Ratchet. This ability triggers only once each turn. + this.getRightHalfCard().addAbility(new DiesCreatureTriggeredAbility( + new TransformSourceEffect().setText("convert {this}"), false, filterNontokenArtifacts + ).setTriggerPhrase("Whenever one or more nontoken artifacts you control are put into a graveyard from the battlefield, ") + .setTriggersLimitEachTurn(1)); } private RatchetFieldMedic(final RatchetFieldMedic card) { diff --git a/Mage.Sets/src/mage/cards/r/RatchetRescueRacer.java b/Mage.Sets/src/mage/cards/r/RatchetRescueRacer.java deleted file mode 100644 index 2d56d3c98e7..00000000000 --- a/Mage.Sets/src/mage/cards/r/RatchetRescueRacer.java +++ /dev/null @@ -1,61 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.common.DiesCreatureTriggeredAbility; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.LifelinkAbility; -import mage.abilities.keyword.LivingMetalAbility; -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.FilterControlledArtifactPermanent; -import mage.filter.predicate.permanent.TokenPredicate; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class RatchetRescueRacer extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledArtifactPermanent(); - - static { - filter.add(TokenPredicate.FALSE); - } - - public RatchetRescueRacer(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(1); - this.toughness = new MageInt(4); - this.color.setWhite(true); - this.nightCard = true; - - // Living metal - this.addAbility(new LivingMetalAbility()); - - // Lifelink - this.addAbility(LifelinkAbility.getInstance()); - - // Whenever one or more nontoken artifacts you control are put into a graveyard from the battlefield, convert Ratchet. This ability triggers only once each turn. - this.addAbility(new DiesCreatureTriggeredAbility( - new TransformSourceEffect().setText("convert {this}"), false, filter - ).setTriggerPhrase("Whenever one or more nontoken artifacts you control " + - "are put into a graveyard from the battlefield, ").setTriggersLimitEachTurn(1)); - } - - private RatchetRescueRacer(final RatchetRescueRacer card) { - super(card); - } - - @Override - public RatchetRescueRacer copy() { - return new RatchetRescueRacer(this); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RavenousDemon.java b/Mage.Sets/src/mage/cards/r/RavenousDemon.java index 3feef6706d8..24c32b3ae09 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousDemon.java +++ b/Mage.Sets/src/mage/cards/r/RavenousDemon.java @@ -1,12 +1,16 @@ package mage.cards.r; -import mage.MageInt; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.DamageControllerEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.TapSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility; import mage.cards.CardSetInfo; +import mage.cards.TransformingDoubleFacedCard; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.common.FilterControlledPermanent; @@ -16,22 +20,37 @@ import java.util.UUID; /** * @author intimidatingant */ -public final class RavenousDemon extends CardImpl { +public final class RavenousDemon extends TransformingDoubleFacedCard { private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.HUMAN, "Human"); public RavenousDemon(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); - this.subtype.add(SubType.DEMON); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "{3}{B}{B}", + "Archdemon of Greed", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "B" + ); - this.secondSideCardClazz = mage.cards.a.ArchdemonOfGreed.class; - - this.power = new MageInt(4); - this.toughness = new MageInt(4); + // Ravenous Demon + this.getLeftHalfCard().setPT(4, 4); // Sacrifice a Human: Transform Ravenous Demon. Activate this ability only any time you could cast a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new SacrificeTargetCost(filter))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new SacrificeTargetCost(filter))); + + // Archdemon of Greed + this.getRightHalfCard().setPT(9, 9); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // At the beginning of your upkeep, sacrifice a Human. If you can't, tap Archdemon of Greed and it deals 9 damage to you. + this.getRightHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid( + null, new TapSourceEffect(), new SacrificeTargetCost(filter), false + ).addOtherwiseEffect(new DamageControllerEffect(9)) + .setText("sacrifice a Human. If you can't, tap {this} and it deals 9 damage to you"))); } private RavenousDemon(final RavenousDemon card) { diff --git a/Mage.Sets/src/mage/cards/r/RecklessStormseeker.java b/Mage.Sets/src/mage/cards/r/RecklessStormseeker.java index 76eeb01bcc3..c4ef345feb8 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessStormseeker.java +++ b/Mage.Sets/src/mage/cards/r/RecklessStormseeker.java @@ -1,14 +1,15 @@ package mage.cards.r; -import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.DayboundAbility; import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.NightboundAbility; +import mage.abilities.keyword.TrampleAbility; +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; @@ -19,16 +20,17 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class RecklessStormseeker extends CardImpl { +public final class RecklessStormseeker extends TransformingDoubleFacedCard { public RecklessStormseeker(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.WEREWOLF}, "{2}{R}", + "Storm-Charged Slasher", + 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(3); - this.secondSideCardClazz = mage.cards.s.StormChargedSlasher.class; + // Reckless Stormseeker + this.getLeftHalfCard().setPT(2, 3); // At the beginning of combat on your turn, target creature you control gets +1/+0 and gains haste until end of turn. Ability ability = new BeginningOfCombatTriggeredAbility( @@ -39,10 +41,30 @@ public final class RecklessStormseeker extends CardImpl { HasteAbility.getInstance(), Duration.EndOfTurn ).setText("and gains haste until end of turn")); ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // Daybound - this.addAbility(new DayboundAbility()); + this.getLeftHalfCard().addAbility(new DayboundAbility()); + + // Storm-Charged Slasher + this.getRightHalfCard().setPT(3, 4); + + // At the beginning of combat on your turn, target creature you control gets +2/+0 and gains trample and haste until end of turn. + Ability ability2 = new BeginningOfCombatTriggeredAbility( + new BoostTargetEffect(2, 0) + .setText("target creature you control gets +2/+0") + ); + ability2.addEffect(new GainAbilityTargetEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn + ).setText("and gains trample")); + ability2.addEffect(new GainAbilityTargetEffect( + HasteAbility.getInstance(), Duration.EndOfTurn + ).setText("and haste until end of turn")); + ability2.addTarget(new TargetControlledCreaturePermanent()); + this.getRightHalfCard().addAbility(ability2); + + // Nightbound + this.getRightHalfCard().addAbility(new NightboundAbility()); } private RecklessStormseeker(final RecklessStormseeker card) { diff --git a/Mage.Sets/src/mage/cards/r/RecklessWaif.java b/Mage.Sets/src/mage/cards/r/RecklessWaif.java index dae8b27df78..20ceb9378b0 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessWaif.java +++ b/Mage.Sets/src/mage/cards/r/RecklessWaif.java @@ -1,10 +1,9 @@ package mage.cards.r; -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 RecklessWaif extends CardImpl { +public final class RecklessWaif extends TransformingDoubleFacedCard { public RecklessWaif(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.ROGUE); - this.subtype.add(SubType.WEREWOLF); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.ROGUE, SubType.WEREWOLF}, "{R}", + "Merciless Predator", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "R" + ); - this.secondSideCardClazz = mage.cards.m.MercilessPredator.class; - - this.power = new MageInt(1); - this.toughness = new MageInt(1); + // Reckless Waif + this.getLeftHalfCard().setPT(1, 1); // At the beginning of each upkeep, if no spells were cast last turn, transform Reckless Waif. - this.addAbility(new TransformAbility()); - this.addAbility(new WerewolfFrontTriggeredAbility()); + this.getLeftHalfCard().addAbility(new WerewolfFrontTriggeredAbility()); + + // Merciless Predator + this.getRightHalfCard().setPT(3, 2); + + // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Merciless Predator. + this.getRightHalfCard().addAbility(new WerewolfBackTriggeredAbility()); } private RecklessWaif(final RecklessWaif card) { diff --git a/Mage.Sets/src/mage/cards/r/ReflectionOfKikiJiki.java b/Mage.Sets/src/mage/cards/r/ReflectionOfKikiJiki.java deleted file mode 100644 index 51abc490f57..00000000000 --- a/Mage.Sets/src/mage/cards/r/ReflectionOfKikiJiki.java +++ /dev/null @@ -1,97 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.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.constants.SuperType; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ReflectionOfKikiJiki extends CardImpl { - - private static final FilterPermanent filter - = new FilterControlledCreaturePermanent("another nonlegendary creature you control"); - - static { - filter.add(AnotherPredicate.instance); - filter.add(Predicates.not(SuperType.LEGENDARY.getPredicate())); - } - - public ReflectionOfKikiJiki(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.GOBLIN); - this.subtype.add(SubType.SHAMAN); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - this.color.setRed(true); - this.nightCard = true; - - // {1}, {T}: Create a token that's a copy of another target nonlegendary creature you control, except it has haste. Sacrifice it at the beginning of the next end step. - Ability ability = new SimpleActivatedAbility(new ReflectionOfKikiJikiEffect(), new GenericManaCost(1)); - ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability); - } - - private ReflectionOfKikiJiki(final ReflectionOfKikiJiki card) { - super(card); - } - - @Override - public ReflectionOfKikiJiki copy() { - return new ReflectionOfKikiJiki(this); - } -} - -class ReflectionOfKikiJikiEffect extends OneShotEffect { - - ReflectionOfKikiJikiEffect() { - super(Outcome.Benefit); - staticText = "create a token that's a copy of another target nonlegendary creature you control, " + - "except it has haste. Sacrifice it at the beginning of the next end step"; - } - - private ReflectionOfKikiJikiEffect(final ReflectionOfKikiJikiEffect effect) { - super(effect); - } - - @Override - public ReflectionOfKikiJikiEffect copy() { - return new ReflectionOfKikiJikiEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); - if (permanent == null) { - return false; - } - - CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, true); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - effect.apply(game, source); - effect.sacrificeTokensCreatedAtNextEndStep(game, source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RefractionElemental.java b/Mage.Sets/src/mage/cards/r/RefractionElemental.java deleted file mode 100644 index d68099354eb..00000000000 --- a/Mage.Sets/src/mage/cards/r/RefractionElemental.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.costs.common.PayLifeCost; -import mage.abilities.effects.common.DamagePlayersEffect; -import mage.abilities.keyword.WardAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class RefractionElemental extends CardImpl { - - public RefractionElemental(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ELEMENTAL); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setRed(true); - this.nightCard = true; - - // Ward--Pay 2 life. - this.addAbility(new WardAbility(new PayLifeCost(2), false)); - - // Whenever you cast a spell, Refraction Elemental deals 2 damage to each opponent. - this.addAbility(new SpellCastControllerTriggeredAbility( - new DamagePlayersEffect(2, TargetController.OPPONENT), false - )); - } - - private RefractionElemental(final RefractionElemental card) { - super(card); - } - - @Override - public RefractionElemental copy() { - return new RefractionElemental(this); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RemnantOfTheRisingStar.java b/Mage.Sets/src/mage/cards/r/RemnantOfTheRisingStar.java deleted file mode 100644 index dc9338acb2e..00000000000 --- a/Mage.Sets/src/mage/cards/r/RemnantOfTheRisingStar.java +++ /dev/null @@ -1,134 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.ReflexiveTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; -import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.costs.mana.ManaCost; -import mage.abilities.costs.mana.ManaCosts; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.hint.Hint; -import mage.abilities.hint.ValueHint; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.counters.CounterType; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.permanent.ModifiedPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class RemnantOfTheRisingStar extends CardImpl { - - private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); - - static { - filter.add(ModifiedPredicate.instance); - } - - private static final Condition condition - = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 4); - private static final Hint hint - = new ValueHint("Modified creatures you control", new PermanentsOnBattlefieldCount(filter)); - - public RemnantOfTheRisingStar(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(2); - this.toughness = new MageInt(2); - this.color.setGreen(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever another creature you control enters, you may pay {X}. When you do, put X +1/+1 counters on that creature. - this.addAbility(new EntersBattlefieldControlledTriggeredAbility( - new RemnantOfTheRisingStarEffect(), StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - )); - - // As long as you control five or more modified creatures, Remnant of the Rising Star gets +5/+5 and has trample. - Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( - new BoostSourceEffect(5, 5, Duration.WhileOnBattlefield), - condition, "as long as you control five or more modified creatures, {this} gets +5/+5" - )); - ability.addEffect(new ConditionalContinuousEffect( - new GainAbilitySourceEffect(TrampleAbility.getInstance()), condition, "and has trample" - )); - this.addAbility(ability.addHint(hint)); - } - - private RemnantOfTheRisingStar(final RemnantOfTheRisingStar card) { - super(card); - } - - @Override - public RemnantOfTheRisingStar copy() { - return new RemnantOfTheRisingStar(this); - } -} - -class RemnantOfTheRisingStarEffect extends OneShotEffect { - - RemnantOfTheRisingStarEffect() { - super(Outcome.Benefit); - staticText = "you may pay {X}. When you do, put X +1/+1 counters on that creature"; - } - - private RemnantOfTheRisingStarEffect(final RemnantOfTheRisingStarEffect effect) { - super(effect); - } - - @Override - public RemnantOfTheRisingStarEffect copy() { - return new RemnantOfTheRisingStarEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - ManaCosts cost = new ManaCostsImpl<>("{X}"); - if (player == null || !player.chooseUse( - Outcome.BoostCreature, "Pay " + cost.getText() + "?", source, game - )) { - return false; - } - int xValue = player.announceX(0, Integer.MAX_VALUE, "Announce the value for {X} (pay to add counters)", game, source, true); - cost.add(new GenericManaCost(xValue)); - if (!cost.pay(source, game, source, source.getControllerId(), false, null)) { - return false; - } - Permanent permanent = (Permanent) getValue("permanentEnteringBattlefield"); - if (permanent == null) { - return false; - } - game.fireReflexiveTriggeredAbility(new ReflexiveTriggeredAbility( - new AddCountersTargetEffect(CounterType.P1P1.createInstance(xValue)) - .setTargetPointer(new FixedTarget(permanent, game)), false - ), source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RequitingHex.java b/Mage.Sets/src/mage/cards/r/RequitingHex.java new file mode 100644 index 00000000000..4f306518d03 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RequitingHex.java @@ -0,0 +1,53 @@ +package mage.cards.r; + +import mage.abilities.condition.common.BlightedCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.BlightAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ManaValuePredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RequitingHex extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("creature with mana value 2 or less"); + + static { + filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3)); + } + + public RequitingHex(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); + + // As an additional cost to cast this spell, you may blight 1. + this.addAbility(new BlightAbility(1)); + + // Destroy target creature with mana value 2 or less. If this spell's additional cost was paid, you gain 2 life. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new GainLifeEffect(2), BlightedCondition.instance, + "If this spell's additional cost was paid, you gain 2 life" + )); + } + + private RequitingHex(final RequitingHex card) { + super(card); + } + + @Override + public RequitingHex copy() { + return new RequitingHex(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java b/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java index 25e42d18a6f..9548fa24f98 100644 --- a/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java +++ b/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java @@ -1,30 +1,34 @@ package mage.cards.r; -import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.YouGainedLifeCondition; import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.hint.ConditionHint; import mage.abilities.hint.Hint; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.cards.TransformingDoubleFacedCard; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.BloodToken; -import mage.watchers.common.PlayerGainedLifeWatcher; import java.util.UUID; /** * @author TheElk801 */ -public final class RestlessBloodseeker extends CardImpl { +public final class RestlessBloodseeker extends TransformingDoubleFacedCard { private static final Condition condition = new YouGainedLifeCondition(); private static final Hint hint = new ConditionHint(condition, "You gained life this turn"); @@ -36,25 +40,42 @@ public final class RestlessBloodseeker extends CardImpl { } public RestlessBloodseeker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + super(ownerId, setInfo, + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE}, "{1}{B}", + "Bloodsoaked Reveler", + new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE}, "B" + ); - this.subtype.add(SubType.VAMPIRE); - this.power = new MageInt(1); - this.toughness = new MageInt(3); - this.secondSideCardClazz = mage.cards.b.BloodsoakedReveler.class; + // Restless Bloodseeker + this.getLeftHalfCard().setPT(1, 3); // At the beginning of your end step, if you gained life this turn, create a Blood token. - this.addAbility(new BeginningOfEndStepTriggeredAbility( + this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility( TargetController.YOU, new CreateTokenEffect(new BloodToken()), false, condition - ).addHint(hint), new PlayerGainedLifeWatcher()); + ).addHint(hint)); // Sacrifice two Blood tokens: Transform Restless Bloodseeker. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility( + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility( new TransformSourceEffect(), new SacrificeTargetCost(2, filter) )); + + // Bloodsoaked Reveler + this.getRightHalfCard().setPT(3, 3); + + // At the beginning of your end step, if you gained life this turn, create a Blood token. + this.getRightHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility( + TargetController.YOU, new CreateTokenEffect(new BloodToken()), + false, condition + ).addHint(hint)); + + // {4}{B}: Each opponent loses 2 life and you gain 2 life. + Ability ability = new SimpleActivatedAbility( + new LoseLifeOpponentsEffect(2), new ManaCostsImpl<>("{4}{B}") + ); + ability.addEffect(new GainLifeEffect(2).concatBy("and")); + this.getRightHalfCard().addAbility(ability); } private RestlessBloodseeker(final RestlessBloodseeker card) { 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/RhysTheEvermore.java b/Mage.Sets/src/mage/cards/r/RhysTheEvermore.java new file mode 100644 index 00000000000..93bee9bb710 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RhysTheEvermore.java @@ -0,0 +1,63 @@ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.RemoveUpToAmountCountersEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FlashAbility; +import mage.abilities.keyword.PersistAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class RhysTheEvermore extends CardImpl { + + public RhysTheEvermore(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // When Rhys enters, another target creature you control gains persist until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(new PersistAbility())); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE_YOU_CONTROL)); + this.addAbility(ability); + + // {W}, {T}: Remove any number of counters from target creature you control. Activate only as a sorcery. + Ability activatedAbility = new ActivateAsSorceryActivatedAbility( + new RemoveUpToAmountCountersEffect(Integer.MAX_VALUE), new ManaCostsImpl<>("{W}") + ); + activatedAbility.addCost(new TapSourceCost()); + activatedAbility.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(activatedAbility); + } + + private RhysTheEvermore(final RhysTheEvermore card) { + super(card); + } + + @Override + public RhysTheEvermore copy() { + return new RhysTheEvermore(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RinoaAngelWing.java b/Mage.Sets/src/mage/cards/r/RinoaAngelWing.java new file mode 100644 index 00000000000..96e52bf32c5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RinoaAngelWing.java @@ -0,0 +1,112 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.DiesOneOrMoreTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.*; +import mage.constants.*; +import mage.counters.CounterType; +import mage.counters.Counters; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RinoaAngelWing extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("attacking creatures you control"); + + static { + filter.add(AttackingPredicate.instance); + } + + public RinoaAngelWing(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.REBEL); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // At the beginning of combat on your turn, creatures you control with flying get +1/+1 and gain vigilance until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new BoostControlledEffect( + 1, 1, Duration.EndOfTurn, StaticFilters.FILTER_CREATURE_FLYING + ).setText("creatures you control with flying get +1/+1")); + ability.addEffect(new GainAbilityControlledEffect( + VigilanceAbility.getInstance(), Duration.EndOfTurn, + StaticFilters.FILTER_CREATURE_FLYING + ).setText("and gain vigilance until end of turn")); + this.addAbility(ability); + + // Whenever one or more attacking creatures you control die, you may return one of them to the battlefield tapped under its owner's control with a flying counter on it. Do this only once each turn. + this.addAbility(new DiesOneOrMoreTriggeredAbility( + new RinoaAngelWingEffect(), filter, true, true + ).setDoOnlyOnceEachTurn(true)); + } + + private RinoaAngelWing(final RinoaAngelWing card) { + super(card); + } + + @Override + public RinoaAngelWing copy() { + return new RinoaAngelWing(this); + } +} + +class RinoaAngelWingEffect extends OneShotEffect { + + RinoaAngelWingEffect() { + super(Outcome.Benefit); + staticText = "return one of them to the battlefield tapped " + + "under its owner's control with a flying counter on it"; + } + + private RinoaAngelWingEffect(final RinoaAngelWingEffect effect) { + super(effect); + } + + @Override + public RinoaAngelWingEffect copy() { + return new RinoaAngelWingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(getTargetPointer().getTargets(game, source)); + TargetCard target = new TargetCard(0, 1, Zone.ALL, StaticFilters.FILTER_CARD); + target.withNotTarget(true); + player.choose(Outcome.PutCreatureInPlay, cards, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + game.setEnterWithCounters(card.getId(), new Counters(CounterType.FLYING.createInstance())); + player.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); + if (CardUtil.getPermanentFromCardPutToBattlefield(card, game) != null) { + return true; + } + } + TriggeredAbility.clearDidThisTurn(source, game); + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/r/RiphookRaider.java b/Mage.Sets/src/mage/cards/r/RiphookRaider.java deleted file mode 100644 index f423c55b5f8..00000000000 --- a/Mage.Sets/src/mage/cards/r/RiphookRaider.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.keyword.DauntAbility; -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 RiphookRaider extends CardImpl { - - public RiphookRaider(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(4); - this.color.setGreen(true); - this.nightCard = true; - - // Riphook Raider can't be blocked by creatures with power 2 or less. - this.addAbility(new DauntAbility()); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private RiphookRaider(final RiphookRaider card) { - super(card); - } - - @Override - public RiphookRaider copy() { - return new RiphookRaider(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/RoarOfTheFifthPeople.java b/Mage.Sets/src/mage/cards/r/RoarOfTheFifthPeople.java deleted file mode 100644 index 6a4bbba19af..00000000000 --- a/Mage.Sets/src/mage/cards/r/RoarOfTheFifthPeople.java +++ /dev/null @@ -1,100 +0,0 @@ -package mage.cards.r; - -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.keyword.DoubleStrikeAbility; -import mage.abilities.keyword.TrampleAbility; -import mage.abilities.mana.GreenManaAbility; -import mage.abilities.mana.RedManaAbility; -import mage.abilities.mana.WhiteManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -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.FilterControlledPermanent; -import mage.game.permanent.token.DinosaurVanillaToken; -import mage.target.common.TargetCardInLibrary; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class RoarOfTheFifthPeople extends CardImpl { - - private static final FilterCard filterCard = new FilterCard("Dinosaur card"); - private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.DINOSAUR, "Dinosaurs you control"); - - static { - filterCard.add(SubType.DINOSAUR.getPredicate()); - } - - public RoarOfTheFifthPeople(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setWhite(true); - this.color.setGreen(true); - this.color.setRed(true); - this.subtype.add(SubType.SAGA); - this.nightCard = true; - - // (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 -- Create two 3/3 green Dinosaur creature tokens. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new CreateTokenEffect(new DinosaurVanillaToken(), 2)); - - // II -- Roar of the Fifth People gains "Creatures you control have '{T}: Add {R}, {G}, or {W}.'" - - // Note: splitting the mana ability in 3 makes it easier on the UI. - Ability gainedAbility = new SimpleStaticAbility(new GainAbilityControlledEffect( - new RedManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES, false - ).setText("Creatures you control have '{T}: Add {R}")); - gainedAbility.addEffect(new GainAbilityControlledEffect( - new GreenManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES, false - ).setText(", {G}")); - gainedAbility.addEffect(new GainAbilityControlledEffect( - new WhiteManaAbility(), Duration.WhileOnBattlefield, StaticFilters.FILTER_CONTROLLED_CREATURES, false - ).setText(", or {W}.'")); - - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, - new GainAbilitySourceEffect(gainedAbility, Duration.WhileOnBattlefield) - .setText("{this} gains \"Creatures you control have '{T}: Add {R}, {G}, or {W}.'\"") - ); - - // III -- Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle. - TargetCardInLibrary target = new TargetCardInLibrary(filterCard); - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new SearchLibraryPutInHandEffect(target, true)); - - // IV -- Dinosaurs you control gain double strike and trample until end of turn. - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_IV, - new GainAbilityControlledEffect( - DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, filter - ).setText("Dinosaurs you control gain double strike"), - new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.EndOfTurn, filter - ).setText("and trample until end of turn") - ); - - this.addAbility(sagaAbility); - } - - private RoarOfTheFifthPeople(final RoarOfTheFifthPeople card) { - super(card); - } - - @Override - public RoarOfTheFifthPeople copy() { - return new RoarOfTheFifthPeople(this); - } -} 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/r/RonaHeraldOfInvasion.java b/Mage.Sets/src/mage/cards/r/RonaHeraldOfInvasion.java index e7c1e9c5f58..745037e126b 100644 --- a/Mage.Sets/src/mage/cards/r/RonaHeraldOfInvasion.java +++ b/Mage.Sets/src/mage/cards/r/RonaHeraldOfInvasion.java @@ -1,28 +1,34 @@ package mage.cards.r; -import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.UntapSourceEffect; -import mage.abilities.keyword.TransformAbility; -import mage.cards.CardImpl; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.Card; 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.FilterSpell; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; import java.util.UUID; /** * @author TheElk801 */ -public final class RonaHeraldOfInvasion extends CardImpl { +public final class RonaHeraldOfInvasion extends TransformingDoubleFacedCard { private static final FilterSpell filter = new FilterSpell("a legendary spell"); @@ -31,26 +37,34 @@ public final class RonaHeraldOfInvasion extends CardImpl { } public RonaHeraldOfInvasion(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.HUMAN, SubType.WIZARD}, "{1}{U}", + "Rona, Tolarian Obliterator", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.WIZARD}, "UB" + ); - 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 = mage.cards.r.RonaTolarianObliterator.class; + // Rona, Herald of Invasion + this.getLeftHalfCard().setPT(1, 3); // Whenever you cast a legendary spell, untap Rona, Herald of Invasion. - this.addAbility(new SpellCastControllerTriggeredAbility(new UntapSourceEffect(), filter, false)); + this.getLeftHalfCard().addAbility(new SpellCastControllerTriggeredAbility(new UntapSourceEffect(), filter, false)); // {T}: Draw a card, then discard a card. - this.addAbility(new SimpleActivatedAbility( + this.getLeftHalfCard().addAbility(new SimpleActivatedAbility( new DrawDiscardControllerEffect(1, 1), new TapSourceCost() )); // {5}{B/P}: Transform Rona. Activate only as a sorcery. - this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{B/P}"))); + this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{5}{B/P}"))); + + // Rona, Tolarian Obliterator + this.getRightHalfCard().setPT(5, 5); + + // Trample + this.getRightHalfCard().addAbility(TrampleAbility.getInstance()); + + // Whenever a source deals damage to Rona, Tolarian Obliterator, that source's controller exiles a card from their hand at random. If it's a land card, you may put it onto the battlefield under your control. Otherwise, you may cast it without paying its mana cost. + this.getRightHalfCard().addAbility(new RonaTolarianObliteratorTriggeredAbility()); } private RonaHeraldOfInvasion(final RonaHeraldOfInvasion card) { @@ -62,3 +76,75 @@ public final class RonaHeraldOfInvasion extends CardImpl { return new RonaHeraldOfInvasion(this); } } + +class RonaTolarianObliteratorTriggeredAbility extends TriggeredAbilityImpl { + + RonaTolarianObliteratorTriggeredAbility() { + super(Zone.BATTLEFIELD, new RonaTolarianObliteratorEffect()); + } + + private RonaTolarianObliteratorTriggeredAbility(final RonaTolarianObliteratorTriggeredAbility ability) { + super(ability); + } + + @Override + public RonaTolarianObliteratorTriggeredAbility copy() { + return new RonaTolarianObliteratorTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PERMANENT; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(getSourceId())) { + this.getEffects().setTargetPointer(new FixedTarget(game.getControllerId(event.getSourceId()))); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever a source deals damage to {this}, that source's controller exiles a card " + + "from their hand at random. If it's a land card, you may put it onto the battlefield " + + "under your control. Otherwise, you may cast it without paying its mana cost."; + } +} + +class RonaTolarianObliteratorEffect extends OneShotEffect { + + RonaTolarianObliteratorEffect() { + super(Outcome.Benefit); + } + + private RonaTolarianObliteratorEffect(final RonaTolarianObliteratorEffect effect) { + super(effect); + } + + @Override + public RonaTolarianObliteratorEffect copy() { + return new RonaTolarianObliteratorEffect(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 = player.getHand().getRandom(game); + if (card == null) { + return false; + } + player.moveCards(card, Zone.EXILED, source, game); + if (!card.isLand(game)) { + return CardUtil.castSpellWithAttributesForFree(controller, source, game, card); + } + return controller.chooseUse(Outcome.PutLandInPlay, "Put " + card.getIdName() + " onto the battlefield?", source, game) + && controller.moveCards(card, Zone.BATTLEFIELD, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RonaTolarianObliterator.java b/Mage.Sets/src/mage/cards/r/RonaTolarianObliterator.java deleted file mode 100644 index 65f8672be31..00000000000 --- a/Mage.Sets/src/mage/cards/r/RonaTolarianObliterator.java +++ /dev/null @@ -1,124 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class RonaTolarianObliterator extends CardImpl { - - public RonaTolarianObliterator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.PHYREXIAN); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - this.color.setBlue(true); - this.color.setBlack(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Whenever a source deals damage to Rona, Tolarian Obliterator, that source's controller exiles a card from their hand at random. If it's a land card, you may put it onto the battlefield under your control. Otherwise, you may cast it without paying its mana cost. - this.addAbility(new RonaTolarianObliteratorTriggeredAbility()); - } - - private RonaTolarianObliterator(final RonaTolarianObliterator card) { - super(card); - } - - @Override - public RonaTolarianObliterator copy() { - return new RonaTolarianObliterator(this); - } -} - -class RonaTolarianObliteratorTriggeredAbility extends TriggeredAbilityImpl { - - RonaTolarianObliteratorTriggeredAbility() { - super(Zone.BATTLEFIELD, new RonaTolarianObliteratorEffect()); - } - - private RonaTolarianObliteratorTriggeredAbility(final RonaTolarianObliteratorTriggeredAbility ability) { - super(ability); - } - - @Override - public RonaTolarianObliteratorTriggeredAbility copy() { - return new RonaTolarianObliteratorTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PERMANENT; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(getSourceId())) { - this.getEffects().setTargetPointer(new FixedTarget(game.getControllerId(event.getSourceId()))); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever a source deals damage to {this}, that source's controller exiles a card " + - "from their hand at random. If it's a land card, you may put it onto the battlefield " + - "under your control. Otherwise, you may cast it without paying its mana cost."; - } -} - -class RonaTolarianObliteratorEffect extends OneShotEffect { - - RonaTolarianObliteratorEffect() { - super(Outcome.Benefit); - } - - private RonaTolarianObliteratorEffect(final RonaTolarianObliteratorEffect effect) { - super(effect); - } - - @Override - public RonaTolarianObliteratorEffect copy() { - return new RonaTolarianObliteratorEffect(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 = player.getHand().getRandom(game); - if (card == null) { - return false; - } - player.moveCards(card, Zone.EXILED, source, game); - if (!card.isLand(game)) { - return CardUtil.castSpellWithAttributesForFree(controller, source, game, card); - } - return controller.chooseUse(Outcome.PutLandInPlay, "Put " + card.getIdName() + " onto the battlefield?", source, game) - && controller.moveCards(card, Zone.BATTLEFIELD, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RooftopPercher.java b/Mage.Sets/src/mage/cards/r/RooftopPercher.java new file mode 100644 index 00000000000..94ebb645075 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RooftopPercher.java @@ -0,0 +1,51 @@ +package mage.cards.r; + +import java.util.UUID; +import mage.MageInt; +import mage.constants.SubType; +import mage.target.common.TargetCardInGraveyard; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.ChangelingAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class RooftopPercher extends CardImpl { + + public RooftopPercher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, exile up to two target cards from graveyards. You gain 3 life. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect()); + ability.addTarget(new TargetCardInGraveyard(0, 2)); + ability.addEffect(new GainLifeEffect(3)); + this.addAbility(ability); + } + + private RooftopPercher(final RooftopPercher card) { + super(card); + } + + @Override + public RooftopPercher copy() { + return new RooftopPercher(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RooftopSaboteurs.java b/Mage.Sets/src/mage/cards/r/RooftopSaboteurs.java deleted file mode 100644 index 7d78c7b665f..00000000000 --- a/Mage.Sets/src/mage/cards/r/RooftopSaboteurs.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.r; - -import mage.MageInt; -import mage.abilities.common.DealsCombatDamageToAPlayerOrBattleTriggeredAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -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 RooftopSaboteurs extends CardImpl { - - public RooftopSaboteurs(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.MOONFOLK); - this.subtype.add(SubType.NINJA); - this.power = new MageInt(2); - this.toughness = new MageInt(3); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Whenever Rooftop Saboteurs deals combat damage to a player or battle, draw a card. - this.addAbility(new DealsCombatDamageToAPlayerOrBattleTriggeredAbility( - new DrawCardSourceControllerEffect(1), false)); - } - - private RooftopSaboteurs(final RooftopSaboteurs card) { - super(card); - } - - @Override - public RooftopSaboteurs copy() { - return new RooftopSaboteurs(this); - } -} diff --git a/Mage.Sets/src/mage/cards/r/RunoStromkirk.java b/Mage.Sets/src/mage/cards/r/RunoStromkirk.java index 158b4130dae..c4b16f5fa67 100644 --- a/Mage.Sets/src/mage/cards/r/RunoStromkirk.java +++ b/Mage.Sets/src/mage/cards/r/RunoStromkirk.java @@ -1,25 +1,29 @@ package mage.cards.r; -import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.PutOnLibraryTargetEffect; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.TransformAbility; 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.SuperType; +import mage.filter.FilterPermanent; import mage.filter.StaticFilters; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.TargetPermanent; import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -27,29 +31,45 @@ import java.util.UUID; /** * @author TheElk801 */ -public final class RunoStromkirk extends CardImpl { +public final class RunoStromkirk extends TransformingDoubleFacedCard { + + private static final FilterPermanent filter = new FilterAttackingCreature("another attacking creature"); + + static { + filter.add(AnotherPredicate.instance); + } public RunoStromkirk(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}"); + super(ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.VAMPIRE, SubType.CLERIC}, "{1}{U}{B}", + "Krothuss, Lord of the Deep", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.KRAKEN, SubType.HORROR}, "UB" + ); - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.VAMPIRE); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(1); - this.toughness = new MageInt(4); - this.secondSideCardClazz = mage.cards.k.KrothussLordOfTheDeep.class; + // Runo Stromkirk + this.getLeftHalfCard().setPT(1, 4); // Flying - this.addAbility(FlyingAbility.getInstance()); + this.getLeftHalfCard().addAbility(FlyingAbility.getInstance()); // When Runo Stromkirk enters the battlefield, put up to one target creature card from your graveyard on top of your library. Ability ability = new EntersBattlefieldTriggeredAbility(new PutOnLibraryTargetEffect(true)); ability.addTarget(new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); - this.addAbility(ability); + this.getLeftHalfCard().addAbility(ability); // At the beginning of your upkeep, look at the top card of your library. You may reveal that card. If a creature card with mana value 6 or greater is revealed this way, transform Runo Stromkirk. - this.addAbility(new TransformAbility()); - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new RunoStromkirkEffect())); + this.getLeftHalfCard().addAbility(new BeginningOfUpkeepTriggeredAbility(new RunoStromkirkEffect())); + + // Krothuss, Lord of the Deep + this.getRightHalfCard().setPT(3, 5); + + // Flying + this.getRightHalfCard().addAbility(FlyingAbility.getInstance()); + + // Whenever Krothuss, Lord of the Deep attacks, create a tapped and attacking token that's a copy of another target attacking creature. If that creature is a Kraken, Leviathan, Octopus, or Serpent, create two of those tokens instead. + Ability ability2 = new AttacksTriggeredAbility(new KrothussLordOfTheDeepEffect()); + ability2.addTarget(new TargetPermanent(filter)); + this.getRightHalfCard().addAbility(ability2); } private RunoStromkirk(final RunoStromkirk card) { @@ -104,3 +124,38 @@ class RunoStromkirkEffect extends OneShotEffect { return true; } } + + +class KrothussLordOfTheDeepEffect extends OneShotEffect { + + KrothussLordOfTheDeepEffect() { + super(Outcome.Benefit); + staticText = "create a tapped and attacking token that's a copy of another target attacking creature. " + + "If that creature is a Kraken, Leviathan, Octopus, or Serpent, create two of those tokens instead"; + } + + private KrothussLordOfTheDeepEffect(final KrothussLordOfTheDeepEffect effect) { + super(effect); + } + + @Override + public KrothussLordOfTheDeepEffect copy() { + return new KrothussLordOfTheDeepEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (permanent == null) { + return false; + } + int count = permanent.hasSubtype(SubType.KRAKEN, game) + || permanent.hasSubtype(SubType.LEVIATHAN, game) + || permanent.hasSubtype(SubType.OCTOPUS, game) + || permanent.hasSubtype(SubType.SERPENT, game) ? 2 : 1; + return new CreateTokenCopyTargetEffect( + null, null, + false, count, true, true + ).apply(game, source); + } +} 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/SanarInnovativeFirstYear.java b/Mage.Sets/src/mage/cards/s/SanarInnovativeFirstYear.java new file mode 100644 index 00000000000..864ca3d15a3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanarInnovativeFirstYear.java @@ -0,0 +1,150 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.assignment.common.ColorAssignment; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.*; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorlessPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInLibrary; +import mage.util.CardUtil; + +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public final class SanarInnovativeFirstYear extends CardImpl { + + public SanarInnovativeFirstYear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U/R}{U/R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.SORCERER); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Vivid -- At the beginning of your first main phase, reveal cards from the top of your library until you reveal X nonland cards, where X is the number of colors among permanents you control. For each of those colors, you may exile a card of that color from among the revealed cards. Then shuffle. You may cast the exiled cards this turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SanarInnovativeFirstYearEffect()) + .setAbilityWord(AbilityWord.VIVID) + .addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private SanarInnovativeFirstYear(final SanarInnovativeFirstYear card) { + super(card); + } + + @Override + public SanarInnovativeFirstYear copy() { + return new SanarInnovativeFirstYear(this); + } +} + +class SanarInnovativeFirstYearEffect extends OneShotEffect { + + SanarInnovativeFirstYearEffect() { + super(Outcome.Benefit); + staticText = "reveal cards from the top of your library until you reveal X nonland cards, " + + "where X is the number of colors among permanents you control. For each of those colors, " + + "you may exile a card of that color from among the revealed cards. Then shuffle. " + + "You may cast the exiled cards this turn"; + } + + private SanarInnovativeFirstYearEffect(final SanarInnovativeFirstYearEffect effect) { + super(effect); + } + + @Override + public SanarInnovativeFirstYearEffect copy() { + return new SanarInnovativeFirstYearEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + ObjectColor color = ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getAllControlledColors(game, source); + int count = color.getColorCount(); + if (player == null || count < 1) { + return false; + } + Cards cards = new CardsImpl(); + for (Card card : player.getLibrary().getCards(game)) { + cards.add(card); + if (cards.count(StaticFilters.FILTER_CARD_NON_LAND, game) >= count) { + break; + } + } + player.revealCards(source, cards, game); + TargetCard target = new SanarInnovativeFirstYearTarget(color); + player.choose(outcome, cards, target, source, game); + Cards toExile = new CardsImpl(target.getTargets()); + player.moveCards(toExile, Zone.EXILED, source, game); + toExile.retainZone(Zone.EXILED, game); + player.shuffleLibrary(source, game); + for (Card card : toExile.getCards(game)) { + CardUtil.makeCardPlayable(game, source, card, true, Duration.EndOfTurn, false); + } + return true; + } +} + +class SanarInnovativeFirstYearTarget extends TargetCardInLibrary { + + private final ColorAssignment colorAssigner; + + private static FilterCard makeFilter(ObjectColor color) { + FilterCard filterCard = new FilterCard(CardUtil.concatWithAnd( + color.getColors() + .stream() + .map(ObjectColor::getDescription) + .map(s -> "a " + s + " card") + .collect(Collectors.toList()) + )); + filterCard.add(Predicates.not(ColorlessPredicate.instance)); + return filterCard; + } + + SanarInnovativeFirstYearTarget(ObjectColor color) { + super(0, color.getColorCount(), makeFilter(color)); + this.colorAssigner = new ColorAssignment(color.toString().split("")); + } + + private SanarInnovativeFirstYearTarget(final SanarInnovativeFirstYearTarget target) { + super(target); + this.colorAssigner = target.colorAssigner; + } + + @Override + public SanarInnovativeFirstYearTarget copy() { + return new SanarInnovativeFirstYearTarget(this); + } + + @Override + public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) { + if (!super.canTarget(playerId, id, source, game)) { + return false; + } + Card card = game.getCard(id); + if (card == null) { + return false; + } + if (this.getTargets().isEmpty()) { + return true; + } + Cards cards = new CardsImpl(this.getTargets()); + cards.add(card); + return colorAssigner.getRoleCount(cards, game) >= cards.size(); + } +} 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/SaplingNursery.java b/Mage.Sets/src/mage/cards/s/SaplingNursery.java new file mode 100644 index 00000000000..65a705f09dc --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SaplingNursery.java @@ -0,0 +1,63 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.LandfallAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ExileSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.AffinityAbility; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AffinityType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.game.permanent.token.TreefolkReachToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SaplingNursery extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("Treefolk and Forests"); + + static { + filter.add(Predicates.or( + SubType.TREEFOLK.getPredicate(), + SubType.FOREST.getPredicate() + )); + } + + public SaplingNursery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{6}{G}{G}"); + + // Affinity for Forests + this.addAbility(new AffinityAbility(AffinityType.FORESTS)); + + // Landfall -- Whenever a land you control enters, create a 3/4 green Treefolk creature token with reach. + this.addAbility(new LandfallAbility(new CreateTokenEffect(new TreefolkReachToken()))); + + // {1}{G}, Exile this enchantment: Treefolk and Forests you control gain indestructible until end of turn. + Ability ability = new SimpleActivatedAbility(new GainAbilityControlledEffect( + IndestructibleAbility.getInstance(), Duration.EndOfTurn, filter + ), new ManaCostsImpl<>("{1}{G}")); + ability.addCost(new ExileSourceCost()); + this.addAbility(ability); + } + + private SaplingNursery(final SaplingNursery card) { + super(card); + } + + @Override + public SaplingNursery copy() { + return new SaplingNursery(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java b/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java index 555e0f6c8c3..3ef97eadaae 100644 --- a/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java +++ b/Mage.Sets/src/mage/cards/s/SarkhanDragonAscendant.java @@ -4,7 +4,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.costs.common.BeholdDragonCost; +import mage.abilities.costs.common.BeholdCost; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.continuous.AddCardSubTypeSourceEffect; @@ -13,10 +13,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SubType; -import mage.constants.SuperType; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; @@ -42,7 +39,7 @@ public final class SarkhanDragonAscendant extends CardImpl { // When Sarkhan enters, you may behold a Dragon. If you do, create a Treasure token. this.addAbility(new EntersBattlefieldTriggeredAbility( - new DoIfCostPaid(new CreateTokenEffect(new TreasureToken()), new BeholdDragonCost()) + new DoIfCostPaid(new CreateTokenEffect(new TreasureToken()), new BeholdCost(BeholdType.DRAGON)) )); // Whenever a Dragon you control enters, put a +1/+1 counter on Sarkhan. Until end of turn, Sarkhan becomes a Dragon in addition to its other types and gains flying. diff --git a/Mage.Sets/src/mage/cards/s/ScarbladeScout.java b/Mage.Sets/src/mage/cards/s/ScarbladeScout.java new file mode 100644 index 00000000000..e7d1d056d20 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScarbladeScout.java @@ -0,0 +1,42 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.MillCardsControllerEffect; +import mage.abilities.keyword.LifelinkAbility; +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 ScarbladeScout extends CardImpl { + + public ScarbladeScout(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // When this creature enters, mill two cards. + this.addAbility(new EntersBattlefieldTriggeredAbility(new MillCardsControllerEffect(2))); + } + + private ScarbladeScout(final ScarbladeScout card) { + super(card); + } + + @Override + public ScarbladeScout copy() { + return new ScarbladeScout(this); + } +} 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/ScroungedScythe.java b/Mage.Sets/src/mage/cards/s/ScroungedScythe.java deleted file mode 100644 index 0d3e7b0075b..00000000000 --- a/Mage.Sets/src/mage/cards/s/ScroungedScythe.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.cards.s; - -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.EquippedHasSubtypeCondition; -import mage.abilities.decorator.ConditionalContinuousEffect; -import mage.abilities.effects.common.continuous.BoostEquippedEffect; -import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.keyword.EquipAbility; -import mage.abilities.keyword.MenaceAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class ScroungedScythe extends CardImpl { - - private static final Condition condition = new EquippedHasSubtypeCondition(SubType.HUMAN); - - public ScroungedScythe(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - this.subtype.add(SubType.EQUIPMENT); - - this.nightCard = true; - - // Equipped creature gets +1/+1. - this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 1))); - - // As long as equipped creature is a Human, it has menace. - this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect( - new GainAbilityAttachedEffect(new MenaceAbility(false), AttachmentType.EQUIPMENT), - condition, "As long as equipped creature is a Human, it has menace. " + - "(It can't be blocked except by two or more creatures.)" - ))); - - // Equip {2} - this.addAbility(new EquipAbility(2, false)); - } - - private ScroungedScythe(final ScroungedScythe card) { - super(card); - } - - @Override - public ScroungedScythe copy() { - return new ScroungedScythe(this); - } -} 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/Sear.java b/Mage.Sets/src/mage/cards/s/Sear.java new file mode 100644 index 00000000000..7a9d26e2435 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Sear.java @@ -0,0 +1,32 @@ +package mage.cards.s; + +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreatureOrPlaneswalker; + +import java.util.UUID; + +/** + * @author muz + */ +public final class Sear extends CardImpl { + + public Sear(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}"); + + // Excavation Explosion deals 4 damage to target creature or planeswalker. + this.getSpellAbility().addEffect(new DamageTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker()); + } + + private Sear(final Sear card) { + super(card); + } + + @Override + public Sear copy() { + return new Sear(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/SecretArcadeDustyParlor.java b/Mage.Sets/src/mage/cards/s/SecretArcadeDustyParlor.java new file mode 100644 index 00000000000..d44b691db08 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SecretArcadeDustyParlor.java @@ -0,0 +1,120 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardSetInfo; +import mage.cards.RoomCard; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.target.common.TargetCreaturePermanent; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SecretArcadeDustyParlor extends RoomCard { + + public SecretArcadeDustyParlor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, "{4}{W}", "{2}{W}"); + + // Secret Arcade + // Nonland permanents you control and permanent spells you control are enchantments in addition to their other types. + this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new SecretArcadeEffect())); + + // Dusty Parlor + // 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. + Ability ability = new SpellCastControllerTriggeredAbility( + new AddCountersTargetEffect(CounterType.P1P1.createInstance(), DustyParlorValue.instance) + .setText("put a number of +1/+1 counters equal to that spell's mana value on up to one target creature"), + StaticFilters.FILTER_SPELL_AN_ENCHANTMENT, false + ); + ability.addTarget(new TargetCreaturePermanent(0, 1)); + this.getRightHalfCard().addAbility(ability); + } + + private SecretArcadeDustyParlor(final SecretArcadeDustyParlor card) { + super(card); + } + + @Override + public SecretArcadeDustyParlor copy() { + return new SecretArcadeDustyParlor(this); + } +} + +class SecretArcadeEffect extends ContinuousEffectImpl { + + SecretArcadeEffect() { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + this.dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); + this.dependencyTypes.add(DependencyType.AuraAddingRemoving); + staticText = "nonland permanents you control and permanent spells you control " + + "are enchantments in addition to their other types"; + } + + private SecretArcadeEffect(final SecretArcadeEffect effect) { + super(effect); + } + + @Override + public SecretArcadeEffect copy() { + return new SecretArcadeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getActivePermanents( + StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND, source.getControllerId(), source, game + )) { + permanent.addCardType(game, CardType.ENCHANTMENT); + } + for (StackObject stackObject : game.getStack()) { + if (stackObject instanceof Spell + && stackObject.isPermanent(game) + && stackObject.isControlledBy(source.getControllerId())) { + stackObject.addCardType(game, CardType.ENCHANTMENT); + } + } + return true; + } +} + +enum DustyParlorValue implements DynamicValue { + instance; + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return Optional + .ofNullable(effect.getValue("spellCast")) + .map(Spell.class::cast) + .map(Spell::getManaValue) + .orElse(0); + } + + @Override + public DustyParlorValue copy() { + return this; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "1"; + } +} 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/SerraFaithkeeper.java b/Mage.Sets/src/mage/cards/s/SerraFaithkeeper.java deleted file mode 100644 index 21a7c081401..00000000000 --- a/Mage.Sets/src/mage/cards/s/SerraFaithkeeper.java +++ /dev/null @@ -1,42 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.keyword.FlyingAbility; -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 SerraFaithkeeper extends CardImpl { - - public SerraFaithkeeper(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ANGEL); - this.power = new MageInt(4); - this.toughness = new MageInt(4); - this.color.setWhite(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Vigilance - this.addAbility(VigilanceAbility.getInstance()); - } - - private SerraFaithkeeper(final SerraFaithkeeper card) { - super(card); - } - - @Override - public SerraFaithkeeper copy() { - return new SerraFaithkeeper(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/ShadowsLair.java b/Mage.Sets/src/mage/cards/s/ShadowsLair.java deleted file mode 100644 index fed50911cb7..00000000000 --- a/Mage.Sets/src/mage/cards/s/ShadowsLair.java +++ /dev/null @@ -1,51 +0,0 @@ -package mage.cards.s; - -import mage.abilities.Ability; -import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.RemoveCountersSourceCost; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.mana.BlackManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.counters.CounterType; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ShadowsLair extends CardImpl { - - public ShadowsLair(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.subtype.add(SubType.CAVE); - this.nightCard = true; - - // {T}: Add {B}. - this.addAbility(new BlackManaAbility()); - - // {B}, {T}, Remove a dread counter from Shadows' Lair: You draw a card and you lose 1 life. - Ability ability = new SimpleActivatedAbility( - new DrawCardSourceControllerEffect(1, true), new ManaCostsImpl<>("{B}") - ); - ability.addCost(new TapSourceCost()); - ability.addCost(new RemoveCountersSourceCost(CounterType.DREAD.createInstance())); - ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); - this.addAbility(ability); - } - - private ShadowsLair(final ShadowsLair card) { - super(card); - } - - @Override - public ShadowsLair copy() { - return new ShadowsLair(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/Shimmercreep.java b/Mage.Sets/src/mage/cards/s/Shimmercreep.java new file mode 100644 index 00000000000..8008d5f6cff --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Shimmercreep.java @@ -0,0 +1,51 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.abilities.keyword.MenaceAbility; +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 TheElk801 + */ +public final class Shimmercreep extends CardImpl { + + public Shimmercreep(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Menace + this.addAbility(new MenaceAbility()); + + // Vivid -- When this creature enters, each opponent loses X life and you gain X life, where X is the number of colors among permanents you control. + Ability ability = new EntersBattlefieldTriggeredAbility( + new LoseLifeOpponentsEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS) + .setText("each opponent loses X life") + ); + ability.addEffect(new GainLifeEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS) + .setText("and you gain X life, where X is the number of colors among permanents you control")); + this.addAbility(ability.setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private Shimmercreep(final Shimmercreep card) { + super(card); + } + + @Override + public Shimmercreep copy() { + return new Shimmercreep(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/Shinestriker.java b/Mage.Sets/src/mage/cards/s/Shinestriker.java new file mode 100644 index 00000000000..15b23ae7eef --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Shinestriker.java @@ -0,0 +1,46 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.FlyingAbility; +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 TheElk801 + */ +public final class Shinestriker extends CardImpl { + + public Shinestriker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vivid -- When this creature enters, draw cards equal to the number of colors among permanents you control. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DrawCardSourceControllerEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS) + .setText("draw cards equal to the number of colors among permanents you control") + ).setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private Shinestriker(final Shinestriker card) { + super(card); + } + + @Override + public Shinestriker copy() { + return new Shinestriker(this); + } +} 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/ShivaWardenOfIce.java b/Mage.Sets/src/mage/cards/s/ShivaWardenOfIce.java deleted file mode 100644 index cf667f30444..00000000000 --- a/Mage.Sets/src/mage/cards/s/ShivaWardenOfIce.java +++ /dev/null @@ -1,66 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.common.SagaAbility; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.abilities.effects.common.TapAllEffect; -import mage.abilities.effects.common.combat.CantBeBlockedTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterLandPermanent; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ShivaWardenOfIce extends CardImpl { - - private static final FilterPermanent filter = new FilterLandPermanent("lands your opponents control"); - - static { - filter.add(TargetController.OPPONENT.getControllerPredicate()); - } - - public ShivaWardenOfIce(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.ELEMENTAL); - this.power = new MageInt(4); - this.toughness = new MageInt(5); - this.nightCard = true; - this.color.setBlue(true); - - // (As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); - - // I, II -- Mesmerize -- Target creature can't be blocked this turn. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, ability -> { - ability.addEffect(new CantBeBlockedTargetEffect(Duration.EndOfTurn)); - ability.addTarget(new TargetCreaturePermanent()); - ability.withFlavorWord("Mesmerize"); - }); - - // III -- Cold Snap -- Tap all lands your opponents control. Exile Shiva, then return it to the battlefield. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, ability -> { - ability.addEffect(new TapAllEffect(filter)); - ability.addEffect(new ExileSourceAndReturnFaceUpEffect()); - ability.withFlavorWord("Cold Snap"); - }); - this.addAbility(sagaAbility); - } - - private ShivaWardenOfIce(final ShivaWardenOfIce card) { - super(card); - } - - @Override - public ShivaWardenOfIce copy() { - return new ShivaWardenOfIce(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/ShoreLurker.java b/Mage.Sets/src/mage/cards/s/ShoreLurker.java new file mode 100644 index 00000000000..b485cd0151a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShoreLurker.java @@ -0,0 +1,42 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.keyword.SurveilEffect; +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 ShoreLurker extends CardImpl { + + public ShoreLurker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, surveil 1. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SurveilEffect(1))); + } + + private ShoreLurker(final ShoreLurker card) { + super(card); + } + + @Override + public ShoreLurker copy() { + return new ShoreLurker(this); + } +} 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/SilvergillMentor.java b/Mage.Sets/src/mage/cards/s/SilvergillMentor.java new file mode 100644 index 00000000000..1d3432fbe59 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SilvergillMentor.java @@ -0,0 +1,49 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.OrCost; +import mage.abilities.costs.common.BeholdCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.BeholdType; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.MerfolkWhiteBlueToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SilvergillMentor extends CardImpl { + + public SilvergillMentor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // As an additional cost to cast this spell, behold a Merfolk or pay {2}. + this.getSpellAbility().addCost(new OrCost( + "behold a Merfolk or pay {2}", + new BeholdCost(BeholdType.MERFOLK), new GenericManaCost(2) + )); + + // When this creature enters, create a 1/1 white and blue Merfolk creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new MerfolkWhiteBlueToken()))); + } + + private SilvergillMentor(final SilvergillMentor card) { + super(card); + } + + @Override + public SilvergillMentor copy() { + return new SilvergillMentor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SilvergillPeddler.java b/Mage.Sets/src/mage/cards/s/SilvergillPeddler.java new file mode 100644 index 00000000000..e3eab16931b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SilvergillPeddler.java @@ -0,0 +1,38 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.BecomesTappedSourceTriggeredAbility; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +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 SilvergillPeddler extends CardImpl { + + public SilvergillPeddler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.CITIZEN); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Whenever this creature becomes tapped, draw a card, then discard a card. + this.addAbility(new BecomesTappedSourceTriggeredAbility(new DrawDiscardControllerEffect())); + } + + private SilvergillPeddler(final SilvergillPeddler card) { + super(card); + } + + @Override + public SilvergillPeddler copy() { + return new SilvergillPeddler(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SilverpeltWerewolf.java b/Mage.Sets/src/mage/cards/s/SilverpeltWerewolf.java deleted file mode 100644 index 8bf1157c998..00000000000 --- a/Mage.Sets/src/mage/cards/s/SilverpeltWerewolf.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -import java.util.UUID; - -/** - * @author Loki - */ -public final class SilverpeltWerewolf extends CardImpl { - - public SilverpeltWerewolf(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, null); - this.subtype.add(SubType.WEREWOLF); - this.color.setGreen(true); - - this.power = new MageInt(4); - this.toughness = new MageInt(5); - - this.nightCard = true; - - // Whenever Silverpelt Werewolf deals combat damage to a player, draw a card. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Silverpelt Werewolf. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private SilverpeltWerewolf(final SilverpeltWerewolf card) { - super(card); - } - - @Override - public SilverpeltWerewolf copy() { - return new SilverpeltWerewolf(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SinisterGnarlbark.java b/Mage.Sets/src/mage/cards/s/SinisterGnarlbark.java new file mode 100644 index 00000000000..796c400fbef --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SinisterGnarlbark.java @@ -0,0 +1,42 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.keyword.BlightControllerEffect; +import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; +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 SinisterGnarlbark extends CardImpl { + + public SinisterGnarlbark(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + + this.subtype.add(SubType.TREEFOLK); + this.subtype.add(SubType.WARLOCK); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // At the beginning of your end step, draw a card and blight 1. + Ability ability = new BeginningOfEndStepTriggeredAbility(new DrawCardSourceControllerEffect(1)); + ability.addEffect(new BlightControllerEffect(1).concatBy("and")); + this.addAbility(ability); + } + + private SinisterGnarlbark(final SinisterGnarlbark card) { + super(card); + } + + @Override + public SinisterGnarlbark copy() { + return new SinisterGnarlbark(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SinuousPredator.java b/Mage.Sets/src/mage/cards/s/SinuousPredator.java deleted file mode 100644 index d96130e866e..00000000000 --- a/Mage.Sets/src/mage/cards/s/SinuousPredator.java +++ /dev/null @@ -1,42 +0,0 @@ - -package mage.cards.s; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneSourceEffect; -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 SinuousPredator extends CardImpl { - - public SinuousPredator(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(4); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Sinuous Predator can't be blocked by more than one creature. - this.addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneSourceEffect())); - } - - private SinuousPredator(final SinuousPredator card) { - super(card); - } - - @Override - public SinuousPredator copy() { - return new SinuousPredator(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java b/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java index 633e0672e50..cba122f8e55 100644 --- a/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java +++ b/Mage.Sets/src/mage/cards/s/SisayWeatherlightCaptain.java @@ -1,13 +1,11 @@ package mage.cards.s; import mage.MageInt; -import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; @@ -15,7 +13,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterCard; -import mage.filter.StaticFilters; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.game.Game; @@ -40,10 +37,10 @@ public final class SisayWeatherlightCaptain extends CardImpl { // Sisay, Weatherlight Captain gets +1/+1 for each color among other legendary permanents you control. this.addAbility(new SimpleStaticAbility(new BoostSourceEffect( - SisayWeatherlightCaptainValue.instance, - SisayWeatherlightCaptainValue.instance, + ColorsAmongControlledPermanentsCount.OTHER_LEGENDARY, + ColorsAmongControlledPermanentsCount.OTHER_LEGENDARY, Duration.WhileOnBattlefield - ))); + )).addHint(ColorsAmongControlledPermanentsCount.OTHER_LEGENDARY.getHint())); // {W}{U}{B}{R}{G}: Search your library for a legendary permanent card with converted mana cost less than Sisay's power, put that card onto the battlefield, then shuffle your library. this.addAbility(new SimpleActivatedAbility( @@ -62,38 +59,6 @@ public final class SisayWeatherlightCaptain extends CardImpl { } } -enum SisayWeatherlightCaptainValue implements DynamicValue { - instance; - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - ObjectColor color = new ObjectColor(); - for (Permanent permanent : game.getBattlefield().getAllActivePermanents( - StaticFilters.FILTER_PERMANENT_LEGENDARY, sourceAbility.getControllerId(), game - )) { - if (permanent != null && !permanent.getId().equals(sourceAbility.getSourceId())) { - color.addColor(permanent.getColor(game)); - } - } - return color.getColorCount(); - } - - @Override - public DynamicValue copy() { - return instance; - } - - @Override - public String getMessage() { - return "color among other legendary permanents you control"; - } - - @Override - public String toString() { - return "1"; - } -} - class SisayWeatherlightCaptainEffect extends OneShotEffect { SisayWeatherlightCaptainEffect() { @@ -123,4 +88,4 @@ class SisayWeatherlightCaptainEffect extends OneShotEffect { filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, power)); return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)).apply(game, source); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SizzlingChangeling.java b/Mage.Sets/src/mage/cards/s/SizzlingChangeling.java new file mode 100644 index 00000000000..7e594e168fc --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SizzlingChangeling.java @@ -0,0 +1,42 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; +import mage.abilities.keyword.ChangelingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SizzlingChangeling extends CardImpl { + + public SizzlingChangeling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.SHAPESHIFTER); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Changeling + this.addAbility(new ChangelingAbility()); + + // When this creature dies, exile the top card of your library. Until the end of your next turn, you may play that card. + this.addAbility(new DiesSourceTriggeredAbility(new ExileTopXMayPlayUntilEffect(1, Duration.UntilEndOfYourNextTurn))); + } + + private SizzlingChangeling(final SizzlingChangeling card) { + super(card); + } + + @Override + public SizzlingChangeling copy() { + return new SizzlingChangeling(this); + } +} 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/SlumberingWalker.java b/Mage.Sets/src/mage/cards/s/SlumberingWalker.java new file mode 100644 index 00000000000..0d8b878453e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SlumberingWalker.java @@ -0,0 +1,67 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.effects.common.DoWhenCostPaid; +import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +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.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.PowerPredicate; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SlumberingWalker extends CardImpl { + + private static final FilterCard filter = new FilterCreatureCard("creature card with power 2 or less from your graveyard"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public SlumberingWalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); + + this.subtype.add(SubType.GIANT); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(7); + + // This creature enters with two -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.M1M1.createInstance(2)), + "with two -1/-1 counters on it" + )); + + // At the beginning of your end step, you may remove a counter from this creature. When you do, return target creature card with power 2 or less from your graveyard to the battlefield. + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new ReturnFromGraveyardToBattlefieldTargetEffect(), false + ); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoWhenCostPaid( + ability, new RemoveCountersSourceCost(1), "Remove a counter?" + ))); + } + + private SlumberingWalker(final SlumberingWalker card) { + super(card); + } + + @Override + public SlumberingWalker copy() { + return new SlumberingWalker(this); + } +} 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/SoddenVerdure.java b/Mage.Sets/src/mage/cards/s/SoddenVerdure.java new file mode 100644 index 00000000000..82be2c711ab --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SoddenVerdure.java @@ -0,0 +1,53 @@ +package mage.cards.s; + +import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; +import mage.abilities.condition.common.YouControlPermanentCondition; +import mage.abilities.mana.BlueManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.common.FilterLandPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SoddenVerdure extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("basic lands"); + + static { + filter.add(SuperType.BASIC.getPredicate()); + } + + private static final YouControlPermanentCondition condition = + new YouControlPermanentCondition(filter, ComparisonType.OR_GREATER, 2); + + public SoddenVerdure(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add(SubType.FOREST); + this.subtype.add(SubType.ISLAND); + + // ({T}: Add {G} or {U}.) + this.addAbility(new GreenManaAbility()); + this.addAbility(new BlueManaAbility()); + + // This land enters tapped unless you control two or more basic lands. + this.addAbility(new EntersBattlefieldTappedUnlessAbility(condition).addHint(condition.getHint())); + } + + private SoddenVerdure(final SoddenVerdure card) { + super(card); + } + + @Override + public SoddenVerdure copy() { + return new SoddenVerdure(this); + } +} 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/SoulOfRavnica.java b/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java index dad384c2e10..74480a77692 100644 --- a/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java +++ b/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java @@ -1,4 +1,3 @@ - package mage.cards.s; import mage.MageInt; @@ -6,7 +5,8 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ExileSourceFromGraveCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.DrawCardForEachColorAmongControlledPermanentsEffect; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -17,13 +17,12 @@ import mage.constants.Zone; import java.util.UUID; /** - * * @author LevelX2 */ public final class SoulOfRavnica extends CardImpl { public SoulOfRavnica(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); this.subtype.add(SubType.AVATAR); this.power = new MageInt(6); @@ -33,10 +32,11 @@ public final class SoulOfRavnica extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // {5}{U}{U}: Draw a card for each color among permanents you control. - this.addAbility(new SimpleActivatedAbility(new DrawCardForEachColorAmongControlledPermanentsEffect(), new ManaCostsImpl<>("{5}{U}{U}"))); + this.addAbility(new SimpleActivatedAbility(new DrawCardSourceControllerEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS), new ManaCostsImpl<>("{5}{U}{U}")) + .addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); // {5}{U}{U}, Exile Soul of Ravnica from your graveyard: Draw a card for each color among permanents you control. - Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new DrawCardForEachColorAmongControlledPermanentsEffect(), new ManaCostsImpl<>("{5}{U}{U}")); + Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new DrawCardSourceControllerEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS), new ManaCostsImpl<>("{5}{U}{U}")); ability.addCost(new ExileSourceFromGraveCost()); this.addAbility(ability); } 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/SourbreadAuntie.java b/Mage.Sets/src/mage/cards/s/SourbreadAuntie.java new file mode 100644 index 00000000000..ec947948dcc --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SourbreadAuntie.java @@ -0,0 +1,43 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.game.permanent.token.BlackAndRedGoblinToken; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SourbreadAuntie extends CardImpl { + + public SourbreadAuntie(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // When this creature enters, you may blight 2. If you do, create two 1/1 black and red Goblin creature tokens. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( + new CreateTokenEffect(new BlackAndRedGoblinToken(), 2), new BlightCost(2) + ))); + } + + private SourbreadAuntie(final SourbreadAuntie card) { + super(card); + } + + @Override + public SourbreadAuntie copy() { + return new SourbreadAuntie(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SovereignsMacuahuitl.java b/Mage.Sets/src/mage/cards/s/SovereignsMacuahuitl.java deleted file mode 100644 index 86401a5368f..00000000000 --- a/Mage.Sets/src/mage/cards/s/SovereignsMacuahuitl.java +++ /dev/null @@ -1,44 +0,0 @@ -package mage.cards.s; - -import mage.abilities.common.EntersBattlefieldAttachToTarget; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.continuous.BoostEquippedEffect; -import mage.abilities.keyword.EquipAbility; -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 SovereignsMacuahuitl extends CardImpl { - - public SovereignsMacuahuitl(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, ""); - - this.subtype.add(SubType.EQUIPMENT); - this.nightCard = true; - this.color.setRed(true); - - // When Sovereign's Macuahuitl enters the battlefield, attach it to target creature you control. - this.addAbility(new EntersBattlefieldAttachToTarget()); - - // Equipped creature gets +2/+0. - this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 0))); - - // Equip {2} - this.addAbility(new EquipAbility(2)); - } - - private SovereignsMacuahuitl(final SovereignsMacuahuitl card) { - super(card); - } - - @Override - public SovereignsMacuahuitl copy() { - return new SovereignsMacuahuitl(this); - } -} 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/Squawkroaster.java b/Mage.Sets/src/mage/cards/s/Squawkroaster.java new file mode 100644 index 00000000000..9f34a43577e --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Squawkroaster.java @@ -0,0 +1,46 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.common.continuous.SetBasePowerSourceEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Squawkroaster extends CardImpl { + + public Squawkroaster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(0); + this.toughness = new MageInt(4); + + // Double strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // Vivid -- Squawkroaster's power is equal to the number of colors among permanents you control. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SetBasePowerSourceEffect(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS) + ).setAbilityWord(AbilityWord.VIVID).addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint())); + } + + private Squawkroaster(final Squawkroaster card) { + super(card); + } + + @Override + public Squawkroaster copy() { + return new Squawkroaster(this); + } +} 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/StartingTown.java b/Mage.Sets/src/mage/cards/s/StartingTown.java index b3ca8840ca2..65da7614c63 100644 --- a/Mage.Sets/src/mage/cards/s/StartingTown.java +++ b/Mage.Sets/src/mage/cards/s/StartingTown.java @@ -4,6 +4,7 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedUnlessAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.hint.ConditionHint; import mage.abilities.mana.AnyColorManaAbility; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; @@ -27,7 +28,7 @@ public final class StartingTown extends CardImpl { this.subtype.add(SubType.TOWN); // This land enters tapped unless it's your first, second, or third turn of the game. - this.addAbility(new EntersBattlefieldTappedUnlessAbility(StartingTownCondition.instance)); + this.addAbility(new EntersBattlefieldTappedUnlessAbility(StartingTownCondition.instance).addHint(new ConditionHint(StartingTownCondition.instance))); // {T}: Add {C}. this.addAbility(new ColorlessManaAbility()); 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/StormChargedSlasher.java b/Mage.Sets/src/mage/cards/s/StormChargedSlasher.java deleted file mode 100644 index 1da4c1b1449..00000000000 --- a/Mage.Sets/src/mage/cards/s/StormChargedSlasher.java +++ /dev/null @@ -1,60 +0,0 @@ -package mage.cards.s; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.HasteAbility; -import mage.abilities.keyword.NightboundAbility; -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.target.common.TargetControlledCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class StormChargedSlasher extends CardImpl { - - public StormChargedSlasher(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; - - // At the beginning of combat on your turn, target creature you control gets +2/+0 and gains trample and haste until end of turn. - Ability ability = new BeginningOfCombatTriggeredAbility( - new BoostTargetEffect(2, 0) - .setText("target creature you control gets +2/+0") - ); - ability.addEffect(new GainAbilityTargetEffect( - TrampleAbility.getInstance(), Duration.EndOfTurn - ).setText("and gains trample")); - ability.addEffect(new GainAbilityTargetEffect( - HasteAbility.getInstance(), Duration.EndOfTurn - ).setText("and haste until end of turn")); - ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private StormChargedSlasher(final StormChargedSlasher card) { - super(card); - } - - @Override - public StormChargedSlasher copy() { - return new StormChargedSlasher(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/Stratosoarer.java b/Mage.Sets/src/mage/cards/s/Stratosoarer.java new file mode 100644 index 00000000000..5d769a70879 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Stratosoarer.java @@ -0,0 +1,50 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.BasicLandcyclingAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Stratosoarer extends CardImpl { + + public Stratosoarer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When this creature enters, target creature gains flying until end of turn. + Ability ability = new EntersBattlefieldTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance())); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // Basic landcycling {1}{U} + this.addAbility(new BasicLandcyclingAbility(new ManaCostsImpl<>("{1}{U}"))); + } + + private Stratosoarer(final Stratosoarer card) { + super(card); + } + + @Override + public Stratosoarer copy() { + return new Stratosoarer(this); + } +} 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/SunDappledCelebrant.java b/Mage.Sets/src/mage/cards/s/SunDappledCelebrant.java new file mode 100644 index 00000000000..fa223914973 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunDappledCelebrant.java @@ -0,0 +1,41 @@ +package mage.cards.s; + +import mage.MageInt; +import mage.abilities.keyword.ConvokeAbility; +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 SunDappledCelebrant extends CardImpl { + + public SunDappledCelebrant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); + + this.subtype.add(SubType.TREEFOLK); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Convoke + this.addAbility(new ConvokeAbility()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + } + + private SunDappledCelebrant(final SunDappledCelebrant card) { + super(card); + } + + @Override + public SunDappledCelebrant copy() { + return new SunDappledCelebrant(this); + } +} 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/SurlyFarrier.java b/Mage.Sets/src/mage/cards/s/SurlyFarrier.java new file mode 100644 index 00000000000..4dc3a3709e1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SurlyFarrier.java @@ -0,0 +1,50 @@ +package mage.cards.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.constants.SubType; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class SurlyFarrier extends CardImpl { + + public SurlyFarrier(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.CITIZEN); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {T}: Target creature you control gets +1/+1 and gains vigilance until end of turn. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility( + new BoostTargetEffect(1, 1).setText("target creature you control gets +1/+1"), + new TapSourceCost() + ); + ability.addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance()).setText("and gains vigilance until end of turn")); + ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE)); + this.addAbility(ability); + } + + private SurlyFarrier(final SurlyFarrier card) { + super(card); + } + + @Override + public SurlyFarrier copy() { + return new SurlyFarrier(this); + } +} 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/SwatAway.java b/Mage.Sets/src/mage/cards/s/SwatAway.java new file mode 100644 index 00000000000..e7f42facf75 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SwatAway.java @@ -0,0 +1,53 @@ +package mage.cards.s; + +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect; +import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureAttackingYou; +import mage.filter.common.FilterSpellOrPermanent; +import mage.target.common.TargetSpellOrPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class SwatAway extends CardImpl { + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition( + new FilterCreatureAttackingYou("a creature is attacking you") + ); + private static final FilterSpellOrPermanent filter = new FilterSpellOrPermanent("spell or creature"); + + static { + filter.getPermanentFilter().add(CardType.CREATURE.getPredicate()); + } + + public SwatAway(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}"); + + // This spell costs {2} less to cast if a creature is attacking you. + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new SpellCostReductionSourceEffect(2, condition).setCanWorksOnStackOnly(true) + ).setRuleAtTheTop(true)); + + // The owner of target spell or creature puts it on their choice of the top or bottom of their library. + this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect(true)); + this.getSpellAbility().addTarget(new TargetSpellOrPermanent(filter)); + } + + private SwatAway(final SwatAway card) { + super(card); + } + + @Override + public SwatAway copy() { + return new SwatAway(this); + } +} 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/TanufelRimespeaker.java b/Mage.Sets/src/mage/cards/t/TanufelRimespeaker.java new file mode 100644 index 00000000000..cd1227cae48 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TanufelRimespeaker.java @@ -0,0 +1,42 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TanufelRimespeaker extends CardImpl { + + public TanufelRimespeaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Whenever you cast a spell with mana value 4 or greater, draw a card. + this.addAbility(new SpellCastControllerTriggeredAbility( + new DrawCardSourceControllerEffect(1), + StaticFilters.FILTER_SPELL_MV_4_OR_GREATER, false + )); + } + + private TanufelRimespeaker(final TanufelRimespeaker card) { + super(card); + } + + @Override + public TanufelRimespeaker copy() { + return new TanufelRimespeaker(this); + } +} 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/TarnationVista.java b/Mage.Sets/src/mage/cards/t/TarnationVista.java index d2f684026e1..4ea1f5d26d1 100644 --- a/Mage.Sets/src/mage/cards/t/TarnationVista.java +++ b/Mage.Sets/src/mage/cards/t/TarnationVista.java @@ -5,16 +5,14 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTappedAsItEntersChooseColorAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; import mage.abilities.effects.mana.AddManaChosenColorEffect; import mage.abilities.effects.mana.ManaEffect; -import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; import java.util.UUID; @@ -30,10 +28,12 @@ public final class TarnationVista extends CardImpl { this.addAbility(new EntersBattlefieldTappedAsItEntersChooseColorAbility()); // {T}: Add one mana of the chosen color. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaChosenColorEffect(), new TapSourceCost())); + this.addAbility(new SimpleManaAbility(new AddManaChosenColorEffect(), new TapSourceCost())); // {1}, {T}: For each color among monocolored permanents you control, add one mana of that color. - this.addAbility(new TarnationVistaManaAbility()); + Ability ability = new SimpleManaAbility(new TarnationVistaEffect(), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability.addHint(ColorsAmongControlledPermanentsCount.MONOCOLORED_PERMANENTS.getHint())); } private TarnationVista(final TarnationVista card) { @@ -46,30 +46,11 @@ public final class TarnationVista extends CardImpl { } } -class TarnationVistaManaAbility extends ActivatedManaAbilityImpl { - - TarnationVistaManaAbility() { - super(Zone.BATTLEFIELD, new TarnationVistaEffect(), new GenericManaCost(1)); - this.addCost(new TapSourceCost()); - } - - private TarnationVistaManaAbility(final TarnationVistaManaAbility ability) { - super(ability); - } - - @Override - public TarnationVistaManaAbility copy() { - return new TarnationVistaManaAbility(this); - } - -} - -// Inspired by Bloom Tender class TarnationVistaEffect extends ManaEffect { TarnationVistaEffect() { super(); - staticText = "For each color among monocolored permanents you control, add one mana of that color"; + staticText = "for each color among monocolored permanents you control, add one mana of that color"; } private TarnationVistaEffect(final TarnationVistaEffect effect) { @@ -83,30 +64,9 @@ class TarnationVistaEffect extends ManaEffect { @Override public Mana produceMana(Game game, Ability source) { - Mana mana = new Mana(); if (game == null) { - return mana; + return new Mana(); } - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(source.getControllerId())) { - if (permanent.getColor(game).getColorCount() != 1) { - continue; - } - if (mana.getBlack() == 0 && permanent.getColor(game).isBlack()) { - mana.increaseBlack(); - } - if (mana.getBlue() == 0 && permanent.getColor(game).isBlue()) { - mana.increaseBlue(); - } - if (mana.getRed() == 0 && permanent.getColor(game).isRed()) { - mana.increaseRed(); - } - if (mana.getGreen() == 0 && permanent.getColor(game).isGreen()) { - mana.increaseGreen(); - } - if (mana.getWhite() == 0 && permanent.getColor(game).isWhite()) { - mana.increaseWhite(); - } - } - return mana; + return Mana.fromColor(ColorsAmongControlledPermanentsCount.MONOCOLORED_PERMANENTS.getAllControlledColors(game, source)); } } 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/TeferiAkosaOfZhalfir.java b/Mage.Sets/src/mage/cards/t/TeferiAkosaOfZhalfir.java deleted file mode 100644 index 738954cfd63..00000000000 --- a/Mage.Sets/src/mage/cards/t/TeferiAkosaOfZhalfir.java +++ /dev/null @@ -1,115 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.delayed.ReflexiveTriggeredAbility; -import mage.abilities.costs.common.DiscardTargetCost; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect; -import mage.abilities.effects.common.discard.DiscardControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; -import mage.filter.common.FilterNonlandPermanent; -import mage.filter.predicate.mageobject.ManaValuePredicate; -import mage.game.Game; -import mage.game.command.emblems.TeferiAkosaOfZhalfirEmblem; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetPermanent; -import mage.target.common.TargetCardInHand; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TeferiAkosaOfZhalfir extends CardImpl { - - public TeferiAkosaOfZhalfir(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.TEFERI); - this.setStartingLoyalty(4); - this.color.setWhite(true); - this.color.setBlue(true); - this.nightCard = true; - - // +1: Draw two cards. Then discard two cards unless you discard a creature card. - Ability ability = new LoyaltyAbility(new DrawCardSourceControllerEffect(2), 1); - ability.addEffect(new DoIfCostPaid( - null, new DiscardControllerEffect(2), - new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)) - .setText("discard a creature card instead of discarding two cards") - ).setText("Then discard two cards unless you discard a creature card")); - this.addAbility(ability); - - // -2: You get an emblem with "Knights you control get +1/+0 and have ward {1}." - this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new TeferiAkosaOfZhalfirEmblem()), -2)); - - // -3: Tap any number of untapped creatures you control. When you do, shuffle target nonland permanent an opponent controls with mana value X or less into its owner's library, where X is the number of creatures tapped this way. - this.addAbility(new LoyaltyAbility(new TeferiAkosaOfZhalfirEffect(), -3)); - } - - private TeferiAkosaOfZhalfir(final TeferiAkosaOfZhalfir card) { - super(card); - } - - @Override - public TeferiAkosaOfZhalfir copy() { - return new TeferiAkosaOfZhalfir(this); - } -} - -class TeferiAkosaOfZhalfirEffect extends OneShotEffect { - - TeferiAkosaOfZhalfirEffect() { - super(Outcome.Benefit); - staticText = "tap any number of untapped creatures you control. When you do, " + - "shuffle target nonland permanent an opponent controls with mana value X or less " + - "into its owner's library, where X is the number of creatures tapped this way"; - } - - private TeferiAkosaOfZhalfirEffect(final TeferiAkosaOfZhalfirEffect effect) { - super(effect); - } - - @Override - public TeferiAkosaOfZhalfirEffect copy() { - return new TeferiAkosaOfZhalfirEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - TargetPermanent target = new TargetPermanent( - 0, Integer.MAX_VALUE, StaticFilters.FILTER_CONTROLLED_UNTAPPED_CREATURES, true - ); - player.choose(Outcome.Tap, target, source, game); - int count = 0; - for (UUID targetId : target.getTargets()) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null && permanent.tap(source, game)) { - count++; - } - } - FilterPermanent filter = new FilterNonlandPermanent("nonland permanent an opponent controls with mana value " + count + " or less"); - filter.add(TargetController.OPPONENT.getControllerPredicate()); - filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, count + 1)); - ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(new ShuffleIntoLibraryTargetEffect() - .setText("shuffle target nonland permanent an opponent controls with mana value X or less " + - "into its owner's library, where X is the number of creatures tapped this way"), false); - ability.addTarget(new TargetPermanent(filter)); - game.fireReflexiveTriggeredAbility(ability, source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TempleOfCivilization.java b/Mage.Sets/src/mage/cards/t/TempleOfCivilization.java deleted file mode 100644 index 0e5544cfd20..00000000000 --- a/Mage.Sets/src/mage/cards/t/TempleOfCivilization.java +++ /dev/null @@ -1,64 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.mana.WhiteManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.TimingRule; -import mage.game.Game; -import mage.watchers.common.PlayerAttackedWatcher; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class TempleOfCivilization extends CardImpl { - - public TempleOfCivilization(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.nightCard = true; - - // (Transforms from Ojer Taq, Deepest Foundation.) - - // {T}: Add {W}. - this.addAbility(new WhiteManaAbility()); - - // {2}{W}, {T}: Transform Temple of Civilization. Activate only if you attacked with three or more creatures this turn and only as a sorcery. - Ability ability = new ActivateIfConditionActivatedAbility( - new TransformSourceEffect(), new ManaCostsImpl<>("{2}{W}"), TempleOfCivilizationCondition.instance - ).setTiming(TimingRule.SORCERY); - ability.addCost(new TapSourceCost()); - this.addAbility(ability, new PlayerAttackedWatcher()); - } - - private TempleOfCivilization(final TempleOfCivilization card) { - super(card); - } - - @Override - public TempleOfCivilization copy() { - return new TempleOfCivilization(this); - } -} - -enum TempleOfCivilizationCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - PlayerAttackedWatcher watcher = game.getState().getWatcher(PlayerAttackedWatcher.class); - return watcher != null && watcher.getNumberOfAttackersCurrentTurn(source.getControllerId()) >= 3; - } - - @Override - public String toString() { - return "you attacked with three or more creatures this turn"; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TempleOfCultivation.java b/Mage.Sets/src/mage/cards/t/TempleOfCultivation.java deleted file mode 100644 index bd991824891..00000000000 --- a/Mage.Sets/src/mage/cards/t/TempleOfCultivation.java +++ /dev/null @@ -1,55 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.ActivateIfConditionActivatedAbility; -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.common.TransformSourceEffect; -import mage.abilities.hint.common.PermanentsYouControlHint; -import mage.abilities.mana.GreenManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.TimingRule; -import mage.filter.common.FilterControlledPermanent; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class TempleOfCultivation extends CardImpl { - - private static final Condition condition = new PermanentsOnTheBattlefieldCondition( - new FilterControlledPermanent("you control ten or more permanents"), ComparisonType.MORE_THAN, 9 - ); - - public TempleOfCultivation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.nightCard = true; - - // (Transforms from Ojer Kaslem, Deepest Growth.) - - // {T}: Add {G}. - this.addAbility(new GreenManaAbility()); - - // {2}{G}, {T}: Transform Temple of Cultivation. Activate only if you control ten or more permanents and only as a sorcery. - Ability ability = new ActivateIfConditionActivatedAbility( - new TransformSourceEffect(), new ManaCostsImpl<>("{2}{G}"), condition - ).setTiming(TimingRule.SORCERY); - ability.addCost(new TapSourceCost()); - this.addAbility(ability.addHint(PermanentsYouControlHint.instance)); - } - - private TempleOfCultivation(final TempleOfCultivation card) { - super(card); - } - - @Override - public TempleOfCultivation copy() { - return new TempleOfCultivation(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TempleOfCyclicalTime.java b/Mage.Sets/src/mage/cards/t/TempleOfCyclicalTime.java deleted file mode 100644 index 88fa042529e..00000000000 --- a/Mage.Sets/src/mage/cards/t/TempleOfCyclicalTime.java +++ /dev/null @@ -1,55 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; -import mage.abilities.condition.common.SourceHasCounterCondition; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; -import mage.abilities.mana.BlueManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.TimingRule; -import mage.counters.CounterType; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class TempleOfCyclicalTime extends CardImpl { - - private static final Condition condition = new SourceHasCounterCondition(CounterType.TIME, ComparisonType.EQUAL_TO, 0); - - public TempleOfCyclicalTime(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.nightCard = true; - - // (Transforms from Ojer Pakpatiq, Deepest Epoch.) - - // {T}: Add {U}. Remove a time counter from Temple of Cyclical Time. - Ability ability = new BlueManaAbility(); - ability.addEffect(new RemoveCounterSourceEffect(CounterType.TIME.createInstance())); - this.addAbility(ability); - - // {2}{U}, {T}: Transform Temple of Cyclical Time. Activate only if it has no time counters on it and only as a sorcery. - ability = new ActivateIfConditionActivatedAbility( - new TransformSourceEffect(), new ManaCostsImpl<>("{2}{U}"), condition - ).setTiming(TimingRule.SORCERY); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private TempleOfCyclicalTime(final TempleOfCyclicalTime card) { - super(card); - } - - @Override - public TempleOfCyclicalTime copy() { - return new TempleOfCyclicalTime(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TempleOfPower.java b/Mage.Sets/src/mage/cards/t/TempleOfPower.java deleted file mode 100644 index c6bb1dc614d..00000000000 --- a/Mage.Sets/src/mage/cards/t/TempleOfPower.java +++ /dev/null @@ -1,156 +0,0 @@ -package mage.cards.t; - -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.ActivateIfConditionActivatedAbility; -import mage.abilities.condition.Condition; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.hint.Hint; -import mage.abilities.mana.RedManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.TimingRule; -import mage.constants.WatcherScope; -import mage.game.Game; -import mage.game.command.CommandObject; -import mage.game.events.DamagedEvent; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.stack.StackObject; -import mage.watchers.Watcher; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * @author Susucr - */ -public final class TempleOfPower extends CardImpl { - - public TempleOfPower(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - this.nightCard = true; - - // (Transforms from Ojer Axonil, Deepest Might.) - - // {T}: Add {R}. - this.addAbility(new RedManaAbility()); - - // {2}{R}, {T}: Transform Temple of Power. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery. - Ability ability = new ActivateIfConditionActivatedAbility( - new TransformSourceEffect(), new ManaCostsImpl<>("{2}{R}"), TempleOfPowerCondition.instance - ).setTiming(TimingRule.SORCERY); - ability.addCost(new TapSourceCost()); - this.addAbility(ability.addHint(TempleOfPowerHint.instance), new TempleOfPowerWatcher()); - } - - private TempleOfPower(final TempleOfPower card) { - super(card); - } - - @Override - public TempleOfPower copy() { - return new TempleOfPower(this); - } -} - -enum TempleOfPowerCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class); - return watcher != null - && 4 <= watcher.damageForPlayer(source.getControllerId()); - } - - @Override - public String toString() { - return "red sources you controlled dealt 4 or more noncombat damage this turn"; - } -} - -enum TempleOfPowerHint implements Hint { - instance; - - @Override - public String getText(Game game, Ability ability) { - TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class); - if (watcher == null) { - return ""; - } - - return "Non-combat damage from red source: " - + watcher.damageForPlayer(ability.getControllerId()); - } - - @Override - public TempleOfPowerHint copy() { - return instance; - } -} - -class TempleOfPowerWatcher extends Watcher { - - // player -> total non combat damage from red source controlled by that player dealt this turn. - private final Map damageMap = new HashMap<>(); - - public TempleOfPowerWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER - || event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) { - DamagedEvent dmgEvent = (DamagedEvent) event; - - // watch only non combat damage events. - if (dmgEvent == null || dmgEvent.isCombatDamage()) { - return; - } - - MageObject sourceObject; - UUID sourceControllerId = null; - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); - if (sourcePermanent != null) { - // source is a permanent. - sourceObject = sourcePermanent; - sourceControllerId = sourcePermanent.getControllerId(); - } else { - sourceObject = game.getSpellOrLKIStack(event.getSourceId()); - if (sourceObject != null) { - // source is a spell. - sourceControllerId = ((StackObject) sourceObject).getControllerId(); - } else { - sourceObject = game.getObject(event.getSourceId()); - if (sourceObject instanceof CommandObject) { - // source is a Command Object. For instance Emblem - sourceControllerId = ((CommandObject) sourceObject).getControllerId(); - } - } - } - - // watch only red sources dealing damage - if (sourceObject == null || sourceControllerId == null || !sourceObject.getColor().isRed()) { - return; - } - - damageMap.compute(sourceControllerId, (k, i) -> (i == null ? 0 : i) + event.getAmount()); - } - } - - @Override - public void reset() { - damageMap.clear(); - super.reset(); - } - - int damageForPlayer(UUID playerId) { - return damageMap.getOrDefault(playerId, 0); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TendTheSprigs.java b/Mage.Sets/src/mage/cards/t/TendTheSprigs.java new file mode 100644 index 00000000000..05fc76ffd4d --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TendTheSprigs.java @@ -0,0 +1,66 @@ +package mage.cards.t; + +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +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.ComparisonType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.game.permanent.token.TreefolkReachToken; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TendTheSprigs extends CardImpl { + + private static final FilterPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(Predicates.or( + CardType.LAND.getPredicate(), + SubType.TREEFOLK.getPredicate() + )); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.MORE_THAN, 6); + private static final Hint hint = new ValueHint( + "Lands and Treefolk you control", new PermanentsOnBattlefieldCount(filter) + ); + + public TendTheSprigs(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); + + // Search your library for a basic land card, put it onto the battlefield tapped, then shuffle. Then if you control seven or more lands and/or Treefolk, create a 3/4 green Treefolk creature token with reach. + this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), true) + ); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new CreateTokenEffect(new TreefolkReachToken()), condition, "Then if you control seven " + + "or more lands and/or Treefolk, create a 3/4 green Treefolk creature token with reach" + )); + this.getSpellAbility().addHint(hint); + } + + private TendTheSprigs(final TendTheSprigs card) { + super(card); + } + + @Override + public TendTheSprigs copy() { + return new TendTheSprigs(this); + } +} 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/TerrorOfKruinPass.java b/Mage.Sets/src/mage/cards/t/TerrorOfKruinPass.java deleted file mode 100644 index 987091f32de..00000000000 --- a/Mage.Sets/src/mage/cards/t/TerrorOfKruinPass.java +++ /dev/null @@ -1,55 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.DoubleStrikeAbility; -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.FilterPermanent; - -import java.util.UUID; - -/** - * @author North - */ -public final class TerrorOfKruinPass extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent(SubType.WEREWOLF, "Werewolves"); - - public TerrorOfKruinPass(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.color.setRed(true); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - - this.addAbility(DoubleStrikeAbility.getInstance()); - - // Werewolves you control have menace. (They can't be blocked except by two or more creatures.) - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( - new MenaceAbility(), Duration.WhileOnBattlefield, filter, false - ))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Terror of Kruin Pass. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private TerrorOfKruinPass(final TerrorOfKruinPass card) { - super(card); - } - - @Override - public TerrorOfKruinPass copy() { - return new TerrorOfKruinPass(this); - } -} 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/TheBrokenSky.java b/Mage.Sets/src/mage/cards/t/TheBrokenSky.java deleted file mode 100644 index 934cbd712ea..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheBrokenSky.java +++ /dev/null @@ -1,61 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.permanent.token.WhiteBlackSpiritToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TheBrokenSky extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature tokens"); - - static { - filter.add(TokenPredicate.TRUE); - } - - public TheBrokenSky(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - - this.color.setWhite(true); - this.color.setBlack(true); - this.nightCard = true; - - // Creature tokens you control get +1/+0 and have lifelink. - Ability ability = new SimpleStaticAbility(new BoostControlledEffect( - 1, 0, Duration.WhileOnBattlefield, filter - )); - ability.addEffect(new GainAbilityControlledEffect( - LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, filter - ).setText("and have lifelink")); - this.addAbility(ability); - - // At the beginning of your end step, create a 1/1 white and black Spirit creature token with flying. - this.addAbility(new BeginningOfEndStepTriggeredAbility( - new CreateTokenEffect(new WhiteBlackSpiritToken()) - )); - } - - private TheBrokenSky(final TheBrokenSky card) { - super(card); - } - - @Override - public TheBrokenSky copy() { - return new TheBrokenSky(this); - } -} 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/TheCore.java b/Mage.Sets/src/mage/cards/t/TheCore.java deleted file mode 100644 index 07a9cc149d1..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheCore.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.t; - -import mage.Mana; -import mage.abilities.condition.common.DescendCondition; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount; -import mage.abilities.mana.DynamicManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.AbilityWord; -import mage.constants.CardType; -import mage.constants.SuperType; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author Susucr - */ -public final class TheCore extends CardImpl { - - private static final DynamicValue xValue = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_PERMANENT); - - public TheCore(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - // (Transforms from Matzalantli.) - this.nightCard = true; - - // Fathomless descent -- {T}: Add X mana of any one color, where X is the number of permanent cards in your graveyard. - this.addAbility(new DynamicManaAbility( - Mana.AnyMana(1), xValue, new TapSourceCost(), - "Add X mana of any one color, where X is the number of permanent cards in your graveyard.", - true - ).setAbilityWord(AbilityWord.FATHOMLESS_DESCENT).addHint(DescendCondition.getHint())); - } - - private TheCore(final TheCore card) { - super(card); - } - - @Override - public TheCore copy() { - return new TheCore(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/TheGreatSynthesis.java b/Mage.Sets/src/mage/cards/t/TheGreatSynthesis.java deleted file mode 100644 index 160a80da2a6..00000000000 --- a/Mage.Sets/src/mage/cards/t/TheGreatSynthesis.java +++ /dev/null @@ -1,99 +0,0 @@ -package mage.cards.t; - -import mage.abilities.Ability; -import mage.abilities.common.SagaAbility; -import mage.abilities.dynamicvalue.common.CardsInControllerHandCount; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.ExileSourceAndReturnFaceUpEffect; -import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; -import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.constants.*; -import mage.filter.StaticFilters; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.players.Player; -import mage.util.CardUtil; - -import java.util.UUID; - -public class TheGreatSynthesis extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Phyrexian creatures"); - - static { - filter.add(Predicates.not(SubType.PHYREXIAN.getPredicate())); - } - - public TheGreatSynthesis(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, ""); - this.addSubType(SubType.SAGA); - this.color.setBlue(true); - this.nightCard = true; - - //(As this Saga enters and after your draw step, add a lore counter.) - SagaAbility sagaAbility = new SagaAbility(this); - - //I — Draw cards equal to the number of cards in your hand. You have no maximum hand size for as long as you - //control The Great Synthesis. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, - new DrawCardSourceControllerEffect(CardsInControllerHandCount.ANY) - .setText("draw cards equal to the number of cards in your hand"), - new MaximumHandSizeControllerEffect(Integer.MAX_VALUE, Duration.WhileOnBattlefield, - MaximumHandSizeControllerEffect.HandSizeModification.SET) - .setText("you have no maximum hand size for as long as you control {this}")); - - //II — Return all non-Phyrexian creatures to their owners' hands. - sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new ReturnToHandFromBattlefieldAllEffect(filter)); - - //III — You may cast any number of spells from your hand without paying their mana cost. Exile The Great - //Synthesis, then return it to the battlefield (front face up). - sagaAbility.addChapterEffect( - this, SagaChapter.CHAPTER_III, - new TheGreatSynthesisCastEffect(), - new ExileSourceAndReturnFaceUpEffect() - ); - - this.addAbility(sagaAbility); - } - - private TheGreatSynthesis(final TheGreatSynthesis card) { - super(card); - } - - @Override - public TheGreatSynthesis copy() { - return new TheGreatSynthesis(this); - } -} - -class TheGreatSynthesisCastEffect extends OneShotEffect { - public TheGreatSynthesisCastEffect() { - super(Outcome.PlayForFree); - this.staticText = "you may cast any number of spells from your hand without paying their mana costs"; - } - - private TheGreatSynthesisCastEffect(final TheGreatSynthesisCastEffect effect) { - super(effect); - } - - @Override - public TheGreatSynthesisCastEffect copy() { - return new TheGreatSynthesisCastEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Cards cards = controller.getHand(); - CardUtil.castMultipleWithAttributeForFree(controller, source, game, cards, StaticFilters.FILTER_CARD); - 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..fdbd9c70e50 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}, "" + ); + // 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/TheReaperKingNoMore.java b/Mage.Sets/src/mage/cards/t/TheReaperKingNoMore.java new file mode 100644 index 00000000000..ff4e19c17a7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheReaperKingNoMore.java @@ -0,0 +1,109 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author PurpleCrowbar + */ +public final class TheReaperKingNoMore extends CardImpl { + + public TheReaperKingNoMore (UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE} ,"{2/B}{2/R}{2/G}"); + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.SCARECROW); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When The Reaper enters, put a -1/-1 counter on each of up to two target creatures. + Ability ability = new EntersBattlefieldTriggeredAbility( + new AddCountersTargetEffect(CounterType.M1M1.createInstance()) + ); + ability.addTarget(new TargetCreaturePermanent(0, 2)); + this.addAbility(ability); + + // Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may put that card onto the battlefield under your control. Do this only once each turn. + this.addAbility(new TheReaperKingNoMoreTriggeredAbility()); + } + + private TheReaperKingNoMore(final TheReaperKingNoMore card) { + super(card); + } + + @Override + public TheReaperKingNoMore copy() { + return new TheReaperKingNoMore(this); + } +} + +class TheReaperKingNoMoreTriggeredAbility extends TriggeredAbilityImpl { + + public TheReaperKingNoMoreTriggeredAbility() { + super(Zone.BATTLEFIELD, new ReturnToBattlefieldUnderYourControlTargetEffect(), true); + setLeavesTheBattlefieldTrigger(true); + setDoOnlyOnceEachTurn(true); + } + + private TheReaperKingNoMoreTriggeredAbility(final TheReaperKingNoMoreTriggeredAbility ability) { + super(ability); + } + + @Override + public TheReaperKingNoMoreTriggeredAbility copy() { + return new TheReaperKingNoMoreTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.isDiesEvent()) { + Permanent permanent = zEvent.getTarget(); + if (permanent != null + && permanent.getCounters(game).containsKey(CounterType.M1M1) + && game.getOpponents(controllerId).contains(permanent.getControllerId())) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId(), game.getState().getZoneChangeCounter(event.getTargetId()))); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may put that card onto " + + "the battlefield under your control. Do this only once each turn."; + } + + @Override + public boolean isInUseableZone(Game game, MageObject sourceObject, GameEvent event) { + return TriggeredAbilityImpl.isInUseableZoneDiesTrigger(this, sourceObject, event, game); + } +} 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/TheSoulStone.java b/Mage.Sets/src/mage/cards/t/TheSoulStone.java index 252ea24aafa..4f48be7e60c 100644 --- a/Mage.Sets/src/mage/cards/t/TheSoulStone.java +++ b/Mage.Sets/src/mage/cards/t/TheSoulStone.java @@ -45,7 +45,9 @@ public final class TheSoulStone extends CardImpl { // {6}{B}, {T}, Exile a creature you control: Harness The Soul Stone. Ability ability = new SimpleActivatedAbility(new HarnessSourceEffect(), new ManaCostsImpl<>("{6}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new ExileTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE))); + ability.addCost(new ExileTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE)) + .withSourceExileZone(false) + ); this.addAbility(ability); // ∞ -- At the beginning of your upkeep, return target creature card from your graveyard to the battlefield. 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/ThoughtweftCharge.java b/Mage.Sets/src/mage/cards/t/ThoughtweftCharge.java new file mode 100644 index 00000000000..cba13872a26 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThoughtweftCharge.java @@ -0,0 +1,41 @@ +package mage.cards.t; + +import mage.abilities.condition.common.CreatureEnteredUnderYourControlCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetCreaturePermanent; +import mage.watchers.common.CreatureEnteredControllerWatcher; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ThoughtweftCharge extends CardImpl { + + public ThoughtweftCharge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Target creature gets +3/+3 until end of turn. If a creature entered the battlefield under your control this turn, draw a card. + this.getSpellAbility().addEffect(new BoostTargetEffect(3, 3)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new DrawCardSourceControllerEffect(1), CreatureEnteredUnderYourControlCondition.instance, + "If a creature entered the battlefield under your control this turn, draw a card" + )); + this.getSpellAbility().addWatcher(new CreatureEnteredControllerWatcher()); + } + + private ThoughtweftCharge(final ThoughtweftCharge card) { + super(card); + } + + @Override + public ThoughtweftCharge copy() { + return new ThoughtweftCharge(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/ThoughtweftImbuer.java b/Mage.Sets/src/mage/cards/t/ThoughtweftImbuer.java new file mode 100644 index 00000000000..d6187039576 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThoughtweftImbuer.java @@ -0,0 +1,50 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.common.AttacksAloneControlledTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +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.filter.common.FilterControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ThoughtweftImbuer extends CardImpl { + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( + new FilterControlledPermanent(SubType.KITHKIN), null + ); + private static final Hint hint = new ValueHint("Kithkin you control", xValue); + + public ThoughtweftImbuer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.ADVISOR); + this.power = new MageInt(0); + this.toughness = new MageInt(5); + + // Whenever a creature you control attacks alone, it gets +X/+X until end of turn, where X is the number of Kithkin you control. + this.addAbility(new AttacksAloneControlledTriggeredAbility( + new BoostTargetEffect(xValue, xValue), true, false + ).addHint(hint)); + } + + private ThoughtweftImbuer(final ThoughtweftImbuer card) { + super(card); + } + + @Override + public ThoughtweftImbuer copy() { + return new ThoughtweftImbuer(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/ThoughtweftLieutenant.java b/Mage.Sets/src/mage/cards/t/ThoughtweftLieutenant.java new file mode 100644 index 00000000000..5a7bc618c5d --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThoughtweftLieutenant.java @@ -0,0 +1,50 @@ +package mage.cards.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldThisOrAnotherTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author muz + */ +public final class ThoughtweftLieutenant extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent(SubType.KITHKIN, "Kithkin"); + + public ThoughtweftLieutenant(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever this creature or another Kithkin you control enters, target creature you control gets +1+1 and gains trample until end of turn. + Ability ability = new EntersBattlefieldThisOrAnotherTriggeredAbility( + new BoostTargetEffect(1, 1).setText("target creature you control gets +1/+1"), filter, false, true + ); + ability.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()) + .setText("and gains trample until end of turn")); + ability.addTarget(new TargetControlledCreaturePermanent()); + } + + private ThoughtweftLieutenant(final ThoughtweftLieutenant card) { + super(card); + } + + @Override + public ThoughtweftLieutenant copy() { + return new ThoughtweftLieutenant(this); + } +} 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/TombOfTheDuskRose.java b/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java deleted file mode 100644 index 46a7ecf9733..00000000000 --- a/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java +++ /dev/null @@ -1,91 +0,0 @@ -package mage.cards.t; - -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.mana.AnyColorManaAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SuperType; -import mage.constants.Zone; -import mage.filter.StaticFilters; -import mage.game.ExileZone; -import mage.game.Game; -import mage.players.Player; -import mage.target.TargetCard; -import mage.target.common.TargetCardInExile; -import mage.util.CardUtil; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class TombOfTheDuskRose extends CardImpl { - - public TombOfTheDuskRose(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - this.nightCard = true; - - // (Transforms from Profane Procession.) - - // {T}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); - - // {2}{W}{B},{T} : Put a creature card exiled with this permanent onto the battlefield under your control. - Ability ability = new SimpleActivatedAbility(new TombOfTheDuskRoseEffect(), new ManaCostsImpl<>("{2}{W}{B}")); - ability.addCost(new TapSourceCost()); - this.addAbility(ability); - } - - private TombOfTheDuskRose(final TombOfTheDuskRose card) { - super(card); - } - - @Override - public TombOfTheDuskRose copy() { - return new TombOfTheDuskRose(this); - } -} - -class TombOfTheDuskRoseEffect extends OneShotEffect { - - TombOfTheDuskRoseEffect() { - super(Outcome.PutCardInPlay); - this.staticText = "put a creature card exiled with this permanent onto the battlefield under your control"; - } - - private TombOfTheDuskRoseEffect(final TombOfTheDuskRoseEffect effect) { - super(effect); - } - - @Override - public TombOfTheDuskRoseEffect copy() { - return new TombOfTheDuskRoseEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); - if (exileZone == null || exileZone.count(StaticFilters.FILTER_CARD_CREATURE, game) < 1) { - return false; - } - TargetCard targetCard = new TargetCardInExile(StaticFilters.FILTER_CARD_CREATURE, exileZone.getId()); - targetCard.withNotTarget(true); - controller.choose(outcome, targetCard, source, game); - Card card = game.getCard(targetCard.getFirstTarget()); - return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game); - } -} 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/TovolarsMagehunter.java b/Mage.Sets/src/mage/cards/t/TovolarsMagehunter.java deleted file mode 100644 index 24b484f51df..00000000000 --- a/Mage.Sets/src/mage/cards/t/TovolarsMagehunter.java +++ /dev/null @@ -1,51 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.common.SpellCastOpponentTriggeredAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SetTargetPointer; -import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.StaticFilters; - -import java.util.UUID; - -/** - * @author North - */ -public final class TovolarsMagehunter extends CardImpl { - - public TovolarsMagehunter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.WEREWOLF); - - this.color.setRed(true); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Whenever an opponent casts a spell, Tovolar's Magehunter deals 2 damage to that player. - this.addAbility(new SpellCastOpponentTriggeredAbility( - Zone.BATTLEFIELD, new DamageTargetEffect(2).withTargetDescription("that player"), - StaticFilters.FILTER_SPELL_A, false, SetTargetPointer.PLAYER - )); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Tovolar's Magehunter. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private TovolarsMagehunter(final TovolarsMagehunter card) { - super(card); - } - - @Override - public TovolarsMagehunter copy() { - return new TovolarsMagehunter(this); - } -} 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/TranceKujaFateDefied.java b/Mage.Sets/src/mage/cards/t/TranceKujaFateDefied.java deleted file mode 100644 index c16551c9f7d..00000000000 --- a/Mage.Sets/src/mage/cards/t/TranceKujaFateDefied.java +++ /dev/null @@ -1,84 +0,0 @@ -package mage.cards.t; - -import java.util.Optional; -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.util.CardUtil; - -/** - * @author balazskristof - */ -public final class TranceKujaFateDefied extends CardImpl { - - public TranceKujaFateDefied(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.AVATAR); - this.subtype.add(SubType.WIZARD); - this.power = new MageInt(4); - this.toughness = new MageInt(6); - - this.color.setBlack(true); - this.color.setRed(true); - - this.nightCard = true; - - // Flame Star -- If a Wizard you control would deal damage to a permanent or player, it deals double that damage instead. - this.addAbility(new SimpleStaticAbility(new TranceKujaFateDefiedEffect()).withFlavorWord("Flame Star")); - } - - private TranceKujaFateDefied(final TranceKujaFateDefied card) { - super(card); - } - - @Override - public TranceKujaFateDefied copy() { - return new TranceKujaFateDefied(this); - } -} - -class TranceKujaFateDefiedEffect extends ReplacementEffectImpl { - - TranceKujaFateDefiedEffect() { - super(Duration.WhileOnBattlefield, Outcome.Damage); - staticText = "If a Wizard you control would deal damage to a permanent or player, it deals double that damage instead."; - } - - private TranceKujaFateDefiedEffect(final TranceKujaFateDefiedEffect effect) { - super(effect); - } - - @Override - public TranceKujaFateDefiedEffect copy() { - return new TranceKujaFateDefiedEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER) - || event.getType().equals(GameEvent.EventType.DAMAGE_PERMANENT); - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - return game.getControllerId(event.getSourceId()).equals(source.getControllerId()) - && Optional.ofNullable(game.getObject(event.getSourceId())) - .map(object -> object.hasSubtype(SubType.WIZARD, game)) - .orElse(false); - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - event.setAmount(CardUtil.overflowMultiply(event.getAmount(), 2)); - return false; - } -} \ No newline at end of file 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/TributaryVaulter.java b/Mage.Sets/src/mage/cards/t/TributaryVaulter.java new file mode 100644 index 00000000000..290dccd3f5f --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TributaryVaulter.java @@ -0,0 +1,56 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesTappedSourceTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.FlyingAbility; +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.mageobject.AnotherPredicate; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TributaryVaulter extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledPermanent(SubType.MERFOLK, "another target Merfolk you control"); + + static { + filter.add(AnotherPredicate.instance); + } + + public TributaryVaulter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever this creature becomes tapped, another target Merfolk you control gets +2/+0 until end of turn. + Ability ability = new BecomesTappedSourceTriggeredAbility(new BoostTargetEffect(2, 0)); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private TributaryVaulter(final TributaryVaulter card) { + super(card); + } + + @Override + public TributaryVaulter copy() { + return new TributaryVaulter(this); + } +} 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/TrugaCliffcharger.java b/Mage.Sets/src/mage/cards/t/TrugaCliffcharger.java deleted file mode 100644 index 79f4a82dd9c..00000000000 --- a/Mage.Sets/src/mage/cards/t/TrugaCliffcharger.java +++ /dev/null @@ -1,62 +0,0 @@ -package mage.cards.t; - -import mage.MageInt; -import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.costs.common.DiscardCardCost; -import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.target.common.TargetCardInLibrary; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class TrugaCliffcharger extends CardImpl { - - private static final FilterCard filter = new FilterCard("a land or battle card"); - - static { - filter.add(Predicates.or( - CardType.LAND.getPredicate(), - CardType.BATTLE.getPredicate() - )); - } - - public TrugaCliffcharger(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.RHINO); - this.power = new MageInt(3); - this.toughness = new MageInt(4); - this.color.setRed(true); - this.color.setGreen(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // When Truga Cliffcharger enters the battlefield, you may discard a card. If you do, search your library for a land or battle card, reveal it, put it into your hand, then shuffle. - this.addAbility(new EntersBattlefieldTriggeredAbility( - new DoIfCostPaid(new SearchLibraryPutInHandEffect( - new TargetCardInLibrary(filter), true - ), new DiscardCardCost()) - )); - } - - private TrugaCliffcharger(final TrugaCliffcharger card) { - super(card); - } - - @Override - public TrugaCliffcharger copy() { - return new TrugaCliffcharger(this); - } -} 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/TrystanCallousCultivator.java b/Mage.Sets/src/mage/cards/t/TrystanCallousCultivator.java new file mode 100644 index 00000000000..f717b709f84 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TrystanCallousCultivator.java @@ -0,0 +1,89 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.common.TransformIntoSourceTriggeredAbility; +import mage.abilities.common.TransformsOrEntersTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.CardsInControllerGraveyardCondition; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.*; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.abilities.keyword.DeathtouchAbility; +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.FilterCard; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TrystanCallousCultivator extends TransformingDoubleFacedCard { + + private static final FilterCard filter = new FilterCard(SubType.ELF); + private static final Condition condition = new CardsInControllerGraveyardCondition(1, filter); + private static final Hint hint = new ConditionHint(condition, "There is an Elf card in your graveyard"); + + public TrystanCallousCultivator(UUID ownerId, CardSetInfo setInfo) { + super( + ownerId, setInfo, + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELF, SubType.DRUID}, "{2}{G}", + "Trystan, Penitent Culler", + new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.ELF, SubType.WARLOCK}, "B" + ); + this.getLeftHalfCard().setPT(3, 4); + this.getRightHalfCard().setPT(3, 4); + + // Deathtouch + this.getLeftHalfCard().addAbility(DeathtouchAbility.getInstance()); + + // Whenever this creature enters or transforms into Trystan, Callous Cultivator, mill three cards. Then if there is an Elf card in your graveyard, you gain 2 life. + Ability ability = new TransformsOrEntersTriggeredAbility( + new MillCardsControllerEffect(3), false + ); + ability.addEffect(new ConditionalOneShotEffect( + new GainLifeEffect(2), condition, "Then if there is " + + "an Elf card in your graveyard, you gain 2 life" + )); + this.getLeftHalfCard().addAbility(ability.addHint(hint)); + + // At the beginning of your first main phase, you may pay {B}. If you do, transform Trystan. + this.getLeftHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{B}")) + )); + + // Deathtouch + this.getRightHalfCard().addAbility(DeathtouchAbility.getInstance()); + + // Trystan, Penitent Culler + // Whenever this creature transforms into Trystan, Penitent Culler, mill three cards, then you may exile an Elf card from your graveyard. If you do, each opponent loses 2 life. + ability = new TransformIntoSourceTriggeredAbility(new MillCardsControllerEffect(3)); + ability.addEffect(new DoIfCostPaid( + new LoseLifeOpponentsEffect(2), + new ExileFromGraveCost(new TargetCardInYourGraveyard(filter)) + )); + this.getRightHalfCard().addAbility(ability); + + // At the beginning of your first main phase, you may pay {G}. If you do, transform Trystan. + this.getRightHalfCard().addAbility(new BeginningOfFirstMainTriggeredAbility( + new DoIfCostPaid(new TransformSourceEffect(), new ManaCostsImpl<>("{G}")) + )); + } + + private TrystanCallousCultivator(final TrystanCallousCultivator card) { + super(card); + } + + @Override + public TrystanCallousCultivator copy() { + return new TrystanCallousCultivator(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/Tweeze.java b/Mage.Sets/src/mage/cards/t/Tweeze.java new file mode 100644 index 00000000000..47aca89d9ee --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/Tweeze.java @@ -0,0 +1,38 @@ +package mage.cards.t; + +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.common.TargetAnyTarget; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Tweeze extends CardImpl { + + public Tweeze(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); + + // Tweeze deals 3 damage to any target. You may discard a card. If you do, draw a card. + this.getSpellAbility().addEffect(new DamageTargetEffect(3)); + this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().addEffect(new DoIfCostPaid( + new DrawCardSourceControllerEffect(1), new DiscardCardCost() + )); + } + + private Tweeze(final Tweeze card) { + super(card); + } + + @Override + public Tweeze copy() { + return new Tweeze(this); + } +} 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/UnforgivingAim.java b/Mage.Sets/src/mage/cards/u/UnforgivingAim.java new file mode 100644 index 00000000000..8dc0154edb4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnforgivingAim.java @@ -0,0 +1,45 @@ +package mage.cards.u; + +import java.util.UUID; + +import mage.abilities.Mode; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.game.permanent.token.BlackGreenElfToken; +import mage.target.TargetPermanent; +import mage.target.common.TargetEnchantmentPermanent; + +/** + * + * @author muz + */ +public final class UnforgivingAim extends CardImpl { + + public UnforgivingAim(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); + + // Choose one -- + // * Destroy target creature with flying. + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_FLYING)); + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + + // * Destroy target enchantment. + this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect()).addTarget(new TargetEnchantmentPermanent())); + + // * Create a 2/2 black and green Elf creature token. + this.getSpellAbility().addMode(new Mode(new CreateTokenEffect(new BlackGreenElfToken()))); + } + + private UnforgivingAim(final UnforgivingAim card) { + super(card); + } + + @Override + public UnforgivingAim copy() { + return new UnforgivingAim(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UnhallowedCathar.java b/Mage.Sets/src/mage/cards/u/UnhallowedCathar.java deleted file mode 100644 index 9f61fbec892..00000000000 --- a/Mage.Sets/src/mage/cards/u/UnhallowedCathar.java +++ /dev/null @@ -1,42 +0,0 @@ - -package mage.cards.u; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.CantBlockAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; - -/** - * - * @author BetaSteward - */ -public final class UnhallowedCathar extends CardImpl { - - public UnhallowedCathar(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},""); - this.subtype.add(SubType.ZOMBIE); - this.subtype.add(SubType.SOLDIER); - this.color.setBlack(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - this.power = new MageInt(2); - this.toughness = new MageInt(1); - - // Unhallowed Cathar can't block. - this.addAbility(new CantBlockAbility()); - } - - private UnhallowedCathar(final UnhallowedCathar card) { - super(card); - } - - @Override - public UnhallowedCathar copy() { - return new UnhallowedCathar(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/UntamedPup.java b/Mage.Sets/src/mage/cards/u/UntamedPup.java deleted file mode 100644 index 4dbcd4007c9..00000000000 --- a/Mage.Sets/src/mage/cards/u/UntamedPup.java +++ /dev/null @@ -1,74 +0,0 @@ -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.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; -import mage.abilities.keyword.NightboundAbility; -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.counters.CounterType; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.target.common.TargetCreaturePermanent; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class UntamedPup extends CardImpl { - - private static final FilterPermanent filter = new FilterPermanent("Wolves and Werewolves"); - - static { - filter.add(Predicates.or( - SubType.WOLF.getPredicate(), - SubType.WEREWOLF.getPredicate() - )); - } - - public UntamedPup(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.setGreen(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Other Wolves and Werewolves you control have trample. - this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( - TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter, true - ))); - - // {3}{G}: Put a +1/+1 counter on target creature. - Ability ability = new SimpleActivatedAbility( - new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{3}{G}") - ); - ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private UntamedPup(final UntamedPup card) { - super(card); - } - - @Override - public UntamedPup copy() { - return new UntamedPup(this); - } -} diff --git a/Mage.Sets/src/mage/cards/u/UnwelcomeSprite.java b/Mage.Sets/src/mage/cards/u/UnwelcomeSprite.java new file mode 100644 index 00000000000..79a748d3bd1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnwelcomeSprite.java @@ -0,0 +1,44 @@ +package mage.cards.u; + +import mage.MageInt; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.condition.common.OpponentsTurnCondition; +import mage.abilities.effects.keyword.SurveilEffect; +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 UnwelcomeSprite extends CardImpl { + + public UnwelcomeSprite(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add(SubType.FAERIE); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever you cast a spell during an opponent's turn, surveil 2. + this.addAbility(new SpellCastControllerTriggeredAbility(new SurveilEffect(2), false) + .withTriggerCondition(OpponentsTurnCondition.instance)); + } + + private UnwelcomeSprite(final UnwelcomeSprite card) { + super(card); + } + + @Override + public UnwelcomeSprite copy() { + return new UnwelcomeSprite(this); + } +} 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/u/UrzaAcademyHeadmaster.java b/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java index 0b091865b6b..c720f977813 100644 --- a/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java +++ b/Mage.Sets/src/mage/cards/u/UrzaAcademyHeadmaster.java @@ -190,7 +190,7 @@ class UrzaAcademyHeadmasterRandomEffect extends OneShotEffect { break; case 12: // NISSA SAGE ANIMIST 1 sb.append("Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand."); - effects.add(new mage.cards.n.NissaSageAnimist(controller.getId(), setInfo).getAbilities().get(2).getEffects().get(0)); + effects.add(new mage.cards.n.NissaVastwoodSeer(controller.getId(), setInfo).getRightHalfCard().getAbilities().get(2).getEffects().get(0)); break; case 13: // NISSA WORLDWAKER 1 sb.append("Target land you control becomes a 4/4 Elemental creature with trample. It's still a land."); diff --git a/Mage.Sets/src/mage/cards/v/ValorsReachTagTeam.java b/Mage.Sets/src/mage/cards/v/ValorsReachTagTeam.java deleted file mode 100644 index b01d199a7c8..00000000000 --- a/Mage.Sets/src/mage/cards/v/ValorsReachTagTeam.java +++ /dev/null @@ -1,35 +0,0 @@ -package mage.cards.v; - -import mage.abilities.effects.common.CreateTokenEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.game.permanent.token.ValorsReachTagTeamToken; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ValorsReachTagTeam extends CardImpl { - - public ValorsReachTagTeam(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, ""); - - this.color.setWhite(true); - this.color.setRed(true); - this.nightCard = true; - - // Create two 3/2 red and white Warrior creature tokens with "Whenever this creature and at least one other creature token attack, put a +1/+1 counter on this creature." - this.getSpellAbility().addEffect(new CreateTokenEffect(new ValorsReachTagTeamToken(), 2)); - } - - private ValorsReachTagTeam(final ValorsReachTagTeam card) { - super(card); - } - - @Override - public ValorsReachTagTeam copy() { - return new ValorsReachTagTeam(this); - } -} 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/VertexPaladin.java b/Mage.Sets/src/mage/cards/v/VertexPaladin.java deleted file mode 100644 index 179114e6001..00000000000 --- a/Mage.Sets/src/mage/cards/v/VertexPaladin.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.cards.v; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.abilities.keyword.FlyingAbility; -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 VertexPaladin extends CardImpl { - - public VertexPaladin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ANGEL); - this.subtype.add(SubType.KNIGHT); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.color.setWhite(true); - this.color.setBlue(true); - this.nightCard = true; - - // Flying - this.addAbility(FlyingAbility.getInstance()); - - // Vertex Paladin's power and toughness are each equal to the number of creatures you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CreaturesYouControlCount.PLURAL))); - } - - private VertexPaladin(final VertexPaladin card) { - super(card); - } - - @Override - public VertexPaladin copy() { - return new VertexPaladin(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VesselOfTheAllConsuming.java b/Mage.Sets/src/mage/cards/v/VesselOfTheAllConsuming.java deleted file mode 100644 index a4ac3365a20..00000000000 --- a/Mage.Sets/src/mage/cards/v/VesselOfTheAllConsuming.java +++ /dev/null @@ -1,121 +0,0 @@ -package mage.cards.v; - -import mage.MageInt; -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.common.DealsDamageSourceTriggeredAbility; -import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; -import mage.abilities.condition.Condition; -import mage.abilities.effects.common.LoseGameTargetPlayerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.TrampleAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.WatcherScope; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.watchers.Watcher; - -import java.util.AbstractMap; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class VesselOfTheAllConsuming extends CardImpl { - - public VesselOfTheAllConsuming(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, ""); - - this.subtype.add(SubType.OGRE); - this.subtype.add(SubType.SHAMAN); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - this.color.setBlack(true); - this.color.setRed(true); - this.nightCard = true; - - // Trample - this.addAbility(TrampleAbility.getInstance()); - - // Whenever Vessel of the All-Consuming deals damage, put a +1/+1 counter on it. - this.addAbility(new DealsDamageSourceTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))); - - // Whenever Vessel of the All-Consuming deals damage to a player, if it has dealt 10 or more damage to that player this turn, they lose the game. - this.addAbility(new DealsDamageToAPlayerTriggeredAbility( - new LoseGameTargetPlayerEffect().setText("they lose the game"), false, true - ).withInterveningIf(VesselOfTheAllConsumingCondition.instance)); - } - - private VesselOfTheAllConsuming(final VesselOfTheAllConsuming card) { - super(card); - } - - @Override - public VesselOfTheAllConsuming copy() { - return new VesselOfTheAllConsuming(this); - } - - public static Watcher makeWatcher() { - return new VesselOfTheAllConsumingWatcher(); - } -} - -enum VesselOfTheAllConsumingCondition implements Condition { - instance; - - @Override - public boolean apply(Game game, Ability source) { - return VesselOfTheAllConsumingWatcher.checkPermanent(game, source); - } - - @Override - public String toString() { - return "it has dealt 10 or more damage to that player this turn"; - } -} - -class VesselOfTheAllConsumingWatcher extends Watcher { - - private final Map, Integer> morMap = new HashMap<>(); - - VesselOfTheAllConsumingWatcher() { - super(WatcherScope.GAME); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() != GameEvent.EventType.DAMAGED_PLAYER) { - return; - } - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null) { - int damage = event.getAmount(); - morMap.compute(new AbstractMap.SimpleImmutableEntry(new MageObjectReference(permanent, game), event.getTargetId()), - (u, i) -> i == null ? damage : Integer.sum(i, damage)); - } - } - - @Override - public void reset() { - super.reset(); - morMap.clear(); - } - - static boolean checkPermanent(Game game, Ability source) { - Map, Integer> morMap = game.getState() - .getWatcher(VesselOfTheAllConsumingWatcher.class) - .morMap; - Entry key = new AbstractMap.SimpleImmutableEntry( - new MageObjectReference(game.getPermanent(source.getSourceId()), game), - source.getEffects().get(0).getTargetPointer().getFirst(game, source)); - return morMap.getOrDefault(key, 0) >= 10; - } -} diff --git a/Mage.Sets/src/mage/cards/v/Vibrance.java b/Mage.Sets/src/mage/cards/v/Vibrance.java new file mode 100644 index 00000000000..7aaa6f71830 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/Vibrance.java @@ -0,0 +1,57 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.TwoOfManaColorSpentCondition; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.keyword.EvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterLandCard; +import mage.target.common.TargetAnyTarget; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author PurpleCrowbar + */ +public final class Vibrance extends CardImpl { + + public Vibrance(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R/G}{R/G}"); + + this.subtype.add(SubType.ELEMENTAL, SubType.INCARNATION); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When this creature enters, if {R}{R} was spent to cast it, this creature deals 3 damage to any target. + Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(3)) + .withInterveningIf(TwoOfManaColorSpentCondition.RED); + ability.addTarget(new TargetAnyTarget()); + this.addAbility(ability); + + // When this creature enters, if {G}{G} was spent to cast it, search your library for a land card, reveal it, put it into your hand, then shuffle. You gain 2 life. + ability = new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterLandCard()), true)) + .withInterveningIf(TwoOfManaColorSpentCondition.GREEN); + ability.addEffect(new GainLifeEffect(2)); + this.addAbility(ability); + + // Evoke {R/G}{R/G} + this.addAbility(new EvokeAbility("{R/G}{R/G}")); + } + + private Vibrance(final Vibrance card) { + super(card); + } + + @Override + public Vibrance copy() { + return new Vibrance(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VildinPackAlpha.java b/Mage.Sets/src/mage/cards/v/VildinPackAlpha.java deleted file mode 100644 index 9bfc27a5810..00000000000 --- a/Mage.Sets/src/mage/cards/v/VildinPackAlpha.java +++ /dev/null @@ -1,83 +0,0 @@ -package mage.cards.v; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; - -import java.util.UUID; - -/** - * @author LevelX2 - */ -public final class VildinPackAlpha extends CardImpl { - - private static final FilterPermanent filter = new FilterCreaturePermanent(SubType.WEREWOLF, "a Werewolf"); - - public VildinPackAlpha(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(3); - this.color.setRed(true); - - this.nightCard = true; - - // Whenever a Werewolf you control enters, you may transform it. - this.addAbility(new EntersBattlefieldControlledTriggeredAbility( - Zone.BATTLEFIELD, new VildinPackAlphaEffect(), filter, - true, SetTargetPointer.PERMANENT - )); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Vildin-Pack Alpha. - this.addAbility(new WerewolfBackTriggeredAbility()); - } - - private VildinPackAlpha(final VildinPackAlpha card) { - super(card); - } - - @Override - public VildinPackAlpha copy() { - return new VildinPackAlpha(this); - } -} - -class VildinPackAlphaEffect extends OneShotEffect { - - VildinPackAlphaEffect() { - super(Outcome.Benefit); - this.staticText = "you may transform it"; - } - - private VildinPackAlphaEffect(final VildinPackAlphaEffect effect) { - super(effect); - } - - @Override - public VildinPackAlphaEffect copy() { - return new VildinPackAlphaEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - Permanent werewolf = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (werewolf != null) { - werewolf.transform(source, game); - } - 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/VillagePillagers.java b/Mage.Sets/src/mage/cards/v/VillagePillagers.java new file mode 100644 index 00000000000..6bf7cab9496 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VillagePillagers.java @@ -0,0 +1,61 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.keyword.WitherAbility; +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.FilterOpponentsCreaturePermanent; +import mage.filter.predicate.permanent.CounterAnyPredicate; +import mage.game.permanent.token.TreasureToken; + +import java.util.UUID; + +/** + * @author PurpleCrowbar + */ +public final class VillagePillagers extends CardImpl { + + private static final FilterPermanent filter + = new FilterOpponentsCreaturePermanent("a creature an opponent controls with a counter on it"); + + static { + filter.add(CounterAnyPredicate.instance); + } + + public VillagePillagers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.subtype.add(SubType.GOBLIN, SubType.WARRIOR); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Wither + this.addAbility(WitherAbility.getInstance()); + + // When this creature enters, it deals 1 damage to each creature your opponents control. + this.addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect( + 1, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE + ).setText("it deals 1 damage to each creature your opponents control"))); + + // Whenever a creature an opponent controls with a counter on it dies, you create a tapped Treasure token. + this.addAbility(new DiesCreatureTriggeredAbility( + new CreateTokenEffect(new TreasureToken(), 1, true), false, filter + )); + } + + private VillagePillagers(final VillagePillagers card) { + super(card); + } + + @Override + public VillagePillagers copy() { + return new VillagePillagers(this); + } +} 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/VinebredBrawler.java b/Mage.Sets/src/mage/cards/v/VinebredBrawler.java new file mode 100644 index 00000000000..f045eea8e60 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VinebredBrawler.java @@ -0,0 +1,61 @@ +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.target.TargetPermanent; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author muz + */ +public final class VinebredBrawler extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.ELF, "another target Elf you control"); + + static { + filter.add(AnotherPredicate.instance); + } + + public VinebredBrawler(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // This creature must be blocked if able. + this.addAbility(new SimpleStaticAbility(new MustBeBlockedByAtLeastOneSourceEffect(Duration.WhileOnBattlefield))); + + // Whenever this creature attacks, another target Elf you control gets +2/+1 until end of turn. + Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(2, 1, Duration.EndOfTurn), false); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + private VinebredBrawler(final VinebredBrawler card) { + super(card); + } + + @Override + public VinebredBrawler copy() { + return new VinebredBrawler(this); + } +} diff --git a/Mage.Sets/src/mage/cards/v/VirulentEmissary.java b/Mage.Sets/src/mage/cards/v/VirulentEmissary.java new file mode 100644 index 00000000000..f8a074fb442 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VirulentEmissary.java @@ -0,0 +1,44 @@ + +package mage.cards.v; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +/** + * + * @author muz + */ +public final class VirulentEmissary extends CardImpl { + + public VirulentEmissary(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{G}"); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.ASSASSIN); + + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Whenever another creature you control enters, you gain 1 life. + this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL)); + } + + private VirulentEmissary(final VirulentEmissary card) { + super(card); + } + + @Override + public VirulentEmissary copy() { + return new VirulentEmissary(this); + } +} 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/VoraciousTomeSkimmer.java b/Mage.Sets/src/mage/cards/v/VoraciousTomeSkimmer.java new file mode 100644 index 00000000000..5f552503a9c --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/VoraciousTomeSkimmer.java @@ -0,0 +1,47 @@ +package mage.cards.v; + +import mage.MageInt; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.condition.common.OpponentsTurnCondition; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +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 VoraciousTomeSkimmer extends CardImpl { + + public VoraciousTomeSkimmer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U/B}{U/B}{U/B}"); + + this.subtype.add(SubType.FAERIE); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever you cast a spell during an opponent's turn, you may pay 1 life. If you do, draw a card. + this.addAbility(new SpellCastControllerTriggeredAbility( + new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new PayLifeCost(1)), false + ).withTriggerCondition(OpponentsTurnCondition.instance)); + } + + private VoraciousTomeSkimmer(final VoraciousTomeSkimmer card) { + super(card); + } + + @Override + public VoraciousTomeSkimmer copy() { + return new VoraciousTomeSkimmer(this); + } +} 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/WanderbrinePreacher.java b/Mage.Sets/src/mage/cards/w/WanderbrinePreacher.java new file mode 100644 index 00000000000..9c733a63f53 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WanderbrinePreacher.java @@ -0,0 +1,38 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.common.BecomesTappedSourceTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WanderbrinePreacher extends CardImpl { + + public WanderbrinePreacher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.CLERIC); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever this creature becomes tapped, you gain 2 life. + this.addAbility(new BecomesTappedSourceTriggeredAbility(new GainLifeEffect(2))); + } + + private WanderbrinePreacher(final WanderbrinePreacher card) { + super(card); + } + + @Override + public WanderbrinePreacher copy() { + return new WanderbrinePreacher(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WanderwineDistracter.java b/Mage.Sets/src/mage/cards/w/WanderwineDistracter.java new file mode 100644 index 00000000000..5b55e97d8db --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WanderwineDistracter.java @@ -0,0 +1,42 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesTappedSourceTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetOpponentsCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WanderwineDistracter extends CardImpl { + + public WanderwineDistracter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add(SubType.MERFOLK); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Whenever this creature becomes tapped, target creature an opponent controls gets -3/-0 until end of turn. + Ability ability = new BecomesTappedSourceTriggeredAbility(new BoostTargetEffect(-3, 0)); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + this.addAbility(ability); + } + + private WanderwineDistracter(final WanderwineDistracter card) { + super(card); + } + + @Override + public WanderwineDistracter copy() { + return new WanderwineDistracter(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WarbriarBlessing.java b/Mage.Sets/src/mage/cards/w/WarbriarBlessing.java index ee17f2c4a7b..36c705727e2 100644 --- a/Mage.Sets/src/mage/cards/w/WarbriarBlessing.java +++ b/Mage.Sets/src/mage/cards/w/WarbriarBlessing.java @@ -3,8 +3,8 @@ package mage.cards.w; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.FightEnchantedTargetEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -13,8 +13,6 @@ 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.TargetPermanent; import java.util.UUID; @@ -37,7 +35,7 @@ public final class WarbriarBlessing extends CardImpl { this.addAbility(ability); // When Warbriar Blessing enters the battlefield, enchanted creature fights up to one target creature you don't control. - ability = new EntersBattlefieldTriggeredAbility(new WarbriarBlessingEffect()); + ability = new EntersBattlefieldTriggeredAbility(new FightEnchantedTargetEffect()); ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL, false)); this.addAbility(ability); @@ -54,35 +52,3 @@ public final class WarbriarBlessing extends CardImpl { return new WarbriarBlessing(this); } } - -class WarbriarBlessingEffect extends OneShotEffect { - - WarbriarBlessingEffect() { - super(Outcome.Benefit); - staticText = "enchanted creature fights up to one target creature you don't control. " + - "(Each deals damage equal to its power to the other.)"; - } - - private WarbriarBlessingEffect(final WarbriarBlessingEffect effect) { - super(effect); - } - - @Override - public WarbriarBlessingEffect copy() { - return new WarbriarBlessingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = source.getSourcePermanentIfItStillExists(game); - Permanent opponentsPermanent = game.getPermanent(source.getFirstTarget()); - if (permanent == null || opponentsPermanent == null) { - return false; - } - Permanent attach = game.getPermanent(permanent.getAttachedTo()); - if (attach == null) { - return false; - } - return attach.fight(opponentsPermanent, source, game); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WarrenTorchmaster.java b/Mage.Sets/src/mage/cards/w/WarrenTorchmaster.java new file mode 100644 index 00000000000..d45c6ca37cc --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WarrenTorchmaster.java @@ -0,0 +1,49 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.common.DoWhenCostPaid; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.triggers.BeginningOfCombatTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WarrenTorchmaster extends CardImpl { + + public WarrenTorchmaster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // At the beginning of combat on your turn, you may blight 1. When you do, target creature gains haste until end of turn. + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new GainAbilityTargetEffect(HasteAbility.getInstance()), false + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(new BeginningOfCombatTriggeredAbility( + new DoWhenCostPaid(ability, new BlightCost(1), "Blight 1?") + )); + } + + private WarrenTorchmaster(final WarrenTorchmaster card) { + super(card); + } + + @Override + public WarrenTorchmaster copy() { + return new WarrenTorchmaster(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WaterWhip.java b/Mage.Sets/src/mage/cards/w/WaterWhip.java index 7bf6ea5f9fe..5917a472da4 100644 --- a/Mage.Sets/src/mage/cards/w/WaterWhip.java +++ b/Mage.Sets/src/mage/cards/w/WaterWhip.java @@ -1,12 +1,15 @@ package mage.cards.w; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.WaterbendCost; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.Zone; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -23,6 +26,9 @@ public final class WaterWhip extends CardImpl { // As an additional cost to cast this spell, waterbend {5}. this.getSpellAbility().addCost(new WaterbendCost(5)); + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {5}") + ).setRuleAtTheTop(true)); // Return up to two target creatures to their owners' hands. Draw two cards. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/w/WaterbendersRestoration.java b/Mage.Sets/src/mage/cards/w/WaterbendersRestoration.java index a2f1cf39bed..a8ae100f9f5 100644 --- a/Mage.Sets/src/mage/cards/w/WaterbendersRestoration.java +++ b/Mage.Sets/src/mage/cards/w/WaterbendersRestoration.java @@ -1,11 +1,14 @@ package mage.cards.w; -import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.WaterbendXCost; import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; +import mage.abilities.effects.common.InfoEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.Zone; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.targetadjustment.XTargetsCountAdjuster; @@ -22,7 +25,10 @@ public final class WaterbendersRestoration extends CardImpl { this.subtype.add(SubType.LESSON); // As an additional cost to cast this spell, waterbend {X}. - this.getSpellAbility().addCost(new WaterbendCost("{X}")); + this.getSpellAbility().addCost(new WaterbendXCost()); + this.addAbility(new SimpleStaticAbility( + Zone.ALL, new InfoEffect("as an additional cost to cast this spell, waterbend {X}") + ).setRuleAtTheTop(true)); // Exile X target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step. this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect() 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/WaywardDisciple.java b/Mage.Sets/src/mage/cards/w/WaywardDisciple.java deleted file mode 100644 index fc43c45ec88..00000000000 --- a/Mage.Sets/src/mage/cards/w/WaywardDisciple.java +++ /dev/null @@ -1,55 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.DiesThisOrAnotherTriggeredAbility; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.TargetController; -import mage.filter.common.FilterCreaturePermanent; -import mage.target.common.TargetOpponent; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class WaywardDisciple extends CardImpl { - - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - } - - public WaywardDisciple(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(2); - this.toughness = new MageInt(4); - this.color.setBlack(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Whenever Wayward Disciple or another creature you control dies, target opponent loses 1 life and you gain 1 life. - Ability ability = new DiesThisOrAnotherTriggeredAbility(new LoseLifeTargetEffect(1), false, filter); - ability.addEffect(new GainLifeEffect(1).concatBy("and")); - ability.addTarget(new TargetOpponent()); - this.addAbility(ability); - } - - private WaywardDisciple(final WaywardDisciple card) { - super(card); - } - - @Override - public WaywardDisciple copy() { - return new WaywardDisciple(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/WestvaleCultLeader.java b/Mage.Sets/src/mage/cards/w/WestvaleCultLeader.java deleted file mode 100644 index 2cdb7950a39..00000000000 --- a/Mage.Sets/src/mage/cards/w/WestvaleCultLeader.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -import mage.abilities.hint.common.CreaturesYouControlHint; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.permanent.token.HumanClericToken; - -import java.util.UUID; - -/** - * @author fireshoes - */ -public final class WestvaleCultLeader extends CardImpl { - - public WestvaleCultLeader(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - this.subtype.add(SubType.HUMAN); - this.subtype.add(SubType.CLERIC); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.color.setWhite(true); - - // this card is the second face of double-faced card - this.nightCard = true; - - // Westvale Cult Leader's power and toughness are each equal to the number of creatures you control. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CreaturesYouControlCount.PLURAL)) - .addHint(CreaturesYouControlHint.instance)); - - // At the beginning of your end step, create a 1/1 white and black Human Cleric creature token. - this.addAbility(new BeginningOfEndStepTriggeredAbility(new CreateTokenEffect(new HumanClericToken()))); - } - - private WestvaleCultLeader(final WestvaleCultLeader card) { - super(card); - } - - @Override - public WestvaleCultLeader copy() { - return new WestvaleCultLeader(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WildUnraveling.java b/Mage.Sets/src/mage/cards/w/WildUnraveling.java new file mode 100644 index 00000000000..9afa1c9ce15 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WildUnraveling.java @@ -0,0 +1,40 @@ +package mage.cards.w; + +import mage.abilities.costs.OrCost; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WildUnraveling extends CardImpl { + + public WildUnraveling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{U}"); + + // As an additional cost to cast this spell, blight 2 or pay {1}. + this.getSpellAbility().addCost(new OrCost( + "blight 2 or pay {1}", new BlightCost(2), new GenericManaCost(2) + )); + + // Counter target spell. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell()); + } + + private WildUnraveling(final WildUnraveling card) { + super(card); + } + + @Override + public WildUnraveling copy() { + return new WildUnraveling(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WildbloodPack.java b/Mage.Sets/src/mage/cards/w/WildbloodPack.java deleted file mode 100644 index 6dd0d6f908a..00000000000 --- a/Mage.Sets/src/mage/cards/w/WildbloodPack.java +++ /dev/null @@ -1,54 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.WerewolfBackTriggeredAbility; -import mage.abilities.effects.common.continuous.BoostControlledEffect; -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 nantuko - */ -public final class WildbloodPack extends CardImpl { - - public WildbloodPack(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(5); - this.toughness = new MageInt(5); - - this.addAbility(TrampleAbility.getInstance()); - - // Attacking creatures you control get +3/+0. - this.addAbility(new SimpleStaticAbility(new BoostControlledEffect( - 3, 0, Duration.WhileOnBattlefield, - StaticFilters.FILTER_ATTACKING_CREATURES, false - ))); - - // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Wildblood Pack. - this.addAbility(new WerewolfBackTriggeredAbility()); - - } - - private WildbloodPack(final WildbloodPack card) { - super(card); - } - - @Override - public WildbloodPack copy() { - return new WildbloodPack(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WildsongHowler.java b/Mage.Sets/src/mage/cards/w/WildsongHowler.java deleted file mode 100644 index dad0a4f2a96..00000000000 --- a/Mage.Sets/src/mage/cards/w/WildsongHowler.java +++ /dev/null @@ -1,49 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.common.TransformsOrEntersTriggeredAbility; -import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.keyword.NightboundAbility; -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 TheElk801 - */ -public final class WildsongHowler extends CardImpl { - - public WildsongHowler(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.setGreen(true); - this.nightCard = true; - - // Whenever this creature enters the battlefield or transforms into Wildsong Howler, look at the top six cards of your library. - // You may reveal a creature card from among them and put it into your hand. - // Put the rest on the bottom of your library in a random order. - this.addAbility(new TransformsOrEntersTriggeredAbility( - new LookLibraryAndPickControllerEffect(6, 1, StaticFilters.FILTER_CARD_CREATURE_A, PutCards.HAND, PutCards.BOTTOM_RANDOM), - false)); - - // Nightbound - this.addAbility(new NightboundAbility()); - } - - private WildsongHowler(final WildsongHowler card) { - super(card); - } - - @Override - public WildsongHowler copy() { - return new WildsongHowler(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/WingedTempleOfOrazca.java b/Mage.Sets/src/mage/cards/w/WingedTempleOfOrazca.java deleted file mode 100644 index 8b286c53754..00000000000 --- a/Mage.Sets/src/mage/cards/w/WingedTempleOfOrazca.java +++ /dev/null @@ -1,88 +0,0 @@ -package mage.cards.w; - -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.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.keyword.FlyingAbility; -import mage.abilities.mana.AnyColorManaAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; - -/** - * - * @author LevelX2 - */ -public final class WingedTempleOfOrazca extends CardImpl { - - public WingedTempleOfOrazca(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); - - this.supertype.add(SuperType.LEGENDARY); - - this.nightCard = true; - - // (Transforms from Hadana's Climb.) - - // {T}: Add one mana of any color. - this.addAbility(new AnyColorManaAbility()); - - // {1}{G}{U}, {T}: Target creature you control gains flying and gets +X/+X until end of turn, where X is its power. - Ability ability = new SimpleActivatedAbility(new WingedTempleOfOrazcaEffect(), new ManaCostsImpl<>("{1}{G}{U}")); - ability.addCost(new TapSourceCost()); - ability.addTarget(new TargetControlledCreaturePermanent()); - this.addAbility(ability); - } - - private WingedTempleOfOrazca(final WingedTempleOfOrazca card) { - super(card); - } - - @Override - public WingedTempleOfOrazca copy() { - return new WingedTempleOfOrazca(this); - } -} - -class WingedTempleOfOrazcaEffect extends OneShotEffect { - - WingedTempleOfOrazcaEffect() { - super(Outcome.Benefit); - this.staticText = "target creature you control gains flying and gets +X/+X until end of turn, where X is its power"; - } - - private WingedTempleOfOrazcaEffect(final WingedTempleOfOrazcaEffect effect) { - super(effect); - } - - @Override - public WingedTempleOfOrazcaEffect copy() { - return new WingedTempleOfOrazcaEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (creature != null && creature.isCreature(game)) { - int pow = creature.getPower().getValue(); - ContinuousEffect effect = new BoostTargetEffect(pow, pow, Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(creature, game)); - game.addEffect(effect, source); - effect = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); - effect.setTargetPointer(new FixedTarget(creature, game)); - game.addEffect(effect, source); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/w/WinnowingForces.java b/Mage.Sets/src/mage/cards/w/WinnowingForces.java deleted file mode 100644 index 34ccc655ee8..00000000000 --- a/Mage.Sets/src/mage/cards/w/WinnowingForces.java +++ /dev/null @@ -1,45 +0,0 @@ -package mage.cards.w; - -import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.common.LandsYouControlCount; -import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect; -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 WinnowingForces extends CardImpl { - - public WinnowingForces(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.subtype.add(SubType.ELF); - this.subtype.add(SubType.WARRIOR); - this.power = new MageInt(0); - this.toughness = new MageInt(0); - this.color.setGreen(true); - this.color.setBlack(true); - this.nightCard = true; - - // Winnowing Forces's power and toughness are each equal to the number of lands you control. - this.addAbility(new SimpleStaticAbility( - Zone.ALL, new SetBasePowerToughnessSourceEffect(LandsYouControlCount.instance) - )); - } - - private WinnowingForces(final WinnowingForces card) { - super(card); - } - - @Override - public WinnowingForces copy() { - return new WinnowingForces(this); - } -} diff --git a/Mage.Sets/src/mage/cards/w/Wistfulness.java b/Mage.Sets/src/mage/cards/w/Wistfulness.java new file mode 100644 index 00000000000..35f6091e685 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/Wistfulness.java @@ -0,0 +1,64 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.TwoOfManaColorSpentCondition; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.keyword.EvokeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterArtifactOrEnchantmentPermanent; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class Wistfulness extends CardImpl { + + private static final FilterPermanent filter + = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment an opponent controls"); + + static { + filter.add(TargetController.OPPONENT.getControllerPredicate()); + } + + public Wistfulness(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G/U}{G/U}"); + + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.INCARNATION); + this.power = new MageInt(6); + this.toughness = new MageInt(5); + + // When this creature enters, if {G}{G} was spent to cast it, exile target artifact or enchantment an opponent controls. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect()) + .withInterveningIf(TwoOfManaColorSpentCondition.GREEN); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + + // When this creature enters, if {U}{U} was spent to cast it, draw two cards, then discard a card. + this.addAbility(new EntersBattlefieldTriggeredAbility( + new DrawDiscardControllerEffect(2, 1) + ).withInterveningIf(TwoOfManaColorSpentCondition.BLUE)); + + // Evoke {G/U}{G/U} + this.addAbility(new EvokeAbility("{G/U}{G/U}")); + } + + private Wistfulness(final Wistfulness card) { + super(card); + } + + @Override + public Wistfulness copy() { + return new Wistfulness(this); + } +} 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/cards/z/ZilorthaApexOfIkoria.java b/Mage.Sets/src/mage/cards/z/ZilorthaApexOfIkoria.java deleted file mode 100644 index 3509c40ef64..00000000000 --- a/Mage.Sets/src/mage/cards/z/ZilorthaApexOfIkoria.java +++ /dev/null @@ -1,82 +0,0 @@ -package mage.cards.z; - -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.AsThoughEffectImpl; -import mage.abilities.keyword.ReachAbility; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; - -import java.util.UUID; - -/** - * @author TheElk801 - */ -public final class ZilorthaApexOfIkoria extends CardImpl { - - public ZilorthaApexOfIkoria(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, ""); - - this.supertype.add(SuperType.LEGENDARY); - this.subtype.add(SubType.DINOSAUR); - this.power = new MageInt(8); - this.toughness = new MageInt(8); - this.color.setGreen(true); - this.nightCard = true; - - // Reach - this.addAbility(ReachAbility.getInstance()); - - // For each non-Human creature you control, you may have that creature assign its combat damage as though it weren't blocked. - this.addAbility(new SimpleStaticAbility(new ZilorthaApexOfIkoriaEffect())); - } - - private ZilorthaApexOfIkoria(final ZilorthaApexOfIkoria card) { - super(card); - } - - @Override - public ZilorthaApexOfIkoria copy() { - return new ZilorthaApexOfIkoria(this); - } -} - -class ZilorthaApexOfIkoriaEffect extends AsThoughEffectImpl { - - ZilorthaApexOfIkoriaEffect() { - super(AsThoughEffectType.DAMAGE_NOT_BLOCKED, Duration.WhileOnBattlefield, Outcome.Damage); - this.staticText = "for each non-Human creature you control, you may have that " + - "creature assign its combat damage as though it weren't blocked"; - } - - private ZilorthaApexOfIkoriaEffect(ZilorthaApexOfIkoriaEffect effect) { - super(effect); - } - - @Override - public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(sourceId); - return controller != null - && permanent != null - && permanent.isControlledBy(controller.getId()) - && !permanent.hasSubtype(SubType.HUMAN, game) - && controller.chooseUse(Outcome.Damage, "Have " + permanent.getLogName() - + " assign damage as though it weren't blocked?", source, game); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public ZilorthaApexOfIkoriaEffect copy() { - return new ZilorthaApexOfIkoriaEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java index 1cc47ff9291..705abf5f972 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbender.java @@ -4,15 +4,11 @@ import mage.cards.ExpansionSet; import mage.constants.Rarity; import mage.constants.SetType; -import java.util.Arrays; -import java.util.List; - /** * @author TheElk801 */ public final class AvatarTheLastAirbender extends ExpansionSet { - private static final List unfinished = Arrays.asList("Aang's Iceberg", "Aang, Swift Savior", "Avatar Aang", "Benevolent River Spirit", "Crashing Wave", "Flexible Waterbender", "Foggy Swamp Vinebender", "Foggy Swamp Visions", "Geyser Leaper", "Giant Koi", "Hama, the Bloodbender", "Invasion Submersible", "Katara, Bending Prodigy", "Katara, Water Tribe's Hope", "North Pole Patrol", "Ruinous Waterbending", "Secret of Bloodbending", "Spirit Water Revival", "The Legend of Kuruk", "The Unagi of Kyoshi Island", "Waterbender Ascension", "Waterbending Lesson", "Water Tribe Rallier", "Watery Grasp", "Yue, the Moon Spirit"); private static final AvatarTheLastAirbender instance = new AvatarTheLastAirbender(); public static AvatarTheLastAirbender getInstance() { @@ -61,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)); @@ -152,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)); @@ -430,7 +416,5 @@ public final class AvatarTheLastAirbender extends ExpansionSet { cards.add(new SetCardInfo("Zuko, Conflicted", 253, Rarity.RARE, mage.cards.z.ZukoConflicted.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zuko, Conflicted", 302, Rarity.RARE, mage.cards.z.ZukoConflicted.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zuko, Exiled Prince", 163, Rarity.UNCOMMON, mage.cards.z.ZukoExiledPrince.class)); - - cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } } diff --git a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java index e5f25cf5dd7..51a5ad2f8f8 100644 --- a/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java +++ b/Mage.Sets/src/mage/sets/AvatarTheLastAirbenderEternal.java @@ -4,16 +4,11 @@ import mage.cards.ExpansionSet; import mage.constants.Rarity; import mage.constants.SetType; -import java.util.Arrays; -import java.util.List; - /** * @author TheElk801 */ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { - private static final List unfinished = Arrays.asList("Katara, Seeking Revenge", "Ruthless Waterbender", "Waterbender's Restoration", "Water Whip"); - private static final AvatarTheLastAirbenderEternal instance = new AvatarTheLastAirbenderEternal(); public static AvatarTheLastAirbenderEternal getInstance() { @@ -44,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)); @@ -342,7 +333,5 @@ public final class AvatarTheLastAirbenderEternal extends ExpansionSet { cards.add(new SetCardInfo("Zuko, Firebending Master", 127, Rarity.MYTHIC, mage.cards.z.ZukoFirebendingMaster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zuko, Firebending Master", 200, Rarity.MYTHIC, mage.cards.z.ZukoFirebendingMaster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zuko, Seeking Honor", 150, Rarity.UNCOMMON, mage.cards.z.ZukoSeekingHonor.class)); - - cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); } } diff --git a/Mage.Sets/src/mage/sets/CommanderCollectionBlack.java b/Mage.Sets/src/mage/sets/CommanderCollectionBlack.java index f54c7d6122e..9162e1962f1 100644 --- a/Mage.Sets/src/mage/sets/CommanderCollectionBlack.java +++ b/Mage.Sets/src/mage/sets/CommanderCollectionBlack.java @@ -22,7 +22,6 @@ public final class CommanderCollectionBlack extends ExpansionSet { cards.add(new SetCardInfo("Command Tower", 8, Rarity.RARE, mage.cards.c.CommandTower.class)); cards.add(new SetCardInfo("Ghoulcaller Gisa", 2, Rarity.MYTHIC, mage.cards.g.GhoulcallerGisa.class)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 1, Rarity.MYTHIC, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Liliana, Heretical Healer", 1, Rarity.MYTHIC, mage.cards.l.LilianaHereticalHealer.class)); cards.add(new SetCardInfo("Ophiomancer", 3, Rarity.RARE, mage.cards.o.Ophiomancer.class)); cards.add(new SetCardInfo("Phyrexian Arena", 4, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); diff --git a/Mage.Sets/src/mage/sets/CoreSet2019.java b/Mage.Sets/src/mage/sets/CoreSet2019.java index 09d37b5b5f0..5a814ec341e 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2019.java +++ b/Mage.Sets/src/mage/sets/CoreSet2019.java @@ -220,7 +220,6 @@ public final class CoreSet2019 extends ExpansionSet { cards.add(new SetCardInfo("Mystic Archaeologist", 63, Rarity.RARE, mage.cards.m.MysticArchaeologist.class)); cards.add(new SetCardInfo("Naturalize", 190, Rarity.COMMON, mage.cards.n.Naturalize.class)); cards.add(new SetCardInfo("Nexus of Fate", 306, Rarity.MYTHIC, mage.cards.n.NexusOfFate.class)); - cards.add(new SetCardInfo("Nicol Bolas, the Arisen", 218, Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.class)); cards.add(new SetCardInfo("Nicol Bolas, the Ravager", 218, Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class)); cards.add(new SetCardInfo("Nightmare's Thirst", 111, Rarity.UNCOMMON, mage.cards.n.NightmaresThirst.class)); cards.add(new SetCardInfo("Novice Knight", 30, Rarity.UNCOMMON, mage.cards.n.NoviceKnight.class)); diff --git a/Mage.Sets/src/mage/sets/CoreSet2019Promos.java b/Mage.Sets/src/mage/sets/CoreSet2019Promos.java index 9ebf7e2f241..490e6681905 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2019Promos.java +++ b/Mage.Sets/src/mage/sets/CoreSet2019Promos.java @@ -77,7 +77,6 @@ public class CoreSet2019Promos extends ExpansionSet { cards.add(new SetCardInfo("Mistcaller", "62s", Rarity.RARE, mage.cards.m.Mistcaller.class)); cards.add(new SetCardInfo("Murder", 110, Rarity.UNCOMMON, mage.cards.m.Murder.class)); cards.add(new SetCardInfo("Mystic Archaeologist", "63s", Rarity.RARE, mage.cards.m.MysticArchaeologist.class)); - cards.add(new SetCardInfo("Nicol Bolas, the Arisen", "218s", Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.class)); cards.add(new SetCardInfo("Nicol Bolas, the Ravager", "218s", Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class)); cards.add(new SetCardInfo("Omniscience", "65s", Rarity.MYTHIC, mage.cards.o.Omniscience.class)); cards.add(new SetCardInfo("One with the Machine", "66s", Rarity.RARE, mage.cards.o.OneWithTheMachine.class)); diff --git a/Mage.Sets/src/mage/sets/DarkAscension.java b/Mage.Sets/src/mage/sets/DarkAscension.java index 0514b53479c..9273ed0220e 100644 --- a/Mage.Sets/src/mage/sets/DarkAscension.java +++ b/Mage.Sets/src/mage/sets/DarkAscension.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.Card; @@ -43,7 +42,6 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Alpha Brawl", 82, Rarity.RARE, mage.cards.a.AlphaBrawl.class)); cards.add(new SetCardInfo("Altar of the Lost", 144, Rarity.UNCOMMON, mage.cards.a.AltarOfTheLost.class)); cards.add(new SetCardInfo("Archangel's Light", 1, Rarity.MYTHIC, mage.cards.a.ArchangelsLight.class)); - cards.add(new SetCardInfo("Archdemon of Greed", 71, Rarity.RARE, mage.cards.a.ArchdemonOfGreed.class)); cards.add(new SetCardInfo("Artful Dodge", 27, Rarity.COMMON, mage.cards.a.ArtfulDodge.class)); cards.add(new SetCardInfo("Avacyn's Collar", 145, Rarity.UNCOMMON, mage.cards.a.AvacynsCollar.class)); cards.add(new SetCardInfo("Bar the Door", 2, Rarity.COMMON, mage.cards.b.BarTheDoor.class)); @@ -98,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)); @@ -119,7 +116,6 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Helvault", 151, Rarity.MYTHIC, mage.cards.h.Helvault.class)); cards.add(new SetCardInfo("Highborn Ghoul", 68, Rarity.COMMON, mage.cards.h.HighbornGhoul.class)); cards.add(new SetCardInfo("Hinterland Hermit", 94, Rarity.COMMON, mage.cards.h.HinterlandHermit.class)); - cards.add(new SetCardInfo("Hinterland Scourge", 94, Rarity.COMMON, mage.cards.h.HinterlandScourge.class)); cards.add(new SetCardInfo("Hollowhenge Beast", 118, Rarity.COMMON, mage.cards.h.HollowhengeBeast.class)); cards.add(new SetCardInfo("Hollowhenge Spirit", 10, Rarity.UNCOMMON, mage.cards.h.HollowhengeSpirit.class)); cards.add(new SetCardInfo("Hunger of the Howlpack", 119, Rarity.COMMON, mage.cards.h.HungerOfTheHowlpack.class)); @@ -132,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)); @@ -142,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)); @@ -169,7 +163,6 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Shriekgeist", 49, Rarity.COMMON, mage.cards.s.Shriekgeist.class)); cards.add(new SetCardInfo("Sightless Ghoul", 73, Rarity.COMMON, mage.cards.s.SightlessGhoul.class)); cards.add(new SetCardInfo("Silverclaw Griffin", 21, Rarity.COMMON, mage.cards.s.SilverclawGriffin.class)); - cards.add(new SetCardInfo("Silverpelt Werewolf", 122, Rarity.UNCOMMON, mage.cards.s.SilverpeltWerewolf.class)); cards.add(new SetCardInfo("Skillful Lunge", 22, Rarity.COMMON, mage.cards.s.SkillfulLunge.class)); cards.add(new SetCardInfo("Skirsdag Flayer", 74, Rarity.UNCOMMON, mage.cards.s.SkirsdagFlayer.class)); cards.add(new SetCardInfo("Somberwald Dryad", 126, Rarity.COMMON, mage.cards.s.SomberwaldDryad.class)); @@ -186,13 +179,11 @@ public final class DarkAscension extends ExpansionSet { cards.add(new SetCardInfo("Thraben Doomsayer", 25, Rarity.RARE, mage.cards.t.ThrabenDoomsayer.class)); cards.add(new SetCardInfo("Thraben Heretic", 26, Rarity.UNCOMMON, mage.cards.t.ThrabenHeretic.class)); cards.add(new SetCardInfo("Torch Fiend", 106, Rarity.COMMON, mage.cards.t.TorchFiend.class)); - cards.add(new SetCardInfo("Tovolar's Magehunter", 98, Rarity.RARE, mage.cards.t.TovolarsMagehunter.class)); cards.add(new SetCardInfo("Tower Geist", 53, Rarity.UNCOMMON, mage.cards.t.TowerGeist.class)); cards.add(new SetCardInfo("Tracker's Instincts", 128, Rarity.UNCOMMON, mage.cards.t.TrackersInstincts.class)); cards.add(new SetCardInfo("Tragic Slip", 76, Rarity.COMMON, mage.cards.t.TragicSlip.class)); cards.add(new SetCardInfo("Ulvenwald Bear", 129, Rarity.COMMON, mage.cards.u.UlvenwaldBear.class)); cards.add(new SetCardInfo("Undying Evil", 77, Rarity.COMMON, mage.cards.u.UndyingEvil.class)); - cards.add(new SetCardInfo("Unhallowed Cathar", 13, Rarity.COMMON, mage.cards.u.UnhallowedCathar.class)); cards.add(new SetCardInfo("Vault of the Archangel", 158, Rarity.RARE, mage.cards.v.VaultOfTheArchangel.class)); cards.add(new SetCardInfo("Vengeful Vampire", 78, Rarity.UNCOMMON, mage.cards.v.VengefulVampire.class)); cards.add(new SetCardInfo("Village Survivors", 130, Rarity.UNCOMMON, mage.cards.v.VillageSurvivors.class)); @@ -245,8 +236,8 @@ class DarkAscensionCollator implements BoosterCollator { private final CardRun land = new CardRun(false, "ISD_250", "ISD_251", "ISD_252", "ISD_253", "ISD_254", "ISD_255", "ISD_256", "ISD_257", "ISD_258", "ISD_259", "ISD_260", "ISD_261", "ISD_262", "ISD_263", "ISD_264"); private final BoosterStructure AAAAABBBB = new BoosterStructure( - commonA, commonA, commonA, commonA, commonA, - commonB, commonB, commonB, commonB + commonA, commonA, commonA, commonA, commonA, + commonB, commonB, commonB, commonB ); private final BoosterStructure AAB = new BoosterStructure(uncommonA, uncommonA, uncommonB); private final BoosterStructure ABB = new BoosterStructure(uncommonA, uncommonB, uncommonB); diff --git a/Mage.Sets/src/mage/sets/DarkAscensionPromos.java b/Mage.Sets/src/mage/sets/DarkAscensionPromos.java index 4de0aa57778..9901edd99bd 100644 --- a/Mage.Sets/src/mage/sets/DarkAscensionPromos.java +++ b/Mage.Sets/src/mage/sets/DarkAscensionPromos.java @@ -20,12 +20,10 @@ public class DarkAscensionPromos extends ExpansionSet { this.hasBoosters = false; this.hasBasicLands = false; - cards.add(new SetCardInfo("Archdemon of Greed", "71*", Rarity.RARE, mage.cards.a.ArchdemonOfGreed.class)); cards.add(new SetCardInfo("Gravecrawler", "64*", Rarity.RARE, mage.cards.g.Gravecrawler.class)); cards.add(new SetCardInfo("Mondronen Shaman", "98*", Rarity.RARE, mage.cards.m.MondronenShaman.class)); cards.add(new SetCardInfo("Ravenous Demon", "71*", Rarity.RARE, mage.cards.r.RavenousDemon.class)); cards.add(new SetCardInfo("Strangleroot Geist", 127, Rarity.UNCOMMON, mage.cards.s.StranglerootGeist.class)); - cards.add(new SetCardInfo("Tovolar's Magehunter", "98*", Rarity.RARE, mage.cards.t.TovolarsMagehunter.class)); cards.add(new SetCardInfo("Zombie Apocalypse", 80, Rarity.RARE, mage.cards.z.ZombieApocalypse.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..1dad64f44fb 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,16 @@ 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("Cramped Vents // Access Maze", 17, Rarity.RARE, mage.cards.c.CrampedVentsAccessMaze.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 +92,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 +115,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 +163,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 +177,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 +216,11 @@ 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("Polluted Cistern // Dim Oubliette", 23, Rarity.RARE, mage.cards.p.PollutedCisternDimOubliette.class)); 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 +237,28 @@ 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("Secret Arcade // Dusty Parlor", 10, Rarity.RARE, mage.cards.s.SecretArcadeDustyParlor.class)); 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 +266,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 +309,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 2e178da8f64..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)); @@ -133,7 +128,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Graf Rats", 91, Rarity.COMMON, mage.cards.g.GrafRats.class)); cards.add(new SetCardInfo("Grapple with the Past", 160, Rarity.COMMON, mage.cards.g.GrappleWithThePast.class)); cards.add(new SetCardInfo("Grim Flayer", 184, Rarity.MYTHIC, mage.cards.g.GrimFlayer.class)); - cards.add(new SetCardInfo("Grisly Anglerfish", 63, Rarity.UNCOMMON, mage.cards.g.GrislyAnglerfish.class)); cards.add(new SetCardInfo("Grizzled Angler", 63, Rarity.UNCOMMON, mage.cards.g.GrizzledAngler.class)); cards.add(new SetCardInfo("Guardian of Pilgrims", 30, Rarity.COMMON, mage.cards.g.GuardianOfPilgrims.class)); cards.add(new SetCardInfo("Hamlet Captain", 161, Rarity.UNCOMMON, mage.cards.h.HamletCaptain.class)); @@ -143,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)); @@ -154,7 +147,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Ironwright's Cleansing", 32, Rarity.COMMON, mage.cards.i.IronwrightsCleansing.class)); cards.add(new SetCardInfo("Ishkanah, Grafwidow", 162, Rarity.MYTHIC, mage.cards.i.IshkanahGrafwidow.class)); cards.add(new SetCardInfo("It of the Horrid Swarm", 8, Rarity.COMMON, mage.cards.i.ItOfTheHorridSwarm.class)); - cards.add(new SetCardInfo("It That Rides as One", 33, Rarity.UNCOMMON, mage.cards.i.ItThatRidesAsOne.class)); cards.add(new SetCardInfo("Kessig Prowler", 163, Rarity.UNCOMMON, mage.cards.k.KessigProwler.class)); cards.add(new SetCardInfo("Laboratory Brute", 67, Rarity.COMMON, mage.cards.l.LaboratoryBrute.class)); cards.add(new SetCardInfo("Lashweed Lurker", 9, Rarity.UNCOMMON, mage.cards.l.LashweedLurker.class)); @@ -203,7 +195,6 @@ public final class EldritchMoon extends ExpansionSet { cards.add(new SetCardInfo("Shrill Howler", 168, Rarity.UNCOMMON, mage.cards.s.ShrillHowler.class)); cards.add(new SetCardInfo("Sigarda's Aid", 41, Rarity.RARE, mage.cards.s.SigardasAid.class)); cards.add(new SetCardInfo("Sigardian Priest", 42, Rarity.COMMON, mage.cards.s.SigardianPriest.class)); - cards.add(new SetCardInfo("Sinuous Predator", 163, Rarity.UNCOMMON, mage.cards.s.SinuousPredator.class)); cards.add(new SetCardInfo("Skirsdag Supplicant", 104, Rarity.COMMON, mage.cards.s.SkirsdagSupplicant.class)); cards.add(new SetCardInfo("Slayer's Cleaver", 198, Rarity.UNCOMMON, mage.cards.s.SlayersCleaver.class)); cards.add(new SetCardInfo("Smoldering Werewolf", 142, Rarity.UNCOMMON, mage.cards.s.SmolderingWerewolf.class)); @@ -241,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 43a1d38d199..08f1ff1161e 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasy.java +++ b/Mage.Sets/src/mage/sets/FinalFantasy.java @@ -74,16 +74,12 @@ 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)); cards.add(new SetCardInfo("Blazing Bomb", 130, Rarity.COMMON, mage.cards.b.BlazingBomb.class)); cards.add(new SetCardInfo("Blitzball Shot", 176, Rarity.COMMON, mage.cards.b.BlitzballShot.class)); cards.add(new SetCardInfo("Blitzball", 254, Rarity.COMMON, mage.cards.b.Blitzball.class)); - cards.add(new SetCardInfo("Braska's Final Aeon", 104, Rarity.RARE, mage.cards.b.BraskasFinalAeon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Braska's Final Aeon", 363, Rarity.RARE, mage.cards.b.BraskasFinalAeon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Braska's Final Aeon", 448, Rarity.RARE, mage.cards.b.BraskasFinalAeon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Buster Sword", 255, Rarity.MYTHIC, mage.cards.b.BusterSword.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Buster Sword", 351, Rarity.MYTHIC, mage.cards.b.BusterSword.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cactuar", 177, Rarity.UNCOMMON, mage.cards.c.Cactuar.class)); @@ -94,8 +90,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Cecil, Dark Knight", 445, Rarity.RARE, mage.cards.c.CecilDarkKnight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cecil, Dark Knight", 525, Rarity.RARE, mage.cards.c.CecilDarkKnight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cecil, Dark Knight", 91, Rarity.RARE, mage.cards.c.CecilDarkKnight.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Chaos, the Endless", 221, Rarity.UNCOMMON, mage.cards.c.ChaosTheEndless.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Chaos, the Endless", 486, Rarity.UNCOMMON, mage.cards.c.ChaosTheEndless.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Choco, Seeker of Paradise", 215, Rarity.RARE, mage.cards.c.ChocoSeekerOfParadise.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Choco, Seeker of Paradise", 479, Rarity.RARE, mage.cards.c.ChocoSeekerOfParadise.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Choco, Seeker of Paradise", 569, Rarity.RARE, mage.cards.c.ChocoSeekerOfParadise.class, NON_FULL_USE_VARIOUS)); @@ -142,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)); @@ -178,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)); @@ -210,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)); @@ -249,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)); @@ -296,11 +277,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Kefka, Court Mage", 398, Rarity.MYTHIC, mage.cards.k.KefkaCourtMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kefka, Court Mage", 496, Rarity.MYTHIC, mage.cards.k.KefkaCourtMage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kefka, Court Mage", 543, Rarity.MYTHIC, mage.cards.k.KefkaCourtMage.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kefka, Ruler of Ruin", 231, Rarity.MYTHIC, mage.cards.k.KefkaRulerOfRuin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kefka, Ruler of Ruin", 322, Rarity.MYTHIC, mage.cards.k.KefkaRulerOfRuin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kefka, Ruler of Ruin", 398, Rarity.MYTHIC, mage.cards.k.KefkaRulerOfRuin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kefka, Ruler of Ruin", 496, Rarity.MYTHIC, mage.cards.k.KefkaRulerOfRuin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kefka, Ruler of Ruin", 543, Rarity.MYTHIC, mage.cards.k.KefkaRulerOfRuin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kuja, Genome Sorcerer", 232, Rarity.RARE, mage.cards.k.KujaGenomeSorcerer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kuja, Genome Sorcerer", 399, Rarity.RARE, mage.cards.k.KujaGenomeSorcerer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kuja, Genome Sorcerer", 497, Rarity.RARE, mage.cards.k.KujaGenomeSorcerer.class, NON_FULL_USE_VARIOUS)); @@ -326,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)); @@ -364,10 +339,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Phantom Train", 110, Rarity.UNCOMMON, mage.cards.p.PhantomTrain.class)); cards.add(new SetCardInfo("Phoenix Down", 29, Rarity.UNCOMMON, mage.cards.p.PhoenixDown.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phoenix Down", 578, Rarity.UNCOMMON, mage.cards.p.PhoenixDown.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Phoenix, Warden of Fire", 229, Rarity.RARE, mage.cards.p.PhoenixWardenOfFire.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Phoenix, Warden of Fire", 397, Rarity.RARE, mage.cards.p.PhoenixWardenOfFire.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Phoenix, Warden of Fire", 494, Rarity.RARE, mage.cards.p.PhoenixWardenOfFire.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Phoenix, Warden of Fire", 542, Rarity.RARE, mage.cards.p.PhoenixWardenOfFire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 294, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", 295, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", 296, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); @@ -439,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)); @@ -455,14 +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("Shiva, Warden of Ice", 378, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shiva, Warden of Ice", 438, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shiva, Warden of Ice", 523, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shiva, Warden of Ice", 58, Rarity.RARE, mage.cards.s.ShivaWardenOfIce.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)); @@ -544,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)); @@ -574,10 +530,6 @@ public final class FinalFantasy extends ExpansionSet { cards.add(new SetCardInfo("Torgal, A Fine Hound", 345, Rarity.UNCOMMON, mage.cards.t.TorgalAFineHound.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Torgal, A Fine Hound", 474, Rarity.UNCOMMON, mage.cards.t.TorgalAFineHound.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Town Greeter", 209, Rarity.COMMON, mage.cards.t.TownGreeter.class)); - cards.add(new SetCardInfo("Trance Kuja, Fate Defied", 232, Rarity.RARE, mage.cards.t.TranceKujaFateDefied.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Trance Kuja, Fate Defied", 399, Rarity.RARE, mage.cards.t.TranceKujaFateDefied.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Trance Kuja, Fate Defied", 497, Rarity.RARE, mage.cards.t.TranceKujaFateDefied.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Trance Kuja, Fate Defied", 544, Rarity.RARE, mage.cards.t.TranceKujaFateDefied.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Travel the Overworld", 82, Rarity.UNCOMMON, mage.cards.t.TravelTheOverworld.class)); cards.add(new SetCardInfo("Traveling Chocobo", "551a", Rarity.MYTHIC, mage.cards.t.TravelingChocobo.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Traveling Chocobo", "551b", Rarity.MYTHIC, mage.cards.t.TravelingChocobo.class, NON_FULL_USE_VARIOUS)); @@ -597,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)); @@ -637,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..f5f147f867f 100644 --- a/Mage.Sets/src/mage/sets/FinalFantasyCommander.java +++ b/Mage.Sets/src/mage/sets/FinalFantasyCommander.java @@ -86,8 +86,10 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Champion's Helm", 337, Rarity.RARE, mage.cards.c.ChampionsHelm.class)); cards.add(new SetCardInfo("Champions from Beyond", 101, Rarity.RARE, mage.cards.c.ChampionsFromBeyond.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Champions from Beyond", 11, Rarity.RARE, mage.cards.c.ChampionsFromBeyond.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Chaos Shrine's Black Crystal", 445, Rarity.RARE, mage.cards.c.ChaosShrinesBlackCrystal.class)); 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)); @@ -140,6 +142,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Drowned Catacomb", 388, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); cards.add(new SetCardInfo("Duelist's Flame", 452, Rarity.RARE, mage.cards.d.DuelistsFlame.class)); cards.add(new SetCardInfo("Duskshell Crawler", 301, Rarity.COMMON, mage.cards.d.DuskshellCrawler.class)); + cards.add(new SetCardInfo("Edea, Possessed Sorceress", 448, Rarity.RARE, mage.cards.e.EdeaPossessedSorceress.class)); cards.add(new SetCardInfo("Edgar, Master Machinist", 169, Rarity.RARE, mage.cards.e.EdgarMasterMachinist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Edgar, Master Machinist", 80, Rarity.RARE, mage.cards.e.EdgarMasterMachinist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Elena, Turk Recruit", 133, Rarity.RARE, mage.cards.e.ElenaTurkRecruit.class, NON_FULL_USE_VARIOUS)); @@ -187,6 +190,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)); @@ -230,6 +234,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Into the Story", 266, Rarity.UNCOMMON, mage.cards.i.IntoTheStory.class)); cards.add(new SetCardInfo("Island", 479, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Isolated Chapel", 405, Rarity.RARE, mage.cards.i.IsolatedChapel.class)); + cards.add(new SetCardInfo("Judgment of Alexander", 455, Rarity.RARE, mage.cards.j.JudgmentOfAlexander.class)); cards.add(new SetCardInfo("Jungle Shrine", 406, Rarity.UNCOMMON, mage.cards.j.JungleShrine.class)); cards.add(new SetCardInfo("Kefka, Dancing Mad", 174, Rarity.RARE, mage.cards.k.KefkaDancingMad.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kefka, Dancing Mad", 84, Rarity.RARE, mage.cards.k.KefkaDancingMad.class, NON_FULL_USE_VARIOUS)); @@ -273,6 +278,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)); @@ -314,6 +320,7 @@ public final class FinalFantasyCommander extends ExpansionSet { cards.add(new SetCardInfo("Rikku, Resourceful Guardian", 145, Rarity.RARE, mage.cards.r.RikkuResourcefulGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rikku, Resourceful Guardian", 41, Rarity.RARE, mage.cards.r.RikkuResourcefulGuardian.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rikku, Resourceful Guardian", 468, Rarity.RARE, mage.cards.r.RikkuResourcefulGuardian.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rinoa, Angel Wing", 450, Rarity.RARE, mage.cards.r.RinoaAngelWing.class)); cards.add(new SetCardInfo("Rise of the Dark Realms", 283, Rarity.MYTHIC, mage.cards.r.RiseOfTheDarkRealms.class)); cards.add(new SetCardInfo("Rite of Replication", 270, Rarity.RARE, mage.cards.r.RiteOfReplication.class)); cards.add(new SetCardInfo("Rogue's Passage", 415, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); @@ -366,6 +373,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/FromTheVaultTransform.java b/Mage.Sets/src/mage/sets/FromTheVaultTransform.java index 68ef3e439ca..58d91a5f682 100644 --- a/Mage.Sets/src/mage/sets/FromTheVaultTransform.java +++ b/Mage.Sets/src/mage/sets/FromTheVaultTransform.java @@ -1,4 +1,3 @@ - package mage.sets; import mage.cards.ExpansionSet; @@ -30,16 +29,11 @@ public final class FromTheVaultTransform extends ExpansionSet { cards.add(new SetCardInfo("Delver of Secrets", 7, Rarity.MYTHIC, mage.cards.d.DelverOfSecrets.class)); cards.add(new SetCardInfo("Elbrus, the Binding Blade", 8, Rarity.MYTHIC, mage.cards.e.ElbrusTheBindingBlade.class)); cards.add(new SetCardInfo("Garruk Relentless", 9, Rarity.MYTHIC, mage.cards.g.GarrukRelentless.class)); - cards.add(new SetCardInfo("Garruk, the Veil-Cursed", 9, Rarity.MYTHIC, mage.cards.g.GarrukTheVeilCursed.class)); cards.add(new SetCardInfo("Gisela, the Broken Blade", 10, Rarity.MYTHIC, mage.cards.g.GiselaTheBrokenBlade.class)); cards.add(new SetCardInfo("Huntmaster of the Fells", 11, Rarity.MYTHIC, mage.cards.h.HuntmasterOfTheFells.class)); cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 12, Rarity.MYTHIC, mage.cards.j.JaceVrynsProdigy.class)); - cards.add(new SetCardInfo("Jace, Telepath Unbound", 12, Rarity.MYTHIC, mage.cards.j.JaceTelepathUnbound.class)); cards.add(new SetCardInfo("Kytheon, Hero of Akros", 13, Rarity.MYTHIC, mage.cards.k.KytheonHeroOfAkros.class)); - cards.add(new SetCardInfo("Gideon, Battle-Forged", 13, Rarity.MYTHIC, mage.cards.g.GideonBattleForged.class)); cards.add(new SetCardInfo("Liliana, Heretical Healer", 14, Rarity.MYTHIC, mage.cards.l.LilianaHereticalHealer.class)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 14, Rarity.MYTHIC, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Nissa, Vastwood Seer", 15, Rarity.MYTHIC, mage.cards.n.NissaVastwoodSeer.class)); - cards.add(new SetCardInfo("Nissa, Sage Animist", 15, Rarity.MYTHIC, mage.cards.n.NissaSageAnimist.class)); } } diff --git a/Mage.Sets/src/mage/sets/HasCon2017.java b/Mage.Sets/src/mage/sets/HasCon2017.java index a8ef14cac47..f1341c2f45d 100644 --- a/Mage.Sets/src/mage/sets/HasCon2017.java +++ b/Mage.Sets/src/mage/sets/HasCon2017.java @@ -21,7 +21,6 @@ public final class HasCon2017 extends ExpansionSet { this.hasBasicLands = false; cards.add(new ExpansionSet.SetCardInfo("Grimlock, Dinobot Leader", 1, Rarity.MYTHIC, mage.cards.g.GrimlockDinobotLeader.class)); - cards.add(new ExpansionSet.SetCardInfo("Grimlock, Ferocious King", 1, Rarity.MYTHIC, mage.cards.g.GrimlockFerociousKing.class)); cards.add(new ExpansionSet.SetCardInfo("Sword of Dungeons & Dragons", 3, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class)); } } diff --git a/Mage.Sets/src/mage/sets/Innistrad.java b/Mage.Sets/src/mage/sets/Innistrad.java index a37d00cdd8c..13615469bf5 100644 --- a/Mage.Sets/src/mage/sets/Innistrad.java +++ b/Mage.Sets/src/mage/sets/Innistrad.java @@ -48,7 +48,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Avacynian Priest", 4, Rarity.COMMON, mage.cards.a.AvacynianPriest.class)); cards.add(new SetCardInfo("Back from the Brink", 44, Rarity.RARE, mage.cards.b.BackFromTheBrink.class)); cards.add(new SetCardInfo("Balefire Dragon", 129, Rarity.MYTHIC, mage.cards.b.BalefireDragon.class)); - cards.add(new SetCardInfo("Bane of Hanweir", 145, Rarity.UNCOMMON, mage.cards.b.BaneOfHanweir.class)); cards.add(new SetCardInfo("Battleground Geist", 45, Rarity.UNCOMMON, mage.cards.b.BattlegroundGeist.class)); cards.add(new SetCardInfo("Bitterheart Witch", 88, Rarity.UNCOMMON, mage.cards.b.BitterheartWitch.class)); cards.add(new SetCardInfo("Blasphemous Act", 130, Rarity.RARE, mage.cards.b.BlasphemousAct.class)); @@ -124,8 +123,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Gallows Warden", 16, Rarity.UNCOMMON, mage.cards.g.GallowsWarden.class)); cards.add(new SetCardInfo("Galvanic Juggernaut", 222, Rarity.UNCOMMON, mage.cards.g.GalvanicJuggernaut.class)); cards.add(new SetCardInfo("Garruk Relentless", 181, Rarity.MYTHIC, mage.cards.g.GarrukRelentless.class)); - cards.add(new SetCardInfo("Garruk, the Veil-Cursed", 181, Rarity.MYTHIC, mage.cards.g.GarrukTheVeilCursed.class)); - cards.add(new SetCardInfo("Gatstaf Howler", 182, Rarity.UNCOMMON, mage.cards.g.GatstafHowler.class)); cards.add(new SetCardInfo("Gatstaf Shepherd", 182, Rarity.UNCOMMON, mage.cards.g.GatstafShepherd.class)); cards.add(new SetCardInfo("Gavony Township", 239, Rarity.RARE, mage.cards.g.GavonyTownship.class)); cards.add(new SetCardInfo("Geist of Saint Traft", 213, Rarity.MYTHIC, mage.cards.g.GeistOfSaintTraft.class)); @@ -153,8 +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 Alpha", 193, Rarity.RARE, mage.cards.h.HowlpackAlpha.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)); @@ -162,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)); @@ -171,13 +165,11 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Kessig Wolf Run", 243, Rarity.RARE, mage.cards.k.KessigWolfRun.class)); cards.add(new SetCardInfo("Kessig Wolf", 151, Rarity.COMMON, mage.cards.k.KessigWolf.class)); cards.add(new SetCardInfo("Kindercatch", 190, Rarity.COMMON, mage.cards.k.Kindercatch.class)); - cards.add(new SetCardInfo("Krallenhorde Wantons", 185, Rarity.COMMON, mage.cards.k.KrallenhordeWantons.class)); cards.add(new SetCardInfo("Kruin Outlaw", 152, Rarity.RARE, mage.cards.k.KruinOutlaw.class)); cards.add(new SetCardInfo("Laboratory Maniac", 61, Rarity.RARE, mage.cards.l.LaboratoryManiac.class)); cards.add(new SetCardInfo("Lantern Spirit", 62, Rarity.UNCOMMON, mage.cards.l.LanternSpirit.class)); cards.add(new SetCardInfo("Liliana of the Veil", 105, Rarity.MYTHIC, mage.cards.l.LilianaOfTheVeil.class)); cards.add(new SetCardInfo("Lost in the Mist", 63, Rarity.COMMON, mage.cards.l.LostInTheMist.class)); - cards.add(new SetCardInfo("Ludevic's Abomination", 64, Rarity.RARE, mage.cards.l.LudevicsAbomination.class)); cards.add(new SetCardInfo("Ludevic's Test Subject", 64, Rarity.RARE, mage.cards.l.LudevicsTestSubject.class)); cards.add(new SetCardInfo("Lumberknot", 191, Rarity.UNCOMMON, mage.cards.l.Lumberknot.class)); cards.add(new SetCardInfo("Make a Wish", 192, Rarity.UNCOMMON, mage.cards.m.MakeAWish.class)); @@ -191,7 +183,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Mayor of Avabruck", 193, Rarity.RARE, mage.cards.m.MayorOfAvabruck.class)); cards.add(new SetCardInfo("Memory's Journey", 66, Rarity.UNCOMMON, mage.cards.m.MemorysJourney.class)); cards.add(new SetCardInfo("Mentor of the Meek", 21, Rarity.RARE, mage.cards.m.MentorOfTheMeek.class)); - cards.add(new SetCardInfo("Merciless Predator", 159, Rarity.UNCOMMON, mage.cards.m.MercilessPredator.class)); cards.add(new SetCardInfo("Midnight Haunting", 22, Rarity.UNCOMMON, mage.cards.m.MidnightHaunting.class)); cards.add(new SetCardInfo("Mikaeus, the Lunarch", 23, Rarity.MYTHIC, mage.cards.m.MikaeusTheLunarch.class)); cards.add(new SetCardInfo("Mindshrieker", 67, Rarity.RARE, mage.cards.m.Mindshrieker.class)); @@ -229,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)); @@ -266,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)); @@ -278,9 +267,7 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 256, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); 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("Terror of Kruin Pass", 152, Rarity.RARE, mage.cards.t.TerrorOfKruinPass.class)); 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)); @@ -292,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)); @@ -307,7 +293,6 @@ public final class Innistrad extends ExpansionSet { cards.add(new SetCardInfo("Villagers of Estwald", 209, Rarity.COMMON, mage.cards.v.VillagersOfEstwald.class)); cards.add(new SetCardInfo("Voiceless Spirit", 42, Rarity.COMMON, mage.cards.v.VoicelessSpirit.class)); cards.add(new SetCardInfo("Walking Corpse", 126, Rarity.COMMON, mage.cards.w.WalkingCorpse.class)); - cards.add(new SetCardInfo("Wildblood Pack", 149, Rarity.RARE, mage.cards.w.WildbloodPack.class)); cards.add(new SetCardInfo("Witchbane Orb", 236, Rarity.RARE, mage.cards.w.WitchbaneOrb.class)); cards.add(new SetCardInfo("Wooden Stake", 237, Rarity.COMMON, mage.cards.w.WoodenStake.class)); cards.add(new SetCardInfo("Woodland Cemetery", 249, Rarity.RARE, mage.cards.w.WoodlandCemetery.class)); diff --git a/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java b/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java index aa578902369..4cf85b4fdca 100644 --- a/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java +++ b/Mage.Sets/src/mage/sets/InnistradCrimsonVow.java @@ -46,7 +46,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Alchemist's Retrieval", 47, Rarity.COMMON, mage.cards.a.AlchemistsRetrieval.class)); cards.add(new SetCardInfo("Alluring Suitor", 141, Rarity.UNCOMMON, mage.cards.a.AlluringSuitor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Alluring Suitor", 300, Rarity.UNCOMMON, mage.cards.a.AlluringSuitor.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ancestor's Embrace", 22, Rarity.COMMON, mage.cards.a.AncestorsEmbrace.class)); cards.add(new SetCardInfo("Ancestral Anger", 142, Rarity.COMMON, mage.cards.a.AncestralAnger.class)); cards.add(new SetCardInfo("Ancient Lumberknot", 230, Rarity.UNCOMMON, mage.cards.a.AncientLumberknot.class)); cards.add(new SetCardInfo("Angelic Quartermaster", 2, Rarity.UNCOMMON, mage.cards.a.AngelicQuartermaster.class)); @@ -71,13 +70,8 @@ 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("Bloodsoaked Reveler", 128, Rarity.UNCOMMON, mage.cards.b.BloodsoakedReveler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Bloodsoaked Reveler", 295, Rarity.UNCOMMON, mage.cards.b.BloodsoakedReveler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodsworn Squire", 289, Rarity.UNCOMMON, mage.cards.b.BloodswornSquire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodsworn Squire", 97, Rarity.UNCOMMON, mage.cards.b.BloodswornSquire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodtithe Harvester", 232, Rarity.UNCOMMON, mage.cards.b.BloodtitheHarvester.class, NON_FULL_USE_VARIOUS)); @@ -85,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)); @@ -93,10 +86,8 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Brine Comber", 233, Rarity.UNCOMMON, mage.cards.b.BrineComber.class)); cards.add(new SetCardInfo("By Invitation Only", 346, Rarity.RARE, mage.cards.b.ByInvitationOnly.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("By Invitation Only", 5, Rarity.RARE, mage.cards.b.ByInvitationOnly.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Cackling Culprit", 28, Rarity.UNCOMMON, mage.cards.c.CacklingCulprit.class)); cards.add(new SetCardInfo("Cartographer's Survey", 190, Rarity.UNCOMMON, mage.cards.c.CartographersSurvey.class)); cards.add(new SetCardInfo("Catapult Fodder", 99, Rarity.UNCOMMON, mage.cards.c.CatapultFodder.class)); - cards.add(new SetCardInfo("Catlike Curiosity", 69, Rarity.UNCOMMON, mage.cards.c.CatlikeCuriosity.class)); cards.add(new SetCardInfo("Cemetery Desecrator", 100, Rarity.MYTHIC, mage.cards.c.CemeteryDesecrator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cemetery Desecrator", 366, Rarity.MYTHIC, mage.cards.c.CemeteryDesecrator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Cemetery Gatekeeper", 148, Rarity.MYTHIC, mage.cards.c.CemeteryGatekeeper.class, NON_FULL_USE_VARIOUS)); @@ -114,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)); @@ -144,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)); @@ -188,7 +176,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Falkenrath Forebear", 334, Rarity.RARE, mage.cards.f.FalkenrathForebear.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fear of Death", 59, Rarity.COMMON, mage.cards.f.FearOfDeath.class)); cards.add(new SetCardInfo("Fearful Villager", 157, Rarity.COMMON, mage.cards.f.FearfulVillager.class)); - cards.add(new SetCardInfo("Fearsome Werewolf", 157, Rarity.COMMON, mage.cards.f.FearsomeWerewolf.class)); cards.add(new SetCardInfo("Fell Stinger", 112, Rarity.UNCOMMON, mage.cards.f.FellStinger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fell Stinger", 406, Rarity.UNCOMMON, mage.cards.f.FellStinger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fierce Retribution", 13, Rarity.COMMON, mage.cards.f.FierceRetribution.class)); @@ -206,8 +193,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Geistlight Snare", 60, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Geralf, Visionary Stitcher", 319, Rarity.RARE, mage.cards.g.GeralfVisionaryStitcher.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Geralf, Visionary Stitcher", 61, Rarity.RARE, mage.cards.g.GeralfVisionaryStitcher.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ghastly Mimicry", 361, Rarity.RARE, mage.cards.g.GhastlyMimicry.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ghastly Mimicry", 68, Rarity.RARE, mage.cards.g.GhastlyMimicry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gift of Fangs", 113, Rarity.COMMON, mage.cards.g.GiftOfFangs.class)); cards.add(new SetCardInfo("Glorious Sunrise", 200, Rarity.RARE, mage.cards.g.GloriousSunrise.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Glorious Sunrise", 388, Rarity.RARE, mage.cards.g.GloriousSunrise.class, NON_FULL_USE_VARIOUS)); @@ -221,7 +206,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Groom's Finery", 117, Rarity.UNCOMMON, mage.cards.g.GroomsFinery.class)); cards.add(new SetCardInfo("Gryff Rider", 15, Rarity.COMMON, mage.cards.g.GryffRider.class)); cards.add(new SetCardInfo("Gryffwing Cavalry", 16, Rarity.UNCOMMON, mage.cards.g.GryffwingCavalry.class)); - cards.add(new SetCardInfo("Gutter Shortcut", 62, Rarity.UNCOMMON, mage.cards.g.GutterShortcut.class)); cards.add(new SetCardInfo("Gutter Skulker", 62, Rarity.UNCOMMON, mage.cards.g.GutterSkulker.class)); cards.add(new SetCardInfo("Halana and Alena, Partners", 239, Rarity.RARE, mage.cards.h.HalanaAndAlenaPartners.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Halana and Alena, Partners", 325, Rarity.RARE, mage.cards.h.HalanaAndAlenaPartners.class, NON_FULL_USE_VARIOUS)); @@ -229,17 +213,11 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Hallowed Haunting", 349, Rarity.MYTHIC, mage.cards.h.HallowedHaunting.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hamlet Vanguard", 201, Rarity.RARE, mage.cards.h.HamletVanguard.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hamlet Vanguard", 389, Rarity.RARE, mage.cards.h.HamletVanguard.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hauken's Insight", 320, Rarity.MYTHIC, mage.cards.h.HaukensInsight.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hauken's Insight", 332, Rarity.MYTHIC, mage.cards.h.HaukensInsight.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Hauken's Insight", 65, Rarity.MYTHIC, mage.cards.h.HaukensInsight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Headless Rider", 118, Rarity.RARE, mage.cards.h.HeadlessRider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Headless Rider", 372, Rarity.RARE, mage.cards.h.HeadlessRider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Henrika Domnathi", 119, Rarity.MYTHIC, mage.cards.h.HenrikaDomnathi.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Henrika Domnathi", 293, Rarity.MYTHIC, mage.cards.h.HenrikaDomnathi.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Henrika Domnathi", 335, Rarity.MYTHIC, mage.cards.h.HenrikaDomnathi.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Henrika, Infernal Seer", 119, Rarity.MYTHIC, mage.cards.h.HenrikaInfernalSeer.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Henrika, Infernal Seer", 293, Rarity.MYTHIC, mage.cards.h.HenrikaInfernalSeer.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Henrika, Infernal Seer", 335, Rarity.MYTHIC, mage.cards.h.HenrikaInfernalSeer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hero's Downfall", 120, Rarity.UNCOMMON, mage.cards.h.HerosDownfall.class)); cards.add(new SetCardInfo("Heron of Hope", 18, Rarity.COMMON, mage.cards.h.HeronOfHope.class)); cards.add(new SetCardInfo("Heron-Blessed Geist", 19, Rarity.COMMON, mage.cards.h.HeronBlessedGeist.class)); @@ -252,8 +230,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Hopeful Initiate", 350, Rarity.RARE, mage.cards.h.HopefulInitiate.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Howling Moon", 204, Rarity.RARE, mage.cards.h.HowlingMoon.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Howling Moon", 391, Rarity.RARE, mage.cards.h.HowlingMoon.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Howlpack Avenger", 162, Rarity.RARE, mage.cards.h.HowlpackAvenger.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Howlpack Avenger", 378, Rarity.RARE, mage.cards.h.HowlpackAvenger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Howlpack Piper", 205, Rarity.RARE, mage.cards.h.HowlpackPiper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Howlpack Piper", 392, Rarity.RARE, mage.cards.h.HowlpackPiper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hullbreaker Horror", 359, Rarity.RARE, mage.cards.h.HullbreakerHorror.class, NON_FULL_USE_VARIOUS)); @@ -262,7 +238,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Ill-Tempered Loner", 162, Rarity.RARE, mage.cards.i.IllTemperedLoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ill-Tempered Loner", 378, Rarity.RARE, mage.cards.i.IllTemperedLoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Infestation Expert", 206, Rarity.UNCOMMON, mage.cards.i.InfestationExpert.class)); - cards.add(new SetCardInfo("Infested Werewolf", 206, Rarity.UNCOMMON, mage.cards.i.InfestedWerewolf.class)); cards.add(new SetCardInfo("Innocent Traveler", 121, Rarity.UNCOMMON, mage.cards.i.InnocentTraveler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Innocent Traveler", 294, Rarity.UNCOMMON, mage.cards.i.InnocentTraveler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Innocent Traveler", 336, Rarity.UNCOMMON, mage.cards.i.InnocentTraveler.class, NON_FULL_USE_VARIOUS)); @@ -279,8 +254,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Jacob Hauken, Inspector", 320, Rarity.MYTHIC, mage.cards.j.JacobHaukenInspector.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jacob Hauken, Inspector", 332, Rarity.MYTHIC, mage.cards.j.JacobHaukenInspector.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jacob Hauken, Inspector", 65, Rarity.MYTHIC, mage.cards.j.JacobHaukenInspector.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Katilda's Rising Dawn", 21, Rarity.RARE, mage.cards.k.KatildasRisingDawn.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Katilda's Rising Dawn", 317, Rarity.RARE, mage.cards.k.KatildasRisingDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katilda, Dawnhart Martyr", 21, Rarity.RARE, mage.cards.k.KatildaDawnhartMartyr.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Katilda, Dawnhart Martyr", 317, Rarity.RARE, mage.cards.k.KatildaDawnhartMartyr.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kaya, Geist Hunter", 240, Rarity.MYTHIC, mage.cards.k.KayaGeistHunter.class, NON_FULL_USE_VARIOUS)); @@ -289,24 +262,16 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Kessig Wolfrider", 165, Rarity.RARE, mage.cards.k.KessigWolfrider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kessig Wolfrider", 379, Rarity.RARE, mage.cards.k.KessigWolfrider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kindly Ancestor", 22, Rarity.COMMON, mage.cards.k.KindlyAncestor.class)); - cards.add(new SetCardInfo("Krothuss, Lord of the Deep", 246, Rarity.RARE, mage.cards.k.KrothussLordOfTheDeep.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Krothuss, Lord of the Deep", 316, Rarity.RARE, mage.cards.k.KrothussLordOfTheDeep.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Krothuss, Lord of the Deep", 327, Rarity.RARE, mage.cards.k.KrothussLordOfTheDeep.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lacerate Flesh", 166, Rarity.COMMON, mage.cards.l.LacerateFlesh.class)); cards.add(new SetCardInfo("Laid to Rest", 207, Rarity.UNCOMMON, mage.cards.l.LaidToRest.class)); cards.add(new SetCardInfo("Lambholt Raconteur", 167, Rarity.UNCOMMON, mage.cards.l.LambholtRaconteur.class)); - cards.add(new SetCardInfo("Lambholt Ravager", 167, Rarity.UNCOMMON, mage.cards.l.LambholtRavager.class)); cards.add(new SetCardInfo("Lantern Bearer", 66, Rarity.COMMON, mage.cards.l.LanternBearer.class)); cards.add(new SetCardInfo("Lantern Flare", 23, Rarity.RARE, mage.cards.l.LanternFlare.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lantern Flare", 351, Rarity.RARE, mage.cards.l.LanternFlare.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lantern of the Lost", 259, Rarity.UNCOMMON, mage.cards.l.LanternOfTheLost.class)); - cards.add(new SetCardInfo("Lanterns' Lift", 66, Rarity.COMMON, mage.cards.l.LanternsLift.class)); cards.add(new SetCardInfo("Lightning Wolf", 168, Rarity.COMMON, mage.cards.l.LightningWolf.class)); cards.add(new SetCardInfo("Lunar Rejection", 67, Rarity.UNCOMMON, mage.cards.l.LunarRejection.class)); cards.add(new SetCardInfo("Magma Pummeler", 169, Rarity.UNCOMMON, mage.cards.m.MagmaPummeler.class)); - cards.add(new SetCardInfo("Malicious Invader", 121, Rarity.UNCOMMON, mage.cards.m.MaliciousInvader.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Malicious Invader", 294, Rarity.UNCOMMON, mage.cards.m.MaliciousInvader.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Malicious Invader", 336, Rarity.UNCOMMON, mage.cards.m.MaliciousInvader.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Manaform Hellkite", 170, Rarity.MYTHIC, mage.cards.m.ManaformHellkite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Manaform Hellkite", 380, Rarity.MYTHIC, mage.cards.m.ManaformHellkite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Markov Purifier", 241, Rarity.UNCOMMON, mage.cards.m.MarkovPurifier.class, NON_FULL_USE_VARIOUS)); @@ -321,7 +286,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Mirrorhall Mimic", 68, Rarity.RARE, mage.cards.m.MirrorhallMimic.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mischievous Catgeist", 69, Rarity.UNCOMMON, mage.cards.m.MischievousCatgeist.class)); cards.add(new SetCardInfo("Moldgraf Millipede", 209, Rarity.COMMON, mage.cards.m.MoldgrafMillipede.class)); - cards.add(new SetCardInfo("Moonlit Ambusher", 212, Rarity.UNCOMMON, mage.cards.m.MoonlitAmbusher.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 401, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); @@ -333,7 +297,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Necroduality", 70, Rarity.MYTHIC, mage.cards.n.Necroduality.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nurturing Presence", 26, Rarity.COMMON, mage.cards.n.NurturingPresence.class)); cards.add(new SetCardInfo("Oakshade Stalker", 212, Rarity.UNCOMMON, mage.cards.o.OakshadeStalker.class)); - cards.add(new SetCardInfo("Odious Witch", 127, Rarity.COMMON, mage.cards.o.OdiousWitch.class)); cards.add(new SetCardInfo("Odric, Blood-Cursed", 243, Rarity.RARE, mage.cards.o.OdricBloodCursed.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Odric, Blood-Cursed", 314, Rarity.RARE, mage.cards.o.OdricBloodCursed.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Old Rutstein", 244, Rarity.RARE, mage.cards.o.OldRutstein.class, NON_FULL_USE_VARIOUS)); @@ -363,7 +326,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Pointed Discussion", 126, Rarity.COMMON, mage.cards.p.PointedDiscussion.class)); cards.add(new SetCardInfo("Pyre Spawn", 173, Rarity.COMMON, mage.cards.p.PyreSpawn.class)); cards.add(new SetCardInfo("Radiant Grace", 31, Rarity.UNCOMMON, mage.cards.r.RadiantGrace.class)); - cards.add(new SetCardInfo("Radiant Restraints", 31, Rarity.UNCOMMON, mage.cards.r.RadiantRestraints.class)); cards.add(new SetCardInfo("Ragged Recluse", 127, Rarity.COMMON, mage.cards.r.RaggedRecluse.class)); cards.add(new SetCardInfo("Reckless Impulse", 174, Rarity.COMMON, mage.cards.r.RecklessImpulse.class)); cards.add(new SetCardInfo("Reclusive Taxidermist", 214, Rarity.UNCOMMON, mage.cards.r.ReclusiveTaxidermist.class, NON_FULL_USE_VARIOUS)); @@ -374,7 +336,6 @@ public final class InnistradCrimsonVow extends ExpansionSet { cards.add(new SetCardInfo("Restless Bloodseeker", 128, Rarity.UNCOMMON, mage.cards.r.RestlessBloodseeker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Restless Bloodseeker", 295, Rarity.UNCOMMON, mage.cards.r.RestlessBloodseeker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Retrieve", 215, Rarity.UNCOMMON, mage.cards.r.Retrieve.class)); - cards.add(new SetCardInfo("Riphook Raider", 203, Rarity.COMMON, mage.cards.r.RiphookRaider.class)); cards.add(new SetCardInfo("Rot-Tide Gargantua", 129, Rarity.COMMON, mage.cards.r.RotTideGargantua.class)); cards.add(new SetCardInfo("Runebound Wolf", 176, Rarity.UNCOMMON, mage.cards.r.RuneboundWolf.class)); cards.add(new SetCardInfo("Runo Stromkirk", 246, Rarity.RARE, mage.cards.r.RunoStromkirk.class, NON_FULL_USE_VARIOUS)); @@ -444,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)); @@ -472,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)); @@ -481,24 +438,18 @@ 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)); cards.add(new SetCardInfo("Welcoming Vampire", 287, Rarity.RARE, mage.cards.w.WelcomingVampire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Welcoming Vampire", 46, Rarity.RARE, mage.cards.w.WelcomingVampire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Whispering Wizard", 88, Rarity.UNCOMMON, mage.cards.w.WhisperingWizard.class)); - cards.add(new SetCardInfo("Wildsong Howler", 205, Rarity.RARE, mage.cards.w.WildsongHowler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Wildsong Howler", 392, Rarity.RARE, mage.cards.w.WildsongHowler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Winged Portent", 365, Rarity.RARE, mage.cards.w.WingedPortent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Winged Portent", 89, Rarity.RARE, mage.cards.w.WingedPortent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Witch's Web", 227, Rarity.COMMON, mage.cards.w.WitchsWeb.class)); 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 87c7f024a56..3a0aa70042d 100644 --- a/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java +++ b/Mage.Sets/src/mage/sets/InnistradDoubleFeature.java @@ -34,7 +34,7 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Alchemist's Gambit", 407, Rarity.RARE, mage.cards.a.AlchemistsGambit.class)); cards.add(new SetCardInfo("Alchemist's Retrieval", 314, Rarity.COMMON, mage.cards.a.AlchemistsRetrieval.class)); cards.add(new SetCardInfo("Alluring Suitor", 408, Rarity.UNCOMMON, mage.cards.a.AlluringSuitor.class)); - cards.add(new SetCardInfo("Ancestor's Embrace", 289, Rarity.COMMON, mage.cards.a.AncestorsEmbrace.class)); + cards.add(new SetCardInfo("Ambitious Farmhand", 2, Rarity.UNCOMMON, mage.cards.a.AmbitiousFarmhand.class)); cards.add(new SetCardInfo("Ancestral Anger", 409, Rarity.COMMON, mage.cards.a.AncestralAnger.class)); cards.add(new SetCardInfo("Ancient Lumberknot", 497, Rarity.UNCOMMON, mage.cards.a.AncientLumberknot.class)); cards.add(new SetCardInfo("Angelfire Ignition", 209, Rarity.RARE, mage.cards.a.AngelfireIgnition.class)); @@ -43,13 +43,11 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Apprentice Sharpshooter", 452, Rarity.COMMON, mage.cards.a.ApprenticeSharpshooter.class)); cards.add(new SetCardInfo("Arcane Infusion", 210, Rarity.UNCOMMON, mage.cards.a.ArcaneInfusion.class)); cards.add(new SetCardInfo("Archghoul of Thraben", 360, Rarity.UNCOMMON, mage.cards.a.ArchghoulOfThraben.class)); - cards.add(new SetCardInfo("Archive Haunt", 68, Rarity.UNCOMMON, mage.cards.a.ArchiveHaunt.class)); cards.add(new SetCardInfo("Ardent Elementalist", 128, Rarity.COMMON, mage.cards.a.ArdentElementalist.class)); cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 211, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class)); 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)); @@ -58,7 +56,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Bat Whisperer", 86, Rarity.COMMON, mage.cards.b.BatWhisperer.class)); cards.add(new SetCardInfo("Belligerent Guest", 411, Rarity.COMMON, mage.cards.b.BelligerentGuest.class)); cards.add(new SetCardInfo("Beloved Beggar", 3, Rarity.UNCOMMON, mage.cards.b.BelovedBeggar.class)); - cards.add(new SetCardInfo("Benevolent Geist", 61, Rarity.RARE, mage.cards.b.BenevolentGeist.class)); cards.add(new SetCardInfo("Bereaved Survivor", 4, Rarity.UNCOMMON, mage.cards.b.BereavedSurvivor.class)); cards.add(new SetCardInfo("Binding Geist", 315, Rarity.COMMON, mage.cards.b.BindingGeist.class)); cards.add(new SetCardInfo("Biolume Egg", 316, Rarity.UNCOMMON, mage.cards.b.BiolumeEgg.class)); @@ -72,17 +69,14 @@ 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("Bloodsoaked Reveler", 395, Rarity.UNCOMMON, mage.cards.b.BloodsoakedReveler.class)); cards.add(new SetCardInfo("Bloodsworn Squire", 364, Rarity.UNCOMMON, mage.cards.b.BloodswornSquire.class)); cards.add(new SetCardInfo("Bloodthirsty Adversary", 129, Rarity.MYTHIC, mage.cards.b.BloodthirstyAdversary.class)); cards.add(new SetCardInfo("Bloodtithe Collector", 90, Rarity.UNCOMMON, mage.cards.b.BloodtitheCollector.class)); 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)); @@ -99,7 +93,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Burn Down the House", 131, Rarity.RARE, mage.cards.b.BurnDownTheHouse.class)); cards.add(new SetCardInfo("Burn the Accursed", 132, Rarity.COMMON, mage.cards.b.BurnTheAccursed.class)); cards.add(new SetCardInfo("By Invitation Only", 272, Rarity.RARE, mage.cards.b.ByInvitationOnly.class)); - cards.add(new SetCardInfo("Cackling Culprit", 295, Rarity.UNCOMMON, mage.cards.c.CacklingCulprit.class)); cards.add(new SetCardInfo("Can't Stay Away", 213, Rarity.RARE, mage.cards.c.CantStayAway.class)); cards.add(new SetCardInfo("Candlegrove Witch", 8, Rarity.COMMON, mage.cards.c.CandlegroveWitch.class)); cards.add(new SetCardInfo("Candlelit Cavalry", 175, Rarity.COMMON, mage.cards.c.CandlelitCavalry.class)); @@ -109,7 +102,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Cathar Commando", 10, Rarity.COMMON, mage.cards.c.CatharCommando.class)); cards.add(new SetCardInfo("Cathar's Call", 11, Rarity.UNCOMMON, mage.cards.c.CatharsCall.class)); cards.add(new SetCardInfo("Cathartic Pyre", 133, Rarity.UNCOMMON, mage.cards.c.CatharticPyre.class)); - cards.add(new SetCardInfo("Catlike Curiosity", 336, Rarity.UNCOMMON, mage.cards.c.CatlikeCuriosity.class)); cards.add(new SetCardInfo("Celestus Sanctifier", 12, Rarity.COMMON, mage.cards.c.CelestusSanctifier.class)); cards.add(new SetCardInfo("Cemetery Desecrator", 367, Rarity.MYTHIC, mage.cards.c.CemeteryDesecrator.class)); cards.add(new SetCardInfo("Cemetery Gatekeeper", 415, Rarity.MYTHIC, mage.cards.c.CemeteryGatekeeper.class)); @@ -123,8 +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("Chilling Chronicle", 63, Rarity.UNCOMMON, mage.cards.c.ChillingChronicle.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)); @@ -143,7 +133,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Cradle of Safety", 321, Rarity.COMMON, mage.cards.c.CradleOfSafety.class)); cards.add(new SetCardInfo("Crawl from the Cellar", 93, Rarity.COMMON, mage.cards.c.CrawlFromTheCellar.class)); cards.add(new SetCardInfo("Crawling Infestation", 460, Rarity.UNCOMMON, mage.cards.c.CrawlingInfestation.class)); - cards.add(new SetCardInfo("Creeping Inn", 264, Rarity.MYTHIC, mage.cards.c.CreepingInn.class)); cards.add(new SetCardInfo("Creepy Puppeteer", 418, Rarity.RARE, mage.cards.c.CreepyPuppeteer.class)); cards.add(new SetCardInfo("Croaking Counterpart", 215, Rarity.RARE, mage.cards.c.CroakingCounterpart.class)); cards.add(new SetCardInfo("Crossroads Candleguide", 253, Rarity.COMMON, mage.cards.c.CrossroadsCandleguide.class)); @@ -173,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)); @@ -206,7 +193,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Edgar's Awakening", 377, Rarity.UNCOMMON, mage.cards.e.EdgarsAwakening.class)); cards.add(new SetCardInfo("Edgar, Charmed Groom", 503, Rarity.RARE, mage.cards.e.EdgarCharmedGroom.class)); cards.add(new SetCardInfo("Electric Revelation", 135, Rarity.COMMON, mage.cards.e.ElectricRevelation.class)); - cards.add(new SetCardInfo("Embodiment of Flame", 141, Rarity.UNCOMMON, mage.cards.e.EmbodimentOfFlame.class)); cards.add(new SetCardInfo("End the Festivities", 422, Rarity.COMMON, mage.cards.e.EndTheFestivities.class)); cards.add(new SetCardInfo("Endless Ranks of the Dead", 535, Rarity.RARE, mage.cards.e.EndlessRanksOfTheDead.class)); cards.add(new SetCardInfo("Enduring Angel", 17, Rarity.MYTHIC, mage.cards.e.EnduringAngel.class)); @@ -224,11 +210,9 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Falkenrath Pit Fighter", 137, Rarity.RARE, mage.cards.f.FalkenrathPitFighter.class)); cards.add(new SetCardInfo("Famished Foragers", 138, Rarity.COMMON, mage.cards.f.FamishedForagers.class)); cards.add(new SetCardInfo("Fangblade Brigand", 139, Rarity.UNCOMMON, mage.cards.f.FangbladeBrigand.class)); - cards.add(new SetCardInfo("Fangblade Eviscerator", 139, Rarity.UNCOMMON, mage.cards.f.FangbladeEviscerator.class)); cards.add(new SetCardInfo("Fateful Absence", 18, Rarity.RARE, mage.cards.f.FatefulAbsence.class)); cards.add(new SetCardInfo("Fear of Death", 326, Rarity.COMMON, mage.cards.f.FearOfDeath.class)); cards.add(new SetCardInfo("Fearful Villager", 424, Rarity.COMMON, mage.cards.f.FearfulVillager.class)); - cards.add(new SetCardInfo("Fearsome Werewolf", 424, Rarity.COMMON, mage.cards.f.FearsomeWerewolf.class)); cards.add(new SetCardInfo("Fell Stinger", 379, Rarity.UNCOMMON, mage.cards.f.FellStinger.class)); cards.add(new SetCardInfo("Festival Crasher", 140, Rarity.COMMON, mage.cards.f.FestivalCrasher.class)); cards.add(new SetCardInfo("Field of Ruin", 262, Rarity.UNCOMMON, mage.cards.f.FieldOfRuin.class)); @@ -246,7 +230,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Forsaken Thresher", 523, Rarity.UNCOMMON, mage.cards.f.ForsakenThresher.class)); cards.add(new SetCardInfo("Foul Play", 101, Rarity.UNCOMMON, mage.cards.f.FoulPlay.class)); cards.add(new SetCardInfo("Frenzied Devils", 426, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class)); - cards.add(new SetCardInfo("Frenzied Trapbreaker", 190, Rarity.UNCOMMON, mage.cards.f.FrenziedTrapbreaker.class)); cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class)); cards.add(new SetCardInfo("Galvanic Iteration", 224, Rarity.RARE, mage.cards.g.GalvanicIteration.class)); cards.add(new SetCardInfo("Gavony Dawnguard", 20, Rarity.UNCOMMON, mage.cards.g.GavonyDawnguard.class)); @@ -256,7 +239,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Geistlight Snare", 327, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class)); cards.add(new SetCardInfo("Geistwave", 56, Rarity.COMMON, mage.cards.g.Geistwave.class)); cards.add(new SetCardInfo("Geralf, Visionary Stitcher", 328, Rarity.RARE, mage.cards.g.GeralfVisionaryStitcher.class)); - cards.add(new SetCardInfo("Ghastly Mimicry", 335, Rarity.RARE, mage.cards.g.GhastlyMimicry.class)); cards.add(new SetCardInfo("Ghoulcaller's Harvest", 225, Rarity.RARE, mage.cards.g.GhoulcallersHarvest.class)); cards.add(new SetCardInfo("Ghoulish Procession", 102, Rarity.UNCOMMON, mage.cards.g.GhoulishProcession.class)); cards.add(new SetCardInfo("Gift of Fangs", 380, Rarity.COMMON, mage.cards.g.GiftOfFangs.class)); @@ -265,7 +247,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Gluttonous Guest", 381, Rarity.COMMON, mage.cards.g.GluttonousGuest.class)); cards.add(new SetCardInfo("Graf Reaver", 382, Rarity.RARE, mage.cards.g.GrafReaver.class)); cards.add(new SetCardInfo("Grafted Identity", 57, Rarity.RARE, mage.cards.g.GraftedIdentity.class)); - cards.add(new SetCardInfo("Graveyard Glutton", 104, Rarity.RARE, mage.cards.g.GraveyardGlutton.class)); cards.add(new SetCardInfo("Graveyard Trespasser", 104, Rarity.RARE, mage.cards.g.GraveyardTrespasser.class)); cards.add(new SetCardInfo("Grisly Ritual", 383, Rarity.COMMON, mage.cards.g.GrislyRitual.class)); cards.add(new SetCardInfo("Grizzly Ghoul", 226, Rarity.UNCOMMON, mage.cards.g.GrizzlyGhoul.class)); @@ -273,22 +254,18 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Groom's Finery", 384, Rarity.UNCOMMON, mage.cards.g.GroomsFinery.class)); cards.add(new SetCardInfo("Gryff Rider", 282, Rarity.COMMON, mage.cards.g.GryffRider.class)); cards.add(new SetCardInfo("Gryffwing Cavalry", 283, Rarity.UNCOMMON, mage.cards.g.GryffwingCavalry.class)); - cards.add(new SetCardInfo("Gutter Shortcut", 329, Rarity.UNCOMMON, mage.cards.g.GutterShortcut.class)); cards.add(new SetCardInfo("Gutter Skulker", 329, Rarity.UNCOMMON, mage.cards.g.GutterSkulker.class)); cards.add(new SetCardInfo("Halana and Alena, Partners", 506, Rarity.RARE, mage.cards.h.HalanaAndAlenaPartners.class)); cards.add(new SetCardInfo("Hallowed Haunting", 284, Rarity.MYTHIC, mage.cards.h.HallowedHaunting.class)); cards.add(new SetCardInfo("Hallowed Respite", 227, Rarity.RARE, mage.cards.h.HallowedRespite.class)); cards.add(new SetCardInfo("Hamlet Vanguard", 468, Rarity.RARE, mage.cards.h.HamletVanguard.class)); - cards.add(new SetCardInfo("Harvesttide Assailant", 143, Rarity.COMMON, mage.cards.h.HarvesttideAssailant.class)); cards.add(new SetCardInfo("Harvesttide Infiltrator", 143, Rarity.COMMON, mage.cards.h.HarvesttideInfiltrator.class)); cards.add(new SetCardInfo("Harvesttide Sentry", 186, Rarity.COMMON, mage.cards.h.HarvesttideSentry.class)); - cards.add(new SetCardInfo("Hauken's Insight", 332, Rarity.MYTHIC, mage.cards.h.HaukensInsight.class)); cards.add(new SetCardInfo("Haunted Ridge", 263, Rarity.RARE, mage.cards.h.HauntedRidge.class)); cards.add(new SetCardInfo("Headless Rider", 385, Rarity.RARE, mage.cards.h.HeadlessRider.class)); cards.add(new SetCardInfo("Hedgewitch's Mask", 23, Rarity.COMMON, mage.cards.h.HedgewitchsMask.class)); cards.add(new SetCardInfo("Heirloom Mirror", 105, Rarity.UNCOMMON, mage.cards.h.HeirloomMirror.class)); cards.add(new SetCardInfo("Henrika Domnathi", 386, Rarity.MYTHIC, mage.cards.h.HenrikaDomnathi.class)); - cards.add(new SetCardInfo("Henrika, Infernal Seer", 386, Rarity.MYTHIC, mage.cards.h.HenrikaInfernalSeer.class)); cards.add(new SetCardInfo("Hero's Downfall", 387, Rarity.UNCOMMON, mage.cards.h.HerosDownfall.class)); cards.add(new SetCardInfo("Heron of Hope", 285, Rarity.COMMON, mage.cards.h.HeronOfHope.class)); cards.add(new SetCardInfo("Heron-Blessed Geist", 286, Rarity.COMMON, mage.cards.h.HeronBlessedGeist.class)); @@ -303,7 +280,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Hound Tamer", 187, Rarity.UNCOMMON, mage.cards.h.HoundTamer.class)); cards.add(new SetCardInfo("Howl of the Hunt", 188, Rarity.COMMON, mage.cards.h.HowlOfTheHunt.class)); cards.add(new SetCardInfo("Howling Moon", 471, Rarity.RARE, mage.cards.h.HowlingMoon.class)); - cards.add(new SetCardInfo("Howlpack Avenger", 429, Rarity.RARE, mage.cards.h.HowlpackAvenger.class)); cards.add(new SetCardInfo("Howlpack Piper", 472, Rarity.RARE, mage.cards.h.HowlpackPiper.class)); cards.add(new SetCardInfo("Hullbreaker Horror", 330, Rarity.RARE, mage.cards.h.HullbreakerHorror.class)); cards.add(new SetCardInfo("Hungry for More", 228, Rarity.UNCOMMON, mage.cards.h.HungryForMore.class)); @@ -312,8 +288,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Immolation", 144, Rarity.COMMON, mage.cards.i.Immolation.class)); cards.add(new SetCardInfo("Infernal Grasp", 107, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class)); cards.add(new SetCardInfo("Infestation Expert", 473, Rarity.UNCOMMON, mage.cards.i.InfestationExpert.class)); - cards.add(new SetCardInfo("Infested Werewolf", 473, Rarity.UNCOMMON, mage.cards.i.InfestedWerewolf.class)); - cards.add(new SetCardInfo("Inherited Fiend", 105, Rarity.UNCOMMON, mage.cards.i.InheritedFiend.class)); cards.add(new SetCardInfo("Innocent Traveler", 388, Rarity.UNCOMMON, mage.cards.i.InnocentTraveler.class)); cards.add(new SetCardInfo("Inspired Idea", 331, Rarity.RARE, mage.cards.i.InspiredIdea.class)); cards.add(new SetCardInfo("Into the Night", 430, Rarity.UNCOMMON, mage.cards.i.IntoTheNight.class)); @@ -324,7 +298,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Jadar, Ghoulcaller of Nephalia", 108, Rarity.RARE, mage.cards.j.JadarGhoulcallerOfNephalia.class)); cards.add(new SetCardInfo("Jerren, Corrupted Bishop", 109, Rarity.MYTHIC, mage.cards.j.JerrenCorruptedBishop.class)); cards.add(new SetCardInfo("Join the Dance", 229, Rarity.UNCOMMON, mage.cards.j.JoinTheDance.class)); - cards.add(new SetCardInfo("Katilda's Rising Dawn", 288, Rarity.RARE, mage.cards.k.KatildasRisingDawn.class)); cards.add(new SetCardInfo("Katilda, Dawnhart Martyr", 288, Rarity.RARE, mage.cards.k.KatildaDawnhartMartyr.class)); cards.add(new SetCardInfo("Katilda, Dawnhart Prime", 230, Rarity.RARE, mage.cards.k.KatildaDawnhartPrime.class)); cards.add(new SetCardInfo("Kaya, Geist Hunter", 507, Rarity.MYTHIC, mage.cards.k.KayaGeistHunter.class)); @@ -332,16 +305,13 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Kessig Naturalist", 231, Rarity.UNCOMMON, mage.cards.k.KessigNaturalist.class)); cards.add(new SetCardInfo("Kessig Wolfrider", 432, Rarity.RARE, mage.cards.k.KessigWolfrider.class)); cards.add(new SetCardInfo("Kindly Ancestor", 289, Rarity.COMMON, mage.cards.k.KindlyAncestor.class)); - cards.add(new SetCardInfo("Krothuss, Lord of the Deep", 513, Rarity.RARE, mage.cards.k.KrothussLordOfTheDeep.class)); cards.add(new SetCardInfo("Lacerate Flesh", 433, Rarity.COMMON, mage.cards.l.LacerateFlesh.class)); cards.add(new SetCardInfo("Laid to Rest", 474, Rarity.UNCOMMON, mage.cards.l.LaidToRest.class)); cards.add(new SetCardInfo("Lambholt Harrier", 145, Rarity.COMMON, mage.cards.l.LambholtHarrier.class)); cards.add(new SetCardInfo("Lambholt Raconteur", 434, Rarity.UNCOMMON, mage.cards.l.LambholtRaconteur.class)); - cards.add(new SetCardInfo("Lambholt Ravager", 434, Rarity.UNCOMMON, mage.cards.l.LambholtRavager.class)); cards.add(new SetCardInfo("Lantern Bearer", 333, Rarity.COMMON, mage.cards.l.LanternBearer.class)); cards.add(new SetCardInfo("Lantern Flare", 290, Rarity.RARE, mage.cards.l.LanternFlare.class)); cards.add(new SetCardInfo("Lantern of the Lost", 526, Rarity.UNCOMMON, mage.cards.l.LanternOfTheLost.class)); - cards.add(new SetCardInfo("Lanterns' Lift", 333, Rarity.COMMON, mage.cards.l.LanternsLift.class)); cards.add(new SetCardInfo("Larder Zombie", 58, Rarity.COMMON, mage.cards.l.LarderZombie.class)); cards.add(new SetCardInfo("Lier, Disciple of the Drowned", 59, Rarity.MYTHIC, mage.cards.l.LierDiscipleOfTheDrowned.class)); cards.add(new SetCardInfo("Liesa, Forgotten Archangel", 232, Rarity.RARE, mage.cards.l.LiesaForgottenArchangel.class)); @@ -349,16 +319,13 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Lightning Wolf", 435, Rarity.COMMON, mage.cards.l.LightningWolf.class)); cards.add(new SetCardInfo("Locked in the Cemetery", 60, Rarity.COMMON, mage.cards.l.LockedInTheCemetery.class)); cards.add(new SetCardInfo("Lord of the Forsaken", 110, Rarity.MYTHIC, mage.cards.l.LordOfTheForsaken.class)); - cards.add(new SetCardInfo("Lord of the Ulvenwald", 231, Rarity.UNCOMMON, mage.cards.l.LordOfTheUlvenwald.class)); cards.add(new SetCardInfo("Loyal Gryff", 26, Rarity.UNCOMMON, mage.cards.l.LoyalGryff.class)); cards.add(new SetCardInfo("Ludevic, Necrogenius", 233, Rarity.RARE, mage.cards.l.LudevicNecrogenius.class)); - cards.add(new SetCardInfo("Luminous Phantom", 27, Rarity.COMMON, mage.cards.l.LuminousPhantom.class)); cards.add(new SetCardInfo("Lunar Frenzy", 147, Rarity.UNCOMMON, mage.cards.l.LunarFrenzy.class)); cards.add(new SetCardInfo("Lunar Rejection", 334, Rarity.UNCOMMON, mage.cards.l.LunarRejection.class)); cards.add(new SetCardInfo("Lunarch Veteran", 27, Rarity.COMMON, mage.cards.l.LunarchVeteran.class)); cards.add(new SetCardInfo("Magma Pummeler", 436, Rarity.UNCOMMON, mage.cards.m.MagmaPummeler.class)); cards.add(new SetCardInfo("Malevolent Hermit", 61, Rarity.RARE, mage.cards.m.MalevolentHermit.class)); - cards.add(new SetCardInfo("Malicious Invader", 388, Rarity.UNCOMMON, mage.cards.m.MaliciousInvader.class)); cards.add(new SetCardInfo("Manaform Hellkite", 437, Rarity.MYTHIC, mage.cards.m.ManaformHellkite.class)); cards.add(new SetCardInfo("Markov Purifier", 508, Rarity.UNCOMMON, mage.cards.m.MarkovPurifier.class)); cards.add(new SetCardInfo("Markov Retribution", 438, Rarity.UNCOMMON, mage.cards.m.MarkovRetribution.class)); @@ -372,18 +339,15 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Mirrorhall Mimic", 335, Rarity.RARE, mage.cards.m.MirrorhallMimic.class)); cards.add(new SetCardInfo("Mischievous Catgeist", 336, Rarity.UNCOMMON, mage.cards.m.MischievousCatgeist.class)); cards.add(new SetCardInfo("Moldgraf Millipede", 476, Rarity.COMMON, mage.cards.m.MoldgrafMillipede.class)); - cards.add(new SetCardInfo("Moonlit Ambusher", 479, Rarity.UNCOMMON, mage.cards.m.MoonlitAmbusher.class)); cards.add(new SetCardInfo("Moonrager's Slash", 148, Rarity.COMMON, mage.cards.m.MoonragersSlash.class)); cards.add(new SetCardInfo("Moonsilver Key", 255, Rarity.UNCOMMON, mage.cards.m.MoonsilverKey.class)); cards.add(new SetCardInfo("Moonveil Regent", 149, Rarity.MYTHIC, mage.cards.m.MoonveilRegent.class)); cards.add(new SetCardInfo("Morbid Opportunist", 113, Rarity.UNCOMMON, mage.cards.m.MorbidOpportunist.class)); cards.add(new SetCardInfo("Morkrut Behemoth", 114, Rarity.COMMON, mage.cards.m.MorkrutBehemoth.class)); - cards.add(new SetCardInfo("Morning Apparition", 28, Rarity.COMMON, mage.cards.m.MorningApparition.class)); cards.add(new SetCardInfo("Mounted Dreadknight", 150, Rarity.COMMON, mage.cards.m.MountedDreadknight.class)); cards.add(new SetCardInfo("Mourning Patrol", 28, Rarity.COMMON, mage.cards.m.MourningPatrol.class)); cards.add(new SetCardInfo("Mulch", 477, Rarity.COMMON, mage.cards.m.Mulch.class)); cards.add(new SetCardInfo("Mysterious Tome", 63, Rarity.UNCOMMON, mage.cards.m.MysteriousTome.class)); - cards.add(new SetCardInfo("Mystic Monstrosity", 256, Rarity.UNCOMMON, mage.cards.m.MysticMonstrosity.class)); cards.add(new SetCardInfo("Mystic Skull", 256, Rarity.UNCOMMON, mage.cards.m.MysticSkull.class)); cards.add(new SetCardInfo("Nature's Embrace", 478, Rarity.COMMON, mage.cards.n.NaturesEmbrace.class)); cards.add(new SetCardInfo("Nebelgast Beguiler", 292, Rarity.COMMON, mage.cards.n.NebelgastBeguiler.class)); @@ -396,10 +360,8 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Nurturing Presence", 293, Rarity.COMMON, mage.cards.n.NurturingPresence.class)); cards.add(new SetCardInfo("Oakshade Stalker", 479, Rarity.UNCOMMON, mage.cards.o.OakshadeStalker.class)); cards.add(new SetCardInfo("Obsessive Astronomer", 152, Rarity.UNCOMMON, mage.cards.o.ObsessiveAstronomer.class)); - cards.add(new SetCardInfo("Odious Witch", 394, Rarity.COMMON, mage.cards.o.OdiousWitch.class)); cards.add(new SetCardInfo("Odric's Outrider", 29, Rarity.UNCOMMON, mage.cards.o.OdricsOutrider.class)); cards.add(new SetCardInfo("Odric, Blood-Cursed", 510, Rarity.RARE, mage.cards.o.OdricBloodCursed.class)); - cards.add(new SetCardInfo("Olag, Ludevic's Hubris", 233, Rarity.RARE, mage.cards.o.OlagLudevicsHubris.class)); cards.add(new SetCardInfo("Old Rutstein", 511, Rarity.RARE, mage.cards.o.OldRutstein.class)); cards.add(new SetCardInfo("Old Stickfingers", 234, Rarity.RARE, mage.cards.o.OldStickfingers.class)); cards.add(new SetCardInfo("Olivia's Attendants", 439, Rarity.RARE, mage.cards.o.OliviasAttendants.class)); @@ -408,7 +370,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Ollenbock Escort", 294, Rarity.UNCOMMON, mage.cards.o.OllenbockEscort.class)); cards.add(new SetCardInfo("Ominous Roost", 65, Rarity.UNCOMMON, mage.cards.o.OminousRoost.class)); cards.add(new SetCardInfo("Organ Hoarder", 66, Rarity.COMMON, mage.cards.o.OrganHoarder.class)); - cards.add(new SetCardInfo("Ormendahl, the Corrupter", 109, Rarity.MYTHIC, mage.cards.o.OrmendahlTheCorrupter.class)); cards.add(new SetCardInfo("Otherworldly Gaze", 67, Rarity.COMMON, mage.cards.o.OtherworldlyGaze.class)); cards.add(new SetCardInfo("Outland Liberator", 190, Rarity.UNCOMMON, mage.cards.o.OutlandLiberator.class)); cards.add(new SetCardInfo("Overcharged Amalgam", 338, Rarity.RARE, mage.cards.o.OverchargedAmalgam.class)); @@ -431,13 +392,11 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Play with Fire", 154, Rarity.UNCOMMON, mage.cards.p.PlayWithFire.class)); cards.add(new SetCardInfo("Plummet", 193, Rarity.COMMON, mage.cards.p.Plummet.class)); cards.add(new SetCardInfo("Pointed Discussion", 393, Rarity.COMMON, mage.cards.p.PointedDiscussion.class)); - cards.add(new SetCardInfo("Poppet Factory", 71, Rarity.MYTHIC, mage.cards.p.PoppetFactory.class)); cards.add(new SetCardInfo("Poppet Stitcher", 71, Rarity.MYTHIC, mage.cards.p.PoppetStitcher.class)); cards.add(new SetCardInfo("Primal Adversary", 194, Rarity.MYTHIC, mage.cards.p.PrimalAdversary.class)); cards.add(new SetCardInfo("Purifying Dragon", 155, Rarity.UNCOMMON, mage.cards.p.PurifyingDragon.class)); cards.add(new SetCardInfo("Pyre Spawn", 440, Rarity.COMMON, mage.cards.p.PyreSpawn.class)); cards.add(new SetCardInfo("Radiant Grace", 298, Rarity.UNCOMMON, mage.cards.r.RadiantGrace.class)); - cards.add(new SetCardInfo("Radiant Restraints", 298, Rarity.UNCOMMON, mage.cards.r.RadiantRestraints.class)); cards.add(new SetCardInfo("Ragged Recluse", 394, Rarity.COMMON, mage.cards.r.RaggedRecluse.class)); cards.add(new SetCardInfo("Raze the Effigy", 156, Rarity.COMMON, mage.cards.r.RazeTheEffigy.class)); cards.add(new SetCardInfo("Reckless Impulse", 441, Rarity.COMMON, mage.cards.r.RecklessImpulse.class)); @@ -451,7 +410,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Retrieve", 482, Rarity.UNCOMMON, mage.cards.r.Retrieve.class)); cards.add(new SetCardInfo("Return to Nature", 195, Rarity.COMMON, mage.cards.r.ReturnToNature.class)); cards.add(new SetCardInfo("Revenge of the Drowned", 72, Rarity.COMMON, mage.cards.r.RevengeOfTheDrowned.class)); - cards.add(new SetCardInfo("Riphook Raider", 470, Rarity.COMMON, mage.cards.r.RiphookRaider.class)); cards.add(new SetCardInfo("Rise of the Ants", 196, Rarity.UNCOMMON, mage.cards.r.RiseOfTheAnts.class)); cards.add(new SetCardInfo("Rite of Harmony", 236, Rarity.RARE, mage.cards.r.RiteOfHarmony.class)); cards.add(new SetCardInfo("Rite of Oblivion", 237, Rarity.UNCOMMON, mage.cards.r.RiteOfOblivion.class)); @@ -472,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)); @@ -507,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)); @@ -521,11 +476,9 @@ public final class InnistradDoubleFeature extends ExpansionSet { 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)); - cards.add(new SetCardInfo("Storm-Charged Slasher", 157, Rarity.RARE, mage.cards.s.StormChargedSlasher.class)); 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)); @@ -542,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)); @@ -554,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)); @@ -574,7 +522,6 @@ public final class InnistradDoubleFeature extends ExpansionSet { cards.add(new SetCardInfo("Unnatural Growth", 206, Rarity.RARE, mage.cards.u.UnnaturalGrowth.class)); cards.add(new SetCardInfo("Unnatural Moonrise", 247, Rarity.UNCOMMON, mage.cards.u.UnnaturalMoonrise.class)); cards.add(new SetCardInfo("Unruly Mob", 40, Rarity.COMMON, mage.cards.u.UnrulyMob.class)); - cards.add(new SetCardInfo("Untamed Pup", 187, Rarity.UNCOMMON, mage.cards.u.UntamedPup.class)); cards.add(new SetCardInfo("Vadrik, Astral Archmage", 248, Rarity.RARE, mage.cards.v.VadrikAstralArchmage.class)); cards.add(new SetCardInfo("Valorous Stance", 309, Rarity.UNCOMMON, mage.cards.v.ValorousStance.class)); cards.add(new SetCardInfo("Vampire Interloper", 125, Rarity.COMMON, mage.cards.v.VampireInterloper.class)); @@ -585,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)); @@ -595,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)); @@ -604,13 +549,10 @@ 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)); cards.add(new SetCardInfo("Whispering Wizard", 355, Rarity.UNCOMMON, mage.cards.w.WhisperingWizard.class)); - cards.add(new SetCardInfo("Wildsong Howler", 472, Rarity.RARE, mage.cards.w.WildsongHowler.class)); cards.add(new SetCardInfo("Willow Geist", 207, Rarity.RARE, mage.cards.w.WillowGeist.class)); cards.add(new SetCardInfo("Winged Portent", 356, Rarity.RARE, mage.cards.w.WingedPortent.class)); cards.add(new SetCardInfo("Winterthorn Blessing", 251, Rarity.UNCOMMON, mage.cards.w.WinterthornBlessing.class)); @@ -618,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 34a26a0de74..7bfffd9308b 100644 --- a/Mage.Sets/src/mage/sets/InnistradMidnightHunt.java +++ b/Mage.Sets/src/mage/sets/InnistradMidnightHunt.java @@ -42,17 +42,15 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Abandon the Post", 127, Rarity.COMMON, mage.cards.a.AbandonThePost.class)); cards.add(new SetCardInfo("Adeline, Resplendent Cathar", 1, Rarity.RARE, mage.cards.a.AdelineResplendentCathar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Adeline, Resplendent Cathar", 312, Rarity.RARE, mage.cards.a.AdelineResplendentCathar.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ambitious Farmhand", 2, Rarity.UNCOMMON, mage.cards.a.AmbitiousFarmhand.class)); cards.add(new SetCardInfo("Angelfire Ignition", 209, Rarity.RARE, mage.cards.a.AngelfireIgnition.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Angelfire Ignition", 367, Rarity.RARE, mage.cards.a.AngelfireIgnition.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arcane Infusion", 210, Rarity.UNCOMMON, mage.cards.a.ArcaneInfusion.class)); - cards.add(new SetCardInfo("Archive Haunt", 68, Rarity.UNCOMMON, mage.cards.a.ArchiveHaunt.class)); cards.add(new SetCardInfo("Ardent Elementalist", 128, Rarity.COMMON, mage.cards.a.ArdentElementalist.class)); cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 211, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class, NON_FULL_USE_VARIOUS)); 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)); @@ -60,8 +58,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Baneblade Scoundrel", 85, Rarity.UNCOMMON, mage.cards.b.BanebladeScoundrel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bat Whisperer", 86, Rarity.COMMON, mage.cards.b.BatWhisperer.class)); cards.add(new SetCardInfo("Beloved Beggar", 3, Rarity.UNCOMMON, mage.cards.b.BelovedBeggar.class)); - cards.add(new SetCardInfo("Benevolent Geist", 336, Rarity.RARE, mage.cards.b.BenevolentGeist.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Benevolent Geist", 61, Rarity.RARE, mage.cards.b.BenevolentGeist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bereaved Survivor", 4, Rarity.UNCOMMON, mage.cards.b.BereavedSurvivor.class)); cards.add(new SetCardInfo("Bird Admirer", 169, Rarity.COMMON, mage.cards.b.BirdAdmirer.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bird Admirer", 298, Rarity.COMMON, mage.cards.b.BirdAdmirer.class, NON_FULL_USE_VARIOUS)); @@ -102,7 +98,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Champion of the Perished", 385, Rarity.RARE, mage.cards.c.ChampionOfThePerished.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Champion of the Perished", 91, Rarity.RARE, mage.cards.c.ChampionOfThePerished.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chaplain of Alms", 13, Rarity.UNCOMMON, mage.cards.c.ChaplainOfAlms.class)); - cards.add(new SetCardInfo("Chilling Chronicle", 63, Rarity.UNCOMMON, mage.cards.c.ChillingChronicle.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)); cards.add(new SetCardInfo("Component Collector", 43, Rarity.COMMON, mage.cards.c.ComponentCollector.class)); @@ -115,8 +110,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Covert Cutpurse", 92, Rarity.UNCOMMON, mage.cards.c.CovertCutpurse.class)); cards.add(new SetCardInfo("Covetous Castaway", 45, Rarity.UNCOMMON, mage.cards.c.CovetousCastaway.class)); cards.add(new SetCardInfo("Crawl from the Cellar", 93, Rarity.COMMON, mage.cards.c.CrawlFromTheCellar.class)); - cards.add(new SetCardInfo("Creeping Inn", 264, Rarity.MYTHIC, mage.cards.c.CreepingInn.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Creeping Inn", 379, Rarity.MYTHIC, mage.cards.c.CreepingInn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Croaking Counterpart", 215, Rarity.RARE, mage.cards.c.CroakingCounterpart.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Croaking Counterpart", 369, Rarity.RARE, mage.cards.c.CroakingCounterpart.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Crossroads Candleguide", 253, Rarity.COMMON, mage.cards.c.CrossroadsCandleguide.class)); @@ -144,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)); @@ -161,7 +152,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Eccentric Farmer", 185, Rarity.COMMON, mage.cards.e.EccentricFarmer.class)); cards.add(new SetCardInfo("Ecstatic Awakener", 100, Rarity.COMMON, mage.cards.e.EcstaticAwakener.class)); cards.add(new SetCardInfo("Electric Revelation", 135, Rarity.COMMON, mage.cards.e.ElectricRevelation.class)); - cards.add(new SetCardInfo("Embodiment of Flame", 141, Rarity.UNCOMMON, mage.cards.e.EmbodimentOfFlame.class)); cards.add(new SetCardInfo("Enduring Angel", 17, Rarity.MYTHIC, mage.cards.e.EnduringAngel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Enduring Angel", 327, Rarity.MYTHIC, mage.cards.e.EnduringAngel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Evolving Wilds", 261, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); @@ -174,8 +164,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Famished Foragers", 138, Rarity.COMMON, mage.cards.f.FamishedForagers.class)); cards.add(new SetCardInfo("Fangblade Brigand", 139, Rarity.UNCOMMON, mage.cards.f.FangbladeBrigand.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fangblade Brigand", 292, Rarity.UNCOMMON, mage.cards.f.FangbladeBrigand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fangblade Eviscerator", 139, Rarity.UNCOMMON, mage.cards.f.FangbladeEviscerator.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Fangblade Eviscerator", 292, Rarity.UNCOMMON, mage.cards.f.FangbladeEviscerator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fateful Absence", 18, Rarity.RARE, mage.cards.f.FatefulAbsence.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Fateful Absence", 328, Rarity.RARE, mage.cards.f.FatefulAbsence.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Festival Crasher", 140, Rarity.COMMON, mage.cards.f.FestivalCrasher.class)); @@ -191,8 +179,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Forest", 384, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Foul Play", 101, Rarity.UNCOMMON, mage.cards.f.FoulPlay.class)); - cards.add(new SetCardInfo("Frenzied Trapbreaker", 190, Rarity.UNCOMMON, mage.cards.f.FrenziedTrapbreaker.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Frenzied Trapbreaker", 303, Rarity.UNCOMMON, mage.cards.f.FrenziedTrapbreaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class)); cards.add(new SetCardInfo("Galvanic Iteration", 224, Rarity.RARE, mage.cards.g.GalvanicIteration.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Galvanic Iteration", 371, Rarity.RARE, mage.cards.g.GalvanicIteration.class, NON_FULL_USE_VARIOUS)); @@ -210,15 +196,11 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Gisa, Glorious Resurrector", 314, Rarity.RARE, mage.cards.g.GisaGloriousResurrector.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grafted Identity", 335, Rarity.RARE, mage.cards.g.GraftedIdentity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grafted Identity", 57, Rarity.RARE, mage.cards.g.GraftedIdentity.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Graveyard Glutton", 104, Rarity.RARE, mage.cards.g.GraveyardGlutton.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Graveyard Glutton", 290, Rarity.RARE, mage.cards.g.GraveyardGlutton.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Graveyard Trespasser", 104, Rarity.RARE, mage.cards.g.GraveyardTrespasser.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Graveyard Trespasser", 290, Rarity.RARE, mage.cards.g.GraveyardTrespasser.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grizzly Ghoul", 226, Rarity.UNCOMMON, mage.cards.g.GrizzlyGhoul.class)); cards.add(new SetCardInfo("Hallowed Respite", 227, Rarity.RARE, mage.cards.h.HallowedRespite.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hallowed Respite", 373, Rarity.RARE, mage.cards.h.HallowedRespite.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Harvesttide Assailant", 143, Rarity.COMMON, mage.cards.h.HarvesttideAssailant.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Harvesttide Assailant", 293, Rarity.COMMON, mage.cards.h.HarvesttideAssailant.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Harvesttide Infiltrator", 143, Rarity.COMMON, mage.cards.h.HarvesttideInfiltrator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Harvesttide Infiltrator", 293, Rarity.COMMON, mage.cards.h.HarvesttideInfiltrator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Harvesttide Sentry", 186, Rarity.COMMON, mage.cards.h.HarvesttideSentry.class)); @@ -237,7 +219,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Immolation", 144, Rarity.COMMON, mage.cards.i.Immolation.class)); cards.add(new SetCardInfo("Infernal Grasp", 107, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Infernal Grasp", 389, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Inherited Fiend", 105, Rarity.UNCOMMON, mage.cards.i.InheritedFiend.class)); cards.add(new SetCardInfo("Intrepid Adversary", 25, Rarity.MYTHIC, mage.cards.i.IntrepidAdversary.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Intrepid Adversary", 329, Rarity.MYTHIC, mage.cards.i.IntrepidAdversary.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 270, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); @@ -265,12 +246,9 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Locked in the Cemetery", 60, Rarity.COMMON, mage.cards.l.LockedInTheCemetery.class)); cards.add(new SetCardInfo("Lord of the Forsaken", 110, Rarity.MYTHIC, mage.cards.l.LordOfTheForsaken.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lord of the Forsaken", 346, Rarity.MYTHIC, mage.cards.l.LordOfTheForsaken.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Lord of the Ulvenwald", 231, Rarity.UNCOMMON, mage.cards.l.LordOfTheUlvenwald.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Lord of the Ulvenwald", 310, Rarity.UNCOMMON, mage.cards.l.LordOfTheUlvenwald.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Loyal Gryff", 26, Rarity.UNCOMMON, mage.cards.l.LoyalGryff.class)); cards.add(new SetCardInfo("Ludevic, Necrogenius", 233, Rarity.RARE, mage.cards.l.LudevicNecrogenius.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ludevic, Necrogenius", 320, Rarity.RARE, mage.cards.l.LudevicNecrogenius.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Luminous Phantom", 27, Rarity.COMMON, mage.cards.l.LuminousPhantom.class)); cards.add(new SetCardInfo("Lunar Frenzy", 147, Rarity.UNCOMMON, mage.cards.l.LunarFrenzy.class)); cards.add(new SetCardInfo("Lunarch Veteran", 27, Rarity.COMMON, mage.cards.l.LunarchVeteran.class)); cards.add(new SetCardInfo("Malevolent Hermit", 336, Rarity.RARE, mage.cards.m.MalevolentHermit.class, NON_FULL_USE_VARIOUS)); @@ -286,14 +264,12 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Moonveil Regent", 357, Rarity.MYTHIC, mage.cards.m.MoonveilRegent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Morbid Opportunist", 113, Rarity.UNCOMMON, mage.cards.m.MorbidOpportunist.class)); cards.add(new SetCardInfo("Morkrut Behemoth", 114, Rarity.COMMON, mage.cards.m.MorkrutBehemoth.class)); - cards.add(new SetCardInfo("Morning Apparition", 28, Rarity.COMMON, mage.cards.m.MorningApparition.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 383, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mounted Dreadknight", 150, Rarity.COMMON, mage.cards.m.MountedDreadknight.class)); cards.add(new SetCardInfo("Mourning Patrol", 28, Rarity.COMMON, mage.cards.m.MourningPatrol.class)); cards.add(new SetCardInfo("Mysterious Tome", 63, Rarity.UNCOMMON, mage.cards.m.MysteriousTome.class)); - cards.add(new SetCardInfo("Mystic Monstrosity", 256, Rarity.UNCOMMON, mage.cards.m.MysticMonstrosity.class)); cards.add(new SetCardInfo("Mystic Skull", 256, Rarity.UNCOMMON, mage.cards.m.MysticSkull.class)); cards.add(new SetCardInfo("Nebelgast Intruder", 64, Rarity.UNCOMMON, mage.cards.n.NebelgastIntruder.class)); cards.add(new SetCardInfo("Necrosynthesis", 115, Rarity.UNCOMMON, mage.cards.n.Necrosynthesis.class)); @@ -302,15 +278,11 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Novice Occultist", 117, Rarity.COMMON, mage.cards.n.NoviceOccultist.class)); cards.add(new SetCardInfo("Obsessive Astronomer", 152, Rarity.UNCOMMON, mage.cards.o.ObsessiveAstronomer.class)); cards.add(new SetCardInfo("Odric's Outrider", 29, Rarity.UNCOMMON, mage.cards.o.OdricsOutrider.class)); - cards.add(new SetCardInfo("Olag, Ludevic's Hubris", 233, Rarity.RARE, mage.cards.o.OlagLudevicsHubris.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Olag, Ludevic's Hubris", 320, Rarity.RARE, mage.cards.o.OlagLudevicsHubris.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Old Stickfingers", 234, Rarity.RARE, mage.cards.o.OldStickfingers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Old Stickfingers", 321, Rarity.RARE, mage.cards.o.OldStickfingers.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Olivia's Midnight Ambush", 118, Rarity.COMMON, mage.cards.o.OliviasMidnightAmbush.class)); cards.add(new SetCardInfo("Ominous Roost", 65, Rarity.UNCOMMON, mage.cards.o.OminousRoost.class)); cards.add(new SetCardInfo("Organ Hoarder", 66, Rarity.COMMON, mage.cards.o.OrganHoarder.class)); - cards.add(new SetCardInfo("Ormendahl, the Corrupter", 109, Rarity.MYTHIC, mage.cards.o.OrmendahlTheCorrupter.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ormendahl, the Corrupter", 316, Rarity.MYTHIC, mage.cards.o.OrmendahlTheCorrupter.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Otherworldly Gaze", 67, Rarity.COMMON, mage.cards.o.OtherworldlyGaze.class)); cards.add(new SetCardInfo("Outland Liberator", 190, Rarity.UNCOMMON, mage.cards.o.OutlandLiberator.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Outland Liberator", 303, Rarity.UNCOMMON, mage.cards.o.OutlandLiberator.class, NON_FULL_USE_VARIOUS)); @@ -331,8 +303,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Play with Fire", 154, Rarity.UNCOMMON, mage.cards.p.PlayWithFire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Play with Fire", 390, Rarity.UNCOMMON, mage.cards.p.PlayWithFire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plummet", 193, Rarity.COMMON, mage.cards.p.Plummet.class)); - cards.add(new SetCardInfo("Poppet Factory", 339, Rarity.MYTHIC, mage.cards.p.PoppetFactory.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Poppet Factory", 71, Rarity.MYTHIC, mage.cards.p.PoppetFactory.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Poppet Stitcher", 339, Rarity.MYTHIC, mage.cards.p.PoppetStitcher.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Poppet Stitcher", 71, Rarity.MYTHIC, mage.cards.p.PoppetStitcher.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Primal Adversary", 194, Rarity.MYTHIC, mage.cards.p.PrimalAdversary.class, NON_FULL_USE_VARIOUS)); @@ -358,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)); @@ -392,21 +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("Storm-Charged Slasher", 157, Rarity.RARE, mage.cards.s.StormChargedSlasher.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Storm-Charged Slasher", 294, Rarity.RARE, mage.cards.s.StormChargedSlasher.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)); @@ -426,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)); @@ -441,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)); @@ -456,8 +411,6 @@ public final class InnistradMidnightHunt extends ExpansionSet { cards.add(new SetCardInfo("Unnatural Growth", 365, Rarity.RARE, mage.cards.u.UnnaturalGrowth.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Unnatural Moonrise", 247, Rarity.UNCOMMON, mage.cards.u.UnnaturalMoonrise.class)); cards.add(new SetCardInfo("Unruly Mob", 40, Rarity.COMMON, mage.cards.u.UnrulyMob.class)); - cards.add(new SetCardInfo("Untamed Pup", 187, Rarity.UNCOMMON, mage.cards.u.UntamedPup.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Untamed Pup", 302, Rarity.UNCOMMON, mage.cards.u.UntamedPup.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vadrik, Astral Archmage", 248, Rarity.RARE, mage.cards.v.VadrikAstralArchmage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vadrik, Astral Archmage", 325, Rarity.RARE, mage.cards.v.VadrikAstralArchmage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vampire Interloper", 125, Rarity.COMMON, mage.cards.v.VampireInterloper.class)); @@ -465,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/InnistradPromos.java b/Mage.Sets/src/mage/sets/InnistradPromos.java index 7a0c46fd575..f118ae1429f 100644 --- a/Mage.Sets/src/mage/sets/InnistradPromos.java +++ b/Mage.Sets/src/mage/sets/InnistradPromos.java @@ -23,8 +23,6 @@ public class InnistradPromos extends ExpansionSet { cards.add(new SetCardInfo("Devil's Play", 140, Rarity.RARE, mage.cards.d.DevilsPlay.class)); cards.add(new SetCardInfo("Diregraf Ghoul", 97, Rarity.UNCOMMON, mage.cards.d.DiregrafGhoul.class)); cards.add(new SetCardInfo("Elite Inquisitor", 13, Rarity.RARE, mage.cards.e.EliteInquisitor.class)); - cards.add(new SetCardInfo("Howlpack Alpha", "193*", Rarity.RARE, mage.cards.h.HowlpackAlpha.class)); - cards.add(new SetCardInfo("Ludevic's Abomination", "64*", Rarity.RARE, mage.cards.l.LudevicsAbomination.class)); cards.add(new SetCardInfo("Ludevic's Test Subject", "64*", Rarity.RARE, mage.cards.l.LudevicsTestSubject.class)); cards.add(new SetCardInfo("Mayor of Avabruck", "193*", Rarity.RARE, mage.cards.m.MayorOfAvabruck.class)); diff --git a/Mage.Sets/src/mage/sets/InnistradRemastered.java b/Mage.Sets/src/mage/sets/InnistradRemastered.java index 929fbb28697..f2644ce218f 100644 --- a/Mage.Sets/src/mage/sets/InnistradRemastered.java +++ b/Mage.Sets/src/mage/sets/InnistradRemastered.java @@ -33,11 +33,13 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Abundant Maw", 329, Rarity.COMMON, mage.cards.a.AbundantMaw.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Aim High", 185, Rarity.COMMON, mage.cards.a.AimHigh.class)); cards.add(new SetCardInfo("Alchemist's Greeting", 140, Rarity.COMMON, mage.cards.a.AlchemistsGreeting.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Alchemist's Greeting", 393, Rarity.COMMON, mage.cards.a.AlchemistsGreeting.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Alchemist's Greeting", 393, Rarity.COMMON, mage.cards.a.AlchemistsGreeting.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Altered Ego", 228, Rarity.RARE, mage.cards.a.AlteredEgo.class)); + cards.add(new SetCardInfo("Ambitious Farmhand", 448, Rarity.UNCOMMON, mage.cards.a.AmbitiousFarmhand.class, RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Ambitious Farmhand", 8, Rarity.UNCOMMON, mage.cards.a.AmbitiousFarmhand.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ambush Viper", 186, Rarity.COMMON, mage.cards.a.AmbushViper.class)); cards.add(new SetCardInfo("Ancestral Anger", 141, Rarity.COMMON, mage.cards.a.AncestralAnger.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ancestral Anger", 394, Rarity.COMMON, mage.cards.a.AncestralAnger.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Ancestral Anger", 394, Rarity.COMMON, mage.cards.a.AncestralAnger.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Angel's Tomb", 253, Rarity.UNCOMMON, mage.cards.a.AngelsTomb.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Angel's Tomb", 438, Rarity.UNCOMMON, mage.cards.a.AngelsTomb.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Angelfire Ignition", 229, Rarity.RARE, mage.cards.a.AngelfireIgnition.class)); @@ -50,18 +52,13 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Archghoul of Thraben", 95, Rarity.UNCOMMON, mage.cards.a.ArchghoulOfThraben.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arlinn Kord", 230, Rarity.MYTHIC, mage.cards.a.ArlinnKord.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arlinn Kord", 324, Rarity.MYTHIC, mage.cards.a.ArlinnKord.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ashmouth Blade", 269, Rarity.UNCOMMON, mage.cards.a.AshmouthBlade.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Ashmouth Blade", 473, Rarity.UNCOMMON, mage.cards.a.AshmouthBlade.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Asylum Visitor", 371, Rarity.UNCOMMON, mage.cards.a.AsylumVisitor.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Asylum Visitor", 96, Rarity.UNCOMMON, mage.cards.a.AsylumVisitor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Avacyn, Angel of Hope", 477, Rarity.MYTHIC, mage.cards.a.AvacynAngelOfHope.class, RETRO_ART_USE_VARIOUS)); 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("Bane of Hanweir", 158, Rarity.COMMON, mage.cards.b.BaneOfHanweir.class)); 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)); cards.add(new SetCardInfo("Bedlam Reveler", 312, Rarity.RARE, mage.cards.b.BedlamReveler.class, NON_FULL_USE_VARIOUS)); @@ -74,22 +71,19 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Blood Artist", 372, Rarity.UNCOMMON, mage.cards.b.BloodArtist.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Blood Artist", 97, Rarity.UNCOMMON, mage.cards.b.BloodArtist.class, NON_FULL_USE_VARIOUS)); 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 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)); cards.add(new SetCardInfo("Bloodline Keeper", 98, Rarity.MYTHIC, mage.cards.b.BloodlineKeeper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodmad Vampire", 145, Rarity.COMMON, mage.cards.b.BloodmadVampire.class)); - cards.add(new SetCardInfo("Bloodsoaked Reveler", 128, Rarity.UNCOMMON, mage.cards.b.BloodsoakedReveler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Bloodsoaked Reveler", 463, Rarity.UNCOMMON, mage.cards.b.BloodsoakedReveler.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodtithe Harvester", 233, Rarity.UNCOMMON, mage.cards.b.BloodtitheHarvester.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodtithe Harvester", 427, Rarity.UNCOMMON, mage.cards.b.BloodtitheHarvester.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Boarded Window", 255, Rarity.UNCOMMON, mage.cards.b.BoardedWindow.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Boarded Window", 439, Rarity.UNCOMMON, mage.cards.b.BoardedWindow.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Borrowed Hostility", 146, Rarity.COMMON, mage.cards.b.BorrowedHostility.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Borrowed Hostility", 396, Rarity.COMMON, mage.cards.b.BorrowedHostility.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Borrowed Hostility", 396, Rarity.COMMON, mage.cards.b.BorrowedHostility.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Bound by Moonsilver", 13, Rarity.COMMON, mage.cards.b.BoundByMoonsilver.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bound by Moonsilver", 335, Rarity.COMMON, mage.cards.b.BoundByMoonsilver.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Bramble Wurm", 187, Rarity.COMMON, mage.cards.b.BrambleWurm.class, NON_FULL_USE_VARIOUS)); @@ -97,7 +91,7 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Brisela, Voice of Nightmares", "14b", Rarity.MYTHIC, mage.cards.b.BriselaVoiceOfNightmares.class)); cards.add(new SetCardInfo("Bruna, the Fading Light", 14, Rarity.RARE, mage.cards.b.BrunaTheFadingLight.class)); cards.add(new SetCardInfo("Burning Vengeance", 147, Rarity.UNCOMMON, mage.cards.b.BurningVengeance.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Burning Vengeance", 397, Rarity.UNCOMMON, mage.cards.b.BurningVengeance.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Burning Vengeance", 397, Rarity.UNCOMMON, mage.cards.b.BurningVengeance.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Butcher Ghoul", 373, Rarity.COMMON, mage.cards.b.ButcherGhoul.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Butcher Ghoul", 99, Rarity.COMMON, mage.cards.b.ButcherGhoul.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Butcher's Cleaver", 256, Rarity.UNCOMMON, mage.cards.b.ButchersCleaver.class, NON_FULL_USE_VARIOUS)); @@ -117,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)); @@ -154,7 +146,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Deadly Allure", 103, Rarity.UNCOMMON, mage.cards.d.DeadlyAllure.class)); cards.add(new SetCardInfo("Deathcap Glade", 275, Rarity.RARE, mage.cards.d.DeathcapGlade.class)); cards.add(new SetCardInfo("Decimator of the Provinces", 2, Rarity.RARE, mage.cards.d.DecimatorOfTheProvinces.class)); - cards.add(new SetCardInfo("Deluge of the Dead", 120, Rarity.RARE, mage.cards.d.DelugeOfTheDead.class)); cards.add(new SetCardInfo("Delver of Secrets", 457, Rarity.COMMON, mage.cards.d.DelverOfSecrets.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Delver of Secrets", 60, Rarity.COMMON, mage.cards.d.DelverOfSecrets.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Demonic Taskmaster", 104, Rarity.UNCOMMON, mage.cards.d.DemonicTaskmaster.class, NON_FULL_USE_VARIOUS)); @@ -189,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)); @@ -203,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)); @@ -216,7 +204,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Galvanic Juggernaut", 263, Rarity.UNCOMMON, mage.cards.g.GalvanicJuggernaut.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Galvanic Juggernaut", 443, Rarity.UNCOMMON, mage.cards.g.GalvanicJuggernaut.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Garruk Relentless", 197, Rarity.MYTHIC, mage.cards.g.GarrukRelentless.class)); - cards.add(new SetCardInfo("Garruk, the Veil-Cursed", 197, Rarity.MYTHIC, mage.cards.g.GarrukTheVeilCursed.class)); cards.add(new SetCardInfo("Gather the Townsfolk", 23, Rarity.COMMON, mage.cards.g.GatherTheTownsfolk.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gather the Townsfolk", 341, Rarity.COMMON, mage.cards.g.GatherTheTownsfolk.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Geier Reach Bandit", 156, Rarity.UNCOMMON, mage.cards.g.GeierReachBandit.class, NON_FULL_USE_VARIOUS)); @@ -237,13 +224,11 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Grapple with the Past", 199, Rarity.COMMON, mage.cards.g.GrappleWithThePast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grapple with the Past", 412, Rarity.COMMON, mage.cards.g.GrappleWithThePast.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Gravecrawler", 114, Rarity.RARE, mage.cards.g.Gravecrawler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Gravecrawler", 380, Rarity.RARE, mage.cards.g.Gravecrawler.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Gravecrawler", 380, Rarity.RARE, mage.cards.g.Gravecrawler.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Grimgrin, Corpse-Born", 239, Rarity.MYTHIC, mage.cards.g.GrimgrinCorpseBorn.class)); cards.add(new SetCardInfo("Griselbrand", 115, Rarity.MYTHIC, mage.cards.g.Griselbrand.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Griselbrand", 381, Rarity.MYTHIC, mage.cards.g.Griselbrand.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Griselbrand", 381, Rarity.MYTHIC, mage.cards.g.Griselbrand.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Griselbrand", 485, Rarity.MYTHIC, mage.cards.g.Griselbrand.class, FULL_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Grisly Anglerfish", 458, Rarity.UNCOMMON, mage.cards.g.GrislyAnglerfish.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Grisly Anglerfish", 67, Rarity.UNCOMMON, mage.cards.g.GrislyAnglerfish.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grizzled Angler", 458, Rarity.UNCOMMON, mage.cards.g.GrizzledAngler.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Grizzled Angler", 67, Rarity.UNCOMMON, mage.cards.g.GrizzledAngler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grizzly Ghoul", 240, Rarity.UNCOMMON, mage.cards.g.GrizzlyGhoul.class)); @@ -259,11 +244,11 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Hanweir, the Writhing Township", "157b", Rarity.RARE, mage.cards.h.HanweirTheWrithingTownship.class)); cards.add(new SetCardInfo("Harvest Hand", 265, Rarity.COMMON, mage.cards.h.HarvestHand.class)); cards.add(new SetCardInfo("Haunted Dead", 116, Rarity.UNCOMMON, mage.cards.h.HauntedDead.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Haunted Dead", 382, Rarity.UNCOMMON, mage.cards.h.HauntedDead.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Haunted Dead", 382, Rarity.UNCOMMON, mage.cards.h.HauntedDead.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Haunted Ridge", 280, Rarity.RARE, mage.cards.h.HauntedRidge.class)); cards.add(new SetCardInfo("Heartless Summoning", 117, Rarity.RARE, mage.cards.h.HeartlessSummoning.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Heartless Summoning", 309, Rarity.RARE, mage.cards.h.HeartlessSummoning.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Heartless Summoning", 383, Rarity.RARE, mage.cards.h.HeartlessSummoning.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Heartless Summoning", 383, Rarity.RARE, mage.cards.h.HeartlessSummoning.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Helvault", 266, Rarity.RARE, mage.cards.h.Helvault.class)); cards.add(new SetCardInfo("Hermit Druid", 202, Rarity.RARE, mage.cards.h.HermitDruid.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hermit Druid", 488, Rarity.RARE, mage.cards.h.HermitDruid.class, FULL_ART_USE_VARIOUS)); @@ -271,10 +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 Alpha", 207, Rarity.RARE, mage.cards.h.HowlpackAlpha.class)); - 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)); @@ -285,13 +266,11 @@ 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("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)); cards.add(new SetCardInfo("Infernal Grasp", 310, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Infernal Grasp", 385, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Infernal Grasp", 385, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Inspiring Captain", 28, Rarity.COMMON, mage.cards.i.InspiringCaptain.class)); cards.add(new SetCardInfo("Intangible Virtue", 29, Rarity.UNCOMMON, mage.cards.i.IntangibleVirtue.class)); cards.add(new SetCardInfo("Intrepid Provisioner", 205, Rarity.COMMON, mage.cards.i.IntrepidProvisioner.class)); @@ -304,25 +283,22 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Join the Dance", 242, Rarity.UNCOMMON, mage.cards.j.JoinTheDance.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Join the Dance", 432, Rarity.UNCOMMON, mage.cards.j.JoinTheDance.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Killing Wave", 121, Rarity.UNCOMMON, mage.cards.k.KillingWave.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Killing Wave", 386, Rarity.UNCOMMON, mage.cards.k.KillingWave.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Killing Wave", 386, Rarity.UNCOMMON, mage.cards.k.KillingWave.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Kruin Outlaw", 161, Rarity.RARE, mage.cards.k.KruinOutlaw.class)); cards.add(new SetCardInfo("Laboratory Maniac", 304, Rarity.UNCOMMON, mage.cards.l.LaboratoryManiac.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Laboratory Maniac", 359, Rarity.UNCOMMON, mage.cards.l.LaboratoryManiac.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Laboratory Maniac", 71, Rarity.UNCOMMON, mage.cards.l.LaboratoryManiac.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lantern Bearer", 72, Rarity.COMMON, mage.cards.l.LanternBearer.class)); - cards.add(new SetCardInfo("Lanterns' Lift", 72, Rarity.COMMON, mage.cards.l.LanternsLift.class)); cards.add(new SetCardInfo("Liesa, Forgotten Archangel", 243, Rarity.RARE, mage.cards.l.LiesaForgottenArchangel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Liesa, Forgotten Archangel", 433, Rarity.RARE, mage.cards.l.LiesaForgottenArchangel.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Lightning Axe", 162, Rarity.UNCOMMON, mage.cards.l.LightningAxe.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Lightning Axe", 398, Rarity.UNCOMMON, mage.cards.l.LightningAxe.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Lightning Axe", 398, Rarity.UNCOMMON, mage.cards.l.LightningAxe.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Lightning Mauler", 163, Rarity.UNCOMMON, mage.cards.l.LightningMauler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Lightning Mauler", 399, Rarity.UNCOMMON, mage.cards.l.LightningMauler.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Lightning Mauler", 399, Rarity.UNCOMMON, mage.cards.l.LightningMauler.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Liliana of the Veil", 475, Rarity.MYTHIC, mage.cards.l.LilianaOfTheVeil.class, RETRO_ART)); cards.add(new SetCardInfo("Lingering Souls", 30, Rarity.UNCOMMON, mage.cards.l.LingeringSouls.class)); cards.add(new SetCardInfo("Lumberknot", 206, Rarity.UNCOMMON, mage.cards.l.Lumberknot.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lumberknot", 414, Rarity.UNCOMMON, mage.cards.l.Lumberknot.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Luminous Phantom", 32, Rarity.COMMON, mage.cards.l.LuminousPhantom.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Luminous Phantom", 450, Rarity.COMMON, mage.cards.l.LuminousPhantom.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Lunarch Mantle", 31, Rarity.COMMON, mage.cards.l.LunarchMantle.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lunarch Mantle", 344, Rarity.COMMON, mage.cards.l.LunarchMantle.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Lunarch Veteran", 32, Rarity.COMMON, mage.cards.l.LunarchVeteran.class, NON_FULL_USE_VARIOUS)); @@ -351,12 +327,8 @@ 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("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)); cards.add(new SetCardInfo("Mountain", 294, Rarity.LAND, mage.cards.basiclands.Mountain.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 295, Rarity.LAND, mage.cards.basiclands.Mountain.class, RETRO_ART_USE_VARIOUS)); @@ -379,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)); @@ -405,13 +375,12 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Savage Alliance", 169, Rarity.UNCOMMON, mage.cards.s.SavageAlliance.class)); cards.add(new SetCardInfo("Scorned Villager", 212, Rarity.COMMON, mage.cards.s.ScornedVillager.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Scorned Villager", 468, Rarity.COMMON, mage.cards.s.ScornedVillager.class, RETRO_ART_USE_VARIOUS)); - cards.add(new SetCardInfo("Scrounged Scythe", 265, Rarity.COMMON, mage.cards.s.ScroungedScythe.class)); cards.add(new SetCardInfo("Second Harvest", 213, Rarity.RARE, mage.cards.s.SecondHarvest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Second Harvest", 417, Rarity.RARE, mage.cards.s.SecondHarvest.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Seize the Storm", 170, Rarity.COMMON, mage.cards.s.SeizeTheStorm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Seize the Storm", 401, Rarity.COMMON, mage.cards.s.SeizeTheStorm.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Sever the Bloodline", 130, Rarity.UNCOMMON, mage.cards.s.SeverTheBloodline.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sever the Bloodline", 389, Rarity.UNCOMMON, mage.cards.s.SeverTheBloodline.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Sever the Bloodline", 389, Rarity.UNCOMMON, mage.cards.s.SeverTheBloodline.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Shattered Sanctum", 283, Rarity.RARE, mage.cards.s.ShatteredSanctum.class)); cards.add(new SetCardInfo("Shipwreck Marsh", 284, Rarity.RARE, mage.cards.s.ShipwreckMarsh.class)); cards.add(new SetCardInfo("Shrill Howler", 214, Rarity.UNCOMMON, mage.cards.s.ShrillHowler.class, NON_FULL_USE_VARIOUS)); @@ -467,7 +436,6 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Tamiyo, Field Researcher", 249, Rarity.MYTHIC, mage.cards.t.TamiyoFieldResearcher.class)); cards.add(new SetCardInfo("Temporal Mastery", 307, Rarity.MYTHIC, mage.cards.t.TemporalMastery.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Temporal Mastery", 90, Rarity.MYTHIC, mage.cards.t.TemporalMastery.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Terror of Kruin Pass", 161, Rarity.RARE, mage.cards.t.TerrorOfKruinPass.class)); cards.add(new SetCardInfo("Thalia, Heretic Cathar", 300, Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thalia, Heretic Cathar", 351, Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Thalia, Heretic Cathar", 44, Rarity.RARE, mage.cards.t.ThaliaHereticCathar.class, NON_FULL_USE_VARIOUS)); @@ -475,7 +443,7 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("The Gitrog Monster", 431, Rarity.MYTHIC, mage.cards.t.TheGitrogMonster.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("The Gitrog Monster", 489, Rarity.MYTHIC, mage.cards.t.TheGitrogMonster.class, FULL_ART_USE_VARIOUS)); cards.add(new SetCardInfo("The Meathook Massacre", 122, Rarity.MYTHIC, mage.cards.t.TheMeathookMassacre.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Meathook Massacre", 387, Rarity.MYTHIC, mage.cards.t.TheMeathookMassacre.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("The Meathook Massacre", 387, Rarity.MYTHIC, mage.cards.t.TheMeathookMassacre.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("The Meathook Massacre", 486, Rarity.MYTHIC, mage.cards.t.TheMeathookMassacre.class, FULL_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Thermo-Alchemist", 174, Rarity.UNCOMMON, mage.cards.t.ThermoAlchemist.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thermo-Alchemist", 403, Rarity.UNCOMMON, mage.cards.t.ThermoAlchemist.class, RETRO_ART_USE_VARIOUS)); @@ -495,7 +463,7 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Town Gossipmonger", 451, Rarity.UNCOMMON, mage.cards.t.TownGossipmonger.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Town Gossipmonger", 46, Rarity.UNCOMMON, mage.cards.t.TownGossipmonger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tragic Slip", 134, Rarity.COMMON, mage.cards.t.TragicSlip.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Tragic Slip", 390, Rarity.COMMON, mage.cards.t.TragicSlip.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Tragic Slip", 390, Rarity.COMMON, mage.cards.t.TragicSlip.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Travel Preparations", 220, Rarity.UNCOMMON, mage.cards.t.TravelPreparations.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Travel Preparations", 421, Rarity.UNCOMMON, mage.cards.t.TravelPreparations.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Traveler's Amulet", 273, Rarity.COMMON, mage.cards.t.TravelersAmulet.class)); @@ -503,11 +471,9 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Traverse the Ulvenwald", 422, Rarity.RARE, mage.cards.t.TraverseTheUlvenwald.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Tree of Perdition", 135, Rarity.RARE, mage.cards.t.TreeOfPerdition.class)); cards.add(new SetCardInfo("Triskaidekaphobia", 136, Rarity.UNCOMMON, mage.cards.t.Triskaidekaphobia.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Triskaidekaphobia", 391, Rarity.UNCOMMON, mage.cards.t.Triskaidekaphobia.class,RETRO_ART_USE_VARIOUS)); + 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)); @@ -519,14 +485,12 @@ public class InnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Vanquish the Horde", 49, Rarity.RARE, mage.cards.v.VanquishTheHorde.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vexing Devil", 178, Rarity.RARE, mage.cards.v.VexingDevil.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vexing Devil", 313, Rarity.RARE, mage.cards.v.VexingDevil.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vildin-Pack Alpha", 156, Rarity.UNCOMMON, mage.cards.v.VildinPackAlpha.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vildin-Pack Alpha", 464, Rarity.UNCOMMON, mage.cards.v.VildinPackAlpha.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Vilespawn Spider", 251, Rarity.UNCOMMON, mage.cards.v.VilespawnSpider.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Vilespawn Spider", 436, Rarity.UNCOMMON, mage.cards.v.VilespawnSpider.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Village Messenger", 179, Rarity.COMMON, mage.cards.v.VillageMessenger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Village Messenger", 466, Rarity.COMMON, mage.cards.v.VillageMessenger.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Village Rites", 137, Rarity.COMMON, mage.cards.v.VillageRites.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Village Rites", 392, Rarity.COMMON, mage.cards.v.VillageRites.class,RETRO_ART_USE_VARIOUS)); + cards.add(new SetCardInfo("Village Rites", 392, Rarity.COMMON, mage.cards.v.VillageRites.class, RETRO_ART_USE_VARIOUS)); cards.add(new SetCardInfo("Villagers of Estwald", 224, Rarity.COMMON, mage.cards.v.VillagersOfEstwald.class)); cards.add(new SetCardInfo("Voice of the Blessed", 50, Rarity.RARE, mage.cards.v.VoiceOfTheBlessed.class)); cards.add(new SetCardInfo("Voldaren Ambusher", 180, Rarity.UNCOMMON, mage.cards.v.VoldarenAmbusher.class)); @@ -538,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 ac805618e76..00048cbae25 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -36,7 +36,6 @@ public final class Ixalan extends ExpansionSet { this.numBoosterDoubleFaced = -1; this.maxCardNumberInBooster = 279; - cards.add(new SetCardInfo("Adanto, the First Fort", 22, Rarity.RARE, mage.cards.a.AdantoTheFirstFort.class)); cards.add(new SetCardInfo("Adanto Vanguard", 1, Rarity.UNCOMMON, mage.cards.a.AdantoVanguard.class)); cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Air Elemental", 45, Rarity.UNCOMMON, mage.cards.a.AirElemental.class)); @@ -48,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)); @@ -157,7 +155,6 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Island", 265, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Ixalli's Diviner", 192, Rarity.COMMON, mage.cards.i.IxallisDiviner.class)); cards.add(new SetCardInfo("Ixalli's Keeper", 193, Rarity.COMMON, mage.cards.i.IxallisKeeper.class)); @@ -210,7 +207,6 @@ public final class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Pounce", 200, Rarity.COMMON, mage.cards.p.Pounce.class)); cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); - cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Prying Blade", 244, Rarity.COMMON, mage.cards.p.PryingBlade.class)); cards.add(new SetCardInfo("Pterodon Knight", 28, Rarity.COMMON, mage.cards.p.PterodonKnight.class)); @@ -273,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)); @@ -306,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 0c55b5ea44a..7f08fba3205 100644 --- a/Mage.Sets/src/mage/sets/IxalanPromos.java +++ b/Mage.Sets/src/mage/sets/IxalanPromos.java @@ -20,7 +20,6 @@ public class IxalanPromos extends ExpansionSet { this.hasBoosters = false; this.hasBasicLands = false; - cards.add(new SetCardInfo("Adanto, the First Fort", "22s", Rarity.RARE, mage.cards.a.AdantoTheFirstFort.class)); cards.add(new SetCardInfo("Admiral Beckett Brass", "217s", Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", "132s", Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Arcane Adaptation", "46p", Rarity.RARE, mage.cards.a.ArcaneAdaptation.class, NON_FULL_USE_VARIOUS)); @@ -29,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)); @@ -74,7 +72,6 @@ public class IxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Herald of Secret Streams", "59s", Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hostage Taker", "223s", Rarity.RARE, mage.cards.h.HostageTaker.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", "224s", Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); - cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", "191s", Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", "60s", Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Kinjalli's Sunwing", "19p", Rarity.RARE, mage.cards.k.KinjallisSunwing.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kinjalli's Sunwing", "19s", Rarity.RARE, mage.cards.k.KinjallisSunwing.class, NON_FULL_USE_VARIOUS)); @@ -87,7 +84,6 @@ public class IxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Overflowing Insight", "66s", Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Priest of the Wakening Sun", "27s", Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", "243s", Rarity.RARE, mage.cards.p.PrimalAmulet.class)); - cards.add(new SetCardInfo("Primal Wellspring", "243s", Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Rampaging Ferocidon", "154s", Rarity.RARE, mage.cards.r.RampagingFerocidon.class)); cards.add(new SetCardInfo("Regisaur Alpha", "227p", Rarity.RARE, mage.cards.r.RegisaurAlpha.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Regisaur Alpha", "227s", Rarity.RARE, mage.cards.r.RegisaurAlpha.class, NON_FULL_USE_VARIOUS)); @@ -116,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)); @@ -131,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)); @@ -147,5 +140,5 @@ public class IxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Wakening Sun's Avatar", "44s", Rarity.MYTHIC, mage.cards.w.WakeningSunsAvatar.class)); cards.add(new SetCardInfo("Waker of the Wilds", "215s", Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); - } + } } diff --git a/Mage.Sets/src/mage/sets/JudgeGiftCards2021.java b/Mage.Sets/src/mage/sets/JudgeGiftCards2021.java index efe4cd6675d..701106b1162 100644 --- a/Mage.Sets/src/mage/sets/JudgeGiftCards2021.java +++ b/Mage.Sets/src/mage/sets/JudgeGiftCards2021.java @@ -27,7 +27,6 @@ public class JudgeGiftCards2021 extends ExpansionSet { cards.add(new SetCardInfo("K'rrik, Son of Yawgmoth", 2, Rarity.RARE, mage.cards.k.KrrikSonOfYawgmoth.class)); cards.add(new SetCardInfo("Mizzix of the Izmagnus", 8, Rarity.MYTHIC, mage.cards.m.MizzixOfTheIzmagnus.class)); cards.add(new SetCardInfo("Morophon, the Boundless", 1, Rarity.MYTHIC, mage.cards.m.MorophonTheBoundless.class)); - cards.add(new SetCardInfo("Nicol Bolas, the Arisen", 9, Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.class)); cards.add(new SetCardInfo("Nicol Bolas, the Ravager", 9, Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class)); cards.add(new SetCardInfo("The Gitrog Monster", 5, Rarity.MYTHIC, mage.cards.t.TheGitrogMonster.class)); cards.add(new SetCardInfo("Zacama, Primal Calamity", 10, Rarity.MYTHIC, mage.cards.z.ZacamaPrimalCalamity.class)); diff --git a/Mage.Sets/src/mage/sets/JudgeGiftCards2022.java b/Mage.Sets/src/mage/sets/JudgeGiftCards2022.java index 9ac65f709f6..d17992860c3 100644 --- a/Mage.Sets/src/mage/sets/JudgeGiftCards2022.java +++ b/Mage.Sets/src/mage/sets/JudgeGiftCards2022.java @@ -23,7 +23,6 @@ public class JudgeGiftCards2022 extends ExpansionSet { cards.add(new SetCardInfo("Animate Dead", 7, Rarity.RARE, mage.cards.a.AnimateDead.class, RETRO_ART)); cards.add(new SetCardInfo("Greater Auramancy", 1, Rarity.RARE, mage.cards.g.GreaterAuramancy.class)); cards.add(new SetCardInfo("Growing Rites of Itlimoc", 10, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class)); - cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 10, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class)); cards.add(new SetCardInfo("No Mercy", 9, Rarity.RARE, mage.cards.n.NoMercy.class)); cards.add(new SetCardInfo("Omniscience", 2, Rarity.RARE, mage.cards.o.Omniscience.class)); cards.add(new SetCardInfo("Parallel Lives", 3, Rarity.RARE, mage.cards.p.ParallelLives.class)); diff --git a/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java b/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java index b2c2b9b6e99..08b6d104555 100644 --- a/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java +++ b/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java @@ -170,7 +170,6 @@ public final class JumpstartHistoricHorizons extends ExpansionSet { cards.add(new SetCardInfo("Haunted Dead", 336, Rarity.UNCOMMON, mage.cards.h.HauntedDead.class)); cards.add(new SetCardInfo("Healer's Flock", 91, Rarity.UNCOMMON, mage.cards.h.HealersFlock.class)); cards.add(new SetCardInfo("Heir of Falkenrath", 338, Rarity.UNCOMMON, mage.cards.h.HeirOfFalkenrath.class)); - cards.add(new SetCardInfo("Heir to the Night", 338, Rarity.UNCOMMON, mage.cards.h.HeirToTheNight.class)); cards.add(new SetCardInfo("Hell Mongrel", 339, Rarity.COMMON, mage.cards.h.HellMongrel.class)); cards.add(new SetCardInfo("Herd Baloth", 584, Rarity.UNCOMMON, mage.cards.h.HerdBaloth.class)); cards.add(new SetCardInfo("Hive Stirrings", 94, Rarity.COMMON, mage.cards.h.HiveStirrings.class)); @@ -378,7 +377,6 @@ public final class JumpstartHistoricHorizons extends ExpansionSet { cards.add(new SetCardInfo("Warteye Witch", 404, Rarity.COMMON, mage.cards.w.WarteyeWitch.class)); cards.add(new SetCardInfo("Wavesifter", 726, Rarity.COMMON, mage.cards.w.Wavesifter.class)); cards.add(new SetCardInfo("Webweaver Changeling", 666, Rarity.UNCOMMON, mage.cards.w.WebweaverChangeling.class)); - cards.add(new SetCardInfo("Westvale Cult Leader", 90, Rarity.RARE, mage.cards.w.WestvaleCultLeader.class)); cards.add(new SetCardInfo("Windcaller Aven", 275, Rarity.COMMON, mage.cards.w.WindcallerAven.class)); cards.add(new SetCardInfo("Winding Way", 670, Rarity.COMMON, mage.cards.w.WindingWay.class)); cards.add(new SetCardInfo("Winged Shepherd", 158, Rarity.COMMON, mage.cards.w.WingedShepherd.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 5a166126a18..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)); @@ -144,7 +134,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Enthusiastic Mechanaut", 509, Rarity.UNCOMMON, mage.cards.e.EnthusiasticMechanaut.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Era of Enlightenment", 11, Rarity.COMMON, mage.cards.e.EraOfEnlightenment.class)); cards.add(new SetCardInfo("Essence Capture", 52, Rarity.UNCOMMON, mage.cards.e.EssenceCapture.class)); - cards.add(new SetCardInfo("Etching of Kumano", 152, Rarity.UNCOMMON, mage.cards.e.EtchingOfKumano.class)); cards.add(new SetCardInfo("Experimental Synthesizer", 138, Rarity.COMMON, mage.cards.e.ExperimentalSynthesizer.class)); cards.add(new SetCardInfo("Explosive Entry", 139, Rarity.COMMON, mage.cards.e.ExplosiveEntry.class)); cards.add(new SetCardInfo("Explosive Singularity", 140, Rarity.MYTHIC, mage.cards.e.ExplosiveSingularity.class, NON_FULL_USE_VARIOUS)); @@ -167,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)); @@ -284,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)); @@ -312,9 +297,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Lion Sash", 26, Rarity.RARE, mage.cards.l.LionSash.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lion Sash", 368, Rarity.RARE, mage.cards.l.LionSash.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lion Sash", 440, Rarity.RARE, mage.cards.l.LionSash.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Living Breakthrough", 355, Rarity.RARE, mage.cards.l.LivingBreakthrough.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Living Breakthrough", 443, Rarity.RARE, mage.cards.l.LivingBreakthrough.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Living Breakthrough", 57, Rarity.RARE, mage.cards.l.LivingBreakthrough.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lizard Blades", 153, Rarity.RARE, mage.cards.l.LizardBlades.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lizard Blades", 385, Rarity.RARE, mage.cards.l.LizardBlades.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lizard Blades", 468, Rarity.RARE, mage.cards.l.LizardBlades.class, NON_FULL_USE_VARIOUS)); @@ -340,7 +322,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Mechtitan Core", 249, Rarity.RARE, mage.cards.m.MechtitanCore.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mechtitan Core", 402, Rarity.RARE, mage.cards.m.MechtitanCore.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mechtitan Core", 497, Rarity.RARE, mage.cards.m.MechtitanCore.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Memory of Toshiro", 108, Rarity.UNCOMMON, mage.cards.m.MemoryOfToshiro.class)); cards.add(new SetCardInfo("Michiko's Reign of Truth", 29, Rarity.UNCOMMON, mage.cards.m.MichikosReignOfTruth.class)); cards.add(new SetCardInfo("Mindlink Mech", 373, Rarity.RARE, mage.cards.m.MindlinkMech.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mindlink Mech", 448, Rarity.RARE, mage.cards.m.MindlinkMech.class, NON_FULL_USE_VARIOUS)); @@ -367,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)); @@ -379,13 +359,9 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Nezumi Bladeblesser", 318, Rarity.COMMON, mage.cards.n.NezumiBladeblesser.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nezumi Prowler", 116, Rarity.UNCOMMON, mage.cards.n.NezumiProwler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nezumi Prowler", 344, Rarity.UNCOMMON, mage.cards.n.NezumiProwler.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Nezumi Road Captain", 117, Rarity.COMMON, mage.cards.n.NezumiRoadCaptain.class)); 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)); @@ -405,7 +381,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Plains", 293, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_UST_VARIOUS)); cards.add(new SetCardInfo("Plains", 294, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_UST_VARIOUS)); cards.add(new SetCardInfo("Planar Incision", 72, Rarity.COMMON, mage.cards.p.PlanarIncision.class)); - cards.add(new SetCardInfo("Portrait of Michiko", 29, Rarity.UNCOMMON, mage.cards.p.PortraitOfMichiko.class)); cards.add(new SetCardInfo("Prodigy's Prototype", 231, Rarity.UNCOMMON, mage.cards.p.ProdigysPrototype.class)); cards.add(new SetCardInfo("Prosperous Thief", 336, Rarity.UNCOMMON, mage.cards.p.ProsperousThief.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Prosperous Thief", 73, Rarity.UNCOMMON, mage.cards.p.ProsperousThief.class, NON_FULL_USE_VARIOUS)); @@ -419,16 +394,10 @@ public final class KamigawaNeonDynasty extends ExpansionSet { cards.add(new SetCardInfo("Reckoner Bankbuster", 499, Rarity.RARE, mage.cards.r.ReckonerBankbuster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reckoner Shakedown", 119, Rarity.COMMON, mage.cards.r.ReckonerShakedown.class)); cards.add(new SetCardInfo("Reckoner's Bargain", 120, Rarity.COMMON, mage.cards.r.ReckonersBargain.class)); - cards.add(new SetCardInfo("Reflection of Kiki-Jiki", 141, Rarity.RARE, mage.cards.r.ReflectionOfKikiJiki.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Reflection of Kiki-Jiki", 357, Rarity.RARE, mage.cards.r.ReflectionOfKikiJiki.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Reflection of Kiki-Jiki", 465, Rarity.RARE, mage.cards.r.ReflectionOfKikiJiki.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Regent's Authority", 32, Rarity.COMMON, mage.cards.r.RegentsAuthority.class)); cards.add(new SetCardInfo("Reinforced Ronin", 158, Rarity.UNCOMMON, mage.cards.r.ReinforcedRonin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reinforced Ronin", 323, Rarity.UNCOMMON, mage.cards.r.ReinforcedRonin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reito Sentinel", 256, Rarity.UNCOMMON, mage.cards.r.ReitoSentinel.class)); - cards.add(new SetCardInfo("Remnant of the Rising Star", 194, Rarity.MYTHIC, mage.cards.r.RemnantOfTheRisingStar.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Remnant of the Rising Star", 359, Rarity.MYTHIC, mage.cards.r.RemnantOfTheRisingStar.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Remnant of the Rising Star", 475, Rarity.MYTHIC, mage.cards.r.RemnantOfTheRisingStar.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Repel the Vile", 33, Rarity.COMMON, mage.cards.r.RepelTheVile.class)); cards.add(new SetCardInfo("Replication Specialist", 76, Rarity.UNCOMMON, mage.cards.r.ReplicationSpecialist.class)); cards.add(new SetCardInfo("Return to Action", 121, Rarity.COMMON, mage.cards.r.ReturnToAction.class)); @@ -461,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)); @@ -573,10 +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("Vessel of the All-Consuming", 221, Rarity.MYTHIC, mage.cards.v.VesselOfTheAllConsuming.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vessel of the All-Consuming", 361, Rarity.MYTHIC, mage.cards.v.VesselOfTheAllConsuming.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Vessel of the All-Consuming", 486, Rarity.MYTHIC, mage.cards.v.VesselOfTheAllConsuming.class, NON_FULL_USE_VARIOUS)); 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..f3d695adb93 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -18,40 +18,235 @@ public final class LorwynEclipsed extends ExpansionSet { private LorwynEclipsed() { super("Lorwyn Eclipsed", "ECL", ExpansionSet.buildDate(2026, 1, 23), SetType.EXPANSION); this.blockName = "Lorwyn Eclipsed"; // for sorting in GUI - this.hasBasicLands = false; // temporary + this.hasBasicLands = true; + cards.add(new SetCardInfo("Abigale, Eloquent First-Year", 204, Rarity.RARE, mage.cards.a.AbigaleEloquentFirstYear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Abigale, Eloquent First-Year", 368, Rarity.RARE, mage.cards.a.AbigaleEloquentFirstYear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Appeal to Eirdu", 5, Rarity.COMMON, mage.cards.a.AppealToEirdu.class)); + cards.add(new SetCardInfo("Aquitect's Defenses", 44, Rarity.COMMON, mage.cards.a.AquitectsDefenses.class)); 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("Assert Perfection", 164, Rarity.COMMON, mage.cards.a.AssertPerfection.class)); + cards.add(new SetCardInfo("Aurora Awakener", 165, Rarity.MYTHIC, mage.cards.a.AuroraAwakener.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Aurora Awakener", 323, Rarity.MYTHIC, mage.cards.a.AuroraAwakener.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bile-Vial Boggart", 87, Rarity.COMMON, mage.cards.b.BileVialBoggart.class)); 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("Blighted Blackthorn", 90, Rarity.COMMON, mage.cards.b.BlightedBlackthorn.class)); + 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("Bloodline Bidding", 359, Rarity.RARE, mage.cards.b.BloodlineBidding.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloodline Bidding", 385, Rarity.MYTHIC, mage.cards.b.BloodlineBidding.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloodline Bidding", 395, Rarity.MYTHIC, mage.cards.b.BloodlineBidding.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloodline Bidding", 91, Rarity.RARE, mage.cards.b.BloodlineBidding.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloom Tender", 166, Rarity.MYTHIC, mage.cards.b.BloomTender.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloom Tender", 324, Rarity.MYTHIC, mage.cards.b.BloomTender.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloom Tender", 390, Rarity.MYTHIC, mage.cards.b.BloomTender.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bloom Tender", 400, Rarity.MYTHIC, mage.cards.b.BloomTender.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Blossoming Defense", 167, Rarity.UNCOMMON, mage.cards.b.BlossomingDefense.class)); + cards.add(new SetCardInfo("Boggart Mischief", 92, Rarity.UNCOMMON, mage.cards.b.BoggartMischief.class)); + cards.add(new SetCardInfo("Boldwyr Aggressor", 125, Rarity.UNCOMMON, mage.cards.b.BoldwyrAggressor.class)); + cards.add(new SetCardInfo("Boneclub Berserker", 126, Rarity.COMMON, mage.cards.b.BoneclubBerserker.class)); + cards.add(new SetCardInfo("Brigid's Command", 208, Rarity.RARE, mage.cards.b.BrigidsCommand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Brigid's Command", 332, Rarity.RARE, mage.cards.b.BrigidsCommand.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bristlebane Battler", 168, Rarity.RARE, mage.cards.b.BristlebaneBattler.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bristlebane Battler", 325, Rarity.RARE, mage.cards.b.BristlebaneBattler.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Burdened Stoneback", 8, Rarity.UNCOMMON, mage.cards.b.BurdenedStoneback.class)); + cards.add(new SetCardInfo("Burning Curiosity", 129, Rarity.COMMON, mage.cards.b.BurningCuriosity.class)); + cards.add(new SetCardInfo("Champion of the Clachan", 353, Rarity.RARE, mage.cards.c.ChampionOfTheClachan.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Champion of the Clachan", 9, Rarity.RARE, mage.cards.c.ChampionOfTheClachan.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Champion of the Weird", 360, Rarity.RARE, mage.cards.c.ChampionOfTheWeird.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Champion of the Weird", 95, Rarity.RARE, mage.cards.c.ChampionOfTheWeird.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Champions of the Perfect", 171, Rarity.RARE, mage.cards.c.ChampionsOfThePerfect.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Champions of the Perfect", 365, Rarity.RARE, mage.cards.c.ChampionsOfThePerfect.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Chaos Spewer", 210, Rarity.COMMON, mage.cards.c.ChaosSpewer.class)); + cards.add(new SetCardInfo("Chitinous Graspling", 211, Rarity.COMMON, mage.cards.c.ChitinousGraspling.class)); + cards.add(new SetCardInfo("Chomping Changeling", 172, Rarity.UNCOMMON, mage.cards.c.ChompingChangeling.class)); + cards.add(new SetCardInfo("Clachan Festival", 10, Rarity.UNCOMMON, mage.cards.c.ClachanFestival.class)); + cards.add(new SetCardInfo("Crib Swap", 11, Rarity.UNCOMMON, mage.cards.c.CribSwap.class)); + cards.add(new SetCardInfo("Crossroads Watcher", 173, Rarity.COMMON, mage.cards.c.CrossroadsWatcher.class)); + cards.add(new SetCardInfo("Darkness Descends", 97, Rarity.UNCOMMON, mage.cards.d.DarknessDescends.class)); + cards.add(new SetCardInfo("Dawn's Light Archer", 174, Rarity.COMMON, mage.cards.d.DawnsLightArcher.class)); + cards.add(new SetCardInfo("Dawnhand Eulogist", 99, Rarity.COMMON, mage.cards.d.DawnhandEulogist.class)); 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("Disruptor of Currents", 303, Rarity.RARE, mage.cards.d.DisruptorOfCurrents.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Disruptor of Currents", 47, Rarity.RARE, mage.cards.d.DisruptorOfCurrents.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Doran, Besieged by Time", 215, Rarity.RARE, mage.cards.d.DoranBesiegedByTime.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Doran, Besieged by Time", 334, Rarity.RARE, mage.cards.d.DoranBesiegedByTime.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Dose of Dawnglow", 100, Rarity.UNCOMMON, mage.cards.d.DoseOfDawnglow.class)); + cards.add(new SetCardInfo("Dream Seizer", 101, Rarity.COMMON, mage.cards.d.DreamSeizer.class)); + cards.add(new SetCardInfo("Dundoolin Weaver", 175, Rarity.UNCOMMON, mage.cards.d.DundoolinWeaver.class)); + cards.add(new SetCardInfo("Eclipsed Flamekin", 219, Rarity.UNCOMMON, mage.cards.e.EclipsedFlamekin.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Eclipsed Flamekin", 337, Rarity.UNCOMMON, mage.cards.e.EclipsedFlamekin.class, NON_FULL_USE_VARIOUS)); 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("Elder Auntie", 133, Rarity.COMMON, mage.cards.e.ElderAuntie.class)); cards.add(new SetCardInfo("Emptiness", 222, Rarity.MYTHIC, mage.cards.e.Emptiness.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Emptiness", 294, Rarity.MYTHIC, mage.cards.e.Emptiness.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Enraged Flamecaster", 135, Rarity.COMMON, mage.cards.e.EnragedFlamecaster.class)); + cards.add(new SetCardInfo("Evolving Wilds", 264, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); + cards.add(new SetCardInfo("Explosive Prodigy", 136, Rarity.UNCOMMON, mage.cards.e.ExplosiveProdigy.class)); cards.add(new SetCardInfo("Figure of Fable", 224, Rarity.RARE, mage.cards.f.FigureOfFable.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Figure of Fable", 372, Rarity.RARE, mage.cards.f.FigureOfFable.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Flame-Chain Mauler", 138, Rarity.COMMON, mage.cards.f.FlameChainMauler.class)); + cards.add(new SetCardInfo("Flamebraider", 139, Rarity.UNCOMMON, mage.cards.f.Flamebraider.class)); + cards.add(new SetCardInfo("Flamekin Gildweaver", 140, Rarity.COMMON, mage.cards.f.FlamekinGildweaver.class)); + cards.add(new SetCardInfo("Flock Impostor", 16, Rarity.UNCOMMON, mage.cards.f.FlockImpostor.class)); + cards.add(new SetCardInfo("Forest", 273, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Forest", 283, Rarity.LAND, mage.cards.basiclands.Forest.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("Gallant Fowlknight", 17, Rarity.COMMON, mage.cards.g.GallantFowlknight.class)); + cards.add(new SetCardInfo("Gangly Stompling", 226, Rarity.COMMON, mage.cards.g.GanglyStompling.class)); + cards.add(new SetCardInfo("Glamer Gifter", 49, Rarity.UNCOMMON, mage.cards.g.GlamerGifter.class)); + cards.add(new SetCardInfo("Glister Bairn", 227, Rarity.UNCOMMON, mage.cards.g.GlisterBairn.class)); + cards.add(new SetCardInfo("Gnarlbark Elm", 103, Rarity.UNCOMMON, mage.cards.g.GnarlbarkElm.class)); + cards.add(new SetCardInfo("Goatnap", 142, Rarity.UNCOMMON, mage.cards.g.Goatnap.class)); + cards.add(new SetCardInfo("Goldmeadow Nomad", 18, Rarity.COMMON, mage.cards.g.GoldmeadowNomad.class)); + cards.add(new SetCardInfo("Gravelgill Scoundrel", 53, Rarity.COMMON, mage.cards.g.GravelgillScoundrel.class)); + cards.add(new SetCardInfo("Graveshifter", 104, Rarity.UNCOMMON, mage.cards.g.Graveshifter.class)); + cards.add(new SetCardInfo("Great Forest Druid", 178, Rarity.COMMON, mage.cards.g.GreatForestDruid.class)); + cards.add(new SetCardInfo("Gristle Glutton", 144, Rarity.COMMON, mage.cards.g.GristleGlutton.class)); + cards.add(new SetCardInfo("Grub, Storied Matriarch", 105, Rarity.RARE, mage.cards.g.GrubStoriedMatriarch.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Grub, Storied Matriarch", 289, Rarity.RARE, mage.cards.g.GrubStoriedMatriarch.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Gutsplitter Gang", 106, Rarity.UNCOMMON, mage.cards.g.GutsplitterGang.class)); + 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("Harmonized Crescendo", 357, Rarity.RARE, mage.cards.h.HarmonizedCrescendo.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Harmonized Crescendo", 384, Rarity.MYTHIC, mage.cards.h.HarmonizedCrescendo.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Harmonized Crescendo", 394, Rarity.MYTHIC, mage.cards.h.HarmonizedCrescendo.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Harmonized Crescendo", 408, Rarity.RARE, mage.cards.h.HarmonizedCrescendo.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Harmonized Crescendo", 54, Rarity.RARE, mage.cards.h.HarmonizedCrescendo.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Heirloom Auntie", 107, Rarity.COMMON, mage.cards.h.HeirloomAuntie.class)); + cards.add(new SetCardInfo("Hexing Squelcher", 145, Rarity.RARE, mage.cards.h.HexingSquelcher.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Hexing Squelcher", 317, Rarity.RARE, mage.cards.h.HexingSquelcher.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("Hovel Hurler", 230, Rarity.UNCOMMON, mage.cards.h.HovelHurler.class)); + cards.add(new SetCardInfo("Impolite Entrance", 146, Rarity.UNCOMMON, mage.cards.i.ImpoliteEntrance.class)); + cards.add(new SetCardInfo("Iron-Shield Elf", 108, Rarity.UNCOMMON, mage.cards.i.IronShieldElf.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Iron-Shield Elf", 404, Rarity.UNCOMMON, mage.cards.i.IronShieldElf.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 270, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 275, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Island", 280, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Kinsbaile Aspirant", 21, Rarity.UNCOMMON, mage.cards.k.KinsbaileAspirant.class)); + 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("Kithkeeper", 23, Rarity.UNCOMMON, mage.cards.k.Kithkeeper.class)); + cards.add(new SetCardInfo("Kulrath Mystic", 56, Rarity.COMMON, mage.cards.k.KulrathMystic.class)); + cards.add(new SetCardInfo("Kulrath Zealot", 148, Rarity.COMMON, mage.cards.k.KulrathZealot.class)); + cards.add(new SetCardInfo("Lasting Tarfire", 149, Rarity.UNCOMMON, mage.cards.l.LastingTarfire.class)); + cards.add(new SetCardInfo("Lavaleaper", 150, Rarity.RARE, mage.cards.l.Lavaleaper.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Lavaleaper", 318, Rarity.RARE, mage.cards.l.Lavaleaper.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Liminal Hold", 24, Rarity.COMMON, mage.cards.l.LiminalHold.class)); + cards.add(new SetCardInfo("Loch Mare", 307, Rarity.MYTHIC, mage.cards.l.LochMare.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Loch Mare", 57, Rarity.MYTHIC, mage.cards.l.LochMare.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Lofty Dreams", 58, Rarity.UNCOMMON, mage.cards.l.LoftyDreams.class)); + cards.add(new SetCardInfo("Luminollusk", 179, Rarity.UNCOMMON, mage.cards.l.Luminollusk.class)); + cards.add(new SetCardInfo("Lys Alana Informant", 181, Rarity.COMMON, mage.cards.l.LysAlanaInformant.class)); + cards.add(new SetCardInfo("Meek Attack", 151, Rarity.MYTHIC, mage.cards.m.MeekAttack.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Meek Attack", 319, Rarity.MYTHIC, mage.cards.m.MeekAttack.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Meek Attack", 388, Rarity.MYTHIC, mage.cards.m.MeekAttack.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Meek Attack", 398, Rarity.MYTHIC, mage.cards.m.MeekAttack.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Merrow Skyswimmer", 234, Rarity.COMMON, mage.cards.m.MerrowSkyswimmer.class)); + cards.add(new SetCardInfo("Midnight Tilling", 182, Rarity.COMMON, mage.cards.m.MidnightTilling.class)); + cards.add(new SetCardInfo("Mirrorform", 308, Rarity.MYTHIC, mage.cards.m.Mirrorform.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mirrorform", 59, Rarity.MYTHIC, mage.cards.m.Mirrorform.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Moonglove Extractor", 109, Rarity.COMMON, mage.cards.m.MoongloveExtractor.class)); 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("Mountain", 272, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 277, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mountain", 282, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Mudbutton Cursetosser", 112, Rarity.UNCOMMON, mage.cards.m.MudbuttonCursetosser.class)); 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("Nameless Inversion", 113, Rarity.UNCOMMON, mage.cards.n.NamelessInversion.class)); + cards.add(new SetCardInfo("Noggle Robber", 237, Rarity.UNCOMMON, mage.cards.n.NoggleRobber.class)); + 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("Personify", 28, Rarity.UNCOMMON, mage.cards.p.Personify.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Personify", 402, Rarity.UNCOMMON, mage.cards.p.Personify.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Pestered Wellguard", 63, Rarity.UNCOMMON, mage.cards.p.PesteredWellguard.class)); + cards.add(new SetCardInfo("Pitiless Fists", 187, Rarity.UNCOMMON, mage.cards.p.PitilessFists.class)); + cards.add(new SetCardInfo("Plains", 269, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 274, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Plains", 279, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Prideful Feastling", 238, Rarity.COMMON, mage.cards.p.PridefulFeastling.class)); + cards.add(new SetCardInfo("Puca's Eye", 259, Rarity.UNCOMMON, mage.cards.p.PucasEye.class)); + cards.add(new SetCardInfo("Requiting Hex", 116, Rarity.UNCOMMON, mage.cards.r.RequitingHex.class)); + cards.add(new SetCardInfo("Rhys, the Evermore", 32, Rarity.RARE, mage.cards.r.RhysTheEvermore.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rhys, the Evermore", 354, Rarity.RARE, mage.cards.r.RhysTheEvermore.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rooftop Percher", 2, Rarity.COMMON, mage.cards.r.RooftopPercher.class)); + cards.add(new SetCardInfo("Run Away Together", 67, Rarity.COMMON, mage.cards.r.RunAwayTogether.class)); + cards.add(new SetCardInfo("Sanar, Innovative First-Year", 241, Rarity.RARE, mage.cards.s.SanarInnovativeFirstYear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sanar, Innovative First-Year", 378, Rarity.RARE, mage.cards.s.SanarInnovativeFirstYear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sapling Nursery", 192, Rarity.RARE, mage.cards.s.SaplingNursery.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sapling Nursery", 328, Rarity.RARE, mage.cards.s.SaplingNursery.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Scarblade Scout", 118, Rarity.COMMON, mage.cards.s.ScarbladeScout.class)); + cards.add(new SetCardInfo("Sear", 154, Rarity.UNCOMMON, mage.cards.s.Sear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sear", 405, Rarity.UNCOMMON, mage.cards.s.Sear.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Shimmercreep", 120, Rarity.UNCOMMON, mage.cards.s.Shimmercreep.class)); + cards.add(new SetCardInfo("Shinestriker", 68, Rarity.UNCOMMON, mage.cards.s.Shinestriker.class)); + cards.add(new SetCardInfo("Shore Lurker", 34, Rarity.COMMON, mage.cards.s.ShoreLurker.class)); + cards.add(new SetCardInfo("Silvergill Mentor", 403, Rarity.UNCOMMON, mage.cards.s.SilvergillMentor.class)); + cards.add(new SetCardInfo("Silvergill Peddler", 70, Rarity.COMMON, mage.cards.s.SilvergillPeddler.class)); + cards.add(new SetCardInfo("Sizzling Changeling", 155, Rarity.UNCOMMON, mage.cards.s.SizzlingChangeling.class)); + cards.add(new SetCardInfo("Slumbering Walker", 302, Rarity.RARE, mage.cards.s.SlumberingWalker.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Slumbering Walker", 35, Rarity.RARE, mage.cards.s.SlumberingWalker.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sourbread Auntie", 158, Rarity.UNCOMMON, mage.cards.s.SourbreadAuntie.class)); + cards.add(new SetCardInfo("Spell Snare", 71, Rarity.UNCOMMON, mage.cards.s.SpellSnare.class)); + cards.add(new SetCardInfo("Springleaf Drum", 260, Rarity.UNCOMMON, mage.cards.s.SpringleafDrum.class)); + cards.add(new SetCardInfo("Squawkroaster", 160, Rarity.UNCOMMON, mage.cards.s.Squawkroaster.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("Stratosoarer", 72, Rarity.COMMON, mage.cards.s.Stratosoarer.class)); + cards.add(new SetCardInfo("Sun-Dappled Celebrant", 37, Rarity.COMMON, mage.cards.s.SunDappledCelebrant.class)); + cards.add(new SetCardInfo("Surly Farrier", 196, Rarity.COMMON, mage.cards.s.SurlyFarrier.class)); + cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 276, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swamp", 281, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Swat Away", 75, Rarity.UNCOMMON, mage.cards.s.SwatAway.class)); 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("Tanufel Rimespeaker", 77, Rarity.UNCOMMON, mage.cards.t.TanufelRimespeaker.class)); + 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("Temporal Cleansing", 78, Rarity.COMMON, mage.cards.t.TemporalCleansing.class)); + cards.add(new SetCardInfo("Tend the Sprigs", 197, Rarity.COMMON, mage.cards.t.TendTheSprigs.class)); + cards.add(new SetCardInfo("Thoughtweft Charge", 198, Rarity.UNCOMMON, mage.cards.t.ThoughtweftCharge.class)); + cards.add(new SetCardInfo("Thoughtweft Imbuer", 38, Rarity.UNCOMMON, mage.cards.t.ThoughtweftImbuer.class)); + cards.add(new SetCardInfo("Thoughtweft Lieutenant", 246, Rarity.UNCOMMON, mage.cards.t.ThoughtweftLieutenant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Thoughtweft Lieutenant", 343, Rarity.UNCOMMON, mage.cards.t.ThoughtweftLieutenant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tributary Vaulter", 40, Rarity.COMMON, mage.cards.t.TributaryVaulter.class)); + cards.add(new SetCardInfo("Trystan, Callous Cultivator", 199, Rarity.RARE, mage.cards.t.TrystanCallousCultivator.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Trystan, Callous Cultivator", 291, Rarity.RARE, mage.cards.t.TrystanCallousCultivator.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Tweeze", 162, Rarity.COMMON, mage.cards.t.Tweeze.class)); + cards.add(new SetCardInfo("Unexpected Assistance", 80, Rarity.COMMON, mage.cards.u.UnexpectedAssistance.class)); + cards.add(new SetCardInfo("Unforgiving Aim", 200, Rarity.COMMON, mage.cards.u.UnforgivingAim.class)); + cards.add(new SetCardInfo("Unwelcome Sprite", 81, Rarity.UNCOMMON, mage.cards.u.UnwelcomeSprite.class)); + cards.add(new SetCardInfo("Vibrance", 249, Rarity.MYTHIC, mage.cards.v.Vibrance.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vibrance", 295, Rarity.MYTHIC, mage.cards.v.Vibrance.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vinebred Brawler", 201, Rarity.UNCOMMON, mage.cards.v.VinebredBrawler.class)); + cards.add(new SetCardInfo("Virulent Emissary", 202, Rarity.UNCOMMON, mage.cards.v.VirulentEmissary.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Virulent Emissary", 406, Rarity.UNCOMMON, mage.cards.v.VirulentEmissary.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Voracious Tome-Skimmer", 250, Rarity.UNCOMMON, mage.cards.v.VoraciousTomeSkimmer.class)); + cards.add(new SetCardInfo("Wanderbrine Preacher", 41, Rarity.COMMON, mage.cards.w.WanderbrinePreacher.class)); + cards.add(new SetCardInfo("Wanderwine Distracter", 82, Rarity.COMMON, mage.cards.w.WanderwineDistracter.class)); + cards.add(new SetCardInfo("Warren Torchmaster", 163, Rarity.UNCOMMON, mage.cards.w.WarrenTorchmaster.class)); + cards.add(new SetCardInfo("Wild Unraveling", 84, Rarity.COMMON, mage.cards.w.WildUnraveling.class)); + cards.add(new SetCardInfo("Wistfulness", 252, Rarity.MYTHIC, mage.cards.w.Wistfulness.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Wistfulness", 296, Rarity.MYTHIC, mage.cards.w.Wistfulness.class, NON_FULL_USE_VARIOUS)); } } diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsedCommander.java b/Mage.Sets/src/mage/sets/LorwynEclipsedCommander.java new file mode 100644 index 00000000000..ad79b5a2a4c --- /dev/null +++ b/Mage.Sets/src/mage/sets/LorwynEclipsedCommander.java @@ -0,0 +1,177 @@ +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.Rarity; +import mage.constants.SetType; + +/** + * @author TheElk801 + */ +public final class LorwynEclipsedCommander extends ExpansionSet { + + private static final LorwynEclipsedCommander instance = new LorwynEclipsedCommander(); + + public static LorwynEclipsedCommander getInstance() { + return instance; + } + + private LorwynEclipsedCommander() { + super("Lorwyn Eclipsed Commander", "ECC", ExpansionSet.buildDate(2026, 1, 23), SetType.SUPPLEMENTAL); + this.hasBasicLands = false; // temporary + + cards.add(new SetCardInfo("Abundant Countryside", 22, Rarity.RARE, mage.cards.a.AbundantCountryside.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Abundant Countryside", 42, Rarity.RARE, mage.cards.a.AbundantCountryside.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Abundant Growth", 97, Rarity.COMMON, mage.cards.a.AbundantGrowth.class)); + cards.add(new SetCardInfo("Ancient Ziggurat", 144, Rarity.UNCOMMON, mage.cards.a.AncientZiggurat.class)); + cards.add(new SetCardInfo("Arcane Signet", 55, Rarity.UNCOMMON, mage.cards.a.ArcaneSignet.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Arcane Signet", 56, Rarity.UNCOMMON, mage.cards.a.ArcaneSignet.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Archfiend of Ifnir", 70, Rarity.RARE, mage.cards.a.ArchfiendOfIfnir.class)); + cards.add(new SetCardInfo("Assassin's Trophy", 119, Rarity.RARE, mage.cards.a.AssassinsTrophy.class)); + cards.add(new SetCardInfo("Auntie Ool, Cursewretch", 2, Rarity.MYTHIC, mage.cards.a.AuntieOolCursewretch.class)); + cards.add(new SetCardInfo("Avenger of Zendikar", 98, Rarity.MYTHIC, mage.cards.a.AvengerOfZendikar.class)); + cards.add(new SetCardInfo("Bane of Progress", 99, Rarity.RARE, mage.cards.b.BaneOfProgress.class)); + cards.add(new SetCardInfo("Belonging", 25, Rarity.RARE, mage.cards.b.Belonging.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Belonging", 5, Rarity.RARE, mage.cards.b.Belonging.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Binding the Old Gods", 120, Rarity.UNCOMMON, mage.cards.b.BindingTheOldGods.class)); + cards.add(new SetCardInfo("Black Sun's Zenith", 71, Rarity.RARE, mage.cards.b.BlackSunsZenith.class)); + cards.add(new SetCardInfo("Blasphemous Act", 89, Rarity.RARE, mage.cards.b.BlasphemousAct.class)); + cards.add(new SetCardInfo("Blowfly Infestation", 46, Rarity.UNCOMMON, mage.cards.b.BlowflyInfestation.class)); + cards.add(new SetCardInfo("Canyon Slough", 145, Rarity.RARE, mage.cards.c.CanyonSlough.class)); + cards.add(new SetCardInfo("Carnifex Demon", 72, Rarity.RARE, mage.cards.c.CarnifexDemon.class)); + cards.add(new SetCardInfo("Cathartic Pyre", 90, Rarity.UNCOMMON, mage.cards.c.CatharticPyre.class)); + cards.add(new SetCardInfo("Cathartic Reunion", 91, Rarity.COMMON, mage.cards.c.CatharticReunion.class)); + cards.add(new SetCardInfo("Cavalier of Thorns", 100, Rarity.MYTHIC, mage.cards.c.CavalierOfThorns.class)); + cards.add(new SetCardInfo("Chain Reaction", 92, Rarity.RARE, mage.cards.c.ChainReaction.class)); + cards.add(new SetCardInfo("Channeler Initiate", 101, Rarity.RARE, mage.cards.c.ChannelerInitiate.class)); + cards.add(new SetCardInfo("Chimil, the Inner Sun", 137, Rarity.MYTHIC, mage.cards.c.ChimilTheInnerSun.class)); + cards.add(new SetCardInfo("Chromatic Lantern", 138, Rarity.RARE, mage.cards.c.ChromaticLantern.class)); + cards.add(new SetCardInfo("Cinder Glade", 146, Rarity.RARE, mage.cards.c.CinderGlade.class)); + cards.add(new SetCardInfo("Command Tower", 59, Rarity.COMMON, mage.cards.c.CommandTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Command Tower", 60, Rarity.COMMON, mage.cards.c.CommandTower.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Commander's Sphere", 139, Rarity.COMMON, mage.cards.c.CommandersSphere.class)); + cards.add(new SetCardInfo("Contagion Clasp", 140, Rarity.UNCOMMON, mage.cards.c.ContagionClasp.class)); + cards.add(new SetCardInfo("Cream of the Crop", 102, Rarity.RARE, mage.cards.c.CreamOfTheCrop.class)); + cards.add(new SetCardInfo("Cultivate", 103, Rarity.COMMON, mage.cards.c.Cultivate.class)); + cards.add(new SetCardInfo("Descendants' Fury", 93, Rarity.RARE, mage.cards.d.DescendantsFury.class)); + cards.add(new SetCardInfo("Devoted Druid", 104, Rarity.UNCOMMON, mage.cards.d.DevotedDruid.class)); + cards.add(new SetCardInfo("Distant Melody", 45, Rarity.COMMON, mage.cards.d.DistantMelody.class)); + cards.add(new SetCardInfo("Dragonskull Summit", 147, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); + cards.add(new SetCardInfo("Dusk Urchins", 73, Rarity.RARE, mage.cards.d.DuskUrchins.class)); + cards.add(new SetCardInfo("Endurance", 51, Rarity.MYTHIC, mage.cards.e.Endurance.class)); + cards.add(new SetCardInfo("Everlasting Torment", 121, Rarity.RARE, mage.cards.e.EverlastingTorment.class)); + cards.add(new SetCardInfo("Evolution Sage", 105, Rarity.UNCOMMON, mage.cards.e.EvolutionSage.class)); + cards.add(new SetCardInfo("Exotic Orchard", 148, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); + cards.add(new SetCardInfo("Faeburrow Elder", 53, Rarity.RARE, mage.cards.f.FaeburrowElder.class)); + cards.add(new SetCardInfo("Fellwar Stone", 141, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class)); + cards.add(new SetCardInfo("Fertile Ground", 106, Rarity.COMMON, mage.cards.f.FertileGround.class)); + cards.add(new SetCardInfo("Festering Thicket", 61, Rarity.RARE, mage.cards.f.FesteringThicket.class)); + cards.add(new SetCardInfo("Fire Covenant", 54, Rarity.UNCOMMON, mage.cards.f.FireCovenant.class)); + cards.add(new SetCardInfo("Flamekin Village", 149, Rarity.RARE, mage.cards.f.FlamekinVillage.class)); + cards.add(new SetCardInfo("Flourishing Defenses", 107, Rarity.UNCOMMON, mage.cards.f.FlourishingDefenses.class)); + cards.add(new SetCardInfo("Foundation Breaker", 108, Rarity.UNCOMMON, mage.cards.f.FoundationBreaker.class)); + cards.add(new SetCardInfo("Frontier Bivouac", 150, Rarity.UNCOMMON, mage.cards.f.FrontierBivouac.class)); + cards.add(new SetCardInfo("Fury", 50, Rarity.MYTHIC, mage.cards.f.Fury.class)); + cards.add(new SetCardInfo("Garruk's Uprising", 109, Rarity.UNCOMMON, mage.cards.g.GarruksUprising.class)); + cards.add(new SetCardInfo("Glissa Sunslayer", 122, Rarity.RARE, mage.cards.g.GlissaSunslayer.class)); + cards.add(new SetCardInfo("Golgari Rot Farm", 151, Rarity.UNCOMMON, mage.cards.g.GolgariRotFarm.class)); + cards.add(new SetCardInfo("Grave Titan", 74, Rarity.MYTHIC, mage.cards.g.GraveTitan.class)); + cards.add(new SetCardInfo("Greenwarden of Murasa", 110, Rarity.MYTHIC, mage.cards.g.GreenwardenOfMurasa.class)); + cards.add(new SetCardInfo("Grim Poppet", 142, Rarity.RARE, mage.cards.g.GrimPoppet.class)); + cards.add(new SetCardInfo("Gruul Turf", 152, Rarity.UNCOMMON, mage.cards.g.GruulTurf.class)); + cards.add(new SetCardInfo("Hapatra, Vizier of Poisons", 123, Rarity.RARE, mage.cards.h.HapatraVizierOfPoisons.class)); + cards.add(new SetCardInfo("Harmonize", 111, Rarity.UNCOMMON, mage.cards.h.Harmonize.class)); + cards.add(new SetCardInfo("Haunting Voyage", 75, Rarity.MYTHIC, mage.cards.h.HauntingVoyage.class)); + cards.add(new SetCardInfo("Hoarder's Greed", 47, Rarity.UNCOMMON, mage.cards.h.HoardersGreed.class)); + cards.add(new SetCardInfo("Hoofprints of the Stag", 64, Rarity.RARE, mage.cards.h.HoofprintsOfTheStag.class)); + cards.add(new SetCardInfo("Horde of Notions", 124, Rarity.RARE, mage.cards.h.HordeOfNotions.class)); + cards.add(new SetCardInfo("Ifnir Deadlands", 153, Rarity.UNCOMMON, mage.cards.i.IfnirDeadlands.class)); + cards.add(new SetCardInfo("Ignoble Hierarch", 52, Rarity.RARE, mage.cards.i.IgnobleHierarch.class)); + cards.add(new SetCardInfo("Impulsivity", 13, Rarity.RARE, mage.cards.i.Impulsivity.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Impulsivity", 33, Rarity.RARE, mage.cards.i.Impulsivity.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Incandescent Soulstoke", 94, Rarity.UNCOMMON, mage.cards.i.IncandescentSoulstoke.class)); + cards.add(new SetCardInfo("Incremental Blight", 76, Rarity.UNCOMMON, mage.cards.i.IncrementalBlight.class)); + cards.add(new SetCardInfo("Infernal Grasp", 77, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class)); + cards.add(new SetCardInfo("Ingot Chewer", 95, Rarity.COMMON, mage.cards.i.IngotChewer.class)); + cards.add(new SetCardInfo("Jegantha, the Wellspring", 125, Rarity.RARE, mage.cards.j.JeganthaTheWellspring.class)); + cards.add(new SetCardInfo("Jubilation", 17, Rarity.RARE, mage.cards.j.Jubilation.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jubilation", 37, Rarity.RARE, mage.cards.j.Jubilation.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jungle Shrine", 154, Rarity.UNCOMMON, mage.cards.j.JungleShrine.class)); + cards.add(new SetCardInfo("Kindred Summons", 112, Rarity.RARE, mage.cards.k.KindredSummons.class)); + cards.add(new SetCardInfo("Kodama's Reach", 113, Rarity.COMMON, mage.cards.k.KodamasReach.class)); + cards.add(new SetCardInfo("Kulrath Knight", 126, Rarity.UNCOMMON, mage.cards.k.KulrathKnight.class)); + cards.add(new SetCardInfo("Lamentation", 10, Rarity.RARE, mage.cards.l.Lamentation.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Lamentation", 30, Rarity.RARE, mage.cards.l.Lamentation.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Liliana, Death Wielder", 78, Rarity.MYTHIC, mage.cards.l.LilianaDeathWielder.class)); + cards.add(new SetCardInfo("Maelstrom Wanderer", 127, Rarity.RARE, mage.cards.m.MaelstromWanderer.class)); + cards.add(new SetCardInfo("Massacre Girl, Known Killer", 79, Rarity.MYTHIC, mage.cards.m.MassacreGirlKnownKiller.class)); + cards.add(new SetCardInfo("Midnight Banshee", 80, Rarity.RARE, mage.cards.m.MidnightBanshee.class)); + cards.add(new SetCardInfo("Muldrotha, the Gravetide", 128, Rarity.MYTHIC, mage.cards.m.MuldrothaTheGravetide.class)); + cards.add(new SetCardInfo("Mulldrifter", 67, Rarity.UNCOMMON, mage.cards.m.Mulldrifter.class)); + cards.add(new SetCardInfo("Necroskitter", 48, Rarity.RARE, mage.cards.n.Necroskitter.class)); + cards.add(new SetCardInfo("Nesting Grounds", 155, Rarity.RARE, mage.cards.n.NestingGrounds.class)); + cards.add(new SetCardInfo("Night's Whisper", 81, Rarity.COMMON, mage.cards.n.NightsWhisper.class)); + cards.add(new SetCardInfo("Oft-Nabbed Goat", 11, Rarity.RARE, mage.cards.o.OftNabbedGoat.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Oft-Nabbed Goat", 31, Rarity.RARE, mage.cards.o.OftNabbedGoat.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Omnath, Locus of Rage", 129, Rarity.MYTHIC, mage.cards.o.OmnathLocusOfRage.class)); + cards.add(new SetCardInfo("Omnath, Locus of the Roil", 130, Rarity.MYTHIC, mage.cards.o.OmnathLocusOfTheRoil.class)); + cards.add(new SetCardInfo("Opal Palace", 156, Rarity.COMMON, mage.cards.o.OpalPalace.class)); + cards.add(new SetCardInfo("Opulent Palace", 157, Rarity.UNCOMMON, mage.cards.o.OpulentPalace.class)); + cards.add(new SetCardInfo("Painful Truths", 82, Rarity.RARE, mage.cards.p.PainfulTruths.class)); + cards.add(new SetCardInfo("Path of Ancestry", 158, Rarity.COMMON, mage.cards.p.PathOfAncestry.class)); + cards.add(new SetCardInfo("Path to Exile", 65, Rarity.UNCOMMON, mage.cards.p.PathToExile.class)); + cards.add(new SetCardInfo("Persist", 83, Rarity.RARE, mage.cards.p.Persist.class)); + cards.add(new SetCardInfo("Primal Beyond", 159, Rarity.RARE, mage.cards.p.PrimalBeyond.class)); + cards.add(new SetCardInfo("Puppeteer Clique", 84, Rarity.RARE, mage.cards.p.PuppeteerClique.class)); + cards.add(new SetCardInfo("Putrefy", 131, Rarity.UNCOMMON, mage.cards.p.Putrefy.class)); + cards.add(new SetCardInfo("Raging Ravine", 160, Rarity.RARE, mage.cards.r.RagingRavine.class)); + cards.add(new SetCardInfo("Rain-Slicked Copse", 23, Rarity.RARE, mage.cards.r.RainSlickedCopse.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rain-Slicked Copse", 43, Rarity.RARE, mage.cards.r.RainSlickedCopse.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Rakdos Carnarium", 161, Rarity.UNCOMMON, mage.cards.r.RakdosCarnarium.class)); + cards.add(new SetCardInfo("Reality Shift", 68, Rarity.UNCOMMON, mage.cards.r.RealityShift.class)); + cards.add(new SetCardInfo("Realmwalker", 114, Rarity.RARE, mage.cards.r.Realmwalker.class)); + cards.add(new SetCardInfo("Return of the Wildspeaker", 115, Rarity.RARE, mage.cards.r.ReturnOfTheWildspeaker.class)); + cards.add(new SetCardInfo("Risen Reef", 132, Rarity.UNCOMMON, mage.cards.r.RisenReef.class)); + cards.add(new SetCardInfo("Riveteers Overlook", 162, Rarity.COMMON, mage.cards.r.RiveteersOverlook.class)); + cards.add(new SetCardInfo("Rootbound Crag", 163, Rarity.RARE, mage.cards.r.RootboundCrag.class)); + cards.add(new SetCardInfo("Sandsteppe Citadel", 164, Rarity.UNCOMMON, mage.cards.s.SandsteppeCitadel.class)); + cards.add(new SetCardInfo("Savage Lands", 165, Rarity.UNCOMMON, mage.cards.s.SavageLands.class)); + cards.add(new SetCardInfo("Seaside Citadel", 166, Rarity.UNCOMMON, mage.cards.s.SeasideCitadel.class)); + cards.add(new SetCardInfo("Secluded Courtyard", 62, Rarity.UNCOMMON, mage.cards.s.SecludedCourtyard.class)); + cards.add(new SetCardInfo("Selvala, Heart of the Wilds", 116, Rarity.MYTHIC, mage.cards.s.SelvalaHeartOfTheWilds.class)); + cards.add(new SetCardInfo("Shatter the Sky", 66, Rarity.RARE, mage.cards.s.ShatterTheSky.class)); + cards.add(new SetCardInfo("Sheltered Thicket", 167, Rarity.RARE, mage.cards.s.ShelteredThicket.class)); + cards.add(new SetCardInfo("Shriekmaw", 85, Rarity.UNCOMMON, mage.cards.s.Shriekmaw.class)); + cards.add(new SetCardInfo("Sinister Gnarlbark", 12, Rarity.RARE, mage.cards.s.SinisterGnarlbark.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sinister Gnarlbark", 32, Rarity.RARE, mage.cards.s.SinisterGnarlbark.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Skinrender", 86, Rarity.UNCOMMON, mage.cards.s.Skinrender.class)); + cards.add(new SetCardInfo("Slithermuse", 69, Rarity.RARE, mage.cards.s.Slithermuse.class)); + cards.add(new SetCardInfo("Smokebraider", 96, Rarity.COMMON, mage.cards.s.Smokebraider.class)); + cards.add(new SetCardInfo("Smoldering Marsh", 168, Rarity.RARE, mage.cards.s.SmolderingMarsh.class)); + cards.add(new SetCardInfo("Sodden Verdure", 24, Rarity.RARE, mage.cards.s.SoddenVerdure.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sodden Verdure", 44, Rarity.RARE, mage.cards.s.SoddenVerdure.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sol Ring", 57, Rarity.UNCOMMON, mage.cards.s.SolRing.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Sol Ring", 58, Rarity.UNCOMMON, mage.cards.s.SolRing.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Soul Snuffers", 87, Rarity.UNCOMMON, mage.cards.s.SoulSnuffers.class)); + cards.add(new SetCardInfo("Terminate", 134, Rarity.COMMON, mage.cards.t.Terminate.class)); + cards.add(new SetCardInfo("Terramorphic Expanse", 169, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class)); + cards.add(new SetCardInfo("The Reaper, King No More", 4, Rarity.MYTHIC, mage.cards.t.TheReaperKingNoMore.class)); + cards.add(new SetCardInfo("The Scorpion God", 133, Rarity.MYTHIC, mage.cards.t.TheScorpionGod.class)); + cards.add(new SetCardInfo("Thriving Bluff", 170, Rarity.COMMON, mage.cards.t.ThrivingBluff.class)); + cards.add(new SetCardInfo("Thriving Grove", 171, Rarity.COMMON, mage.cards.t.ThrivingGrove.class)); + cards.add(new SetCardInfo("Thriving Heath", 172, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); + cards.add(new SetCardInfo("Thriving Isle", 173, Rarity.COMMON, mage.cards.t.ThrivingIsle.class)); + cards.add(new SetCardInfo("Thriving Moor", 174, Rarity.COMMON, mage.cards.t.ThrivingMoor.class)); + cards.add(new SetCardInfo("Timeless Lotus", 143, Rarity.MYTHIC, mage.cards.t.TimelessLotus.class)); + cards.add(new SetCardInfo("Titan of Industry", 117, Rarity.MYTHIC, mage.cards.t.TitanOfIndustry.class)); + cards.add(new SetCardInfo("Tree of Perdition", 49, Rarity.MYTHIC, mage.cards.t.TreeOfPerdition.class)); + cards.add(new SetCardInfo("Unclaimed Territory", 175, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); + cards.add(new SetCardInfo("Vernal Fen", 63, Rarity.RARE, mage.cards.v.VernalFen.class)); + cards.add(new SetCardInfo("Vernal Sovereign", 135, Rarity.RARE, mage.cards.v.VernalSovereign.class)); + cards.add(new SetCardInfo("Village Pillagers", 14, Rarity.RARE, mage.cards.v.VillagePillagers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Village Pillagers", 34, Rarity.RARE, mage.cards.v.VillagePillagers.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Vraska, Betrayal's Sting", 88, Rarity.MYTHIC, mage.cards.v.VraskaBetrayalsSting.class)); + cards.add(new SetCardInfo("Wickerbough Elder", 118, Rarity.COMMON, mage.cards.w.WickerboughElder.class)); + cards.add(new SetCardInfo("Woodland Cemetery", 176, Rarity.RARE, mage.cards.w.WoodlandCemetery.class)); + cards.add(new SetCardInfo("Yarok, the Desecrated", 136, Rarity.MYTHIC, mage.cards.y.YarokTheDesecrated.class)); + } +} diff --git a/Mage.Sets/src/mage/sets/MagicOnlinePromos.java b/Mage.Sets/src/mage/sets/MagicOnlinePromos.java index fbf0d6992f0..a9be1013abe 100644 --- a/Mage.Sets/src/mage/sets/MagicOnlinePromos.java +++ b/Mage.Sets/src/mage/sets/MagicOnlinePromos.java @@ -135,12 +135,10 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Arcbound Ravager", 72888, Rarity.RARE, mage.cards.a.ArcboundRavager.class)); cards.add(new SetCardInfo("Archaeomancer's Map", 90008, Rarity.RARE, mage.cards.a.ArchaeomancersMap.class)); cards.add(new SetCardInfo("Archangel of Wrath", 103392, Rarity.RARE, mage.cards.a.ArchangelOfWrath.class)); - cards.add(new SetCardInfo("Archdemon of Greed", 43503, Rarity.RARE, mage.cards.a.ArchdemonOfGreed.class)); cards.add(new SetCardInfo("Archelos, Lagoon Mystic", 86334, Rarity.RARE, mage.cards.a.ArchelosLagoonMystic.class)); 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)); @@ -175,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)); @@ -249,7 +246,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Beledros Witherbloom", 90318, Rarity.MYTHIC, mage.cards.b.BeledrosWitherbloom.class)); cards.add(new SetCardInfo("Bell Borca, Spectral Sergeant", 86308, Rarity.RARE, mage.cards.b.BellBorcaSpectralSergeant.class)); cards.add(new SetCardInfo("Bellowing Mauler", 99853, Rarity.RARE, mage.cards.b.BellowingMauler.class)); - cards.add(new SetCardInfo("Benevolent Geist", 93950, Rarity.RARE, mage.cards.b.BenevolentGeist.class)); cards.add(new SetCardInfo("Bennie Bracks, Zoologist", 99815, Rarity.MYTHIC, mage.cards.b.BennieBracksZoologist.class)); cards.add(new SetCardInfo("Bident of Thassa", 50114, Rarity.RARE, mage.cards.b.BidentOfThassa.class)); cards.add(new SetCardInfo("Bile Blight", 53838, Rarity.UNCOMMON, mage.cards.b.BileBlight.class)); @@ -534,7 +530,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Crash the Party", 99839, Rarity.RARE, mage.cards.c.CrashTheParty.class)); cards.add(new SetCardInfo("Crawling Barrens", 83732, Rarity.RARE, mage.cards.c.CrawlingBarrens.class)); cards.add(new SetCardInfo("Creative Technique", 90122, Rarity.RARE, mage.cards.c.CreativeTechnique.class)); - cards.add(new SetCardInfo("Creeping Inn", 94088, Rarity.MYTHIC, mage.cards.c.CreepingInn.class)); cards.add(new SetCardInfo("Creeping Mold", 32525, Rarity.UNCOMMON, mage.cards.c.CreepingMold.class, RETRO_ART)); cards.add(new SetCardInfo("Creepy Puppeteer", 95365, Rarity.RARE, mage.cards.c.CreepyPuppeteer.class)); cards.add(new SetCardInfo("Crippling Fear", 88286, Rarity.RARE, mage.cards.c.CripplingFear.class)); @@ -664,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)); @@ -709,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)); @@ -755,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)); @@ -967,7 +959,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Forest", 40050, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 40060, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 40094, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Forest", 53875, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_ZEN_VARIOUS )); + cards.add(new SetCardInfo("Forest", 53875, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_ZEN_VARIOUS)); cards.add(new SetCardInfo("Forest", 58261, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 73628, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 81872, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); @@ -1040,7 +1032,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Getaway Car", 99727, Rarity.RARE, mage.cards.g.GetawayCar.class)); cards.add(new SetCardInfo("Geyadrone Dihada", 91329, Rarity.MYTHIC, mage.cards.g.GeyadroneDihada.class)); cards.add(new SetCardInfo("Ghalta, Primal Hunger", 66896, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); - cards.add(new SetCardInfo("Ghastly Mimicry", 95313, Rarity.RARE, mage.cards.g.GhastlyMimicry.class)); cards.add(new SetCardInfo("Ghen, Arcanum Weaver", 86340, Rarity.RARE, mage.cards.g.GhenArcanumWeaver.class)); cards.add(new SetCardInfo("Ghor-Clan Rampager", 50110, Rarity.UNCOMMON, mage.cards.g.GhorClanRampager.class)); cards.add(new SetCardInfo("Ghost of Ramirez DePietro", 86286, Rarity.UNCOMMON, mage.cards.g.GhostOfRamirezDePietro.class)); @@ -1240,8 +1231,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Hostile Hostel", 94088, Rarity.MYTHIC, mage.cards.h.HostileHostel.class)); cards.add(new SetCardInfo("Hostile Negotiations", 105712, Rarity.RARE, mage.cards.h.HostileNegotiations.class)); cards.add(new SetCardInfo("Howling Moon", 95417, Rarity.RARE, mage.cards.h.HowlingMoon.class)); - cards.add(new SetCardInfo("Howlpack Alpha", 42866, Rarity.RARE, mage.cards.h.HowlpackAlpha.class)); - cards.add(new SetCardInfo("Howlpack Avenger", 95389, Rarity.RARE, mage.cards.h.HowlpackAvenger.class)); cards.add(new SetCardInfo("Howlpack Piper", 95425, Rarity.RARE, mage.cards.h.HowlpackPiper.class)); cards.add(new SetCardInfo("Huatli, the Sun's Heart", 72241, Rarity.UNCOMMON, mage.cards.h.HuatliTheSunsHeart.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Huatli, the Sun's Heart", 77975, Rarity.UNCOMMON, mage.cards.h.HuatliTheSunsHeart.class, NON_FULL_USE_VARIOUS)); @@ -1345,7 +1334,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Island", 40052, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 40062, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 40100, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Island", 53881, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_ZEN_VARIOUS )); + cards.add(new SetCardInfo("Island", 53881, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_ZEN_VARIOUS)); cards.add(new SetCardInfo("Island", 58255, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 73634, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 81846, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); @@ -1463,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)); @@ -1561,7 +1549,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Lion Sash", 97887, Rarity.RARE, mage.cards.l.LionSash.class)); cards.add(new SetCardInfo("Lion's Eye Diamond", 51936, Rarity.RARE, mage.cards.l.LionsEyeDiamond.class)); cards.add(new SetCardInfo("Lithoform Engine", 83722, Rarity.MYTHIC, mage.cards.l.LithoformEngine.class)); - cards.add(new SetCardInfo("Living Breakthrough", 97937, Rarity.RARE, mage.cards.l.LivingBreakthrough.class)); cards.add(new SetCardInfo("Living Death", 36042, Rarity.RARE, mage.cards.l.LivingDeath.class, RETRO_ART)); cards.add(new SetCardInfo("Living Wish", 35068, Rarity.RARE, mage.cards.l.LivingWish.class)); cards.add(new SetCardInfo("Livio, Oathsworn Sentinel", 86348, Rarity.RARE, mage.cards.l.LivioOathswornSentinel.class)); @@ -1594,7 +1581,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Loyal Retainers", 47973, Rarity.UNCOMMON, mage.cards.l.LoyalRetainers.class)); cards.add(new SetCardInfo("Loyal Warhound", 92630, Rarity.RARE, mage.cards.l.LoyalWarhound.class)); cards.add(new SetCardInfo("Lu Bu, Master-at-Arms", 36130, Rarity.RARE, mage.cards.l.LuBuMasterAtArms.class, RETRO_ART)); - cards.add(new SetCardInfo("Ludevic's Abomination", 42874, Rarity.RARE, mage.cards.l.LudevicsAbomination.class)); cards.add(new SetCardInfo("Ludevic's Test Subject", 42874, Rarity.RARE, mage.cards.l.LudevicsTestSubject.class)); cards.add(new SetCardInfo("Ludevic, Necro-Alchemist", 86166, Rarity.MYTHIC, mage.cards.l.LudevicNecroAlchemist.class)); cards.add(new SetCardInfo("Lukka, Coppercoat Outcast", 80801, Rarity.MYTHIC, mage.cards.l.LukkaCoppercoatOutcast.class)); @@ -1770,7 +1756,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Mountain", 40054, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 40064, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 40096, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Mountain", 53877, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_ZEN_VARIOUS )); + cards.add(new SetCardInfo("Mountain", 53877, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_ZEN_VARIOUS)); cards.add(new SetCardInfo("Mountain", 58259, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 73630, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 81864, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); @@ -1900,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)); @@ -2029,7 +2014,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Plains", 40066, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 40098, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 48582, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Plains", 53879, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_ZEN_VARIOUS )); + cards.add(new SetCardInfo("Plains", 53879, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_ZEN_VARIOUS)); cards.add(new SetCardInfo("Plains", 58253, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 73626, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 81830, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); @@ -2050,7 +2035,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Pollywog Symbiote", 80931, Rarity.UNCOMMON, mage.cards.p.PollywogSymbiote.class)); cards.add(new SetCardInfo("Polukranos, Unchained", 79931, Rarity.MYTHIC, mage.cards.p.PolukranosUnchained.class)); cards.add(new SetCardInfo("Ponder", 35118, Rarity.COMMON, mage.cards.p.Ponder.class, FULL_ART)); - cards.add(new SetCardInfo("Poppet Factory", 93918, Rarity.MYTHIC, mage.cards.p.PoppetFactory.class)); cards.add(new SetCardInfo("Poppet Stitcher", 93918, Rarity.MYTHIC, mage.cards.p.PoppetStitcher.class)); cards.add(new SetCardInfo("Porcuparrot", 80965, Rarity.UNCOMMON, mage.cards.p.Porcuparrot.class)); cards.add(new SetCardInfo("Port Razer", 86068, Rarity.MYTHIC, mage.cards.p.PortRazer.class)); @@ -2179,7 +2163,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Red Dragon", 92754, Rarity.UNCOMMON, mage.cards.r.RedDragon.class)); cards.add(new SetCardInfo("Red Elemental Blast", 43610, Rarity.UNCOMMON, mage.cards.r.RedElementalBlast.class)); cards.add(new SetCardInfo("Reflecting Pool", 62487, Rarity.RARE, mage.cards.r.ReflectingPool.class)); - cards.add(new SetCardInfo("Reflection of Kiki-Jiki", 98009, Rarity.RARE, mage.cards.r.ReflectionOfKikiJiki.class)); cards.add(new SetCardInfo("Reflections of Littjara", 88252, Rarity.RARE, mage.cards.r.ReflectionsOfLittjara.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reflections of Littjara", 88254, Rarity.RARE, mage.cards.r.ReflectionsOfLittjara.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Regal Leosaur", 80967, Rarity.UNCOMMON, mage.cards.r.RegalLeosaur.class)); @@ -2196,7 +2179,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Reliquary Tower", 69250, Rarity.UNCOMMON, mage.cards.r.ReliquaryTower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Reliquary Tower", 86146, Rarity.UNCOMMON, mage.cards.r.ReliquaryTower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Remand", 31429, Rarity.UNCOMMON, mage.cards.r.Remand.class)); - cards.add(new SetCardInfo("Remnant of the Rising Star", 98063, Rarity.MYTHIC, mage.cards.r.RemnantOfTheRisingStar.class)); cards.add(new SetCardInfo("Remove Soul", 35130, Rarity.COMMON, mage.cards.r.RemoveSoul.class, FULL_ART)); cards.add(new SetCardInfo("Renata, Called to the Hunt", 79859, Rarity.UNCOMMON, mage.cards.r.RenataCalledToTheHunt.class)); cards.add(new SetCardInfo("Render Silent", 48576, Rarity.RARE, mage.cards.r.RenderSilent.class)); @@ -2636,7 +2618,7 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 40058, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 40068, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 40092, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Swamp", 53883, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_ZEN_VARIOUS )); + cards.add(new SetCardInfo("Swamp", 53883, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_ZEN_VARIOUS)); cards.add(new SetCardInfo("Swamp", 58257, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 73632, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 81856, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); @@ -2851,7 +2833,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Torrent Sculptor", 90248, Rarity.RARE, mage.cards.t.TorrentSculptor.class)); cards.add(new SetCardInfo("Toski, Bearer of Secrets", 88340, Rarity.RARE, mage.cards.t.ToskiBearerOfSecrets.class)); cards.add(new SetCardInfo("Tourach, Dread Cantor", 91253, Rarity.MYTHIC, mage.cards.t.TourachDreadCantor.class)); - cards.add(new SetCardInfo("Tovolar's Magehunter", 43507, Rarity.RARE, mage.cards.t.TovolarsMagehunter.class)); cards.add(new SetCardInfo("Toxic Deluge", 82832, Rarity.RARE, mage.cards.t.ToxicDeluge.class)); cards.add(new SetCardInfo("Tradewind Rider", 36048, Rarity.RARE, mage.cards.t.TradewindRider.class, RETRO_ART)); cards.add(new SetCardInfo("Training Center", 85954, Rarity.RARE, mage.cards.t.TrainingCenter.class)); @@ -2908,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)); @@ -2979,7 +2959,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Verazol, the Split Current", 83820, Rarity.RARE, mage.cards.v.VerazolTheSplitCurrent.class)); cards.add(new SetCardInfo("Verdant Catacombs", 91403, Rarity.RARE, mage.cards.v.VerdantCatacombs.class)); cards.add(new SetCardInfo("Verdant Mastery", 90138, Rarity.RARE, mage.cards.v.VerdantMastery.class)); - cards.add(new SetCardInfo("Vessel of the All-Consuming", 98105, Rarity.MYTHIC, mage.cards.v.VesselOfTheAllConsuming.class)); cards.add(new SetCardInfo("Vesuvan Duplimancy", 103402, Rarity.MYTHIC, mage.cards.v.VesuvanDuplimancy.class)); cards.add(new SetCardInfo("Vexing Shusher", 32533, Rarity.RARE, mage.cards.v.VexingShusher.class)); cards.add(new SetCardInfo("Veyran, Voice of Duality", 90282, Rarity.MYTHIC, mage.cards.v.VeyranVoiceOfDuality.class)); @@ -3043,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)); @@ -3062,7 +3040,6 @@ public class MagicOnlinePromos extends ExpansionSet { cards.add(new SetCardInfo("Wild-Magic Sorcerer", 92752, Rarity.RARE, mage.cards.w.WildMagicSorcerer.class)); cards.add(new SetCardInfo("Wildcall", 55749, Rarity.RARE, mage.cards.w.Wildcall.class)); cards.add(new SetCardInfo("Wildfire Eternal", 64989, Rarity.RARE, mage.cards.w.WildfireEternal.class)); - cards.add(new SetCardInfo("Wildsong Howler", 95425, Rarity.RARE, mage.cards.w.WildsongHowler.class)); cards.add(new SetCardInfo("Willbender", 36258, Rarity.UNCOMMON, mage.cards.w.Willbender.class)); cards.add(new SetCardInfo("Willow Geist", 94024, Rarity.RARE, mage.cards.w.WillowGeist.class)); cards.add(new SetCardInfo("Willowdusk, Essence Seer", 90288, Rarity.MYTHIC, mage.cards.w.WillowduskEssenceSeer.class)); diff --git a/Mage.Sets/src/mage/sets/MagicOrigins.java b/Mage.Sets/src/mage/sets/MagicOrigins.java index b63aa10a45c..c7aef8f2e7f 100644 --- a/Mage.Sets/src/mage/sets/MagicOrigins.java +++ b/Mage.Sets/src/mage/sets/MagicOrigins.java @@ -132,7 +132,6 @@ public final class MagicOrigins extends ExpansionSet { cards.add(new SetCardInfo("Gather the Pack", 178, Rarity.UNCOMMON, mage.cards.g.GatherThePack.class)); cards.add(new SetCardInfo("Ghirapur Aether Grid", 148, Rarity.UNCOMMON, mage.cards.g.GhirapurAetherGrid.class)); cards.add(new SetCardInfo("Ghirapur Gearcrafter", 149, Rarity.COMMON, mage.cards.g.GhirapurGearcrafter.class)); - cards.add(new SetCardInfo("Gideon, Battle-Forged", 23, Rarity.MYTHIC, mage.cards.g.GideonBattleForged.class)); cards.add(new SetCardInfo("Gideon's Phalanx", 14, Rarity.RARE, mage.cards.g.GideonsPhalanx.class)); cards.add(new SetCardInfo("Gilt-Leaf Winnower", 99, Rarity.RARE, mage.cards.g.GiltLeafWinnower.class)); cards.add(new SetCardInfo("Gnarlroot Trapper", 100, Rarity.UNCOMMON, mage.cards.g.GnarlrootTrapper.class)); @@ -164,7 +163,6 @@ public final class MagicOrigins extends ExpansionSet { cards.add(new SetCardInfo("Island", 259, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 260, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jace's Sanctum", 61, Rarity.RARE, mage.cards.j.JacesSanctum.class)); - cards.add(new SetCardInfo("Jace, Telepath Unbound", 60, Rarity.MYTHIC, mage.cards.j.JaceTelepathUnbound.class)); cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 60, Rarity.MYTHIC, mage.cards.j.JaceVrynsProdigy.class)); cards.add(new SetCardInfo("Jayemdae Tome", 231, Rarity.UNCOMMON, mage.cards.j.JayemdaeTome.class)); cards.add(new SetCardInfo("Jhessian Thief", 62, Rarity.UNCOMMON, mage.cards.j.JhessianThief.class)); @@ -179,7 +177,6 @@ public final class MagicOrigins extends ExpansionSet { cards.add(new SetCardInfo("Languish", 105, Rarity.RARE, mage.cards.l.Languish.class)); cards.add(new SetCardInfo("Leaf Gilder", 184, Rarity.COMMON, mage.cards.l.LeafGilder.class)); cards.add(new SetCardInfo("Lightning Javelin", 153, Rarity.COMMON, mage.cards.l.LightningJavelin.class)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 106, Rarity.MYTHIC, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Liliana, Heretical Healer", 106, Rarity.MYTHIC, mage.cards.l.LilianaHereticalHealer.class)); cards.add(new SetCardInfo("Llanowar Empath", 185, Rarity.COMMON, mage.cards.l.LlanowarEmpath.class)); cards.add(new SetCardInfo("Llanowar Wastes", 248, Rarity.RARE, mage.cards.l.LlanowarWastes.class)); @@ -209,7 +206,6 @@ public final class MagicOrigins extends ExpansionSet { cards.add(new SetCardInfo("Negate", 65, Rarity.COMMON, mage.cards.n.Negate.class)); cards.add(new SetCardInfo("Nightmare", 282, Rarity.RARE, mage.cards.n.Nightmare.class)); cards.add(new SetCardInfo("Nightsnare", 111, Rarity.COMMON, mage.cards.n.Nightsnare.class)); - cards.add(new SetCardInfo("Nissa, Sage Animist", 189, Rarity.MYTHIC, mage.cards.n.NissaSageAnimist.class)); cards.add(new SetCardInfo("Nissa's Pilgrimage", 190, Rarity.COMMON, mage.cards.n.NissasPilgrimage.class)); cards.add(new SetCardInfo("Nissa's Revelation", 191, Rarity.RARE, mage.cards.n.NissasRevelation.class)); cards.add(new SetCardInfo("Nissa, Vastwood Seer", 189, Rarity.MYTHIC, mage.cards.n.NissaVastwoodSeer.class)); diff --git a/Mage.Sets/src/mage/sets/MagicOriginsPromos.java b/Mage.Sets/src/mage/sets/MagicOriginsPromos.java index 07480981180..6966005667f 100644 --- a/Mage.Sets/src/mage/sets/MagicOriginsPromos.java +++ b/Mage.Sets/src/mage/sets/MagicOriginsPromos.java @@ -35,7 +35,6 @@ public class MagicOriginsPromos extends ExpansionSet { cards.add(new SetCardInfo("Exquisite Firecraft", "143s", Rarity.RARE, mage.cards.e.ExquisiteFirecraft.class)); cards.add(new SetCardInfo("Gaea's Revenge", "177s", Rarity.RARE, mage.cards.g.GaeasRevenge.class)); cards.add(new SetCardInfo("Gideon's Phalanx", "14s", Rarity.RARE, mage.cards.g.GideonsPhalanx.class)); - cards.add(new SetCardInfo("Gideon, Battle-Forged", "23s", Rarity.MYTHIC, mage.cards.g.GideonBattleForged.class)); cards.add(new SetCardInfo("Gilt-Leaf Winnower", "99s", Rarity.RARE, mage.cards.g.GiltLeafWinnower.class)); cards.add(new SetCardInfo("Goblin Piledriver", "151s", Rarity.RARE, mage.cards.g.GoblinPiledriver.class)); cards.add(new SetCardInfo("Graveblade Marauder", "101s", Rarity.RARE, mage.cards.g.GravebladeMarauder.class)); @@ -43,7 +42,6 @@ public class MagicOriginsPromos extends ExpansionSet { cards.add(new SetCardInfo("Hixus, Prison Warden", 19, Rarity.RARE, mage.cards.h.HixusPrisonWarden.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hixus, Prison Warden", "19s", Rarity.RARE, mage.cards.h.HixusPrisonWarden.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Honored Hierarch", "182s", Rarity.RARE, mage.cards.h.HonoredHierarch.class)); - cards.add(new SetCardInfo("Jace, Telepath Unbound", "60s", Rarity.MYTHIC, mage.cards.j.JaceTelepathUnbound.class)); cards.add(new SetCardInfo("Jace, Vryn's Prodigy", "60s", Rarity.MYTHIC, mage.cards.j.JaceVrynsProdigy.class)); cards.add(new SetCardInfo("Knight of the White Orchid", "21s", Rarity.RARE, mage.cards.k.KnightOfTheWhiteOrchid.class)); cards.add(new SetCardInfo("Kothophed, Soul Hoarder", 104, Rarity.RARE, mage.cards.k.KothophedSoulHoarder.class, NON_FULL_USE_VARIOUS)); @@ -52,13 +50,11 @@ public class MagicOriginsPromos extends ExpansionSet { cards.add(new SetCardInfo("Kytheon, Hero of Akros", "23s", Rarity.MYTHIC, mage.cards.k.KytheonHeroOfAkros.class)); cards.add(new SetCardInfo("Languish", 105, Rarity.RARE, mage.cards.l.Languish.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Languish", "105s", Rarity.RARE, mage.cards.l.Languish.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", "106s", Rarity.MYTHIC, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Liliana, Heretical Healer", "106s", Rarity.MYTHIC, mage.cards.l.LilianaHereticalHealer.class)); cards.add(new SetCardInfo("Managorger Hydra", "186s", Rarity.RARE, mage.cards.m.ManagorgerHydra.class)); cards.add(new SetCardInfo("Mizzium Meddler", 64, Rarity.RARE, mage.cards.m.MizziumMeddler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mizzium Meddler", "64s", Rarity.RARE, mage.cards.m.MizziumMeddler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nissa's Revelation", "191s", Rarity.RARE, mage.cards.n.NissasRevelation.class)); - cards.add(new SetCardInfo("Nissa, Sage Animist", "189s", Rarity.MYTHIC, mage.cards.n.NissaSageAnimist.class)); cards.add(new SetCardInfo("Nissa, Vastwood Seer", "189s", Rarity.MYTHIC, mage.cards.n.NissaVastwoodSeer.class)); cards.add(new SetCardInfo("Outland Colossus", "193s", Rarity.RARE, mage.cards.o.OutlandColossus.class)); cards.add(new SetCardInfo("Pia and Kiran Nalaar", 157, Rarity.RARE, mage.cards.p.PiaAndKiranNalaar.class, NON_FULL_USE_VARIOUS)); @@ -73,5 +69,5 @@ public class MagicOriginsPromos extends ExpansionSet { cards.add(new SetCardInfo("Tragic Arrogance", "38s", Rarity.RARE, mage.cards.t.TragicArrogance.class)); cards.add(new SetCardInfo("Vryn Wingmare", "40s", Rarity.RARE, mage.cards.v.VrynWingmare.class)); cards.add(new SetCardInfo("Willbreaker", "84s", Rarity.RARE, mage.cards.w.Willbreaker.class)); - } + } } diff --git a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java index 96ae38826a0..03bc2d1c727 100644 --- a/Mage.Sets/src/mage/sets/MarchOfTheMachine.java +++ b/Mage.Sets/src/mage/sets/MarchOfTheMachine.java @@ -41,7 +41,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Aerial Boost", 2, Rarity.COMMON, mage.cards.a.AerialBoost.class)); cards.add(new SetCardInfo("Aetherblade Agent", 88, Rarity.COMMON, mage.cards.a.AetherbladeAgent.class)); - cards.add(new SetCardInfo("Aetherwing, Golden-Scale Flagship", 234, Rarity.UNCOMMON, mage.cards.a.AetherwingGoldenScaleFlagship.class)); cards.add(new SetCardInfo("Akki Scrapchomper", 130, Rarity.COMMON, mage.cards.a.AkkiScrapchomper.class)); cards.add(new SetCardInfo("Alabaster Host Intercessor", 3, Rarity.COMMON, mage.cards.a.AlabasterHostIntercessor.class)); cards.add(new SetCardInfo("Alabaster Host Sanctifier", 4, Rarity.COMMON, mage.cards.a.AlabasterHostSanctifier.class)); @@ -54,20 +53,16 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Archpriest of Shadows", 356, Rarity.RARE, mage.cards.a.ArchpriestOfShadows.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Archpriest of Shadows", 89, Rarity.RARE, mage.cards.a.ArchpriestOfShadows.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Artistic Refusal", 46, Rarity.UNCOMMON, mage.cards.a.ArtisticRefusal.class)); - cards.add(new SetCardInfo("Ashen Reaper", 232, Rarity.UNCOMMON, mage.cards.a.AshenReaper.class)); cards.add(new SetCardInfo("Assimilate Essence", 47, Rarity.COMMON, mage.cards.a.AssimilateEssence.class)); cards.add(new SetCardInfo("Astral Wingspan", 48, Rarity.UNCOMMON, mage.cards.a.AstralWingspan.class)); cards.add(new SetCardInfo("Atraxa's Fall", 176, Rarity.COMMON, mage.cards.a.AtraxasFall.class)); cards.add(new SetCardInfo("Attentive Skywarden", 7, Rarity.COMMON, mage.cards.a.AttentiveSkywarden.class)); - cards.add(new SetCardInfo("Awaken the Maelstrom", 230, Rarity.RARE, mage.cards.a.AwakenTheMaelstrom.class)); - cards.add(new SetCardInfo("Awakened Skyclave", 194, Rarity.UNCOMMON, mage.cards.a.AwakenedSkyclave.class)); cards.add(new SetCardInfo("Axgard Artisan", 332, Rarity.UNCOMMON, mage.cards.a.AxgardArtisan.class)); cards.add(new SetCardInfo("Ayara, Widow of the Realm", 296, Rarity.RARE, mage.cards.a.AyaraWidowOfTheRealm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ayara, Widow of the Realm", 90, Rarity.RARE, mage.cards.a.AyaraWidowOfTheRealm.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Baral and Kari Zev", 218, Rarity.RARE, mage.cards.b.BaralAndKariZev.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Baral and Kari Zev", 302, Rarity.RARE, mage.cards.b.BaralAndKariZev.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Beamtown Beatstick", 131, Rarity.COMMON, mage.cards.b.BeamtownBeatstick.class)); - cards.add(new SetCardInfo("Belligerent Regisaur", 191, Rarity.RARE, mage.cards.b.BelligerentRegisaur.class)); cards.add(new SetCardInfo("Bladed Battle-Fan", 91, Rarity.COMMON, mage.cards.b.BladedBattleFan.class)); cards.add(new SetCardInfo("Blighted Burgeoning", 177, Rarity.COMMON, mage.cards.b.BlightedBurgeoning.class)); cards.add(new SetCardInfo("Blightreaper Thallid", 92, Rarity.UNCOMMON, mage.cards.b.BlightreaperThallid.class)); @@ -76,7 +71,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Bloodfeather Phoenix", 132, Rarity.RARE, mage.cards.b.BloodfeatherPhoenix.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodfeather Phoenix", 362, Rarity.RARE, mage.cards.b.BloodfeatherPhoenix.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bloodfell Caves", 267, Rarity.COMMON, mage.cards.b.BloodfellCaves.class)); - cards.add(new SetCardInfo("Bloomwielder Dryads", 237, Rarity.UNCOMMON, mage.cards.b.BloomwielderDryads.class)); cards.add(new SetCardInfo("Blossoming Sands", 268, Rarity.COMMON, mage.cards.b.BlossomingSands.class)); cards.add(new SetCardInfo("Bola Slinger", 8, Rarity.COMMON, mage.cards.b.BolaSlinger.class)); cards.add(new SetCardInfo("Bonded Herdbeast", 178, Rarity.COMMON, mage.cards.b.BondedHerdbeast.class)); @@ -89,14 +83,11 @@ 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("Caetus, Sea Tyrant of Segovia", 63, Rarity.RARE, mage.cards.c.CaetusSeaTyrantOfSegovia.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)); cards.add(new SetCardInfo("Change the Equation", 50, Rarity.UNCOMMON, mage.cards.c.ChangeTheEquation.class)); cards.add(new SetCardInfo("Chomping Kavu", 179, Rarity.COMMON, mage.cards.c.ChompingKavu.class)); - cards.add(new SetCardInfo("Chrome Host Hulk", 188, Rarity.UNCOMMON, mage.cards.c.ChromeHostHulk.class)); cards.add(new SetCardInfo("Chrome Host Seedshark", 350, Rarity.RARE, mage.cards.c.ChromeHostSeedshark.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Chrome Host Seedshark", 51, Rarity.RARE, mage.cards.c.ChromeHostSeedshark.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("City on Fire", 135, Rarity.RARE, mage.cards.c.CityOnFire.class, NON_FULL_USE_VARIOUS)); @@ -118,9 +109,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Deadly Derision", 99, Rarity.COMMON, mage.cards.d.DeadlyDerision.class)); cards.add(new SetCardInfo("Deeproot Wayfinder", 184, Rarity.RARE, mage.cards.d.DeeprootWayfinder.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Deeproot Wayfinder", 369, Rarity.RARE, mage.cards.d.DeeprootWayfinder.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Defiant Thundermaw", 149, Rarity.MYTHIC, mage.cards.d.DefiantThundermaw.class)); - cards.add(new SetCardInfo("Deluge of the Dead", 115, Rarity.MYTHIC, mage.cards.d.DelugeOfTheDead.class)); - cards.add(new SetCardInfo("Disciples of the Inferno", 148, Rarity.UNCOMMON, mage.cards.d.DisciplesOfTheInferno.class)); cards.add(new SetCardInfo("Dismal Backwater", 269, Rarity.COMMON, mage.cards.d.DismalBackwater.class)); cards.add(new SetCardInfo("Disturbing Conversion", 54, Rarity.COMMON, mage.cards.d.DisturbingConversion.class)); cards.add(new SetCardInfo("Djeru and Hazoret", 221, Rarity.RARE, mage.cards.d.DjeruAndHazoret.class, NON_FULL_USE_VARIOUS)); @@ -139,7 +127,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Elvish Vatkeeper", 223, Rarity.UNCOMMON, mage.cards.e.ElvishVatkeeper.class)); cards.add(new SetCardInfo("Enduring Bondwarden", 14, Rarity.COMMON, mage.cards.e.EnduringBondwarden.class)); cards.add(new SetCardInfo("Ephara's Dispersal", 55, Rarity.COMMON, mage.cards.e.EpharasDispersal.class)); - cards.add(new SetCardInfo("Ephara, Ever-Sheltering", 23, Rarity.RARE, mage.cards.e.EpharaEverSheltering.class)); cards.add(new SetCardInfo("Errant and Giada", 224, Rarity.RARE, mage.cards.e.ErrantAndGiada.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Errant and Giada", 306, Rarity.RARE, mage.cards.e.ErrantAndGiada.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Essence of Orthodoxy", 323, Rarity.RARE, mage.cards.e.EssenceOfOrthodoxy.class, NON_FULL_USE_VARIOUS)); @@ -165,29 +152,23 @@ 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("Gargantuan Slabhorn", 240, Rarity.UNCOMMON, mage.cards.g.GargantuanSlabhorn.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)); cards.add(new SetCardInfo("Ghalta and Mavren", 386, Rarity.RARE, mage.cards.g.GhaltaAndMavren.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Gift of Compleation", 106, Rarity.UNCOMMON, mage.cards.g.GiftOfCompleation.class)); - cards.add(new SetCardInfo("Gitaxian Spellstalker", 151, Rarity.UNCOMMON, mage.cards.g.GitaxianSpellstalker.class)); cards.add(new SetCardInfo("Glissa, Herald of Predation", 226, Rarity.RARE, mage.cards.g.GlissaHeraldOfPredation.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Glissa, Herald of Predation", 308, Rarity.RARE, mage.cards.g.GlissaHeraldOfPredation.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Glistening Dawn", 187, Rarity.RARE, mage.cards.g.GlisteningDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Glistening Dawn", 371, Rarity.RARE, mage.cards.g.GlisteningDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Glistening Deluge", 107, Rarity.UNCOMMON, mage.cards.g.GlisteningDeluge.class)); - cards.add(new SetCardInfo("Glistening Goremonger", 157, Rarity.COMMON, mage.cards.g.GlisteningGoremonger.class)); cards.add(new SetCardInfo("Gloomfang Mauler", 108, Rarity.COMMON, mage.cards.g.GloomfangMauler.class)); cards.add(new SetCardInfo("Gnottvold Hermit", 188, Rarity.UNCOMMON, mage.cards.g.GnottvoldHermit.class)); cards.add(new SetCardInfo("Golden-Scale Aeronaut", 15, Rarity.COMMON, mage.cards.g.GoldenScaleAeronaut.class)); cards.add(new SetCardInfo("Grafted Butcher", 109, Rarity.RARE, mage.cards.g.GraftedButcher.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grafted Butcher", 359, Rarity.RARE, mage.cards.g.GraftedButcher.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Grandmother Ravi Sengir", 116, Rarity.UNCOMMON, mage.cards.g.GrandmotherRaviSengir.class)); cards.add(new SetCardInfo("Guardian of Ghirapur", 16, Rarity.RARE, mage.cards.g.GuardianOfGhirapur.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guardian of Ghirapur", 345, Rarity.RARE, mage.cards.g.GuardianOfGhirapur.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Guildpact Paragon", 1, Rarity.MYTHIC, mage.cards.g.GuildpactParagon.class)); cards.add(new SetCardInfo("Halo Forager", 227, Rarity.UNCOMMON, mage.cards.h.HaloForager.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Halo Forager", 385, Rarity.UNCOMMON, mage.cards.h.HaloForager.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Halo Hopper", 260, Rarity.COMMON, mage.cards.h.HaloHopper.class)); @@ -196,15 +177,11 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Harried Artisan", 143, Rarity.UNCOMMON, mage.cards.h.HarriedArtisan.class)); cards.add(new SetCardInfo("Heliod, the Radiant Dawn", 17, Rarity.RARE, mage.cards.h.HeliodTheRadiantDawn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Heliod, the Radiant Dawn", 293, Rarity.RARE, mage.cards.h.HeliodTheRadiantDawn.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Heliod, the Warped Eclipse", 17, Rarity.RARE, mage.cards.h.HeliodTheWarpedEclipse.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Heliod, the Warped Eclipse", 293, Rarity.RARE, mage.cards.h.HeliodTheWarpedEclipse.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Herbology Instructor", 189, Rarity.UNCOMMON, mage.cards.h.HerbologyInstructor.class)); - cards.add(new SetCardInfo("Hideous Fleshwheeler", 119, Rarity.UNCOMMON, mage.cards.h.HideousFleshwheeler.class)); cards.add(new SetCardInfo("Hidetsugu and Kairi", 228, Rarity.RARE, mage.cards.h.HidetsuguAndKairi.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hidetsugu and Kairi", 309, Rarity.RARE, mage.cards.h.HidetsuguAndKairi.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hoarding Broodlord", 110, Rarity.RARE, mage.cards.h.HoardingBroodlord.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hoarding Broodlord", 360, Rarity.RARE, mage.cards.h.HoardingBroodlord.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Holy Frazzle-Cannon", 238, Rarity.UNCOMMON, mage.cards.h.HolyFrazzleCannon.class)); cards.add(new SetCardInfo("Ichor Drinker", 111, Rarity.COMMON, mage.cards.i.IchorDrinker.class)); cards.add(new SetCardInfo("Ichor Shade", 112, Rarity.COMMON, mage.cards.i.IchorShade.class)); cards.add(new SetCardInfo("Infected Defector", 18, Rarity.COMMON, mage.cards.i.InfectedDefector.class)); @@ -252,7 +229,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Invasion of Vryn", 64, Rarity.UNCOMMON, mage.cards.i.InvasionOfVryn.class)); cards.add(new SetCardInfo("Invasion of Xerex", 242, Rarity.UNCOMMON, mage.cards.i.InvasionOfXerex.class)); cards.add(new SetCardInfo("Invasion of Zendikar", 194, Rarity.UNCOMMON, mage.cards.i.InvasionOfZendikar.class)); - cards.add(new SetCardInfo("Invocation of the Founders", 61, Rarity.RARE, mage.cards.i.InvocationOfTheFounders.class)); cards.add(new SetCardInfo("Iridescent Blademaster", 195, Rarity.COMMON, mage.cards.i.IridescentBlademaster.class)); cards.add(new SetCardInfo("Island", 278, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 284, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); @@ -276,14 +252,8 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Kor Halberd", 27, Rarity.COMMON, mage.cards.k.KorHalberd.class)); cards.add(new SetCardInfo("Kroxa and Kunoros", 245, Rarity.MYTHIC, mage.cards.k.KroxaAndKunoros.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kroxa and Kunoros", 312, Rarity.MYTHIC, mage.cards.k.KroxaAndKunoros.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Kyren Flamewright", 147, Rarity.UNCOMMON, mage.cards.k.KyrenFlamewright.class)); - cards.add(new SetCardInfo("Lazotep Convert", 231, Rarity.UNCOMMON, mage.cards.l.LazotepConvert.class)); - cards.add(new SetCardInfo("Leyline Surge", 193, Rarity.MYTHIC, mage.cards.l.LeylineSurge.class)); - cards.add(new SetCardInfo("Lightshield Array", 22, Rarity.RARE, mage.cards.l.LightshieldArray.class)); cards.add(new SetCardInfo("Lithomantic Barrage", 152, Rarity.UNCOMMON, mage.cards.l.LithomanticBarrage.class)); - cards.add(new SetCardInfo("Malady Invoker", 189, Rarity.UNCOMMON, mage.cards.m.MaladyInvoker.class)); cards.add(new SetCardInfo("Marauding Dreadship", 153, Rarity.COMMON, mage.cards.m.MaraudingDreadship.class)); - cards.add(new SetCardInfo("Marchesa, Resolute Monarch", 114, Rarity.RARE, mage.cards.m.MarchesaResoluteMonarch.class)); cards.add(new SetCardInfo("Marshal of Zhalfir", 246, Rarity.UNCOMMON, mage.cards.m.MarshalOfZhalfir.class)); cards.add(new SetCardInfo("Meeting of Minds", 66, Rarity.COMMON, mage.cards.m.MeetingOfMinds.class)); cards.add(new SetCardInfo("Merciless Repurposing", 117, Rarity.UNCOMMON, mage.cards.m.MercilessRepurposing.class)); @@ -311,12 +281,10 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Omnath, Locus of All", 387, Rarity.RARE, mage.cards.o.OmnathLocusOfAll.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Onakke Javelineer", 156, Rarity.COMMON, mage.cards.o.OnakkeJavelineer.class)); cards.add(new SetCardInfo("Oracle of Tragedy", 71, Rarity.UNCOMMON, mage.cards.o.OracleOfTragedy.class)); - cards.add(new SetCardInfo("Order of the Alabaster Host", 72, Rarity.COMMON, mage.cards.o.OrderOfTheAlabasterHost.class)); cards.add(new SetCardInfo("Order of the Mirror", 72, Rarity.COMMON, mage.cards.o.OrderOfTheMirror.class)); cards.add(new SetCardInfo("Orthion, Hero of Lavabrink", 334, Rarity.RARE, mage.cards.o.OrthionHeroOfLavabrink.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Orthion, Hero of Lavabrink", 379, Rarity.RARE, mage.cards.o.OrthionHeroOfLavabrink.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Overgrown Pest", 197, Rarity.COMMON, mage.cards.o.OvergrownPest.class)); - cards.add(new SetCardInfo("Overloaded Mage-Ring", 64, Rarity.UNCOMMON, mage.cards.o.OverloadedMageRing.class)); cards.add(new SetCardInfo("Ozolith, the Shattered Spire", 198, Rarity.RARE, mage.cards.o.OzolithTheShatteredSpire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ozolith, the Shattered Spire", 372, Rarity.RARE, mage.cards.o.OzolithTheShatteredSpire.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Phyrexian Archivist", 262, Rarity.COMMON, mage.cards.p.PhyrexianArchivist.class)); @@ -324,7 +292,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Phyrexian Censor", 31, Rarity.UNCOMMON, mage.cards.p.PhyrexianCensor.class)); cards.add(new SetCardInfo("Phyrexian Gargantua", 121, Rarity.UNCOMMON, mage.cards.p.PhyrexianGargantua.class)); cards.add(new SetCardInfo("Phyrexian Pegasus", 324, Rarity.COMMON, mage.cards.p.PhyrexianPegasus.class)); - cards.add(new SetCardInfo("Phyrexian Skyflayer", 143, Rarity.UNCOMMON, mage.cards.p.PhyrexianSkyflayer.class)); cards.add(new SetCardInfo("Pile On", 122, Rarity.RARE, mage.cards.p.PileOn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Pile On", 361, Rarity.RARE, mage.cards.p.PileOn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Placid Rottentail", 199, Rarity.COMMON, mage.cards.p.PlacidRottentail.class)); @@ -333,16 +300,11 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Plains", 283, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Polukranos Reborn", 200, Rarity.RARE, mage.cards.p.PolukranosReborn.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Polukranos Reborn", 300, Rarity.RARE, mage.cards.p.PolukranosReborn.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Polukranos, Engine of Ruin", 200, Rarity.RARE, mage.cards.p.PolukranosEngineOfRuin.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Polukranos, Engine of Ruin", 300, Rarity.RARE, mage.cards.p.PolukranosEngineOfRuin.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Portent Tracker", 201, Rarity.COMMON, mage.cards.p.PortentTracker.class)); cards.add(new SetCardInfo("Preening Champion", 73, Rarity.COMMON, mage.cards.p.PreeningChampion.class)); - cards.add(new SetCardInfo("Prickle Faeries", 113, Rarity.UNCOMMON, mage.cards.p.PrickleFaeries.class)); - cards.add(new SetCardInfo("Primordial Plasm", 192, Rarity.UNCOMMON, mage.cards.p.PrimordialPlasm.class)); cards.add(new SetCardInfo("Progenitor Exarch", 32, Rarity.RARE, mage.cards.p.ProgenitorExarch.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Progenitor Exarch", 348, Rarity.RARE, mage.cards.p.ProgenitorExarch.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Protocol Knight", 74, Rarity.COMMON, mage.cards.p.ProtocolKnight.class)); - cards.add(new SetCardInfo("Pyre of the World Tree", 145, Rarity.RARE, mage.cards.p.PyreOfTheWorldTree.class)); cards.add(new SetCardInfo("Pyretic Prankster", 157, Rarity.COMMON, mage.cards.p.PyreticPrankster.class)); cards.add(new SetCardInfo("Quintorius, Loremaster", 250, Rarity.RARE, mage.cards.q.QuintoriusLoremaster.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Quintorius, Loremaster", 314, Rarity.RARE, mage.cards.q.QuintoriusLoremaster.class, NON_FULL_USE_VARIOUS)); @@ -359,13 +321,9 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Realmbreaker, the Invasion Tree", 374, Rarity.RARE, mage.cards.r.RealmbreakerTheInvasionTree.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Redcap Heelslasher", 161, Rarity.COMMON, mage.cards.r.RedcapHeelslasher.class)); cards.add(new SetCardInfo("Referee Squad", 327, Rarity.UNCOMMON, mage.cards.r.RefereeSquad.class)); - cards.add(new SetCardInfo("Refraction Elemental", 146, Rarity.RARE, mage.cards.r.RefractionElemental.class)); cards.add(new SetCardInfo("Render Inert", 123, Rarity.UNCOMMON, mage.cards.r.RenderInert.class)); cards.add(new SetCardInfo("Rona, Herald of Invasion", 295, Rarity.RARE, mage.cards.r.RonaHeraldOfInvasion.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Rona, Herald of Invasion", 75, Rarity.RARE, mage.cards.r.RonaHeraldOfInvasion.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Rona, Tolarian Obliterator", 295, Rarity.RARE, mage.cards.r.RonaTolarianObliterator.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Rona, Tolarian Obliterator", 75, Rarity.RARE, mage.cards.r.RonaTolarianObliterator.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Rooftop Saboteurs", 62, Rarity.UNCOMMON, mage.cards.r.RooftopSaboteurs.class)); cards.add(new SetCardInfo("Rugged Highlands", 271, Rarity.COMMON, mage.cards.r.RuggedHighlands.class)); cards.add(new SetCardInfo("Ruins Recluse", 336, Rarity.UNCOMMON, mage.cards.r.RuinsRecluse.class)); cards.add(new SetCardInfo("Saiba Cryptomancer", 76, Rarity.COMMON, mage.cards.s.SaibaCryptomancer.class)); @@ -384,9 +342,7 @@ 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("Serra Faithkeeper", 21, Rarity.UNCOMMON, mage.cards.s.SerraFaithkeeper.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)); cards.add(new SetCardInfo("Sheoldred", 297, Rarity.MYTHIC, mage.cards.s.Sheoldred.class, NON_FULL_USE_VARIOUS)); @@ -395,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)); @@ -418,26 +373,12 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Tandem Takedown", 208, Rarity.UNCOMMON, mage.cards.t.TandemTakedown.class)); cards.add(new SetCardInfo("Tangled Skyline", 209, Rarity.UNCOMMON, mage.cards.t.TangledSkyline.class)); cards.add(new SetCardInfo("Tarkir Duneshaper", 43, Rarity.COMMON, mage.cards.t.TarkirDuneshaper.class)); - cards.add(new SetCardInfo("Teferi Akosa of Zhalfir", 239, Rarity.MYTHIC, mage.cards.t.TeferiAkosaOfZhalfir.class)); cards.add(new SetCardInfo("Temporal Cleansing", 80, Rarity.COMMON, mage.cards.t.TemporalCleansing.class)); cards.add(new SetCardInfo("Tenured Oilcaster", 126, Rarity.COMMON, mage.cards.t.TenuredOilcaster.class)); cards.add(new SetCardInfo("Terror of Towashi", 331, Rarity.RARE, mage.cards.t.TerrorOfTowashi.class, NON_FULL_USE_VARIOUS)); 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 Broken Sky", 241, Rarity.RARE, mage.cards.t.TheBrokenSky.class)); - 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 Synthesis", 294, Rarity.MYTHIC, mage.cards.t.TheGreatSynthesis.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Great Synthesis", 339, Rarity.MYTHIC, mage.cards.t.TheGreatSynthesis.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Great Synthesis", 65, Rarity.MYTHIC, mage.cards.t.TheGreatSynthesis.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)); @@ -451,16 +392,13 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Traumatic Revelation", 127, Rarity.COMMON, mage.cards.t.TraumaticRevelation.class)); cards.add(new SetCardInfo("Tribute to the World Tree", 211, Rarity.RARE, mage.cards.t.TributeToTheWorldTree.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tribute to the World Tree", 373, Rarity.RARE, mage.cards.t.TributeToTheWorldTree.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Truga Cliffcharger", 233, Rarity.UNCOMMON, mage.cards.t.TrugaCliffcharger.class)); cards.add(new SetCardInfo("Unseal the Necropolis", 128, Rarity.COMMON, mage.cards.u.UnsealTheNecropolis.class)); cards.add(new SetCardInfo("Urabrask", 169, Rarity.MYTHIC, mage.cards.u.Urabrask.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Urabrask", 299, Rarity.MYTHIC, mage.cards.u.Urabrask.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Urabrask", 341, Rarity.MYTHIC, mage.cards.u.Urabrask.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Urn of Godfire", 266, Rarity.COMMON, mage.cards.u.UrnOfGodfire.class)); - cards.add(new SetCardInfo("Valor's Reach Tag Team", 235, Rarity.UNCOMMON, mage.cards.v.ValorsReachTagTeam.class)); cards.add(new SetCardInfo("Vanquish the Weak", 129, Rarity.COMMON, mage.cards.v.VanquishTheWeak.class)); cards.add(new SetCardInfo("Vengeant Earth", 212, Rarity.COMMON, mage.cards.v.VengeantEarth.class)); - cards.add(new SetCardInfo("Vertex Paladin", 242, Rarity.UNCOMMON, mage.cards.v.VertexPaladin.class)); cards.add(new SetCardInfo("Volcanic Spite", 170, Rarity.COMMON, mage.cards.v.VolcanicSpite.class)); cards.add(new SetCardInfo("Voldaren Thrillseeker", 171, Rarity.RARE, mage.cards.v.VoldarenThrillseeker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Voldaren Thrillseeker", 367, Rarity.RARE, mage.cards.v.VoldarenThrillseeker.class, NON_FULL_USE_VARIOUS)); @@ -473,7 +411,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Wicked Slumber", 84, Rarity.UNCOMMON, mage.cards.w.WickedSlumber.class)); cards.add(new SetCardInfo("Wildwood Escort", 216, Rarity.COMMON, mage.cards.w.WildwoodEscort.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 276, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); - cards.add(new SetCardInfo("Winnowing Forces", 236, Rarity.UNCOMMON, mage.cards.w.WinnowingForces.class)); cards.add(new SetCardInfo("Wrenn and Realmbreaker", 217, Rarity.MYTHIC, mage.cards.w.WrennAndRealmbreaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wrenn and Realmbreaker", 322, Rarity.MYTHIC, mage.cards.w.WrennAndRealmbreaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wrenn's Resolve", 173, Rarity.COMMON, mage.cards.w.WrennsResolve.class)); @@ -485,7 +422,6 @@ public final class MarchOfTheMachine extends ExpansionSet { cards.add(new SetCardInfo("Zephyr Winder", 328, Rarity.COMMON, mage.cards.z.ZephyrWinder.class)); cards.add(new SetCardInfo("Zhalfirin Lancer", 45, Rarity.UNCOMMON, mage.cards.z.ZhalfirinLancer.class)); cards.add(new SetCardInfo("Zhalfirin Shapecraft", 87, Rarity.COMMON, mage.cards.z.ZhalfirinShapecraft.class)); - cards.add(new SetCardInfo("Zilortha, Apex of Ikoria", 190, Rarity.RARE, mage.cards.z.ZilorthaApexOfIkoria.class)); cards.add(new SetCardInfo("Zimone and Dina", 257, Rarity.MYTHIC, mage.cards.z.ZimoneAndDina.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zimone and Dina", 318, Rarity.MYTHIC, mage.cards.z.ZimoneAndDina.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zurgo and Ojutai", 258, Rarity.MYTHIC, mage.cards.z.ZurgoAndOjutai.class, NON_FULL_USE_VARIOUS)); @@ -518,10 +454,10 @@ public final class MarchOfTheMachine extends ExpansionSet { .forEach(cardInfo -> inBoosterMap.put("MUL_" + cardInfo.getCardNumber(), cardInfo)); } - @Override - public BoosterCollator createCollator() { - return new MarchOfTheMachineCollator(); - } + @Override + public BoosterCollator createCollator() { + return new MarchOfTheMachineCollator(); + } } // Booster collation info from https://www.lethe.xyz/mtg/collation/mom.html @@ -597,7 +533,7 @@ class MarchOfTheMachineCollator implements BoosterCollator { AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, - AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, + AABBBCCC, AABBBCCC, AABBBCCC, AABBBCCC, AAABBCCC, AAABBCCC, AAABBCCC, AAABBCCC, AAABBCCC, AAABBCCC, AAABBCCC, AAABBBCC, AAABBBCC, AAABBBCC, AAABBBCC, AAABBBCC, @@ -614,7 +550,7 @@ class MarchOfTheMachineCollator implements BoosterCollator { private final RarityConfiguration uncommonRuns = new RarityConfiguration( RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, - RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, + RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, RuUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, URUUU, UuRUU, UuRUU, UuRUU, UuRUU, UuRUU, UuRUU, UuRUU, UuRUU, UuRUU, UuRUU, 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/PioneerMasters.java b/Mage.Sets/src/mage/sets/PioneerMasters.java index 7e1e7b012f8..16d8046ec03 100644 --- a/Mage.Sets/src/mage/sets/PioneerMasters.java +++ b/Mage.Sets/src/mage/sets/PioneerMasters.java @@ -166,7 +166,6 @@ public class PioneerMasters extends ExpansionSet { cards.add(new SetCardInfo("Ghor-Clan Rampager", 226, Rarity.UNCOMMON, mage.cards.g.GhorClanRampager.class)); cards.add(new SetCardInfo("Ghostblade Eidolon", 13, Rarity.COMMON, mage.cards.g.GhostbladeEidolon.class)); cards.add(new SetCardInfo("Gideon, Ally of Zendikar", 14, Rarity.MYTHIC, mage.cards.g.GideonAllyOfZendikar.class)); - cards.add(new SetCardInfo("Gideon, Battle-Forged", 23, Rarity.MYTHIC, mage.cards.g.GideonBattleForged.class)); cards.add(new SetCardInfo("Gift of Orzhova", 307, Rarity.UNCOMMON, mage.cards.g.GiftOfOrzhova.class)); cards.add(new SetCardInfo("Give // Take", 389, Rarity.UNCOMMON, mage.cards.g.GiveTake.class)); cards.add(new SetCardInfo("Gladecover Scout", 175, Rarity.COMMON, mage.cards.g.GladecoverScout.class)); @@ -205,7 +204,6 @@ public class PioneerMasters extends ExpansionSet { cards.add(new SetCardInfo("Izzet Guildgate", 267, Rarity.COMMON, mage.cards.i.IzzetGuildgate.class)); cards.add(new SetCardInfo("Jace, Architect of Thought", 329, Rarity.MYTHIC, mage.cards.j.JaceArchitectOfThought.class)); cards.add(new SetCardInfo("Jace, Memory Adept", 330, Rarity.MYTHIC, mage.cards.j.JaceMemoryAdept.class)); - cards.add(new SetCardInfo("Jace, Telepath Unbound", 60, Rarity.MYTHIC, mage.cards.j.JaceTelepathUnbound.class)); cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 60, Rarity.MYTHIC, mage.cards.j.JaceVrynsProdigy.class)); cards.add(new SetCardInfo("Jarad's Orders", 390, Rarity.RARE, mage.cards.j.JaradsOrders.class)); cards.add(new SetCardInfo("Jhessian Thief", 61, Rarity.UNCOMMON, mage.cards.j.JhessianThief.class)); @@ -231,7 +229,6 @@ public class PioneerMasters extends ExpansionSet { cards.add(new SetCardInfo("Lifebane Zombie", 95, Rarity.RARE, mage.cards.l.LifebaneZombie.class)); cards.add(new SetCardInfo("Liliana of the Dark Realms", 334, Rarity.MYTHIC, mage.cards.l.LilianaOfTheDarkRealms.class)); cards.add(new SetCardInfo("Liliana Vess", 335, Rarity.MYTHIC, mage.cards.l.LilianaVess.class)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 96, Rarity.MYTHIC, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Liliana, Heretical Healer", 96, Rarity.MYTHIC, mage.cards.l.LilianaHereticalHealer.class)); cards.add(new SetCardInfo("Limits of Solidarity", 375, Rarity.UNCOMMON, mage.cards.l.LimitsOfSolidarity.class)); cards.add(new SetCardInfo("Linvala, the Preserver", 25, Rarity.RARE, mage.cards.l.LinvalaThePreserver.class)); @@ -265,7 +262,6 @@ public class PioneerMasters extends ExpansionSet { cards.add(new SetCardInfo("Nightveil Specter", 314, Rarity.UNCOMMON, mage.cards.n.NightveilSpecter.class)); cards.add(new SetCardInfo("Nimbus Naiad", 67, Rarity.COMMON, mage.cards.n.NimbusNaiad.class)); cards.add(new SetCardInfo("Nissa's Pilgrimage", 348, Rarity.UNCOMMON, mage.cards.n.NissasPilgrimage.class)); - cards.add(new SetCardInfo("Nissa, Sage Animist", 187, Rarity.MYTHIC, mage.cards.n.NissaSageAnimist.class)); cards.add(new SetCardInfo("Nissa, Vastwood Seer", 187, Rarity.MYTHIC, mage.cards.n.NissaVastwoodSeer.class)); cards.add(new SetCardInfo("Nissa, Voice of Zendikar", 188, Rarity.MYTHIC, mage.cards.n.NissaVoiceOfZendikar.class)); cards.add(new SetCardInfo("Nivix Cyclops", 234, Rarity.COMMON, mage.cards.n.NivixCyclops.class)); diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java index 07b11bafc73..03e984070f9 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java @@ -45,7 +45,6 @@ public final class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Aquatic Incursion", 32, Rarity.UNCOMMON, mage.cards.a.AquaticIncursion.class)); cards.add(new SetCardInfo("Arch of Orazca", 185, Rarity.RARE, mage.cards.a.ArchOfOrazca.class)); cards.add(new SetCardInfo("Arterial Flow", 62, Rarity.UNCOMMON, mage.cards.a.ArterialFlow.class)); - cards.add(new SetCardInfo("Atzal, Cave of Eternity", 160, Rarity.RARE, mage.cards.a.AtzalCaveOfEternity.class)); cards.add(new SetCardInfo("Atzocan Seer", 153, Rarity.UNCOMMON, mage.cards.a.AtzocanSeer.class)); cards.add(new SetCardInfo("Awakened Amalgam", 175, Rarity.RARE, mage.cards.a.AwakenedAmalgam.class)); cards.add(new SetCardInfo("Azor's Gateway", 176, Rarity.MYTHIC, mage.cards.a.AzorsGateway.class)); @@ -110,7 +109,6 @@ public final class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Goblin Trailblazer", 105, Rarity.COMMON, mage.cards.g.GoblinTrailblazer.class)); cards.add(new SetCardInfo("Golden Demise", 73, Rarity.UNCOMMON, mage.cards.g.GoldenDemise.class)); cards.add(new SetCardInfo("Golden Guardian", 179, Rarity.RARE, mage.cards.g.GoldenGuardian.class)); - cards.add(new SetCardInfo("Gold-Forge Garrison", 179, Rarity.RARE, mage.cards.g.GoldForgeGarrison.class)); cards.add(new SetCardInfo("Grasping Scoundrel", 74, Rarity.COMMON, mage.cards.g.GraspingScoundrel.class)); cards.add(new SetCardInfo("Gruesome Fate", 75, Rarity.COMMON, mage.cards.g.GruesomeFate.class)); cards.add(new SetCardInfo("Hadana's Climb", 158, Rarity.RARE, mage.cards.h.HadanasClimb.class)); @@ -141,7 +139,6 @@ public final class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Mastermind's Acquisition", 77, Rarity.RARE, mage.cards.m.MastermindsAcquisition.class)); cards.add(new SetCardInfo("Mausoleum Harpy", 78, Rarity.UNCOMMON, mage.cards.m.MausoleumHarpy.class)); cards.add(new SetCardInfo("Merfolk Mistbinder", 164, Rarity.UNCOMMON, mage.cards.m.MerfolkMistbinder.class)); - cards.add(new SetCardInfo("Metzali, Tower of Triumph", 165, Rarity.RARE, mage.cards.m.MetzaliTowerOfTriumph.class)); cards.add(new SetCardInfo("Mist-Cloaked Herald", 43, Rarity.COMMON, mage.cards.m.MistCloakedHerald.class)); cards.add(new SetCardInfo("Moment of Craving", 79, Rarity.COMMON, mage.cards.m.MomentOfCraving.class)); cards.add(new SetCardInfo("Moment of Triumph", 15, Rarity.COMMON, mage.cards.m.MomentOfTriumph.class)); @@ -226,14 +223,12 @@ public final class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Tilonalli's Crown", 120, Rarity.COMMON, mage.cards.t.TilonallisCrown.class)); cards.add(new SetCardInfo("Tilonalli's Summoner", 121, Rarity.RARE, mage.cards.t.TilonallisSummoner.class)); cards.add(new SetCardInfo("Timestream Navigator", 59, Rarity.MYTHIC, mage.cards.t.TimestreamNavigator.class)); - cards.add(new SetCardInfo("Tomb of the Dusk Rose", 166, Rarity.RARE, mage.cards.t.TombOfTheDuskRose.class)); cards.add(new SetCardInfo("Tomb Robber", 87, Rarity.RARE, mage.cards.t.TombRobber.class)); cards.add(new SetCardInfo("Trapjaw Tyrant", 29, Rarity.MYTHIC, mage.cards.t.TrapjawTyrant.class)); cards.add(new SetCardInfo("Traveler's Amulet", 184, Rarity.COMMON, mage.cards.t.TravelersAmulet.class)); 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)); @@ -242,7 +237,6 @@ public final class RivalsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Warkite Marauder", 60, Rarity.RARE, mage.cards.w.WarkiteMarauder.class)); cards.add(new SetCardInfo("Waterknot", 61, Rarity.COMMON, mage.cards.w.Waterknot.class)); cards.add(new SetCardInfo("Wayward Swordtooth", 150, Rarity.RARE, mage.cards.w.WaywardSwordtooth.class)); - cards.add(new SetCardInfo("Winged Temple of Orazca", 158, Rarity.RARE, mage.cards.w.WingedTempleOfOrazca.class)); cards.add(new SetCardInfo("Woodland Stream", 191, Rarity.UNCOMMON, mage.cards.w.WoodlandStream.class)); cards.add(new SetCardInfo("World Shaper", 151, Rarity.RARE, mage.cards.w.WorldShaper.class)); cards.add(new SetCardInfo("Zacama, Primal Calamity", 174, Rarity.MYTHIC, mage.cards.z.ZacamaPrimalCalamity.class)); diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java b/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java index d01a374be83..b4271b59ac6 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalanPromos.java @@ -25,7 +25,6 @@ public class RivalsOfIxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Angrath, the Flame-Chained", "152s", Rarity.MYTHIC, mage.cards.a.AngrathTheFlameChained.class)); cards.add(new SetCardInfo("Arch of Orazca", "185p", Rarity.RARE, mage.cards.a.ArchOfOrazca.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arch of Orazca", "185s", Rarity.RARE, mage.cards.a.ArchOfOrazca.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Atzal, Cave of Eternity", "160s", Rarity.RARE, mage.cards.a.AtzalCaveOfEternity.class)); cards.add(new SetCardInfo("Awakened Amalgam", "175s", Rarity.RARE, mage.cards.a.AwakenedAmalgam.class)); cards.add(new SetCardInfo("Azor's Gateway", "176s", Rarity.MYTHIC, mage.cards.a.AzorsGateway.class)); cards.add(new SetCardInfo("Azor, the Lawbringer", "154s", Rarity.MYTHIC, mage.cards.a.AzorTheLawbringer.class)); @@ -53,7 +52,6 @@ public class RivalsOfIxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ghalta, Primal Hunger", "130p", Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ghalta, Primal Hunger", "130s", Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Gold-Forge Garrison", "179s", Rarity.RARE, mage.cards.g.GoldForgeGarrison.class)); cards.add(new SetCardInfo("Golden Guardian", "179s", Rarity.RARE, mage.cards.g.GoldenGuardian.class)); cards.add(new SetCardInfo("Hadana's Climb", "158s", Rarity.RARE, mage.cards.h.HadanasClimb.class)); cards.add(new SetCardInfo("Huatli, Radiant Champion", "159s", Rarity.MYTHIC, mage.cards.h.HuatliRadiantChampion.class)); @@ -65,7 +63,6 @@ public class RivalsOfIxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Kumena, Tyrant of Orazca", "162s", Rarity.MYTHIC, mage.cards.k.KumenaTyrantOfOrazca.class)); cards.add(new SetCardInfo("Mastermind's Acquisition", "77p", Rarity.RARE, mage.cards.m.MastermindsAcquisition.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mastermind's Acquisition", "77s", Rarity.RARE, mage.cards.m.MastermindsAcquisition.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Metzali, Tower of Triumph", "165s", Rarity.RARE, mage.cards.m.MetzaliTowerOfTriumph.class)); cards.add(new SetCardInfo("Nezahal, Primal Tide", "45p", Rarity.RARE, mage.cards.n.NezahalPrimalTide.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nezahal, Primal Tide", "45s", Rarity.RARE, mage.cards.n.NezahalPrimalTide.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Paladin of Atonement", "16s", Rarity.RARE, mage.cards.p.PaladinOfAtonement.class)); @@ -103,18 +100,15 @@ public class RivalsOfIxalanPromos extends ExpansionSet { cards.add(new SetCardInfo("Tilonalli's Summoner", "121p", Rarity.RARE, mage.cards.t.TilonallisSummoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tilonalli's Summoner", "121s", Rarity.RARE, mage.cards.t.TilonallisSummoner.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Timestream Navigator", "59s", Rarity.MYTHIC, mage.cards.t.TimestreamNavigator.class)); - cards.add(new SetCardInfo("Tomb of the Dusk Rose", "166s", Rarity.RARE, mage.cards.t.TombOfTheDuskRose.class)); 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)); cards.add(new SetCardInfo("Warkite Marauder", "60s", Rarity.RARE, mage.cards.w.WarkiteMarauder.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wayward Swordtooth", "150p", Rarity.RARE, mage.cards.w.WaywardSwordtooth.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Wayward Swordtooth", "150s", Rarity.RARE, mage.cards.w.WaywardSwordtooth.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Winged Temple of Orazca", "158s", Rarity.RARE, mage.cards.w.WingedTempleOfOrazca.class)); cards.add(new SetCardInfo("World Shaper", "151p", Rarity.RARE, mage.cards.w.WorldShaper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("World Shaper", "151s", Rarity.RARE, mage.cards.w.WorldShaper.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Zacama, Primal Calamity", "174p", Rarity.MYTHIC, mage.cards.z.ZacamaPrimalCalamity.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/SanDiegoComicCon2015.java b/Mage.Sets/src/mage/sets/SanDiegoComicCon2015.java index ebe390ac11f..53cb80d8f20 100644 --- a/Mage.Sets/src/mage/sets/SanDiegoComicCon2015.java +++ b/Mage.Sets/src/mage/sets/SanDiegoComicCon2015.java @@ -21,13 +21,9 @@ public class SanDiegoComicCon2015 extends ExpansionSet { this.hasBasicLands = false; cards.add(new SetCardInfo("Chandra, Fire of Kaladesh", 135, Rarity.MYTHIC, mage.cards.c.ChandraFireOfKaladesh.class)); - cards.add(new SetCardInfo("Gideon, Battle-Forged", 23, Rarity.MYTHIC, mage.cards.g.GideonBattleForged.class)); - cards.add(new SetCardInfo("Jace, Telepath Unbound", 60, Rarity.MYTHIC, mage.cards.j.JaceTelepathUnbound.class)); cards.add(new SetCardInfo("Jace, Vryn's Prodigy", 60, Rarity.MYTHIC, mage.cards.j.JaceVrynsProdigy.class)); cards.add(new SetCardInfo("Kytheon, Hero of Akros", 23, Rarity.MYTHIC, mage.cards.k.KytheonHeroOfAkros.class)); - cards.add(new SetCardInfo("Liliana, Defiant Necromancer", 106, Rarity.MYTHIC, mage.cards.l.LilianaDefiantNecromancer.class)); cards.add(new SetCardInfo("Liliana, Heretical Healer", 106, Rarity.MYTHIC, mage.cards.l.LilianaHereticalHealer.class)); cards.add(new SetCardInfo("Nissa, Vastwood Seer", 189, Rarity.MYTHIC, mage.cards.n.NissaVastwoodSeer.class)); - cards.add(new SetCardInfo("Nissa, Sage Animist", 189, Rarity.MYTHIC, mage.cards.n.NissaSageAnimist.class)); } } diff --git a/Mage.Sets/src/mage/sets/SecretLairDrop.java b/Mage.Sets/src/mage/sets/SecretLairDrop.java index 44f8823b6ac..bb95ee1e5a5 100644 --- a/Mage.Sets/src/mage/sets/SecretLairDrop.java +++ b/Mage.Sets/src/mage/sets/SecretLairDrop.java @@ -616,7 +616,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Rogue's Passage", 607, Rarity.RARE, mage.cards.r.RoguesPassage.class)); cards.add(new SetCardInfo("Darksteel Citadel", 608, Rarity.RARE, mage.cards.d.DarksteelCitadel.class)); cards.add(new SetCardInfo("Havengul Laboratory", 609, Rarity.RARE, mage.cards.h.HavengulLaboratory.class)); - cards.add(new SetCardInfo("Havengul Mystery", 609, Rarity.RARE, mage.cards.h.HavengulMystery.class)); cards.add(new SetCardInfo("Bonescythe Sliver", 610, Rarity.RARE, mage.cards.b.BonescytheSliver.class)); cards.add(new SetCardInfo("Constricting Sliver", 611, Rarity.RARE, mage.cards.c.ConstrictingSliver.class)); cards.add(new SetCardInfo("Essence Sliver", 612, Rarity.RARE, mage.cards.e.EssenceSliver.class)); @@ -1062,9 +1061,7 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Archangel Avacyn", 1156, Rarity.MYTHIC, mage.cards.a.ArchangelAvacyn.class, NON_FULL_USE_VARIOUS)); 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("Nicol Bolas, the Arisen", 1158, Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.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)); @@ -1117,9 +1114,7 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Archangel Avacyn", 1209, Rarity.MYTHIC, mage.cards.a.ArchangelAvacyn.class, NON_FULL_USE_VARIOUS)); 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("Nicol Bolas, the Arisen", 1211, Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.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)); @@ -1149,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)); @@ -1464,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)); @@ -1610,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)); @@ -2133,7 +2125,6 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Swords to Plowshares", 2167, Rarity.RARE, mage.cards.s.SwordsToPlowshares.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Baral, Chief of Compliance", 2168, Rarity.RARE, mage.cards.b.BaralChiefOfCompliance.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Garruk Relentless", 2169, Rarity.MYTHIC, mage.cards.g.GarrukRelentless.class)); - cards.add(new SetCardInfo("Garruk, the Veil-Cursed", 2169, Rarity.MYTHIC, mage.cards.g.GarrukTheVeilCursed.class)); cards.add(new SetCardInfo("Reaper King", 2170, Rarity.RARE, mage.cards.r.ReaperKing.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Glen Elendra Archmage", 2171, Rarity.RARE, mage.cards.g.GlenElendraArchmage.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guardian Project", 2172, Rarity.MYTHIC, mage.cards.g.GuardianProject.class)); @@ -2178,6 +2169,7 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Teferi's Ageless Insight", 2214, Rarity.RARE, mage.cards.t.TeferisAgelessInsight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Teferi's Ageless Insight", "2214b", Rarity.RARE, mage.cards.t.TeferisAgelessInsight.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Iroas, God of Victory", 2215, Rarity.MYTHIC, mage.cards.i.IroasGodOfVictory.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Nathan Drake, Treasure Hunter", 2216, Rarity.MYTHIC, mage.cards.n.NathanDrakeTreasureHunter.class)); cards.add(new SetCardInfo("Midnight Clock", 2217, Rarity.RARE, mage.cards.m.MidnightClock.class)); cards.add(new SetCardInfo("Whip of Erebos", 2218, Rarity.RARE, mage.cards.w.WhipOfErebos.class)); cards.add(new SetCardInfo("Chain Reaction", 2219, Rarity.RARE, mage.cards.c.ChainReaction.class)); @@ -2187,6 +2179,7 @@ public class SecretLairDrop extends ExpansionSet { cards.add(new SetCardInfo("Blightsteel Colossus", 2223, Rarity.MYTHIC, mage.cards.b.BlightsteelColossus.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tarrian's Soulcleaver", 2224, Rarity.RARE, mage.cards.t.TarriansSoulcleaver.class)); cards.add(new SetCardInfo("Meteor Golem", 2225, Rarity.RARE, mage.cards.m.MeteorGolem.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jin Sakai, Ghost of Tsushima", 2226, Rarity.MYTHIC, mage.cards.j.JinSakaiGhostOfTsushima.class)); cards.add(new SetCardInfo("Path to Exile", 2227, Rarity.RARE, mage.cards.p.PathToExile.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Borne Upon a Wind", 2228, Rarity.RARE, mage.cards.b.BorneUponAWind.class)); cards.add(new SetCardInfo("Ghostly Flicker", 2229, Rarity.RARE, mage.cards.g.GhostlyFlicker.class)); diff --git a/Mage.Sets/src/mage/sets/ShadowsOfThePast.java b/Mage.Sets/src/mage/sets/ShadowsOfThePast.java index 3a9b0e6b694..eb33e9a1bb4 100644 --- a/Mage.Sets/src/mage/sets/ShadowsOfThePast.java +++ b/Mage.Sets/src/mage/sets/ShadowsOfThePast.java @@ -54,7 +54,6 @@ public class ShadowsOfThePast extends ExpansionSet { cards.add(new SetCardInfo("Forge Devil", 41, Rarity.COMMON, mage.cards.f.ForgeDevil.class)); cards.add(new SetCardInfo("Galvanic Juggernaut", 72, Rarity.UNCOMMON, mage.cards.g.GalvanicJuggernaut.class)); cards.add(new SetCardInfo("Garruk Relentless", 49, Rarity.MYTHIC, mage.cards.g.GarrukRelentless.class)); - cards.add(new SetCardInfo("Garruk, the Veil-Cursed", 49, Rarity.MYTHIC, mage.cards.g.GarrukTheVeilCursed.class)); cards.add(new SetCardInfo("Geist of Saint Traft", 62, Rarity.MYTHIC, mage.cards.g.GeistOfSaintTraft.class)); cards.add(new SetCardInfo("Ghoulraiser", 30, Rarity.COMMON, mage.cards.g.Ghoulraiser.class)); cards.add(new SetCardInfo("Gnaw to the Bone", 50, Rarity.COMMON, mage.cards.g.GnawToTheBone.class)); @@ -64,7 +63,6 @@ public class ShadowsOfThePast extends ExpansionSet { cards.add(new SetCardInfo("Havengul Lich", 63, Rarity.MYTHIC, mage.cards.h.HavengulLich.class)); cards.add(new SetCardInfo("Havengul Runebinder", 16, Rarity.RARE, mage.cards.h.HavengulRunebinder.class)); cards.add(new SetCardInfo("Hollowhenge Scavenger", 52, Rarity.COMMON, mage.cards.h.HollowhengeScavenger.class)); - cards.add(new SetCardInfo("Howlpack Alpha", 53, Rarity.RARE, mage.cards.h.HowlpackAlpha.class)); cards.add(new SetCardInfo("Huntmaster of the Fells", 64, Rarity.MYTHIC, mage.cards.h.HuntmasterOfTheFells.class)); cards.add(new SetCardInfo("Immerwolf", 65, Rarity.UNCOMMON, mage.cards.i.Immerwolf.class)); cards.add(new SetCardInfo("Increasing Ambition", 32, Rarity.RARE, mage.cards.i.IncreasingAmbition.class)); @@ -91,7 +89,6 @@ public class ShadowsOfThePast extends ExpansionSet { cards.add(new SetCardInfo("Spider Spawning", 56, Rarity.UNCOMMON, mage.cards.s.SpiderSpawning.class)); cards.add(new SetCardInfo("Stitcher's Apprentice", 24, Rarity.COMMON, mage.cards.s.StitchersApprentice.class)); cards.add(new SetCardInfo("Stromkirk Captain", 67, Rarity.UNCOMMON, mage.cards.s.StromkirkCaptain.class)); - cards.add(new SetCardInfo("Terror of Kruin Pass", 42, Rarity.RARE, mage.cards.t.TerrorOfKruinPass.class)); cards.add(new SetCardInfo("Tragic Slip", 35, Rarity.COMMON, mage.cards.t.TragicSlip.class)); cards.add(new SetCardInfo("Traitorous Blood", 45, Rarity.COMMON, mage.cards.t.TraitorousBlood.class)); cards.add(new SetCardInfo("Travel Preparations", 57, Rarity.COMMON, mage.cards.t.TravelPreparations.class)); diff --git a/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java b/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java index f9aa8c5f5ef..f475231ccc2 100644 --- a/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java +++ b/Mage.Sets/src/mage/sets/ShadowsOverInnistrad.java @@ -49,12 +49,10 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Apothecary Geist", 4, Rarity.COMMON, mage.cards.a.ApothecaryGeist.class)); cards.add(new SetCardInfo("Archangel Avacyn", 5, Rarity.MYTHIC, mage.cards.a.ArchangelAvacyn.class)); cards.add(new SetCardInfo("Arlinn Kord", 243, Rarity.MYTHIC, mage.cards.a.ArlinnKord.class)); - cards.add(new SetCardInfo("Ashmouth Blade", 260, Rarity.UNCOMMON, mage.cards.a.AshmouthBlade.class)); cards.add(new SetCardInfo("Asylum Visitor", 99, Rarity.RARE, mage.cards.a.AsylumVisitor.class)); 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)); @@ -89,7 +87,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Dead Weight", 106, Rarity.COMMON, mage.cards.d.DeadWeight.class)); cards.add(new SetCardInfo("Deathcap Cultivator", 202, Rarity.RARE, mage.cards.d.DeathcapCultivator.class)); cards.add(new SetCardInfo("Declaration in Stone", 12, Rarity.RARE, mage.cards.d.DeclarationInStone.class)); - cards.add(new SetCardInfo("Demon-Possessed Witch", 119, Rarity.UNCOMMON, mage.cards.d.DemonPossessedWitch.class)); cards.add(new SetCardInfo("Deny Existence", 55, Rarity.COMMON, mage.cards.d.DenyExistence.class)); cards.add(new SetCardInfo("Descend upon the Sinful", 13, Rarity.MYTHIC, mage.cards.d.DescendUponTheSinful.class)); cards.add(new SetCardInfo("Devils' Playground", 151, Rarity.RARE, mage.cards.d.DevilsPlayground.class)); @@ -121,7 +118,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Fevered Visions", 244, Rarity.RARE, mage.cards.f.FeveredVisions.class)); cards.add(new SetCardInfo("Fiery Temper", 156, Rarity.COMMON, mage.cards.f.FieryTemper.class)); cards.add(new SetCardInfo("Flameblade Angel", 157, Rarity.RARE, mage.cards.f.FlamebladeAngel.class)); - cards.add(new SetCardInfo("Flameheart Werewolf", 169, Rarity.UNCOMMON, mage.cards.f.FlameheartWerewolf.class)); cards.add(new SetCardInfo("Fleeting Memories", 62, Rarity.UNCOMMON, mage.cards.f.FleetingMemories.class)); cards.add(new SetCardInfo("Foreboding Ruins", 272, Rarity.RARE, mage.cards.f.ForebodingRuins.class)); cards.add(new SetCardInfo("Forest", 295, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); @@ -136,7 +132,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Furtive Homunculus", 64, Rarity.COMMON, mage.cards.f.FurtiveHomunculus.class)); cards.add(new SetCardInfo("Game Trail", 276, Rarity.RARE, mage.cards.g.GameTrail.class)); cards.add(new SetCardInfo("Gatstaf Arsonists", 158, Rarity.COMMON, mage.cards.g.GatstafArsonists.class)); - cards.add(new SetCardInfo("Gatstaf Ravagers", 158, Rarity.COMMON, mage.cards.g.GatstafRavagers.class)); cards.add(new SetCardInfo("Geier Reach Bandit", 159, Rarity.RARE, mage.cards.g.GeierReachBandit.class)); cards.add(new SetCardInfo("Geistblast", 160, Rarity.UNCOMMON, mage.cards.g.Geistblast.class)); cards.add(new SetCardInfo("Geralf's Masterpiece", 65, Rarity.MYTHIC, mage.cards.g.GeralfsMasterpiece.class)); @@ -157,7 +152,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Harvest Hand", 256, Rarity.UNCOMMON, mage.cards.h.HarvestHand.class)); cards.add(new SetCardInfo("Haunted Cloak", 257, Rarity.UNCOMMON, mage.cards.h.HauntedCloak.class)); cards.add(new SetCardInfo("Heir of Falkenrath", 116, Rarity.UNCOMMON, mage.cards.h.HeirOfFalkenrath.class)); - cards.add(new SetCardInfo("Heir to the Night", 116, Rarity.UNCOMMON, mage.cards.h.HeirToTheNight.class)); cards.add(new SetCardInfo("Hermit of the Natterknolls", 209, Rarity.UNCOMMON, mage.cards.h.HermitOfTheNatterknolls.class)); cards.add(new SetCardInfo("Highland Lake", 277, Rarity.UNCOMMON, mage.cards.h.HighlandLake.class)); cards.add(new SetCardInfo("Hinterland Logger", 210, Rarity.COMMON, mage.cards.h.HinterlandLogger.class)); @@ -167,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)); @@ -192,7 +185,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Lightning Axe", 170, Rarity.UNCOMMON, mage.cards.l.LightningAxe.class)); cards.add(new SetCardInfo("Liliana's Indignation", 120, Rarity.UNCOMMON, mage.cards.l.LilianasIndignation.class)); cards.add(new SetCardInfo("Loam Dryad", 216, Rarity.COMMON, mage.cards.l.LoamDryad.class)); - cards.add(new SetCardInfo("Lone Wolf of the Natterknolls", 209, Rarity.UNCOMMON, mage.cards.l.LoneWolfOfTheNatterknolls.class)); cards.add(new SetCardInfo("Macabre Waltz", 121, Rarity.COMMON, mage.cards.m.MacabreWaltz.class)); cards.add(new SetCardInfo("Mad Prophet", 171, Rarity.UNCOMMON, mage.cards.m.MadProphet.class)); cards.add(new SetCardInfo("Magmatic Chasm", 172, Rarity.COMMON, mage.cards.m.MagmaticChasm.class)); @@ -206,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)); @@ -226,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)); @@ -263,7 +252,6 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Sanguinary Mage", 178, Rarity.COMMON, mage.cards.s.SanguinaryMage.class)); cards.add(new SetCardInfo("Sanitarium Skeleton", 133, Rarity.COMMON, mage.cards.s.SanitariumSkeleton.class)); cards.add(new SetCardInfo("Scourge Wolf", 179, Rarity.RARE, mage.cards.s.ScourgeWolf.class)); - cards.add(new SetCardInfo("Scrounged Scythe", 256, Rarity.UNCOMMON, mage.cards.s.ScroungedScythe.class)); cards.add(new SetCardInfo("Seagraf Skaab", 84, Rarity.COMMON, mage.cards.s.SeagrafSkaab.class)); cards.add(new SetCardInfo("Seasons Past", 226, Rarity.MYTHIC, mage.cards.s.SeasonsPast.class)); cards.add(new SetCardInfo("Second Harvest", 227, Rarity.RARE, mage.cards.s.SecondHarvest.class)); @@ -279,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)); @@ -295,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)); @@ -342,17 +328,13 @@ public final class ShadowsOverInnistrad extends ExpansionSet { cards.add(new SetCardInfo("Vessel of Paramnesia", 95, Rarity.COMMON, mage.cards.v.VesselOfParamnesia.class)); cards.add(new SetCardInfo("Vessel of Volatility", 189, Rarity.COMMON, mage.cards.v.VesselOfVolatility.class)); cards.add(new SetCardInfo("Veteran Cathar", 238, Rarity.UNCOMMON, mage.cards.v.VeteranCathar.class)); - cards.add(new SetCardInfo("Vildin-Pack Alpha", 159, Rarity.RARE, mage.cards.v.VildinPackAlpha.class)); cards.add(new SetCardInfo("Village Messenger", 190, Rarity.UNCOMMON, mage.cards.v.VillageMessenger.class)); cards.add(new SetCardInfo("Voldaren Duelist", 191, Rarity.COMMON, mage.cards.v.VoldarenDuelist.class)); cards.add(new SetCardInfo("Warped Landscape", 280, Rarity.COMMON, mage.cards.w.WarpedLandscape.class)); cards.add(new SetCardInfo("Watcher in the Web", 239, Rarity.COMMON, mage.cards.w.WatcherInTheWeb.class)); - cards.add(new SetCardInfo("Wayward Disciple", 34, Rarity.UNCOMMON, mage.cards.w.WaywardDisciple.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("Westvale Cult Leader", 21, Rarity.RARE, mage.cards.w.WestvaleCultLeader.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)); cards.add(new SetCardInfo("Wolf of Devil's Breach", 192, Rarity.MYTHIC, mage.cards.w.WolfOfDevilsBreach.class)); diff --git a/Mage.Sets/src/mage/sets/ShadowsOverInnistradPromos.java b/Mage.Sets/src/mage/sets/ShadowsOverInnistradPromos.java index 9e53eaafb27..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)); @@ -109,11 +107,8 @@ public class ShadowsOverInnistradPromos extends ExpansionSet { cards.add(new SetCardInfo("Traverse the Ulvenwald", "234s", Rarity.RARE, mage.cards.t.TraverseTheUlvenwald.class)); 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("Vildin-Pack Alpha", "159s", Rarity.RARE, mage.cards.v.VildinPackAlpha.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("Westvale Cult Leader", "21s", Rarity.RARE, mage.cards.w.WestvaleCultLeader.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 6cdd42e309e..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)); @@ -39,10 +38,8 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Apothecary Geist", 12, Rarity.COMMON, mage.cards.a.ApothecaryGeist.class)); cards.add(new SetCardInfo("Archangel Avacyn", 13, Rarity.MYTHIC, mage.cards.a.ArchangelAvacyn.class)); cards.add(new SetCardInfo("Arlinn Kord", 230, Rarity.MYTHIC, mage.cards.a.ArlinnKord.class)); - cards.add(new SetCardInfo("Ashmouth Blade", 256, Rarity.UNCOMMON, mage.cards.a.AshmouthBlade.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)); @@ -88,7 +85,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Deathcap Cultivator", 193, Rarity.UNCOMMON, mage.cards.d.DeathcapCultivator.class)); cards.add(new SetCardInfo("Decimator of the Provinces", 2, Rarity.MYTHIC, mage.cards.d.DecimatorOfTheProvinces.class)); cards.add(new SetCardInfo("Declaration in Stone", 23, Rarity.RARE, mage.cards.d.DeclarationInStone.class)); - cards.add(new SetCardInfo("Demon-Possessed Witch", 107, Rarity.UNCOMMON, mage.cards.d.DemonPossessedWitch.class)); cards.add(new SetCardInfo("Deny Existence", 60, Rarity.COMMON, mage.cards.d.DenyExistence.class)); cards.add(new SetCardInfo("Deranged Whelp", 150, Rarity.COMMON, mage.cards.d.DerangedWhelp.class)); cards.add(new SetCardInfo("Descend upon the Sinful", 24, Rarity.MYTHIC, mage.cards.d.DescendUponTheSinful.class)); @@ -123,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)); @@ -139,7 +134,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Galvanic Bombardment", 157, Rarity.COMMON, mage.cards.g.GalvanicBombardment.class)); cards.add(new SetCardInfo("Game Trail", 269, Rarity.UNCOMMON, mage.cards.g.GameTrail.class)); cards.add(new SetCardInfo("Gatstaf Arsonists", 158, Rarity.COMMON, mage.cards.g.GatstafArsonists.class)); - cards.add(new SetCardInfo("Gatstaf Ravagers", 158, Rarity.COMMON, mage.cards.g.GatstafRavagers.class)); cards.add(new SetCardInfo("Gavony Unhallowed", 111, Rarity.COMMON, mage.cards.g.GavonyUnhallowed.class)); cards.add(new SetCardInfo("Geier Reach Bandit", 159, Rarity.UNCOMMON, mage.cards.g.GeierReachBandit.class)); cards.add(new SetCardInfo("Geier Reach Sanitarium", 270, Rarity.RARE, mage.cards.g.GeierReachSanitarium.class)); @@ -170,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)); @@ -188,7 +180,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Island", 280, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 281, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 282, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("It That Rides as One", 36, Rarity.UNCOMMON, mage.cards.i.ItThatRidesAsOne.class)); cards.add(new SetCardInfo("Jace's Scrutiny", 78, Rarity.COMMON, mage.cards.j.JacesScrutiny.class)); cards.add(new SetCardInfo("Jace, Unraveler of Secrets", 77, Rarity.MYTHIC, mage.cards.j.JaceUnravelerOfSecrets.class)); cards.add(new SetCardInfo("Kindly Stranger", 107, Rarity.UNCOMMON, mage.cards.k.KindlyStranger.class)); @@ -214,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)); @@ -234,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)); @@ -260,7 +249,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet { cards.add(new SetCardInfo("Sage of Ancient Lore", 211, Rarity.RARE, mage.cards.s.SageOfAncientLore.class)); cards.add(new SetCardInfo("Sanitarium Skeleton", 133, Rarity.COMMON, mage.cards.s.SanitariumSkeleton.class)); cards.add(new SetCardInfo("Scourge Wolf", 175, Rarity.UNCOMMON, mage.cards.s.ScourgeWolf.class)); - cards.add(new SetCardInfo("Scrounged Scythe", 252, Rarity.UNCOMMON, mage.cards.s.ScroungedScythe.class)); cards.add(new SetCardInfo("Seasons Past", 212, Rarity.MYTHIC, mage.cards.s.SeasonsPast.class)); cards.add(new SetCardInfo("Second Harvest", 213, Rarity.RARE, mage.cards.s.SecondHarvest.class)); cards.add(new SetCardInfo("Selfless Spirit", 42, Rarity.RARE, mage.cards.s.SelflessSpirit.class)); @@ -315,21 +303,17 @@ 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)); cards.add(new SetCardInfo("Uncaged Fury", 183, Rarity.UNCOMMON, mage.cards.u.UncagedFury.class)); cards.add(new SetCardInfo("Vessel of Nascency", 224, Rarity.UNCOMMON, mage.cards.v.VesselOfNascency.class)); cards.add(new SetCardInfo("Veteran Cathar", 225, Rarity.UNCOMMON, mage.cards.v.VeteranCathar.class)); - cards.add(new SetCardInfo("Vildin-Pack Alpha", 159, Rarity.UNCOMMON, mage.cards.v.VildinPackAlpha.class)); cards.add(new SetCardInfo("Village Messenger", 184, Rarity.UNCOMMON, mage.cards.v.VillageMessenger.class)); cards.add(new SetCardInfo("Voldaren Pariah", 138, Rarity.RARE, mage.cards.v.VoldarenPariah.class)); 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/SpecialGuests.java b/Mage.Sets/src/mage/sets/SpecialGuests.java index ec2200fbe48..6e147db92c0 100644 --- a/Mage.Sets/src/mage/sets/SpecialGuests.java +++ b/Mage.Sets/src/mage/sets/SpecialGuests.java @@ -24,6 +24,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Akroma's Memorial", 81, Rarity.MYTHIC, mage.cards.a.AkromasMemorial.class)); cards.add(new SetCardInfo("Arid Mesa", 109, Rarity.MYTHIC, mage.cards.a.AridMesa.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Arid Mesa", 114, Rarity.MYTHIC, mage.cards.a.AridMesa.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Bitterblossom", 133, Rarity.MYTHIC, mage.cards.b.Bitterblossom.class)); cards.add(new SetCardInfo("Bloom Tender", 79, Rarity.MYTHIC, mage.cards.b.BloomTender.class)); cards.add(new SetCardInfo("Bone Miser", 87, Rarity.MYTHIC, mage.cards.b.BoneMiser.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Bone Miser", 97, Rarity.MYTHIC, mage.cards.b.BoneMiser.class, NON_FULL_USE_VARIOUS)); @@ -47,7 +48,10 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Deafening Silence", 120, Rarity.MYTHIC, mage.cards.d.DeafeningSilence.class, FULL_ART)); cards.add(new SetCardInfo("Desert", 37, Rarity.MYTHIC, mage.cards.d.Desert.class)); cards.add(new SetCardInfo("Desertion", 31, Rarity.MYTHIC, mage.cards.d.Desertion.class)); + cards.add(new SetCardInfo("Devoted Druid", 138, Rarity.MYTHIC, mage.cards.d.DevotedDruid.class)); cards.add(new SetCardInfo("Dismember", 41, Rarity.MYTHIC, mage.cards.d.Dismember.class)); + cards.add(new SetCardInfo("Dolmen Gate", 145, Rarity.MYTHIC, mage.cards.d.DolmenGate.class)); + cards.add(new SetCardInfo("Door of Destinies", 146, Rarity.MYTHIC, mage.cards.d.DoorOfDestinies.class)); cards.add(new SetCardInfo("Drown in the Loch", 27, Rarity.MYTHIC, mage.cards.d.DrownInTheLoch.class)); cards.add(new SetCardInfo("Eerie Ultimatum", 104, Rarity.MYTHIC, mage.cards.e.EerieUltimatum.class)); cards.add(new SetCardInfo("Embercleave", 77, Rarity.MYTHIC, mage.cards.e.Embercleave.class)); @@ -57,6 +61,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Expressive Iteration", 43, Rarity.MYTHIC, mage.cards.e.ExpressiveIteration.class)); cards.add(new SetCardInfo("Expropriate", 66, Rarity.MYTHIC, mage.cards.e.Expropriate.class)); cards.add(new SetCardInfo("Fabricate", 20, Rarity.MYTHIC, mage.cards.f.Fabricate.class)); + cards.add(new SetCardInfo("Faerie Macabre", 134, Rarity.MYTHIC, mage.cards.f.FaerieMacabre.class)); cards.add(new SetCardInfo("Field of the Dead", 28, Rarity.MYTHIC, mage.cards.f.FieldOfTheDead.class)); cards.add(new SetCardInfo("Fiend Artisan", 83, Rarity.MYTHIC, mage.cards.f.FiendArtisan.class)); cards.add(new SetCardInfo("Frogmite", 61, Rarity.MYTHIC, mage.cards.f.Frogmite.class)); @@ -69,19 +74,26 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Ghalta, Primal Hunger", 11, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class)); cards.add(new SetCardInfo("Ghostly Prison", 19, Rarity.MYTHIC, mage.cards.g.GhostlyPrison.class)); cards.add(new SetCardInfo("Goblin Bushwhacker", 78, Rarity.MYTHIC, mage.cards.g.GoblinBushwhacker.class)); + cards.add(new SetCardInfo("Goblin Chieftain", 135, Rarity.MYTHIC, mage.cards.g.GoblinChieftain.class)); + cards.add(new SetCardInfo("Goblin Sharpshooter", 136, Rarity.MYTHIC, mage.cards.g.GoblinSharpshooter.class)); cards.add(new SetCardInfo("Green Sun's Zenith", 127, Rarity.MYTHIC, mage.cards.g.GreenSunsZenith.class, FULL_ART)); cards.add(new SetCardInfo("Grief", 46, Rarity.MYTHIC, mage.cards.g.Grief.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grief", 51, Rarity.MYTHIC, mage.cards.g.Grief.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Grim Tutor", 76, Rarity.MYTHIC, mage.cards.g.GrimTutor.class)); cards.add(new SetCardInfo("Hallowed Haunting", 64, Rarity.MYTHIC, mage.cards.h.HallowedHaunting.class)); + cards.add(new SetCardInfo("Heat Shimmer", 137, Rarity.MYTHIC, mage.cards.h.HeatShimmer.class)); + cards.add(new SetCardInfo("Helix Pinnacle", 139, Rarity.MYTHIC, mage.cards.h.HelixPinnacle.class)); + cards.add(new SetCardInfo("Idyllic Tutor", 129, Rarity.MYTHIC, mage.cards.i.IdyllicTutor.class)); cards.add(new SetCardInfo("Inspired Ultimatum", 107, Rarity.MYTHIC, mage.cards.i.InspiredUltimatum.class)); cards.add(new SetCardInfo("Kalamax, the Stormsire", 13, Rarity.MYTHIC, mage.cards.k.KalamaxTheStormsire.class)); cards.add(new SetCardInfo("Kindred Charge", 58, Rarity.MYTHIC, mage.cards.k.KindredCharge.class)); + cards.add(new SetCardInfo("Kinsbaile Cavalier", 130, Rarity.MYTHIC, mage.cards.k.KinsbaileCavalier.class)); + cards.add(new SetCardInfo("Leaf-Crowned Visionary", 140, Rarity.MYTHIC, mage.cards.l.LeafCrownedVisionary.class)); cards.add(new SetCardInfo("Ledger Shredder", 55, Rarity.MYTHIC, mage.cards.l.LedgerShredder.class)); - cards.add(new SetCardInfo("Lord Windgrace", 14, Rarity.MYTHIC, mage.cards.l.LordWindgrace.class)); cards.add(new SetCardInfo("Lord of Atlantis", 1, Rarity.RARE, mage.cards.l.LordOfAtlantis.class)); cards.add(new SetCardInfo("Lord of the Undead", 88, Rarity.MYTHIC, mage.cards.l.LordOfTheUndead.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lord of the Undead", 98, Rarity.MYTHIC, mage.cards.l.LordOfTheUndead.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Lord Windgrace", 14, Rarity.MYTHIC, mage.cards.l.LordWindgrace.class)); cards.add(new SetCardInfo("Maddening Hex", 70, Rarity.MYTHIC, mage.cards.m.MaddeningHex.class)); cards.add(new SetCardInfo("Magus of the Moon", 125, Rarity.MYTHIC, mage.cards.m.MagusOfTheMoon.class, FULL_ART)); cards.add(new SetCardInfo("Malcolm, Keen-Eyed Navigator", 2, Rarity.UNCOMMON, mage.cards.m.MalcolmKeenEyedNavigator.class)); @@ -92,10 +104,12 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Mana Crypt", "17e", Rarity.MYTHIC, mage.cards.m.ManaCrypt.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mana Crypt", "17f", Rarity.MYTHIC, mage.cards.m.ManaCrypt.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mana Crypt", 17, Rarity.MYTHIC, mage.cards.m.ManaCrypt.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Manamorphose", 142, Rarity.MYTHIC, mage.cards.m.Manamorphose.class)); cards.add(new SetCardInfo("Marsh Flats", 110, Rarity.MYTHIC, mage.cards.m.MarshFlats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Marsh Flats", 115, Rarity.MYTHIC, mage.cards.m.MarshFlats.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mephidross Vampire", 4, Rarity.RARE, mage.cards.m.MephidrossVampire.class)); cards.add(new SetCardInfo("Mirri, Weatherlight Duelist", 15, Rarity.MYTHIC, mage.cards.m.MirriWeatherlightDuelist.class)); + cards.add(new SetCardInfo("Mistbind Clique", 131, Rarity.MYTHIC, mage.cards.m.MistbindClique.class)); cards.add(new SetCardInfo("Misty Rainforest", 111, Rarity.MYTHIC, mage.cards.m.MistyRainforest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Misty Rainforest", 116, Rarity.MYTHIC, mage.cards.m.MistyRainforest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Morbid Opportunist", 32, Rarity.MYTHIC, mage.cards.m.MorbidOpportunist.class)); @@ -103,6 +117,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Nexus of Fate", 122, Rarity.MYTHIC, mage.cards.n.NexusOfFate.class, FULL_ART)); cards.add(new SetCardInfo("Notion Thief", 36, Rarity.MYTHIC, mage.cards.n.NotionThief.class)); cards.add(new SetCardInfo("Noxious Revival", 73, Rarity.MYTHIC, mage.cards.n.NoxiousRevival.class)); + cards.add(new SetCardInfo("Painter's Servant", 147, Rarity.MYTHIC, mage.cards.p.PaintersServant.class)); cards.add(new SetCardInfo("Paradise Druid", 80, Rarity.MYTHIC, mage.cards.p.ParadiseDruid.class)); cards.add(new SetCardInfo("Paradox Haze", 123, Rarity.MYTHIC, mage.cards.p.ParadoxHaze.class, FULL_ART)); cards.add(new SetCardInfo("Pathbreaker Ibex", 101, Rarity.MYTHIC, mage.cards.p.PathbreakerIbex.class, NON_FULL_USE_VARIOUS)); @@ -116,6 +131,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Prismatic Vista", 38, Rarity.MYTHIC, mage.cards.p.PrismaticVista.class)); cards.add(new SetCardInfo("Rampaging Ferocidon", 8, Rarity.RARE, mage.cards.r.RampagingFerocidon.class)); cards.add(new SetCardInfo("Rat Colony", 56, Rarity.MYTHIC, mage.cards.r.RatColony.class)); + cards.add(new SetCardInfo("Regal Force", 141, Rarity.MYTHIC, mage.cards.r.RegalForce.class)); cards.add(new SetCardInfo("Relentless Rats", 57, Rarity.MYTHIC, mage.cards.r.RelentlessRats.class)); cards.add(new SetCardInfo("Robe of Stars", 121, Rarity.MYTHIC, mage.cards.r.RobeOfStars.class, FULL_ART)); cards.add(new SetCardInfo("Ruinous Ultimatum", 108, Rarity.MYTHIC, mage.cards.r.RuinousUltimatum.class)); @@ -127,6 +143,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Show and Tell", 21, Rarity.MYTHIC, mage.cards.s.ShowAndTell.class)); cards.add(new SetCardInfo("Skysovereign, Consul Flagship", 103, Rarity.MYTHIC, mage.cards.s.SkysovereignConsulFlagship.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Skysovereign, Consul Flagship", 93, Rarity.MYTHIC, mage.cards.s.SkysovereignConsulFlagship.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Slippery Bogle", 144, Rarity.MYTHIC, mage.cards.s.SlipperyBogle.class)); cards.add(new SetCardInfo("Sliver Overlord", 128, Rarity.MYTHIC, mage.cards.s.SliverOverlord.class, FULL_ART)); cards.add(new SetCardInfo("Solitude", 44, Rarity.MYTHIC, mage.cards.s.Solitude.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Solitude", 49, Rarity.MYTHIC, mage.cards.s.Solitude.class, NON_FULL_USE_VARIOUS)); @@ -143,6 +160,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Thought-Knot Seer", 39, Rarity.MYTHIC, mage.cards.t.ThoughtKnotSeer.class)); cards.add(new SetCardInfo("Thoughtcast", 85, Rarity.MYTHIC, mage.cards.t.Thoughtcast.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thoughtcast", 95, Rarity.MYTHIC, mage.cards.t.Thoughtcast.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Thousand-Year Elixir", 148, Rarity.MYTHIC, mage.cards.t.ThousandYearElixir.class)); cards.add(new SetCardInfo("Thrasios, Triton Hero", 16, Rarity.RARE, mage.cards.t.ThrasiosTritonHero.class)); cards.add(new SetCardInfo("Tireless Tracker", 26, Rarity.MYTHIC, mage.cards.t.TirelessTracker.class)); cards.add(new SetCardInfo("Toski, Bearer of Secrets", 60, Rarity.MYTHIC, mage.cards.t.ToskiBearerOfSecrets.class)); @@ -152,6 +170,7 @@ public final class SpecialGuests extends ExpansionSet { cards.add(new SetCardInfo("Verdant Catacombs", 113, Rarity.MYTHIC, mage.cards.v.VerdantCatacombs.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Verdant Catacombs", 118, Rarity.MYTHIC, mage.cards.v.VerdantCatacombs.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Victimize", 23, Rarity.MYTHIC, mage.cards.v.Victimize.class)); + cards.add(new SetCardInfo("Wanderwine Prophets", 132, Rarity.MYTHIC, mage.cards.w.WanderwineProphets.class)); cards.add(new SetCardInfo("Warping Wail", 119, Rarity.MYTHIC, mage.cards.w.WarpingWail.class, FULL_ART)); cards.add(new SetCardInfo("Whir of Invention", 86, Rarity.MYTHIC, mage.cards.w.WhirOfInvention.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Whir of Invention", 96, Rarity.MYTHIC, mage.cards.w.WhirOfInvention.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/StoreChampionships.java b/Mage.Sets/src/mage/sets/StoreChampionships.java index b9a6e890afe..ea3ef14a33e 100644 --- a/Mage.Sets/src/mage/sets/StoreChampionships.java +++ b/Mage.Sets/src/mage/sets/StoreChampionships.java @@ -55,7 +55,6 @@ public final class StoreChampionships extends ExpansionSet { cards.add(new SetCardInfo("Preacher of the Schism", 34, Rarity.RARE, mage.cards.p.PreacherOfTheSchism.class)); cards.add(new SetCardInfo("Preordain", 39, Rarity.RARE, mage.cards.p.Preordain.class)); cards.add(new SetCardInfo("Reality Smasher", 31, Rarity.RARE, mage.cards.r.RealitySmasher.class)); - cards.add(new SetCardInfo("Reflection of Kiki-Jiki", 44, Rarity.RARE, mage.cards.r.ReflectionOfKikiJiki.class)); cards.add(new SetCardInfo("Shark Typhoon", 28, Rarity.RARE, mage.cards.s.SharkTyphoon.class)); cards.add(new SetCardInfo("Slickshot Show-Off", 43, Rarity.RARE, mage.cards.s.SlickshotShowOff.class)); cards.add(new SetCardInfo("Spell Pierce", 4, Rarity.RARE, mage.cards.s.SpellPierce.class)); diff --git a/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java b/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java index c103cf0d5e0..2028d4f6f54 100644 --- a/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java +++ b/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtles.java @@ -28,6 +28,8 @@ public final class TeenageMutantNinjaTurtles extends ExpansionSet { cards.add(new SetCardInfo("Island", 254, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 311, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Krang, Master Mind", 43, Rarity.RARE, mage.cards.k.KrangMasterMind.class)); + cards.add(new SetCardInfo("Leonardo, Sewer Samurai", 17, Rarity.MYTHIC, mage.cards.l.LeonardoSewerSamurai.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Leonardo, Sewer Samurai", 301, Rarity.MYTHIC, mage.cards.l.LeonardoSewerSamurai.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 256, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Mountain", 313, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Plains", 253, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS)); diff --git a/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtlesEternal.java b/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtlesEternal.java index 7a0a2eebf07..e1cc6eae17e 100644 --- a/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtlesEternal.java +++ b/Mage.Sets/src/mage/sets/TeenageMutantNinjaTurtlesEternal.java @@ -26,7 +26,9 @@ public final class TeenageMutantNinjaTurtlesEternal extends ExpansionSet { cards.add(new SetCardInfo("Heroes in a Half Shell", 6, Rarity.MYTHIC, mage.cards.h.HeroesInAHalfShell.class)); cards.add(new SetCardInfo("Leonardo, Worldly Warrior", 101, Rarity.MYTHIC, mage.cards.l.LeonardoWorldlyWarrior.class)); cards.add(new SetCardInfo("Leonardo, the Balance", 1, Rarity.MYTHIC, mage.cards.l.LeonardoTheBalance.class)); + cards.add(new SetCardInfo("Michelangelo, On the Scene", 124, Rarity.MYTHIC, mage.cards.m.MichelangeloOnTheScene.class)); cards.add(new SetCardInfo("Michelangelo, the Heart", 5, Rarity.MYTHIC, mage.cards.m.MichelangeloTheHeart.class)); + cards.add(new SetCardInfo("Raphael, Tag Team Tough", 118, Rarity.MYTHIC, mage.cards.r.RaphaelTagTeamTough.class)); cards.add(new SetCardInfo("Raphael, the Muscle", 4, Rarity.MYTHIC, mage.cards.r.RaphaelTheMuscle.class)); cards.add(new SetCardInfo("Splinter, the Mentor", 3, Rarity.MYTHIC, mage.cards.s.SplinterTheMentor.class)); } diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index d2c77c86f58..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)); @@ -196,7 +192,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Growing Rites of Itlimoc", 188, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Growing Rites of Itlimoc", 380, Rarity.RARE, mage.cards.g.GrowingRitesOfItlimoc.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Guardian of the Great Door", 16, Rarity.UNCOMMON, mage.cards.g.GuardianOfTheGreatDoor.class)); - cards.add(new SetCardInfo("Guidestone Compass", 62, Rarity.UNCOMMON, mage.cards.g.GuidestoneCompass.class)); cards.add(new SetCardInfo("Helping Hand", 17, Rarity.UNCOMMON, mage.cards.h.HelpingHand.class)); cards.add(new SetCardInfo("Hermitic Nautilus", 58, Rarity.UNCOMMON, mage.cards.h.HermiticNautilus.class)); cards.add(new SetCardInfo("Hidden Cataract", 273, Rarity.COMMON, mage.cards.h.HiddenCataract.class)); @@ -217,7 +212,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Hulking Raptor", 327, Rarity.RARE, mage.cards.h.HulkingRaptor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Hunter's Blowgun", 255, Rarity.COMMON, mage.cards.h.HuntersBlowgun.class)); cards.add(new SetCardInfo("Hurl into History", 59, Rarity.UNCOMMON, mage.cards.h.HurlIntoHistory.class)); - cards.add(new SetCardInfo("Iceberg Titan", 60, Rarity.COMMON, mage.cards.i.IcebergTitan.class)); cards.add(new SetCardInfo("Idol of the Deep King", 155, Rarity.COMMON, mage.cards.i.IdolOfTheDeepKing.class)); cards.add(new SetCardInfo("In the Presence of Ages", 192, Rarity.COMMON, mage.cards.i.InThePresenceOfAges.class)); cards.add(new SetCardInfo("Inti, Seneschal of the Sun", 156, Rarity.RARE, mage.cards.i.IntiSeneschalOfTheSun.class, NON_FULL_USE_VARIOUS)); @@ -229,19 +223,15 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Island", 288, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_UST_VARIOUS)); cards.add(new SetCardInfo("Island", 395, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 396, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 188, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Itlimoc, Cradle of the Sun", 380, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Itzquinth, Firstborn of Gishath", 230, Rarity.UNCOMMON, mage.cards.i.ItzquinthFirstbornOfGishath.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Itzquinth, Firstborn of Gishath", 331, Rarity.UNCOMMON, mage.cards.i.ItzquinthFirstbornOfGishath.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ixalli's Lorekeeper", 194, Rarity.UNCOMMON, mage.cards.i.IxallisLorekeeper.class)); cards.add(new SetCardInfo("Jade Seedstones", 195, Rarity.UNCOMMON, mage.cards.j.JadeSeedstones.class)); - cards.add(new SetCardInfo("Jadeheart Attendant", 195, Rarity.UNCOMMON, mage.cards.j.JadeheartAttendant.class)); cards.add(new SetCardInfo("Jadelight Spelunker", 196, Rarity.RARE, mage.cards.j.JadelightSpelunker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jadelight Spelunker", 382, Rarity.RARE, mage.cards.j.JadelightSpelunker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jadelight Spelunker", 403, Rarity.RARE, mage.cards.j.JadelightSpelunker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Join the Dead", 110, Rarity.COMMON, mage.cards.j.JoinTheDead.class)); cards.add(new SetCardInfo("Kaslem's Stonetree", 197, Rarity.COMMON, mage.cards.k.KaslemsStonetree.class)); - cards.add(new SetCardInfo("Kaslem's Strider", 197, Rarity.COMMON, mage.cards.k.KaslemsStrider.class)); cards.add(new SetCardInfo("Kellan, Daring Traveler", 231, Rarity.RARE, mage.cards.k.KellanDaringTraveler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kellan, Daring Traveler", 341, Rarity.RARE, mage.cards.k.KellanDaringTraveler.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kinjalli's Dawnrunner", 19, Rarity.UNCOMMON, mage.cards.k.KinjallisDawnrunner.class)); @@ -251,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)); @@ -267,8 +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("Master's Manufactory", 233, Rarity.UNCOMMON, mage.cards.m.MastersManufactory.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)); @@ -282,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)); @@ -299,7 +284,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Oltec Cloud Guard", 28, Rarity.COMMON, mage.cards.o.OltecCloudGuard.class)); cards.add(new SetCardInfo("Orazca Puzzle-Door", 68, Rarity.COMMON, mage.cards.o.OrazcaPuzzleDoor.class)); cards.add(new SetCardInfo("Oteclan Landmark", 29, Rarity.COMMON, mage.cards.o.OteclanLandmark.class)); - cards.add(new SetCardInfo("Oteclan Levitator", 29, Rarity.COMMON, mage.cards.o.OteclanLevitator.class)); cards.add(new SetCardInfo("Out of Air", 69, Rarity.COMMON, mage.cards.o.OutOfAir.class)); cards.add(new SetCardInfo("Over the Edge", 205, Rarity.COMMON, mage.cards.o.OverTheEdge.class)); cards.add(new SetCardInfo("Palani's Hatcher", 237, Rarity.RARE, mage.cards.p.PalanisHatcher.class, NON_FULL_USE_VARIOUS)); @@ -349,9 +333,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("River Herald Scout", 72, Rarity.COMMON, mage.cards.r.RiverHeraldScout.class)); cards.add(new SetCardInfo("Roaming Throne", 258, Rarity.RARE, mage.cards.r.RoamingThrone.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Roaming Throne", 344, Rarity.RARE, mage.cards.r.RoamingThrone.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Roar of the Fifth People", 189, Rarity.MYTHIC, mage.cards.r.RoarOfTheFifthPeople.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Roar of the Fifth People", 296, Rarity.MYTHIC, mage.cards.r.RoarOfTheFifthPeople.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Roar of the Fifth People", 339, Rarity.MYTHIC, mage.cards.r.RoarOfTheFifthPeople.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Ruin-Lurker Bat", 33, Rarity.UNCOMMON, mage.cards.r.RuinLurkerBat.class)); cards.add(new SetCardInfo("Rumbling Rockslide", 163, Rarity.COMMON, mage.cards.r.RumblingRockslide.class)); cards.add(new SetCardInfo("Runaway Boulder", 259, Rarity.COMMON, mage.cards.r.RunawayBoulder.class)); @@ -359,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)); @@ -372,7 +351,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Self-Reflection", 74, Rarity.UNCOMMON, mage.cards.s.SelfReflection.class)); cards.add(new SetCardInfo("Sentinel of the Nameless City", 211, Rarity.RARE, mage.cards.s.SentinelOfTheNamelessCity.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sentinel of the Nameless City", 383, Rarity.RARE, mage.cards.s.SentinelOfTheNamelessCity.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Shadows' Lair", 108, Rarity.UNCOMMON, mage.cards.s.ShadowsLair.class)); cards.add(new SetCardInfo("Shipwreck Sentry", 75, Rarity.COMMON, mage.cards.s.ShipwreckSentry.class)); cards.add(new SetCardInfo("Sinuous Benthisaur", 76, Rarity.UNCOMMON, mage.cards.s.SinuousBenthisaur.class)); cards.add(new SetCardInfo("Skullcap Snail", 119, Rarity.COMMON, mage.cards.s.SkullcapSnail.class)); @@ -384,7 +362,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Souls of the Lost", 369, Rarity.RARE, mage.cards.s.SoulsOfTheLost.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sovereign Okinec Ahau", 240, Rarity.MYTHIC, mage.cards.s.SovereignOkinecAhau.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Sovereign Okinec Ahau", 309, Rarity.MYTHIC, mage.cards.s.SovereignOkinecAhau.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Sovereign's Macuahuitl", 155, Rarity.COMMON, mage.cards.s.SovereignsMacuahuitl.class)); cards.add(new SetCardInfo("Spelunking", 213, Rarity.UNCOMMON, mage.cards.s.Spelunking.class)); cards.add(new SetCardInfo("Spring-Loaded Sawblades", 36, Rarity.UNCOMMON, mage.cards.s.SpringLoadedSawblades.class)); cards.add(new SetCardInfo("Spyglass Siren", 405, Rarity.UNCOMMON, mage.cards.s.SpyglassSiren.class, NON_FULL_USE_VARIOUS)); @@ -400,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)); @@ -416,14 +392,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Tarrian's Soulcleaver", 264, Rarity.RARE, mage.cards.t.TarriansSoulcleaver.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tarrian's Soulcleaver", 389, Rarity.RARE, mage.cards.t.TarriansSoulcleaver.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tectonic Hazard", 169, Rarity.COMMON, mage.cards.t.TectonicHazard.class)); - cards.add(new SetCardInfo("Temple of Civilization", 26, Rarity.MYTHIC, mage.cards.t.TempleOfCivilization.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Civilization", 314, Rarity.MYTHIC, mage.cards.t.TempleOfCivilization.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Cultivation", 204, Rarity.MYTHIC, mage.cards.t.TempleOfCultivation.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Cultivation", 318, Rarity.MYTHIC, mage.cards.t.TempleOfCultivation.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Cyclical Time", 315, Rarity.MYTHIC, mage.cards.t.TempleOfCyclicalTime.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Cyclical Time", 67, Rarity.MYTHIC, mage.cards.t.TempleOfCyclicalTime.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Power", 158, Rarity.MYTHIC, mage.cards.t.TempleOfPower.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("Temple of Power", 317, Rarity.MYTHIC, mage.cards.t.TempleOfPower.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tendril of the Mycotyrant", 215, Rarity.UNCOMMON, mage.cards.t.TendrilOfTheMycotyrant.class)); cards.add(new SetCardInfo("Terror Tide", 127, Rarity.RARE, mage.cards.t.TerrorTide.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Terror Tide", 372, Rarity.RARE, mage.cards.t.TerrorTide.class, NON_FULL_USE_VARIOUS)); @@ -431,24 +399,16 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("The Ancient One", 319, Rarity.MYTHIC, mage.cards.t.TheAncientOne.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Belligerent", 225, Rarity.RARE, mage.cards.t.TheBelligerent.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Belligerent", 384, Rarity.RARE, mage.cards.t.TheBelligerent.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Core", 256, Rarity.RARE, mage.cards.t.TheCore.class, NON_FULL_USE_VARIOUS)); - cards.add(new SetCardInfo("The Core", 387, Rarity.RARE, mage.cards.t.TheCore.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Enigma Jewel", 362, Rarity.MYTHIC, mage.cards.t.TheEnigmaJewel.class, NON_FULL_USE_VARIOUS)); 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)); @@ -463,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)); @@ -489,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)); @@ -564,15 +521,15 @@ class TheLostCavernsOfIxalanCollator implements BoosterCollator { // 1.3875 B uncommons (111 / 80) // 1.3875 C uncommons (111 / 80) private final RarityConfiguration uncommonRuns = new RarityConfiguration( - BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, - BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, - BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, - BCC, - BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, - BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, - BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, + BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, + BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, + BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, BCC, + BCC, + BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, + BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, + BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, BBC, - ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, + ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC, ABC ); 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 7ea26010c82..6d5ab6f7e77 100644 --- a/Mage.Sets/src/mage/sets/Transformers.java +++ b/Mage.Sets/src/mage/sets/Transformers.java @@ -20,25 +20,33 @@ public final class Transformers extends ExpansionSet { this.hasBasicLands = false; cards.add(new SetCardInfo("Arcee, Sharpshooter", 7, Rarity.MYTHIC, mage.cards.a.ArceeSharpshooter.class)); - cards.add(new SetCardInfo("Blitzwing, Cruel Tormentor", 4, Rarity.MYTHIC, mage.cards.b.BlitzwingCruelTormentor.class)); - cards.add(new SetCardInfo("Cyclonus, the Saboteur", 9, Rarity.MYTHIC, mage.cards.c.CyclonusTheSaboteur.class)); - cards.add(new SetCardInfo("Flamewar, Brash Veteran", 10, Rarity.MYTHIC, mage.cards.f.FlamewarBrashVeteran.class)); - cards.add(new SetCardInfo("Flamewar, Streetwise Operative", 10, Rarity.MYTHIC, mage.cards.f.FlamewarStreetwiseOperative.class)); - cards.add(new SetCardInfo("Goldbug, Humanity's Ally", 11, Rarity.MYTHIC, mage.cards.g.GoldbugHumanitysAlly.class)); - cards.add(new SetCardInfo("Goldbug, Scrappy Scout", 11, Rarity.MYTHIC, mage.cards.g.GoldbugScrappyScout.class)); - cards.add(new SetCardInfo("Jetfire, Air Guardian", 3, Rarity.MYTHIC, mage.cards.j.JetfireAirGuardian.class)); - cards.add(new SetCardInfo("Jetfire, Ingenious Scientist", 3, Rarity.MYTHIC, mage.cards.j.JetfireIngeniousScientist.class)); - cards.add(new SetCardInfo("Megatron, Destructive Force", 12, Rarity.MYTHIC, mage.cards.m.MegatronDestructiveForce.class)); - cards.add(new SetCardInfo("Megatron, Tyrant", 12, Rarity.MYTHIC, mage.cards.m.MegatronTyrant.class)); + // cards.add(new SetCardInfo("Blaster, Combat DJ", 8, Rarity.MYTHIC, mage.cards.a.BlasterCombatDj.class, NON_FULL_USE_VARIOUS)); + // cards.add(new SetCardInfo("Blaster, Combat DJ", 22, Rarity.MYTHIC, mage.cards.a.BlasterCombatDj.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Blitzwing, Cruel Tormentor", 4, Rarity.MYTHIC, mage.cards.b.BlitzwingCruelTormentor.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Blitzwing, Cruel Tormentor", 19, Rarity.MYTHIC, mage.cards.b.BlitzwingCruelTormentor.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Cyclonus, the Saboteur", 9, Rarity.MYTHIC, mage.cards.c.CyclonusTheSaboteur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Cyclonus, the Saboteur", 23, Rarity.MYTHIC, mage.cards.c.CyclonusTheSaboteur.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Flamewar, Brash Veteran", 10, Rarity.MYTHIC, mage.cards.f.FlamewarBrashVeteran.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Flamewar, Brash Veteran", 24, Rarity.MYTHIC, mage.cards.f.FlamewarBrashVeteran.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goldbug, Humanity's Ally", 11, Rarity.MYTHIC, mage.cards.g.GoldbugHumanitysAlly.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Goldbug, Humanity's Ally", 25, Rarity.MYTHIC, mage.cards.g.GoldbugHumanitysAlly.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jetfire, Ingenious Scientist", 3, Rarity.MYTHIC, mage.cards.j.JetfireIngeniousScientist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jetfire, Ingenious Scientist", 18, Rarity.MYTHIC, mage.cards.j.JetfireIngeniousScientist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Megatron, Tyrant", 12, Rarity.MYTHIC, mage.cards.m.MegatronTyrant.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Megatron, Tyrant", 26, Rarity.MYTHIC, mage.cards.m.MegatronTyrant.class, NON_FULL_USE_VARIOUS)); 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("Ratchet, Rescue Racer", 2, Rarity.MYTHIC, mage.cards.r.RatchetRescueRacer.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)); + // cards.add(new SetCardInfo("Prowl, Stoic Strategist", 1, Rarity.MYTHIC, mage.cards.a.ProwlStoicStrategist.class, NON_FULL_USE_VARIOUS)); + // cards.add(new SetCardInfo("Prowl, Stoic Strategist", 16, Rarity.MYTHIC, mage.cards.a.ProwlStoicStrategist.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ratchet, Field Medic", 2, Rarity.MYTHIC, mage.cards.r.RatchetFieldMedic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ratchet, Field Medic", 17, Rarity.MYTHIC, mage.cards.r.RatchetFieldMedic.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Slicer, Hired Muscle", 6, Rarity.MYTHIC, mage.cards.s.SlicerHiredMuscle.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Slicer, Hired Muscle", 21, Rarity.MYTHIC, mage.cards.s.SlicerHiredMuscle.class, NON_FULL_USE_VARIOUS)); + // cards.add(new SetCardInfo("Soundwave, Sonic Spy", 14, Rarity.MYTHIC, mage.cards.s.SoundwaveSonicSpy.class, NON_FULL_USE_VARIOUS)); + // cards.add(new SetCardInfo("Soundwave, Sonic Spy", 28, Rarity.MYTHIC, mage.cards.s.SoundwaveSonicSpy.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Starscream, Power Hungry", 5, Rarity.MYTHIC, mage.cards.s.StarscreamPowerHungry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Starscream, Power Hungry", 20, Rarity.MYTHIC, mage.cards.s.StarscreamPowerHungry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ultra Magnus, Tactician", 15, Rarity.MYTHIC, mage.cards.u.UltraMagnusTactician.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Ultra Magnus, Tactician", 29, Rarity.MYTHIC, mage.cards.u.UltraMagnusTactician.class, NON_FULL_USE_VARIOUS)); } -} +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/UniversesWithin.java b/Mage.Sets/src/mage/sets/UniversesWithin.java index 4c79b8ba2de..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)); @@ -37,7 +36,6 @@ public final class UniversesWithin extends ExpansionSet { cards.add(new SetCardInfo("Hansk, Slayer Zealot", 22, Rarity.MYTHIC, mage.cards.h.HanskSlayerZealot.class)); cards.add(new SetCardInfo("Hargilde, Kindly Runechanter", 5, Rarity.RARE, mage.cards.h.HargildeKindlyRunechanter.class)); cards.add(new SetCardInfo("Havengul Laboratory", 9, Rarity.RARE, mage.cards.h.HavengulLaboratory.class)); - cards.add(new SetCardInfo("Havengul Mystery", 9, Rarity.RARE, mage.cards.h.HavengulMystery.class)); cards.add(new SetCardInfo("Immard, the Stormcleaver", 14, Rarity.RARE, mage.cards.i.ImmardTheStormcleaver.class)); cards.add(new SetCardInfo("Jurin, Leading the Charge", 27, Rarity.RARE, mage.cards.j.JurinLeadingTheCharge.class)); cards.add(new SetCardInfo("Maarika, Brutal Gladiator", 15, Rarity.RARE, mage.cards.m.MaarikaBrutalGladiator.class)); diff --git a/Mage.Sets/src/mage/sets/XLNTreasureChest.java b/Mage.Sets/src/mage/sets/XLNTreasureChest.java index d4268f37d84..c8fe454fa4d 100644 --- a/Mage.Sets/src/mage/sets/XLNTreasureChest.java +++ b/Mage.Sets/src/mage/sets/XLNTreasureChest.java @@ -20,22 +20,15 @@ public class XLNTreasureChest extends ExpansionSet { this.hasBoosters = false; this.hasBasicLands = false; - cards.add(new SetCardInfo("Adanto, the First Fort", 22, Rarity.RARE, mage.cards.a.AdantoTheFirstFort.class)); 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("Itlimoc, Cradle of the Sun", 191, Rarity.RARE, mage.cards.i.ItlimocCradleOfTheSun.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("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.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/abilities/oneshot/damage/FlameheartWerewolfTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/FlameheartWerewolfTest.java index 4c617a1cf84..23de9f35fbc 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/FlameheartWerewolfTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/oneshot/damage/FlameheartWerewolfTest.java @@ -1,4 +1,3 @@ - package org.mage.test.cards.abilities.oneshot.damage; import mage.constants.PhaseStep; @@ -38,7 +37,7 @@ public class FlameheartWerewolfTest extends CardTestPlayerBase { // both should die assertPermanentCount(playerA, "Flameheart Werewolf", 0); - assertExileCount("Flameheart Werewolf", 1); // exiled by Kalitas + assertExileCount("Kessig Forgemaster", 1); // exiled by Kalitas assertPermanentCount(playerB, "Kalitas, Traitor of Ghet", 0); assertGraveyardCount(playerB, "Kalitas, Traitor of Ghet", 1); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/WaterbendTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/WaterbendTest.java new file mode 100644 index 00000000000..b2497e08664 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/WaterbendTest.java @@ -0,0 +1,112 @@ +package org.mage.test.cards.mana; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.player.TestPlayer; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class WaterbendTest extends CardTestPlayerBase { + + private static final String waterbender = "Flexible Waterbender"; + + @Test + public void testJustMana() { + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + addCard(Zone.BATTLEFIELD, playerA, waterbender); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "waterbend"); + setChoice(playerA, TestPlayer.CHOICE_SKIP); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, waterbender, 5, 2); + assertTapped(waterbender, false); + assertTapped("Island", true); + } + + private static final String relic = "Darksteel Relic"; + + @Test + public void testNoMana() { + addCard(Zone.BATTLEFIELD, playerA, relic, 2); + addCard(Zone.BATTLEFIELD, playerA, waterbender); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "waterbend"); + setChoice(playerA, waterbender); + setChoice(playerA, relic, 2); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, waterbender, 5, 2); + assertTapped(waterbender, true); + assertTapped(relic, true); + } + + @Test + public void testManaAndCreature() { + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); + addCard(Zone.BATTLEFIELD, playerA, waterbender); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "waterbend"); + setChoice(playerA, waterbender); + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, waterbender, 5, 2); + assertTapped(waterbender, true); + assertTapped("Island", true); + } + + private static final String katara = "Katara, Water Tribe's Hope"; + + @Test + public void testX() { + addCard(Zone.BATTLEFIELD, playerA, "Island"); + addCard(Zone.BATTLEFIELD, playerA, relic, 2); + addCard(Zone.BATTLEFIELD, playerA, katara); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "waterbend"); + setChoice(playerA, "X=4"); + setChoice(playerA, relic, 2); + setChoice(playerA, katara); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPowerToughness(playerA, katara, 4, 4); + assertTapped(relic, true); + assertTapped(katara, true); + assertTapped("Island", true); + } + + private static final String spirit = "Benevolent River Spirit"; + + @Test + public void testSpellCost() { + removeAllCardsFromLibrary(playerA); // removes need to make scry choices + addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.BATTLEFIELD, playerA, relic, 3); + addCard(Zone.HAND, playerA, spirit); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, spirit); + setChoice(playerA, relic, 3); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertTapped("Island", true); + assertTapped(relic, true); + assertTapped(spirit, false); + } +} 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/MageIdentifier.java b/Mage/src/main/java/mage/MageIdentifier.java index 551431e689d..73a85dba09f 100644 --- a/Mage/src/main/java/mage/MageIdentifier.java +++ b/Mage/src/main/java/mage/MageIdentifier.java @@ -39,6 +39,7 @@ public enum MageIdentifier { ThundermanDragonWatcher, LockeTreasureHunterWatcher, TheFourthDoctorWatcher, + AccessMazeWatcher, // ----------------------------// // alternate casts // @@ -65,6 +66,7 @@ public enum MageIdentifier { FireLordOzaiAlternateCast, HelbruteAlternateCast, IntoThePitAlternateCast, + LeonardoSewerSamuraiAlternateCast, MaestrosAscendencyAlternateCast, NashiMoonSagesScionAlternateCast, NoctisPrinceOfLucisAlternateCast, diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index 79a36018a96..d77f7a63962 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -1479,7 +1479,7 @@ public class Mana implements Comparable, Serializable, Copyable { /** * Hardcoding here versus using Objects.hash in order to increase performance since this is - * called thousands of times by {@link mage.abilities.mana.ManaOptions#addManaWithCost(List, Game)} + * called thousands of times by {@link mage.abilities.mana.ManaOptions#addManaWithCost(List, mage.game.Game)} * * @return */ @@ -1517,4 +1517,24 @@ public class Mana implements Comparable, Serializable, Copyable { } return value; } + + public static Mana fromColor(ObjectColor color) { + Mana mana = new Mana(); + 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/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index af9c1ec624e..4d0f3cec930 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -7,10 +7,9 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.Condition; import mage.abilities.costs.*; import mage.abilities.costs.common.PayLifeCost; -import mage.abilities.costs.mana.ManaCost; -import mage.abilities.costs.mana.ManaCosts; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.costs.mana.VariableManaCost; +import mage.abilities.costs.common.WaterbendCost; +import mage.abilities.costs.common.WaterbendXCost; +import mage.abilities.costs.mana.*; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; @@ -25,6 +24,7 @@ import mage.choices.ChoiceHintType; import mage.choices.ChoiceImpl; import mage.constants.*; import mage.filter.FilterMana; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.command.Dungeon; import mage.game.command.Emblem; @@ -39,8 +39,10 @@ import mage.game.stack.StackAbility; import mage.players.Player; import mage.target.Target; import mage.target.TargetCard; +import mage.target.TargetPermanent; import mage.target.Targets; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetControlledPermanent; import mage.target.targetadjustment.GenericTargetAdjuster; import mage.target.targetadjustment.TargetAdjuster; import mage.util.CardUtil; @@ -50,6 +52,7 @@ import mage.watchers.Watcher; import org.apache.log4j.Logger; import java.util.*; +import java.util.stream.Collectors; /** * @author BetaSteward_at_googlemail.com @@ -349,6 +352,7 @@ public abstract class AbilityImpl implements Ability { // Phyrexian mana symbols, the player announces whether they intend to pay 2 // life or the corresponding colored mana cost for each of those symbols. AbilityImpl.handlePhyrexianCosts(game, this, this, this.getManaCostsToPay()); + AbilityImpl.handleWaterbendingCosts(game, this, this, this.getManaCostsToPay()); // 20241022 - 601.2b // Not yet included in 601.2b but this is where it will be @@ -687,6 +691,38 @@ public abstract class AbilityImpl implements Ability { } } + public static void handleWaterbendingCosts(Game game, Ability source, Ability abilityToPay, ManaCosts manaCostsToPay) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return; + } + + int total = CardUtil + .castStream(manaCostsToPay, WaterbendCost.class) + .mapToInt(WaterbendCost::manaValue) + .sum(); + if (total < 1) { + return; + } + TargetPermanent target = new TargetControlledPermanent( + 0, total, StaticFilters.FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE, true + ); + target.withChooseHint("to tap for waterbending"); + controller.choose(Outcome.Tap, target, source, game); + Set permanents = target + .getTargets() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + for (Permanent permanent : permanents) { + permanent.tap(source, game); + } + manaCostsToPay.removeIf(WaterbendCost.class::isInstance); + abilityToPay.addCost(new GenericManaCost(total - permanents.size())); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.WATERBENDED, source.getSourceId(), source, controller.getId(), total)); + } + /** * Prepare and pay Phyrexian style effects like replace mana by life * Must be called after original Phyrexian mana processing and after cost modifications, e.g. on payment @@ -779,54 +815,59 @@ public abstract class AbilityImpl implements Ability { } } } - if (variableManaCost != null) { - if (!variableManaCost.isPaid()) { // should only happen for human players - int xValue; - if (!noMana || variableManaCost.getCostType().canUseAnnounceOnFreeCast()) { - if (variableManaCost.wasAnnounced()) { - // announce by rules - xValue = variableManaCost.getAmount(); - } else { - // announce by player - xValue = controller.announceX(variableManaCost.getMinX(), variableManaCost.getMaxX(), - "Announce the value for " + variableManaCost.getText(), game, this, true); - } - - int amountMana = xValue * variableManaCost.getXInstancesCount(); - StringBuilder manaString = threadLocalBuilder.get(); - if (variableManaCost.getFilter() == null || variableManaCost.getFilter().isGeneric()) { - manaString.append('{').append(amountMana).append('}'); - } else { - String manaSymbol = null; - if (variableManaCost.getFilter().isBlack()) { - if (variableManaCost.getFilter().isRed()) { - manaSymbol = "B/R"; - } else { - manaSymbol = "B"; - } - } else if (variableManaCost.getFilter().isRed()) { - manaSymbol = "R"; - } else if (variableManaCost.getFilter().isBlue()) { - manaSymbol = "U"; - } else if (variableManaCost.getFilter().isGreen()) { - manaSymbol = "G"; - } else if (variableManaCost.getFilter().isWhite()) { - manaSymbol = "W"; - } - if (manaSymbol == null) { - throw new UnsupportedOperationException("ManaFilter is not supported: " + this); - } - for (int i = 0; i < amountMana; i++) { - manaString.append('{').append(manaSymbol).append('}'); - } - } - addManaCostsToPay(new ManaCostsImpl<>(manaString.toString())); - getManaCostsToPay().setX(xValue, amountMana); - setCostsTag("X", xValue); - } - variableManaCost.setPaid(); - } + if (variableManaCost == null) { + return variableManaCost; } + if (variableManaCost.isPaid()) { + return variableManaCost; + } // should only happen for human players + int xValue; + if (!noMana || variableManaCost.getCostType().canUseAnnounceOnFreeCast()) { + if (variableManaCost.wasAnnounced()) { + // announce by rules + xValue = variableManaCost.getAmount(); + } else { + // announce by player + xValue = controller.announceX(variableManaCost.getMinX(), variableManaCost.getMaxX(), + "Announce the value for " + variableManaCost.getText(), game, this, true); + } + + int amountMana = xValue * variableManaCost.getXInstancesCount(); + StringBuilder manaString = threadLocalBuilder.get(); + if (!(variableManaCost instanceof WaterbendXCost)) { + if (variableManaCost.getFilter() == null || variableManaCost.getFilter().isGeneric()) { + manaString.append('{').append(amountMana).append('}'); + } else { + String manaSymbol; + if (variableManaCost.getFilter().isBlack()) { + if (variableManaCost.getFilter().isRed()) { + manaSymbol = "B/R"; + } else { + manaSymbol = "B"; + } + } else if (variableManaCost.getFilter().isRed()) { + manaSymbol = "R"; + } else if (variableManaCost.getFilter().isBlue()) { + manaSymbol = "U"; + } else if (variableManaCost.getFilter().isGreen()) { + manaSymbol = "G"; + } else if (variableManaCost.getFilter().isWhite()) { + manaSymbol = "W"; + } else { + throw new UnsupportedOperationException("ManaFilter is not supported: " + this); + } + for (int i = 0; i < amountMana; i++) { + manaString.append('{').append(manaSymbol).append('}'); + } + } + addManaCostsToPay(new ManaCostsImpl<>(manaString.toString())); + } else { + addManaCostsToPay(new WaterbendCost(amountMana)); + } + getManaCostsToPay().setX(xValue, amountMana); + setCostsTag("X", xValue); + } + variableManaCost.setPaid(); return variableManaCost; } @@ -1701,15 +1742,15 @@ public abstract class AbilityImpl implements Ability { @Override public void initSourceObjectZoneChangeCounter(Game game, boolean force) { - if (!(this instanceof MageSingleton) && (force || sourceObjectZoneChangeCounter == 0 )) { + if (!(this instanceof MageSingleton) && (force || sourceObjectZoneChangeCounter == 0)) { setSourceObjectZoneChangeCounter(getCurrentSourceObjectZoneChangeCounter(game)); } } - private int getCurrentSourceObjectZoneChangeCounter(Game game){ + private int getCurrentSourceObjectZoneChangeCounter(Game game) { int zcc = game.getState().getZoneChangeCounter(getSourceId()); Permanent p = game.getPermanentEntering(getSourceId()); - if (p != null && !(p instanceof PermanentToken)){ + if (p != null && !(p instanceof PermanentToken)) { // If the triggered ability triggered while the permanent is entering the battlefield // then add 1 zcc so that it triggers as if the permanent was already on the battlefield // So "Enters with counters" causes "Whenever counters are placed" to trigger with battlefield zcc diff --git a/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java index a537a79f359..db0a74f26fb 100644 --- a/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DiesOneOrMoreTriggeredAbility.java @@ -5,23 +5,34 @@ import mage.abilities.BatchTriggeredAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeBatchEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTargets; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; /** * @author Susucr */ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implements BatchTriggeredAbility { - private final FilterCreaturePermanent filter; + private final FilterPermanent filter; + private final boolean setTargetPointer; - public DiesOneOrMoreTriggeredAbility(Effect effect, FilterCreaturePermanent filter, boolean optional) { + public DiesOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) { + this(effect, filter, optional, false); + } + + public DiesOneOrMoreTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional, boolean setTargetPointer) { super(Zone.BATTLEFIELD, effect, optional); this.filter = filter; + this.setTargetPointer = setTargetPointer; this.setTriggerPhrase("Whenever one or more " + filter.getMessage() + " die, "); setLeavesTheBattlefieldTrigger(true); } @@ -29,6 +40,7 @@ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implemen private DiesOneOrMoreTriggeredAbility(final DiesOneOrMoreTriggeredAbility ability) { super(ability); this.filter = ability.filter; + this.setTargetPointer = ability.setTargetPointer; } @Override @@ -52,7 +64,21 @@ public class DiesOneOrMoreTriggeredAbility extends TriggeredAbilityImpl implemen @Override public boolean checkTrigger(GameEvent event, Game game) { - return !getFilteredEvents((ZoneChangeBatchEvent) event, game).isEmpty(); + List events = getFilteredEvents((ZoneChangeBatchEvent) event, game); + if (events.isEmpty()) { + return false; + } + if (setTargetPointer) { + this.getAllEffects().setTargetPointer(new FixedTargets( + events.stream() + .map(GameEvent::getTargetId) + .map(game::getCard) + .filter(Objects::nonNull) + .collect(Collectors.toSet()), + game + )); + } + return true; } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java b/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java index ca7e543bbe2..a90b37d5815 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/BeheldDragonCondition.java @@ -2,7 +2,7 @@ package mage.abilities.condition.common; import mage.abilities.Ability; import mage.abilities.condition.Condition; -import mage.abilities.keyword.BeholdDragonAbility; +import mage.abilities.keyword.BeholdAbility; import mage.game.Game; import mage.util.CardUtil; @@ -16,7 +16,7 @@ public enum BeheldDragonCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - return CardUtil.checkSourceCostsTagExists(game, source, BeholdDragonAbility.BEHOLD_DRAGON_ACTIVATION_VALUE_KEY); + return CardUtil.checkSourceCostsTagExists(game, source, BeholdAbility.BEHOLD_ACTIVATION_VALUE_KEY); } @Override diff --git a/Mage/src/main/java/mage/abilities/condition/common/BlightedCondition.java b/Mage/src/main/java/mage/abilities/condition/common/BlightedCondition.java new file mode 100644 index 00000000000..a65801a94d0 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/condition/common/BlightedCondition.java @@ -0,0 +1,26 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.abilities.keyword.BlightAbility; +import mage.game.Game; +import mage.util.CardUtil; + +/** + * Checks if the spell was cast with the alternate blight cost + * + * @author TheElk801 + */ +public enum BlightedCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + return CardUtil.checkSourceCostsTagExists(game, source, BlightAbility.BLIGHT_ACTIVATION_VALUE_KEY); + } + + @Override + public String toString() { + return "creature was blighted"; + } +} 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/costs/common/BeholdAndExileCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java new file mode 100644 index 00000000000..09aa2d7a216 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdAndExileCost.java @@ -0,0 +1,62 @@ +package mage.abilities.costs.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.cards.Card; +import mage.constants.BeholdType; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class BeholdAndExileCost extends CostImpl { + + private final BeholdType beholdType; + + public BeholdAndExileCost(BeholdType beholdType) { + super(); + this.beholdType = beholdType; + this.text = "behold " + beholdType.getDescription() + " and exile it"; + } + + private BeholdAndExileCost(final BeholdAndExileCost cost) { + super(cost); + this.beholdType = cost.beholdType; + } + + @Override + public BeholdAndExileCost copy() { + return new BeholdAndExileCost(this); + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return beholdType.canBehold(controllerId, game, source); + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + Player player = game.getPlayer(controllerId); + if (player == null) { + paid = false; + return paid; + } + Card card = beholdType.doBehold(player, game, source); + if (card == null) { + paid = false; + return paid; + } + player.moveCardsToExile( + card, source, game, true, + CardUtil.getExileZoneId(game, source, 1), + CardUtil.getSourceName(game, source) + ); + paid = true; + return paid; + } +} diff --git a/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java new file mode 100644 index 00000000000..ea8e31afb86 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/BeholdCost.java @@ -0,0 +1,46 @@ +package mage.abilities.costs.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.constants.BeholdType; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class BeholdCost extends CostImpl { + + private final BeholdType beholdType; + + public BeholdCost(BeholdType beholdType) { + super(); + this.beholdType = beholdType; + this.text = "behold " + beholdType.getDescription(); + } + + private BeholdCost(final BeholdCost cost) { + super(cost); + this.beholdType = cost.beholdType; + } + + @Override + public BeholdCost copy() { + return new BeholdCost(this); + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return beholdType.canBehold(controllerId, game, source); + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + Player player = game.getPlayer(controllerId); + paid = player != null && beholdType.doBehold(player, game, source) != null; + return paid; + } +} diff --git a/Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java b/Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java deleted file mode 100644 index 3502a9a0888..00000000000 --- a/Mage/src/main/java/mage/abilities/costs/common/BeholdDragonCost.java +++ /dev/null @@ -1,109 +0,0 @@ -package mage.abilities.costs.common; - -import mage.abilities.Ability; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.cards.Card; -import mage.cards.CardsImpl; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.filter.FilterCard; -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.TargetCard; -import mage.target.TargetPermanent; -import mage.target.common.TargetCardInHand; - -import java.util.Optional; -import java.util.UUID; - -/** - * @author TheElk801 - */ -public class BeholdDragonCost extends CostImpl { - - private static final FilterPermanent filterPermanent = new FilterControlledPermanent(SubType.DRAGON); - private static final FilterCard filterCard = new FilterCard("a Dragon card"); - - static { - filterCard.add(SubType.DRAGON.getPredicate()); - } - - public BeholdDragonCost() { - super(); - this.text = "behold a Dragon"; - } - - private BeholdDragonCost(final BeholdDragonCost cost) { - super(cost); - } - - @Override - public BeholdDragonCost copy() { - return new BeholdDragonCost(this); - } - - @Override - public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return Optional - .ofNullable(game.getPlayer(controllerId)) - .map(Player::getHand) - .map(cards -> cards.count(filterCard, game) > 0) - .orElse(false) - || game - .getBattlefield() - .contains(filterPermanent, controllerId, source, game, 1); - } - - @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - Player player = game.getPlayer(controllerId); - if (player == null) { - paid = false; - return paid; - } - boolean hasPermanent = game - .getBattlefield() - .contains(filterPermanent, controllerId, source, game, 1); - boolean hasHand = player.getHand().count(filterCard, game) > 0; - boolean usePermanent; - if (hasPermanent && hasHand) { - usePermanent = player.chooseUse( - Outcome.Neutral, "Choose a Dragon you control or reveal one from your hand?", - null, "Choose controlled", "Reveal from hand", source, game); - } else if (hasPermanent) { - usePermanent = true; - } else if (hasHand) { - usePermanent = false; - } else { - paid = false; - return paid; - } - if (usePermanent) { - TargetPermanent target = new TargetPermanent(filterPermanent); - target.withNotTarget(true); - player.choose(Outcome.Neutral, target, source, game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent == null) { - paid = false; - return paid; - } - game.informPlayers(player.getLogName() + " chooses to behold " + permanent.getLogName()); - paid = true; - return true; - } - TargetCard target = new TargetCardInHand(filterCard); - player.choose(Outcome.Neutral, player.getHand(), target, source, game); - Card card = game.getCard(target.getFirstTarget()); - if (card == null) { - paid = false; - return paid; - } - player.revealCards(source, new CardsImpl(card), game); - paid = true; - return paid; - } -} diff --git a/Mage/src/main/java/mage/abilities/costs/common/BlightCost.java b/Mage/src/main/java/mage/abilities/costs/common/BlightCost.java new file mode 100644 index 00000000000..79c78b85255 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/BlightCost.java @@ -0,0 +1,74 @@ +package mage.abilities.costs.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +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; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class BlightCost extends CostImpl { + + private int amount; + + public BlightCost(int amount) { + super(); + this.amount = amount; + this.text = "blight " + amount; + } + + private BlightCost(final BlightCost cost) { + super(cost); + this.amount = cost.amount; + } + + @Override + public BlightCost copy() { + return new BlightCost(this); + } + + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + return canBlight(controllerId, game, source); + } + + public static boolean canBlight(UUID controllerId, Game game, Ability source) { + return game + .getBattlefield() + .contains(StaticFilters.FILTER_CONTROLLED_CREATURE, controllerId, source, game, 1); + } + + @Override + public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { + Player player = game.getPlayer(controllerId); + paid = player != null && doBlight(player, amount, game, source) != null; + return paid; + } + + 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/costs/common/ExileTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/ExileTargetCost.java index 07cf32a50c9..2cd8b16b742 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/ExileTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/ExileTargetCost.java @@ -1,5 +1,3 @@ - - package mage.abilities.costs.common; import mage.abilities.Ability; @@ -24,6 +22,7 @@ import java.util.UUID; public class ExileTargetCost extends CostImpl { List permanents = new ArrayList<>(); + boolean useSourceExileZone = true; public ExileTargetCost(TargetControlledPermanent target) { target.withNotTarget(true); @@ -36,6 +35,7 @@ public class ExileTargetCost extends CostImpl { for (Permanent permanent : cost.permanents) { this.permanents.add(permanent.copy()); } + this.useSourceExileZone = cost.useSourceExileZone; } @Override @@ -55,13 +55,19 @@ public class ExileTargetCost extends CostImpl { // 117.11. The actions performed when paying a cost may be modified by effects. // Even if they are, meaning the actions that are performed don't match the actions // that are called for, the cost has still been paid. - // so return state here is not important because the user indended to exile the target anyway + // so return state here is not important because the user intended to exile the target anyway } - player.moveCardsToExile( - cards.getCards(game), source, game, true, - CardUtil.getExileZoneId(game, source), - CardUtil.getSourceName(game, source) - ); + if (useSourceExileZone) { + player.moveCardsToExile( + cards.getCards(game), source, game, true, + CardUtil.getExileZoneId(game, source), + CardUtil.getSourceName(game, source) + ); + } + else { + player.moveCardsToExile(cards.getCards(game), source, game, false, null, ""); + } + paid = true; return paid; } @@ -79,4 +85,12 @@ public class ExileTargetCost extends CostImpl { public List getPermanents() { return permanents; } + + /** + * Put exiled cards to source zone, so next linked ability can find it + */ + public ExileTargetCost withSourceExileZone(boolean useSourceExileZone) { + this.useSourceExileZone = useSourceExileZone; + return this; + } } diff --git a/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java b/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java index db762f8a0cd..fc2c034de9b 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/WaterbendCost.java @@ -1,26 +1,31 @@ package mage.abilities.costs.common; -import mage.abilities.Ability; -import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; -import mage.game.Game; - -import java.util.UUID; +import mage.Mana; +import mage.abilities.costs.mana.GenericManaCost; /** - * TODO: Implement properly + * 701.67. Waterbend + *

+ * 701.67a “Waterbend [cost]” means “Pay [cost]. For each generic mana in that cost, + * you may tap an untapped artifact or creature you control rather than pay that mana.” + *

+ * 701.67b If a waterbend cost is part of the total cost to cast a spell or activate an ability + * (usually because the waterbend cost itself is an additional cost), the alternate method to pay for mana + * described in rule 701.67a may be used only to pay for the amount of generic mana in the waterbend cost, + * even if the total cost to cast that spell or activate that ability includes other generic mana components. + *

+ * If you need Waterbend {X} then use {@link WaterbendXCost} + * If using as an additional cost for a spell, add an ability with an InfoEffect for proper text generation (see WaterWhip) * * @author TheElk801 */ -public class WaterbendCost extends CostImpl { +public class WaterbendCost extends GenericManaCost { public WaterbendCost(int amount) { - this("{" + amount + '}'); - } - - public WaterbendCost(String mana) { - super(); - this.text = "waterbend " + mana; + super(amount); + for (int i = 0; i < amount; i++) { + options.add(Mana.ColorlessMana(i)); + } } private WaterbendCost(final WaterbendCost cost) { @@ -33,12 +38,7 @@ public class WaterbendCost extends CostImpl { } @Override - public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { - return false; - } - - @Override - public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) { - return false; + public String getText() { + return "waterbend " + super.getText(); } } diff --git a/Mage/src/main/java/mage/abilities/costs/common/WaterbendXCost.java b/Mage/src/main/java/mage/abilities/costs/common/WaterbendXCost.java new file mode 100644 index 00000000000..b9d2e4d25a8 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/WaterbendXCost.java @@ -0,0 +1,36 @@ +package mage.abilities.costs.common; + +import mage.abilities.costs.VariableCostType; +import mage.abilities.costs.mana.VariableManaCost; + +/** + * Used for Waterbend {X} costs, otherwise use {@link WaterbendCost} + * If using as an additional cost for a spell, add an ability with an InfoEffect for proper text generation (see WaterbendersRestoration) + * + * @author TheElk801 + */ +public class WaterbendXCost extends VariableManaCost { + + public WaterbendXCost() { + this(0); + } + + public WaterbendXCost(int minX) { + super(VariableCostType.NORMAL); + this.setMinX(minX); + } + + private WaterbendXCost(final WaterbendXCost cost) { + super(cost); + } + + @Override + public WaterbendXCost copy() { + return new WaterbendXCost(this); + } + + @Override + public String getText() { + return "waterbend {X}"; + } +} diff --git a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java index 566934b34c7..1b81566e238 100644 --- a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java @@ -5,20 +5,27 @@ import mage.abilities.Ability; import mage.abilities.AbilityImpl; import mage.abilities.costs.*; import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.common.WaterbendCost; import mage.abilities.mana.ManaOptions; import mage.constants.ColoredManaSymbol; import mage.constants.ManaType; import mage.constants.Outcome; import mage.filter.Filter; +import mage.filter.StaticFilters; import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.players.ManaPool; import mage.players.Player; +import mage.target.TargetPermanent; import mage.target.Targets; +import mage.target.common.TargetControlledPermanent; import mage.util.CardUtil; import mage.util.ManaUtil; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** * @param @@ -162,6 +169,7 @@ public class ManaCostsImpl extends ArrayList implements M if (payingPlayer != null) { int bookmark = game.bookmarkState(); handlePhyrexianManaCosts(ability, payingPlayer, source, game); + handleWaterbendingCosts(ability, payingPlayer, source, game); if (pay(ability, game, source, payingPlayerId, false, null)) { game.removeBookmark(bookmark); return true; @@ -195,6 +203,33 @@ public class ManaCostsImpl extends ArrayList implements M tempCosts.pay(source, game, source, payingPlayer.getId(), false, null); } + private void handleWaterbendingCosts(Ability abilityToPay, Player payingPlayer, Ability source, Game game) { + int total = CardUtil + .castStream(this, WaterbendCost.class) + .mapToInt(WaterbendCost::manaValue) + .sum(); + if (total < 1) { + return; + } + TargetPermanent target = new TargetControlledPermanent( + 0, total, StaticFilters.FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE, true + ); + target.withChooseHint("to tap for waterbending"); + payingPlayer.choose(Outcome.Tap, target, source, game); + Set permanents = target + .getTargets() + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + for (Permanent permanent : permanents) { + permanent.tap(source, game); + } + this.removeIf(WaterbendCost.class::isInstance); + this.add(new GenericManaCost(total - permanents.size())); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.WATERBENDED, source.getSourceId(), source, payingPlayer.getId(), total)); + } + @Override public ManaCosts getUnpaid() { ManaCosts unpaid = new ManaCostsImpl<>(); diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ColorsAmongControlledPermanentsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ColorsAmongControlledPermanentsCount.java new file mode 100644 index 00000000000..1fa1bfd017e --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ColorsAmongControlledPermanentsCount.java @@ -0,0 +1,114 @@ +package mage.abilities.dynamicvalue.common; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.hint.Hint; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.MonocoloredPredicate; +import mage.game.Game; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author TheElk801 + */ +public enum ColorsAmongControlledPermanentsCount implements DynamicValue { + ALL_PERMANENTS(StaticFilters.FILTER_CONTROLLED_PERMANENTS), + MONOCOLORED_PERMANENTS(PermanentFilters.MONOCOLORED_PERMANENTS), + OTHER_LEGENDARY(PermanentFilters.OTHER_LEGENDARY), + ALLIES(new FilterControlledPermanent(SubType.ALLY, "Allies you control")); + private final FilterPermanent filter; + private final Hint hint; + + ColorsAmongControlledPermanentsCount(FilterPermanent filter) { + this.filter = filter; + this.hint = new ColorsAmongControlledPermanentsHint(this); + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return getAllControlledColors(game, sourceAbility).getColorCount(); + } + + @Override + public ColorsAmongControlledPermanentsCount copy() { + return this; + } + + @Override + public String getMessage() { + return "for each color among " + filter.getMessage(); + } + + @Override + public String toString() { + return "1"; + } + + public Hint getHint() { + return hint; + } + + public FilterPermanent getFilter() { + return filter; + } + + public ObjectColor getAllControlledColors(Game game, Ability source) { + return game + .getBattlefield() + .getActivePermanents(filter, source.getControllerId(), source, game) + .stream() + .map(permanent -> permanent.getColor(game)) + .reduce(new ObjectColor(), (c1, c2) -> c1.union(c2)); + } +} + +class ColorsAmongControlledPermanentsHint implements Hint { + + private final ColorsAmongControlledPermanentsCount count; + + ColorsAmongControlledPermanentsHint(ColorsAmongControlledPermanentsCount count) { + this.count = count; + } + + @Override + public String getText(Game game, Ability ability) { + List colors = this + .count + .getAllControlledColors(game, ability) + .getColors() + .stream() + .map(ObjectColor::getDescription) + .collect(Collectors.toList()); + return "Colors among " + this.count.getFilter().getMessage() + ": " + colors.size() + + (colors.size() > 0 ? " (" + String.join(", ", colors) + ')' : ""); + } + + @Override + public Hint copy() { + return this; + } +} + +class PermanentFilters { + static final FilterPermanent MONOCOLORED_PERMANENTS = new FilterControlledPermanent("monocolored permanents you control"); + + static { + MONOCOLORED_PERMANENTS.add(MonocoloredPredicate.instance); + } + + static final FilterPermanent OTHER_LEGENDARY = new FilterControlledPermanent("other legendary permanents you control"); + + static { + OTHER_LEGENDARY.add(AnotherPredicate.instance); + OTHER_LEGENDARY.add(SuperType.LEGENDARY.getPredicate()); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/AdditionalCombatPhaseEffect.java b/Mage/src/main/java/mage/abilities/effects/common/AdditionalCombatPhaseEffect.java index 273fcbe3cff..0ac46edfd12 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/AdditionalCombatPhaseEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/AdditionalCombatPhaseEffect.java @@ -13,9 +13,7 @@ public class AdditionalCombatPhaseEffect extends OneShotEffect { private final int additionalPhases; public AdditionalCombatPhaseEffect() { - super(Outcome.Benefit); - this.additionalPhases = 1; - staticText = "after this phase, there is an additional combat phase"; + this(1); } public AdditionalCombatPhaseEffect(int additionalPhases) { @@ -23,13 +21,11 @@ public class AdditionalCombatPhaseEffect extends OneShotEffect { if (additionalPhases < 1) { throw new IllegalArgumentException("Number of additional phases must be at least 1"); } - if (additionalPhases == 1) { - this.additionalPhases = 1; - staticText = "after this phase, there is an additional combat phase"; - } else { - this.additionalPhases = additionalPhases; - staticText = "after this phase, there are " + additionalPhases + " additional combat phases"; - } + this.additionalPhases = additionalPhases; + staticText = "after this phase, there " + + (additionalPhases > 1 ? "are " + additionalPhases : "is an") + + " additional combat phase" + + (additionalPhases > 1 ? "s" : ""); } protected AdditionalCombatPhaseEffect(final AdditionalCombatPhaseEffect effect) { 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/DrawCardForEachColorAmongControlledPermanentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawCardForEachColorAmongControlledPermanentsEffect.java deleted file mode 100644 index 00df6e96f72..00000000000 --- a/Mage/src/main/java/mage/abilities/effects/common/DrawCardForEachColorAmongControlledPermanentsEffect.java +++ /dev/null @@ -1,57 +0,0 @@ -package mage.abilities.effects.common; - -import mage.ObjectColor; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; - -import java.util.HashSet; -import java.util.Set; - -public class DrawCardForEachColorAmongControlledPermanentsEffect extends OneShotEffect { - - public DrawCardForEachColorAmongControlledPermanentsEffect() { - super(Outcome.DrawCard); - this.staticText = "Draw a card for each color among permanents you control"; - } - - protected DrawCardForEachColorAmongControlledPermanentsEffect(final DrawCardForEachColorAmongControlledPermanentsEffect effect) { - super(effect); - } - - @Override - public DrawCardForEachColorAmongControlledPermanentsEffect copy() { - return new DrawCardForEachColorAmongControlledPermanentsEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Set colors = new HashSet<>(); - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(controller.getId())) { - if (permanent.getColor(game).isBlack()) { - colors.add(ObjectColor.BLACK); - } - if (permanent.getColor(game).isBlue()) { - colors.add(ObjectColor.BLUE); - } - if (permanent.getColor(game).isRed()) { - colors.add(ObjectColor.RED); - } - if (permanent.getColor(game).isGreen()) { - colors.add(ObjectColor.GREEN); - } - if (permanent.getColor(game).isWhite()) { - colors.add(ObjectColor.WHITE); - } - } - controller.drawCards(colors.size(), source, game); - return true; - } - 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 eacbc21c535..1e8b2c1c4e9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnSourceEffect.java @@ -2,11 +2,11 @@ package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.constants.Pronoun; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; +import mage.constants.Pronoun; import mage.constants.PutCards; import mage.constants.Zone; import mage.game.Game; @@ -74,7 +74,7 @@ public class ExileAndReturnSourceEffect extends OneShotEffect { returnUnderYourControl ? controller : game.getPlayer(permanent.getOwnerId()), permanent.getMainCard(), source, game, "card" ); - if (additionalEffect == null || game.getPermanent(permanent.getId()) == 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/common/FightEnchantedTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FightEnchantedTargetEffect.java new file mode 100644 index 00000000000..d51f26ee10a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/FightEnchantedTargetEffect.java @@ -0,0 +1,48 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.Optional; + +/** + * @author TheElk801 + */ +public class FightEnchantedTargetEffect extends OneShotEffect { + + public FightEnchantedTargetEffect() { + super(Outcome.Benefit); + } + + private FightEnchantedTargetEffect(final FightEnchantedTargetEffect effect) { + super(effect); + } + + @Override + public FightEnchantedTargetEffect copy() { + return new FightEnchantedTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = Optional + .ofNullable(source.getSourcePermanentOrLKI(game)) + .map(Permanent::getAttachedTo) + .map(game::getPermanent) + .orElse(null); + Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); + return permanent != null && creature != null && permanent.fight(creature, source, game); + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "enchanted creature fights " + getTargetPointer().describeTargets(mode.getTargets(), "it"); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/RemoveUpToAmountCountersEffect.java b/Mage/src/main/java/mage/abilities/effects/common/RemoveUpToAmountCountersEffect.java index e69d9cce542..710d71e9bbd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/RemoveUpToAmountCountersEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/RemoveUpToAmountCountersEffect.java @@ -2,8 +2,6 @@ package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.constants.MultiAmountType; import mage.constants.Outcome; @@ -14,17 +12,13 @@ import mage.util.CardUtil; import java.util.ArrayList; import java.util.List; +import java.util.UUID; public class RemoveUpToAmountCountersEffect extends OneShotEffect { - final DynamicValue amount; + private final int amount; public RemoveUpToAmountCountersEffect(int amount) { - super(Outcome.Neutral); - this.amount = StaticValue.get(amount); - } - - public RemoveUpToAmountCountersEffect(DynamicValue amount) { super(Outcome.Neutral); this.amount = amount; } @@ -41,39 +35,57 @@ public class RemoveUpToAmountCountersEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { - return false; - } - int max = this.amount.calculate(game, source, this); - // from permanent - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - List toChoose = new ArrayList<>(permanent.getCounters(game).keySet()); - List counterList = controller.getMultiAmount(Outcome.UnboostCreature, toChoose, 0, 0, max, MultiAmountType.REMOVE_COUNTERS, game); - for (int i = 0; i < toChoose.size(); i++) { - int amountToRemove = counterList.get(i); - if (amountToRemove > 0) { - permanent.removeCounters(toChoose.get(i), amountToRemove, source, game); - } - } - return true; - } + return doRemoval( + amount, + getTargetPointer().getFirst(game, source), + game.getPlayer(source.getControllerId()), + game, source + ) > 0; + } - // from player - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - List toChoose = new ArrayList<>(player.getCountersAsCopy().keySet()); - List counterList = controller.getMultiAmount(Outcome.Neutral, toChoose, 0, 0, max, MultiAmountType.REMOVE_COUNTERS, game); - for (int i = 0; i < toChoose.size(); i++) { - int amountToRemove = counterList.get(i); - if (amountToRemove > 0) { - player.loseCounters(toChoose.get(i), amountToRemove, source, game); - } - } - return true; + private static List getCounters(Permanent permanent, Player player, Game game) { + if (permanent != null) { + return new ArrayList<>(permanent.getCounters(game).keySet()); } - return false; + if (player != null) { + return new ArrayList<>(player.getCountersAsCopy().keySet()); + } + return new ArrayList<>(); + } + + private static int removeCounters(Permanent permanent, Player player, String counterName, int amountToRemove, Game game, Ability source) { + if (permanent != null) { + return permanent.removeCounters(counterName, amountToRemove, source, game, false); + } + if (player != null) { + // TODO: currently doesn't return how many counters are removed for a player + player.loseCounters(counterName, amountToRemove, source, game); + } + return 0; + } + + public static int doRemoval(int amount, UUID targetId, Player controller, Game game, Ability source) { + Permanent permanent = game.getPermanent(targetId); + Player player = game.getPlayer(targetId); + if (controller == null || (permanent == null && player == null) || amount < 1) { + return 0; + } + List toChoose = getCounters(permanent, player, game); + if (toChoose.isEmpty()) { + return 0; + } + List counterList = controller.getMultiAmount( + Outcome.UnboostCreature, toChoose, 0, 0, + amount, MultiAmountType.REMOVE_COUNTERS, game + ); + int total = 0; + for (int i = 0; i < toChoose.size(); i++) { + int amountToRemove = counterList.get(i); + if (amountToRemove > 0) { + total += removeCounters(permanent, player, toChoose.get(i), amountToRemove, game, source); + } + } + return total; } @Override @@ -81,6 +93,13 @@ public class RemoveUpToAmountCountersEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - return "remove up to " + CardUtil.numberToText(this.amount.toString()) + " counters from " + getTargetPointer().describeTargets(mode.getTargets(), "that permanent"); + StringBuilder sb = new StringBuilder("remove "); + if (amount < Integer.MAX_VALUE) { + sb.append("up to "); + } + sb.append(CardUtil.numberToText(amount)); + sb.append(" counters from "); + sb.append(getTargetPointer().describeTargets(mode.getTargets(), "that permanent")); + return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnExiledCardToHandEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnExiledCardToHandEffect.java new file mode 100644 index 00000000000..31ccd949e39 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnExiledCardToHandEffect.java @@ -0,0 +1,37 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public class ReturnExiledCardToHandEffect extends OneShotEffect { + + public ReturnExiledCardToHandEffect() { + super(Outcome.Benefit); + staticText = "return the exiled card to its owner's hand"; + } + + private ReturnExiledCardToHandEffect(final ReturnExiledCardToHandEffect effect) { + super(effect); + } + + @Override + public ReturnExiledCardToHandEffect copy() { + return new ReturnExiledCardToHandEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + return player != null && exileZone != null && player.moveCards(exileZone, Zone.HAND, source, game); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java index bff4df651c9..bb3d4ff442a 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/AmassEffect.java @@ -24,6 +24,9 @@ import mage.target.TargetPermanent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.Set; +import java.util.UUID; + /** * @author TheElk801 */ @@ -99,23 +102,36 @@ public class AmassEffect extends OneShotEffect { if (!game.getBattlefield().contains(filter, source, game, 1)) { makeToken(subType).putOntoBattlefield(1, game, source); } + Target target = new TargetPermanent(filter); target.withNotTarget(true); - player.choose(Outcome.BoostCreature, target, source, game); - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent == null) { + Permanent armyPermanent; + Set possibleTargets = target.possibleTargets(source.getControllerId(), source, game); + if (possibleTargets.isEmpty()) { return null; } - if (!permanent.hasSubtype(subType, game)) { + // only one possible option, don't prompt user to click permanent + if (possibleTargets.size() == 1) { + armyPermanent = game.getPermanent(possibleTargets.iterator().next()); + } + else { + player.choose(Outcome.BoostCreature, target, source, game); + armyPermanent = game.getPermanent(target.getFirstTarget()); + } + + if (armyPermanent == null) { + return null; + } + if (!armyPermanent.hasSubtype(subType, game)) { game.addEffect(new AddCardSubTypeTargetEffect(subType, Duration.Custom) - .setTargetPointer(new FixedTarget(permanent, game)), source); + .setTargetPointer(new FixedTarget(armyPermanent, game)), source); } if (xValue > 0) { - permanent.addCounters( + armyPermanent.addCounters( CounterType.P1P1.createInstance(xValue), source.getControllerId(), source, game ); } - return permanent; + return armyPermanent; } } 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..a4a3345a46c --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/keyword/BlightControllerEffect.java @@ -0,0 +1,36 @@ +package mage.abilities.effects.keyword; + +import mage.abilities.Ability; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; + +/** + * @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) { + return BlightCost.doBlight(game.getPlayer(source.getControllerId()), amount, game, source) != null; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/BlightTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/BlightTargetEffect.java new file mode 100644 index 00000000000..ad8a6e8f364 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/keyword/BlightTargetEffect.java @@ -0,0 +1,45 @@ +package mage.abilities.effects.keyword; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.costs.common.BlightCost; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public class BlightTargetEffect extends OneShotEffect { + + private final int amount; + + public BlightTargetEffect(int amount) { + super(Outcome.Detriment); + this.amount = amount; + staticText = "blight " + amount; + } + + private BlightTargetEffect(final BlightTargetEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public BlightTargetEffect copy() { + return new BlightTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return BlightCost.doBlight(game.getPlayer(getTargetPointer().getFirst(game, source)), amount, game, source) != null; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + return getTargetPointer().describeTargets(mode.getTargets(), "that player") + " blights " + amount; + } +} 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/BeholdDragonAbility.java b/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java similarity index 57% rename from Mage/src/main/java/mage/abilities/keyword/BeholdDragonAbility.java rename to Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java index 9c9d6fd5bbc..2a381d00d19 100644 --- a/Mage/src/main/java/mage/abilities/keyword/BeholdDragonAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/BeholdAbility.java @@ -4,9 +4,8 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; import mage.abilities.costs.*; -import mage.abilities.costs.common.BeholdDragonCost; -import mage.abilities.costs.common.CollectEvidenceCost; -import mage.abilities.hint.common.EvidenceHint; +import mage.abilities.costs.common.BeholdCost; +import mage.constants.BeholdType; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -15,38 +14,47 @@ import mage.players.Player; /** * @author TheElk801 */ -public class BeholdDragonAbility extends StaticAbility implements OptionalAdditionalSourceCosts { +public class BeholdAbility extends StaticAbility implements OptionalAdditionalSourceCosts { - private static final String promptString = "Behold a Dragon"; - private static final String keywordText = "As an additional cost to cast this spell, you may behold a Dragon"; - private static final String reminderText = "Choose a Dragon you control or reveal a Dragon card from your hand."; + private static final String promptString = "Behold "; + private static final String keywordText = "As an additional cost to cast this spell, you may behold "; + private static final String reminderText = "Choose $$$ you control or reveal $$$ card from your hand."; private final String rule; - public static final String BEHOLD_DRAGON_ACTIVATION_VALUE_KEY = "beholdDragonActivation"; + public static final String BEHOLD_ACTIVATION_VALUE_KEY = "beholdActivation"; protected OptionalAdditionalCost additionalCost; - public static OptionalAdditionalCost makeCost() { - OptionalAdditionalCost cost = new OptionalAdditionalCostImpl(keywordText , reminderText, new BeholdDragonCost()); + public static OptionalAdditionalCost makeCost(BeholdType beholdType) { + OptionalAdditionalCost cost = new OptionalAdditionalCostImpl( + keywordText + beholdType.getDescription(), + reminderText.replace("$$$", beholdType.getDescription()), + new BeholdCost(beholdType) + ); cost.setRepeatable(false); return cost; } - public BeholdDragonAbility( ) { + + private final BeholdType beholdType; + + public BeholdAbility(BeholdType beholdType) { super(Zone.STACK, null); - this.additionalCost = makeCost(); - this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); + this.beholdType = beholdType; + this.additionalCost = makeCost(beholdType); + this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); this.setRuleAtTheTop(true); } - private BeholdDragonAbility(final BeholdDragonAbility ability) { + private BeholdAbility(final BeholdAbility ability) { super(ability); + this.beholdType = ability.beholdType; this.rule = ability.rule; this.additionalCost = ability.additionalCost.copy(); } @Override - public BeholdDragonAbility copy() { - return new BeholdDragonAbility(this); + public BeholdAbility copy() { + return new BeholdAbility(this); } public void resetCost() { @@ -68,7 +76,7 @@ public class BeholdDragonAbility extends StaticAbility implements OptionalAdditi this.resetCost(); boolean canPay = additionalCost.canPay(ability, this, ability.getControllerId(), game); - if (!canPay || !player.chooseUse(Outcome.Exile, promptString + '?', ability, game)) { + if (!canPay || !player.chooseUse(Outcome.Exile, promptString + beholdType.getDescription() + '?', ability, game)) { return; } @@ -76,7 +84,7 @@ public class BeholdDragonAbility extends StaticAbility implements OptionalAdditi for (Cost cost : ((Costs) additionalCost)) { ability.getCosts().add(cost.copy()); } - ability.setCostsTag(BEHOLD_DRAGON_ACTIVATION_VALUE_KEY, null); + ability.setCostsTag(BEHOLD_ACTIVATION_VALUE_KEY, null); } @Override diff --git a/Mage/src/main/java/mage/abilities/keyword/BlightAbility.java b/Mage/src/main/java/mage/abilities/keyword/BlightAbility.java new file mode 100644 index 00000000000..73d65ff0e92 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/BlightAbility.java @@ -0,0 +1,96 @@ +package mage.abilities.keyword; + +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.StaticAbility; +import mage.abilities.costs.*; +import mage.abilities.costs.common.BlightCost; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +/** + * @author TheElk801 + */ +public class BlightAbility extends StaticAbility implements OptionalAdditionalSourceCosts { + + public static final String BLIGHT_ACTIVATION_VALUE_KEY = "blightActivation"; + + protected OptionalAdditionalCost additionalCost; + + public static OptionalAdditionalCost makeCost(int amount) { + OptionalAdditionalCost cost = new OptionalAdditionalCostImpl( + "As an additional cost to cast this spell, you may blight " + amount, + "You may put " + CardUtil.numberToText(amount, "a") + + " -1/-1 counter" + (amount > 1 ? "s" : "") + "on a creature you control.", + new BlightCost(amount) + ); + cost.setRepeatable(false); + return cost; + } + + private final int amount; + private final String rule; + + public BlightAbility(int amount) { + super(Zone.STACK, null); + this.amount = amount; + this.additionalCost = makeCost(amount); + this.rule = additionalCost.getName() + ". " + additionalCost.getReminderText(); + this.setRuleAtTheTop(true); + } + + private BlightAbility(final BlightAbility ability) { + super(ability); + this.amount = ability.amount; + this.rule = ability.rule; + this.additionalCost = ability.additionalCost.copy(); + } + + @Override + public BlightAbility copy() { + return new BlightAbility(this); + } + + public void resetCost() { + if (additionalCost != null) { + additionalCost.reset(); + } + } + + @Override + public void addOptionalAdditionalCosts(Ability ability, Game game) { + if (!(ability instanceof SpellAbility)) { + return; + } + + Player player = game.getPlayer(ability.getControllerId()); + if (player == null) { + return; + } + + this.resetCost(); + boolean canPay = additionalCost.canPay(ability, this, ability.getControllerId(), game); + if (!canPay || !player.chooseUse(Outcome.Exile, "Blight " + amount + '?', ability, game)) { + return; + } + + additionalCost.activate(); + for (Cost cost : ((Costs) additionalCost)) { + ability.getCosts().add(cost.copy()); + } + ability.setCostsTag(BLIGHT_ACTIVATION_VALUE_KEY, null); + } + + @Override + public String getCastMessageSuffix() { + return additionalCost.getCastSuffixMessage(0); + } + + @Override + public String getRule() { + return rule; + } +} 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/abilities/mana/AddEachControlledColorManaAbility.java b/Mage/src/main/java/mage/abilities/mana/AddEachControlledColorManaAbility.java new file mode 100644 index 00000000000..66ec5373483 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/mana/AddEachControlledColorManaAbility.java @@ -0,0 +1,54 @@ +package mage.abilities.mana; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount; +import mage.abilities.effects.mana.ManaEffect; +import mage.constants.Zone; +import mage.game.Game; + +/** + * @author TheElk801 + */ +public class AddEachControlledColorManaAbility extends ActivatedManaAbilityImpl { + + public AddEachControlledColorManaAbility() { + super(Zone.BATTLEFIELD, new AddEachControlledColorManaEffect(), new TapSourceCost()); + this.addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint()); + } + + private AddEachControlledColorManaAbility(final AddEachControlledColorManaAbility ability) { + super(ability); + } + + @Override + public AddEachControlledColorManaAbility copy() { + return new AddEachControlledColorManaAbility(this); + } +} + +class AddEachControlledColorManaEffect extends ManaEffect { + + AddEachControlledColorManaEffect() { + super(); + staticText = "for each color among permanents you control, add one mana of that color"; + } + + private AddEachControlledColorManaEffect(final AddEachControlledColorManaEffect effect) { + super(effect); + } + + @Override + public AddEachControlledColorManaEffect copy() { + return new AddEachControlledColorManaEffect(this); + } + + @Override + public Mana produceMana(Game game, Ability source) { + if (game == null) { + return new Mana(); + } + return Mana.fromColor(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getAllControlledColors(game, source)); + } +} 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/AbilityWord.java b/Mage/src/main/java/mage/constants/AbilityWord.java index c8044d3c38c..42d20c8def1 100644 --- a/Mage/src/main/java/mage/constants/AbilityWord.java +++ b/Mage/src/main/java/mage/constants/AbilityWord.java @@ -63,6 +63,7 @@ public enum AbilityWord { THRESHOLD("Threshold"), UNDERGROWTH("Undergrowth"), VALIANT("Valiant"), + VIVID("Vivid"), VOID("Void"), WILL_OF_THE_COUNCIL("Will of the council"), WILL_OF_THE_PLANESWALKERS("Will of the planeswalkers"); diff --git a/Mage/src/main/java/mage/constants/BeholdType.java b/Mage/src/main/java/mage/constants/BeholdType.java new file mode 100644 index 00000000000..3e365aea31b --- /dev/null +++ b/Mage/src/main/java/mage/constants/BeholdType.java @@ -0,0 +1,99 @@ +package mage.constants; + +import mage.abilities.Ability; +import mage.cards.Card; +import mage.cards.CardsImpl; +import mage.filter.FilterCard; +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.TargetCard; +import mage.target.TargetPermanent; +import mage.target.common.TargetCardInHand; + +import java.util.Optional; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public enum BeholdType { + DRAGON(SubType.DRAGON), + GOBLIN(SubType.GOBLIN), + ELF(SubType.ELF), + KITHKIN(SubType.KITHKIN), + MERFOLK(SubType.MERFOLK); + + private final FilterPermanent filterPermanent; + private final FilterCard filterCard; + private final String description; + + BeholdType(SubType subType) { + this.filterPermanent = new FilterControlledPermanent(subType); + this.filterCard = new FilterCard(subType); + this.description = subType.getIndefiniteArticle() + ' ' + subType.getDescription(); + } + + public String getDescription() { + return description; + } + + public FilterCard getFilterCard() { + return filterCard; + } + + public FilterPermanent getFilterPermanent() { + return filterPermanent; + } + + public boolean canBehold(UUID controllerId, Game game, Ability source) { + return Optional + .ofNullable(game.getPlayer(controllerId)) + .map(Player::getHand) + .map(cards -> cards.count(this.getFilterCard(), game) > 0) + .orElse(false) + || game + .getBattlefield() + .contains(this.getFilterPermanent(), controllerId, source, game, 1); + } + + public Card doBehold(Player player, Game game, Ability source) { + boolean hasPermanent = game + .getBattlefield() + .contains(this.getFilterPermanent(), player.getId(), source, game, 1); + boolean hasHand = player.getHand().count(this.getFilterCard(), game) > 0; + boolean usePermanent; + if (hasPermanent && hasHand) { + usePermanent = player.chooseUse( + Outcome.Neutral, "Choose " + this.getDescription() + " you control or reveal one from your hand?", + null, "Choose controlled", "Reveal from hand", source, game); + } else if (hasPermanent) { + usePermanent = true; + } else if (hasHand) { + usePermanent = false; + } else { + return null; + } + if (usePermanent) { + TargetPermanent target = new TargetPermanent(this.getFilterPermanent()); + target.withNotTarget(true); + player.choose(Outcome.Neutral, target, source, game); + Permanent permanent = game.getPermanent(target.getFirstTarget()); + if (permanent == null) { + return null; + } + game.informPlayers(player.getLogName() + " chooses to behold " + permanent.getLogName()); + return permanent; + } + TargetCard target = new TargetCardInHand(this.getFilterCard()); + player.choose(Outcome.Neutral, player.getHand(), target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return null; + } + player.revealCards(source, new CardsImpl(card), game); + return card; + } +} diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index ac396d048b2..bd033ec3542 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -8,7 +8,6 @@ import java.util.*; import java.util.stream.Collectors; public enum SubType { - //205.3k Instants and sorceries share their lists of subtypes; these subtypes are called spell types. ADVENTURE("Adventure", SubTypeSet.SpellType), ARCANE("Arcane", SubTypeSet.SpellType), @@ -16,7 +15,7 @@ public enum SubType { OMEN("Omen", SubTypeSet.SpellType), TRAP("Trap", SubTypeSet.SpellType), - // Battle subtypes + // 205.3q Battles have a unique subtype, called a battle type. That battle type is Siege. SIEGE("Siege", SubTypeSet.BattleType), // 205.3i: Lands have their own unique set of subtypes; these subtypes are called land types. @@ -31,13 +30,14 @@ public enum SubType { GATE("Gate", SubTypeSet.NonBasicLandType), LAIR("Lair", SubTypeSet.NonBasicLandType), LOCUS("Locus", SubTypeSet.NonBasicLandType), - PLANET("Planet", SubTypeSet.NonBasicLandType), - SPHERE("Sphere", SubTypeSet.NonBasicLandType), - URZAS("Urza's", SubTypeSet.NonBasicLandType), MINE("Mine", SubTypeSet.NonBasicLandType), + PLANET("Planet", SubTypeSet.NonBasicLandType), POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType), + SPHERE("Sphere", SubTypeSet.NonBasicLandType), TOWER("Tower", SubTypeSet.NonBasicLandType), TOWN("Town", SubTypeSet.NonBasicLandType), + URZAS("Urza's", SubTypeSet.NonBasicLandType), + // 205.3h Enchantments have their own unique set of subtypes; these subtypes are called enchantment types. AURA("Aura", SubTypeSet.EnchantmentType), BACKGROUND("Background", SubTypeSet.EnchantmentType), @@ -45,13 +45,16 @@ 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), SAGA("Saga", SubTypeSet.EnchantmentType), SHARD("Shard", SubTypeSet.EnchantmentType), SHRINE("Shrine", SubTypeSet.EnchantmentType), + // 205.3g: Artifacts have their own unique set of subtypes; these subtypes are called artifact types. + ATTRACTION("Attraction", SubTypeSet.ArtifactType), BLOOD("Blood", SubTypeSet.ArtifactType), BOBBLEHEAD("Bobblehead", SubTypeSet.ArtifactType), CLUE("Clue", SubTypeSet.ArtifactType), @@ -61,14 +64,17 @@ public enum SubType { FORTIFICATION("Fortification", SubTypeSet.ArtifactType), GOLD("Gold", SubTypeSet.ArtifactType), INCUBATOR("Incubator", SubTypeSet.ArtifactType), + INFINITY("Infinity", SubTypeSet.ArtifactType), JUNK("Junk", SubTypeSet.ArtifactType), LANDER("Lander", SubTypeSet.ArtifactType), MAP("Map", SubTypeSet.ArtifactType), MUTAGEN("Mutagen", SubTypeSet.ArtifactType), POWERSTONE("Powerstone", SubTypeSet.ArtifactType), SPACECRAFT("Spacecraft", SubTypeSet.ArtifactType), + STONE("Stone", SubTypeSet.ArtifactType), TREASURE("Treasure", SubTypeSet.ArtifactType), VEHICLE("Vehicle", SubTypeSet.ArtifactType), + // 205.3m : Creatures and kindreds share their lists of subtypes; these subtypes are called creature types. // A ADVISOR("Advisor", SubTypeSet.CreatureType), @@ -128,6 +134,7 @@ public enum SubType { CAT("Cat", SubTypeSet.CreatureType), CENTAUR("Centaur", SubTypeSet.CreatureType), CEREAN("Cerean", SubTypeSet.CreatureType, true), // Star Wars + CHILD("Child", SubTypeSet.CreatureType), CHIMERA("Chimera", SubTypeSet.CreatureType), CHISS("Chiss", SubTypeSet.CreatureType, true), CITIZEN("Citizen", SubTypeSet.CreatureType), @@ -193,6 +200,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), @@ -235,7 +243,6 @@ public enum SubType { ILLUSION("Illusion", SubTypeSet.CreatureType), IMP("Imp", SubTypeSet.CreatureType), INCARNATION("Incarnation", SubTypeSet.CreatureType), - INFINITY("Infinity", SubTypeSet.ArtifactType), INKLING("Inkling", SubTypeSet.CreatureType), INQUISITOR("Inquisitor", SubTypeSet.CreatureType), INSECT("Insect", SubTypeSet.CreatureType), @@ -342,8 +349,8 @@ public enum SubType { PROCESSOR("Processor", SubTypeSet.CreatureType), PUREBLOOD("Pureblood", SubTypeSet.CreatureType, true), // Q - QUARREN("Quarren", SubTypeSet.CreatureType, true), // Star Wars QU("Qu", SubTypeSet.CreatureType), + QUARREN("Quarren", SubTypeSet.CreatureType, true), // Star Wars // R RABBIT("Rabbit", SubTypeSet.CreatureType), RACCOON("Raccoon", SubTypeSet.CreatureType), @@ -370,9 +377,9 @@ public enum SubType { SCORPION("Scorpion", SubTypeSet.CreatureType), SCOUT("Scout", SubTypeSet.CreatureType), SCULPTURE("Sculpture", SubTypeSet.CreatureType), + SEAL("Seal", SubTypeSet.CreatureType), SERF("Serf", SubTypeSet.CreatureType), SERPENT("Serpent", SubTypeSet.CreatureType), - SEAL("Seal", SubTypeSet.CreatureType), SERVO("Servo", SubTypeSet.CreatureType), SHADE("Shade", SubTypeSet.CreatureType), SHAMAN("Shaman", SubTypeSet.CreatureType), @@ -382,6 +389,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 +399,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), @@ -405,7 +414,6 @@ public enum SubType { SQUIRREL("Squirrel", SubTypeSet.CreatureType), STARFISH("Starfish", SubTypeSet.CreatureType), STARSHIP("Starship", SubTypeSet.CreatureType, true), // Star Wars - STONE("Stone", SubTypeSet.ArtifactType), SULLUSTAN("Sullustan", SubTypeSet.CreatureType, true), // Star Wars SURRAKAR("Surrakar", SubTypeSet.CreatureType), SURVIVOR("Survivor", SubTypeSet.CreatureType), @@ -464,7 +472,8 @@ public enum SubType { ZABRAK("Zabrak", SubTypeSet.CreatureType, true), // Star Wars ZOMBIE("Zombie", SubTypeSet.CreatureType), ZUBERA("Zubera", SubTypeSet.CreatureType), - // Planeswalker + + // 205.3j Planeswalkers have their own unique set of subtypes AJANI("Ajani", SubTypeSet.PlaneswalkerType), AMINATOU("Aminatou", SubTypeSet.PlaneswalkerType), ANGRATH("Angrath", SubTypeSet.PlaneswalkerType), diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 83ff2fb5d20..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.*; /** @@ -477,6 +478,17 @@ public final class StaticFilters { FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE.setLockedFilter(true); } + public static final FilterControlledPermanent FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE = new FilterControlledPermanent("untapped artifact or creature you control"); + + static { + FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE.add(TappedPredicate.UNTAPPED); + FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE.add(Predicates.or( + CardType.ARTIFACT.getPredicate(), + CardType.CREATURE.getPredicate() + )); + FILTER_CONTROLLED_UNTAPPED_ARTIFACT_OR_CREATURE.setLockedFilter(true); + } + public static final FilterControlledPermanent FILTER_CONTROLLED_ARTIFACT_OR_OTHER_CREATURE = new FilterControlledPermanent("another creature or an artifact"); static { @@ -978,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/BlackAndRedGoblinToken.java b/Mage/src/main/java/mage/game/permanent/token/BlackAndRedGoblinToken.java new file mode 100644 index 00000000000..33d2a9e6bd2 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/BlackAndRedGoblinToken.java @@ -0,0 +1,29 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author muz + */ +public final class BlackAndRedGoblinToken extends TokenImpl { + + public BlackAndRedGoblinToken() { + super("Goblin Token", "1/1 black and red Goblin creature token"); + cardType.add(CardType.CREATURE); + subtype.add(SubType.GOBLIN); + color.setBlack(true); + color.setRed(true); + power = new MageInt(1); + toughness = new MageInt(1); + } + + private BlackAndRedGoblinToken(final BlackAndRedGoblinToken token) { + super(token); + } + + public BlackAndRedGoblinToken copy() { + return new BlackAndRedGoblinToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/BlackGreenElfToken.java b/Mage/src/main/java/mage/game/permanent/token/BlackGreenElfToken.java new file mode 100644 index 00000000000..c128a2da77d --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/BlackGreenElfToken.java @@ -0,0 +1,29 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author muz + */ +public final class BlackGreenElfToken extends TokenImpl { + + public BlackGreenElfToken() { + super("Elf Token", "2/2 black and green Elf creature token"); + this.cardType.add(CardType.CREATURE); + this.color.setGreen(true); + this.subtype.add(SubType.ELF); + + this.power = new MageInt(2); + this.toughness = new MageInt(2); + } + + private BlackGreenElfToken(final BlackGreenElfToken token) { + super(token); + } + + public BlackGreenElfToken copy() { + return new BlackGreenElfToken(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/KithkinGreenWhiteToken.java b/Mage/src/main/java/mage/game/permanent/token/KithkinGreenWhiteToken.java new file mode 100644 index 00000000000..ecb8e2e8856 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/KithkinGreenWhiteToken.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 KithkinGreenWhiteToken extends TokenImpl { + + public KithkinGreenWhiteToken() { + super("Kithkin Token", "1/1 green and white Kithkin creature token"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + color.setWhite(true); + subtype.add(SubType.KITHKIN); + power = new MageInt(1); + toughness = new MageInt(1); + } + + private KithkinGreenWhiteToken(final KithkinGreenWhiteToken token) { + super(token); + } + + public KithkinGreenWhiteToken copy() { + return new KithkinGreenWhiteToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.java b/Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.java new file mode 100644 index 00000000000..c782d3c653f --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/MerfolkWhiteBlueToken.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 MerfolkWhiteBlueToken extends TokenImpl { + + public MerfolkWhiteBlueToken() { + super("Merfolk Token", "1/1 white and blue Merfolk creature token"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + color.setBlue(true); + subtype.add(SubType.MERFOLK); + power = new MageInt(1); + toughness = new MageInt(1); + } + + private MerfolkWhiteBlueToken(final MerfolkWhiteBlueToken token) { + super(token); + } + + public MerfolkWhiteBlueToken copy() { + return new MerfolkWhiteBlueToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/CribSwapShapeshifterWhiteToken.java b/Mage/src/main/java/mage/game/permanent/token/ShapeshifterColorlessToken.java similarity index 63% rename from Mage/src/main/java/mage/game/permanent/token/CribSwapShapeshifterWhiteToken.java rename to Mage/src/main/java/mage/game/permanent/token/ShapeshifterColorlessToken.java index 8b8261d386b..8295f713350 100644 --- a/Mage/src/main/java/mage/game/permanent/token/CribSwapShapeshifterWhiteToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/ShapeshifterColorlessToken.java @@ -8,9 +8,9 @@ import mage.constants.SubType; /** * @author spjspj */ -public final class CribSwapShapeshifterWhiteToken extends TokenImpl { +public final class ShapeshifterColorlessToken extends TokenImpl { - public CribSwapShapeshifterWhiteToken() { + public ShapeshifterColorlessToken() { super("Shapeshifter Token", "1/1 colorless Shapeshifter creature token with changeling"); cardType.add(CardType.CREATURE); subtype.add(SubType.SHAPESHIFTER); @@ -19,11 +19,11 @@ public final class CribSwapShapeshifterWhiteToken extends TokenImpl { addAbility(new ChangelingAbility()); } - private CribSwapShapeshifterWhiteToken(final CribSwapShapeshifterWhiteToken token) { + private ShapeshifterColorlessToken(final ShapeshifterColorlessToken token) { super(token); } - public CribSwapShapeshifterWhiteToken copy() { - return new CribSwapShapeshifterWhiteToken(this); + public ShapeshifterColorlessToken copy() { + return new ShapeshifterColorlessToken(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/TreefolkReachToken.java b/Mage/src/main/java/mage/game/permanent/token/TreefolkReachToken.java new file mode 100644 index 00000000000..3cb64f2faef --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/TreefolkReachToken.java @@ -0,0 +1,31 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.ReachAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class TreefolkReachToken extends TokenImpl { + + public TreefolkReachToken() { + super("Treefolk Token", "3/4 green Treefolk creature token with reach"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + subtype.add(SubType.TREEFOLK); + power = new MageInt(3); + toughness = new MageInt(4); + + addAbility(ReachAbility.getInstance()); + } + + private TreefolkReachToken(final TreefolkReachToken token) { + super(token); + } + + public TreefolkReachToken copy() { + return new TreefolkReachToken(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/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index e2c6348cbaa..fdc6ae38fa6 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -3711,62 +3711,63 @@ public abstract class PlayerImpl implements Player, Serializable { * @return */ protected boolean canPlay(ActivatedAbility ability, ManaOptions availableMana, MageObject sourceObject, Game game) { - if (!ability.isManaActivatedAbility()) { - ActivatedAbility copy = ability.copy(); // Copy is needed because cost reduction effects modify e.g. the mana to activate/cast the ability - if (!copy.canActivate(playerId, game).canActivate()) { - return false; + if (ability.isManaActivatedAbility()) { + return false; + } + ActivatedAbility copy = ability.copy(); // Copy is needed because cost reduction effects modify e.g. the mana to activate/cast the ability + if (!copy.canActivate(playerId, game).canActivate()) { + return false; + } + + // apply dynamic costs and cost modification + copy.adjustX(game); + if (availableMana != null) { + // TODO: need research, why it look at availableMana here - can delete condition? + game.getContinuousEffects().costModification(copy, game); + } + boolean canBeCastRegularly = true; + Set allowedIdentifiers = null; + if (copy instanceof SpellAbility) { + if (copy.getManaCosts().isEmpty() && copy.getCosts().isEmpty()) { + // 117.6. Some mana costs contain no mana symbols. This represents an unpayable cost... + // 117.6a (...) If an alternative cost is applied to an unpayable cost, + // including an effect that allows a player to cast a spell without paying its mana cost, the alternative cost may be paid. + canBeCastRegularly = false; + } + allowedIdentifiers = ((SpellAbility) copy).spellCanBeActivatedNow(playerId, game); + if (!allowedIdentifiers.contains(MageIdentifier.Default)) { + // If the timing restriction is lifted only for specific MageIdentifier, the default cast can not be used. + canBeCastRegularly = false; + } + } + if (canBeCastRegularly && canPayMinimumManaCost(copy, availableMana, game)) { + return true; + } + + // ALTERNATIVE COST FROM dynamic effects + for (MageIdentifier identifier : getCastSourceIdWithAlternateMana().getOrDefault(copy.getSourceId(), new HashSet<>())) { + if (allowedIdentifiers != null && !(allowedIdentifiers.contains(MageIdentifier.Default) || allowedIdentifiers.contains(identifier))) { + continue; + } + ManaCosts alternateCosts = getCastSourceIdManaCosts().get(copy.getSourceId()).get(identifier); + Costs costs = getCastSourceIdCosts().get(copy.getSourceId()).get(identifier); + + boolean canPutToPlay = true; + if (alternateCosts != null && !alternateCosts.canPay(copy, copy, playerId, game)) { + canPutToPlay = false; + } + if (costs != null && !costs.canPay(copy, copy, playerId, game)) { + canPutToPlay = false; } - // apply dynamic costs and cost modification - copy.adjustX(game); - if (availableMana != null) { - // TODO: need research, why it look at availableMana here - can delete condition? - game.getContinuousEffects().costModification(copy, game); - } - boolean canBeCastRegularly = true; - Set allowedIdentifiers = null; - if (copy instanceof SpellAbility) { - if (copy.getManaCosts().isEmpty() && copy.getCosts().isEmpty()) { - // 117.6. Some mana costs contain no mana symbols. This represents an unpayable cost... - // 117.6a (...) If an alternative cost is applied to an unpayable cost, - // including an effect that allows a player to cast a spell without paying its mana cost, the alternative cost may be paid. - canBeCastRegularly = false; - } - allowedIdentifiers = ((SpellAbility) copy).spellCanBeActivatedNow(playerId, game); - if (!allowedIdentifiers.contains(MageIdentifier.Default)) { - // If the timing restriction is lifted only for specific MageIdentifier, the default cast can not be used. - canBeCastRegularly = false; - } - } - if (canBeCastRegularly && canPayMinimumManaCost(copy, availableMana, game)) { + if (canPutToPlay) { return true; } + } - // ALTERNATIVE COST FROM dynamic effects - for (MageIdentifier identifier : getCastSourceIdWithAlternateMana().getOrDefault(copy.getSourceId(), new HashSet<>())) { - if (allowedIdentifiers != null && !(allowedIdentifiers.contains(MageIdentifier.Default) || allowedIdentifiers.contains(identifier))) { - continue; - } - ManaCosts alternateCosts = getCastSourceIdManaCosts().get(copy.getSourceId()).get(identifier); - Costs costs = getCastSourceIdCosts().get(copy.getSourceId()).get(identifier); - - boolean canPutToPlay = true; - if (alternateCosts != null && !alternateCosts.canPay(copy, copy, playerId, game)) { - canPutToPlay = false; - } - if (costs != null && !costs.canPay(copy, copy, playerId, game)) { - canPutToPlay = false; - } - - if (canPutToPlay) { - return true; - } - } - - // ALTERNATIVE COST from source card (any AlternativeSourceCosts) - if (AbilityType.SPELL.equals(ability.getAbilityType())) { - return canPlayCardByAlternateCost(game.getCard(ability.getSourceId()), availableMana, copy, game); - } + // ALTERNATIVE COST from source card (any AlternativeSourceCosts) + if (AbilityType.SPELL.equals(ability.getAbilityType())) { + return canPlayCardByAlternateCost(game.getCard(ability.getSourceId()), availableMana, copy, game); } return false; } @@ -4110,7 +4111,7 @@ public abstract class PlayerImpl implements Player, Serializable { TransformingDoubleFacedCard mainCard = (TransformingDoubleFacedCard) object; getPlayableFromObjectSingle(game, fromZone, mainCard.getLeftHalfCard(), mainCard.getLeftHalfCard().getAbilities(game), availableMana, output); getPlayableFromObjectSingle(game, fromZone, mainCard, mainCard.getSharedAbilities(game), availableMana, output); - } else if (object instanceof CardWithSpellOption) { + } else if (object instanceof CardWithSpellOption) { // adventure must use different card characteristics for different spells (main or adventure) CardWithSpellOption cardWithSpellOption = (CardWithSpellOption) object; getPlayableFromObjectSingle(game, fromZone, cardWithSpellOption.getSpellCard(), cardWithSpellOption.getSpellCard().getAbilities(game), availableMana, output); @@ -4254,8 +4255,7 @@ public abstract class PlayerImpl implements Player, Serializable { Game game = originalGame.createSimulationForPlayableCalc(); ManaOptions availableMana = getManaAvailable(game); // get available mana options (mana pool and conditional mana added (but conditional still lose condition)) - boolean fromAll = fromZone.equals(Zone.ALL); - if (hidden && (fromAll || fromZone == Zone.HAND)) { + if (hidden && fromZone.match(Zone.HAND)) { for (Card card : hand.getCards(game)) { for (Ability ability : card.getAbilities(game)) { // gets this activated ability from hand? (Morph?) if (ability.getZone().match(Zone.HAND)) { @@ -4300,7 +4300,7 @@ public abstract class PlayerImpl implements Player, Serializable { } } - if (fromAll || fromZone == Zone.GRAVEYARD) { + if (fromZone.match(Zone.GRAVEYARD)) { for (UUID playerId : game.getState().getPlayersInRange(getId(), game)) { Player player = game.getPlayer(playerId); if (player == null) { @@ -4312,7 +4312,7 @@ public abstract class PlayerImpl implements Player, Serializable { } } - if (fromAll || fromZone == Zone.EXILED) { + if (fromZone.match(Zone.EXILED)) { for (ExileZone exile : game.getExile().getExileZones()) { for (Card card : exile.getCards(game)) { getPlayableFromObjectAll(game, Zone.EXILED, card, availableMana, playable); @@ -4321,7 +4321,7 @@ public abstract class PlayerImpl implements Player, Serializable { } // check to play revealed cards - if (fromAll) { + if (fromZone.match(Zone.ALL)) { for (Cards revealedCards : game.getState().getRevealed().values()) { for (Card card : revealedCards.getCards(game)) { // revealed cards can be from any zones @@ -4331,7 +4331,7 @@ public abstract class PlayerImpl implements Player, Serializable { } // outside cards - if (fromAll || fromZone == Zone.OUTSIDE) { + if (fromZone.match(Zone.OUTSIDE)) { // companion cards for (Cards companionCards : game.getState().getCompanion().values()) { for (Card card : companionCards.getCards(game)) { @@ -4349,7 +4349,7 @@ public abstract class PlayerImpl implements Player, Serializable { } // check if it's possible to play the top card of a library - if (fromAll || fromZone == Zone.LIBRARY) { + if (fromZone.match(Zone.LIBRARY)) { for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) { Player player = game.getPlayer(playerInRangeId); if (player != null && player.getLibrary().hasCards()) { @@ -4365,7 +4365,7 @@ public abstract class PlayerImpl implements Player, Serializable { // TODO: remove direct hand check (reveal fix in Sen Triplets)? // human games: cards from opponent's hand must be revealed before play // AI games: computer can see and play cards from opponent's hand without reveal - if (fromAll || fromZone == Zone.HAND) { + if (fromZone.match(Zone.HAND)) { for (UUID playerInRangeId : game.getState().getPlayersInRange(getId(), game)) { Player player = game.getPlayer(playerInRangeId); if (player != null && !player.getHand().isEmpty()) { @@ -4383,7 +4383,7 @@ public abstract class PlayerImpl implements Player, Serializable { List activatedAll = new ArrayList<>(); // activated abilities from battlefield objects - if (fromAll || fromZone == Zone.BATTLEFIELD) { + if (fromZone.match(Zone.BATTLEFIELD)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { boolean canUseActivated = permanent.canUseActivatedAbilities(game); List currentPlayable = new ArrayList<>(); @@ -4398,7 +4398,7 @@ public abstract class PlayerImpl implements Player, Serializable { } // activated abilities from stack objects - if (fromAll || fromZone == Zone.STACK) { + if (fromZone.match(Zone.STACK)) { for (StackObject stackObject : game.getState().getStack()) { List currentPlayable = new ArrayList<>(); getPlayableFromObjectAll(game, Zone.STACK, stackObject, availableMana, currentPlayable); @@ -4410,7 +4410,7 @@ public abstract class PlayerImpl implements Player, Serializable { } // activated abilities from objects in the command zone (emblems or commanders) - if (fromAll || fromZone == Zone.COMMAND) { + if (fromZone.match(Zone.COMMAND)) { for (CommandObject commandObject : game.getState().getCommand()) { List currentPlayable = new ArrayList<>(); getPlayableFromObjectAll(game, Zone.COMMAND, commandObject, availableMana, currentPlayable); diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 2dcb5501ee3..49b4e4e0a73 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -1453,6 +1453,9 @@ public final class CardUtil { public static List getCastableComponents(Card cardToCast, FilterCard filter, Ability source, Player player, Game game, SpellCastTracker spellCastTracker, boolean playLand) { UUID playerId = player.getId(); List cards = new ArrayList<>(); + if (cardToCast == null) { + return cards; + } if (cardToCast instanceof CardWithHalves) { cards.add(((CardWithHalves) cardToCast).getLeftHalfCard()); cards.add(((CardWithHalves) cardToCast).getRightHalfCard()); 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..b0136c42d7c 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, Collections.emptyList()); } public int getThisTurnSacrificedPermanents() { - return sacrificedPermanents.values().stream().mapToInt(permanents -> permanents.size()).sum(); + return sacrificedPermanents.values().stream().mapToInt(List::size).sum(); } } diff --git a/Mage/src/main/resources/tokens-database.txt b/Mage/src/main/resources/tokens-database.txt index dd6c10c31d5..7e352684134 100644 --- a/Mage/src/main/resources/tokens-database.txt +++ b/Mage/src/main/resources/tokens-database.txt @@ -319,7 +319,7 @@ |Generate|TOK:C15|Lightning Rager|||LightningRagerToken| |Generate|TOK:C15|Phyrexian Germ|||PhyrexianGermToken| |Generate|TOK:C15|Saproling|||SaprolingToken| -|Generate|TOK:C15|Shapeshifter|||CribSwapShapeshifterWhiteToken| +|Generate|TOK:C15|Shapeshifter|||ShapeshifterColorlessToken| |Generate|TOK:C15|Snake|1||SnakeToken| |Generate|TOK:C15|Snake|2||PatagiaViperSnakeToken| |Generate|TOK:C15|Spider|||SpiderToken| @@ -381,7 +381,7 @@ |Generate|TOK:C18|Phyrexian Myr|||BrudicladTelchorMyrToken| |Generate|TOK:C18|Plant|||PlantToken| |Generate|TOK:C18|Servo|||ServoToken| -|Generate|TOK:C18|Shapeshifter|||CribSwapShapeshifterWhiteToken| +|Generate|TOK:C18|Shapeshifter|||ShapeshifterColorlessToken| |Generate|TOK:C18|Soldier|||SoldierToken| |Generate|TOK:C18|Survivor|||SurvivorToken| |Generate|TOK:C18|Thopter|1||ThopterColorlessToken| @@ -698,7 +698,7 @@ |Generate|TOK:LRW|Goblin Rogue|||GoblinRogueToken| |Generate|TOK:LRW|Kithkin Soldier|||KithkinSoldierToken| |Generate|TOK:LRW|Merfolk Wizard|||MerfolkWizardToken| -|Generate|TOK:LRW|Shapeshifter|||CribSwapShapeshifterWhiteToken| +|Generate|TOK:LRW|Shapeshifter|||ShapeshifterColorlessToken| |Generate|TOK:LRW|Wolf|||WolfToken| # M10 @@ -1589,7 +1589,7 @@ |Generate|TOK:2XM|Plant|||PlantToken| |Generate|TOK:2XM|Saproling|||SaprolingToken| |Generate|TOK:2XM|Servo|||ServoToken| -|Generate|TOK:2XM|Shapeshifter|||CribSwapShapeshifterWhiteToken| +|Generate|TOK:2XM|Shapeshifter|||ShapeshifterColorlessToken| |Generate|TOK:2XM|Soldier|||SoldierToken| |Generate|TOK:2XM|Squirrel|||SquirrelToken| |Generate|TOK:2XM|Thopter|1||ThopterColorlessToken| @@ -1688,7 +1688,7 @@ |Generate|TOK:CM2|Phyrexian Wurm|1||WurmWithDeathtouchToken| |Generate|TOK:CM2|Phyrexian Wurm|2||WurmWithLifelinkToken| |Generate|TOK:CM2|Saproling|||SaprolingToken| -|Generate|TOK:CM2|Shapeshifter|||CribSwapShapeshifterWhiteToken| +|Generate|TOK:CM2|Shapeshifter|||ShapeshifterColorlessToken| |Generate|TOK:CM2|Spirit|||SpiritWhiteToken| |Generate|TOK:CM2|Triskelavite|||TriskelaviteToken| |Generate|TOK:CM2|Tuktuk the Returned|||TuktukTheReturnedToken| @@ -1828,7 +1828,7 @@ |Generate|TOK:CLB|Rabbit|||RabbitToken| |Generate|TOK:CLB|Saproling|||SaprolingToken| |Generate|TOK:CLB|Satyr|||XenagosSatyrToken| -|Generate|TOK:CLB|Shapeshifter|1||CribSwapShapeshifterWhiteToken| +|Generate|TOK:CLB|Shapeshifter|1||ShapeshifterColorlessToken| |Generate|TOK:CLB|Shapeshifter|2||ShapeshifterToken| |Generate|TOK:CLB|Shapeshifter|3||Shapeshifter32Token| |Generate|TOK:CLB|Shapeshifter|4||ShapeshifterBlueToken| @@ -2557,7 +2557,7 @@ |Generate|TOK:M3C|Phyrexian Myr|||BrudicladTelchorMyrToken| |Generate|TOK:M3C|Sand Warrior|||SandWarriorToken| |Generate|TOK:M3C|Saproling|||SaprolingToken| -|Generate|TOK:M3C|Shapeshifter|1||CribSwapShapeshifterWhiteToken| +|Generate|TOK:M3C|Shapeshifter|1||ShapeshifterColorlessToken| |Generate|TOK:M3C|Shapeshifter|2||ShapeshifterBlueToken| |Generate|TOK:M3C|Spirit|||UginTheIneffableToken| |Generate|TOK:M3C|Tarmogoyf|||TarmogoyfToken| @@ -2910,6 +2910,9 @@ |Generate|TOK:TLE|Marit Lage|||MaritLageToken| |Generate|TOK:TLE|Soldier|||SoldierRedToken| +# ECL +|Generate|TOK:ECL|Goblin|||BlackAndRedGoblinToken| + #TMT |Generate|TOK:TMT|Mutagen|||MutagenToken| 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..09b960ae3fc 100644 --- a/Utils/known-sets.txt +++ b/Utils/known-sets.txt @@ -166,6 +166,7 @@ The Lord of the Rings: Tales of Middle-earth|TheLordOfTheRingsTalesOfMiddleEarth Tales of Middle-earth Commander|TalesOfMiddleEarthCommander| Lorwyn|Lorwyn| Lorwyn Eclipsed|LorwynEclipsed| +Lorwyn Eclipsed Commander|LorwynEclipsedCommander| The Lost Caverns of Ixalan|TheLostCavernsOfIxalan| The Lost Caverns of Ixalan Commander|LostCavernsOfIxalanCommander| Magic 2010|Magic2010| @@ -191,6 +192,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..8a6e39e344c 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.| @@ -60791,45 +60818,328 @@ Worldly Tutor|Avatar: The Last Airbender Eternal|314|R|{G}|Instant|||Search your Arcane Signet|Avatar: The Last Airbender Eternal|315|R|{2}|Artifact|||{T}: Add one mana of any color in your commander's color identity.| Sol Ring|Avatar: The Last Airbender Eternal|316|R|{1}|Artifact|||{T}: Add {C}{C}.| Swiftfoot Boots|Avatar: The Last Airbender Eternal|317|R|{2}|Artifact - Equipment|||Equipped creature has hexproof and haste.$Equip {1}| +Rooftop Percher|Lorwyn Eclipsed|2|C|{5}|Creature - Shapeshifter|3|3|Changeling$Flying$When this creature enters, exile up to two target cards from graveyards. You gain 3 life.| +Appeal to Eirdu|Lorwyn Eclipsed|5|C|{3}{W}|Instant|||Convoke$One or two target creatures each get +2/+1 until end of turn.| +Bark of Doran|Lorwyn Eclipsed|6|U|{1}{W}|Artifact - Equipment|||Equipped creature gets +0/+1.$As long as equipped creature's toughness is greater than its power, it assigns combat damage equal to its toughness rather than its power.$Equip {1}| +Brigid, Clachan's Heart|Lorwyn Eclipsed|7|R|{2}{W}|Legendary Creature - Kithkin Warrior|3|2|Whenever this creature enters or transforms into Brigid, Clachan's Heart, create a 1/1 green and white Kithkin creature token.$At the beginning of your first main phase, you may pay {G}. If you do, transform Brigid.| +Brigid, Doun's Mind|Lorwyn Eclipsed|7|R||Legendary Creature - Kithkin Soldier|3|2|{T}: Add X {G} or X {W}, where X is the number of other creatures you control.$At the beginning of your first main phase, you may pay {W}. If you do, transform Brigid.| +Burdened Stoneback|Lorwyn Eclipsed|8|U|{1}{W}|Creature - Giant Warrior|4|4|This creature enters with two -1/-1 counters on it.${1}{W}, Remove a counter from this creature: Target creature gains indestructible until end of turn. Activate only as a sorcery.| +Champion of the Clachan|Lorwyn Eclipsed|9|R|{3}{W}|Creature - Kithkin Knight|4|5|Flash$As an additional cost to cast this spell, behold a Kithkin and exile it.$Other Kithkin you control get +1/+1.$When this creature leaves the battlefield, return the exiled card to its owner's hand.| +Clachan Festival|Lorwyn Eclipsed|10|U|{2}{W}|Kindred Enchantment - Kithkin|||When this enchantment enters, create two 1/1 green and white Kithkin creature tokens.${4}{W}: Create a 1/1 green and white Kithkin creature token.| +Crib Swap|Lorwyn Eclipsed|11|U|{2}{W}|Kindred Instant - Shapeshifter|||Changeling$Exile target creature. Its controller creates a 1/1 colorless Shapeshifter creature token with changeling.| +Curious Colossus|Lorwyn Eclipsed|12|M|{5}{W}{W}|Creature - Giant Warrior|7|7|When this creature enters, each creature target opponent controls loses all abilities, becomes a Coward in addition to its other types, and has base power and toughness 1/1.| Eirdu, Carrier of Dawn|Lorwyn Eclipsed|13|M|{3}{W}{W}|Legendary Creature - Elemental God|5|5|Flying, lifelink$Creature spells you cast have convoke.$At the beginning of your first main phase, you may pay {B}. If you do, transform Eirdu.| Isilu, Carrier of Twilight|Lorwyn Eclipsed|13|M||Legendary Creature - Elemental God|5|5|Flying, lifelink$Each other nontoken creature you control has persist.$At the beginning of your first main phase, you may pay {W}. If you do, transform Isilu.| +Flock Impostor|Lorwyn Eclipsed|16|U|{2}{W}|Creature - Shapeshifter|2|2|Changeling$Flash$Flying$When this creature enters, return up to one other target creature you control to its owner's hand.| +Gallant Fowlknight|Lorwyn Eclipsed|17|C|{3}{W}|Creature - Kithkin Knight|3|4|When this creature enters, creatures you control get +1/+0 until end of turn. Kithkin creatures you control also gain first strike until end of turn.| +Goldmeadow Nomad|Lorwyn Eclipsed|18|C|{W}|Creature - Kithkin Scout|1|2|{W}, Exile this card from your graveyard: Create a 1/1 green and white Kithkin creature token. Activate only as a sorcery.| +Kinbinding|Lorwyn Eclipsed|20|R|{3}{W}{W}|Enchantment|||Creatures you control get +X/+X, where X is the number of creatures that entered the battlefield under your control this turn.$At the beginning of combat on your turn, create a 1/1 green and white Kithkin creature token.| +Kinsbaile Aspirant|Lorwyn Eclipsed|21|U|{W}|Creature - Kithkin Citizen|2|1|As an additional cost to cast this spell, behold a Kithkin or pay {2}.$Whenever another creature you control enters, this creature gets +1/+1 until end of turn.| +Kithkeeper|Lorwyn Eclipsed|23|U|{6}{W}|Creature - Elemental|3|3|Vivid -- When this creature enters, create X 1/1 green and white Kithkin creature tokens, where X is the number of colors among permanents you control.$Tap three untapped creatures you control: This creature gets +3/+0 and gains flying until end of turn.| +Liminal Hold|Lorwyn Eclipsed|24|C|{3}{W}|Enchantment|||When this enchantment enters, exile up to one target nonland permanent an opponent controls until this enchantment leaves the battlefield. You gain 2 life.| +Meanders Guide|Lorwyn Eclipsed|25|U|{2}{W}|Creature - Merfolk Scout|3|2|Whenever this creature attacks, you may tap another untapped Merfolk you control. When you do, return target creature card with mana value 3 or less from your graveyard to the battlefield.| 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.| +Personify|Lorwyn Eclipsed|28|U|{1}{W}|Instant|||Exile target creature you control, then return that card to the battlefield under its owner's control. Create a 1/1 colorless Shapeshifter creature token with changeling.| +Pyrrhic Strike|Lorwyn Eclipsed|30|U|{2}{W}|Instant|||As an additional cost to cast this spell, you may blight 2.$Choose one. If this spell's additional cost was paid, choose both instead.$* Destroy target artifact or enchantment.$* Destroy target creature with mana value 3 or greater.| +Reluctant Dounguard|Lorwyn Eclipsed|31|C|{2}{W}|Creature - Kithkin Soldier|4|4|This creature enters with two -1/-1 counters on it.$Whenever another creature you control enters while this creature has a -1/-1 counter on it, remove a -1/-1 counter from this creature.| +Rhys, the Evermore|Lorwyn Eclipsed|32|R|{1}{W}|Legendary Creature - Elf Warrior|2|2|Flash$When Rhys enters, another target creature you control gains persist until end of turn.${W}, {T}: Remove any number of counters from target creature you control. Activate only as a sorcery.| +Shore Lurker|Lorwyn Eclipsed|34|C|{3}{W}|Creature - Merfolk Scout|3|3|Flying$When this creature enters, surveil 1.| +Slumbering Walker|Lorwyn Eclipsed|35|R|{3}{W}{W}|Creature - Giant Warrior|4|7|This creature enters with two -1/-1 counters on it.$At the beginning of your end step, you may remove a counter from this creature. When you do, return target creature card with power 2 or less from your graveyard to the battlefield.| +Spiral into Solitude|Lorwyn Eclipsed|36|C|{1}{W}|Enchantment - Aura|||Enchant creature$Enchanted creature can't attack or block.${1}{W}, Blight 1, Sacrifice this Aura: Exile enchanted creature.| +Sun-Dappled Celebrant|Lorwyn Eclipsed|37|C|{4}{W}{W}|Creature - Treefolk Cleric|5|6|Convoke$Vigilance| +Thoughtweft Imbuer|Lorwyn Eclipsed|38|U|{3}{W}|Creature - Kithkin Advisor|0|5|Whenever a creature you control attacks alone, it gets +X/+X until end of turn, where X is the number of Kithkin you control.| +Tributary Vaulter|Lorwyn Eclipsed|40|C|{2}{W}|Creature - Merfolk Warrior|1|3|Flying$Whenever this creature becomes tapped, another target Merfolk you control gets +2/+0 until end of turn.| +Wanderbrine Preacher|Lorwyn Eclipsed|41|C|{1}{W}|Creature - Merfolk Cleric|2|2|Whenever this creature becomes tapped, you gain 2 life.| +Winnowing|Lorwyn Eclipsed|43|R|{4}{W}{W}|Sorcery|||Convoke$For each player, you choose a creature that player controls. Then each player sacrifices all other creatures they control that don't share a creature type with the chosen creature they control.| +Aquitect's Defenses|Lorwyn Eclipsed|44|C|{1}{U}|Enchantment - Aura|||Flash$Enchant creature you control$When this Aura enters, enchanted creature gains hexproof until end of turn.$Enchanted creature gets +1/+2.| +Blossombind|Lorwyn Eclipsed|45|C|{1}{U}|Enchantment - Aura|||Enchant creature$When this Aura enters, tap enchanted creature.$Enchanted creature can't become untapped and can't have counters put on it.| +Disruptor of Currents|Lorwyn Eclipsed|47|R|{3}{U}{U}|Creature - Merfolk Wizard|3|3|Flash$Convoke$When this creature enters, return up to one other target nonland permanent to its owner's hand.| +Flitterwing Nuisance|Lorwyn Eclipsed|48|R|{U}|Creature - Faerie Rogue|2|2|Flying$This creature enters with a -1/-1 counter on it.${2}{U}, Remove a counter from this creature: Whenever a creature you control deals combat damage to a player or planeswalker this turn, draw a card.| +Glamer Gifter|Lorwyn Eclipsed|49|U|{1}{U}|Creature - Faerie Wizard|1|2|Flash$Flying$When this creature enters, choose up to one other target creature. Until end of turn, that creature has base power and toughness 4/4 and gains all creature types.| +Glen Elendra's Answer|Lorwyn Eclipsed|52|M|{2}{U}{U}|Instant|||This spell can't be countered.$Counter all spells your opponents control and all abilities your opponents control. Create a 1/1 blue and black Faerie creature token with flying for each spell and ability countered this way.| +Gravelgill Scoundrel|Lorwyn Eclipsed|53|C|{1}{U}|Creature - Merfolk Rogue|1|3|Vigilance$Whenever this creature attacks, you may tap another untapped creature you control. If you do, this creature can't be blocked this turn.| +Harmonized Crescendo|Lorwyn Eclipsed|54|R|{4}{U}{U}|Instant|||Convoke$Choose a creature type. Draw a card for each permanent you control of that type.| +Kulrath Mystic|Lorwyn Eclipsed|56|C|{2}{U}|Creature - Elemental Wizard|2|4|Whenever you cast a spell with mana value 4 or greater, this creature gets +2/+0 and gains vigilance until end of turn.| +Loch Mare|Lorwyn Eclipsed|57|M|{1}{U}|Creature - Horse Serpent|4|5|This creature enters with three -1/-1 counters on it.${1}{U}, Remove a counter from this creature: Draw a card.${2}{U}, Remove two counters from this creature: Tap target creature. Put a stun counter on it.| +Lofty Dreams|Lorwyn Eclipsed|58|U|{3}{U}{U}|Enchantment - Aura|||Convoke$Enchant creature$When this Aura enters, draw a card.$Enchanted creature gets +2/+2 and has flying.| +Mirrorform|Lorwyn Eclipsed|59|M|{4}{U}{U}|Instant|||Each nonland permanent you control becomes a copy of target non-Aura permanent.| +Oko, Lorwyn Liege|Lorwyn Eclipsed|61|M|{2}{U}|Legendary Planeswalker - Oko|3|At the beginning of your first main phase, you may pay {G}. If you do, transform Oko.$+2: Up to one target creature gains all creature types.$+1: Target creature gets -2/-0 until your next turn.| +Oko, Shadowmoor Scion|Lorwyn Eclipsed|61|M||Legendary Planeswalker - Oko|3|At the beginning of your first main phase, you may pay {U}. If you do, transform Oko.$-1: Mill three cards. You may put a permanent card from among them into your hand.$-3: Create two 3/3 green Elk creature tokens.$-6: Choose a creature type. You get an emblem with "Creatures you control of the chosen type get +3/+3 and have vigilance and hexproof."| +Omni-Changeling|Lorwyn Eclipsed|62|U|{3}{U}{U}|Creature - Shapeshifter|0|0|Changeling$Convoke$You may have this creature enter as a copy of any creature on the battlefield, except it has changeling.| +Pestered Wellguard|Lorwyn Eclipsed|63|U|{3}{U}|Creature - Merfolk Soldier|3|2|Whenever this creature becomes tapped, create a 1/1 blue and black Faerie creature token with flying.| +Run Away Together|Lorwyn Eclipsed|67|C|{1}{U}|Instant|||Choose two target creatures controlled by different players. Return those creatures to their owners' hands.| +Shinestriker|Lorwyn Eclipsed|68|U|{4}{U}{U}|Creature - Elemental|3|3|Flying$Vivid -- When this creature enters, draw cards equal to the number of colors among permanents you control.| +Silvergill Peddler|Lorwyn Eclipsed|70|C|{2}{U}|Creature - Merfolk Citizen|2|3|Whenever this creature becomes tapped, draw a card, then discard a card.| +Spell Snare|Lorwyn Eclipsed|71|U|{U}|Instant|||Counter target spell with mana value 2.| +Stratosoarer|Lorwyn Eclipsed|72|C|{4}{U}|Creature - Elemental|3|5|Flying$When this creature enters, target creature gains flying until end of turn.$Basic landcycling {1}{U}| +Sunderflock|Lorwyn Eclipsed|74|R|{7}{U}{U}|Creature - Elemental|5|5|This spell costs {X} less to cast, where X is the greatest mana value among Elementals you control.$Flying$When this creature enters, if you cast it, return all non-Elemental creatures to their owners' hands.| +Swat Away|Lorwyn Eclipsed|75|U|{2}{U}{U}|Instant|||This spell costs {2} less to cast if a creature is attacking you.$The owner of target spell or creature puts it on their choice of the top or bottom of their library.| 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.| +Tanufel Rimespeaker|Lorwyn Eclipsed|77|U|{3}{U}|Creature - Elemental Wizard|2|4|Whenever you cast a spell with mana value 4 or greater, draw a card.| +Temporal Cleansing|Lorwyn Eclipsed|78|C|{3}{U}|Sorcery|||Convoke$The owner of target nonland permanent puts it into their library second from the top or on the bottom.| +Unexpected Assistance|Lorwyn Eclipsed|80|C|{3}{U}{U}|Instant|||Convoke$Draw three cards, then discard a card.| +Unwelcome Sprite|Lorwyn Eclipsed|81|U|{1}{U}|Creature - Faerie Rogue|2|1|Flying$Whenever you cast a spell during an opponent's turn, surveil 2.| +Wanderwine Distracter|Lorwyn Eclipsed|82|C|{3}{U}|Creature - Merfolk Wizard|4|3|Whenever this creature becomes tapped, target creature an opponent controls gets -3/-0 until end of turn.| +Wanderwine Farewell|Lorwyn Eclipsed|83|U|{5}{U}{U}|Kindred Sorcery - Merfolk|||Convoke$Return one or two target nonland permanents to their owners' hands. Then if you control a Merfolk, create a 1/1 white and blue Merfolk creature token for each permanent returned to its owner's hand this way.| +Wild Unraveling|Lorwyn Eclipsed|84|C|{U}{U}|Instant|||As an additional cost to cast this spell, blight 2 or pay {1}.$Counter target spell.| +Auntie's Sentence|Lorwyn Eclipsed|85|C|{1}{B}|Sorcery|||Choose one --$* Target opponent reveals their hand. You choose a nonland permanent card from it. That player discards that card.$* Target creature gets -2/-2 until end of turn.| +Bile-Vial Boggart|Lorwyn Eclipsed|87|C|{B}|Creature - Goblin Assassin|1|1|When this creature dies, put a -1/-1 counter on up to one target creature.| 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.| +Blighted Blackthorn|Lorwyn Eclipsed|90|C|{4}{B}|Creature - Treefolk Warlock|3|7|Whenever this creature enters or attacks, you may blight 2. If you do, you draw a card and lose 1 life.| +Bloodline Bidding|Lorwyn Eclipsed|91|R|{6}{B}{B}|Sorcery|||Convoke$Choose a creature type. Return all creature cards of the chosen type from your graveyard to the battlefield.| +Boggart Mischief|Lorwyn Eclipsed|92|U|{2}{B}|Kindred Enchantment - Goblin|||When this enchantment enters, you may blight 1. If you do, create two 1/1 black and red Goblin creature tokens.$Whenever a Goblin creature you control dies, each opponent loses 1 life and you gain 1 life.| +Champion of the Weird|Lorwyn Eclipsed|95|R|{3}{B}|Creature - Goblin Berserker|5|5|As an additional cost to cast this spell, behold a Goblin and exile it.$Pay 1 life, Blight 2: Target opponent blights 2. Activate only as a sorcery.$When this creature leaves the battlefield, return the exiled card to its owner's hand.| +Darkness Descends|Lorwyn Eclipsed|97|U|{2}{B}{B}|Sorcery|||Put two -1/-1 counters on each creature.| +Dawnhand Dissident|Lorwyn Eclipsed|98|R|{B}|Creature - Elf Warlock|1|2|{T}, Blight 1: Surveil 1.${T}, Blight 2: Exile target card from a graveyard.$During your turn, you may cast creature spells from among cards you own exiled with this creature by removing three counters from among creatures you control in addition to paying their other costs.| +Dawnhand Eulogist|Lorwyn Eclipsed|99|C|{3}{B}|Creature - Elf Warlock|3|3|Menace$When this creature enters, mill three cards. Then if there is an Elf card in your graveyard, each opponent loses 2 life and you gain 2 life.| +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.| +Dream Seizer|Lorwyn Eclipsed|101|C|{3}{B}|Creature - Faerie Rogue|3|2|Flying$When this creature enters, you may blight 1. If you do, each opponent discards a card.| +Gnarlbark Elm|Lorwyn Eclipsed|103|U|{2}{B}|Creature - Treefolk Warlock|3|4|This creature enters with two -1/-1 counters on it.${2}{B}, Remove two counters from this creature: Target creature gets -2/-2 until end of turn. Activate only as a sorcery.| +Graveshifter|Lorwyn Eclipsed|104|U|{3}{B}|Creature - Shapeshifter|2|2|Changeling$When this creature enters, you may return target creature card from your graveyard to your hand.| +Grub, Storied Matriarch|Lorwyn Eclipsed|105|R|{2}{B}|Legendary Creature - Goblin Warlock|2|1|Menace$Whenever this creature enters or transforms into Grub, Storied Matriarch, return up to one target Goblin card from your graveyard to your hand.$At the beginning of your first main phase, you may pay {R}. If you do, transform Grub.| +Grub, Notorious Auntie|Lorwyn Eclipsed|105|R||Legendary Creature - Goblin Warrior|2|1|Menace$Whenever Grub attacks, you may blight 1. If you do, create a tapped and attacking token that's a copy of the blighted creature, except it has "At the beginning of the end step, sacrifice this token."$At the beginning of your first main phase, you may pay {B}. If you do, transform Grub.| +Gutsplitter Gang|Lorwyn Eclipsed|106|U|{3}{B}|Creature - Goblin Berserker|6|6|At the beginning of your first main phase, you may blight 2. If you don't, you lose 3 life.| +Heirloom Auntie|Lorwyn Eclipsed|107|C|{2}{B}|Creature - Goblin Warlock|4|4|This creature enters with two -1/-1 counters on it.$Whenever another creature you control dies, surveil 1, then remove a -1/-1 counter from this creature.| +Iron-Shield Elf|Lorwyn Eclipsed|108|U|{1}{B}|Creature - Elf Warrior|3|1|Discard a card: This creature gains indestructible until end of turn. Tap it.| +Moonglove Extractor|Lorwyn Eclipsed|109|C|{2}{B}|Creature - Elf Warlock|2|1|Whenever this creature attacks, you draw a card and lose 1 life.| +Mornsong Aria|Lorwyn Eclipsed|111|R|{1}{B}{B}|Legendary Enchantment|||Players can't draw cards or gain life.$At the beginning of each player's draw step, that player loses 3 life, searches their library for a card, puts it into their hand, then shuffles.| +Mudbutton Cursetosser|Lorwyn Eclipsed|112|U|{B}|Creature - Goblin Warlock|2|1|As an additional cost to cast this spell, behold a Goblin or pay {2}.$This creature can't block.$When this creature dies, destroy target creature an opponent controls with power 2 or less.| +Nameless Inversion|Lorwyn Eclipsed|113|U|{1}{B}|Kindred Instant - Shapeshifter|||Changeling$Target creature gets +3/-3 and loses all creature types until end of turn.| +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.| +Requiting Hex|Lorwyn Eclipsed|116|U|{B}|Instant|||As an additional cost to cast this spell, you may blight 1.$Destroy target creature with mana value 2 or less. If this spell's additional cost was paid, you gain 2 life.| +Retched Wretch|Lorwyn Eclipsed|117|U|{2}{B}|Creature - Goblin|4|2|When this creature dies, if it had a -1/-1 counter on it, return it to the battlefield under its owner's control and it loses all abilities.| +Scarblade Scout|Lorwyn Eclipsed|118|C|{1}{B}|Creature - Elf Scout|2|2|Lifelink$When this creature enters, mill two cards.| +Shimmercreep|Lorwyn Eclipsed|120|U|{4}{B}|Creature - Elemental|3|5|Menace$Vivid -- When this creature enters, each opponent loses X life and you gain X life, where X is the number of colors among permanents you control.| +Unbury|Lorwyn Eclipsed|123|U|{1}{B}|Instant|||Choose one --$* Return target creature card from your graveyard to your hand.$* Return two target creature cards that share a creature type from your graveyard to your hand.| 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.| +Boldwyr Aggressor|Lorwyn Eclipsed|125|U|{3}{R}{R}|Creature - Giant Warrior|2|5|Double strike$Other Giants you control have double strike.| +Boneclub Berserker|Lorwyn Eclipsed|126|C|{3}{R}|Creature - Goblin Berserker|2|4|This creature gets +2/+0 for each other Goblin you control.| +Burning Curiosity|Lorwyn Eclipsed|129|C|{2}{R}|Sorcery|||As an additional cost to cast this spell, you may blight 1.$Exile the top two cards of your library. If this spell's additional cost was paid, exile the top three cards instead. Until the end of your next turn, you may play those cards.| +Collective Inferno|Lorwyn Eclipsed|132|R|{3}{R}{R}|Enchantment|||Convoke$As this enchantment enters, choose a creature type.$Double all damage that sources you control of the chosen type would deal.| +Elder Auntie|Lorwyn Eclipsed|133|C|{2}{R}|Creature - Goblin Warlock|2|2|When this creature enters, create a 1/1 black and red Goblin creature token.| +Enraged Flamecaster|Lorwyn Eclipsed|135|C|{2}{R}|Creature - Elemental Sorcerer|3|2|Reach$Whenever you cast a spell with mana value 4 or greater, this creature deals 2 damage to each opponent.| +Explosive Prodigy|Lorwyn Eclipsed|136|U|{1}{R}|Creature - Elemental Sorcerer|1|1|Vivid -- When this creature enters, it deals X damage to target creature an opponent controls, where X is the number of colors among permanents you control.| +Flame-Chain Mauler|Lorwyn Eclipsed|138|C|{1}{R}|Creature - Elemental Warrior|2|2|{1}{R}: This creature gets +1/+0 and gains menace until end of turn.| +Flamebraider|Lorwyn Eclipsed|139|U|{1}{R}|Creature - Elemental Bard|2|2|{T}: Add two mana in any combination of colors. Spend this mana only to cast Elemental spells or activate abilities of Elemental sources.| +Flamekin Gildweaver|Lorwyn Eclipsed|140|C|{3}{R}|Creature - Elemental Sorcerer|4|3|Trample$When this creature enters, create a Treasure token.| +Goatnap|Lorwyn Eclipsed|142|U|{2}{R}|Sorcery|||Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn. If that creature is a Goat, it also gets +3/+0 until end of turn.| +Goliath Daydreamer|Lorwyn Eclipsed|143|R|{2}{R}{R}|Creature - Giant Wizard|4|4|Whenever you cast an instant or sorcery spell from your hand, exile that card with a dream counter on it instead of putting it into your graveyard as it resolves.$Whenever this creature attacks, you may cast a spell from among cards you own in exile with dream counters on them without paying its mana cost.| +Gristle Glutton|Lorwyn Eclipsed|144|C|{1}{R}|Creature - Goblin Scout|1|3|{T}, Blight 1: Discard a card. If you do, draw a card.| +Hexing Squelcher|Lorwyn Eclipsed|145|R|{1}{R}|Creature - Goblin Sorcerer|2|2|This spell can't be countered.$Ward--Pay 2 life.$Spells you control can't be countered.$Other creatures you control have "Ward--Pay 2 life."| +Impolite Entrance|Lorwyn Eclipsed|146|U|{R}|Sorcery|||Target creature gains trample and haste until end of turn.$Draw a card.| +Kindle the Inner Flame|Lorwyn Eclipsed|147|U|{3}{R}|Kindred Sorcery - Elemental|||Create a token that's a copy of target creature you control, except it has haste and "At the beginning of the end step, sacrifice this token."$Flashback--{1}{R}, Behold three Elementals.| +Kulrath Zealot|Lorwyn Eclipsed|148|C|{5}{R}|Creature - Elemental Warrior|6|5|When this creature enters, exile the top card of your library. Until the end of your next turn, you may play that card.$Basic landcycling {1}{R}| +Lasting Tarfire|Lorwyn Eclipsed|149|U|{1}{R}|Enchantment|||At the beginning of each end step, if you put a counter on a creature this turn, this enchantment deals 2 damage to each opponent.| +Lavaleaper|Lorwyn Eclipsed|150|R|{3}{R}|Creature - Elemental|4|4|All creatures have haste.$Whenever a player taps a basic land for mana, that player adds one mana of any type that land produced.| +Meek Attack|Lorwyn Eclipsed|151|M|{2}{R}|Enchantment|||{1}{R}: You may put a creature card with total power and toughness 5 or less from your hand onto the battlefield. That creature gains haste. At the beginning of the next end step, sacrifice that creature.| +Sear|Lorwyn Eclipsed|154|U|{1}{R}|Instant|||Sear deals 4 damage to target creature or planeswalker.| +Sizzling Changeling|Lorwyn Eclipsed|155|U|{2}{R}|Creature - Shapeshifter|3|2|Changeling$When this creature dies, exile the top card of your library. Until the end of your next turn, you may play that card.| +Sourbread Auntie|Lorwyn Eclipsed|158|U|{2}{R}{R}|Creature - Goblin Warrior|4|3|When this creature enters, you may blight 2. If you do, create two 1/1 black and red Goblin creature tokens.| +Spinerock Tyrant|Lorwyn Eclipsed|159|M|{3}{R}{R}|Creature - Dragon|6|6|Flying$Wither$Whenever you cast an instant or sorcery spell with a single target, you may copy it. If you do, those spells gain wither. You may choose new targets for the copy.| +Squawkroaster|Lorwyn Eclipsed|160|U|{3}{R}|Creature - Elemental|*|4|Double strike$Vivid -- Squawkroaster's power is equal to the number of colors among permanents you control.| +Tweeze|Lorwyn Eclipsed|162|C|{2}{R}|Instant|||Tweeze deals 3 damage to any target. You may discard a card. If you do, draw a card.| +Warren Torchmaster|Lorwyn Eclipsed|163|U|{1}{R}|Creature - Goblin Warrior|2|2|At the beginning of combat on your turn, you may blight 1. When you do, target creature gains haste until end of turn.| +Assert Perfection|Lorwyn Eclipsed|164|C|{1}{G}|Sorcery|||Target creature you control gets +1/+0 until end of turn. It deals damage equal to its power to up to one target creature an opponent controls.| +Aurora Awakener|Lorwyn Eclipsed|165|M|{6}{G}|Creature - Giant Druid|7|7|Trample$Vivid -- When this creature enters, reveal cards from the top of your library until you reveal X permanent cards, where X is the number of colors among permanents you control. Put any number of those permanent cards onto the battlefield, then put the rest of the revealed cards on the bottom of your library in a random order.| +Bloom Tender|Lorwyn Eclipsed|166|M|{1}{G}|Creature - Elf Druid|1|1|Vivid -- {T}: For each color among permanents you control, add one mana of that color.| +Blossoming Defense|Lorwyn Eclipsed|167|U|{G}|Instant|||Target creature you control gets +2/+2 and gains hexproof until end of turn.| +Bristlebane Battler|Lorwyn Eclipsed|168|R|{1}{G}|Creature - Kithkin Soldier|6|6|Trample, ward {2}$This creature enters with five -1/-1 counters on it.$Whenever another creature you control enters while this creature has a -1/-1 counter on it, remove a -1/-1 counter from this creature.| +Bristlebane Outrider|Lorwyn Eclipsed|169|U|{3}{G}|Creature - Kithkin Knight|3|5|This creature can't be blocked by creatures with power 2 or less.$As long as another creature entered the battlefield under your control this turn, this creature gets +2/+0.| +Celestial Reunion|Lorwyn Eclipsed|170|M|{X}{G}|Sorcery|||As an additional cost to cast this spell, you may choose a creature type and behold two creatures of that type.$Search your library for a creature card with mana value X or less, reveal it, put it into your hand, then shuffle. If this spell's additional cost was paid and the revealed card is the chosen type, put that card onto the battlefield instead of putting it into your hand.| +Champions of the Perfect|Lorwyn Eclipsed|171|R|{3}{G}|Creature - Elf Warrior|6|6|As an additional cost to cast this spell, behold an Elf and exile it.$Whenever you cast a creature spell, draw a card.$When this creature leaves the battlefield, return the exiled card to its owner's hand.| +Chomping Changeling|Lorwyn Eclipsed|172|U|{2}{G}|Creature - Shapeshifter|1|2|Changeling$When this creature enters, destroy up to one target artifact or enchantment.| +Crossroads Watcher|Lorwyn Eclipsed|173|C|{2}{G}|Creature - Kithkin Ranger|3|3|Trample$Whenever another creature you control enters, this creature gets +1/+0 until end of turn.| +Dawn's Light Archer|Lorwyn Eclipsed|174|C|{2}{G}|Creature - Elf Archer|4|2|Flash$Reach| +Dundoolin Weaver|Lorwyn Eclipsed|175|U|{1}{G}|Creature - Kithkin Druid|2|1|When this creature enters, if you control three or more creatures, return target permanent card from your graveyard to your hand.| 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.| +Great Forest Druid|Lorwyn Eclipsed|178|C|{1}{G}|Creature - Treefolk Druid|0|4|{T}: Add one mana of any color.| +Luminollusk|Lorwyn Eclipsed|179|U|{3}{G}|Creature - Elemental|2|4|Deathtouch$Vivid -- When this creature enters, you gain life equal to the number of colors among permanents you control.| +Lys Alana Informant|Lorwyn Eclipsed|181|C|{1}{G}|Creature - Elf Scout|3|1|When this creature enters or dies, surveil 1.| +Midnight Tilling|Lorwyn Eclipsed|182|C|{1}{G}|Instant|||Mill four cards, then you may return a permanent card from among them to your hand.| +Mistmeadow Council|Lorwyn Eclipsed|183|C|{4}{G}|Creature - Kithkin Advisor|4|3|This spell costs {1} less to cast if you control a Kithkin.$When this creature enters, draw a card.| +Morcant's Eyes|Lorwyn Eclipsed|185|U|{1}{G}|Kindred Enchantment - Elf|||At the beginning of your upkeep, surveil 1.${4}{G}{G}, Sacrifice this enchantment: Create X 2/2 black and green Elf creature tokens, where X is the number of Elf cards in your graveyard. Activate only as a sorcery.| Mutable Explorer|Lorwyn Eclipsed|186|R|{2}{G}|Creature - Shapeshifter|1|1|Changeling$When this creature enters, create a tapped Mutavault token.| +Pitiless Fists|Lorwyn Eclipsed|187|U|{3}{G}|Enchantment - Aura|||Enchant creature you control$When this Aura enters, enchanted creature fights up to one target creature an opponent controls.$Enchanted creature gets +2/+2.| +Prismabasher|Lorwyn Eclipsed|188|U|{4}{G}{G}|Creature - Elemental|6|6|Trample$Vivid -- When this creature enters, up to X target creatures you control get +X/+X until end of turn, where X is the number of colors among permanents you control.| +Sapling Nursery|Lorwyn Eclipsed|192|R|{6}{G}{G}|Enchantment|||Affinity for Forests$Landfall -- Whenever a land you control enters, create a 3/4 green Treefolk creature token with reach.${1}{G}, Exile this enchantment: Treefolk and Forests you control gain indestructible until end of turn.| +Selfless Safewright|Lorwyn Eclipsed|193|R|{3}{G}{G}|Creature - Elf Warrior|4|2|Flash$Convoke$When this creature enters, choose a creature type. Other permanents you control of that type gain hexproof and indestructible until end of turn.| +Shimmerwilds Growth|Lorwyn Eclipsed|194|U|{1}{G}|Enchantment - Aura|||Enchant land$As this Aura enters, choose a color.$Enchanted land is the chosen color.$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of the chosen color.| +Surly Farrier|Lorwyn Eclipsed|196|C|{1}{G}|Creature - Kithkin Citizen|2|2|{T}: Target creature you control gets +1/+1 and gains vigilance until end of turn. Activate only as a sorcery.| +Tend the Sprigs|Lorwyn Eclipsed|197|C|{2}{G}|Sorcery|||Search your library for a basic land card, put it onto the battlefield tapped, then shuffle. Then if you control seven or more lands and/or Treefolk, create a 3/4 green Treefolk creature token with reach.| +Thoughtweft Charge|Lorwyn Eclipsed|198|U|{1}{G}|Instant|||Target creature gets +3/+3 until end of turn. If a creature entered the battlefield under your control this turn, draw a card.| +Trystan, Callous Cultivator|Lorwyn Eclipsed|199|R|{2}{G}|Legendary Creature - Elf Druid|3|4|Deathtouch$Whenever this creature enters or transforms into Trystan, Callous Cultivator, mill three cards. Then if there is an Elf card in your graveyard, you gain 2 life.$At the beginning of your first main phase, you may pay {B}. If you do, transform Trystan.| +Trystan, Penitent Culler|Lorwyn Eclipsed|199|R||Legendary Creature - Elf Warlock|3|4|Deathtouch$Whenever this creature transforms into Trystan, Penitent Culler, mill three cards, then you may exile an Elf card from your graveyard. If you do, each opponent loses 2 life.$At the beginning of your first main phase, you may pay {G}. If you do, transform Trystan.| +Unforgiving Aim|Lorwyn Eclipsed|200|C|{2}{G}|Instant|||Choose one --$* Destroy target creature with flying.$* Destroy target enchantment.$* Create a 2/2 black and green Elf creature token.| +Vinebred Brawler|Lorwyn Eclipsed|201|U|{2}{G}|Creature - Elf Berserker|4|2|This creature must be blocked if able.$Whenever this creature attacks, another target Elf you control gets +2/+1 until end of turn.| +Virulent Emissary|Lorwyn Eclipsed|202|U|{G}|Creature - Elf Assassin|1|1|Deathtouch$Whenever another creature you control enters, you gain 1 life.| +Abigale, Eloquent First-Year|Lorwyn Eclipsed|204|R|{W/B}{W/B}|Legendary Creature - Bird Bard|1|1|Flying, first strike, lifelink$When Abigale enters, up to one other target creature loses all abilities. Put a flying counter, a first strike counter, and a lifelink counter on that creature.| Ashling's Command|Lorwyn Eclipsed|205|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.| +Bre of Clan Stoutarm|Lorwyn Eclipsed|207|R|{2}{R}{W}|Legendary Creature - Giant Warrior|4|4|{1}{W}, {T}: Another target creature you control gains flying and lifelink until end of turn.$At the beginning of your end step, if you gained life this turn, exile cards from the top of your library until you exile a nonland card. You may cast that card without paying its mana cost if the spell's mana value is less than or equal to the amount of life you gained this turn. Otherwise, put it into your hand.| +Brigid's Command|Lorwyn Eclipsed|208|R|{1}{G}{W}|Kindred Sorcery - Kithkin|||Choose two --$* Create a token that's a copy of target Kithkin you control.$* Target player creates a 1/1 green and white Kithkin creature token.$* Target creature you control gets +3/+3 until end of turn.$* Target creature you control fights target creature an opponent controls.| +Chaos Spewer|Lorwyn Eclipsed|210|C|{2}{B/R}|Creature - Goblin Warlock|5|4|When this creature enters, you may pay {2}. If you don't, blight 2.| +Chitinous Graspling|Lorwyn Eclipsed|211|C|{3}{G/U}|Creature - Shapeshifter|3|4|Changeling$Reach| 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}| +Deepway Navigator|Lorwyn Eclipsed|214|R|{W}{U}|Creature - Merfolk Wizard|2|2|Flash$When this creature enters, untap each other Merfolk you control.$As long as you attacked with three or more Merfolk this turn, Merfolk you control get +1/+0.| +Doran, Besieged by Time|Lorwyn Eclipsed|215|R|{1}{W}{B}{G}|Legendary Creature - Treefolk Druid|0|5|Each creature spell you cast with toughness greater than its power costs {1} less to cast.$Whenever a creature you control attacks or blocks, it gets +X/+X until end of turn, where X is the difference between its power and toughness.| +Eclipsed Flamekin|Lorwyn Eclipsed|219|U|{1}{U/R}{U/R}|Creature - Elemental Scout|1|4|When this creature enters, look at the top four cards of your library. You may reveal an Elemental, Island, or Mountain card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.| 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.| +Flaring Cinder|Lorwyn Eclipsed|225|C|{1}{U/R}{U/R}|Creature - Elemental Sorcerer|3|2|When this creature enters and whenever you cast a spell with mana value 4 or greater, you may discard a card. If you do, draw a card.| +Gangly Stompling|Lorwyn Eclipsed|226|C|{2}{R/G}|Creature - Shapeshifter|4|2|Changeling$Trample| +Glister Bairn|Lorwyn Eclipsed|227|U|{2}{G/U}{G/U}{G/U}|Creature - Ouphe|1|4|Vivid -- At the beginning of combat on your turn, another target creature you control gets +X/+X until end of turn, where X is the number of colors among permanents you control.| +Grub's Command|Lorwyn Eclipsed|228|R|{3}{B}{R}|Kindred Sorcery - Goblin|||Choose two --$* Create a token that's a copy of target Goblin you control.$* Creatures target player controls get +1/+1 and gain haste until end of turn.$* Destroy target artifact or creature.$* Target player mills five cards, then puts each Goblin card milled this way into their hand.| +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.| +Hovel Hurler|Lorwyn Eclipsed|230|U|{3}{R/W}{R/W}|Creature - Giant Warrior|6|7|This creature enters with two -1/-1 counters on it.${R/W}{R/W}, Remove a counter from this creature: Another target creature you control gets +1/+0 and gains flying until end of turn. 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.| +Lluwen, Imperfect Naturalist|Lorwyn Eclipsed|232|R|{B/G}{B/G}|Legendary Creature - Elf Druid|1|3|When Lluwen enters, mill four cards, then you may put a creature or land card from among the milled cards on top of your library.${2}{B/G}{B/G}{B/G}, {T}, Discard a land card: Create a 1/1 black and green Worm creature token for each land card in your graveyard.| +Maralen, Fae Ascendant|Lorwyn Eclipsed|233|R|{2}{B}{G}{U}|Legendary Creature - Elf Faerie Noble|4|5|Flying$Whenever Maralen or another Elf or Faerie you control enters, exile the top two cards of target opponent's library.$Once each turn, you may cast a spell with mana value less than or equal to the number of Elves and Faeries you control from among cards exiled with Maralen this turn without paying its mana cost.| +Merrow Skyswimmer|Lorwyn Eclipsed|234|C|{3}{W/U}{W/U}|Creature - Merfolk Soldier|2|2|Convoke$Flying, vigilance$When this creature enters, create a 1/1 white and blue Merfolk creature token.| +Noggle Robber|Lorwyn Eclipsed|237|U|{1}{R/G}{R/G}|Creature - Noggle Rogue|3|3|When this creature enters or dies, create a Treasure token.| +Prideful Feastling|Lorwyn Eclipsed|238|C|{2}{W/B}|Creature - Shapeshifter|2|3|Changeling$Lifelink| +Sanar, Innovative First-Year|Lorwyn Eclipsed|241|R|{2}{U/R}{U/R}|Legendary Creature - Goblin Sorcerer|2|4|Vivid -- At the beginning of your first main phase, reveal cards from the top of your library until you reveal X nonland cards, where X is the number of colors among permanents you control. For each of those colors, you may exile a card of that color from among the revealed cards. Then shuffle. You may cast the exiled cards this turn.| +Sygg's Command|Lorwyn Eclipsed|244|R|{1}{W}{U}|Kindred Sorcery - Merfolk|||Choose two --$* Create a token that's a copy of target Merfolk you control.$* Creatures target player controls gain lifelink until end of turn.$* Target player draws a card.$* Tap target creature. Put a stun counter on it.| +Tam, Mindful First-Year|Lorwyn Eclipsed|245|R|{1}{G/U}|Legendary Creature - Gorgon Wizard|2|2|Each other creature you control has hexproof from each of its colors.${T}: Target creature you control becomes all colors until end of turn.| +Thoughtweft Lieutenant|Lorwyn Eclipsed|246|U|{G}{W}|Creature - Kithkin Soldier|2|2|Whenever this creature or another Kithkin you control enters, target creature you control gets +1/+1 and gains trample until end of turn.| +Vibrance|Lorwyn Eclipsed|249|M|{3}{R/G}{R/G}|Creature - Elemental Incarnation|4|4|When this creature enters, if {R}{R} was spent to cast it, this creature deals 3 damage to any target.$When this creature enters, if {G}{G} was spent to cast it, search your library for a land card, reveal it, put it into your hand, then shuffle. You gain 2 life.$Evoke {R/G}{R/G}| +Voracious Tome-Skimmer|Lorwyn Eclipsed|250|U|{U/B}{U/B}{U/B}|Creature - Faerie Rogue|2|3|Flying$Whenever you cast a spell during an opponent's turn, you may pay 1 life. If you do, draw a card.| +Wary Farmer|Lorwyn Eclipsed|251|C|{1}{G/W}{G/W}|Creature - Kithkin Citizen|3|3|At the beginning of your end step, if another creature entered the battlefield under your control this turn, surveil 1.| +Wistfulness|Lorwyn Eclipsed|252|M|{3}{G/U}{G/U}|Creature - Elemental Incarnation|6|5|When this creature enters, if {G}{G} was spent to cast it, exile target artifact or enchantment an opponent controls.$When this creature enters, if {U}{U} was spent to cast it, draw two cards, then discard a card.$Evoke {G/U}{G/U}| +Chronicle of Victory|Lorwyn Eclipsed|253|M|{6}|Legendary Artifact|||As Chronicle of Victory enters, choose a creature type.$Creatures you control of the chosen type get +2/+2 and have first strike and trample.$Whenever you cast a spell of the chosen type, draw a card.| +Dawn-Blessed Pennant|Lorwyn Eclipsed|254|U|{1}|Artifact|||As this artifact enters, choose Elemental, Elf, Faerie, Giant, Goblin, Kithkin, Merfolk, or Treefolk.$Whenever a permanent you control of the chosen type enters, you gain 1 life.${2}, {T}, Sacrifice this artifact: Return target card of the chosen type from your graveyard to your hand.| +Firdoch Core|Lorwyn Eclipsed|255|C|{3}|Kindred Artifact - Shapeshifter|||Changeling${T}: Add one mana of any color.${4}: This artifact becomes a 4/4 artifact creature until end of turn.| +Gathering Stone|Lorwyn Eclipsed|257|U|{4}|Artifact|||As this artifact enters, choose a creature type.$Spells you cast of the chosen type cost {1} less to cast.$When this artifact enters and at the beginning of your upkeep, look at the top card of your library. If it's a card of the chosen type, you may reveal it and put it into your hand. If you don't put the card into your hand, you may put it into your graveyard.| +Mirrormind Crown|Lorwyn Eclipsed|258|R|{4}|Artifact - Equipment|||As long as this Equipment is attached to a creature, the first time you would create one or more tokens each turn, you may instead create that many tokens that are copies of equipped creature.$Equip {2}| +Puca's Eye|Lorwyn Eclipsed|259|U|{2}|Artifact|||When this artifact enters, draw a card, then choose a color. This artifact becomes the chosen color.${3}, {T}: Draw a card. Activate only if there are five colors among permanents you control.| +Springleaf Drum|Lorwyn Eclipsed|260|U|{1}|Artifact|||{T}, Tap an untapped creature you control: Add one mana of any color.| 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.| +Eclipsed Realms|Lorwyn Eclipsed|263|U||Land|||As this land enters, choose Elemental, Elf, Faerie, Giant, Goblin, Kithkin, Merfolk, or Treefolk.${T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast a spell of the chosen type or activate an ability of a source of the chosen type.| +Evolving Wilds|Lorwyn Eclipsed|264|C||Land|||{T}, Sacrifice this land: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.| 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.| Steam Vents|Lorwyn Eclipsed|267|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.| Temple Garden|Lorwyn Eclipsed|268|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.| +Plains|Lorwyn Eclipsed|269|C||Basic Land - Plains|||({T}: Add {W}.)| +Island|Lorwyn Eclipsed|270|C||Basic Land - Island|||({T}: Add {U}.)| +Swamp|Lorwyn Eclipsed|271|C||Basic Land - Swamp|||({T}: Add {B}.)| +Mountain|Lorwyn Eclipsed|272|C||Basic Land - Mountain|||({T}: Add {R}.)| +Forest|Lorwyn Eclipsed|273|C||Basic Land - Forest|||({T}: Add {G}.)| +Plains|Lorwyn Eclipsed|274|C||Basic Land - Plains|||({T}: Add {W}.)| +Island|Lorwyn Eclipsed|275|C||Basic Land - Island|||({T}: Add {U}.)| +Swamp|Lorwyn Eclipsed|276|C||Basic Land - Swamp|||({T}: Add {B}.)| +Mountain|Lorwyn Eclipsed|277|C||Basic Land - Mountain|||({T}: Add {R}.)| +Forest|Lorwyn Eclipsed|278|C||Basic Land - Forest|||({T}: Add {G}.)| +Plains|Lorwyn Eclipsed|279|C||Basic Land - Plains|||({T}: Add {W}.)| +Island|Lorwyn Eclipsed|280|C||Basic Land - Island|||({T}: Add {U}.)| +Swamp|Lorwyn Eclipsed|281|C||Basic Land - Swamp|||({T}: Add {B}.)| +Mountain|Lorwyn Eclipsed|282|C||Basic Land - Mountain|||({T}: Add {R}.)| +Forest|Lorwyn Eclipsed|283|C||Basic Land - Forest|||({T}: Add {G}.)| +Brigid, Clachan's Heart|Lorwyn Eclipsed|285|R|{2}{W}|Legendary Creature - Kithkin Warrior|3|2|Whenever this creature enters or transforms into Brigid, Clachan's Heart, create a 1/1 green and white Kithkin creature token.$At the beginning of your first main phase, you may pay {G}. If you do, transform Brigid.| +Brigid, Doun's Mind|Lorwyn Eclipsed|285|R||Legendary Creature - Kithkin Soldier|3|2|{T}: Add X {G} or X {W}, where X is the number of other creatures you control.$At the beginning of your first main phase, you may pay {W}. If you do, transform Brigid.| Eirdu, Carrier of Dawn|Lorwyn Eclipsed|286|M|{3}{W}{W}|Legendary Creature - Elemental God|5|5|Flying, lifelink$Creature spells you cast have convoke.$At the beginning of your first main phase, you may pay {B}. If you do, transform Eirdu.| Isilu, Carrier of Twilight|Lorwyn Eclipsed|286|M||Legendary Creature - Elemental God|5|5|Flying, lifelink$Each other nontoken creature you control has persist.$At the beginning of your first main phase, you may pay {W}. If you do, transform Isilu.| +Oko, Lorwyn Liege|Lorwyn Eclipsed|287|M|{2}{U}|Legendary Planeswalker - Oko|3|At the beginning of your first main phase, you may pay {G}. If you do, transform Oko.$+2: Up to one target creature gains all creature types.$+1: Target creature gets -2/-0 until your next turn.| +Oko, Shadowmoor Scion|Lorwyn Eclipsed|287|M||Legendary Planeswalker - Oko|3|At the beginning of your first main phase, you may pay {U}. If you do, transform Oko.$-1: Mill three cards. You may put a permanent card from among them into your hand.$-3: Create two 3/3 green Elk creature tokens.$-6: Choose a creature type. You get an emblem with "Creatures you control of the chosen type get +3/+3 and have vigilance and hexproof."| Sygg, Wanderwine Wisdom|Lorwyn Eclipsed|288|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|288|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.| +Grub, Storied Matriarch|Lorwyn Eclipsed|289|R|{2}{B}|Legendary Creature - Goblin Warlock|2|1|Menace$Whenever this creature enters or transforms into Grub, Storied Matriarch, return up to one target Goblin card from your graveyard to your hand.$At the beginning of your first main phase, you may pay {R}. If you do, transform Grub.| +Grub, Notorious Auntie|Lorwyn Eclipsed|289|R||Legendary Creature - Goblin Warrior|2|1|Menace$Whenever Grub attacks, you may blight 1. If you do, create a tapped and attacking token that's a copy of the blighted creature, except it has "At the beginning of the end step, sacrifice this token."$At the beginning of your first main phase, you may pay {B}. If you do, transform Grub.| Ashling, Rekindled|Lorwyn Eclipsed|290|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|290|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.| +Trystan, Callous Cultivator|Lorwyn Eclipsed|291|R|{2}{G}|Legendary Creature - Elf Druid|3|4|Deathtouch$Whenever this creature enters or transforms into Trystan, Callous Cultivator, mill three cards. Then if there is an Elf card in your graveyard, you gain 2 life.$At the beginning of your first main phase, you may pay {B}. If you do, transform Trystan.| +Trystan, Penitent Culler|Lorwyn Eclipsed|291|R||Legendary Creature - Elf Warlock|3|4|Deathtouch$Whenever this creature transforms into Trystan, Penitent Culler, mill three cards, then you may exile an Elf card from your graveyard. If you do, each opponent loses 2 life.$At the beginning of your first main phase, you may pay {G}. If you do, transform Trystan.| Deceit|Lorwyn Eclipsed|293|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|294|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}| +Vibrance|Lorwyn Eclipsed|295|M|{3}{R/G}{R/G}|Creature - Elemental Incarnation|4|4|When this creature enters, if {R}{R} was spent to cast it, this creature deals 3 damage to any target.$When this creature enters, if {G}{G} was spent to cast it, search your library for a land card, reveal it, put it into your hand, then shuffle. You gain 2 life.$Evoke {R/G}{R/G}| +Wistfulness|Lorwyn Eclipsed|296|M|{3}{G/U}{G/U}|Creature - Elemental Incarnation|6|5|When this creature enters, if {G}{G} was spent to cast it, exile target artifact or enchantment an opponent controls.$When this creature enters, if {U}{U} was spent to cast it, draw two cards, then discard a card.$Evoke {G/U}{G/U}| +Curious Colossus|Lorwyn Eclipsed|298|M|{5}{W}{W}|Creature - Giant Warrior|7|7|When this creature enters, each creature target opponent controls loses all abilities, becomes a Coward in addition to its other types, and has base power and toughness 1/1.| +Kinbinding|Lorwyn Eclipsed|299|R|{3}{W}{W}|Enchantment|||Creatures you control get +X/+X, where X is the number of creatures that entered the battlefield under your control this turn.$At the beginning of combat on your turn, create a 1/1 green and white Kithkin creature token.| Morningtide's Light|Lorwyn Eclipsed|301|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.| +Slumbering Walker|Lorwyn Eclipsed|302|R|{3}{W}{W}|Creature - Giant Warrior|4|7|This creature enters with two -1/-1 counters on it.$At the beginning of your end step, you may remove a counter from this creature. When you do, return target creature card with power 2 or less from your graveyard to the battlefield.| +Disruptor of Currents|Lorwyn Eclipsed|303|R|{3}{U}{U}|Creature - Merfolk Wizard|3|3|Flash$Convoke$When this creature enters, return up to one other target nonland permanent to its owner's hand.| +Flitterwing Nuisance|Lorwyn Eclipsed|304|R|{U}|Creature - Faerie Rogue|2|2|Flying$This creature enters with a -1/-1 counter on it.${2}{U}, Remove a counter from this creature: Whenever a creature you control deals combat damage to a player or planeswalker this turn, draw a card.| +Glen Elendra's Answer|Lorwyn Eclipsed|306|M|{2}{U}{U}|Instant|||This spell can't be countered.$Counter all spells your opponents control and all abilities your opponents control. Create a 1/1 blue and black Faerie creature token with flying for each spell and ability countered this way.| +Loch Mare|Lorwyn Eclipsed|307|M|{1}{U}|Creature - Horse Serpent|4|5|This creature enters with three -1/-1 counters on it.${1}{U}, Remove a counter from this creature: Draw a card.${2}{U}, Remove two counters from this creature: Tap target creature. Put a stun counter on it.| +Mirrorform|Lorwyn Eclipsed|308|M|{4}{U}{U}|Instant|||Each nonland permanent you control becomes a copy of target non-Aura permanent.| +Sunderflock|Lorwyn Eclipsed|309|R|{7}{U}{U}|Creature - Elemental|5|5|This spell costs {X} less to cast, where X is the greatest mana value among Elementals you control.$Flying$When this creature enters, if you cast it, return all non-Elemental creatures to their owners' hands.| Bitterbloom Bearer|Lorwyn Eclipsed|310|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.| +Dawnhand Dissident|Lorwyn Eclipsed|311|R|{B}|Creature - Elf Warlock|1|2|{T}, Blight 1: Surveil 1.${T}, Blight 2: Exile target card from a graveyard.$During your turn, you may cast creature spells from among cards you own exiled with this creature by removing three counters from among creatures you control in addition to paying their other costs.| +Goliath Daydreamer|Lorwyn Eclipsed|316|R|{2}{R}{R}|Creature - Giant Wizard|4|4|Whenever you cast an instant or sorcery spell from your hand, exile that card with a dream counter on it instead of putting it into your graveyard as it resolves.$Whenever this creature attacks, you may cast a spell from among cards you own in exile with dream counters on them without paying its mana cost.| +Hexing Squelcher|Lorwyn Eclipsed|317|R|{1}{R}|Creature - Goblin Sorcerer|2|2|This spell can't be countered.$Ward--Pay 2 life.$Spells you control can't be countered.$Other creatures you control have "Ward--Pay 2 life."| +Lavaleaper|Lorwyn Eclipsed|318|R|{3}{R}|Creature - Elemental|4|4|All creatures have haste.$Whenever a player taps a basic land for mana, that player adds one mana of any type that land produced.| +Meek Attack|Lorwyn Eclipsed|319|M|{2}{R}|Enchantment|||{1}{R}: You may put a creature card with total power and toughness 5 or less from your hand onto the battlefield. That creature gains haste. At the beginning of the next end step, sacrifice that creature.| +Spinerock Tyrant|Lorwyn Eclipsed|322|M|{3}{R}{R}|Creature - Dragon|6|6|Flying$Wither$Whenever you cast an instant or sorcery spell with a single target, you may copy it. If you do, those spells gain wither. You may choose new targets for the copy.| +Aurora Awakener|Lorwyn Eclipsed|323|M|{6}{G}|Creature - Giant Druid|7|7|Trample$Vivid -- When this creature enters, reveal cards from the top of your library until you reveal X permanent cards, where X is the number of colors among permanents you control. Put any number of those permanent cards onto the battlefield, then put the rest of the revealed cards on the bottom of your library in a random order.| +Bloom Tender|Lorwyn Eclipsed|324|M|{1}{G}|Creature - Elf Druid|1|1|Vivid -- {T}: For each color among permanents you control, add one mana of that color.| +Bristlebane Battler|Lorwyn Eclipsed|325|R|{1}{G}|Creature - Kithkin Soldier|6|6|Trample, ward {2}$This creature enters with five -1/-1 counters on it.$Whenever another creature you control enters while this creature has a -1/-1 counter on it, remove a -1/-1 counter from this creature.| +Celestial Reunion|Lorwyn Eclipsed|326|M|{X}{G}|Sorcery|||As an additional cost to cast this spell, you may choose a creature type and behold two creatures of that type.$Search your library for a creature card with mana value X or less, reveal it, put it into your hand, then shuffle. If this spell's additional cost was paid and the revealed card is the chosen type, put that card onto the battlefield instead of putting it into your hand.| Mutable Explorer|Lorwyn Eclipsed|327|R|{2}{G}|Creature - Shapeshifter|1|1|Changeling$When this creature enters, create a tapped Mutavault token.| +Sapling Nursery|Lorwyn Eclipsed|328|R|{6}{G}{G}|Enchantment|||Affinity for Forests$Landfall -- Whenever a land you control enters, create a 3/4 green Treefolk creature token with reach.${1}{G}, Exile this enchantment: Treefolk and Forests you control gain indestructible until end of turn.| 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.| +Brigid's Command|Lorwyn Eclipsed|332|R|{1}{G}{W}|Kindred Sorcery - Kithkin|||Choose two --$* Create a token that's a copy of target Kithkin you control.$* Target player creates a 1/1 green and white Kithkin creature token.$* Target creature you control gets +3/+3 until end of turn.$* Target creature you control fights target creature an opponent controls.| +Doran, Besieged by Time|Lorwyn Eclipsed|334|R|{1}{W}{B}{G}|Legendary Creature - Treefolk Druid|0|5|Each creature spell you cast with toughness greater than its power costs {1} less to cast.$Whenever a creature you control attacks or blocks, it gets +X/+X until end of turn, where X is the difference between its power and toughness.| +Eclipsed Flamekin|Lorwyn Eclipsed|337|U|{1}{U/R}{U/R}|Creature - Elemental Scout|1|4|When this creature enters, look at the top four cards of your library. You may reveal an Elemental, Island, or Mountain card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.| +Grub's Command|Lorwyn Eclipsed|340|R|{3}{B}{R}|Kindred Sorcery - Goblin|||Choose two --$* Create a token that's a copy of target Goblin you control.$* Creatures target player controls get +1/+1 and gain haste until end of turn.$* Destroy target artifact or creature.$* Target player mills five cards, then puts each Goblin card milled this way into their hand.| +Sygg's Command|Lorwyn Eclipsed|342|R|{1}{W}{U}|Kindred Sorcery - Merfolk|||Choose two --$* Create a token that's a copy of target Merfolk you control.$* Creatures target player controls gain lifelink until end of turn.$* Target player draws a card.$* Tap target creature. Put a stun counter on it.| +Thoughtweft Lieutenant|Lorwyn Eclipsed|343|U|{G}{W}|Creature - Kithkin Soldier|2|2|Whenever this creature or another Kithkin you control enters, target creature you control gets +1/+1 and gains trample until end of turn.| +Chronicle of Victory|Lorwyn Eclipsed|346|M|{6}|Legendary Artifact|||As Chronicle of Victory enters, choose a creature type.$Creatures you control of the chosen type get +2/+2 and have first strike and trample.$Whenever you cast a spell of the chosen type, draw a card.| 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.| +Champion of the Clachan|Lorwyn Eclipsed|353|R|{3}{W}|Creature - Kithkin Knight|4|5|Flash$As an additional cost to cast this spell, behold a Kithkin and exile it.$Other Kithkin you control get +1/+1.$When this creature leaves the battlefield, return the exiled card to its owner's hand.| +Rhys, the Evermore|Lorwyn Eclipsed|354|R|{1}{W}|Legendary Creature - Elf Warrior|2|2|Flash$When Rhys enters, another target creature you control gains persist until end of turn.${W}, {T}: Remove any number of counters from target creature you control. Activate only as a sorcery.| +Winnowing|Lorwyn Eclipsed|355|R|{4}{W}{W}|Sorcery|||Convoke$For each player, you choose a creature that player controls. Then each player sacrifices all other creatures they control that don't share a creature type with the chosen creature they control.| +Harmonized Crescendo|Lorwyn Eclipsed|357|R|{4}{U}{U}|Instant|||Convoke$Choose a creature type. Draw a card for each permanent you control of that type.| +Bloodline Bidding|Lorwyn Eclipsed|359|R|{6}{B}{B}|Sorcery|||Convoke$Choose a creature type. Return all creature cards of the chosen type from your graveyard to the battlefield.| +Champion of the Weird|Lorwyn Eclipsed|360|R|{3}{B}|Creature - Goblin Berserker|5|5|As an additional cost to cast this spell, behold a Goblin and exile it.$Pay 1 life, Blight 2: Target opponent blights 2. Activate only as a sorcery.$When this creature leaves the battlefield, return the exiled card to its owner's hand.| +Mornsong Aria|Lorwyn Eclipsed|361|R|{1}{B}{B}|Legendary Enchantment|||Players can't draw cards or gain life.$At the beginning of each player's draw step, that player loses 3 life, searches their library for a card, puts it into their hand, then shuffles.| +Collective Inferno|Lorwyn Eclipsed|363|R|{3}{R}{R}|Enchantment|||Convoke$As this enchantment enters, choose a creature type.$Double all damage that sources you control of the chosen type would deal.| +Champions of the Perfect|Lorwyn Eclipsed|365|R|{3}{G}|Creature - Elf Warrior|6|6|As an additional cost to cast this spell, behold an Elf and exile it.$Whenever you cast a creature spell, draw a card.$When this creature leaves the battlefield, return the exiled card to its owner's hand.| 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.| +Selfless Safewright|Lorwyn Eclipsed|367|R|{3}{G}{G}|Creature - Elf Warrior|4|2|Flash$Convoke$When this creature enters, choose a creature type. Other permanents you control of that type gain hexproof and indestructible until end of turn.| +Abigale, Eloquent First-Year|Lorwyn Eclipsed|368|R|{W/B}{W/B}|Legendary Creature - Bird Bard|1|1|Flying, first strike, lifelink$When Abigale enters, up to one other target creature loses all abilities. Put a flying counter, a first strike counter, and a lifelink counter on that creature.| +Bre of Clan Stoutarm|Lorwyn Eclipsed|369|R|{2}{R}{W}|Legendary Creature - Giant Warrior|4|4|{1}{W}, {T}: Another target creature you control gains flying and lifelink until end of turn.$At the beginning of your end step, if you gained life this turn, exile cards from the top of your library until you exile a nonland card. You may cast that card without paying its mana cost if the spell's mana value is less than or equal to the amount of life you gained this turn. Otherwise, put it into your hand.| +Deepway Navigator|Lorwyn Eclipsed|370|R|{W}{U}|Creature - Merfolk Wizard|2|2|Flash$When this creature enters, untap each other Merfolk you control.$As long as you attacked with three or more Merfolk this turn, Merfolk you control get +1/+0.| 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.| +Lluwen, Imperfect Naturalist|Lorwyn Eclipsed|375|R|{B/G}{B/G}|Legendary Creature - Elf Druid|1|3|When Lluwen enters, mill four cards, then you may put a creature or land card from among the milled cards on top of your library.${2}{B/G}{B/G}{B/G}, {T}, Discard a land card: Create a 1/1 black and green Worm creature token for each land card in your graveyard.| +Maralen, Fae Ascendant|Lorwyn Eclipsed|376|R|{2}{B}{G}{U}|Legendary Creature - Elf Faerie Noble|4|5|Flying$Whenever Maralen or another Elf or Faerie you control enters, exile the top two cards of target opponent's library.$Once each turn, you may cast a spell with mana value less than or equal to the number of Elves and Faeries you control from among cards exiled with Maralen this turn without paying its mana cost.| +Sanar, Innovative First-Year|Lorwyn Eclipsed|378|R|{2}{U/R}{U/R}|Legendary Creature - Goblin Sorcerer|2|4|Vivid -- At the beginning of your first main phase, reveal cards from the top of your library until you reveal X nonland cards, where X is the number of colors among permanents you control. For each of those colors, you may exile a card of that color from among the revealed cards. Then shuffle. You may cast the exiled cards this turn.| +Tam, Mindful First-Year|Lorwyn Eclipsed|380|R|{1}{G/U}|Legendary Creature - Gorgon Wizard|2|2|Each other creature you control has hexproof from each of its colors.${T}: Target creature you control becomes all colors until end of turn.| +Mirrormind Crown|Lorwyn Eclipsed|381|R|{4}|Artifact - Equipment|||As long as this Equipment is attached to a creature, the first time you would create one or more tokens each turn, you may instead create that many tokens that are copies of equipped creature.$Equip {2}| +Winnowing|Lorwyn Eclipsed|382|M|{4}{W}{W}|Sorcery|||Convoke$For each player, you choose a creature that player controls. Then each player sacrifices all other creatures they control that don't share a creature type with the chosen creature they control.| +Harmonized Crescendo|Lorwyn Eclipsed|384|M|{4}{U}{U}|Instant|||Convoke$Choose a creature type. Draw a card for each permanent you control of that type.| +Bloodline Bidding|Lorwyn Eclipsed|385|M|{6}{B}{B}|Sorcery|||Convoke$Choose a creature type. Return all creature cards of the chosen type from your graveyard to the battlefield.| +Collective Inferno|Lorwyn Eclipsed|387|M|{3}{R}{R}|Enchantment|||Convoke$As this enchantment enters, choose a creature type.$Double all damage that sources you control of the chosen type would deal.| +Meek Attack|Lorwyn Eclipsed|388|M|{2}{R}|Enchantment|||{1}{R}: You may put a creature card with total power and toughness 5 or less from your hand onto the battlefield. That creature gains haste. At the beginning of the next end step, sacrifice that creature.| +Spinerock Tyrant|Lorwyn Eclipsed|389|M|{3}{R}{R}|Creature - Dragon|6|6|Flying$Wither$Whenever you cast an instant or sorcery spell with a single target, you may copy it. If you do, those spells gain wither. You may choose new targets for the copy.| +Bloom Tender|Lorwyn Eclipsed|390|M|{1}{G}|Creature - Elf Druid|1|1|Vivid -- {T}: For each color among permanents you control, add one mana of that color.| +Selfless Safewright|Lorwyn Eclipsed|391|M|{3}{G}{G}|Creature - Elf Warrior|4|2|Flash$Convoke$When this creature enters, choose a creature type. Other permanents you control of that type gain hexproof and indestructible until end of turn.| +Winnowing|Lorwyn Eclipsed|392|M|{4}{W}{W}|Sorcery|||Convoke$For each player, you choose a creature that player controls. Then each player sacrifices all other creatures they control that don't share a creature type with the chosen creature they control.| +Harmonized Crescendo|Lorwyn Eclipsed|394|M|{4}{U}{U}|Instant|||Convoke$Choose a creature type. Draw a card for each permanent you control of that type.| +Bloodline Bidding|Lorwyn Eclipsed|395|M|{6}{B}{B}|Sorcery|||Convoke$Choose a creature type. Return all creature cards of the chosen type from your graveyard to the battlefield.| +Collective Inferno|Lorwyn Eclipsed|397|M|{3}{R}{R}|Enchantment|||Convoke$As this enchantment enters, choose a creature type.$Double all damage that sources you control of the chosen type would deal.| +Meek Attack|Lorwyn Eclipsed|398|M|{2}{R}|Enchantment|||{1}{R}: You may put a creature card with total power and toughness 5 or less from your hand onto the battlefield. That creature gains haste. At the beginning of the next end step, sacrifice that creature.| +Spinerock Tyrant|Lorwyn Eclipsed|399|M|{3}{R}{R}|Creature - Dragon|6|6|Flying$Wither$Whenever you cast an instant or sorcery spell with a single target, you may copy it. If you do, those spells gain wither. You may choose new targets for the copy.| +Bloom Tender|Lorwyn Eclipsed|400|M|{1}{G}|Creature - Elf Druid|1|1|Vivid -- {T}: For each color among permanents you control, add one mana of that color.| +Selfless Safewright|Lorwyn Eclipsed|401|M|{3}{G}{G}|Creature - Elf Warrior|4|2|Flash$Convoke$When this creature enters, choose a creature type. Other permanents you control of that type gain hexproof and indestructible until end of turn.| +Personify|Lorwyn Eclipsed|402|U|{1}{W}|Instant|||Exile target creature you control, then return that card to the battlefield under its owner's control. Create a 1/1 colorless Shapeshifter creature token with changeling.| +Silvergill Mentor|Lorwyn Eclipsed|403|U|{1}{U}|Creature - Merfolk Wizard|2|1|As an additional cost to cast this spell, behold a Merfolk or pay {2}.$When this creature enters, create a 1/1 white and blue Merfolk creature token.| +Iron-Shield Elf|Lorwyn Eclipsed|404|U|{1}{B}|Creature - Elf Warrior|3|1|Discard a card: This creature gains indestructible until end of turn. Tap it.| +Sear|Lorwyn Eclipsed|405|U|{1}{R}|Instant|||Sear deals 4 damage to target creature or planeswalker.| +Virulent Emissary|Lorwyn Eclipsed|406|U|{G}|Creature - Elf Assassin|1|1|Deathtouch$Whenever another creature you control enters, you gain 1 life.| +Kinbinding|Lorwyn Eclipsed|407|R|{3}{W}{W}|Enchantment|||Creatures you control get +X/+X, where X is the number of creatures that entered the battlefield under your control this turn.$At the beginning of combat on your turn, create a 1/1 green and white Kithkin creature token.| +Harmonized Crescendo|Lorwyn Eclipsed|408|R|{4}{U}{U}|Instant|||Convoke$Choose a creature type. Draw a card for each permanent you control of that type.| 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 +61240,205 @@ 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.| +Ashling, the Limitless|Lorwyn Eclipsed Commander|1|M|{2}{R}|Legendary Creature - Elemental Sorcerer|2|3|Elemental spells you cast from your hand have evoke {4}.$Whenever you sacrifice a nontoken Elemental, create a token that's a copy of it. The token gains haste until end of turn. At the beginning of your next end step, sacrifice it unless you pay {W}{U}{B}{R}{G}.| +Auntie Ool, Cursewretch|Lorwyn Eclipsed Commander|2|M|{1}{B}{R}{G}|Legendary Creature - Goblin Warlock|4|4|Ward--Blight 2.$Whenever one or more -1/-1 counters are put on a creature, draw a card if you control that creature. If you don't control it, its controller loses 1 life.| +Mass of Mysteries|Lorwyn Eclipsed Commander|3|M|{W}{U}{B}{R}{G}|Legendary Creature - Elemental|5|5|First strike, vigilance, trample$At the beginning of combat on your turn, another target Elemental you control gains myriad until end of turn.| +The Reaper, King No More|Lorwyn Eclipsed Commander|4|M|{2/B}{2/R}{2/G}|Legendary Artifact Creature - Scarecrow|3|3|When The Reaper enters, put a -1/-1 counter on each of up to two target creatures.$Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may put that card onto the battlefield under your control. Do this only once each turn.| +Belonging|Lorwyn Eclipsed Commander|5|R|{5}{W}|Creature - Elemental Incarnation|6|6|When this creature enters, create three 1/1 colorless Shapeshifter creature tokens with changeling.$Encore {6}{W}{W}| +Subterfuge|Lorwyn Eclipsed Commander|6|R|{4}{U}|Creature - Elemental Incarnation|3|5|When this creature enters, target creature gains flying and "Whenever this creature deals combat damage to a player, draw that many cards" until end of turn.$Encore {7}{U}{U}| +Aberrant Return|Lorwyn Eclipsed Commander|7|R|{4}{B}{B}|Sorcery|||Put one, two, or three target creature cards from graveyards onto the battlefield under your control. Each of them enters with an additional -1/-1 counter on it.| +Eventide's Shadow|Lorwyn Eclipsed Commander|8|R|{4}{B}|Sorcery|||Remove any number of counters from among permanents on the battlefield. You draw cards and lose life equal to the number of counters removed this way.| +Grave Venerations|Lorwyn Eclipsed Commander|9|R|{3}{B}|Enchantment|||When this enchantment enters, you become the monarch.$At the beginning of your end step, if you're the monarch, return up to one target creature card from your graveyard to your hand.$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.| +Lamentation|Lorwyn Eclipsed Commander|10|R|{5}{B}|Creature - Elemental Incarnation|5|4|When this creature enters, destroy target creature an opponent controls. You gain 3 life.$Encore {6}{B}{B}| +Oft-Nabbed Goat|Lorwyn Eclipsed Commander|11|R|{1}{B}|Creature - Goat|0|5|{1}: Draw a card. Gain control of this creature and put a -1/-1 counter on it. Only your opponents may activate this ability and only as a sorcery.$When this creature dies, if it had one or more -1/-1 counters on it, its owner draws that many cards and each other player loses that much life.| +Sinister Gnarlbark|Lorwyn Eclipsed Commander|12|R|{2}{B}|Creature - Treefolk Warlock|0|4|At the beginning of your end step, draw a card and blight 1.| +Impulsivity|Lorwyn Eclipsed Commander|13|R|{6}{R}|Creature - Elemental Incarnation|7|5|When this creature enters, you may cast target instant or sorcery card from a graveyard without paying its mana cost. If that spell would be put into a graveyard, exile it instead.$Encore {7}{R}{R}| +Village Pillagers|Lorwyn Eclipsed Commander|14|R|{3}{R}{R}|Creature - Goblin Warrior|5|5|Wither$When this creature enters, it deals 1 damage to each creature your opponents control.$Whenever a creature an opponent controls with a counter on it dies, you create a tapped Treasure token.| +Elemental Spectacle|Lorwyn Eclipsed Commander|15|R|{5}{G}|Sorcery|||Vivid -- Create a number of 5/5 red and green Elemental creature tokens equal to the number of colors among permanents you control. Then you gain life equal to the number of creatures you control.| +Ferrafor, Young Yew|Lorwyn Eclipsed Commander|16|R|{6}{G}|Legendary Creature - Treefolk Druid|4|7|When Ferrafor enters, create a number of 1/1 green Saproling creature tokens equal to the number of counters among creatures target player controls.${T}: Double the number of each kind of counter on target creature.| +Jubilation|Lorwyn Eclipsed Commander|17|R|{5}{G}|Creature - Elemental Incarnation|5|5|When this creature enters, creatures you control get +2/+2 and gain trample until end of turn.$Encore {7}{G}{G}| +Puca's Covenant|Lorwyn Eclipsed Commander|18|R|{2}{G}|Enchantment|||Whenever a creature you control with a counter on it dies, you may return another target permanent card with mana value less than or equal to the number of counters on that creature from your graveyard to your hand. Do this only once each turn.| +Springleaf Parade|Lorwyn Eclipsed Commander|19|R|{G}{G}|Enchantment|||When this enchantment enters, create X 1/1 colorless Shapeshifter creature tokens with changeling.$Creature tokens you control have "{T}: Add one mana of any color."| +Dread Tiller|Lorwyn Eclipsed Commander|20|R|{1}{B}{G}|Artifact Creature - Scarecrow|2|4|When this creature enters, put a -1/-1 counter on target creature.$Whenever a creature with a -1/-1 counter on it dies, you may put a land card from your hand or graveyard onto the battlefield tapped.| +Wickersmith's Tools|Lorwyn Eclipsed Commander|21|R|{3}|Artifact|||Whenever one or more -1/-1 counters are put on a creature, put a charge counter on this artifact.${T}: Add one mana of any color.${5}, {T}, Sacrifice this artifact: Create X tapped 2/2 colorless Scarecrow artifact creature tokens, where X is the number of charge counters on this artifact.| +Abundant Countryside|Lorwyn Eclipsed Commander|22|R||Land|||{T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast a creature spell.${6}, {T}: Create a 1/1 colorless Shapeshifter creature token with changeling.| +Rain-Slicked Copse|Lorwyn Eclipsed Commander|23|R||Land - Forest Island|||({T}: Add {G} or {U}.)$This land enters tapped.$Cycling {2}| +Sodden Verdure|Lorwyn Eclipsed Commander|24|R||Land - Forest Island|||({T}: Add {G} or {U}.)$This land enters tapped unless you control two or more basic lands.| +Belonging|Lorwyn Eclipsed Commander|25|R|{5}{W}|Creature - Elemental Incarnation|6|6|When this creature enters, create three 1/1 colorless Shapeshifter creature tokens with changeling.$Encore {6}{W}{W}| +Subterfuge|Lorwyn Eclipsed Commander|26|R|{4}{U}|Creature - Elemental Incarnation|3|5|When this creature enters, target creature gains flying and "Whenever this creature deals combat damage to a player, draw that many cards" until end of turn.$Encore {7}{U}{U}| +Aberrant Return|Lorwyn Eclipsed Commander|27|R|{4}{B}{B}|Sorcery|||Put one, two, or three target creature cards from graveyards onto the battlefield under your control. Each of them enters with an additional -1/-1 counter on it.| +Eventide's Shadow|Lorwyn Eclipsed Commander|28|R|{4}{B}|Sorcery|||Remove any number of counters from among permanents on the battlefield. You draw cards and lose life equal to the number of counters removed this way.| +Grave Venerations|Lorwyn Eclipsed Commander|29|R|{3}{B}|Enchantment|||When this enchantment enters, you become the monarch.$At the beginning of your end step, if you're the monarch, return up to one target creature card from your graveyard to your hand.$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.| +Lamentation|Lorwyn Eclipsed Commander|30|R|{5}{B}|Creature - Elemental Incarnation|5|4|When this creature enters, destroy target creature an opponent controls. You gain 3 life.$Encore {6}{B}{B}| +Oft-Nabbed Goat|Lorwyn Eclipsed Commander|31|R|{1}{B}|Creature - Goat|0|5|{1}: Draw a card. Gain control of this creature and put a -1/-1 counter on it. Only your opponents may activate this ability and only as a sorcery.$When this creature dies, if it had one or more -1/-1 counters on it, its owner draws that many cards and each other player loses that much life.| +Sinister Gnarlbark|Lorwyn Eclipsed Commander|32|R|{2}{B}|Creature - Treefolk Warlock|0|4|At the beginning of your end step, draw a card and blight 1.| +Impulsivity|Lorwyn Eclipsed Commander|33|R|{6}{R}|Creature - Elemental Incarnation|7|5|When this creature enters, you may cast target instant or sorcery card from a graveyard without paying its mana cost. If that spell would be put into a graveyard, exile it instead.$Encore {7}{R}{R}| +Village Pillagers|Lorwyn Eclipsed Commander|34|R|{3}{R}{R}|Creature - Goblin Warrior|5|5|Wither$When this creature enters, it deals 1 damage to each creature your opponents control.$Whenever a creature an opponent controls with a counter on it dies, you create a tapped Treasure token.| +Elemental Spectacle|Lorwyn Eclipsed Commander|35|R|{5}{G}|Sorcery|||Vivid -- Create a number of 5/5 red and green Elemental creature tokens equal to the number of colors among permanents you control. Then you gain life equal to the number of creatures you control.| +Ferrafor, Young Yew|Lorwyn Eclipsed Commander|36|R|{6}{G}|Legendary Creature - Treefolk Druid|4|7|When Ferrafor enters, create a number of 1/1 green Saproling creature tokens equal to the number of counters among creatures target player controls.${T}: Double the number of each kind of counter on target creature.| +Jubilation|Lorwyn Eclipsed Commander|37|R|{5}{G}|Creature - Elemental Incarnation|5|5|When this creature enters, creatures you control get +2/+2 and gain trample until end of turn.$Encore {7}{G}{G}| +Puca's Covenant|Lorwyn Eclipsed Commander|38|R|{2}{G}|Enchantment|||Whenever a creature you control with a counter on it dies, you may return another target permanent card with mana value less than or equal to the number of counters on that creature from your graveyard to your hand. Do this only once each turn.| +Springleaf Parade|Lorwyn Eclipsed Commander|39|R|{G}{G}|Enchantment|||When this enchantment enters, create X 1/1 colorless Shapeshifter creature tokens with changeling.$Creature tokens you control have "{T}: Add one mana of any color."| +Dread Tiller|Lorwyn Eclipsed Commander|40|R|{1}{B}{G}|Artifact Creature - Scarecrow|2|4|When this creature enters, put a -1/-1 counter on target creature.$Whenever a creature with a -1/-1 counter on it dies, you may put a land card from your hand or graveyard onto the battlefield tapped.| +Wickersmith's Tools|Lorwyn Eclipsed Commander|41|R|{3}|Artifact|||Whenever one or more -1/-1 counters are put on a creature, put a charge counter on this artifact.${T}: Add one mana of any color.${5}, {T}, Sacrifice this artifact: Create X tapped 2/2 colorless Scarecrow artifact creature tokens, where X is the number of charge counters on this artifact.| +Abundant Countryside|Lorwyn Eclipsed Commander|42|R||Land|||{T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast a creature spell.${6}, {T}: Create a 1/1 colorless Shapeshifter creature token with changeling.| +Rain-Slicked Copse|Lorwyn Eclipsed Commander|43|R||Land - Forest Island|||({T}: Add {G} or {U}.)$This land enters tapped.$Cycling {2}| +Sodden Verdure|Lorwyn Eclipsed Commander|44|R||Land - Forest Island|||({T}: Add {G} or {U}.)$This land enters tapped unless you control two or more basic lands.| +Distant Melody|Lorwyn Eclipsed Commander|45|C|{3}{U}|Sorcery|||Choose a creature type. Draw a card for each permanent you control of that type.| +Blowfly Infestation|Lorwyn Eclipsed Commander|46|U|{2}{B}|Enchantment|||Whenever a creature dies, if it had a -1/-1 counter on it, put a -1/-1 counter on target creature.| +Hoarder's Greed|Lorwyn Eclipsed Commander|47|U|{3}{B}|Sorcery|||You lose 2 life and draw two cards, then clash with an opponent. If you win, repeat this process.| +Necroskitter|Lorwyn Eclipsed Commander|48|R|{1}{B}{B}|Creature - Elemental|1|4|Wither$Whenever a creature an opponent controls with a -1/-1 counter on it dies, you may return that card to the battlefield under your control.| +Tree of Perdition|Lorwyn Eclipsed Commander|49|M|{3}{B}|Creature - Plant|0|13|Defender${T}: Exchange target opponent's life total with this creature's toughness.| +Fury|Lorwyn Eclipsed Commander|50|M|{3}{R}{R}|Creature - Elemental Incarnation|3|3|Double strike$When this creature enters, it deals 4 damage divided as you choose among any number of target creatures and/or planeswalkers.$Evoke--Exile a red card from your hand.| +Endurance|Lorwyn Eclipsed Commander|51|M|{1}{G}{G}|Creature - Elemental Incarnation|3|4|Flash$Reach$When this creature enters, up to one target player puts all the cards from their graveyard on the bottom of their library in a random order.$Evoke--Exile a green card from your hand.| +Ignoble Hierarch|Lorwyn Eclipsed Commander|52|R|{G}|Creature - Goblin Shaman|0|1|Exalted${T}: Add {B}, {R}, or {G}.| +Faeburrow Elder|Lorwyn Eclipsed Commander|53|R|{1}{G}{W}|Creature - Treefolk Druid|0|0|Vigilance$This creature gets +1/+1 for each color among permanents you control.${T}: For each color among permanents you control, add one mana of that color.| +Fire Covenant|Lorwyn Eclipsed Commander|54|U|{1}{B}{R}|Instant|||As an additional cost to cast this spell, pay X life.$Fire Covenant deals X damage divided as you choose among any number of target creatures.| +Arcane Signet|Lorwyn Eclipsed Commander|55|U|{2}|Artifact|||{T}: Add one mana of any color in your commander's color identity.| +Arcane Signet|Lorwyn Eclipsed Commander|56|U|{2}|Artifact|||{T}: Add one mana of any color in your commander's color identity.| +Sol Ring|Lorwyn Eclipsed Commander|57|U|{1}|Artifact|||{T}: Add {C}{C}.| +Sol Ring|Lorwyn Eclipsed Commander|58|U|{1}|Artifact|||{T}: Add {C}{C}.| +Command Tower|Lorwyn Eclipsed Commander|59|C||Land|||{T}: Add one mana of any color in your commander's color identity.| +Command Tower|Lorwyn Eclipsed Commander|60|C||Land|||{T}: Add one mana of any color in your commander's color identity.| +Festering Thicket|Lorwyn Eclipsed Commander|61|R||Land - Swamp Forest|||({T}: Add {B} or {G}.)$This land enters tapped.$Cycling {2}| +Secluded Courtyard|Lorwyn Eclipsed Commander|62|U||Land|||As this land enters, choose a creature type.${T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast a creature spell of the chosen type or activate an ability of a creature source of the chosen type.| +Vernal Fen|Lorwyn Eclipsed Commander|63|R||Land - Swamp Forest|||({T}: Add {B} or {G}.)$This land enters tapped unless you control two or more basic lands.| +Hoofprints of the Stag|Lorwyn Eclipsed Commander|64|R|{1}{W}|Kindred Enchantment - Elemental|||Whenever you draw a card, you may put a hoofprint counter on this enchantment.${2}{W}, Remove four hoofprint counters from this enchantment: Create a 4/4 white Elemental creature token with flying. Activate only during your turn.| +Path to Exile|Lorwyn Eclipsed Commander|65|U|{W}|Instant|||Exile target creature. Its controller may search their library for a basic land card, put that card onto the battlefield tapped, then shuffle.| +Shatter the Sky|Lorwyn Eclipsed Commander|66|R|{2}{W}{W}|Sorcery|||Each player who controls a creature with power 4 or greater draws a card. Then destroy all creatures.| +Mulldrifter|Lorwyn Eclipsed Commander|67|U|{4}{U}|Creature - Elemental|2|2|Flying$When this creature enters, draw two cards.$Evoke {2}{U}| +Reality Shift|Lorwyn Eclipsed Commander|68|U|{1}{U}|Instant|||Exile target creature. Its controller manifests the top card of their library.| +Slithermuse|Lorwyn Eclipsed Commander|69|R|{2}{U}{U}|Creature - Elemental|3|3|When this creature leaves the battlefield, choose an opponent. If that player has more cards in hand than you, draw cards equal to the difference.$Evoke {3}{U}| +Archfiend of Ifnir|Lorwyn Eclipsed Commander|70|R|{3}{B}{B}|Creature - Demon|5|4|Flying$Whenever you cycle or discard another card, put a -1/-1 counter on each creature your opponents control.$Cycling {2}| +Black Sun's Zenith|Lorwyn Eclipsed Commander|71|R|{X}{B}{B}|Sorcery|||Put X -1/-1 counters on each creature. Shuffle Black Sun's Zenith into its owner's library.| +Carnifex Demon|Lorwyn Eclipsed Commander|72|R|{4}{B}{B}|Creature - Phyrexian Demon|6|6|Flying$This creature enters with two -1/-1 counters on it.${B}, Remove a -1/-1 counter from this creature: Put a -1/-1 counter on each other creature.| +Dusk Urchins|Lorwyn Eclipsed Commander|73|R|{2}{B}|Creature - Ouphe|4|3|Whenever this creature attacks or blocks, put a -1/-1 counter on it.$When this creature dies, draw a card for each -1/-1 counter on it.| +Grave Titan|Lorwyn Eclipsed Commander|74|M|{4}{B}{B}|Creature - Giant|6|6|Deathtouch$Whenever this creature enters or attacks, create two 2/2 black Zombie creature tokens.| +Haunting Voyage|Lorwyn Eclipsed Commander|75|M|{4}{B}{B}|Sorcery|||Choose a creature type. Return up to two creature cards of that type from your graveyard to the battlefield. If this spell was foretold, return all creature cards of that type from your graveyard to the battlefield instead.$Foretell {5}{B}{B}| +Incremental Blight|Lorwyn Eclipsed Commander|76|U|{3}{B}{B}|Sorcery|||Put a -1/-1 counter on target creature, two -1/-1 counters on another target creature, and three -1/-1 counters on a third target creature.| +Infernal Grasp|Lorwyn Eclipsed Commander|77|U|{1}{B}|Instant|||Destroy target creature. You lose 2 life.| +Liliana, Death Wielder|Lorwyn Eclipsed Commander|78|M|{5}{B}{B}|Legendary Planeswalker - Liliana|5|+2: Put a -1/-1 counter on up to one target creature.$-3: Destroy target creature with a -1/-1 counter on it.$-10: Return all creature cards from your graveyard to the battlefield.| +Massacre Girl, Known Killer|Lorwyn Eclipsed Commander|79|M|{2}{B}{B}|Legendary Creature - Human Assassin|4|4|Menace$Creatures you control have wither.$Whenever a creature an opponent controls dies, if its toughness was less than 1, draw a card.| +Midnight Banshee|Lorwyn Eclipsed Commander|80|R|{3}{B}{B}{B}|Creature - Spirit|5|5|Wither$At the beginning of your upkeep, put a -1/-1 counter on each nonblack creature.| +Night's Whisper|Lorwyn Eclipsed Commander|81|C|{1}{B}|Sorcery|||You draw two cards and lose 2 life.| +Painful Truths|Lorwyn Eclipsed Commander|82|R|{2}{B}|Sorcery|||Converge -- You draw X cards and lose X life, where X is the number of colors of mana spent to cast this spell.| +Persist|Lorwyn Eclipsed Commander|83|R|{1}{B}|Sorcery|||Return target nonlegendary creature card from your graveyard to the battlefield with a -1/-1 counter on it.| +Puppeteer Clique|Lorwyn Eclipsed Commander|84|R|{3}{B}{B}|Creature - Faerie Wizard|3|2|Flying$When this creature enters, put target creature card from an opponent's graveyard onto the battlefield under your control. It gains haste. At the beginning of your next end step, exile it.$Persist| +Shriekmaw|Lorwyn Eclipsed Commander|85|U|{4}{B}|Creature - Elemental|3|2|Fear$When this creature enters, destroy target nonartifact, nonblack creature.$Evoke {1}{B}| +Skinrender|Lorwyn Eclipsed Commander|86|U|{2}{B}{B}|Creature - Phyrexian Zombie|3|3|When this creature enters, put three -1/-1 counters on target creature.| +Soul Snuffers|Lorwyn Eclipsed Commander|87|U|{2}{B}{B}|Creature - Elemental Shaman|3|3|When this creature enters, put a -1/-1 counter on each creature.| +Vraska, Betrayal's Sting|Lorwyn Eclipsed Commander|88|M|{4}{B}{B/P}|Legendary Planeswalker - Vraska|6|Compleated$0: You draw a card and lose 1 life. Proliferate.$-2: Target creature becomes a Treasure artifact with "{T}, Sacrifice this artifact: Add one mana of any color" and loses all other card types and abilities.$-9: If target player has fewer than nine poison counters, they get a number of poison counters equal to the difference.| +Blasphemous Act|Lorwyn Eclipsed Commander|89|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.| +Cathartic Pyre|Lorwyn Eclipsed Commander|90|U|{1}{R}|Instant|||Choose one --$* Cathartic Pyre deals 3 damage to target creature or planeswalker.$* Discard up to two cards, then draw that many cards.| +Cathartic Reunion|Lorwyn Eclipsed Commander|91|C|{1}{R}|Sorcery|||As an additional cost to cast this spell, discard two cards.$Draw three cards.| +Chain Reaction|Lorwyn Eclipsed Commander|92|R|{2}{R}{R}|Sorcery|||Chain Reaction deals X damage to each creature, where X is the number of creatures on the battlefield.| +Descendants' Fury|Lorwyn Eclipsed Commander|93|R|{3}{R}|Enchantment|||Whenever one or more creatures you control deal combat damage to a player, you may sacrifice one of them. If you do, reveal cards from the top of your library until you reveal a creature card that shares a creature type with the sacrificed creature. Put that card onto the battlefield and the rest on the bottom of your library in a random order.| +Incandescent Soulstoke|Lorwyn Eclipsed Commander|94|U|{2}{R}|Creature - Elemental Shaman|2|2|Other Elemental creatures you control get +1/+1.${1}{R}, {T}: You may put an Elemental creature card from your hand onto the battlefield. That creature gains haste until end of turn. Sacrifice it at the beginning of the next end step.| +Ingot Chewer|Lorwyn Eclipsed Commander|95|C|{4}{R}|Creature - Elemental|3|3|When this creature enters, destroy target artifact.$Evoke {R}| +Smokebraider|Lorwyn Eclipsed Commander|96|C|{1}{R}|Creature - Elemental Shaman|1|1|{T}: Add two mana in any combination of colors. Spend this mana only to cast Elemental spells or activate abilities of Elementals.| +Abundant Growth|Lorwyn Eclipsed Commander|97|C|{G}|Enchantment - Aura|||Enchant land$When this Aura enters, draw a card.$Enchanted land has "{T}: Add one mana of any color."| +Avenger of Zendikar|Lorwyn Eclipsed Commander|98|M|{5}{G}{G}|Creature - Elemental|5|5|When this creature enters, create a 0/1 green Plant creature token for each land you control.$Landfall -- Whenever a land you control enters, you may put a +1/+1 counter on each Plant creature you control.| +Bane of Progress|Lorwyn Eclipsed Commander|99|R|{4}{G}{G}|Creature - Elemental|2|2|When this creature enters, destroy all artifacts and enchantments. Put a +1/+1 counter on this creature for each permanent destroyed this way.| +Cavalier of Thorns|Lorwyn Eclipsed Commander|100|M|{2}{G}{G}{G}|Creature - Elemental Knight|5|6|Reach$When this creature enters, reveal the top five cards of your library. Put a land card from among them onto the battlefield and the rest into your graveyard.$When this creature dies, you may exile it. If you do, put another target card from your graveyard on top of your library.| +Channeler Initiate|Lorwyn Eclipsed Commander|101|R|{1}{G}|Creature - Human Druid|3|4|When this creature enters, put three -1/-1 counters on target creature you control.${T}, Remove a -1/-1 counter from this creature: Add one mana of any color.| +Cream of the Crop|Lorwyn Eclipsed Commander|102|R|{1}{G}|Enchantment|||Whenever a creature you control enters, you may look at the top X cards of your library, where X is that creature's power. If you do, put one of those cards on top of your library and the rest on the bottom of your library in any order.| +Cultivate|Lorwyn Eclipsed Commander|103|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.| +Devoted Druid|Lorwyn Eclipsed Commander|104|U|{1}{G}|Creature - Elf Druid|0|2|{T}: Add {G}.$Put a -1/-1 counter on this creature: Untap this creature.| +Evolution Sage|Lorwyn Eclipsed Commander|105|U|{2}{G}|Creature - Elf Druid|3|2|Landfall -- Whenever a land you control enters, proliferate.| +Fertile Ground|Lorwyn Eclipsed Commander|106|C|{1}{G}|Enchantment - Aura|||Enchant land$Whenever enchanted land is tapped for mana, its controller adds an additional one mana of any color.| +Flourishing Defenses|Lorwyn Eclipsed Commander|107|U|{4}{G}|Enchantment|||Whenever a -1/-1 counter is put on a creature, you may create a 1/1 green Elf Warrior creature token.| +Foundation Breaker|Lorwyn Eclipsed Commander|108|U|{3}{G}|Creature - Elemental|2|2|When this creature enters, you may destroy target artifact or enchantment.$Evoke {1}{G}| +Garruk's Uprising|Lorwyn Eclipsed Commander|109|U|{2}{G}|Enchantment|||When this enchantment enters, if you control a creature with power 4 or greater, draw a card.$Creatures you control have trample.$Whenever a creature you control with power 4 or greater enters, draw a card.| +Greenwarden of Murasa|Lorwyn Eclipsed Commander|110|M|{4}{G}{G}|Creature - Elemental|5|4|When this creature enters, you may return target card from your graveyard to your hand.$When this creature dies, you may exile it. If you do, return target card from your graveyard to your hand.| +Harmonize|Lorwyn Eclipsed Commander|111|U|{2}{G}{G}|Sorcery|||Draw three cards.| +Kindred Summons|Lorwyn Eclipsed Commander|112|R|{5}{G}{G}|Instant|||Choose a creature type. Reveal cards from the top of your library until you reveal X creature cards of the chosen type, where X is the number of creatures you control of that type. Put those cards onto the battlefield, then shuffle the rest of the revealed cards into your library.| +Kodama's Reach|Lorwyn Eclipsed Commander|113|C|{2}{G}|Sorcery - Arcane|||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.| +Realmwalker|Lorwyn Eclipsed Commander|114|R|{2}{G}|Creature - Shapeshifter|2|3|Changeling$As this creature enters, choose a creature type.$You may look at the top card of your library any time.$You may cast creature spells of the chosen type from the top of your library.| +Return of the Wildspeaker|Lorwyn Eclipsed Commander|115|R|{4}{G}|Instant|||Choose one --$* Draw cards equal to the greatest power among non-Human creatures you control.$* Non-Human creatures you control get +3/+3 until end of turn.| +Selvala, Heart of the Wilds|Lorwyn Eclipsed Commander|116|M|{1}{G}{G}|Legendary Creature - Elf Scout|2|3|Whenever another creature enters, its controller may draw a card if its power is greater than each other creature's power.${G}, {T}: Add X mana in any combination of colors, where X is the greatest power among creatures you control.| +Titan of Industry|Lorwyn Eclipsed Commander|117|M|{4}{G}{G}{G}|Creature - Elemental|7|7|Reach, trample$When this creature enters, choose two --$* Destroy target artifact or enchantment.$* Target player gains 5 life.$* Create a 4/4 green Rhino Warrior creature token.$* Put a shield counter on a creature you control.| +Wickerbough Elder|Lorwyn Eclipsed Commander|118|C|{3}{G}|Creature - Treefolk Shaman|4|4|This creature enters with a -1/-1 counter on it.${G}, Remove a -1/-1 counter from this creature: Destroy target artifact or enchantment.| +Assassin's Trophy|Lorwyn Eclipsed Commander|119|R|{B}{G}|Instant|||Destroy target permanent an opponent controls. Its controller may search their library for a basic land card, put it onto the battlefield, then shuffle.| +Binding the Old Gods|Lorwyn Eclipsed Commander|120|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.| +Everlasting Torment|Lorwyn Eclipsed Commander|121|R|{2}{B/R}|Enchantment|||Players can't gain life.$Damage can't be prevented.$All damage is dealt as though its source had wither.| +Glissa Sunslayer|Lorwyn Eclipsed Commander|122|R|{1}{B}{G}|Legendary Creature - Phyrexian Zombie Elf|3|3|First strike, deathtouch$Whenever Glissa Sunslayer deals combat damage to a player, choose one --$* You draw a card and lose 1 life.$* Destroy target enchantment.$* Remove up to three counters from target permanent.| +Hapatra, Vizier of Poisons|Lorwyn Eclipsed Commander|123|R|{B}{G}|Legendary Creature - Human Cleric|2|2|Whenever Hapatra deals combat damage to a player, you may put a -1/-1 counter on target creature.$Whenever you put one or more -1/-1 counters on a creature, create a 1/1 green Snake creature token with deathtouch.| +Horde of Notions|Lorwyn Eclipsed Commander|124|R|{W}{U}{B}{R}{G}|Legendary Creature - Elemental|5|5|Vigilance, trample, haste${W}{U}{B}{R}{G}: You may play target Elemental card from your graveyard without paying its mana cost.| +Jegantha, the Wellspring|Lorwyn Eclipsed Commander|125|R|{4}{R/G}|Legendary Creature - Elemental Elk|5|5|Companion -- No card in your starting deck has more than one of the same mana symbol in its mana cost.${T}: Add {W}{U}{B}{R}{G}. This mana can't be spent to pay generic mana costs.| +Kulrath Knight|Lorwyn Eclipsed Commander|126|U|{3}{B/R}{B/R}|Creature - Elemental Knight|3|3|Flying$Wither$Creatures your opponents control with counters on them can't attack or block.| +Maelstrom Wanderer|Lorwyn Eclipsed Commander|127|R|{5}{G}{U}{R}|Legendary Creature - Elemental|7|5|Creatures you control have haste.$Cascade, cascade| +Muldrotha, the Gravetide|Lorwyn Eclipsed Commander|128|M|{3}{B}{G}{U}|Legendary Creature - Elemental Avatar|6|6|During each of your turns, you may play a land and cast a permanent spell of each permanent type from your graveyard.| +Omnath, Locus of Rage|Lorwyn Eclipsed Commander|129|M|{3}{R}{R}{G}{G}|Legendary Creature - Elemental|5|5|Landfall -- Whenever a land you control enters, create a 5/5 red and green Elemental creature token.$Whenever Omnath or another Elemental you control dies, Omnath deals 3 damage to any target.| +Omnath, Locus of the Roil|Lorwyn Eclipsed Commander|130|M|{1}{G}{U}{R}|Legendary Creature - Elemental|3|3|When Omnath enters, it deals damage to any target equal to the number of Elementals you control.$Landfall -- Whenever a land you control enters, put a +1/+1 counter on target Elemental you control. If you control eight or more lands, draw a card.| +Putrefy|Lorwyn Eclipsed Commander|131|U|{1}{B}{G}|Instant|||Destroy target artifact or creature. It can't be regenerated.| +Risen Reef|Lorwyn Eclipsed Commander|132|U|{1}{G}{U}|Creature - Elemental|1|1|Whenever this creature or another Elemental you control enters, look at the top card of your library. If it's a land card, you may put it onto the battlefield tapped. If you don't put the card onto the battlefield, put it into your hand.| +The Scorpion God|Lorwyn Eclipsed Commander|133|M|{3}{B}{R}|Legendary Creature - God|6|5|Whenever a creature with a -1/-1 counter on it dies, draw a card.${1}{B}{R}: Put a -1/-1 counter on another target creature.$When The Scorpion God dies, return it to its owner's hand at the beginning of the next end step.| +Terminate|Lorwyn Eclipsed Commander|134|C|{B}{R}|Instant|||Destroy target creature. It can't be regenerated.| +Vernal Sovereign|Lorwyn Eclipsed Commander|135|R|{4}{G}{W}|Creature - Elemental Elk|4|4|Whenever this creature enters or attacks, create a green and white Elemental creature token with "This token's power and toughness are each equal to the number of creatures you control."| +Yarok, the Desecrated|Lorwyn Eclipsed Commander|136|M|{2}{B}{G}{U}|Legendary Creature - Elemental Horror|3|5|Deathtouch, lifelink$If a permanent entering causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.| +Chimil, the Inner Sun|Lorwyn Eclipsed Commander|137|M|{6}|Legendary Artifact|||Spells you control can't be countered.$At the beginning of your end step, discover 5.| +Chromatic Lantern|Lorwyn Eclipsed Commander|138|R|{3}|Artifact|||Lands you control have "{T}: Add one mana of any color."${T}: Add one mana of any color.| +Commander's Sphere|Lorwyn Eclipsed Commander|139|C|{3}|Artifact|||{T}: Add one mana of any color in your commander's color identity.$Sacrifice this artifact: Draw a card.| +Contagion Clasp|Lorwyn Eclipsed Commander|140|U|{2}|Artifact|||When this artifact enters, put a -1/-1 counter on target creature.${4}, {T}: Proliferate.| +Fellwar Stone|Lorwyn Eclipsed Commander|141|U|{2}|Artifact|||{T}: Add one mana of any color that a land an opponent controls could produce.| +Grim Poppet|Lorwyn Eclipsed Commander|142|R|{7}|Artifact Creature - Scarecrow|4|4|This creature enters with three -1/-1 counters on it.$Remove a -1/-1 counter from this creature: Put a -1/-1 counter on another target creature.| +Timeless Lotus|Lorwyn Eclipsed Commander|143|M|{5}|Legendary Artifact|||Timeless Lotus enters tapped.${T}: Add {W}{U}{B}{R}{G}.| +Ancient Ziggurat|Lorwyn Eclipsed Commander|144|U||Land|||{T}: Add one mana of any color. Spend this mana only to cast a creature spell.| +Canyon Slough|Lorwyn Eclipsed Commander|145|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$This land enters tapped.$Cycling {2}| +Cinder Glade|Lorwyn Eclipsed Commander|146|R||Land - Mountain Forest|||({T}: Add {R} or {G}.)$This land enters tapped unless you control two or more basic lands.| +Dragonskull Summit|Lorwyn Eclipsed Commander|147|R||Land|||This land enters tapped unless you control a Swamp or a Mountain.${T}: Add {B} or {R}.| +Exotic Orchard|Lorwyn Eclipsed Commander|148|R||Land|||{T}: Add one mana of any color that a land an opponent controls could produce.| +Flamekin Village|Lorwyn Eclipsed Commander|149|R||Land|||As this land enters, you may reveal an Elemental card from your hand. If you don't, this land enters tapped.${T}: Add {R}.${R}, {T}: Target creature gains haste until end of turn.| +Frontier Bivouac|Lorwyn Eclipsed Commander|150|U||Land|||This land enters tapped.${T}: Add {G}, {U}, or {R}.| +Golgari Rot Farm|Lorwyn Eclipsed Commander|151|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {B}{G}.| +Gruul Turf|Lorwyn Eclipsed Commander|152|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {R}{G}.| +Ifnir Deadlands|Lorwyn Eclipsed Commander|153|U||Land - Desert|||{T}: Add {C}.${T}, Pay 1 life: Add {B}.${2}{B}{B}, {T}, Sacrifice a Desert: Put two -1/-1 counters on target creature an opponent controls. Activate only as a sorcery.| +Jungle Shrine|Lorwyn Eclipsed Commander|154|U||Land|||This land enters tapped.${T}: Add {R}, {G}, or {W}.| +Nesting Grounds|Lorwyn Eclipsed Commander|155|R||Land|||{T}: Add {C}.${1}, {T}: Move a counter from target permanent you control onto a second target permanent. Activate only as a sorcery.| +Opal Palace|Lorwyn Eclipsed Commander|156|C||Land|||{T}: Add {C}.${1}, {T}: Add one mana of any color in your commander's color identity. If you spend this mana to cast your commander, it enters with a number of additional +1/+1 counters on it equal to the number of times it's been cast from the command zone this game.| +Opulent Palace|Lorwyn Eclipsed Commander|157|U||Land|||This land enters tapped.${T}: Add {B}, {G}, or {U}.| +Path of Ancestry|Lorwyn Eclipsed Commander|158|C||Land|||This land enters tapped.${T}: Add one mana of any color in your commander's color identity. When that mana is spent to cast a creature spell that shares a creature type with your commander, scry 1.| +Primal Beyond|Lorwyn Eclipsed Commander|159|R||Land|||As this land enters, you may reveal an Elemental card from your hand. If you don't, this land enters tapped.${T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast an Elemental spell or activate an ability of an Elemental.| +Raging Ravine|Lorwyn Eclipsed Commander|160|R||Land|||This land enters tapped.${T}: Add {R} or {G}.${2}{R}{G}: Until end of turn, this land becomes a 3/3 red and green Elemental creature with "Whenever this creature attacks, put a +1/+1 counter on it." It's still a land.| +Rakdos Carnarium|Lorwyn Eclipsed Commander|161|U||Land|||This land enters tapped.$When this land enters, return a land you control to its owner's hand.${T}: Add {B}{R}.| +Riveteers Overlook|Lorwyn Eclipsed Commander|162|C||Land|||When this land enters, sacrifice it. When you do, search your library for a basic Swamp, Mountain, or Forest card, put it onto the battlefield tapped, then shuffle and you gain 1 life.| +Rootbound Crag|Lorwyn Eclipsed Commander|163|R||Land|||This land enters tapped unless you control a Mountain or a Forest.${T}: Add {R} or {G}.| +Sandsteppe Citadel|Lorwyn Eclipsed Commander|164|U||Land|||This land enters tapped.${T}: Add {W}, {B}, or {G}.| +Savage Lands|Lorwyn Eclipsed Commander|165|U||Land|||This land enters tapped.${T}: Add {B}, {R}, or {G}.| +Seaside Citadel|Lorwyn Eclipsed Commander|166|U||Land|||This land enters tapped.${T}: Add {G}, {W}, or {U}.| +Sheltered Thicket|Lorwyn Eclipsed Commander|167|R||Land - Mountain Forest|||({T}: Add {R} or {G}.)$This land enters tapped.$Cycling {2}| +Smoldering Marsh|Lorwyn Eclipsed Commander|168|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$This land enters tapped unless you control two or more basic lands.| +Terramorphic Expanse|Lorwyn Eclipsed Commander|169|C||Land|||{T}, Sacrifice this land: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.| +Thriving Bluff|Lorwyn Eclipsed Commander|170|C||Land|||This land enters tapped. As it enters, choose a color other than red.${T}: Add {R} or one mana of the chosen color.| +Thriving Grove|Lorwyn Eclipsed Commander|171|C||Land|||This land enters tapped. As it enters, choose a color other than green.${T}: Add {G} or one mana of the chosen color.| +Thriving Heath|Lorwyn Eclipsed Commander|172|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|Lorwyn Eclipsed Commander|173|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|Lorwyn Eclipsed Commander|174|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.| +Unclaimed Territory|Lorwyn Eclipsed Commander|175|U||Land|||As this land enters, choose a creature type.${T}: Add {C}.${T}: Add one mana of any color. Spend this mana only to cast a creature spell of the chosen type.| +Woodland Cemetery|Lorwyn Eclipsed Commander|176|R||Land|||This land enters tapped unless you control a Swamp or a Forest.${T}: Add {B} or {G}.| diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index ba5e1cb23de..e946cab0e60 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -140,6 +140,7 @@ Ikoria: Lair of Behemoths|IKO| Invasion|INV| Innistrad|ISD| Lorwyn Eclipsed|ECL| +Lorwyn Eclipsed Commander|ECC| The Lost Caverns of Ixalan|LCI| The Lost Caverns of Ixalan Commander|LCC| Innistrad: Midnight Hunt|MID| @@ -178,6 +179,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|