diff --git a/Mage.Common/src/main/java/mage/remote/SessionImpl.java b/Mage.Common/src/main/java/mage/remote/SessionImpl.java index c1ed457c5d2..1a777ed2355 100644 --- a/Mage.Common/src/main/java/mage/remote/SessionImpl.java +++ b/Mage.Common/src/main/java/mage/remote/SessionImpl.java @@ -505,6 +505,7 @@ public class SessionImpl implements Session { } if (t.toString().contains("to make private")) { // example: Unable to make private void java.io.ObjectOutputStream.clear() accessible: module java.base does not "opens java.io" to unnamed module + // TODO: show that error as error dialog, so users can report to github message = "Wrong java version - check your client running scripts and params." + message; break; } @@ -512,6 +513,17 @@ public class SessionImpl implements Session { message = '\n' + t.getCause().getMessage() + message; logger.debug(t.getCause().getMessage()); } + + if (t.getCause() == null) { + // last chance to find real reason + if (Arrays.stream(t.getStackTrace()).anyMatch(stack -> Objects.equals("ObjectInputStream.java", stack.getFileName()))) { + // how-to fix: non-standard java version require additional params, see https://github.com/magefree/mage/issues/12768 + // TODO: show that error as error dialog, so users can report to github + message = "Wrong client-server protocol - report to server's admin about compatibility problems. " + message; + break; + } + } + t = t.getCause(); } client.showMessage("Unable connect to server. " + message); diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index 25a7d7540fe..01e7b642b81 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -282,7 +282,7 @@ public class HumanPlayer extends PlayerImpl { return; } if (logger.isDebugEnabled()) { - logger.debug("Setting game priority for " + getId() + " [" + DebugUtil.getMethodNameWithSource(2) + ']'); + logger.debug("Setting game priority for " + getId() + " [" + DebugUtil.getMethodNameWithSource(1) + ']'); } game.getState().setPriorityPlayerId(getId()); } @@ -313,7 +313,7 @@ public class HumanPlayer extends PlayerImpl { while (loop) { // start waiting for next answer response.clear(); - response.setActiveAction(game, DebugUtil.getMethodNameWithSource(2)); + response.setActiveAction(game, DebugUtil.getMethodNameWithSource(1)); game.resumeTimer(getTurnControlledBy()); responseOpenedForAnswer = true; diff --git a/Mage.Sets/src/mage/cards/a/AbhorrentOculus.java b/Mage.Sets/src/mage/cards/a/AbhorrentOculus.java index e318c452ab8..3d1ae7b37c0 100644 --- a/Mage.Sets/src/mage/cards/a/AbhorrentOculus.java +++ b/Mage.Sets/src/mage/cards/a/AbhorrentOculus.java @@ -29,7 +29,7 @@ public final class AbhorrentOculus extends CardImpl { // As an additional cost to cast this spell, exile six cards from your graveyard. this.getSpellAbility().addCost(new ExileFromGraveCost( - new TargetCardInYourGraveyard(StaticFilters.FILTER_CARDS_FROM_YOUR_GRAVEYARD) + new TargetCardInYourGraveyard(6, StaticFilters.FILTER_CARDS_FROM_YOUR_GRAVEYARD) )); // Flying diff --git a/Mage.Sets/src/mage/cards/a/Adrestia.java b/Mage.Sets/src/mage/cards/a/Adrestia.java new file mode 100644 index 00000000000..86f4638d9c7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/Adrestia.java @@ -0,0 +1,146 @@ +package mage.cards.a; + +import java.util.*; + +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.hint.ConditionHint; +import mage.abilities.hint.Hint; +import mage.constants.*; +import mage.abilities.keyword.IslandwalkAbility; +import mage.abilities.keyword.CrewAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +/** + * + * @author Grath + */ +public final class Adrestia extends CardImpl { + + private static final Condition condition = AdrestiaCondition.instance; + + public Adrestia(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.VEHICLE); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Islandwalk + this.addAbility(new IslandwalkAbility()); + + // Whenever Adrestia attacks, if an Assassin crewed it this turn, draw a card. Adrestia becomes an Assassin in addition to its other types until end of turn. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility(new DrawCardSourceControllerEffect(1), false), + condition, "Whenever Adrestia attacks, if an Assassin crewed it this turn, draw a card. Adrestia becomes an Assassin in addition to its other types until end of turn."); + ability.addEffect(new AdrestiaEffect()); + ability.addHint(AdrestiaCondition.getHint()); + this.addAbility(ability, new AdrestiaWatcher()); + + // Crew 1 + this.addAbility(new CrewAbility(1)); + + } + + private Adrestia(final Adrestia card) { + super(card); + } + + @Override + public Adrestia copy() { + return new Adrestia(this); + } +} + +class AdrestiaEffect extends ContinuousEffectImpl { + + public AdrestiaEffect() { + super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + } + + protected AdrestiaEffect(final AdrestiaEffect effect) { + super(effect); + } + + @Override + public AdrestiaEffect copy() { + return new AdrestiaEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + permanent.addSubType(game, SubType.ASSASSIN); + return true; + } +} + +enum AdrestiaCondition implements Condition { + instance; + private static final Hint hint = new ConditionHint(instance, "an Assassin crewed it this turn"); + + @Override + public boolean apply(Game game, Ability source) { + return AdrestiaWatcher.checkIfAssassinCrewed(source.getSourcePermanentOrLKI(game), game); + } + + public static Hint getHint() { + return hint; + } +} + +class AdrestiaWatcher extends Watcher { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.ASSASSIN, "an Assassin"); + private final Map crewMap = new HashMap<>(); + + public AdrestiaWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.CREWED_VEHICLE) { + MageObjectReference vehicle = new MageObjectReference(event.getSourceId(), game); + Permanent crewer = game.getPermanentOrLKIBattlefield(event.getTargetId()); + if (crewer != null) { + if (!crewMap.containsKey(vehicle)) { + crewMap.put(vehicle, filter.match(crewer, game)); + } + else { + crewMap.put(vehicle, crewMap.get(vehicle) || filter.match(crewer, game)); + } + } + } + } + + @Override + public void reset() { + super.reset(); + crewMap.clear(); + } + + public static boolean checkIfAssassinCrewed(Permanent vehicle, Game game) { + return game + .getState() + .getWatcher(AdrestiaWatcher.class) + .crewMap + .getOrDefault(new MageObjectReference(vehicle, game), Boolean.FALSE); + } +} diff --git a/Mage.Sets/src/mage/cards/a/AltanakTheThriceCalled.java b/Mage.Sets/src/mage/cards/a/AltanakTheThriceCalled.java index f409438d279..66c2ab87934 100644 --- a/Mage.Sets/src/mage/cards/a/AltanakTheThriceCalled.java +++ b/Mage.Sets/src/mage/cards/a/AltanakTheThriceCalled.java @@ -16,6 +16,7 @@ import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.StaticFilters; +import mage.filter.common.FilterLandCard; import mage.target.common.TargetCardInYourGraveyard; import java.util.UUID; @@ -25,6 +26,8 @@ import java.util.UUID; */ public final class AltanakTheThriceCalled extends CardImpl { + private static final FilterLandCard filter = new FilterLandCard("land card from your graveyard"); + public AltanakTheThriceCalled(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); @@ -47,7 +50,7 @@ public final class AltanakTheThriceCalled extends CardImpl { Zone.HAND, new ReturnFromGraveyardToBattlefieldTargetEffect(true), new ManaCostsImpl<>("{1}{G}") ); ability.addCost(new DiscardSourceCost()); - ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_LAND)); + ability.addTarget(new TargetCardInYourGraveyard(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/ArabellaAbandonedDoll.java b/Mage.Sets/src/mage/cards/a/ArabellaAbandonedDoll.java index 56ed1e66ca7..eb91e0f31e3 100644 --- a/Mage.Sets/src/mage/cards/a/ArabellaAbandonedDoll.java +++ b/Mage.Sets/src/mage/cards/a/ArabellaAbandonedDoll.java @@ -11,11 +11,10 @@ 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.constants.*; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.PowerPredicate; import java.util.UUID; @@ -24,9 +23,12 @@ import java.util.UUID; */ public final class ArabellaAbandonedDoll extends CardImpl { - private static final DynamicValue xValue = new PermanentsOnBattlefieldCount( - new FilterControlledCreaturePermanent("creatures you control with power 2 or less"), null - ); + private static final FilterPermanent filter = new FilterControlledCreaturePermanent("creatures you control with power 2 or less"); + static { + filter.add(new PowerPredicate(ComparisonType.OR_LESS, 2)); + } + + private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter, 1); private static final Hint hint = new ValueHint("Creatures you control with power 2 or less", xValue); public ArabellaAbandonedDoll(UUID ownerId, CardSetInfo setInfo) { @@ -42,7 +44,7 @@ public final class ArabellaAbandonedDoll extends CardImpl { new DamagePlayersEffect(xValue, TargetController.OPPONENT) .setText("it deals X damage to each opponent") ); - ability.addEffect(new GainLifeEffect(xValue)); + ability.addEffect(new GainLifeEffect(xValue).setText("and you gain X life, where X is the number of creatures you control with power 2 or less")); this.addAbility(ability.addHint(hint)); } diff --git a/Mage.Sets/src/mage/cards/a/AvelineDeGrandpre.java b/Mage.Sets/src/mage/cards/a/AvelineDeGrandpre.java new file mode 100644 index 00000000000..c04d54c072e --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AvelineDeGrandpre.java @@ -0,0 +1,111 @@ +package mage.cards.a; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.DisguiseAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author Grath + */ +public final class AvelineDeGrandpre extends CardImpl { + + public AvelineDeGrandpre(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Whenever a creature you control with deathtouch deals combat damage to a player, put that many +1/+1 counters on that creature. + this.addAbility(new AvelineDeGrandpreTriggeredAbility()); + + // Disguise {B}{G} + this.addAbility(new DisguiseAbility(this, new ManaCostsImpl<>("{B}{G}"))); + + } + + private AvelineDeGrandpre(final AvelineDeGrandpre card) { + super(card); + } + + @Override + public AvelineDeGrandpre copy() { + return new AvelineDeGrandpre(this); + } +} + +class AvelineDeGrandpreTriggeredAbility extends TriggeredAbilityImpl { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("a creature you control with deathtouch"); + + static { + filter.add(new AbilityPredicate(DeathtouchAbility.class)); + } + + public AvelineDeGrandpreTriggeredAbility() { + // Copied from Necropolis Regent, I don't know why QUEST counters. + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.QUEST.createInstance()), false); + } + + private AvelineDeGrandpreTriggeredAbility(final AvelineDeGrandpreTriggeredAbility ability) { + super(ability); + } + + @Override + public AvelineDeGrandpreTriggeredAbility copy() { + return new AvelineDeGrandpreTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (((DamagedPlayerEvent) event).isCombatDamage()) { + Permanent creature = game.getPermanent(event.getSourceId()); + if (creature != null && creature.isControlledBy(controllerId) && filter.match(creature, game)) { + this.getEffects().clear(); + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(event.getAmount())); + effect.setTargetPointer(new FixedTarget(creature.getId(), game)); + this.addEffect(effect); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a creature you control with deathtouch deals combat damage to a player, put that many +1/+1 counters on it."; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/BalustradeWurm.java b/Mage.Sets/src/mage/cards/b/BalustradeWurm.java index 61d168fa705..320e73ec35f 100644 --- a/Mage.Sets/src/mage/cards/b/BalustradeWurm.java +++ b/Mage.Sets/src/mage/cards/b/BalustradeWurm.java @@ -2,6 +2,7 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.common.CantBeCounteredSourceAbility; import mage.abilities.condition.common.DeliriumCondition; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldWithCounterEffect; @@ -28,6 +29,8 @@ public final class BalustradeWurm extends CardImpl { this.toughness = new MageInt(5); // This spell can't be countered. + this.addAbility(new CantBeCounteredSourceAbility()); + // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/b/Bamboozle.java b/Mage.Sets/src/mage/cards/b/Bamboozle.java index f5c798e0558..96b9e5aadd5 100644 --- a/Mage.Sets/src/mage/cards/b/Bamboozle.java +++ b/Mage.Sets/src/mage/cards/b/Bamboozle.java @@ -75,7 +75,7 @@ class BamboozleEffect extends OneShotEffect { putOnTopLibrary.remove(game.getCard(cardId)); } targetPlayer.moveCards(putInGraveyard, Zone.GRAVEYARD, source, game); - targetPlayer.putCardsOnTopOfLibrary(putOnTopLibrary, game, source, false); + targetPlayer.putCardsOnTopOfLibrary(putOnTopLibrary, game, source, true); return true; } diff --git a/Mage.Sets/src/mage/cards/b/BarbedFoliage.java b/Mage.Sets/src/mage/cards/b/BarbedFoliage.java index 03f5b378003..8be9d1d6656 100644 --- a/Mage.Sets/src/mage/cards/b/BarbedFoliage.java +++ b/Mage.Sets/src/mage/cards/b/BarbedFoliage.java @@ -9,6 +9,7 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; @@ -32,7 +33,7 @@ public final class BarbedFoliage extends CardImpl { // Whenever a creature attacks you, it loses flanking until end of turn. this.addAbility(new AttackedByCreatureTriggeredAbility( - new LoseAbilityTargetEffect(new FlankingAbility()) + new LoseAbilityTargetEffect(new FlankingAbility(), Duration.EndOfTurn) .setText("it loses flanking until end of turn"), false, SetTargetPointer.PERMANENT )); diff --git a/Mage.Sets/src/mage/cards/b/BedheadBeastie.java b/Mage.Sets/src/mage/cards/b/BedheadBeastie.java new file mode 100644 index 00000000000..deb5a0dd8d7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BedheadBeastie.java @@ -0,0 +1,41 @@ +package mage.cards.b; + +import mage.MageInt; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.MenaceAbility; +import mage.abilities.keyword.MountaincyclingAbility; +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 BedheadBeastie extends CardImpl { + + public BedheadBeastie(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + + this.subtype.add(SubType.BEAST); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Menace + this.addAbility(new MenaceAbility()); + + // Mountaincycling {2} + this.addAbility(new MountaincyclingAbility(new ManaCostsImpl<>("{2}"))); + } + + private BedheadBeastie(final BedheadBeastie card) { + super(card); + } + + @Override + public BedheadBeastie copy() { + return new BedheadBeastie(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/Broodspinner.java b/Mage.Sets/src/mage/cards/b/Broodspinner.java index 638644dbff2..5300633bb6b 100644 --- a/Mage.Sets/src/mage/cards/b/Broodspinner.java +++ b/Mage.Sets/src/mage/cards/b/Broodspinner.java @@ -16,7 +16,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.game.permanent.token.IzoniInsectToken; +import mage.game.permanent.token.InsectBlackGreenFlyingToken; import java.util.UUID; @@ -40,8 +40,9 @@ public final class Broodspinner extends CardImpl { // {4}{B}{G}, {T}, Sacrifice Broodspinner: Create a number of 1/1 black and green Insect creature tokens with flying equal to the number of card types among cards in your graveyard. Ability ability = new SimpleActivatedAbility(new CreateTokenEffect( - new IzoniInsectToken(), CardTypesInGraveyardCount.YOU - ), new ManaCostsImpl<>("{4}{B}{G}")); + new InsectBlackGreenFlyingToken(), CardTypesInGraveyardCount.YOU + ).setText("create a number of 1/1 black and green Insect creature tokens with flying equal to the number of card types among cards in your graveyard"), + new ManaCostsImpl<>("{4}{B}{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability.addHint(CardTypesInGraveyardHint.YOU)); diff --git a/Mage.Sets/src/mage/cards/c/CacklingSlasher.java b/Mage.Sets/src/mage/cards/c/CacklingSlasher.java new file mode 100644 index 00000000000..eb7fbfa81ca --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CacklingSlasher.java @@ -0,0 +1,48 @@ +package mage.cards.c; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.MorbidCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.hint.common.MorbidHint; +import mage.abilities.keyword.DeathtouchAbility; +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 CacklingSlasher extends CardImpl { + + public CacklingSlasher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Cackling Slasher enters with a +1/+1 counter on it if a creature died this turn. + this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), MorbidCondition.instance, "" + ), "with a +1/+1 counter on it if a creature died this turn").addHint(MorbidHint.instance)); + } + + private CacklingSlasher(final CacklingSlasher card) { + super(card); + } + + @Override + public CacklingSlasher copy() { + return new CacklingSlasher(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/CaduceusStaffOfHermes.java b/Mage.Sets/src/mage/cards/c/CaduceusStaffOfHermes.java index c1ba0d65c32..414cd73e90d 100644 --- a/Mage.Sets/src/mage/cards/c/CaduceusStaffOfHermes.java +++ b/Mage.Sets/src/mage/cards/c/CaduceusStaffOfHermes.java @@ -48,7 +48,7 @@ public final class CaduceusStaffOfHermes extends CardImpl { new PreventDamageToSourceEffect(Duration.WhileOnBattlefield, Integer.MAX_VALUE) .setText("Prevent all damage that would be dealt to this creature") ), AttachmentType.EQUIPMENT), condition, - "and has \"Prevent all damage that would be dealt to this creature.\"" + "and \"Prevent all damage that would be dealt to this creature.\"" )); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/ClockworkPercussionist.java b/Mage.Sets/src/mage/cards/c/ClockworkPercussionist.java index 9138006153b..854bc36feff 100644 --- a/Mage.Sets/src/mage/cards/c/ClockworkPercussionist.java +++ b/Mage.Sets/src/mage/cards/c/ClockworkPercussionist.java @@ -29,7 +29,8 @@ public final class ClockworkPercussionist extends CardImpl { this.addAbility(HasteAbility.getInstance()); // When Clockwork Percussionist dies, exile the top card of your library. You may play it until the end of your next turn. - this.addAbility(new DiesSourceTriggeredAbility(new ExileTopXMayPlayUntilEffect(1, Duration.UntilEndOfYourNextTurn))); + this.addAbility(new DiesSourceTriggeredAbility(new ExileTopXMayPlayUntilEffect(1, Duration.UntilEndOfYourNextTurn) + .withTextOptions("it", true))); } private ClockworkPercussionist(final ClockworkPercussionist card) { diff --git a/Mage.Sets/src/mage/cards/c/ConvertToSlime.java b/Mage.Sets/src/mage/cards/c/ConvertToSlime.java new file mode 100644 index 00000000000..f41238df2af --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConvertToSlime.java @@ -0,0 +1,84 @@ +package mage.cards.c; + +import mage.abilities.Ability; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.OozeToken; +import mage.target.common.TargetArtifactPermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetEnchantmentPermanent; +import mage.target.targetpointer.EachTargetPointer; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ConvertToSlime extends CardImpl { + + public ConvertToSlime(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{G}"); + + // 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. + this.getSpellAbility().addEffect(new ConvertToSlimeEffect()); + this.getSpellAbility().addTarget(new TargetArtifactPermanent(0, 1)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1)); + this.getSpellAbility().addTarget(new TargetEnchantmentPermanent(0, 1)); + this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU); + } + + private ConvertToSlime(final ConvertToSlime card) { + super(card); + } + + @Override + public ConvertToSlime copy() { + return new ConvertToSlime(this); + } +} + +class ConvertToSlimeEffect extends OneShotEffect { + + ConvertToSlimeEffect() { + super(Outcome.Benefit); + staticText = "destroy up to one target artifact, up to one target creature, " + + "and up to one target enchantment.
" + AbilityWord.DELIRIUM.formatWord() + + "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."; + this.setTargetPointer(new EachTargetPointer()); + } + + private ConvertToSlimeEffect(final ConvertToSlimeEffect effect) { + super(effect); + } + + @Override + public ConvertToSlimeEffect copy() { + return new ConvertToSlimeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int total = 0; + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null && permanent.destroy(source, game)) { + total += permanent.getManaValue(); + } + } + game.processAction(); + if (DeliriumCondition.instance.apply(game, source)) { + new OozeToken(total, total).putOntoBattlefield(1, game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/c/CynicalLoner.java b/Mage.Sets/src/mage/cards/c/CynicalLoner.java index abff97e3ff3..de39d75ac90 100644 --- a/Mage.Sets/src/mage/cards/c/CynicalLoner.java +++ b/Mage.Sets/src/mage/cards/c/CynicalLoner.java @@ -33,7 +33,7 @@ public final class CynicalLoner extends CardImpl { this.addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); // Survival -- At the beginning of your second main phase, if Cynical Loner is tapped, you may search your library for a card, put it into your graveyard, then shuffle. - this.addAbility(new SurvivalAbility(new SearchLibraryPutInGraveyardEffect(false))); + this.addAbility(new SurvivalAbility(new SearchLibraryPutInGraveyardEffect(false), true)); } private CynicalLoner(final CynicalLoner card) { diff --git a/Mage.Sets/src/mage/cards/d/DelugeOfDoom.java b/Mage.Sets/src/mage/cards/d/DelugeOfDoom.java new file mode 100644 index 00000000000..a8cf96890c3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DelugeOfDoom.java @@ -0,0 +1,39 @@ +package mage.cards.d; + +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount; +import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +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 DelugeOfDoom extends CardImpl { + + private static final DynamicValue xValue = new SignInversionDynamicValue(CardTypesInGraveyardCount.YOU); + + public DelugeOfDoom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); + + // All creatures get -X/-X until end of turn, where X is the number of card types among cards in your graveyard. + this.getSpellAbility().addEffect(new BoostAllEffect(xValue, xValue, Duration.EndOfTurn) + .setText("all creatures get -X/-X until end of turn, where X is the number of card types among cards in your graveyard")); + this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU); + } + + private DelugeOfDoom(final DelugeOfDoom card) { + super(card); + } + + @Override + public DelugeOfDoom copy() { + return new DelugeOfDoom(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DemolisherSpawn.java b/Mage.Sets/src/mage/cards/d/DemolisherSpawn.java new file mode 100644 index 00000000000..4a236b49b07 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DemolisherSpawn.java @@ -0,0 +1,57 @@ +package mage.cards.d; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DemolisherSpawn extends CardImpl { + + public DemolisherSpawn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{5}{G}{G}"); + + this.subtype.add(SubType.HORROR); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // 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. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new AttacksTriggeredAbility(new BoostAllEffect( + 4, 4, Duration.EndOfTurn, + StaticFilters.FILTER_ATTACKING_CREATURES, true + )), DeliriumCondition.instance, "Whenever {this} attacks, if there are four or more " + + "card types among cards in your graveyard, other attacking creatures get +4/+4 until end of turn." + ).setAbilityWord(AbilityWord.DELIRIUM).addHint(CardTypesInGraveyardHint.YOU)); + } + + private DemolisherSpawn(final DemolisherSpawn card) { + super(card); + } + + @Override + public DemolisherSpawn copy() { + return new DemolisherSpawn(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DissectionTools.java b/Mage.Sets/src/mage/cards/d/DissectionTools.java new file mode 100644 index 00000000000..df90c072f42 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DissectionTools.java @@ -0,0 +1,60 @@ +package mage.cards.d; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.effects.common.ManifestDreadThenAttachEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.LifelinkAbility; +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.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class DissectionTools extends CardImpl { + + public DissectionTools(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); + + this.subtype.add(SubType.EQUIPMENT); + + // When Dissection Tools enters, manifest dread, then attach Dissection Tools to that creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ManifestDreadThenAttachEffect())); + + // Equipped creature gets +2/+2 and has deathtouch and lifelink. + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + DeathtouchAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and has deathtouch")); + ability.addEffect(new GainAbilityAttachedEffect( + LifelinkAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText("and lifelink")); + this.addAbility(ability); + + // Equip--Sacrifice a creature. + this.addAbility(new EquipAbility( + Outcome.BoostCreature, new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_A_CREATURE) + )); + } + + private DissectionTools(final DissectionTools card) { + super(card); + } + + @Override + public DissectionTools copy() { + return new DissectionTools(this); + } +} diff --git a/Mage.Sets/src/mage/cards/d/DiversionSpecialist.java b/Mage.Sets/src/mage/cards/d/DiversionSpecialist.java index 0a40c60a35a..f2f64e9eaf3 100644 --- a/Mage.Sets/src/mage/cards/d/DiversionSpecialist.java +++ b/Mage.Sets/src/mage/cards/d/DiversionSpecialist.java @@ -33,7 +33,8 @@ public final class DiversionSpecialist extends CardImpl { this.addAbility(new MenaceAbility()); // {1}, Sacrifice another creature or enchantment: Exile the top card of your library. You may play it this turn. - Ability ability = new SimpleActivatedAbility(new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn), new GenericManaCost(1)); + Ability ability = new SimpleActivatedAbility(new ExileTopXMayPlayUntilEffect(1, Duration.EndOfTurn) + .withTextOptions("it", true), new GenericManaCost(1)); ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ANOTHER_CREATURE_OR_ENCHANTMENT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DuskmournsDomination.java b/Mage.Sets/src/mage/cards/d/DuskmournsDomination.java index 0527f725ddd..02d421b0a3c 100644 --- a/Mage.Sets/src/mage/cards/d/DuskmournsDomination.java +++ b/Mage.Sets/src/mage/cards/d/DuskmournsDomination.java @@ -31,7 +31,7 @@ public final class DuskmournsDomination extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); this.addAbility(new EnchantAbility(auraTarget)); // You control enchanted creature. diff --git a/Mage.Sets/src/mage/cards/e/EntityTracker.java b/Mage.Sets/src/mage/cards/e/EntityTracker.java new file mode 100644 index 00000000000..83af38133bf --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/EntityTracker.java @@ -0,0 +1,42 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.abilityword.EerieAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class EntityTracker extends CardImpl { + + public EntityTracker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SCOUT); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flash + this.addAbility(FlashAbility.getInstance()); + + // Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, draw a card. + this.addAbility(new EerieAbility(new DrawCardSourceControllerEffect(1))); + } + + private EntityTracker(final EntityTracker card) { + super(card); + } + + @Override + public EntityTracker copy() { + return new EntityTracker(this); + } +} diff --git a/Mage.Sets/src/mage/cards/e/ErraticApparition.java b/Mage.Sets/src/mage/cards/e/ErraticApparition.java new file mode 100644 index 00000000000..41db917205a --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ErraticApparition.java @@ -0,0 +1,46 @@ +package mage.cards.e; + +import mage.MageInt; +import mage.abilities.abilityword.EerieAbility; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +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.Duration; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ErraticApparition extends CardImpl { + + public ErraticApparition(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); + + this.subtype.add(SubType.SPIRIT); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, Erratic Apparition gets +1/+1 until end of turn. + this.addAbility(new EerieAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn))); + } + + private ErraticApparition(final ErraticApparition card) { + super(card); + } + + @Override + public ErraticApparition copy() { + return new ErraticApparition(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FearOfExposure.java b/Mage.Sets/src/mage/cards/f/FearOfExposure.java new file mode 100644 index 00000000000..c4300d5908b --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FearOfExposure.java @@ -0,0 +1,55 @@ +package mage.cards.f; + +import mage.MageInt; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class FearOfExposure extends CardImpl { + + private static final FilterControlledPermanent filter + = new FilterControlledPermanent("untapped creatures and/or lands you control"); + + static { + filter.add(TappedPredicate.UNTAPPED); + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.LAND.getPredicate() + )); + } + + public FearOfExposure(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{2}{G}"); + + this.subtype.add(SubType.NIGHTMARE); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // As an additional cost to cast this spell, tap two untapped creatures and/or lands you control. + this.getSpellAbility().addCost(new TapTargetCost(new TargetControlledPermanent(2, filter))); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + } + + private FearOfExposure(final FearOfExposure card) { + super(card); + } + + @Override + public FearOfExposure copy() { + return new FearOfExposure(this); + } +} diff --git a/Mage.Sets/src/mage/cards/f/FearOfFalling.java b/Mage.Sets/src/mage/cards/f/FearOfFalling.java index 094c9c07923..d44d8c846f1 100644 --- a/Mage.Sets/src/mage/cards/f/FearOfFalling.java +++ b/Mage.Sets/src/mage/cards/f/FearOfFalling.java @@ -9,6 +9,7 @@ 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.common.FilterCreaturePermanent; @@ -39,9 +40,9 @@ public final class FearOfFalling extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever Fear of Falling attacks, target creature defending player controls gets -2/-0 and loses flying until your next turn. - Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(-2, 0) + Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(-2, 0, Duration.UntilYourNextTurn) .setText("target creature defending player controls gets -2/-0")); - ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance()).setText("and loses flying")); + ability.addEffect(new LoseAbilityTargetEffect(FlyingAbility.getInstance(), Duration.UntilYourNextTurn).setText("and loses flying until your next turn")); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FlameOfAnor.java b/Mage.Sets/src/mage/cards/f/FlameOfAnor.java index c285bf91067..19fc14d2f12 100644 --- a/Mage.Sets/src/mage/cards/f/FlameOfAnor.java +++ b/Mage.Sets/src/mage/cards/f/FlameOfAnor.java @@ -33,6 +33,7 @@ public final class FlameOfAnor extends CardImpl { // Choose one. If you control a Wizard as you cast this spell, you may choose two instead. this.getSpellAbility().getModes().setMoreCondition(condition); + this.getSpellAbility().getModes().setMoreLimit(2); this.getSpellAbility().getModes().setChooseText( "Choose one. If you control a Wizard as you cast this spell, you may choose two instead." ); diff --git a/Mage.Sets/src/mage/cards/g/GetOut.java b/Mage.Sets/src/mage/cards/g/GetOut.java new file mode 100644 index 00000000000..23d1cd8a5ae --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GetOut.java @@ -0,0 +1,59 @@ +package mage.cards.g; + +import mage.MageObject; +import mage.abilities.Mode; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.target.TargetPermanent; +import mage.target.TargetSpell; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class GetOut extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("creature or enchantment spell"); + private static final FilterPermanent filter2 = new FilterPermanent("creatures and/or enchantments you own"); + private static final Predicate predicate = Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.ENCHANTMENT.getPredicate() + ); + + static { + filter.add(predicate); + filter2.add(predicate); + filter2.add(TargetController.YOU.getOwnerPredicate()); + } + + public GetOut(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{U}"); + + // Choose one -- + // * Counter target creature or enchantment spell. + this.getSpellAbility().addEffect(new CounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell(filter)); + + // * Return one or two target creatures and/or enchantments you own to your hand. + this.getSpellAbility().addMode(new Mode(new ReturnToHandTargetEffect().setText("return one or two target creatures and/or enchantments you own to your hand")) + .addTarget(new TargetPermanent(1, 2, filter2))); + } + + private GetOut(final GetOut card) { + super(card); + } + + @Override + public GetOut copy() { + return new GetOut(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GleefulArsonist.java b/Mage.Sets/src/mage/cards/g/GleefulArsonist.java new file mode 100644 index 00000000000..aad51332598 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GleefulArsonist.java @@ -0,0 +1,52 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.SpellCastOpponentTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.UndyingAbility; +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 TheElk801 + */ +public final class GleefulArsonist extends CardImpl { + + private static final DynamicValue xValue = new SourcePermanentPowerCount(); + + public GleefulArsonist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Whenever an opponent casts a noncreature spell, Gleeful Arsonist deals damage equal to its power to that player. + this.addAbility(new SpellCastOpponentTriggeredAbility( + Zone.BATTLEFIELD, new DamageTargetEffect(xValue).setText("{this} deals damage equal to its power to that player"), + StaticFilters.FILTER_SPELL_A_NON_CREATURE, false, SetTargetPointer.PLAYER + )); + + // Undying + this.addAbility(new UndyingAbility()); + } + + private GleefulArsonist(final GleefulArsonist card) { + super(card); + } + + @Override + public GleefulArsonist copy() { + return new GleefulArsonist(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GrievousWound.java b/Mage.Sets/src/mage/cards/g/GrievousWound.java index ec35432ee57..83d179d33ba 100644 --- a/Mage.Sets/src/mage/cards/g/GrievousWound.java +++ b/Mage.Sets/src/mage/cards/g/GrievousWound.java @@ -15,7 +15,6 @@ import mage.game.permanent.Permanent; import mage.target.TargetPlayer; import mage.target.targetpointer.FixedTarget; -import java.util.Optional; import java.util.UUID; /** @@ -76,10 +75,8 @@ class GrievousWoundTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (!Optional - .ofNullable(getSourcePermanentIfItStillExists(game)) - .map(Permanent::getAttachedTo) - .equals(event.getTargetId())) { + Permanent attachment = getSourcePermanentIfItStillExists(game); + if (attachment == null || !event.getTargetId().equals(attachment.getAttachedTo())) { return false; } this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId())); diff --git a/Mage.Sets/src/mage/cards/h/HedgeShredder.java b/Mage.Sets/src/mage/cards/h/HedgeShredder.java index 19dfb28b325..bff6e50cef6 100644 --- a/Mage.Sets/src/mage/cards/h/HedgeShredder.java +++ b/Mage.Sets/src/mage/cards/h/HedgeShredder.java @@ -58,7 +58,7 @@ public final class HedgeShredder extends CardImpl { class HedgeShredderTriggeredAbility extends TriggeredAbilityImpl { HedgeShredderTriggeredAbility() { - super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect()); + super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(true)); } private HedgeShredderTriggeredAbility(final HedgeShredderTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/cards/h/HorridVigor.java b/Mage.Sets/src/mage/cards/h/HorridVigor.java new file mode 100644 index 00000000000..f6c7de2c050 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HorridVigor.java @@ -0,0 +1,37 @@ +package mage.cards.h; + +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.IndestructibleAbility; +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 HorridVigor extends CardImpl { + + public HorridVigor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{G}"); + + // Target creature gains deathtouch and indestructible until end of turn. + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance()) + .setText("target creature gains deathtouch")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(IndestructibleAbility.getInstance()) + .setText("and indestructible until end of turn")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + private HorridVigor(final HorridVigor card) { + super(card); + } + + @Override + public HorridVigor copy() { + return new HorridVigor(this); + } +} diff --git a/Mage.Sets/src/mage/cards/i/ImpossibleInferno.java b/Mage.Sets/src/mage/cards/i/ImpossibleInferno.java index e4bc140c07a..a3a1f0073d4 100644 --- a/Mage.Sets/src/mage/cards/i/ImpossibleInferno.java +++ b/Mage.Sets/src/mage/cards/i/ImpossibleInferno.java @@ -33,7 +33,6 @@ public final class ImpossibleInferno extends CardImpl { "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" )); - this.getSpellAbility().setAbilityWord(AbilityWord.DELIRIUM); this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU); } diff --git a/Mage.Sets/src/mage/cards/i/InfernalPhantom.java b/Mage.Sets/src/mage/cards/i/InfernalPhantom.java index 252d006332c..0f4328055c0 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalPhantom.java +++ b/Mage.Sets/src/mage/cards/i/InfernalPhantom.java @@ -35,7 +35,8 @@ public final class InfernalPhantom extends CardImpl { this.addAbility(new EerieAbility(new BoostSourceEffect(2, 0, Duration.EndOfTurn))); // When Infernal Phantom dies, it deals damage equal to its power to any target. - Ability ability = new DiesSourceTriggeredAbility(new DamageTargetEffect(xValue, "it")); + Ability ability = new DiesSourceTriggeredAbility(new DamageTargetEffect(xValue, "it") + .setText("it deals damage equal to its power to any target")); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IntrudingSoulrager.java b/Mage.Sets/src/mage/cards/i/IntrudingSoulrager.java index 00028644017..1f728735333 100644 --- a/Mage.Sets/src/mage/cards/i/IntrudingSoulrager.java +++ b/Mage.Sets/src/mage/cards/i/IntrudingSoulrager.java @@ -12,6 +12,7 @@ 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.FilterControlledPermanent; @@ -35,7 +36,7 @@ public final class IntrudingSoulrager extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // {T}, Sacrifice a Room: Intruding Soulrager deals 2 damage to each opponent. Draw a card. - Ability ability = new SimpleActivatedAbility(new DamagePlayersEffect(2), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(new DamagePlayersEffect(2, TargetController.OPPONENT), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(filter)); ability.addEffect(new DrawCardSourceControllerEffect(1)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/i/IonasJudgment.java b/Mage.Sets/src/mage/cards/i/IonasJudgment.java index 92fcc40b3d1..4f0f2e4b221 100644 --- a/Mage.Sets/src/mage/cards/i/IonasJudgment.java +++ b/Mage.Sets/src/mage/cards/i/IonasJudgment.java @@ -1,35 +1,26 @@ - - package mage.cards.i; -import java.util.UUID; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; +import mage.filter.StaticFilters; import mage.target.TargetPermanent; +import java.util.UUID; + /** * * @author Loki */ public final class IonasJudgment extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("creature or enchantment"); - - static { - filter.add(Predicates.or( - CardType.CREATURE.getPredicate(), - CardType.ENCHANTMENT.getPredicate())); - } public IonasJudgment (UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{W}"); + // Exile target creature or enchantment. this.getSpellAbility().addEffect(new ExileTargetEffect()); - this.getSpellAbility().addTarget(new TargetPermanent(filter)); - + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURE_OR_ENCHANTMENT)); } private IonasJudgment(final IonasJudgment card) { diff --git a/Mage.Sets/src/mage/cards/k/KillersMask.java b/Mage.Sets/src/mage/cards/k/KillersMask.java new file mode 100644 index 00000000000..2c73b58f9cb --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KillersMask.java @@ -0,0 +1,47 @@ +package mage.cards.k; + +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.ManifestDreadThenAttachEffect; +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 TheElk801 + */ +public final class KillersMask extends CardImpl { + + public KillersMask(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{B}"); + + this.subtype.add(SubType.EQUIPMENT); + + // When Killer's Mask enters, manifest dread, then attach Killer's Mask to that creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ManifestDreadThenAttachEffect())); + + // Equipped creature has menace. + this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect( + new MenaceAbility(false), AttachmentType.EQUIPMENT + ))); + + // Equip {2} + this.addAbility(new EquipAbility(2)); + } + + private KillersMask(final KillersMask card) { + super(card); + } + + @Override + public KillersMask copy() { + return new KillersMask(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KonaRescueBeastie.java b/Mage.Sets/src/mage/cards/k/KonaRescueBeastie.java index a8973914eea..4a873f29b50 100644 --- a/Mage.Sets/src/mage/cards/k/KonaRescueBeastie.java +++ b/Mage.Sets/src/mage/cards/k/KonaRescueBeastie.java @@ -27,7 +27,7 @@ public final class KonaRescueBeastie extends CardImpl { this.toughness = new MageInt(3); // Survival - At the beginning of your second main phase, if Kona, Rescue Beastie is tapped, you may put a permanent card from your hand onto the battlefield - this.addAbility(new SurvivalAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_CREATURE_A))); + this.addAbility(new SurvivalAbility(new PutCardFromHandOntoBattlefieldEffect(StaticFilters.FILTER_CARD_A_PERMANENT))); } private KonaRescueBeastie(final KonaRescueBeastie card) { diff --git a/Mage.Sets/src/mage/cards/l/LivingPhone.java b/Mage.Sets/src/mage/cards/l/LivingPhone.java new file mode 100644 index 00000000000..4e08426c505 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LivingPhone.java @@ -0,0 +1,50 @@ +package mage.cards.l; + +import mage.MageInt; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.PutCards; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.PowerPredicate; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class LivingPhone extends CardImpl { + + private static final FilterCard filter = new FilterCreatureCard("a creature card with power 2 or less"); + + static { + filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); + } + + public LivingPhone(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{W}"); + + this.subtype.add(SubType.TOY); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // When Living Phone dies, look at the top five cards of your library. You may reveal a creature card with power 2 or less 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 DiesSourceTriggeredAbility(new LookLibraryAndPickControllerEffect( + 5, 1, filter, PutCards.HAND, PutCards.BOTTOM_RANDOM + ))); + } + + private LivingPhone(final LivingPhone card) { + super(card); + } + + @Override + public LivingPhone copy() { + return new LivingPhone(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MiasmaDemon.java b/Mage.Sets/src/mage/cards/m/MiasmaDemon.java new file mode 100644 index 00000000000..d1cb6d2b296 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MiasmaDemon.java @@ -0,0 +1,85 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +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.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MiasmaDemon extends CardImpl { + + public MiasmaDemon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + + this.subtype.add(SubType.DEMON); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Miasma Demon enters, you may discard any number of cards. When you do, up to that many target creatures each get -2/-2 until end of turn. + this.addAbility(new EntersBattlefieldTriggeredAbility(new MiasmaDemonEffect())); + } + + private MiasmaDemon(final MiasmaDemon card) { + super(card); + } + + @Override + public MiasmaDemon copy() { + return new MiasmaDemon(this); + } +} + +class MiasmaDemonEffect extends OneShotEffect { + + MiasmaDemonEffect() { + super(Outcome.Benefit); + staticText = "you may discard any number of cards. When you do, " + + "up to that many target creatures each get -2/-2 until end of turn"; + } + + private MiasmaDemonEffect(final MiasmaDemonEffect effect) { + super(effect); + } + + @Override + public MiasmaDemonEffect copy() { + return new MiasmaDemonEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + int amount = player.discard(0, Integer.MAX_VALUE, false, source, game).size(); + if (amount < 1) { + return false; + } + ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( + new BoostTargetEffect(-2, -2), false, + "Up to that many target creatures each get -2/-2 until end of turn" + ); + ability.addTarget(new TargetCreaturePermanent(0, amount)); + game.fireReflexiveTriggeredAbility(ability, source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/o/OverlordOfTheBalemurk.java b/Mage.Sets/src/mage/cards/o/OverlordOfTheBalemurk.java new file mode 100644 index 00000000000..7c8cff9fcf5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OverlordOfTheBalemurk.java @@ -0,0 +1,96 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.MillCardsControllerEffect; +import mage.abilities.keyword.ImpendingAbility; +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.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInYourGraveyard; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class OverlordOfTheBalemurk extends CardImpl { + + public OverlordOfTheBalemurk(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.HORROR); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Impending 5--{1}{B} + this.addAbility(new ImpendingAbility("{1}{B}", 5)); + + // Whenever Overlord of the Balemurk enters or attacks, mill four cards, then you may return a non-Avatar creature card or a planeswalker card from your graveyard to your hand. + Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new MillCardsControllerEffect(4)); + ability.addEffect(new OverlordOfTheBalemurkEffect()); + this.addAbility(ability); + } + + private OverlordOfTheBalemurk(final OverlordOfTheBalemurk card) { + super(card); + } + + @Override + public OverlordOfTheBalemurk copy() { + return new OverlordOfTheBalemurk(this); + } +} + +class OverlordOfTheBalemurkEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("non-Avatar creature card or a planeswalker card from your graveyard"); + + static { + filter.add(Predicates.or( + Predicates.and( + Predicates.not(SubType.AVATAR.getPredicate()), + CardType.CREATURE.getPredicate() + ), CardType.PLANESWALKER.getPredicate() + )); + } + + OverlordOfTheBalemurkEffect() { + super(Outcome.Benefit); + staticText = ", then you may return a non-Avatar creature card " + + "or a planeswalker card from your graveyard to your hand"; + } + + private OverlordOfTheBalemurkEffect(final OverlordOfTheBalemurkEffect effect) { + super(effect); + } + + @Override + public OverlordOfTheBalemurkEffect copy() { + return new OverlordOfTheBalemurkEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + TargetCard target = new TargetCardInYourGraveyard(0, 1, filter, true); + player.choose(Outcome.PutCreatureInPlay, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + return card != null && player.moveCards(card, Zone.HAND, source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/p/PersistentConstrictor.java b/Mage.Sets/src/mage/cards/p/PersistentConstrictor.java new file mode 100644 index 00000000000..3644e3288e7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PersistentConstrictor.java @@ -0,0 +1,86 @@ +package mage.cards.p; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.PersistAbility; +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.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class PersistentConstrictor extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("creature they control"); + + static { + filter.add(TargetController.ACTIVE.getControllerPredicate()); + } + + public PersistentConstrictor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); + + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.SNAKE); + this.power = new MageInt(5); + this.toughness = new MageInt(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. + Ability ability = new BeginningOfUpkeepTriggeredAbility( + new PersistentConstrictorEffect(), TargetController.OPPONENT, false + ); + ability.addEffect(new AddCountersTargetEffect(CounterType.M1M1.createInstance()).concatBy("and you")); + ability.addTarget(new TargetPermanent(0, 1, filter)); + this.addAbility(ability); + + // Persist + this.addAbility(new PersistAbility()); + } + + private PersistentConstrictor(final PersistentConstrictor card) { + super(card); + } + + @Override + public PersistentConstrictor copy() { + return new PersistentConstrictor(this); + } +} + +class PersistentConstrictorEffect extends OneShotEffect { + + PersistentConstrictorEffect() { + super(Outcome.Benefit); + staticText = "they lose 1 life"; + } + + private PersistentConstrictorEffect(final PersistentConstrictorEffect effect) { + super(effect); + } + + @Override + public PersistentConstrictorEffect copy() { + return new PersistentConstrictorEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(game.getActivePlayerId()); + return player != null && player.loseLife(1, game, source, false) > 0; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PortentOfCalamity.java b/Mage.Sets/src/mage/cards/p/PortentOfCalamity.java new file mode 100644 index 00000000000..c5c9b6eb05a --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PortentOfCalamity.java @@ -0,0 +1,133 @@ +package mage.cards.p; + +import mage.abilities.Ability; +import mage.abilities.assignment.common.CardTypeAssignment; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.MayCastTargetCardEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.CastManaAdjustment; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetCardInLibrary; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +import java.util.Arrays; +import java.util.UUID; + +/** + * @author notgreat + */ +public final class PortentOfCalamity extends CardImpl { + + public PortentOfCalamity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}"); + + + // Reveal the top X cards of your library. For each card type, you may exile a card of that type from among them. Put the rest into your graveyard. You may cast a spell from among the exiled cards without paying its mana cost if you exiled four or more cards this way. Then put the rest of the exiled cards into your hand. + this.getSpellAbility().addEffect(new PortentOfCalamityEffect()); + } + + private PortentOfCalamity(final PortentOfCalamity card) { + super(card); + } + + @Override + public PortentOfCalamity copy() { + return new PortentOfCalamity(this); + } +} + +//Based on Atraxa, Grand Unifier +class PortentOfCalamityEffect extends OneShotEffect { + + PortentOfCalamityEffect() { + super(Outcome.Benefit); + staticText = "Reveal the top X cards of your library. For each card type, you may exile a card of that type from among them. " + + "Put the rest into your graveyard. You may cast a spell from among the exiled cards without paying its mana cost " + + "if you exiled four or more cards this way. Then put the rest of the exiled cards into your hand"; + } + + private PortentOfCalamityEffect(final PortentOfCalamityEffect effect) { + super(effect); + } + + @Override + public PortentOfCalamityEffect copy() { + return new PortentOfCalamityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, CardUtil.getSourceCostsTag(game, source, "X", 0))); + player.revealCards(source, cards, game); + + TargetCard target = new PortentOfCalamityTarget(); + player.choose(Outcome.DrawCard, cards, target, source, game); + Cards chosen = new CardsImpl(target.getTargets()); + player.moveCards(chosen, Zone.EXILED, source, game); + cards.retainZone(Zone.LIBRARY, game); + player.moveCards(cards, Zone.GRAVEYARD, source, game); + + if (chosen.size() >= 4){ + TargetCard freeCast = new TargetCard(0, 1, Zone.EXILED, StaticFilters.FILTER_CARD); + player.choose(Outcome.PlayForFree, chosen, freeCast, source, game); + Effect effect = new MayCastTargetCardEffect(CastManaAdjustment.WITHOUT_PAYING_MANA_COST); + effect.setTargetPointer(new FixedTarget(freeCast.getFirstTarget())); + effect.apply(game, source); + } + chosen.retainZone(Zone.EXILED, game); + player.moveCards(chosen, Zone.HAND, source, game); + return true; + } +} + +class PortentOfCalamityTarget extends TargetCardInLibrary { + + private static final FilterCard filter + = new FilterCard("a card of each card type"); + + private static final CardTypeAssignment cardTypeAssigner + = new CardTypeAssignment(Arrays.stream(CardType.values()).toArray(CardType[]::new)); + + PortentOfCalamityTarget() { + super(0, Integer.MAX_VALUE, filter); + } + + private PortentOfCalamityTarget(final PortentOfCalamityTarget target) { + super(target); + } + + @Override + public PortentOfCalamityTarget copy() { + return new PortentOfCalamityTarget(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 cardTypeAssigner.getRoleCount(cards, game) >= cards.size(); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RebelSalvo.java b/Mage.Sets/src/mage/cards/r/RebelSalvo.java index e35891c1812..b06205cdef2 100644 --- a/Mage.Sets/src/mage/cards/r/RebelSalvo.java +++ b/Mage.Sets/src/mage/cards/r/RebelSalvo.java @@ -11,6 +11,7 @@ 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.Zone; import mage.filter.common.FilterControlledPermanent; @@ -36,10 +37,10 @@ public final class RebelSalvo extends CardImpl { // Affinity for Equipment this.addAbility(new SimpleStaticAbility(Zone.ALL, new AffinityEffect(filter)).addHint(hint)); - // Rebel Salvo deals 5 damage to target creature or planeswalker. That permanent loses indestructible unil end of turn. + // Rebel Salvo deals 5 damage to target creature or planeswalker. That permanent loses indestructible until end of turn. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker()); - this.getSpellAbility().addEffect(new LoseAbilityTargetEffect(IndestructibleAbility.getInstance()) + this.getSpellAbility().addEffect(new LoseAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn) .setText("that permanent loses indestructible until end of turn")); } diff --git a/Mage.Sets/src/mage/cards/r/RipchainRazorkin.java b/Mage.Sets/src/mage/cards/r/RipchainRazorkin.java new file mode 100644 index 00000000000..b00ee12a132 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RipchainRazorkin.java @@ -0,0 +1,48 @@ +package mage.cards.r; + +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.DrawCardSourceControllerEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.StaticFilters; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class RipchainRazorkin extends CardImpl { + + public RipchainRazorkin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.BERSERKER); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Reach + this.addAbility(ReachAbility.getInstance()); + + // {2}{R}, Sacrifice a land: Draw a card. + Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{2}{R}")); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND_A)); + this.addAbility(ability); + } + + private RipchainRazorkin(final RipchainRazorkin card) { + super(card); + } + + @Override + public RipchainRazorkin copy() { + return new RipchainRazorkin(this); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RootwiseSurvivor.java b/Mage.Sets/src/mage/cards/r/RootwiseSurvivor.java index c5838daaa80..f7787bbb8e2 100644 --- a/Mage.Sets/src/mage/cards/r/RootwiseSurvivor.java +++ b/Mage.Sets/src/mage/cards/r/RootwiseSurvivor.java @@ -13,8 +13,9 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.game.permanent.token.custom.CreatureToken; -import mage.target.common.TargetLandPermanent; +import mage.target.TargetPermanent; import java.util.UUID; @@ -38,8 +39,9 @@ public final class RootwiseSurvivor extends CardImpl { Ability ability = new SurvivalAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(3))); ability.addEffect(new BecomesCreatureTargetEffect(new CreatureToken( 0, 0, "0/0 Elemental creature" - ).withSubType(SubType.ELEMENTAL), false, false, Duration.EndOfTurn)); - ability.addTarget(new TargetLandPermanent(0, 1)); + ).withSubType(SubType.ELEMENTAL), false, false, Duration.Custom) + .setText("That land becomes a 0/0 Elemental creature in addition to its other types")); + ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); ability.addEffect(new GainAbilityTargetEffect( HasteAbility.getInstance(), Duration.UntilYourNextTurn ).setText("it gains haste until your next turn")); diff --git a/Mage.Sets/src/mage/cards/r/RoshanHiddenMagister.java b/Mage.Sets/src/mage/cards/r/RoshanHiddenMagister.java index 47760e576b4..cd75a3282b6 100644 --- a/Mage.Sets/src/mage/cards/r/RoshanHiddenMagister.java +++ b/Mage.Sets/src/mage/cards/r/RoshanHiddenMagister.java @@ -26,8 +26,8 @@ import mage.filter.predicate.card.FaceDownPredicate; public final class RoshanHiddenMagister extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Face-down creatures"); - public static final FilterControlledCreatureSpell filterSpells = new FilterControlledCreatureSpell("creature spells you control"); - public static final FilterOwnedCreatureCard filterCards = new FilterOwnedCreatureCard("creature cards you own"); + private static final FilterControlledCreatureSpell filterSpells = new FilterControlledCreatureSpell("creature spells you control"); + private static final FilterOwnedCreatureCard filterCards = new FilterOwnedCreatureCard("creature cards you own"); static { filter.add(FaceDownPredicate.instance); @@ -44,7 +44,7 @@ public final class RoshanHiddenMagister extends CardImpl { // Other creatures you control are Assassins 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. this.addAbility(new SimpleStaticAbility(new AddCreatureSubTypeAllMultiZoneEffect( - StaticFilters.FILTER_CONTROLLED_CREATURES, + StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES, filterSpells, filterCards, SubType.ASSASSIN @@ -59,10 +59,10 @@ public final class RoshanHiddenMagister extends CardImpl { // Whenever a permanent you control is turned face up, you draw a card and you lose 1 life. Ability ability = new TurnedFaceUpAllTriggeredAbility( - new DrawCardSourceControllerEffect(1), + new DrawCardSourceControllerEffect(1, true), StaticFilters.FILTER_CONTROLLED_A_PERMANENT ); - ability.addEffect(new LoseLifeSourceControllerEffect(1)); + ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SawbladeSkinripper.java b/Mage.Sets/src/mage/cards/s/SawbladeSkinripper.java index 442ff4cb294..eded8a073a5 100644 --- a/Mage.Sets/src/mage/cards/s/SawbladeSkinripper.java +++ b/Mage.Sets/src/mage/cards/s/SawbladeSkinripper.java @@ -103,12 +103,12 @@ enum SawbladeSkinripperValue implements DynamicValue { } @Override - public String getMessage() { + public String toString() { return "that much"; } @Override - public String toString() { + public String getMessage() { return ""; } } diff --git a/Mage.Sets/src/mage/cards/s/SeasonOfTheBold.java b/Mage.Sets/src/mage/cards/s/SeasonOfTheBold.java new file mode 100644 index 00000000000..1e4cca5e2cd --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeasonOfTheBold.java @@ -0,0 +1,89 @@ +package mage.cards.s; + +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.Mode; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author notgreat + */ +public final class SeasonOfTheBold extends CardImpl { + + public SeasonOfTheBold(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}"); + + + // Choose up to five {P} worth of modes. You may choose the same mode more than once. + this.getSpellAbility().getModes().setMaxPawPrints(5); + this.getSpellAbility().getModes().setMinModes(0); + this.getSpellAbility().getModes().setMaxModes(5); + this.getSpellAbility().getModes().setMayChooseSameModeMoreThanOnce(true); + + // {P} -- Create a tapped Treasure token. + this.getSpellAbility().addEffect(new CreateTokenEffect(new TreasureToken(), 1, true)); + this.spellAbility.getModes().getMode().withPawPrintValue(1); + + // {P}{P} -- Exile the top two cards of your library. Until the end of your next turn, you may play them. + Mode mode2 = new Mode(new ExileTopXMayPlayUntilEffect(2, Duration.UntilEndOfYourNextTurn)); + this.getSpellAbility().addMode(mode2.withPawPrintValue(2)); + + // {P}{P}{P} -- Until the end of your next turn, whenever you cast a spell, Season of the Bold deals 2 damage to up to one target creature. + Mode mode3 = new Mode(new CreateDelayedTriggeredAbilityEffect(new SeasonOfTheBoldDelayedTriggeredAbility())); + this.getSpellAbility().addMode(mode3.withPawPrintValue(3)); + } + + private SeasonOfTheBold(final SeasonOfTheBold card) { + super(card); + } + + @Override + public SeasonOfTheBold copy() { + return new SeasonOfTheBold(this); + } +} + +// Based on ShowdownOfTheSkaldsDelayedTriggeredAbility +class SeasonOfTheBoldDelayedTriggeredAbility extends DelayedTriggeredAbility { + + SeasonOfTheBoldDelayedTriggeredAbility() { + super(new DamageTargetEffect(2), Duration.UntilEndOfYourNextTurn, false, false); + this.addTarget(new TargetCreaturePermanent(0, 1)); + } + + private SeasonOfTheBoldDelayedTriggeredAbility(final SeasonOfTheBoldDelayedTriggeredAbility ability) { + super(ability); + } + + @Override + public SeasonOfTheBoldDelayedTriggeredAbility copy() { + return new SeasonOfTheBoldDelayedTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getPlayerId().equals(this.getControllerId()); + } + + @Override + public String getRule() { + return "Until the end of your next turn, whenever you cast a spell, {this} deals 2 damage to up to one target creature."; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SeasonOfWeaving.java b/Mage.Sets/src/mage/cards/s/SeasonOfWeaving.java new file mode 100644 index 00000000000..26f62b14ef5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SeasonOfWeaving.java @@ -0,0 +1,99 @@ +package mage.cards.s; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author notgreat + */ +public final class SeasonOfWeaving extends CardImpl { + private static final FilterPermanent filter = new FilterNonlandPermanent("nonland, nontoken permanent"); + + static { + filter.add(TokenPredicate.FALSE); + } + + public SeasonOfWeaving(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}"); + + // Choose up to five {P} worth of modes. You may choose the same mode more than once. + this.getSpellAbility().getModes().setMaxPawPrints(5); + this.getSpellAbility().getModes().setMinModes(0); + this.getSpellAbility().getModes().setMaxModes(5); + this.getSpellAbility().getModes().setMayChooseSameModeMoreThanOnce(true); + + // {P} -- Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + this.spellAbility.getModes().getMode().withPawPrintValue(1); + + // {P}{P} -- Choose an artifact or creature you control. Create a token that's a copy of it. + Mode mode2 = new Mode(new SeasonOfWeavingEffect()); + this.getSpellAbility().addMode(mode2.withPawPrintValue(2)); + + // {P}{P}{P} -- Return each nonland, nontoken permanent to its owner's hand. + Mode mode3 = new Mode(new ReturnToHandFromBattlefieldAllEffect(filter)); + this.getSpellAbility().addMode(mode3.withPawPrintValue(3)); + } + + private SeasonOfWeaving(final SeasonOfWeaving card) { + super(card); + } + + @Override + public SeasonOfWeaving copy() { + return new SeasonOfWeaving(this); + } +} + + +class SeasonOfWeavingEffect extends OneShotEffect { + + SeasonOfWeavingEffect() { + super(Outcome.PutCreatureInPlay); + setText("Choose an artifact or creature you control. Create a token that's a copy of it"); + } + + private SeasonOfWeavingEffect(final SeasonOfWeavingEffect effect) { + super(effect); + } + + @Override + public SeasonOfWeavingEffect copy() { + return new SeasonOfWeavingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Target target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE).withNotTarget(true); + if (player.choose(outcome, target, source, game)) { + Effect effect = new CreateTokenCopyTargetEffect(); + effect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)); + effect.apply(game, source); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SmiteTheDeathless.java b/Mage.Sets/src/mage/cards/s/SmiteTheDeathless.java index ef240883cf6..195593f5785 100644 --- a/Mage.Sets/src/mage/cards/s/SmiteTheDeathless.java +++ b/Mage.Sets/src/mage/cards/s/SmiteTheDeathless.java @@ -7,6 +7,7 @@ import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Duration; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -21,7 +22,7 @@ public final class SmiteTheDeathless extends CardImpl { // Smite the Deathless deals 3 damage to target creature. That creature loses indestructible until end of turn. If that creature would die this turn, exile it instead. this.getSpellAbility().addEffect(new DamageTargetEffect(3)); - this.getSpellAbility().addEffect(new LoseAbilityTargetEffect(IndestructibleAbility.getInstance()) + this.getSpellAbility().addEffect(new LoseAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn) .setText("that creature loses indestructible until end of turn")); this.getSpellAbility().addEffect(new ExileTargetIfDiesEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/s/SplitskinDoll.java b/Mage.Sets/src/mage/cards/s/SplitskinDoll.java index 70ef402ebbe..c953c6c9c94 100644 --- a/Mage.Sets/src/mage/cards/s/SplitskinDoll.java +++ b/Mage.Sets/src/mage/cards/s/SplitskinDoll.java @@ -51,7 +51,7 @@ public final class SplitskinDoll extends CardImpl { // When Splitskin Doll enters, draw a card. Then discard a card unless you control another creature with power 2 or less. Ability ability = new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)); ability.addEffect(new ConditionalOneShotEffect( - new DiscardControllerEffect(1), condition, "then discard " + + new DiscardControllerEffect(1), condition, "Then discard " + "a card unless you control another creature with power 2 or less" )); this.addAbility(ability.addHint(hint)); diff --git a/Mage.Sets/src/mage/cards/t/TheSwarmweaver.java b/Mage.Sets/src/mage/cards/t/TheSwarmweaver.java index 1d98df44b96..eb12ffe1b25 100644 --- a/Mage.Sets/src/mage/cards/t/TheSwarmweaver.java +++ b/Mage.Sets/src/mage/cards/t/TheSwarmweaver.java @@ -19,7 +19,7 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; import mage.game.permanent.Permanent; -import mage.game.permanent.token.IzoniInsectToken; +import mage.game.permanent.token.InsectBlackGreenFlyingToken; import java.util.UUID; @@ -49,7 +49,7 @@ public final class TheSwarmweaver extends CardImpl { this.toughness = new MageInt(3); // When The Swarmweaver enters, create two 1/1 black and green Insect creature tokens with flying. - this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new IzoniInsectToken()))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new InsectBlackGreenFlyingToken(), 2))); // 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. Ability ability = new SimpleStaticAbility(new ConditionalContinuousEffect( diff --git a/Mage.Sets/src/mage/cards/t/TheyCameFromThePipes.java b/Mage.Sets/src/mage/cards/t/TheyCameFromThePipes.java index 15df0cc0eb3..2d8b55b5a8c 100644 --- a/Mage.Sets/src/mage/cards/t/TheyCameFromThePipes.java +++ b/Mage.Sets/src/mage/cards/t/TheyCameFromThePipes.java @@ -31,7 +31,7 @@ public final class TheyCameFromThePipes extends CardImpl { // When They Came from the Pipes enters, manifest dread twice. Ability ability = new EntersBattlefieldTriggeredAbility(new ManifestDreadEffect()); - ability.addEffect(new ManifestDreadEffect().setText("twice")); + ability.addEffect(new ManifestDreadEffect().setText(" twice")); this.addAbility(ability); // Whenever a face-down creature you control enters, draw a card. diff --git a/Mage.Sets/src/mage/cards/u/UnnervingGrasp.java b/Mage.Sets/src/mage/cards/u/UnnervingGrasp.java new file mode 100644 index 00000000000..b99247edf7d --- /dev/null +++ b/Mage.Sets/src/mage/cards/u/UnnervingGrasp.java @@ -0,0 +1,34 @@ +package mage.cards.u; + +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.keyword.ManifestDreadEffect; +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 UnnervingGrasp extends CardImpl { + + public UnnervingGrasp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); + + // Return up to one target nonland permanent to its owner's hand. Manifest dread. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetNonlandPermanent(0, 1)); + this.getSpellAbility().addEffect(new ManifestDreadEffect()); + } + + private UnnervingGrasp(final UnnervingGrasp card) { + super(card); + } + + @Override + public UnnervingGrasp copy() { + return new UnnervingGrasp(this); + } +} diff --git a/Mage.Sets/src/mage/cards/u/UntimelyMalfunction.java b/Mage.Sets/src/mage/cards/u/UntimelyMalfunction.java index 67349e6ff21..d467e2dc3f1 100644 --- a/Mage.Sets/src/mage/cards/u/UntimelyMalfunction.java +++ b/Mage.Sets/src/mage/cards/u/UntimelyMalfunction.java @@ -8,9 +8,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.filter.FilterSpell; +import mage.filter.FilterStackObject; import mage.filter.predicate.other.NumberOfTargetsPredicate; -import mage.target.TargetSpell; +import mage.target.TargetStackObject; import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetCreaturePermanent; @@ -21,7 +21,7 @@ import java.util.UUID; */ public final class UntimelyMalfunction extends CardImpl { - private static final FilterSpell filter = new FilterSpell("spell with a single target"); + private static final FilterStackObject filter = new FilterStackObject("spell or ability with a single target"); static { filter.add(new NumberOfTargetsPredicate(1)); @@ -36,7 +36,8 @@ public final class UntimelyMalfunction extends CardImpl { this.getSpellAbility().addTarget(new TargetArtifactPermanent()); // * Change the target of target spell or ability with a single target. - this.getSpellAbility().addMode(new Mode(new ChooseNewTargetsTargetEffect(true, true)).addTarget(new TargetSpell(filter))); + this.getSpellAbility().addMode(new Mode(new ChooseNewTargetsTargetEffect(true, true)) + .addTarget(new TargetStackObject(filter))); // * One or two target creatures can't block this turn. this.getSpellAbility().addMode(new Mode(new CantBlockTargetEffect(Duration.EndOfTurn)).addTarget(new TargetCreaturePermanent(1, 2))); diff --git a/Mage.Sets/src/mage/cards/v/VedalkenHumiliator.java b/Mage.Sets/src/mage/cards/v/VedalkenHumiliator.java index 882f8ca4e71..d6741ad3893 100644 --- a/Mage.Sets/src/mage/cards/v/VedalkenHumiliator.java +++ b/Mage.Sets/src/mage/cards/v/VedalkenHumiliator.java @@ -4,7 +4,7 @@ import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.condition.common.MetalcraftCondition; -import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.continuous.LoseAllAbilitiesAllEffect; import mage.abilities.effects.common.continuous.SetBasePowerToughnessAllEffect; import mage.abilities.hint.common.MetalcraftHint; @@ -42,9 +42,9 @@ public final class VedalkenHumiliator extends CardImpl { StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE, Duration.EndOfTurn )); - this.addAbility(new ConditionalTriggeredAbility( + this.addAbility(new ConditionalInterveningIfTriggeredAbility( ability, MetalcraftCondition.instance, - "Metalcraft — Whenever {this} attacks, " + "Whenever {this} attacks, " + "if you control three or more artifacts, " + "creatures your opponents control lose all abilities " + "and have base power and toughness 1/1 until end of turn.") diff --git a/Mage.Sets/src/mage/cards/v/VengefulPossession.java b/Mage.Sets/src/mage/cards/v/VengefulPossession.java index 762b91aad20..bca41c0428f 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulPossession.java +++ b/Mage.Sets/src/mage/cards/v/VengefulPossession.java @@ -25,7 +25,7 @@ public final class VengefulPossession extends CardImpl { // Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. You may discard a card. If you do, draw a card. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap that creature")); + this.getSpellAbility().addEffect(new UntapTargetEffect().setText("Untap it")); this.getSpellAbility().addEffect(new GainAbilityTargetEffect( HasteAbility.getInstance(), Duration.EndOfTurn ).setText("It gains haste until end of turn.")); diff --git a/Mage.Sets/src/mage/cards/v/ViolentUrge.java b/Mage.Sets/src/mage/cards/v/ViolentUrge.java new file mode 100644 index 00000000000..5f4c6814789 --- /dev/null +++ b/Mage.Sets/src/mage/cards/v/ViolentUrge.java @@ -0,0 +1,54 @@ +package mage.cards.v; + +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.AddContinuousEffectToGame; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.hint.common.CardTypesInGraveyardHint; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class ViolentUrge extends CardImpl { + + public ViolentUrge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); + + // Target creature gets +1/+0 and gains first strike until end of turn. + this.getSpellAbility().addEffect(new BoostTargetEffect( + 1, 0, Duration.EndOfTurn + ).setText("Target creature gets +1/+0")); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect( + FirstStrikeAbility.getInstance(), Duration.EndOfTurn + ).setText("and gains first strike until end of turn")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Delirium -- If there are four or more card types among cards in your graveyard, that creature gains double strike until end of turn. + this.getSpellAbility().addEffect(new ConditionalOneShotEffect( + new AddContinuousEffectToGame(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance())), + DeliriumCondition.instance, AbilityWord.DELIRIUM.formatWord() + "If there are four or more " + + "card types among cards in your graveyard, that creature gains double strike until end of turn" + )); + this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU); + } + + private ViolentUrge(final ViolentUrge card) { + super(card); + } + + @Override + public ViolentUrge copy() { + return new ViolentUrge(this); + } +} diff --git a/Mage.Sets/src/mage/cards/w/WintersIntervention.java b/Mage.Sets/src/mage/cards/w/WintersIntervention.java new file mode 100644 index 00000000000..c3d998c69b3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WintersIntervention.java @@ -0,0 +1,34 @@ +package mage.cards.w; + +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +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 WintersIntervention extends CardImpl { + + public WintersIntervention(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}"); + + // Winter's Intervention deals 2 damage to target creature. You gain 2 life. + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new GainLifeEffect(2)); + } + + private WintersIntervention(final WintersIntervention card) { + super(card); + } + + @Override + public WintersIntervention copy() { + return new WintersIntervention(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AssassinsCreed.java b/Mage.Sets/src/mage/sets/AssassinsCreed.java index 49117b4c31d..f5dad8fa2cf 100644 --- a/Mage.Sets/src/mage/sets/AssassinsCreed.java +++ b/Mage.Sets/src/mage/sets/AssassinsCreed.java @@ -24,12 +24,14 @@ public final class AssassinsCreed extends ExpansionSet { cards.add(new SetCardInfo("Abstergo Entertainment", 79, Rarity.RARE, mage.cards.a.AbstergoEntertainment.class)); cards.add(new SetCardInfo("Achilles Davenport", 294, Rarity.RARE, mage.cards.a.AchillesDavenport.class)); cards.add(new SetCardInfo("Adewale, Breaker of Chains", 44, Rarity.UNCOMMON, mage.cards.a.AdewaleBreakerOfChains.class)); + cards.add(new SetCardInfo("Adrestia", 68, Rarity.UNCOMMON, mage.cards.a.Adrestia.class)); cards.add(new SetCardInfo("Arbaaz Mir", 46, Rarity.UNCOMMON, mage.cards.a.ArbaazMir.class)); cards.add(new SetCardInfo("Arno Dorian", 47, Rarity.UNCOMMON, mage.cards.a.ArnoDorian.class)); cards.add(new SetCardInfo("Assassin Den", 281, Rarity.UNCOMMON, mage.cards.a.AssassinDen.class)); cards.add(new SetCardInfo("Assassin Gauntlet", 12, Rarity.UNCOMMON, mage.cards.a.AssassinGauntlet.class)); cards.add(new SetCardInfo("Assassin Initiate", 22, Rarity.UNCOMMON, mage.cards.a.AssassinInitiate.class)); cards.add(new SetCardInfo("Assassin's Trophy", 95, Rarity.RARE, mage.cards.a.AssassinsTrophy.class)); + cards.add(new SetCardInfo("Aveline de Grandpre", 40, Rarity.RARE, mage.cards.a.AvelineDeGrandpre.class)); cards.add(new SetCardInfo("Aya of Alexandria", 48, Rarity.RARE, mage.cards.a.AyaOfAlexandria.class)); cards.add(new SetCardInfo("Ballad of the Black Flag", 13, Rarity.UNCOMMON, mage.cards.b.BalladOfTheBlackFlag.class)); cards.add(new SetCardInfo("Basim Ibn Ishaq", 49, Rarity.RARE, mage.cards.b.BasimIbnIshaq.class)); diff --git a/Mage.Sets/src/mage/sets/Bloomburrow.java b/Mage.Sets/src/mage/sets/Bloomburrow.java index c3ebff10808..4ce257ae16d 100644 --- a/Mage.Sets/src/mage/sets/Bloomburrow.java +++ b/Mage.Sets/src/mage/sets/Bloomburrow.java @@ -191,6 +191,7 @@ public final class Bloomburrow extends ExpansionSet { cards.add(new SetCardInfo("Plumecreed Mentor", 228, Rarity.UNCOMMON, mage.cards.p.PlumecreedMentor.class)); cards.add(new SetCardInfo("Polliwallop", 189, Rarity.COMMON, mage.cards.p.Polliwallop.class)); cards.add(new SetCardInfo("Pond Prophet", 229, Rarity.COMMON, mage.cards.p.PondProphet.class)); + cards.add(new SetCardInfo("Portent of Calamity", 66, Rarity.RARE, mage.cards.p.PortentOfCalamity.class)); cards.add(new SetCardInfo("Psychic Whorl", 105, Rarity.COMMON, mage.cards.p.PsychicWhorl.class)); cards.add(new SetCardInfo("Quaketusk Boar", 146, Rarity.UNCOMMON, mage.cards.q.QuaketuskBoar.class)); cards.add(new SetCardInfo("Rabbit Response", 26, Rarity.COMMON, mage.cards.r.RabbitResponse.class)); @@ -217,6 +218,8 @@ public final class Bloomburrow extends ExpansionSet { cards.add(new SetCardInfo("Scrapshooter", 191, Rarity.RARE, mage.cards.s.Scrapshooter.class)); cards.add(new SetCardInfo("Season of Gathering", 192, Rarity.MYTHIC, mage.cards.s.SeasonOfGathering.class)); cards.add(new SetCardInfo("Season of Loss", 112, Rarity.MYTHIC, mage.cards.s.SeasonOfLoss.class)); + cards.add(new SetCardInfo("Season of Weaving", 68, Rarity.MYTHIC, mage.cards.s.SeasonOfWeaving.class)); + cards.add(new SetCardInfo("Season of the Bold", 152, Rarity.MYTHIC, mage.cards.s.SeasonOfTheBold.class)); cards.add(new SetCardInfo("Season of the Burrow", 29, Rarity.MYTHIC, mage.cards.s.SeasonOfTheBurrow.class)); cards.add(new SetCardInfo("Seasoned Warrenguard", 30, Rarity.UNCOMMON, mage.cards.s.SeasonedWarrenguard.class)); cards.add(new SetCardInfo("Seedglaive Mentor", 231, Rarity.UNCOMMON, mage.cards.s.SeedglaiveMentor.class)); diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java index d70f4da0cac..db9ccba4914 100644 --- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java +++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java @@ -33,11 +33,13 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Baseball Bat", 209, Rarity.UNCOMMON, mage.cards.b.BaseballBat.class)); cards.add(new SetCardInfo("Bashful Beastie", 169, Rarity.COMMON, mage.cards.b.BashfulBeastie.class)); cards.add(new SetCardInfo("Bear Trap", 243, Rarity.COMMON, mage.cards.b.BearTrap.class)); + cards.add(new SetCardInfo("Bedhead Beastie", 125, Rarity.COMMON, mage.cards.b.BedheadBeastie.class)); cards.add(new SetCardInfo("Betrayer's Bargain", 126, Rarity.UNCOMMON, mage.cards.b.BetrayersBargain.class)); cards.add(new SetCardInfo("Blazemire Verge", 256, Rarity.RARE, mage.cards.b.BlazemireVerge.class)); cards.add(new SetCardInfo("Bleeding Woods", 257, Rarity.COMMON, mage.cards.b.BleedingWoods.class)); cards.add(new SetCardInfo("Break Down the Door", 170, Rarity.UNCOMMON, mage.cards.b.BreakDownTheDoor.class)); cards.add(new SetCardInfo("Broodspinner", 211, Rarity.UNCOMMON, mage.cards.b.Broodspinner.class)); + cards.add(new SetCardInfo("Cackling Slasher", 85, Rarity.COMMON, mage.cards.c.CacklingSlasher.class)); cards.add(new SetCardInfo("Cautious Survivor", 172, Rarity.COMMON, mage.cards.c.CautiousSurvivor.class)); cards.add(new SetCardInfo("Chainsaw", 128, Rarity.RARE, mage.cards.c.Chainsaw.class)); cards.add(new SetCardInfo("Clammy Prowler", 45, Rarity.COMMON, mage.cards.c.ClammyProwler.class)); @@ -52,6 +54,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Dashing Bloodsucker", 90, Rarity.UNCOMMON, mage.cards.d.DashingBloodsucker.class)); cards.add(new SetCardInfo("Defiant Survivor", 175, Rarity.UNCOMMON, mage.cards.d.DefiantSurvivor.class)); cards.add(new SetCardInfo("Demonic Counsel", 92, Rarity.RARE, mage.cards.d.DemonicCounsel.class)); + cards.add(new SetCardInfo("Dissection Tools", 245, Rarity.RARE, mage.cards.d.DissectionTools.class)); 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("Doomsday Excruciator", 94, Rarity.RARE, mage.cards.d.DoomsdayExcruciator.class)); @@ -64,11 +67,14 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Enduring Tenacity", 95, Rarity.RARE, mage.cards.e.EnduringTenacity.class)); cards.add(new SetCardInfo("Enduring Vitality", 176, Rarity.RARE, mage.cards.e.EnduringVitality.class)); cards.add(new SetCardInfo("Enter the Enigma", 52, Rarity.COMMON, mage.cards.e.EnterTheEnigma.class)); + cards.add(new SetCardInfo("Entity Tracker", 53, Rarity.RARE, mage.cards.e.EntityTracker.class)); + cards.add(new SetCardInfo("Erratic Apparition", 54, Rarity.COMMON, mage.cards.e.ErraticApparition.class)); cards.add(new SetCardInfo("Etched Cornfield", 258, Rarity.COMMON, mage.cards.e.EtchedCornfield.class)); cards.add(new SetCardInfo("Ethereal Armor", 7, Rarity.UNCOMMON, mage.cards.e.EtherealArmor.class)); cards.add(new SetCardInfo("Exorcise", 8, Rarity.UNCOMMON, mage.cards.e.Exorcise.class)); cards.add(new SetCardInfo("Fanatic of the Harrowing", 96, Rarity.COMMON, mage.cards.f.FanaticOfTheHarrowing.class)); cards.add(new SetCardInfo("Fear of Being Hunted", 134, Rarity.UNCOMMON, mage.cards.f.FearOfBeingHunted.class)); + cards.add(new SetCardInfo("Fear of Exposure", 177, Rarity.UNCOMMON, mage.cards.f.FearOfExposure.class)); cards.add(new SetCardInfo("Fear of Failed Tests", 55, Rarity.UNCOMMON, mage.cards.f.FearOfFailedTests.class)); cards.add(new SetCardInfo("Fear of Falling", 56, Rarity.UNCOMMON, mage.cards.f.FearOfFalling.class)); cards.add(new SetCardInfo("Fear of Immobility", 10, Rarity.COMMON, mage.cards.f.FearOfImmobility.class)); @@ -87,6 +93,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Frantic Strength", 179, Rarity.COMMON, mage.cards.f.FranticStrength.class)); cards.add(new SetCardInfo("Friendly Ghost", 12, Rarity.COMMON, mage.cards.f.FriendlyGhost.class)); cards.add(new SetCardInfo("Friendly Teddy", 247, Rarity.COMMON, mage.cards.f.FriendlyTeddy.class)); + cards.add(new SetCardInfo("Get Out", 60, Rarity.UNCOMMON, mage.cards.g.GetOut.class)); cards.add(new SetCardInfo("Give In to Violence", 101, Rarity.COMMON, mage.cards.g.GiveInToViolence.class)); cards.add(new SetCardInfo("Glimmer Seeker", 14, Rarity.UNCOMMON, mage.cards.g.GlimmerSeeker.class)); cards.add(new SetCardInfo("Glimmerlight", 249, Rarity.COMMON, mage.cards.g.Glimmerlight.class)); @@ -98,6 +105,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Hand That Feeds", 139, Rarity.COMMON, mage.cards.h.HandThatFeeds.class)); cards.add(new SetCardInfo("Hardened Escort", 16, Rarity.COMMON, mage.cards.h.HardenedEscort.class)); cards.add(new SetCardInfo("Hedge Shredder", 183, Rarity.RARE, mage.cards.h.HedgeShredder.class)); + cards.add(new SetCardInfo("Horrid Vigor", 184, Rarity.COMMON, mage.cards.h.HorridVigor.class)); cards.add(new SetCardInfo("House Cartographer", 185, Rarity.UNCOMMON, mage.cards.h.HouseCartographer.class)); cards.add(new SetCardInfo("Hushwood Verge", 261, Rarity.RARE, mage.cards.h.HushwoodVerge.class)); cards.add(new SetCardInfo("Impossible Inferno", 140, Rarity.COMMON, mage.cards.i.ImpossibleInferno.class)); @@ -106,6 +114,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Insidious Fungus", 186, Rarity.UNCOMMON, mage.cards.i.InsidiousFungus.class)); cards.add(new SetCardInfo("Intruding Soulrager", 218, Rarity.UNCOMMON, mage.cards.i.IntrudingSoulrager.class)); cards.add(new SetCardInfo("Island", 273, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); + cards.add(new SetCardInfo("Killer's Mask", 104, Rarity.UNCOMMON, mage.cards.k.KillersMask.class)); cards.add(new SetCardInfo("Kona, Rescue Beastie", 187, Rarity.RARE, mage.cards.k.KonaRescueBeastie.class)); cards.add(new SetCardInfo("Lakeside Shack", 262, Rarity.COMMON, mage.cards.l.LakesideShack.class)); cards.add(new SetCardInfo("Let's Play a Game", 105, Rarity.UNCOMMON, mage.cards.l.LetsPlayAGame.class)); @@ -115,9 +124,11 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Leyline of the Void", 106, Rarity.RARE, mage.cards.l.LeylineOfTheVoid.class)); cards.add(new SetCardInfo("Lionheart Glimmer", 19, Rarity.UNCOMMON, mage.cards.l.LionheartGlimmer.class)); cards.add(new SetCardInfo("Live or Die", 107, Rarity.UNCOMMON, mage.cards.l.LiveOrDie.class)); + cards.add(new SetCardInfo("Living Phone", 20, Rarity.COMMON, mage.cards.l.LivingPhone.class)); cards.add(new SetCardInfo("Malevolent Chandelier", 252, Rarity.COMMON, mage.cards.m.MalevolentChandelier.class)); cards.add(new SetCardInfo("Manifest Dread", 189, Rarity.COMMON, mage.cards.m.ManifestDread.class)); cards.add(new SetCardInfo("Marina Vendrell's Grimoire", 64, Rarity.RARE, mage.cards.m.MarinaVendrellsGrimoire.class)); + cards.add(new SetCardInfo("Miasma Demon", 109, Rarity.UNCOMMON, mage.cards.m.MiasmaDemon.class)); cards.add(new SetCardInfo("Midnight Mayhem", 222, Rarity.UNCOMMON, mage.cards.m.MidnightMayhem.class)); cards.add(new SetCardInfo("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)); @@ -128,6 +139,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Oblivious Bookworm", 225, Rarity.UNCOMMON, mage.cards.o.ObliviousBookworm.class)); cards.add(new SetCardInfo("Optimistic Scavenger", 21, Rarity.UNCOMMON, mage.cards.o.OptimisticScavenger.class)); cards.add(new SetCardInfo("Orphans of the Wheat", 22, Rarity.UNCOMMON, mage.cards.o.OrphansOfTheWheat.class)); + cards.add(new SetCardInfo("Overlord of the Balemurk", 113, Rarity.MYTHIC, mage.cards.o.OverlordOfTheBalemurk.class)); cards.add(new SetCardInfo("Overlord of the Boilerbilges", 146, Rarity.MYTHIC, mage.cards.o.OverlordOfTheBoilerbilges.class)); cards.add(new SetCardInfo("Overlord of the Floodpits", 68, Rarity.MYTHIC, mage.cards.o.OverlordOfTheFloodpits.class)); cards.add(new SetCardInfo("Overlord of the Hauntwoods", 194, Rarity.MYTHIC, mage.cards.o.OverlordOfTheHauntwoods.class)); @@ -148,10 +160,12 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Razorkin Needlehead", 153, Rarity.RARE, mage.cards.r.RazorkinNeedlehead.class)); cards.add(new SetCardInfo("Razortrap Gorge", 267, Rarity.COMMON, mage.cards.r.RazortrapGorge.class)); cards.add(new SetCardInfo("Resurrected Cultist", 115, Rarity.COMMON, mage.cards.r.ResurrectedCultist.class)); + 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("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("Sawblade Skinripper", 231, Rarity.UNCOMMON, mage.cards.s.SawbladeSkinripper.class)); + cards.add(new SetCardInfo("Scorching Dragonfire", 156, Rarity.COMMON, mage.cards.s.ScorchingDragonfire.class)); cards.add(new SetCardInfo("Scrabbling Skullcrab", 71, Rarity.UNCOMMON, mage.cards.s.ScrabblingSkullcrab.class)); cards.add(new SetCardInfo("Screaming Nemesis", 157, Rarity.MYTHIC, mage.cards.s.ScreamingNemesis.class)); cards.add(new SetCardInfo("Shardmage's Rescue", 29, Rarity.UNCOMMON, mage.cards.s.ShardmagesRescue.class)); @@ -182,6 +196,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Twitching Doll", 201, Rarity.RARE, mage.cards.t.TwitchingDoll.class)); cards.add(new SetCardInfo("Tyvar, the Pummeler", 202, Rarity.MYTHIC, mage.cards.t.TyvarThePummeler.class)); cards.add(new SetCardInfo("Under the Skin", 203, Rarity.UNCOMMON, mage.cards.u.UnderTheSkin.class)); + cards.add(new SetCardInfo("Unnerving Grasp", 80, Rarity.UNCOMMON, mage.cards.u.UnnervingGrasp.class)); cards.add(new SetCardInfo("Unsettling Twins", 38, Rarity.COMMON, mage.cards.u.UnsettlingTwins.class)); cards.add(new SetCardInfo("Untimely Malfunction", 161, Rarity.UNCOMMON, mage.cards.u.UntimelyMalfunction.class)); cards.add(new SetCardInfo("Unwanted Remake", 39, Rarity.UNCOMMON, mage.cards.u.UnwantedRemake.class)); @@ -195,9 +210,11 @@ public final class DuskmournHouseOfHorror extends ExpansionSet { cards.add(new SetCardInfo("Vicious Clown", 163, Rarity.COMMON, mage.cards.v.ViciousClown.class)); cards.add(new SetCardInfo("Victor, Valgavoth's Seneschal", 238, Rarity.RARE, mage.cards.v.VictorValgavothsSeneschal.class)); cards.add(new SetCardInfo("Vile Mutilator", 122, Rarity.UNCOMMON, mage.cards.v.VileMutilator.class)); + cards.add(new SetCardInfo("Violent Urge", 164, Rarity.UNCOMMON, mage.cards.v.ViolentUrge.class)); cards.add(new SetCardInfo("Wary Watchdog", 206, Rarity.COMMON, mage.cards.w.WaryWatchdog.class)); cards.add(new SetCardInfo("Wickerfolk Thresher", 207, Rarity.UNCOMMON, mage.cards.w.WickerfolkThresher.class)); cards.add(new SetCardInfo("Wildfire Wickerfolk", 239, Rarity.UNCOMMON, mage.cards.w.WildfireWickerfolk.class)); + cards.add(new SetCardInfo("Winter's Intervention", 123, Rarity.COMMON, mage.cards.w.WintersIntervention.class)); cards.add(new SetCardInfo("Winter, Misanthropic Guide", 240, Rarity.RARE, mage.cards.w.WinterMisanthropicGuide.class)); cards.add(new SetCardInfo("Withering Torment", 124, Rarity.UNCOMMON, mage.cards.w.WitheringTorment.class)); cards.add(new SetCardInfo("Zimone, All-Questioning", 241, Rarity.RARE, mage.cards.z.ZimoneAllQuestioning.class)); diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java index 20a3640d974..293ed4ce304 100644 --- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java +++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java @@ -19,30 +19,167 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet { super("Duskmourn: House of Horror Commander", "DSC", ExpansionSet.buildDate(2024, 9, 27), SetType.SUPPLEMENTAL); this.hasBasicLands = false; + cards.add(new SetCardInfo("Adarkar Wastes", 258, Rarity.RARE, mage.cards.a.AdarkarWastes.class)); + 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("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)); + 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)); + cards.add(new SetCardInfo("Ashaya, Soul of the Wild", 170, Rarity.MYTHIC, mage.cards.a.AshayaSoulOfTheWild.class)); + cards.add(new SetCardInfo("Athreos, Shroud-Veiled", 212, Rarity.MYTHIC, mage.cards.a.AthreosShroudVeiled.class)); + cards.add(new SetCardInfo("Augur of Autumn", 171, Rarity.RARE, mage.cards.a.AugurOfAutumn.class)); + 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("Beanstalk Giant", 172, Rarity.UNCOMMON, mage.cards.b.BeanstalkGiant.class)); cards.add(new SetCardInfo("Beast Within", 80, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); + cards.add(new SetCardInfo("Bedevil", 84, Rarity.RARE, mage.cards.b.Bedevil.class)); + cards.add(new SetCardInfo("Biomass Mutation", 214, Rarity.RARE, mage.cards.b.BiomassMutation.class)); + cards.add(new SetCardInfo("Blood Pact", 76, Rarity.COMMON, mage.cards.b.BloodPact.class)); + cards.add(new SetCardInfo("Blood Seeker", 77, Rarity.COMMON, mage.cards.b.BloodSeeker.class)); + cards.add(new SetCardInfo("Body of Knowledge", 112, Rarity.RARE, mage.cards.b.BodyOfKnowledge.class)); + cards.add(new SetCardInfo("Bojuka Bog", 265, Rarity.COMMON, mage.cards.b.BojukaBog.class)); + cards.add(new SetCardInfo("Brainstone", 242, Rarity.UNCOMMON, mage.cards.b.Brainstone.class)); + cards.add(new SetCardInfo("Brainstorm", 113, Rarity.COMMON, mage.cards.b.Brainstorm.class)); + cards.add(new SetCardInfo("Burnished Hart", 243, Rarity.UNCOMMON, mage.cards.b.BurnishedHart.class)); cards.add(new SetCardInfo("Cackling Counterpart", 72, Rarity.RARE, mage.cards.c.CacklingCounterpart.class)); + cards.add(new SetCardInfo("Cast Out", 98, Rarity.UNCOMMON, mage.cards.c.CastOut.class)); + cards.add(new SetCardInfo("Castle Vantress", 267, Rarity.RARE, mage.cards.c.CastleVantress.class)); + cards.add(new SetCardInfo("Caves of Koilos", 268, Rarity.RARE, mage.cards.c.CavesOfKoilos.class)); cards.add(new SetCardInfo("Citanul Hierophants", 81, Rarity.RARE, mage.cards.c.CitanulHierophants.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("Counterspell", 114, Rarity.COMMON, mage.cards.c.Counterspell.class)); cards.add(new SetCardInfo("Crypt Ghast", 368, Rarity.MYTHIC, mage.cards.c.CryptGhast.class)); + cards.add(new SetCardInfo("Cultivate", 174, Rarity.COMMON, mage.cards.c.Cultivate.class)); cards.add(new SetCardInfo("Damn", 369, Rarity.MYTHIC, mage.cards.d.Damn.class)); + 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("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("Demon of Fate's Design", 137, Rarity.RARE, mage.cards.d.DemonOfFatesDesign.class)); 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("Doomwake Giant", 138, Rarity.RARE, mage.cards.d.DoomwakeGiant.class)); + cards.add(new SetCardInfo("Dream Eater", 116, Rarity.MYTHIC, mage.cards.d.DreamEater.class)); + cards.add(new SetCardInfo("Drownyard Temple", 272, Rarity.RARE, mage.cards.d.DrownyardTemple.class)); + cards.add(new SetCardInfo("Entreat the Angels", 99, Rarity.MYTHIC, mage.cards.e.EntreatTheAngels.class)); + cards.add(new SetCardInfo("Eureka Moment", 216, Rarity.COMMON, mage.cards.e.EurekaMoment.class)); + 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("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("Feed the Swarm", 78, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class)); + cards.add(new SetCardInfo("Flooded Grove", 276, Rarity.RARE, mage.cards.f.FloodedGrove.class)); + cards.add(new SetCardInfo("Gleeful Arsonist", 27, Rarity.RARE, mage.cards.g.GleefulArsonist.class)); 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("Greater Tanuki", 181, Rarity.COMMON, mage.cards.g.GreaterTanuki.class)); cards.add(new SetCardInfo("Growth Spiral", 88, Rarity.COMMON, mage.cards.g.GrowthSpiral.class)); + cards.add(new SetCardInfo("Halimar Depths", 282, Rarity.COMMON, mage.cards.h.HalimarDepths.class)); + cards.add(new SetCardInfo("Hall of Heliod's Generosity", 283, Rarity.RARE, mage.cards.h.HallOfHeliodsGenerosity.class)); + cards.add(new SetCardInfo("Hinterland Harbor", 284, Rarity.RARE, mage.cards.h.HinterlandHarbor.class)); + cards.add(new SetCardInfo("Hydra Omnivore", 185, Rarity.MYTHIC, mage.cards.h.HydraOmnivore.class)); + cards.add(new SetCardInfo("Inkshield", 221, Rarity.RARE, mage.cards.i.Inkshield.class)); + cards.add(new SetCardInfo("Kefnet the Mindful", 118, Rarity.MYTHIC, mage.cards.k.KefnetTheMindful.class)); + cards.add(new SetCardInfo("Kheru Spellsnatcher", 119, Rarity.RARE, mage.cards.k.KheruSpellsnatcher.class)); + cards.add(new SetCardInfo("Life Insurance", 224, Rarity.RARE, mage.cards.l.LifeInsurance.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)); 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("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)); + cards.add(new SetCardInfo("Moldgraf Monstrosity", 83, Rarity.RARE, mage.cards.m.MoldgrafMonstrosity.class)); + cards.add(new SetCardInfo("Monologue Tax", 100, Rarity.RARE, mage.cards.m.MonologueTax.class)); cards.add(new SetCardInfo("Moon-Blessed Cleric", 69, Rarity.UNCOMMON, mage.cards.m.MoonBlessedCleric.class)); + cards.add(new SetCardInfo("Mosswort Bridge", 288, Rarity.RARE, mage.cards.m.MosswortBridge.class)); + cards.add(new SetCardInfo("Multani, Yavimaya's Avatar", 190, Rarity.MYTHIC, mage.cards.m.MultaniYavimayasAvatar.class)); + cards.add(new SetCardInfo("Myriad Landscape", 289, Rarity.UNCOMMON, mage.cards.m.MyriadLandscape.class)); + cards.add(new SetCardInfo("Night's Whisper", 79, Rarity.COMMON, mage.cards.n.NightsWhisper.class)); + cards.add(new SetCardInfo("Nightmare Shepherd", 149, Rarity.RARE, mage.cards.n.NightmareShepherd.class)); + cards.add(new SetCardInfo("Obscura Storefront", 291, Rarity.COMMON, mage.cards.o.ObscuraStorefront.class)); + cards.add(new SetCardInfo("Ondu Spiritdancer", 101, Rarity.RARE, mage.cards.o.OnduSpiritdancer.class)); + cards.add(new SetCardInfo("One with the Multiverse", 121, Rarity.MYTHIC, mage.cards.o.OneWithTheMultiverse.class)); + cards.add(new SetCardInfo("Orzhov Basilica", 292, Rarity.UNCOMMON, mage.cards.o.OrzhovBasilica.class)); + cards.add(new SetCardInfo("Orzhov Signet", 249, Rarity.UNCOMMON, mage.cards.o.OrzhovSignet.class)); + cards.add(new SetCardInfo("Otherworldly Gaze", 122, Rarity.COMMON, mage.cards.o.OtherworldlyGaze.class)); + 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("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)); + cards.add(new SetCardInfo("Prognostic Sphinx", 124, Rarity.RARE, mage.cards.p.PrognosticSphinx.class)); + cards.add(new SetCardInfo("Putrefy", 90, Rarity.UNCOMMON, mage.cards.p.Putrefy.class)); + cards.add(new SetCardInfo("Quandrix Campus", 294, Rarity.COMMON, mage.cards.q.QuandrixCampus.class)); + cards.add(new SetCardInfo("Rampant Growth", 193, Rarity.COMMON, mage.cards.r.RampantGrowth.class)); + cards.add(new SetCardInfo("Rashmi, Eternities Crafter", 231, Rarity.MYTHIC, mage.cards.r.RashmiEternitiesCrafter.class)); + 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("Reliquary Tower", 295, Rarity.UNCOMMON, mage.cards.r.ReliquaryTower.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("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("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("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("Sigil of the Empty Throne", 103, Rarity.RARE, mage.cards.s.SigilOfTheEmptyThrone.class)); + cards.add(new SetCardInfo("Simic Growth Chamber", 298, Rarity.UNCOMMON, mage.cards.s.SimicGrowthChamber.class)); + cards.add(new SetCardInfo("Simic Signet", 252, Rarity.UNCOMMON, mage.cards.s.SimicSignet.class)); + cards.add(new SetCardInfo("Skaab Ruinator", 128, Rarity.MYTHIC, mage.cards.s.SkaabRuinator.class)); 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("Spirit-Sister's Call", 232, Rarity.MYTHIC, mage.cards.s.SpiritSistersCall.class)); + cards.add(new SetCardInfo("Starfield Mystic", 105, Rarity.RARE, mage.cards.s.StarfieldMystic.class)); + cards.add(new SetCardInfo("Suspicious Bookcase", 95, Rarity.COMMON, mage.cards.s.SuspiciousBookcase.class)); + cards.add(new SetCardInfo("Swords to Plowshares", 106, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class)); + cards.add(new SetCardInfo("Tainted Field", 302, Rarity.UNCOMMON, mage.cards.t.TaintedField.class)); + cards.add(new SetCardInfo("Tainted Isle", 303, Rarity.UNCOMMON, mage.cards.t.TaintedIsle.class)); + cards.add(new SetCardInfo("Tangled Islet", 306, Rarity.COMMON, mage.cards.t.TangledIslet.class)); + cards.add(new SetCardInfo("Tatyova, Benthic Druid", 235, Rarity.UNCOMMON, mage.cards.t.TatyovaBenthicDruid.class)); cards.add(new SetCardInfo("Telling Time", 75, Rarity.UNCOMMON, mage.cards.t.TellingTime.class)); + cards.add(new SetCardInfo("Temple of Deceit", 307, Rarity.RARE, mage.cards.t.TempleOfDeceit.class)); + cards.add(new SetCardInfo("Temple of Enlightenment", 308, Rarity.RARE, mage.cards.t.TempleOfEnlightenment.class)); + cards.add(new SetCardInfo("Temple of Mystery", 311, Rarity.RARE, mage.cards.t.TempleOfMystery.class)); + cards.add(new SetCardInfo("Temple of Silence", 312, Rarity.RARE, mage.cards.t.TempleOfSilence.class)); + cards.add(new SetCardInfo("Temple of the False God", 313, Rarity.UNCOMMON, mage.cards.t.TempleOfTheFalseGod.class)); + cards.add(new SetCardInfo("Temur War Shaman", 200, Rarity.RARE, mage.cards.t.TemurWarShaman.class)); cards.add(new SetCardInfo("Terminus", 70, Rarity.RARE, mage.cards.t.Terminus.class)); + cards.add(new SetCardInfo("The Eldest Reborn", 139, Rarity.UNCOMMON, mage.cards.t.TheEldestReborn.class)); cards.add(new SetCardInfo("They Came from the Pipes", 14, Rarity.RARE, mage.cards.t.TheyCameFromThePipes.class)); + 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("Thriving Heath", 315, Rarity.COMMON, mage.cards.t.ThrivingHeath.class)); + cards.add(new SetCardInfo("Thriving Isle", 316, Rarity.COMMON, mage.cards.t.ThrivingIsle.class)); + cards.add(new SetCardInfo("Thriving Moor", 317, Rarity.COMMON, mage.cards.t.ThrivingMoor.class)); + cards.add(new SetCardInfo("Time Wipe", 237, Rarity.RARE, mage.cards.t.TimeWipe.class)); + cards.add(new SetCardInfo("Timely Ward", 107, Rarity.RARE, mage.cards.t.TimelyWard.class)); + cards.add(new SetCardInfo("Trail of Mystery", 203, Rarity.RARE, mage.cards.t.TrailOfMystery.class)); + cards.add(new SetCardInfo("Trygon Predator", 238, Rarity.UNCOMMON, mage.cards.t.TrygonPredator.class)); + cards.add(new SetCardInfo("Underground River", 321, Rarity.RARE, mage.cards.u.UndergroundRiver.class)); cards.add(new SetCardInfo("Utter End", 91, Rarity.RARE, mage.cards.u.UtterEnd.class)); + cards.add(new SetCardInfo("Verge Rangers", 108, Rarity.RARE, mage.cards.v.VergeRangers.class)); + cards.add(new SetCardInfo("Vineglimmer Snarl", 323, Rarity.RARE, mage.cards.v.VineglimmerSnarl.class)); + cards.add(new SetCardInfo("Whisperwood Elemental", 204, Rarity.MYTHIC, mage.cards.w.WhisperwoodElemental.class)); + cards.add(new SetCardInfo("Wilderness Reclamation", 205, Rarity.UNCOMMON, mage.cards.w.WildernessReclamation.class)); + cards.add(new SetCardInfo("Worldspine Wurm", 206, Rarity.MYTHIC, mage.cards.w.WorldspineWurm.class)); + cards.add(new SetCardInfo("Yavimaya Coast", 327, Rarity.RARE, mage.cards.y.YavimayaCoast.class)); + cards.add(new SetCardInfo("Yavimaya Elder", 208, Rarity.COMMON, mage.cards.y.YavimayaElder.class)); + cards.add(new SetCardInfo("Yedora, Grave Gardener", 209, Rarity.UNCOMMON, mage.cards.y.YedoraGraveGardener.class)); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/utils/DebugUtilTest.java b/Mage.Tests/src/test/java/org/mage/test/utils/DebugUtilTest.java new file mode 100644 index 00000000000..45ff3069e33 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/utils/DebugUtilTest.java @@ -0,0 +1,30 @@ +package org.mage.test.utils; + +import mage.util.DebugUtil; +import org.junit.Assert; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author JayDi85 + */ +public class DebugUtilTest extends CardTestPlayerBase { + + private void firstMethod() { + secondMethod(); + } + + private void secondMethod() { + String resCurrent = DebugUtil.getMethodNameWithSource(0); + String resPrev = DebugUtil.getMethodNameWithSource(1); + String resPrevPrev = DebugUtil.getMethodNameWithSource(2); + Assert.assertTrue("must find secondMethod, but get " + resCurrent, resCurrent.startsWith("secondMethod")); + Assert.assertTrue("must find firstMethod, but get " + resPrev, resPrev.startsWith("firstMethod")); + Assert.assertTrue("must find test_StackTraceWithSourceName, but get " + resPrevPrev, resPrevPrev.startsWith("test_StackTraceWithSourceName")); + } + + @Test + public void test_StackTraceWithSourceName() { + firstMethod(); + } +} diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index ca45bc385d1..7202d3d882d 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -142,16 +142,14 @@ public class VerifyCardDataTest { skipListAddName(SKIP_LIST_TYPE, "UNH", "Old Fogey"); // uses summon word as a joke card skipListAddName(SKIP_LIST_TYPE, "UND", "Old Fogey"); skipListAddName(SKIP_LIST_TYPE, "UST", "capital offense"); // uses "instant" instead "Instant" as a joke card - skipListAddName(SKIP_LIST_TYPE, "DSK", "Balustrade Wurm"); // temporary - skipListAddName(SKIP_LIST_TYPE, "DSK", "Spineseeker Centipede"); // temporary + skipListAddName(SKIP_LIST_TYPE, "DSK", "Balemurk Leech"); // temporary // subtype // skipListAddName(SKIP_LIST_SUBTYPE, set, cardName); skipListAddName(SKIP_LIST_SUBTYPE, "UGL", "Miss Demeanor"); // uses multiple types as a joke card: Lady, of, Proper, Etiquette skipListAddName(SKIP_LIST_SUBTYPE, "UGL", "Elvish Impersonators"); // subtype is "Elves" pun skipListAddName(SKIP_LIST_SUBTYPE, "UND", "Elvish Impersonators"); - skipListAddName(SKIP_LIST_SUBTYPE, "DSK", "Balustrade Wurm"); // temporary - skipListAddName(SKIP_LIST_SUBTYPE, "DSK", "Spineseeker Centipede"); // temporary + skipListAddName(SKIP_LIST_SUBTYPE, "DSK", "Balemurk Leech"); // temporary // number // skipListAddName(SKIP_LIST_NUMBER, set, cardName); diff --git a/Mage/src/main/java/mage/abilities/Modes.java b/Mage/src/main/java/mage/abilities/Modes.java index 6fb4f30d168..bff1f93530a 100644 --- a/Mage/src/main/java/mage/abilities/Modes.java +++ b/Mage/src/main/java/mage/abilities/Modes.java @@ -38,6 +38,7 @@ public class Modes extends LinkedHashMap implements Copyable private int maxPawPrints; private Filter maxModesFilter; // calculates the max number of available modes private Condition moreCondition; // allows multiple modes choose (example: choose one... if condition, you may choose both) + private int moreLimit = Integer.MAX_VALUE; // if multiple modes are allowed, this limits how many additional modes may be chosen (usually doesn't need to change) private boolean limitUsageByOnce = false; // limit mode selection to once per game private boolean limitUsageResetOnNewTurn = false; // reset once per game limit on new turn, example: Galadriel, Light of Valinor @@ -73,6 +74,7 @@ public class Modes extends LinkedHashMap implements Copyable this.maxPawPrints = modes.maxPawPrints; this.maxModesFilter = modes.maxModesFilter; // can't change so no copy needed this.moreCondition = modes.moreCondition; + this.moreLimit = modes.moreLimit; this.limitUsageByOnce = modes.limitUsageByOnce; this.limitUsageResetOnNewTurn = modes.limitUsageResetOnNewTurn; @@ -197,7 +199,7 @@ public class Modes extends LinkedHashMap implements Copyable return count; } - public int getSelectedPawPrints(){ + public int getSelectedPawPrints() { return this.selectedModes.stream() .mapToInt(modeID -> get(modeID).getPawPrintValue()) .sum(); @@ -241,9 +243,9 @@ public class Modes extends LinkedHashMap implements Copyable return realMaxModes; } - // use case: make two modes chooseable (all cards that use this currently go from one to two) + // use case: make more modes chooseable if (moreCondition != null && moreCondition.apply(game, source)) { - realMaxModes = 2; + realMaxModes = this.moreLimit; } // use case: limit max modes by opponents (example: choose one or more... each mode must target a different player) @@ -292,10 +294,10 @@ public class Modes extends LinkedHashMap implements Copyable } public void addMode(Mode mode) { - if (this.maxPawPrints > 0 && mode.getPawPrintValue() == 0){ + if (this.maxPawPrints > 0 && mode.getPawPrintValue() == 0) { throw new IllegalArgumentException("Mode must have nonzero pawprints value in a pawprints mode set."); } - if (this.maxPawPrints == 0 && mode.getPawPrintValue() > 0){ + if (this.maxPawPrints == 0 && mode.getPawPrintValue() > 0) { throw new IllegalArgumentException("Cannot add pawprints mode to non-pawprints mode set."); } this.put(mode.getId(), mode); @@ -305,6 +307,10 @@ public class Modes extends LinkedHashMap implements Copyable this.moreCondition = moreCondition; } + public void setMoreLimit(int moreLimit) { + this.moreLimit = moreLimit; + } + private boolean isAlreadySelectedModesOutdated(Game game, Ability source) { return this.isLimitUsageResetOnNewTurn() && getOnceTurnNum(game, source) != game.getTurnNum(); @@ -552,7 +558,7 @@ public class Modes extends LinkedHashMap implements Copyable if (isLimitUsageByOnce() && nonAvailableModes.contains(mode.getId())) { continue; } - if (getMaxPawPrints() > 0 && getSelectedPawPrints() + mode.getPawPrintValue() > getMaxPawPrints()){ + if (getMaxPawPrints() > 0 && getSelectedPawPrints() + mode.getPawPrintValue() > getMaxPawPrints()) { continue; } availableModes.add(mode); @@ -574,7 +580,7 @@ public class Modes extends LinkedHashMap implements Copyable } sb.append("choose "); } - if (this.getMaxPawPrints() > 0){ + if (this.getMaxPawPrints() > 0) { sb.append("up to ").append(CardUtil.numberToText(this.getMaxPawPrints())).append(" {P} worth of modes"); } else if (this.getMinModes() == 0 && this.getMaxModes(null, null) == 1) { sb.append("up to one"); @@ -620,7 +626,7 @@ public class Modes extends LinkedHashMap implements Copyable sb.append(mode.getCost().getText()); sb.append(" — "); } else if (mode.getPawPrintValue() > 0) { - for (int i = 0; i < mode.getPawPrintValue(); ++i){ + for (int i = 0; i < mode.getPawPrintValue(); ++i) { sb.append("{P}"); } sb.append(" — "); diff --git a/Mage/src/main/java/mage/abilities/decorator/ConditionalTriggeredAbility.java b/Mage/src/main/java/mage/abilities/decorator/ConditionalTriggeredAbility.java index 455af0a5f2a..cb12f7b2b66 100644 --- a/Mage/src/main/java/mage/abilities/decorator/ConditionalTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/decorator/ConditionalTriggeredAbility.java @@ -10,6 +10,7 @@ import mage.abilities.effects.Effects; import mage.constants.EffectType; import mage.game.Game; import mage.game.events.GameEvent; +import mage.util.CardUtil; import mage.watchers.Watcher; import java.util.List; @@ -71,7 +72,9 @@ public class ConditionalTriggeredAbility extends TriggeredAbilityImpl { if (abilityText == null || abilityText.isEmpty()) { return ability.getRule(); } - return abilityText; + return (flavorWord != null ? CardUtil.italicizeWithEmDash(flavorWord) : "") + + (abilityWord != null ? abilityWord.formatWord() : "") + + abilityText + (abilityText.endsWith(".") || abilityText.endsWith("\"") || abilityText.endsWith(">") ? "" : "."); } @Override diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java index 0b929f78f4a..c1cdd545214 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LoseAbilityTargetEffect.java @@ -1,4 +1,3 @@ - package mage.abilities.effects.common.continuous; import mage.abilities.Ability; @@ -12,16 +11,14 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.CardUtil; +import java.util.UUID; + /** * @author jeffwadsworth */ public class LoseAbilityTargetEffect extends ContinuousEffectImpl { - protected Ability ability; - - public LoseAbilityTargetEffect(Ability ability) { - this(ability, Duration.WhileOnBattlefield); - } + private final Ability ability; public LoseAbilityTargetEffect(Ability ability, Duration duration) { super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.LoseAbility); @@ -40,11 +37,15 @@ public class LoseAbilityTargetEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - permanent.removeAbility(ability, source.getSourceId(), game); + boolean result = false; + for (UUID uuid : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(uuid); + if (permanent != null) { + permanent.removeAbility(ability, source.getSourceId(), game); + result = true; + } } - return true; + return result; } @Override diff --git a/Mage/src/main/java/mage/constants/TargetController.java b/Mage/src/main/java/mage/constants/TargetController.java index ffd672f28f8..2737b52adba 100644 --- a/Mage/src/main/java/mage/constants/TargetController.java +++ b/Mage/src/main/java/mage/constants/TargetController.java @@ -83,6 +83,8 @@ public enum TargetController { return card.isOwnedBy(input.getSource().getControllerId()); case SOURCE_TARGETS: return card.isOwnedBy(input.getSource().getFirstTarget()); + case ACTIVE: + return card.isOwnedBy(game.getActivePlayerId()); case MONARCH: return card.isOwnedBy(game.getMonarchId()); case ANY: @@ -126,6 +128,8 @@ public enum TargetController { return player.getId().equals(input.getSource().getControllerId()); case SOURCE_TARGETS: return player.getId().equals(input.getSource().getFirstTarget()); + case ACTIVE: + return game.isActivePlayer(player.getId()); case MONARCH: return player.getId().equals(game.getMonarchId()); default: diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 17e1f1bea73..d4e86a19c30 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -360,6 +360,7 @@ public final class StaticFilters { public static final FilterPermanent FILTER_PERMANENT_ANOTHER_CREATURE_OR_ENCHANTMENT = new FilterPermanent("another creature or enchantment"); static { + FILTER_PERMANENT_ANOTHER_CREATURE_OR_ENCHANTMENT.add(AnotherPredicate.instance); FILTER_PERMANENT_ANOTHER_CREATURE_OR_ENCHANTMENT.add(Predicates.or( CardType.CREATURE.getPredicate(), CardType.ENCHANTMENT.getPredicate() diff --git a/Mage/src/main/java/mage/filter/common/FilterLandCard.java b/Mage/src/main/java/mage/filter/common/FilterLandCard.java index 12104450149..2fe2b9b82ac 100644 --- a/Mage/src/main/java/mage/filter/common/FilterLandCard.java +++ b/Mage/src/main/java/mage/filter/common/FilterLandCard.java @@ -1,9 +1,6 @@ - - package mage.filter.common; import mage.constants.CardType; -import mage.constants.SuperType; import mage.filter.FilterCard; /** @@ -20,12 +17,6 @@ public class FilterLandCard extends FilterCard { this.add(CardType.LAND.getPredicate()); } - public static FilterLandCard basicLandCard() { - FilterLandCard filter = new FilterLandCard("basic land card"); - filter.add(SuperType.BASIC.getPredicate()); - return filter; - } - protected FilterLandCard(final FilterLandCard filter) { super(filter); } diff --git a/Mage/src/main/java/mage/game/permanent/token/InsectBlackGreenFlyingToken.java b/Mage/src/main/java/mage/game/permanent/token/InsectBlackGreenFlyingToken.java new file mode 100644 index 00000000000..94c906461da --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/InsectBlackGreenFlyingToken.java @@ -0,0 +1,31 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author TheElk801 + */ +public final class InsectBlackGreenFlyingToken extends TokenImpl { + + public InsectBlackGreenFlyingToken() { + super("Insect Token", "1/1 black and green Insect creature token with flying"); + cardType.add(CardType.CREATURE); + color.setBlack(true); + color.setGreen(true); + subtype.add(SubType.INSECT); + power = new MageInt(1); + toughness = new MageInt(1); + this.addAbility(FlyingAbility.getInstance()); + } + + private InsectBlackGreenFlyingToken(final InsectBlackGreenFlyingToken token) { + super(token); + } + + public InsectBlackGreenFlyingToken copy() { + return new InsectBlackGreenFlyingToken(this); + } +} diff --git a/Mage/src/main/java/mage/game/permanent/token/OozeToken.java b/Mage/src/main/java/mage/game/permanent/token/OozeToken.java index cb1e9fffb3b..ae3a6ae9bfd 100644 --- a/Mage/src/main/java/mage/game/permanent/token/OozeToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/OozeToken.java @@ -7,7 +7,7 @@ import mage.constants.SubType; public final class OozeToken extends TokenImpl { public OozeToken(int power, int toughness) { - super("Ooze Token", power + "/" + toughness + " green ooze creature token"); + super("Ooze Token", power + "/" + toughness + " green Ooze creature token"); cardType.add(CardType.CREATURE); color.setGreen(true); subtype.add(SubType.OOZE); @@ -16,7 +16,7 @@ public final class OozeToken extends TokenImpl { } public OozeToken() { - super("Ooze Token", "X/X green ooze creature token"); + super("Ooze Token", "X/X green Ooze creature token"); cardType.add(CardType.CREATURE); color.setGreen(true); subtype.add(SubType.OOZE); diff --git a/Mage/src/main/java/mage/util/DebugUtil.java b/Mage/src/main/java/mage/util/DebugUtil.java index 47460248fbe..51f029ca0d9 100644 --- a/Mage/src/main/java/mage/util/DebugUtil.java +++ b/Mage/src/main/java/mage/util/DebugUtil.java @@ -1,7 +1,5 @@ package mage.util; -import java.lang.reflect.Method; - /** * Devs only: enable or disable debug features *

@@ -58,46 +56,33 @@ public class DebugUtil { public static boolean NETWORK_PROFILE_REQUESTS = false; // collect diff time between requests, http status and url into special log file public static String NETWORK_PROFILE_REQUESTS_DUMP_FILE_NAME = "httpRequests.log"; - public static String getMethodNameWithSource(final int depth) { - return TraceHelper.getMethodNameWithSource(depth); + /** + * Return method and source line number like "secondMethod - DebugUtilTest.java:21" + * + * @param skipMethodsAmount use 0 to return current method info, use 1 for prev method, use 2 for prev-prev method + */ + public static String getMethodNameWithSource(final int skipMethodsAmount) { + // 3 is default methods amount to skip: + // - getMethodNameWithSource + // - TraceHelper.getMethodNameWithSource + // - Thread.currentThread().getStackTrace() + return TraceHelper.getMethodNameWithSource(3 + skipMethodsAmount); } } /** - * Debug: allows to find a caller's method name - * Original code + * Debug: allows to find a caller's method name, compatible with java 8 and 9+ + * Original code */ class TraceHelper { - private static Method m; - - static { - try { - m = Throwable.class.getDeclaredMethod("getStackTraceElement", int.class); - m.setAccessible(true); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static String getMethodName(final int depth) { - try { - StackTraceElement element = (StackTraceElement) m.invoke(new Throwable(), depth + 1); - return element.getMethodName(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - public static String getMethodNameWithSource(final int depth) { - try { - StackTraceElement element = (StackTraceElement) m.invoke(new Throwable(), depth + 1); - return String.format("%s - %s:%d", element.getMethodName(), element.getFileName(), element.getLineNumber()); - } catch (Exception e) { - e.printStackTrace(); - return null; + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + if (stackTrace.length == 0) { + return "[no access to stack]"; + } else { + return String.format("%s - %s:%d", stackTrace[depth].getMethodName(), stackTrace[depth].getFileName(), stackTrace[depth].getLineNumber()); } } } \ No newline at end of file diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index b58a60d3ac4..55ca242188c 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -53991,12 +53991,14 @@ Fear of Abduction|Duskmourn: House of Horror|9|U|{4}{W}{W}|Enchantment Creature Fear of Immobility|Duskmourn: House of Horror|10|C|{4}{W}|Enchantment Creature - Nightmare|4|4|When Fear of Immobility enters, tap up to one target creature. If an opponent controls that creature, put a stun counter on it.| Fear of Surveillance|Duskmourn: House of Horror|11|C|{1}{W}|Enchantment Creature - Nightmare|2|2|Vigilance$Whenever Fear of Surveillance attacks, surveil 1.| Friendly Ghost|Duskmourn: House of Horror|12|C|{3}{W}|Creature - Spirit|2|4|Flying$When Friendly Ghost 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 Ghostly Dancers 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 Glimmer Seeker 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|||(You may cast 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 a 1/1 white Glimmer enchantment creature token.$Elegant Rotunda${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.)$When you unlock this door, put a +1/+1 counter on each of up to two target creatures.| Hardened Escort|Duskmourn: House of Horror|16|C|{2}{W}|Creature - Human Soldier|2|4|Whenever Hardened Escort 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 Leyline of Hope 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.| Lionheart Glimmer|Duskmourn: House of Horror|19|U|{3}{W}{W}|Enchantment Creature - Cat Glimmer|2|5|Ward {2}$Whenever you attack, creatures you control get +1/+1 until end of turn.| +Living Phone|Duskmourn: House of Horror|20|C|{2}{W}|Artifact Creature - Toy|2|1|When Living Phone dies, look at the top five cards of your library. You may reveal a creature card with power 2 or less from among them and put it into your hand. Put the rest on the bottom of your library in a random order.| Optimistic Scavenger|Duskmourn: House of Horror|21|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.| Orphans of the Wheat|Duskmourn: House of Horror|22|U|{1}{W}|Creature - Human|2|1|Whenever Orphans of the Wheat attacks, tap any number of untapped creatures you control. Orphans of the Wheat gets +1/+1 until end of turn for each creature tapped this way.| Overlord of the Mistmoors|Duskmourn: House of Horror|23|M|{5}{W}{W}|Enchantment Creature - Avatar Horror|6|6|Impending 4--{2}{W}{W}$Whenever Overlord of the Mistmoors enters or attacks, create two 2/1 white Insect creature tokens with flying.| @@ -54004,11 +54006,14 @@ Patched Plaything|Duskmourn: House of Horror|24|U|{2}{W}|Artifact Creature - Toy Reluctant Role Model|Duskmourn: House of Horror|26|R|{1}{W}|Creature - Human Survivor|2|2|Survival -- At the beginning of your second main phase, if Reluctant Role Model is tapped, put a flying, lifelink, or +1/+1 counter on it.$Whenever Reluctant Role Model or another creature you control dies, if it had counters on it, put those counters on up to one target creature.| Savior of the Small|Duskmourn: House of Horror|27|U|{3}{W}|Creature - Kor Survivor|3|4|Survival -- At the beginning of your second main phase, if Savior of the Small is tapped, return target creature card with mana value 3 or less from your graveyard to your hand.| Shardmage's Rescue|Duskmourn: House of Horror|29|U|{W}|Enchantment - Aura|||Flash$Enchant creature you control$As long as Shardmage's Rescue entered this turn, enchanted creature has hexproof.$Enchanted creature gets +1/+1.| +Sheltered by Ghosts|Duskmourn: House of Horror|30|U|{1}{W}|Enchantment - Aura|||Enchant creature you control$When Sheltered by Ghosts enters, exile target nonland permanent an opponent controls until Sheltered by Ghosts leaves the battlefield.$Enchanted creature gets +1/+0 and has lifelink and ward {2}.| 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 Splitskin Doll 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|||(You may cast 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, return target creature card with mana value 3 or less from your graveyard to the battlefield.$Hospital Room${3}{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 attack, put a +1/+1 counter on target attacking creature.| Toby, Beastie Befriender|Duskmourn: House of Horror|35|R|{2}{W}|Legendary Creature - Human Wizard|1|1|When Toby, Beastie Befriender enters, create a 4/4 white Beast creature token with "This creature 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 Trapped in the Screen enters, exile target artifact, creature, or enchantment an opponent controls until Trapped in the Screen leaves the battlefield.| +Unidentified Hovership|Duskmourn: House of Horror|37|R|{1}{W}{W}|Artifact - Vehicle|2|2|Flying$When Unidentified Hovership enters, exile up to one target creature with toughness 5 or less.$When Unidentified Hovership leaves the battlefield, the exiled card's owner manifests dread.$Crew 1| Unsettling Twins|Duskmourn: House of Horror|38|C|{3}{W}|Creature - Human|2|2|When Unsettling Twins enters, manifest dread.| Unwanted Remake|Duskmourn: House of Horror|39|U|{W}|Instant|||Destroy target creature. Its controller manifests dread.| Veteran Survivor|Duskmourn: House of Horror|40|U|{W}|Creature - Human Survivor|2|1|Survival -- At the beginning of your second main phase, if Veteran Survivor is tapped, exile up to one target card from a graveyard.$As long as there are three or more cards exiled with Veteran Survivor, it gets +3/+3 and has hexproof.| @@ -54023,11 +54028,14 @@ Daggermaw Megalodon|Duskmourn: House of Horror|48|C|{4}{U}{U}|Creature - Shark|5 Duskmourn's Domination|Duskmourn: House of Horror|50|U|{4}{U}{U}|Enchantment - Aura|||Enchant creature$You control enchanted creature.$Enchanted creature gets -3/-0 and loses all abilities.| Enduring Curiosity|Duskmourn: House of Horror|51|R|{2}{U}{U}|Enchantment Creature - Cat Glimmer|4|3|Flash$Whenever a creature you control deals combat damage to a player, draw a card.$When Enduring Curiosity dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment.| Enter the Enigma|Duskmourn: House of Horror|52|C|{U}|Sorcery|||Target creature can't be blocked this turn.$Draw a card.| +Entity Tracker|Duskmourn: House of Horror|53|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.| +Erratic Apparition|Duskmourn: House of Horror|54|C|{2}{U}|Creature - Spirit|1|3|Flying, vigilance$Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, Erratic Apparition gets +1/+1 until end of turn.| Fear of Failed Tests|Duskmourn: House of Horror|55|U|{4}{U}|Enchantment Creature - Nightmare|2|7|Whenever Fear of Failed Tests deals combat damage to a player, draw that many cards.| Fear of Falling|Duskmourn: House of Horror|56|U|{3}{U}{U}|Enchantment Creature - Nightmare|4|4|Flying$Whenever Fear of Falling attacks, target creature defending player controls gets -2/-0 and loses flying until your next turn.| Fear of Impostors|Duskmourn: House of Horror|57|U|{1}{U}{U}|Enchantment Creature - Nightmare|3|2|Flash$When Fear of Impostors enters, counter target spell. Its controller manifests dread.| Fear of Isolation|Duskmourn: House of Horror|58|U|{1}{U}|Enchantment Creature - Nightmare|2|3|As an additional cost to cast this spell, return a permanent you control to its owner's hand.$Flying| Floodpits Drowner|Duskmourn: House of Horror|59|U|{1}{U}|Creature - Merfolk|2|1|Flash$Vigilance$When Floodpits Drowner enters, tap target creature an opponent controls and put a stun counter on it.${1}{U}, {T}: Shuffle Floodpits Drowner and target creature with a stun counter on it into their owners' libraries.| +Get Out|Duskmourn: House of Horror|60|U|{U}{U}|Instant|||Choose one --$* Counter target creature or enchantment spell.$* Return one or two target creatures and/or enchantments you own to your hand.| Ghostly Keybearer|Duskmourn: House of Horror|61|U|{3}{U}|Creature - Spirit|3|3|Flying$Whenever Ghostly Keybearer deals combat damage to a player, unlock a locked door of up to one target Room you control.| Leyline of Transformation|Duskmourn: House of Horror|63|R|{2}{U}{U}|Enchantment|||If Leyline of Transformation is in your opening hand, you may begin the game with it on the battlefield.$As Leyline of Transformation 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.| @@ -54044,14 +54052,18 @@ 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 Tunnel Surveyor 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.| +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 Unwilling Vessel.$When Unwilling Vessel dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on Unwilling Vessel.| Vanish from Sight|Duskmourn: House of Horror|82|C|{3}{U}|Instant|||Target nonland permanent's owner puts it on the top or bottom of their library. Surveil 1.| Appendage Amalgam|Duskmourn: House of Horror|83|C|{2}{B}|Enchantment Creature - Horror|3|2|Flash$Whenever Appendage Amalgam attacks, surveil 1.| -Balemurk Leech|Duskmourn: House of Horror|84|C|{1}{B}|Creature Leech|2|2|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.| +Balemurk Leech|Duskmourn: House of Horror|84|C|{1}{B}|Creature - Leech|2|2|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.| +Cackling Slasher|Duskmourn: House of Horror|85|C|{3}{B}|Creature - Human Assassin|3|3|Deathtouch$Cackling Slasher enters with a +1/+1 counter on it if a creature died this turn.| Come Back Wrong|Duskmourn: House of Horror|86|R|{2}{B}|Sorcery|||Destroy target creature. If a creature card is put into a graveyard this way, return it to the battlefield under your control. Sacrifice it at the beginning of your next end step.| Commune with Evil|Duskmourn: House of Horror|87|U|{2}{B}|Sorcery|||Look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. You gain 3 life.| +Cracked Skull|Duskmourn: House of Horror|88|C|{2}{B}|Enchantment|||Enchant creature$When Cracked Skull 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|Cynical Loner can't be blocked by Glimmers.$Survival -- At the beginning of your second main phase, if Cynical Loner 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, Dashing Bloodsucker gets +2/+0 and gains lifelink until end of turn.| +Defiled Crypt // Cadaver Lab|Duskmourn: House of Horror|91|U|{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.)$Whenever one or more cards leave your graveyard, create a 2/2 black Horror enchantment creature token. This ability triggers only once each turn.$Cadaver Lab${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, return target creature card from your graveyard to your hand.| 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.| Doomsday Excruciator|Duskmourn: House of Horror|94|R|{B}{B}{B}{B}{B}{B}|Creature - Demon|6|6|Flying$When Doomsday Excruciator 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.| @@ -54063,13 +54075,16 @@ Funeral Room // Awakening Hall|Duskmourn: House of Horror|100|M|{2}{B}|Enchantme 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 Innocuous Rat dies, manifest dread.| +Killer's Mask|Duskmourn: House of Horror|104|U|{2}{B}|Artifact - Equipment|||When Killer's Mask enters, manifest dread, then attach Killer's Mask to that creature.$Equipped creature has menace.$Equip {2}| Let's Play a Game|Duskmourn: House of Horror|105|U|{3}{B}|Sorcery|||Delirium -- Choose one. If there are four or more card types among cards in your graveyard, choose one or more instead.$* Creatures your opponents control get -1/-1 until end of turn.$* Each opponent discards two cards.$* Each opponent loses 3 life and you gain 3 life.| Leyline of the Void|Duskmourn: House of Horror|106|R|{2}{B}{B}|Enchantment|||If Leyline of the Void is in your opening hand, you may begin the game with it on the battlefield.$If a card would be put into an opponent's graveyard from anywhere, exile it instead.| Live or Die|Duskmourn: House of Horror|107|U|{3}{B}{B}|Instant|||Choose one --$* Return target creature card from your graveyard to the battlefield.$* Destroy target creature.| Meathook Massacre II|Duskmourn: House of Horror|108|M|{X}{X}{B}{B}{B}{B}|Legendary Enchantment|||When Meathook Massacre II enters, each player sacrifices X creatures.$Whenever a creature you control dies, you may pay 3 life. If you do, return that card under your control with a finality counter on it.$Whenever a creature an opponent controls dies, they may pay 3 life. If they don't, return that card under your control with a finality counter on it.| +Miasma Demon|Duskmourn: House of Horror|109|U|{4}{B}{B}|Creature - Demon|5|4|Flying$When Miasma Demon enters, you may discard any number of cards. When you do, up to that many target creatures each get -2/-2 until end of turn.| Murder|Duskmourn: House of Horror|110|C|{1}{B}{B}|Instant|||Destroy target creature.| Nowhere to Run|Duskmourn: House of Horror|111|U|{1}{B}|Enchantment|||Flash$When Nowhere to Run enters, target creature an opponent controls gets -3/-3 until end of turn.$Creatures your opponents control can be the targets of spells and abilities as though they didn't have hexproof. Ward abilities of those creatures don't trigger.| Osseous Sticktwister|Duskmourn: House of Horror|112|U|{1}{B}|Artifact Creature - Scarecrow|2|2|Lifelink$Delirium -- At the beginning of your end step, if there are four or more card types among cards in your graveyard, each opponent may sacrifice a nonland permanent or discard a card. Then Osseous Sticktwister deals damage equal to its power to each opponent who didn't sacrifice a permanent or discard a card this way.| +Overlord of the Balemurk|Duskmourn: House of Horror|113|M|{3}{B}{B}|Enchantment Creature - Avatar Horror|5|5|Impending 5--{1}{B}$Whenever Overlord of the Balemurk enters or attacks, mill four cards, then you may return a non-Avatar creature card or a planeswalker card from your graveyard to your hand.| Popular Egotist|Duskmourn: House of Horror|114|U|{2}{B}|Creature - Human Rogue|3|2|{1}{B}, Sacrifice another creature or enchantment: Popular Egotist gains indestructible until end of turn. Tap it.$Whenever you sacrifice a permanent, target opponent loses 1 life and you gain 1 life.| Resurrected Cultist|Duskmourn: House of Horror|115|C|{2}{B}|Creature - Human Cleric|4|1|Delirium -- {2}{B}{B}: Return Resurrected Cultist 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}| @@ -54079,7 +54094,9 @@ Unstoppable Slasher|Duskmourn: House of Horror|119|R|{2}{B}|Creature - Zombie As 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 Valgavoth's Faithful: Return target creature card from your graveyard to the battlefield. Activate only as a sorcery.| Vile Mutilator|Duskmourn: House of Horror|122|U|{5}{B}{B}|Creature - Demon|6|5|As an additional cost to cast this spell, sacrifice a creature or enchantment.$Flying, trample$When Vile Mutilator enters, each opponent sacrifices a nontoken enchantment, then sacrifices a nontoken creature.| +Winter's Intervention|Duskmourn: House of Horror|123|C|{1}{B}|Instant|||Winter's Intervention deals 2 damage to target creature. You gain 2 life.| Withering Torment|Duskmourn: House of Horror|124|U|{2}{B}|Instant|||Destroy target creature or enchantment. You lose 2 life.| +Bedhead Beastie|Duskmourn: House of Horror|125|C|{4}{R}{R}|Creature - Beast|5|6|Menace$Mountaincycling {2}| Betrayer's Bargain|Duskmourn: House of Horror|126|U|{1}{R}|Instant|||As an additioinal 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.| Chainsaw|Duskmourn: House of Horror|128|R|{1}{R}|Artifact - Equipment|||When Chainsaw enters, it deals 3 damage to up to one target creature.$Whenever one or more creatures die, put a rev counter on Chainsaw.$Equipped creature gets +X/+0, where X is the number of rev counters on Chainsaw.$Equip {3}| Charred Foyer // Warped Space|Duskmourn: House of Horror|129|M|{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.)$At the beginning of your upkeep, exile the top card of your library. You may play that card this turn.$Warped Space${4}{R}{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.)$Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast from exile.| @@ -54100,41 +54117,49 @@ 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, Swift Survivalist 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 Overlord of the Boilerbilges 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|||(You may cast 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, exile the top two cards of your library. You may play them until the end of your next turn.$Defaced Gallery${1}{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.)$Whenever you attack, attacking creatures you control get +1/+0 until end of turn.| Piggy Bank|Duskmourn: House of Horror|148|U|{1}{R}|Artifact Creature - Boar Toy|3|2|When Piggy Bank 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.| Rampaging Soulrager|Duskmourn: House of Horror|151|C|{2}{R}|Creature - Spirit|1|4|Rampaging Soulrager gets +3/+0 as long as there are two or more unlocked doors among Rooms you control.| Razorkin Hordecaller|Duskmourn: House of Horror|152|U|{4}{R}|Creature - Human Clown Berserker|4|4|Haste$Whenever you attack, create a 1/1 red Gremlin creature token.| Razorkin Needlehead|Duskmourn: House of Horror|153|R|{R}{R}|Creature - Human Assassin|2|2|Razorkin Needlehead has first strike during your turn.$Whenever an opponent draws a card, Razorkin Needlehead deals 1 damage to them.| +Ripchain Razorkin|Duskmourn: House of Horror|154|C|{3}{R}|Creature - Human Berserker|5|3|Reach${2}{R}, Sacrifice a land: Draw a card.| 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 Screaming Nemesis 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.| -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 Anguish deals 5 damage to that creature, and the other can't block this turn.| +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.| Vengeful Possession|Duskmourn: House of Horror|162|U|{2}{R}|Sorcery|||Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. You may discard a card. If you do, draw a card.| Vicious Clown|Duskmourn: House of Horror|163|C|{2}{R}|Creature - Human Clown|2|3|Whenever another creature you control with power 2 or less enters, Vicious Clown gets +2/+0 until end of turn.| +Violent Urge|Duskmourn: House of Horror|164|U|{R}|Instant|||Target creature gets +1/+0 and gains first strike until end of turn.$Delirium -- If there are four or more card types among cards in your graveyard, that creature gains double strike until end of turn.| +Waltz of Rage|Duskmourn: House of Horror|165|R|{3}{R}{R}|Sorcery|||Target creature you control deals damage equal to its power to each other creature. Until end of turn, whenever a creature you control dies, exile the top card of your library. You may play it until the end of your next turn.| Altanak, the Thrice-Called|Duskmourn: House of Horror|166|U|{5}{G}{G}|Legendary Creature - Insect Beast|9|9|Trample$Whenever Altanak, the Thrice-Called becomes the target of a spell or ability an opponent controls, draw a card.${1}{G}, Discard Altanak, the Thrice-Called: Return target land card from your graveyard to the battlefield tapped.| Anthropede|Duskmourn: House of Horror|167|C|{3}{G}|Creature - Insect|3|4|Reach$When Anthropede enters, you may discard a card or pay {2}. When you do, destroy target Room.| Balustrade Wurm|Duskmourn: House of Horror|168|R|{3}{G}{G}|Creature - Wurm|5|5|This spell can't be countered.$Trample, haste$Delirium -- {2}{G}{G}: Return Balustrade Wurm 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.| Bashful Beastie|Duskmourn: House of Horror|169|C|{4}{G}|Creature - Beast|5|4|When Bashful Beastie dies, manifest dread.| Break Down the Door|Duskmourn: House of Horror|170|U|{2}{G}|Instant|||Choose one --$* Exile target artifact.$* Exile target enchantment.$* Manifest dread.| -Cathartic Parting|Duskmourn: House of Horror|171|C|{1}{G}|Sorcery|||The owner of target artifact or enchantment an opponent controls shuffles it into their library. You may shuffle up to four target cards from your graveyard into your library.| +Cathartic Parting|Duskmourn: House of Horror|171|U|{1}{G}|Sorcery|||The owner of target artifact or enchantment an opponent controls shuffles it into their library. You may shuffle up to four target cards from your graveyard into your library.| Cautious Survivor|Duskmourn: House of Horror|172|C|{3}{G}|Creature - Elf Survivor|4|4|Survival -- At the beginning of your second main phase, if Cautious Survivor is tapped, you gain 2 life.| Coordinated Clobbering|Duskmourn: House of Horror|173|U|{G}|Sorcery|||Tap one or two target untapped creatures you control. They each deal damage equal to their power to target creature an opponent controls.| Cryptid Inspector|Duskmourn: House of Horror|174|C|{2}{G}|Creature - Elf Warrior|2|3|Vigilance$Whenever a face-down permanent you control enters and whenever Cryptid Inspector or another permanent you control is turned face up, put a +1/+1 counter on Cryptid Inspector.| Defiant Survivor|Duskmourn: House of Horror|175|U|{2}{G}|Creature - Human Survivor|3|2|Survival -- At the beginning of your second main phase, if Defiant Survivor is tapped, manifest dread.| Enduring Vitality|Duskmourn: House of Horror|176|R|{1}{G}{G}|Enchantment Creature - Elk Glimmer|3|3|Vigilance$Creatures you control have "{T}: Add one mana of any color."$When Enduring Vitality dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment.| +Fear of Exposure|Duskmourn: House of Horror|177|U|{2}{G}|Enchantment Creature - Nightmare|5|4|As an additional cost to cast this spell, tap two untapped creatures and/or lands you control.$Trample| Flesh Burrower|Duskmourn: House of Horror|178|C|{1}{G}|Creature - Insect|2|2|Deathtouch$Whenever Flesh Burrower 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 Grasping Longneck dies, you gain 2 life.| Greenhouse // Rickety Gazebo|Duskmourn: House of Horror|181|U|{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.)$Lands you control have "{T}: Add one mana of any color."$Rickety Gazebo${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, mill four cards, then return up to two permanent cards from among them to your hand.| Hauntwoods Shrieker|Duskmourn: House of Horror|182|M|{1}{G}{G}|Creature - Beast Mutant|3|3|Whenever Hauntwoods Shrieker 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 Hedge Shredder 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.| House Cartographer|Duskmourn: House of Horror|185|U|{1}{G}|Creature - Human Scout Survivor|2|2|Survival -- At the beginning of your second main phase, if House Cartographer is tapped, reveal cards from the top of your library until you reveal a land card. Put that card into your hand and the rest on the bottom of your library in a random order.| Insidious Fungus|Duskmourn: House of Horror|186|U|{G}|Creature - Fungus|1|2|{2}, Sacrifice Insidious Fungus: Choose one --$* Destroy target artifact.$* Destroy target enchantment.$* Draw a card. Then you may put a land card from your hand onto the battlefield tapped.| -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, Rescue Beastie is tapped, you may put a permanent card from your hand onto the battlefield| +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, Rescue Beastie 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 Leyline of Mutation 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 that 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|||(You may cast 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, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.$Weight Room${5}{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 three +1/+1 counters on that creature.| Omnivorous Flytrap|Duskmourn: House of Horror|192|R|{2}{G}|Creature - Plant|2|4|Delirium -- Whenever Omnivorous Flytrap 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.| Overlord of the Hauntwoods|Duskmourn: House of Horror|194|M|{3}{G}{G}|Enchantment Creature - Avatar Horror|6|5|Impending 4--{1}{G}{G}$Whenever Overlord of the Hauntwoods enters or attacks, create a tapped colorless land token named Everywhere that is every basic land type.| @@ -54148,10 +54173,12 @@ 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, the Pummeler 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 cast either half. That door unlocks on the battlefield. As a sorcery, you may pay the mana cost of a locked door to unlock it.)$You may play land cards from your graveyard.$Forgotten Cellar${3}{G}{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, 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.| Wary Watchdog|Duskmourn: House of Horror|206|C|{1}{G}|Creature - Dog|3|1|When Wary Watchdog enters or dies, surveil 1.| Wickerfolk Thresher|Duskmourn: House of Horror|207|U|{3}{G}|Artifact Creature - Scarecrow|5|4|Delirium -- Whenever Wickerfolk Thresher 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, Abandoned Doll 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.| Baseball Bat|Duskmourn: House of Horror|209|U|{G}{W}|Artifact - Equipment|||When Baseball Bat enters, attach it to target creature you control.$Equipped creature gets +1/+1.$Whenever equipped creature attacks, tap up to one target creature.$Equip {3}| +Beastie Beatdown|Duskmourn: House of Horror|210|U|{R}{G}|Sorcery|||Choose target creature you control and target creature an opponent controls.$Delirium -- If there are four or more card types among cards in your graveyard, put two +1/+1 counters on the creature you control.$The creature you control deals damage equal to its power to the creature an opponent controls.| Broodspinner|Duskmourn: House of Horror|211|U|{B}{G}|Creature - Spider|2|3|Reach$When Broodspinner enters, surveil 2.${4}{B}{G}, {T}, Sacrifice Broodspinner: Create a number of 1/1 black and green Insect creature tokens with flying equal to the number of card types among cards in your graveyard.| Disturbing Mirth|Duskmourn: House of Horror|212|U|{B}{R}|Enchantment|||When Disturbing Mirth enters, you may sacrifice another enchantment or creature. If you do, draw two cards.$When you sacrifice Disturbing Mirth, manifest dread.| Drag to the Roots|Duskmourn: House of Horror|213|U|{2}{B}{G}|Instant|||Delirium -- This spell costs {2} less to cast as long as there are four or more card types among cards in your graveyard.$Destroy target nonland permanent.| @@ -54168,6 +54195,7 @@ Niko, Light of Hope|Duskmourn: House of Horror|224|M|{2}{W}{U}|Legendary Creatur 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|||(You may cast 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 room, destroy all creatures with power 3 or greater.$Lecture Hall${5}{U}{U}$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.)$Other permanents you control have hexproof.| +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, Spawn Hunter 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}| 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 Sawblade Skinripper.$At the beginning of your end step, if you sacrificed one or more permanents this turn, Sawblade Skinripper 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 Shrewd Storyteller is tapped, put a +1/+1 counter on target creature.| @@ -54182,11 +54210,13 @@ Zimone, All-Questioning|Duskmourn: House of Horror|241|R|{1}{G}{U}|Legendary Cre Attack-in-the-Box|Duskmourn: House of Horror|242|U|{3}|Artifact Creature - Toy|2|4|Whenever Attack-in-the-Box attacks, you may have it get +4/+0 until end of turn. If you do, sacrifice it at the beginning of the next end step.| Bear Trap|Duskmourn: House of Horror|243|C|{1}|Artifact|||Flash${3}, {T}, Sacrifice Bear Trap: It deals 3 damage to target creature.| Conductive Machete|Duskmourn: House of Horror|244|U|{4}|Artifact - Equipment|||When Conductive Machete enters, manifest dread, then attach Conductive Machete to that creature.$Equipped creature gets +2/+1.$Equip {4}| +Dissection Tools|Duskmourn: House of Horror|245|R|{5}|Artifact - Equipment|||When Dissection Tools enters, manifest dread, then attach Dissection Tools to that creature.$Equipped creature gets +2/+2 and has deathtouch and lifelink.$Equip--Sacrifice a creature.| Found Footage|Duskmourn: House of Horror|246|C|{1}|Artifact - Clue|||You may look at face-down creatures your opponents control any time.${2}, Sacrifice Found Footage: Surveil 2, then draw a card.| Friendly Teddy|Duskmourn: House of Horror|247|C|{2}|Artifact Creature - Bear Toy|2|2|When Friendly Teddy dies, each player draws a card.| Ghost Vacuum|Duskmourn: House of Horror|248|R|{1}|Artifact|||{T}: Exile target card from a graveyard.${6}, {T}, Sacrifice Ghost Vacuum: Put each creature card exiled with Ghost Vacuum onto the battlefield under your control with a flying counter on it. Each of them is a 1/1 Spirit in addition to its other types. Activate only as a sorcery.| Glimmerlight|Duskmourn: House of Horror|249|C|{2}|Artifact - Equipment|||When Glimmerlight enters, create a 1/1 white Glimmer enchantment creature token.$Equipped creature gets +1/+1.$Equip {1}| Haunted Screen|Duskmourn: House of Horror|250|U|{3}|Artifact|||{T}: Add {W} or {B}.${T}, Pay 1 life: Add {G}, {U}, or {R}.${7}: Put seven +1/+1 counters on Haunted Screen. It becomes a 0/0 Spirit creature in addition to its other types. Activate only once.| +Keys to the House|Duskmourn: House of Horror|251|U|{1}|Artifact|||{1}, {T}, Sacrifice Keys to the House: Search your library for a basic land card, reveal it, put it into your hand, then shuffle.${3}, {T}, Sacrifice Keys to the House: Lock or unlock a door of target Room you control. Activate only as a sorcery.| Malevolent Chandelier|Duskmourn: House of Horror|252|C|{6}|Artifact Creature - Construct|4|4|Flying${2}: Put target card from a graveyard on the bottom of its owner's library. Activate only as a sorcery.| Marvin, Murderous Mimic|Duskmourn: House of Horror|253|R|{2}|Legendary Artifact Creature - Toy|2|2|Marvin, Murderous Mimic has all activated abilities of creatures you control that don't have the same name as this creature.| Saw|Duskmourn: House of Horror|254|U|{2}|Artifact - Equipment|||Equipped creature gets +2/+0.$Whenever equipped creature attacks, you may sacrifice a permanent other than that creature or Saw. If you do, draw a card.$Equip {2}| @@ -54212,6 +54242,7 @@ Island|Duskmourn: House of Horror|279|C||Basic Land - Island|||({T}: Add {U}.)| Swamp|Duskmourn: House of Horror|281|C||Basic Land - Swamp|||({T}: Add {B}.)| Mountain|Duskmourn: House of Horror|283|C||Basic Land - Mountain|||({T}: Add {R}.)| Forest|Duskmourn: House of Horror|285|C||Basic Land - Forest|||({T}: Add {G}.)| +Roaring Furnace // Steaming Sauna|Duskmourn: House of Horror|343|R|{1}{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, this Room deals damage equal to the number of cards in your hand to target creature an opponent controls.$Steaming Sauna${3}{U}{U}$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.)$You have no maximum hand size. At the beginning of your end step, draw a card.| Felidar Savior|Foundations|12|C|{3}{W}|Creature - Cat Beast|2|3|Lifelink$When this creature enters, put a +1/+1 counter on each of up to two other target creatures you control.| Helpful Hunter|Foundations|16|C|{1}{W}|Creature - Cat|1|1|When this creature enters, draw a card.| Prideful Parent|Foundations|21|C|{2}{W}|Creature - Cat|2|2|Vigilance$When this creature enters, create a 1/1 white Cat creature token.| @@ -54570,7 +54601,9 @@ Tornellan Protector|Sega Dreamcast Cards|9|R|{2}{W}|Creature - Cleric|1|2|{T}: U Velukan Dragon|Sega Dreamcast Cards|10|R|{5}{R}{R}|Creature - Dragon|5|5|Flying$Whenever Velukan Dragon attacks or blocks, roll a six-sided die. Velukan Dragon gets +X/+0 until end of turn, where X is the result minus 1.| Aminatou, Veil Piercer|Duskmourn: House of Horror Commander|1|M|{1}{W}{U}{B}|Legendary Creature - Human Wizard|2|4|At the beginning of your upkeep, surveil 2.$Each enchantment card in your hand has miracle. Its miracle cost is equal to its mana cost reduced by {4}.| 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.| 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.| @@ -54583,13 +54616,29 @@ They Came from the Pipes|Duskmourn: House of Horror Commander|14|R|{4}{U}|Enchan 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.| +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. 4$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.| +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}| +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.| +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.| 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.| +Formless Genesis|Duskmourn: House of Horror Commander|34|R|{2}{G}|Kindred Sorcery - Shapeshifter be|||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.| +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.| 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.| Terminus|Duskmourn: House of Horror Commander|70|R|{4}{W}{W}|Sorcery|||Put all creatures on the bottom of their owners' libraries.$Miracle {W}| @@ -54598,15 +54647,148 @@ Cackling Counterpart|Duskmourn: House of Horror Commander|72|R|{1}{U}{U}|Instant Ponder|Duskmourn: House of Horror Commander|73|C|{U}|Sorcery|||Look at the top three cards of your library, then put them back in any order. You may shuffle.$Draw a card.| Portent|Duskmourn: House of Horror Commander|74|C|{U}|Sorcery|||Look at the top three cards of target player's library, then put them back in any order. You may have that player shuffle.$Draw a card at the beginning of the next turn's upkeep.| Telling Time|Duskmourn: House of Horror Commander|75|U|{1}{U}|Instant|||Look at the top three cards of your library. Put one of those cards into your hand, one on top of your library, and one on the bottom of your library.| +Blood Pact|Duskmourn: House of Horror Commander|76|C|{2}{B}|Instant|||Target player draws two cards and loses 2 life.| +Blood Seeker|Duskmourn: House of Horror Commander|77|C|{1}{B}|Creature - Vampire Shaman|1|1|Whenever a creature an opponent controls enters, you may have that player lose 1 life.| +Feed the Swarm|Duskmourn: House of Horror Commander|78|C|{1}{B}|Sorcery|||Destroy target creature or enchantment an opponent controls. You lose life equal to that permanent's mana value.| +Night's Whisper|Duskmourn: House of Horror Commander|79|C|{1}{B}|Sorcery|||You draw two cards and you lose 2 life.| 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.| +Bedevil|Duskmourn: House of Horror Commander|84|R|{B}{B}{R}|Instant|||Destroy target artifact, creature, or planeswalker.| +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.| +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.| +Lightning Greaves|Duskmourn: House of Horror Commander|93|U|{2}|Artifact - Equipment|||Equipped creature has haste and shroud.$Equip {0}| Sol Ring|Duskmourn: House of Horror Commander|94|U|{1}|Artifact|||{T}: Add {C}{C}.| +Suspicious Bookcase|Duskmourn: House of Horror Commander|95|C|{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}| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +Read the Bones|Duskmourn: House of Horror Commander|154|C|{2}{B}|Sorcery|||Scry 2, then draw two cards. You lose 2 life.| +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.| +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.| +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.| +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}| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +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.| +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."| +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.| +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.| +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}.| +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.| +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.| +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.| +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.| +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.| +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.| +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."| +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.| +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.| +Azorius Signet|Duskmourn: House of Horror Commander|240|U|{2}|Artifact|||{1}, {T}: Add {W}{U}.| +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.| +Mind Stone|Duskmourn: House of Horror Commander|248|U|{2}|Artifact|||{T}: Add {C}.${1}, {T}, Sacrifice Mind Stone: Draw a card.| +Orzhov Signet|Duskmourn: House of Horror Commander|249|U|{2}|Artifact|||{1}, {T}: Add {W}{B}.| +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.| +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}.| 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}.| +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}.| +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.| +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}.| +Drownyard Temple|Duskmourn: House of Horror Commander|272|R||Land|||{T}: Add {C}.${3}: Return Drownyard Temple from your graveyard to the battlefield tapped.| +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.| +Flooded Grove|Duskmourn: House of Horror Commander|276|R||Land|||{T}: Add {C}.${G/U}, {T}: Add {G}{G}, {G}{U}, or {U}{U}.| +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}.| +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}.| +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.| +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}.| +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.| +Reliquary Tower|Duskmourn: House of Horror Commander|295|U||Land|||You have no maximum hand size.${T}: Add {C}.| +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}.| +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.| +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 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}.| +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.| +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.| +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}.| +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.| 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.| diff --git a/readme.md b/readme.md index 5fa5fe973d3..76cbbf72936 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/magefree/mage](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/magefree/mage?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) XMage allows you to play Magic against one or more online players or computer opponents. -It includes full rules enforcement for over **25 000** unique cards and more than 65 000 reprints from different editions. +It includes full rules enforcement for over **28 000** unique cards and more than 73 000 reprints from different editions. You can also find custom sets like Star Wars. All regular sets have nearly all implemented cards. It supports single matches and tournaments with dozens of game modes like duel, multiplayer, standard, modern, commander, @@ -75,6 +75,7 @@ Github issues page contain [popular problems and fixes](https://github.com/magef * [Any: can't run client, could not open ...jvm.cfg](https://github.com/magefree/mage/issues/1272#issuecomment-529789018); * [Any: no texts or small buttons in launcher](https://github.com/magefree/mage/issues/4126); * [Windows: ugly cards, buttons or other GUI drawing artifacts](https://github.com/magefree/mage/issues/4626#issuecomment-374640070); +* [Windows: pixilated images, icons and texts](https://github.com/magefree/mage/issues/12768#issuecomment-2347125602); * [MacOS: can't run on M1/M2](https://github.com/magefree/mage/issues/8406#issuecomment-1011720728); * [MacOS: can't open launcher](https://www.reddit.com/r/XMage/comments/kf8l34/updated_java_on_osx_xmage_not_working/ggej8cq/); * [MacOS: client freezes in GUI (on connect dialog, on new match)](https://github.com/magefree/mage/issues/4920#issuecomment-517944308); @@ -115,7 +116,7 @@ More info about [XRender](https://docs.oracle.com/javase/8/docs/technotes/guides This is not guaranteed to yield improvements, but it depends on your use-case. If you have a lot of RAM to spare, you can increase the initial heap size for good measure. More details about [memory settings](https://stackoverflow.com/a/57839720/8401696): -* `-Xms1G -Xmx2G` +* `-Xmx2G` ## Developer