input, Game game) {
+ return !Optional
+ .ofNullable(input.getSource().getSourcePermanentOrLKI(game))
+ .map(Permanent::getAttachedTo)
+ .equals(input.getObject().getId());
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StaffOfEdenVaultsKey.java b/Mage.Sets/src/mage/cards/s/StaffOfEdenVaultsKey.java
new file mode 100644
index 00000000000..00db62d13e3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StaffOfEdenVaultsKey.java
@@ -0,0 +1,70 @@
+package mage.cards.s;
+
+import java.util.UUID;
+
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.ValueHint;
+import mage.constants.SuperType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.filter.FilterCard;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.NamePredicate;
+import mage.filter.predicate.mageobject.PermanentPredicate;
+import mage.target.common.TargetCardInGraveyard;
+
+/**
+ *
+ * @author Grath
+ */
+public final class StaffOfEdenVaultsKey extends CardImpl {
+
+ private static final FilterCard filter = new FilterCard("legendary permanent card not named Staff of Eden, Vault's Key from a graveyard");
+ private static final FilterPermanent filter2 = new FilterControlledPermanent("permanent you control but don't own");
+ private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter2);
+ private static final Hint hint = new ValueHint("Permanents you control but don't own", xValue);
+
+ static {
+ filter.add(SuperType.LEGENDARY.getPredicate());
+ filter.add(PermanentPredicate.instance);
+ filter.add(Predicates.not(new NamePredicate("Staff of Eden, Vault's Key")));
+ filter2.add(TargetController.NOT_YOU.getOwnerPredicate());
+ }
+
+ public StaffOfEdenVaultsKey(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
+
+ this.supertype.add(SuperType.LEGENDARY);
+
+ // When Staff of Eden, Vault's Key enters the battlefield, put target legendary permanent card not named Staff of Eden, Vault's Key from a graveyard onto the battlefield under your control.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect());
+ ability.addTarget(new TargetCardInGraveyard(filter));
+ this.addAbility(ability);
+
+ // {T}: Draw a card for each permanent you control but don't own.
+ ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(xValue), new TapSourceCost());
+ ability.addHint(hint);
+ this.addAbility(ability);
+ }
+
+ private StaffOfEdenVaultsKey(final StaffOfEdenVaultsKey card) {
+ super(card);
+ }
+
+ @Override
+ public StaffOfEdenVaultsKey copy() {
+ return new StaffOfEdenVaultsKey(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/StrengthTestingHammer.java b/Mage.Sets/src/mage/cards/s/StrengthTestingHammer.java
new file mode 100644
index 00000000000..a3c56ecdb5b
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/StrengthTestingHammer.java
@@ -0,0 +1,105 @@
+package mage.cards.s;
+
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbility;
+import mage.abilities.common.AttacksAttachedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DrawCardSourceControllerEffect;
+import mage.abilities.effects.common.continuous.BoostEquippedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.PowerPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author Sidorovich77
+ */
+public final class StrengthTestingHammer extends CardImpl {
+
+
+ public StrengthTestingHammer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ //Whenever equipped creature attacks, roll a six-sided die.
+ // That creature gets +X/+0 until end of turn, where X is the result.
+ // Then, if it has the greatest power or is tied for greatest power among creatures on the battlefield, draw a card.
+
+
+ TriggeredAbility ability = new AttacksAttachedTriggeredAbility(new StrengthTestingHammerEffect());
+ ability.addEffect(new ConditionalOneShotEffect(new DrawCardSourceControllerEffect(1), StrengthTestingHammerCondition.instance).setText("Then if it has the greatest power or is tied for greatest power among creatures on the battlefield, draw a card."));
+ this.addAbility(ability);
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(3));
+ }
+
+ private StrengthTestingHammer(final StrengthTestingHammer card) {
+ super(card);
+ }
+
+ @Override
+ public StrengthTestingHammer copy() {
+ return new StrengthTestingHammer(this);
+ }
+}
+
+//Based on Historian's Wisdom
+enum StrengthTestingHammerCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent hammer = source.getSourcePermanentIfItStillExists(game);
+ if (hammer == null) {
+ return false;
+ }
+ Permanent creature = game.getPermanent(hammer.getAttachedTo());
+ if (creature == null) {
+ return false;
+ }
+ FilterCreaturePermanent filter = new FilterCreaturePermanent();
+ filter.add(new PowerPredicate(ComparisonType.MORE_THAN, creature.getPower().getValue()));
+ return game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game).isEmpty();
+ }
+}
+
+class StrengthTestingHammerEffect extends OneShotEffect {
+
+ StrengthTestingHammerEffect() {
+ super(Outcome.Benefit);
+ staticText = "roll a six-sided die. That creature gets +X/+0 until end of turn, where X is the result.";
+ }
+
+ private StrengthTestingHammerEffect(final StrengthTestingHammerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public StrengthTestingHammerEffect copy() {
+ return new StrengthTestingHammerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player != null) {
+ int result = player.rollDice(outcome, source, game, 6);
+ game.addEffect(new BoostEquippedEffect(result, 0, Duration.EndOfTurn), source);
+ }
+ return false;
+ }
+}
+
+
+
diff --git a/Mage.Sets/src/mage/cards/s/SulfurousSprings.java b/Mage.Sets/src/mage/cards/s/SulfurousSprings.java
index 6041c5e6d95..65f7b051395 100644
--- a/Mage.Sets/src/mage/cards/s/SulfurousSprings.java
+++ b/Mage.Sets/src/mage/cards/s/SulfurousSprings.java
@@ -2,16 +2,12 @@
package mage.cards.s;
import java.util.UUID;
-import mage.Mana;
import mage.abilities.Ability;
-import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageControllerEffect;
-import mage.abilities.mana.ColorlessManaAbility;
-import mage.abilities.mana.SimpleManaAbility;
+import mage.abilities.mana.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
/**
*
@@ -24,10 +20,10 @@ public final class SulfurousSprings extends CardImpl {
this.addAbility(new ColorlessManaAbility());
- Ability blackManaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.BlackMana(1), new TapSourceCost());
+ Ability blackManaAbility = new BlackManaAbility();
blackManaAbility.addEffect(new DamageControllerEffect(1));
this.addAbility(blackManaAbility);
- Ability redManaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.RedMana(1), new TapSourceCost());
+ Ability redManaAbility = new RedManaAbility();
redManaAbility.addEffect(new DamageControllerEffect(1));
this.addAbility(redManaAbility);
}
diff --git a/Mage.Sets/src/mage/cards/s/SuturePriest.java b/Mage.Sets/src/mage/cards/s/SuturePriest.java
index 32b5435e573..7e3a63bf8d6 100644
--- a/Mage.Sets/src/mage/cards/s/SuturePriest.java
+++ b/Mage.Sets/src/mage/cards/s/SuturePriest.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -90,6 +89,6 @@ class SuturePriestSecondTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return "Whenever a creature enters the battlefield under an opponent's control, you may have that player lose 1 life.";
+ return "Whenever a creature an opponent controls enters, you may have that player lose 1 life.";
}
}
diff --git a/Mage.Sets/src/mage/cards/s/SzatsWill.java b/Mage.Sets/src/mage/cards/s/SzatsWill.java
index 5e07b91a2a3..2bd46e1b517 100644
--- a/Mage.Sets/src/mage/cards/s/SzatsWill.java
+++ b/Mage.Sets/src/mage/cards/s/SzatsWill.java
@@ -45,7 +45,7 @@ public final class SzatsWill extends CardImpl {
this.getSpellAbility().getModes().setChooseText(
"Choose one. If you control a commander as you cast this spell, you may choose both."
);
- this.getSpellAbility().getModes().setMoreCondition(ControlACommanderCondition.instance);
+ this.getSpellAbility().getModes().setMoreCondition(2, ControlACommanderCondition.instance);
// • Each opponent sacrifices a creature they control with the greatest power.
this.getSpellAbility().addEffect(new SacrificeOpponentsEffect(filter));
diff --git a/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java b/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java
index 5375eb36362..29e9210cbed 100644
--- a/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java
+++ b/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java
@@ -172,4 +172,4 @@ class TergridGodOfFrightEffect extends OneShotEffect {
}
return false;
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/cards/t/TheMindskinner.java b/Mage.Sets/src/mage/cards/t/TheMindskinner.java
new file mode 100644
index 00000000000..98580d540aa
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheMindskinner.java
@@ -0,0 +1,83 @@
+package mage.cards.t;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.PreventionEffectImpl;
+import mage.abilities.keyword.CantBeBlockedSourceAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.players.Player;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class TheMindskinner extends CardImpl {
+
+ public TheMindskinner(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{U}{U}{U}");
+
+ this.supertype.add(SuperType.LEGENDARY);
+ this.subtype.add(SubType.NIGHTMARE);
+ this.power = new MageInt(10);
+ this.toughness = new MageInt(1);
+
+ // The Mindskinner can't be blocked.
+ this.addAbility(new CantBeBlockedSourceAbility());
+
+ // If a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.
+ this.addAbility(new SimpleStaticAbility(new TheMindskinnerEffect()));
+ }
+
+ private TheMindskinner(final TheMindskinner card) {
+ super(card);
+ }
+
+ @Override
+ public TheMindskinner copy() {
+ return new TheMindskinner(this);
+ }
+}
+
+class TheMindskinnerEffect extends PreventionEffectImpl {
+
+ TheMindskinnerEffect() {
+ super(Duration.WhileOnBattlefield);
+ staticText = "if a source you control would deal damage to an opponent, " +
+ "prevent that damage and each opponent mills that many cards.";
+ }
+
+ private TheMindskinnerEffect(final TheMindskinnerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TheMindskinnerEffect copy() {
+ return new TheMindskinnerEffect(this);
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ preventDamageAction(event, source, game);
+ for (UUID playerId : game.getOpponents(source.getControllerId())) {
+ Player player = game.getPlayer(playerId);
+ if (player != null) {
+ player.millCards(event.getAmount(), source, game);
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ return super.applies(event, source, game) && source.isControlledBy(game.getControllerId(event.getSourceId()));
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java b/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java
index af6067f8b5d..37091da9657 100644
--- a/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java
+++ b/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java
@@ -4,6 +4,7 @@ import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.keyword.InvestigateEffect;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -23,7 +24,8 @@ public final class ThoroughInvestigation extends CardImpl {
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new InvestigateEffect(), 1));
// Whenever you sacrifice a Clue, venture into the dungeon.
- this.addAbility(new SacrificePermanentTriggeredAbility(new VentureIntoTheDungeonEffect(), StaticFilters.FILTER_CONTROLLED_CLUE));
+ this.addAbility(new SacrificePermanentTriggeredAbility(new VentureIntoTheDungeonEffect(), StaticFilters.FILTER_CONTROLLED_CLUE)
+ .addHint(CurrentDungeonHint.instance));
}
private ThoroughInvestigation(final ThoroughInvestigation card) {
diff --git a/Mage.Sets/src/mage/cards/t/ThromokTheInsatiable.java b/Mage.Sets/src/mage/cards/t/ThromokTheInsatiable.java
index b7a13b6d3f6..87373defd90 100644
--- a/Mage.Sets/src/mage/cards/t/ThromokTheInsatiable.java
+++ b/Mage.Sets/src/mage/cards/t/ThromokTheInsatiable.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import mage.MageInt;
@@ -26,7 +25,7 @@ public final class ThromokTheInsatiable extends CardImpl {
this.toughness = new MageInt(0);
// Devour X, where X is the number of creatures devoured this way (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with X +1/+1 counters on it for each of those creatures.)
- this.addAbility(DevourAbility.DevourX());
+ this.addAbility(DevourAbility.devourX());
}
private ThromokTheInsatiable(final ThromokTheInsatiable card) {
diff --git a/Mage.Sets/src/mage/cards/t/TriumphantAdventurer.java b/Mage.Sets/src/mage/cards/t/TriumphantAdventurer.java
index 03c7406dee0..6a562cf14b9 100644
--- a/Mage.Sets/src/mage/cards/t/TriumphantAdventurer.java
+++ b/Mage.Sets/src/mage/cards/t/TriumphantAdventurer.java
@@ -8,6 +8,7 @@ import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.constants.Duration;
@@ -42,7 +43,8 @@ public final class TriumphantAdventurer extends CardImpl {
).addHint(MyTurnHint.instance));
// Whenever Triumphant Adventurer attacks, venture into the dungeon.
- this.addAbility(new AttacksTriggeredAbility(new VentureIntoTheDungeonEffect(), false));
+ this.addAbility(new AttacksTriggeredAbility(new VentureIntoTheDungeonEffect(), false)
+ .addHint(CurrentDungeonHint.instance));
}
private TriumphantAdventurer(final TriumphantAdventurer card) {
diff --git a/Mage.Sets/src/mage/cards/u/UndergroundRiver.java b/Mage.Sets/src/mage/cards/u/UndergroundRiver.java
index 850cc79b3b3..d0067b0b09e 100644
--- a/Mage.Sets/src/mage/cards/u/UndergroundRiver.java
+++ b/Mage.Sets/src/mage/cards/u/UndergroundRiver.java
@@ -2,16 +2,12 @@
package mage.cards.u;
import java.util.UUID;
-import mage.Mana;
import mage.abilities.Ability;
-import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageControllerEffect;
-import mage.abilities.mana.ColorlessManaAbility;
-import mage.abilities.mana.SimpleManaAbility;
+import mage.abilities.mana.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
/**
*
@@ -24,10 +20,10 @@ public final class UndergroundRiver extends CardImpl {
this.addAbility(new ColorlessManaAbility());
- Ability blueManaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.BlueMana(1), new TapSourceCost());
+ Ability blueManaAbility = new BlueManaAbility();
blueManaAbility.addEffect(new DamageControllerEffect(1));
this.addAbility(blueManaAbility);
- Ability blackManaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.BlackMana(1), new TapSourceCost());
+ Ability blackManaAbility = new BlackManaAbility();
blackManaAbility.addEffect(new DamageControllerEffect(1));
this.addAbility(blackManaAbility);
}
diff --git a/Mage.Sets/src/mage/cards/u/UnidentifiedHovership.java b/Mage.Sets/src/mage/cards/u/UnidentifiedHovership.java
new file mode 100644
index 00000000000..bd8dc5aa691
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/u/UnidentifiedHovership.java
@@ -0,0 +1,103 @@
+package mage.cards.u;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ExileTargetForSourceEffect;
+import mage.abilities.effects.keyword.ManifestDreadEffect;
+import mage.abilities.keyword.CrewAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.ToughnessPredicate;
+import mage.game.ExileZone;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class UnidentifiedHovership extends CardImpl {
+
+ private static final FilterPermanent filter = new FilterCreaturePermanent("creature with toughness 5 or less");
+
+ static {
+ filter.add(new ToughnessPredicate(ComparisonType.FEWER_THAN, 6));
+ }
+
+ public UnidentifiedHovership(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}{W}");
+
+ this.subtype.add(SubType.VEHICLE);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // When Unidentified Hovership enters, exile up to one target creature with toughness 5 or less.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect());
+ ability.addTarget(new TargetPermanent(0, 1, filter));
+ this.addAbility(ability);
+
+ // When Unidentified Hovership leaves the battlefield, the exiled card's owner manifests dread.
+ this.addAbility(new LeavesBattlefieldTriggeredAbility(new UnidentifiedHovershipEffect()));
+
+ // Crew 1
+ this.addAbility(new CrewAbility(1));
+ }
+
+ private UnidentifiedHovership(final UnidentifiedHovership card) {
+ super(card);
+ }
+
+ @Override
+ public UnidentifiedHovership copy() {
+ return new UnidentifiedHovership(this);
+ }
+}
+
+class UnidentifiedHovershipEffect extends OneShotEffect {
+
+ UnidentifiedHovershipEffect() {
+ super(Outcome.Benefit);
+ staticText = "the exiled card's owner manifests dread";
+ }
+
+ private UnidentifiedHovershipEffect(final UnidentifiedHovershipEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public UnidentifiedHovershipEffect copy() {
+ return new UnidentifiedHovershipEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
+ if (exileZone == null || exileZone.isEmpty()) {
+ return false;
+ }
+ for (Card card : exileZone.getCards(game)) {
+ Player player = game.getPlayer(card.getOwnerId());
+ if (player != null) {
+ ManifestDreadEffect.doManifestDread(player, source, game);
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/VarisSilverymoonRanger.java b/Mage.Sets/src/mage/cards/v/VarisSilverymoonRanger.java
index 636e004bd05..a4822f7517a 100644
--- a/Mage.Sets/src/mage/cards/v/VarisSilverymoonRanger.java
+++ b/Mage.Sets/src/mage/cards/v/VarisSilverymoonRanger.java
@@ -6,6 +6,7 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.WardAbility;
import mage.cards.CardImpl;
@@ -52,7 +53,7 @@ public final class VarisSilverymoonRanger extends CardImpl {
// Whenever you cast a creature or planeswalker spell, venture into the dungeon. This ability triggers only once each turn.
this.addAbility(new SpellCastControllerTriggeredAbility(
new VentureIntoTheDungeonEffect(), filter, false
- ).setTriggersLimitEachTurn(1));
+ ).setTriggersLimitEachTurn(1).addHint(CurrentDungeonHint.instance));
// Whenever you complete a dungeon, create a 2/2 green Wolf creature token.
this.addAbility(new CompletedDungeonTriggeredAbility(new CreateTokenEffect(new WolfToken())));
diff --git a/Mage.Sets/src/mage/cards/v/VeteranDungeoneer.java b/Mage.Sets/src/mage/cards/v/VeteranDungeoneer.java
index e3c42eefed8..b0d5f86142f 100644
--- a/Mage.Sets/src/mage/cards/v/VeteranDungeoneer.java
+++ b/Mage.Sets/src/mage/cards/v/VeteranDungeoneer.java
@@ -3,6 +3,7 @@ package mage.cards.v;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -24,7 +25,8 @@ public final class VeteranDungeoneer extends CardImpl {
this.toughness = new MageInt(4);
// When Veteran Dungeoneer enters the battlefield, venture into the dungeon.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new VentureIntoTheDungeonEffect()));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new VentureIntoTheDungeonEffect())
+ .addHint(CurrentDungeonHint.instance));
}
private VeteranDungeoneer(final VeteranDungeoneer card) {
diff --git a/Mage.Sets/src/mage/cards/v/ViolentUrge.java b/Mage.Sets/src/mage/cards/v/ViolentUrge.java
index 5f4c6814789..dda8d7c1cdf 100644
--- a/Mage.Sets/src/mage/cards/v/ViolentUrge.java
+++ b/Mage.Sets/src/mage/cards/v/ViolentUrge.java
@@ -39,7 +39,7 @@ public final class ViolentUrge extends CardImpl {
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"
- ));
+ ).concatBy("
"));
this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU);
}
diff --git a/Mage.Sets/src/mage/cards/w/WailOfTheForgotten.java b/Mage.Sets/src/mage/cards/w/WailOfTheForgotten.java
index 1725675130d..df296ccc797 100644
--- a/Mage.Sets/src/mage/cards/w/WailOfTheForgotten.java
+++ b/Mage.Sets/src/mage/cards/w/WailOfTheForgotten.java
@@ -27,7 +27,7 @@ public final class WailOfTheForgotten extends CardImpl {
this.getSpellAbility().getModes().setChooseText(
"choose one. If there are eight or more permanent cards in your graveyard as you cast this spell, choose one or more instead."
);
- this.getSpellAbility().getModes().setMoreCondition(DescendCondition.EIGHT);
+ this.getSpellAbility().getModes().setMoreCondition(3, DescendCondition.EIGHT);
this.getSpellAbility().setAbilityWord(AbilityWord.DESCEND_8);
// * Return target nonland permanent to its owner's hand.
diff --git a/Mage.Sets/src/mage/cards/w/WaltzOfRage.java b/Mage.Sets/src/mage/cards/w/WaltzOfRage.java
new file mode 100644
index 00000000000..11c66830da9
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WaltzOfRage.java
@@ -0,0 +1,119 @@
+package mage.cards.w;
+
+import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.ExileTopXMayPlayUntilEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.filter.StaticFilters;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class WaltzOfRage extends CardImpl {
+
+ public WaltzOfRage(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}");
+
+ // 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.
+ this.getSpellAbility().addEffect(new WaltzOfRageEffect());
+ this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
+ this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new WaltzOfRageTriggeredAbility()));
+ }
+
+ private WaltzOfRage(final WaltzOfRage card) {
+ super(card);
+ }
+
+ @Override
+ public WaltzOfRage copy() {
+ return new WaltzOfRage(this);
+ }
+}
+
+class WaltzOfRageEffect extends OneShotEffect {
+
+ WaltzOfRageEffect() {
+ super(Outcome.Benefit);
+ staticText = "target creature you control deals damage equal to its power to each other creature";
+ }
+
+ private WaltzOfRageEffect(final WaltzOfRageEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public WaltzOfRageEffect copy() {
+ return new WaltzOfRageEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (permanent == null) {
+ return false;
+ }
+ int power = permanent.getPower().getValue();
+ if (power < 1) {
+ return false;
+ }
+ for (Permanent creature : game.getBattlefield().getActivePermanents(
+ StaticFilters.FILTER_PERMANENT_CREATURE,
+ source.getControllerId(), source, game
+ )) {
+ if (!creature.getId().equals(permanent.getId())) {
+ creature.damage(power, permanent.getId(), source, game);
+ }
+ }
+ return true;
+ }
+}
+
+class WaltzOfRageTriggeredAbility extends DelayedTriggeredAbility {
+
+ WaltzOfRageTriggeredAbility() {
+ super(new ExileTopXMayPlayUntilEffect(1, Duration.UntilEndOfYourNextTurn), Duration.EndOfTurn, false, false);
+ }
+
+ private WaltzOfRageTriggeredAbility(final WaltzOfRageTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public WaltzOfRageTriggeredAbility copy() {
+ return new WaltzOfRageTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (!zEvent.isDiesEvent()) {
+ return false;
+ }
+ Permanent permanent = zEvent.getTarget();
+ return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId());
+ }
+
+ @Override
+ public String getRule() {
+ return "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.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WanderingTroubadour.java b/Mage.Sets/src/mage/cards/w/WanderingTroubadour.java
index c7de5e80060..b04a532746a 100644
--- a/Mage.Sets/src/mage/cards/w/WanderingTroubadour.java
+++ b/Mage.Sets/src/mage/cards/w/WanderingTroubadour.java
@@ -6,6 +6,7 @@ import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
import mage.abilities.condition.common.LandfallCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -31,7 +32,7 @@ public final class WanderingTroubadour extends CardImpl {
new BeginningOfYourEndStepTriggeredAbility(new VentureIntoTheDungeonEffect(), false),
LandfallCondition.instance,
"At the beginning of your end step, if you had a land enter the battlefield under your control this turn, venture into the dungeon."
- ), new LandfallWatcher());
+ ).addHint(CurrentDungeonHint.instance), new LandfallWatcher());
}
private WanderingTroubadour(final WanderingTroubadour card) {
diff --git a/Mage.Sets/src/mage/cards/w/WowzerTheAspirational.java b/Mage.Sets/src/mage/cards/w/WowzerTheAspirational.java
new file mode 100644
index 00000000000..55cfdf03022
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/WowzerTheAspirational.java
@@ -0,0 +1,124 @@
+package mage.cards.w;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.AttacksTriggeredAbility;
+import mage.abilities.condition.CompoundCondition;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.IntCompareCondition;
+import mage.abilities.condition.common.CitysBlessingCondition;
+import mage.abilities.condition.common.HaveInitiativeCondition;
+import mage.abilities.condition.common.MonarchIsSourceControllerCondition;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
+import mage.abilities.dynamicvalue.common.CountersControllerCount;
+import mage.abilities.effects.common.WinGameSourceControllerEffect;
+import mage.abilities.hint.ConditionHint;
+import mage.abilities.hint.Hint;
+import mage.abilities.hint.common.CitysBlessingHint;
+import mage.abilities.hint.common.InitiativeHint;
+import mage.abilities.hint.common.MonarchHint;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.counters.CounterType;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author Cguy7777
+ */
+public class WowzerTheAspirational extends CardImpl {
+
+ private static final Condition energyCondition = new WowzerTheAspirationalCondition();
+ private static final Condition bloodCondition
+ = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.BLOOD));
+ private static final Condition clueCondition
+ = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.CLUE));
+ private static final Condition foodCondition
+ = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.FOOD));
+ private static final Condition mapCondition
+ = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.MAP));
+ private static final Condition powerstoneCondition
+ = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.POWERSTONE));
+ private static final Condition treasureCondition
+ = new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.TREASURE));
+
+ private static final Condition winCondition = new CompoundCondition(
+ energyCondition,
+ bloodCondition,
+ clueCondition,
+ foodCondition,
+ mapCondition,
+ powerstoneCondition,
+ treasureCondition,
+ MonarchIsSourceControllerCondition.instance,
+ CitysBlessingCondition.instance,
+ HaveInitiativeCondition.instance);
+
+ private static final Hint energyHint = new ConditionHint(energyCondition, "You have an {E}");
+ private static final Hint bloodHint = new ConditionHint(bloodCondition, "You control a Blood");
+ private static final Hint clueHint = new ConditionHint(clueCondition, "You control a Clue");
+ private static final Hint foodHint = new ConditionHint(foodCondition, "You control a Food");
+ private static final Hint mapHint = new ConditionHint(mapCondition, "You control a Map");
+ private static final Hint powerstoneHint
+ = new ConditionHint(powerstoneCondition, "You control a Powerstone");
+ private static final Hint treasureHint
+ = new ConditionHint(treasureCondition, "You control a Treasure");
+
+ public WowzerTheAspirational(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{C}{W}{U}{B}{R}{G}{S}");
+
+ this.supertype.add(SuperType.LEGENDARY);
+ this.supertype.add(SuperType.SNOW);
+ this.subtype.add(SubType.WURM);
+ this.power = new MageInt(10);
+ this.toughness = new MageInt(10);
+
+ // Whenever Wowzer, the Aspirational attacks,
+ // if you have an {E}, control a Blood, a Clue, a Food, a Map, a Powerstone, and a Treasure,
+ // are the monarch, and have the city's blessing and the initiative, you win the game.
+ this.addAbility(new ConditionalInterveningIfTriggeredAbility(
+ new AttacksTriggeredAbility(new WinGameSourceControllerEffect()),
+ winCondition,
+ "Whenever {this} attacks, " +
+ "if you have an {E}, control a Blood, a Clue, a Food, a Map, a Powerstone, and a Treasure, " +
+ "are the monarch, and have the city's blessing and the initiative, you win the game."
+ ).addHint(energyHint)
+ .addHint(bloodHint)
+ .addHint(clueHint)
+ .addHint(foodHint)
+ .addHint(mapHint)
+ .addHint(powerstoneHint)
+ .addHint(treasureHint)
+ .addHint(MonarchHint.instance)
+ .addHint(CitysBlessingHint.instance)
+ .addHint(InitiativeHint.instance));
+ }
+
+ private WowzerTheAspirational(final WowzerTheAspirational card) {
+ super(card);
+ }
+
+ @Override
+ public WowzerTheAspirational copy() {
+ return new WowzerTheAspirational(this);
+ }
+}
+
+class WowzerTheAspirationalCondition extends IntCompareCondition {
+
+ WowzerTheAspirationalCondition() {
+ super(ComparisonType.MORE_THAN, 0);
+ }
+
+ @Override
+ protected int getInputValue(Game game, Ability source) {
+ return new CountersControllerCount(CounterType.ENERGY).calculate(game, source, null);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/y/YavimayaCoast.java b/Mage.Sets/src/mage/cards/y/YavimayaCoast.java
index 9ce66236ce0..d44530df603 100644
--- a/Mage.Sets/src/mage/cards/y/YavimayaCoast.java
+++ b/Mage.Sets/src/mage/cards/y/YavimayaCoast.java
@@ -2,16 +2,12 @@
package mage.cards.y;
import java.util.UUID;
-import mage.Mana;
import mage.abilities.Ability;
-import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.DamageControllerEffect;
-import mage.abilities.mana.ColorlessManaAbility;
-import mage.abilities.mana.SimpleManaAbility;
+import mage.abilities.mana.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
/**
*
@@ -26,10 +22,10 @@ public final class YavimayaCoast extends CardImpl {
this.addAbility(new ColorlessManaAbility());
// Tap: Add Green or Blue. Yavimaya Coast deals 1 damage to you.
- Ability greenManaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(1), new TapSourceCost());
+ Ability greenManaAbility = new GreenManaAbility();
greenManaAbility.addEffect(new DamageControllerEffect(1));
this.addAbility(greenManaAbility);
- Ability blueManaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.BlueMana(1), new TapSourceCost());
+ Ability blueManaAbility = new BlueManaAbility();
blueManaAbility.addEffect(new DamageControllerEffect(1));
this.addAbility(blueManaAbility);
}
diff --git a/Mage.Sets/src/mage/cards/y/YouFindACursedIdol.java b/Mage.Sets/src/mage/cards/y/YouFindACursedIdol.java
index a275b9292ea..95d30ba7bcb 100644
--- a/Mage.Sets/src/mage/cards/y/YouFindACursedIdol.java
+++ b/Mage.Sets/src/mage/cards/y/YouFindACursedIdol.java
@@ -4,6 +4,7 @@ import mage.abilities.Mode;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -36,6 +37,7 @@ public final class YouFindACursedIdol extends CardImpl {
mode = new Mode(new CreateTokenEffect(new TreasureToken()));
mode.addEffect(new VentureIntoTheDungeonEffect().concatBy("and"));
this.getSpellAbility().addMode(mode.withFlavorWord("Steal Its Eyes"));
+ this.getSpellAbility().addHint(CurrentDungeonHint.instance);
}
private YouFindACursedIdol(final YouFindACursedIdol card) {
diff --git a/Mage.Sets/src/mage/cards/y/YuanTiFangBlade.java b/Mage.Sets/src/mage/cards/y/YuanTiFangBlade.java
index e33ca95618c..74752e85caf 100644
--- a/Mage.Sets/src/mage/cards/y/YuanTiFangBlade.java
+++ b/Mage.Sets/src/mage/cards/y/YuanTiFangBlade.java
@@ -3,6 +3,7 @@ package mage.cards.y;
import mage.MageInt;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -30,7 +31,7 @@ public final class YuanTiFangBlade extends CardImpl {
// Whenever Yuan-Ti Fang-Blade deals combat damage to a player, venture into the dungeon.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new VentureIntoTheDungeonEffect(), false
- ));
+ ).addHint(CurrentDungeonHint.instance));
}
private YuanTiFangBlade(final YuanTiFangBlade card) {
diff --git a/Mage.Sets/src/mage/cards/y/YuanTiMalison.java b/Mage.Sets/src/mage/cards/y/YuanTiMalison.java
index b146543c87f..5e946677a36 100644
--- a/Mage.Sets/src/mage/cards/y/YuanTiMalison.java
+++ b/Mage.Sets/src/mage/cards/y/YuanTiMalison.java
@@ -8,6 +8,7 @@ import mage.abilities.condition.common.SourceAttackingAloneCondition;
import mage.abilities.decorator.ConditionalRestrictionEffect;
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -35,7 +36,8 @@ public final class YuanTiMalison extends CardImpl {
)));
// Whenever Yuan-Ti Malison deals combat damage to a player, venture into the dungeon.
- this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new VentureIntoTheDungeonEffect(), false));
+ this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new VentureIntoTheDungeonEffect(), false)
+ .addHint(CurrentDungeonHint.instance));
}
private YuanTiMalison(final YuanTiMalison card) {
diff --git a/Mage.Sets/src/mage/cards/z/ZaltoFireGiantDuke.java b/Mage.Sets/src/mage/cards/z/ZaltoFireGiantDuke.java
index ae3cb993916..641b230a9d7 100644
--- a/Mage.Sets/src/mage/cards/z/ZaltoFireGiantDuke.java
+++ b/Mage.Sets/src/mage/cards/z/ZaltoFireGiantDuke.java
@@ -3,6 +3,7 @@ package mage.cards.z;
import mage.MageInt;
import mage.abilities.common.DealtDamageToSourceTriggeredAbility;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -30,7 +31,8 @@ public final class ZaltoFireGiantDuke extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// Whenever Zalto, Fire Giant Duke is dealt damage, venture into the dungeon.
- this.addAbility(new DealtDamageToSourceTriggeredAbility(new VentureIntoTheDungeonEffect(), false));
+ this.addAbility(new DealtDamageToSourceTriggeredAbility(new VentureIntoTheDungeonEffect(), false)
+ .addHint(CurrentDungeonHint.instance));
}
private ZaltoFireGiantDuke(final ZaltoFireGiantDuke card) {
diff --git a/Mage.Sets/src/mage/cards/z/ZombieOgre.java b/Mage.Sets/src/mage/cards/z/ZombieOgre.java
index 43f04c185f0..89ff6becde8 100644
--- a/Mage.Sets/src/mage/cards/z/ZombieOgre.java
+++ b/Mage.Sets/src/mage/cards/z/ZombieOgre.java
@@ -4,6 +4,7 @@ import mage.MageInt;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.condition.common.MorbidCondition;
import mage.abilities.effects.keyword.VentureIntoTheDungeonEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.abilities.hint.common.MorbidHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -31,7 +32,7 @@ public final class ZombieOgre extends CardImpl {
this.addAbility(new BeginningOfEndStepTriggeredAbility(
Zone.BATTLEFIELD, new VentureIntoTheDungeonEffect(),
TargetController.YOU, MorbidCondition.instance, false
- ).addHint(MorbidHint.instance));
+ ).addHint(MorbidHint.instance).addHint(CurrentDungeonHint.instance));
}
private ZombieOgre(final ZombieOgre card) {
diff --git a/Mage.Sets/src/mage/sets/AlchemyInnistrad.java b/Mage.Sets/src/mage/sets/AlchemyInnistrad.java
index ca5812d8565..793c67a5263 100644
--- a/Mage.Sets/src/mage/sets/AlchemyInnistrad.java
+++ b/Mage.Sets/src/mage/sets/AlchemyInnistrad.java
@@ -25,6 +25,8 @@ public final class AlchemyInnistrad extends ExpansionSet {
cards.add(new SetCardInfo("Cursebound Witch", 24, Rarity.UNCOMMON, mage.cards.c.CurseboundWitch.class));
cards.add(new SetCardInfo("Expedition Supplier", 6, Rarity.RARE, mage.cards.e.ExpeditionSupplier.class));
cards.add(new SetCardInfo("Faithful Disciple", 7, Rarity.UNCOMMON, mage.cards.f.FaithfulDisciple.class));
+ cards.add(new SetCardInfo("Forsaken Crossroads", 63, Rarity.RARE, mage.cards.f.ForsakenCrossroads.class));
+ cards.add(new SetCardInfo("Hollowhenge Wrangler", 51, Rarity.RARE, mage.cards.h.HollowhengeWrangler.class));
cards.add(new SetCardInfo("Ishkanah, Broodmother", 52, Rarity.MYTHIC, mage.cards.i.IshkanahBroodmother.class));
cards.add(new SetCardInfo("Key to the Archive", 59, Rarity.RARE, mage.cards.k.KeyToTheArchive.class));
cards.add(new SetCardInfo("Kindred Denial", 18, Rarity.UNCOMMON, mage.cards.k.KindredDenial.class));
diff --git a/Mage.Sets/src/mage/sets/AssassinsCreed.java b/Mage.Sets/src/mage/sets/AssassinsCreed.java
index f5dad8fa2cf..3150e3f8845 100644
--- a/Mage.Sets/src/mage/sets/AssassinsCreed.java
+++ b/Mage.Sets/src/mage/sets/AssassinsCreed.java
@@ -118,6 +118,7 @@ public final class AssassinsCreed extends ExpansionSet {
cards.add(new SetCardInfo("Silent Clearing", 115, Rarity.RARE, mage.cards.s.SilentClearing.class));
cards.add(new SetCardInfo("Smoke Bomb", 75, Rarity.UNCOMMON, mage.cards.s.SmokeBomb.class));
cards.add(new SetCardInfo("Spartan Veteran", 292, Rarity.COMMON, mage.cards.s.SpartanVeteran.class));
+ cards.add(new SetCardInfo("Staff of Eden, Vault's Key", 76, Rarity.MYTHIC, mage.cards.s.StaffOfEdenVaultsKey.class));
cards.add(new SetCardInfo("Stone Quarry", 300, Rarity.UNCOMMON, mage.cards.s.StoneQuarry.class));
cards.add(new SetCardInfo("Submerged Boneyard", 301, Rarity.UNCOMMON, mage.cards.s.SubmergedBoneyard.class));
cards.add(new SetCardInfo("Sunbaked Canyon", 111, Rarity.RARE, mage.cards.s.SunbakedCanyon.class));
diff --git a/Mage.Sets/src/mage/sets/DoctorWho.java b/Mage.Sets/src/mage/sets/DoctorWho.java
index 79650578e0a..46f60e21e78 100644
--- a/Mage.Sets/src/mage/sets/DoctorWho.java
+++ b/Mage.Sets/src/mage/sets/DoctorWho.java
@@ -158,6 +158,10 @@ public final class DoctorWho extends ExpansionSet {
cards.add(new SetCardInfo("Myriad Landscape", 290, Rarity.UNCOMMON, mage.cards.m.MyriadLandscape.class));
cards.add(new SetCardInfo("Mystic Monastery", 291, Rarity.UNCOMMON, mage.cards.m.MysticMonastery.class));
cards.add(new SetCardInfo("Nanogene Conversion", 49, Rarity.RARE, mage.cards.n.NanogeneConversion.class));
+ cards.add(new SetCardInfo("Nardole, Resourceful Cyborg", 50, Rarity.RARE, mage.cards.n.NardoleResourcefulCyborg.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Nardole, Resourceful Cyborg", 365, Rarity.RARE, mage.cards.n.NardoleResourcefulCyborg.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Nardole, Resourceful Cyborg", 655, Rarity.RARE, mage.cards.n.NardoleResourcefulCyborg.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Nardole, Resourceful Cyborg", 956, Rarity.RARE, mage.cards.n.NardoleResourcefulCyborg.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ominous Cemetery", 189, Rarity.UNCOMMON, mage.cards.o.OminousCemetery.class));
cards.add(new SetCardInfo("Out of Time", 209, Rarity.RARE, mage.cards.o.OutOfTime.class));
cards.add(new SetCardInfo("Overgrown Farmland", 292, Rarity.RARE, mage.cards.o.OvergrownFarmland.class));
diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java
index db9ccba4914..1b304b8f2f6 100644
--- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java
+++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorror.java
@@ -33,19 +33,25 @@ 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("Beastie Beatdown", 210, Rarity.UNCOMMON, mage.cards.b.BeastieBeatdown.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("Boilerbilges Ripper", 127, Rarity.COMMON, mage.cards.b.BoilerbilgesRipper.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("Cathartic Parting", 171, Rarity.UNCOMMON, mage.cards.c.CatharticParting.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));
cards.add(new SetCardInfo("Clockwork Percussionist", 130, Rarity.COMMON, mage.cards.c.ClockworkPercussionist.class));
+ cards.add(new SetCardInfo("Come Back Wrong", 86, Rarity.RARE, mage.cards.c.ComeBackWrong.class));
cards.add(new SetCardInfo("Commune with Evil", 87, Rarity.UNCOMMON, mage.cards.c.CommuneWithEvil.class));
cards.add(new SetCardInfo("Conductive Machete", 244, Rarity.UNCOMMON, mage.cards.c.ConductiveMachete.class));
+ cards.add(new SetCardInfo("Coordinated Clobbering", 173, Rarity.UNCOMMON, mage.cards.c.CoordinatedClobbering.class));
+ cards.add(new SetCardInfo("Cracked Skull", 88, Rarity.COMMON, mage.cards.c.CrackedSkull.class));
cards.add(new SetCardInfo("Cult Healer", 2, Rarity.COMMON, mage.cards.c.CultHealer.class));
cards.add(new SetCardInfo("Cursed Recording", 131, Rarity.RARE, mage.cards.c.CursedRecording.class));
cards.add(new SetCardInfo("Cursed Windbreaker", 47, Rarity.UNCOMMON, mage.cards.c.CursedWindbreaker.class));
@@ -57,6 +63,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
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("Don't Make a Sound", 49, Rarity.COMMON, mage.cards.d.DontMakeASound.class));
cards.add(new SetCardInfo("Doomsday Excruciator", 94, Rarity.RARE, mage.cards.d.DoomsdayExcruciator.class));
cards.add(new SetCardInfo("Drag to the Roots", 213, Rarity.UNCOMMON, mage.cards.d.DragToTheRoots.class));
cards.add(new SetCardInfo("Duskmourn's Domination", 50, Rarity.UNCOMMON, mage.cards.d.DuskmournsDomination.class));
@@ -74,6 +81,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
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 Burning Alive", 135, Rarity.UNCOMMON, mage.cards.f.FearOfBurningAlive.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));
@@ -90,12 +98,14 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
cards.add(new SetCardInfo("Floodfarm Verge", 259, Rarity.RARE, mage.cards.f.FloodfarmVerge.class));
cards.add(new SetCardInfo("Floodpits Drowner", 59, Rarity.UNCOMMON, mage.cards.f.FloodpitsDrowner.class));
cards.add(new SetCardInfo("Forest", 276, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
+ cards.add(new SetCardInfo("Found Footage", 246, Rarity.COMMON, mage.cards.f.FoundFootage.class));
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("Glimmerburst", 62, Rarity.COMMON, mage.cards.g.Glimmerburst.class));
cards.add(new SetCardInfo("Glimmerlight", 249, Rarity.COMMON, mage.cards.g.Glimmerlight.class));
cards.add(new SetCardInfo("Gloomlake Verge", 260, Rarity.RARE, mage.cards.g.GloomlakeVerge.class));
cards.add(new SetCardInfo("Grasping Longneck", 180, Rarity.COMMON, mage.cards.g.GraspingLongneck.class));
@@ -104,6 +114,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
cards.add(new SetCardInfo("Growing Dread", 216, Rarity.UNCOMMON, mage.cards.g.GrowingDread.class));
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("Haunted Screen", 250, Rarity.UNCOMMON, mage.cards.h.HauntedScreen.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));
@@ -114,6 +125,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("Jump Scare", 17, Rarity.COMMON, mage.cards.j.JumpScare.class));
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));
@@ -128,6 +140,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
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("Marvin, Murderous Mimic", 253, Rarity.RARE, mage.cards.m.MarvinMurderousMimic.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));
@@ -136,6 +149,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
cards.add(new SetCardInfo("Murky Sewer", 263, Rarity.COMMON, mage.cards.m.MurkySewer.class));
cards.add(new SetCardInfo("Nashi, Searcher in the Dark", 223, Rarity.RARE, mage.cards.n.NashiSearcherInTheDark.class));
cards.add(new SetCardInfo("Neglected Manor", 264, Rarity.COMMON, mage.cards.n.NeglectedManor.class));
+ cards.add(new SetCardInfo("Norin, Swift Survivalist", 145, Rarity.UNCOMMON, mage.cards.n.NorinSwiftSurvivalist.class));
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));
@@ -153,6 +167,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
cards.add(new SetCardInfo("Piranha Fly", 70, Rarity.COMMON, mage.cards.p.PiranhaFly.class));
cards.add(new SetCardInfo("Plains", 272, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Popular Egotist", 114, Rarity.UNCOMMON, mage.cards.p.PopularEgotist.class));
+ cards.add(new SetCardInfo("Possessed Goat", 25, Rarity.COMMON, mage.cards.p.PossessedGoat.class));
cards.add(new SetCardInfo("Pyroclasm", 149, Rarity.UNCOMMON, mage.cards.p.Pyroclasm.class));
cards.add(new SetCardInfo("Ragged Playmate", 150, Rarity.COMMON, mage.cards.r.RaggedPlaymate.class));
cards.add(new SetCardInfo("Raucous Carnival", 266, Rarity.COMMON, mage.cards.r.RaucousCarnival.class));
@@ -160,17 +175,22 @@ 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("Rip, Spawn Hunter", 228, Rarity.RARE, mage.cards.r.RipSpawnHunter.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("Saw", 254, Rarity.UNCOMMON, mage.cards.s.Saw.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("Seized from Slumber", 28, Rarity.COMMON, mage.cards.s.SeizedFromSlumber.class));
cards.add(new SetCardInfo("Shardmage's Rescue", 29, Rarity.UNCOMMON, mage.cards.s.ShardmagesRescue.class));
+ cards.add(new SetCardInfo("Sheltered by Ghosts", 30, Rarity.UNCOMMON, mage.cards.s.ShelteredByGhosts.class));
cards.add(new SetCardInfo("Shepherding Spirits", 31, Rarity.COMMON, mage.cards.s.ShepherdingSpirits.class));
cards.add(new SetCardInfo("Shrewd Storyteller", 232, Rarity.UNCOMMON, mage.cards.s.ShrewdStoryteller.class));
+ cards.add(new SetCardInfo("Shroudstomper", 233, Rarity.UNCOMMON, mage.cards.s.Shroudstomper.class));
cards.add(new SetCardInfo("Silent Hallcreeper", 72, Rarity.RARE, mage.cards.s.SilentHallcreeper.class));
cards.add(new SetCardInfo("Skullsnap Nuisance", 234, Rarity.UNCOMMON, mage.cards.s.SkullsnapNuisance.class));
cards.add(new SetCardInfo("Slavering Branchsnapper", 198, Rarity.COMMON, mage.cards.s.SlaveringBranchsnapper.class));
@@ -178,12 +198,14 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
cards.add(new SetCardInfo("Spineseeker Centipede", 199, Rarity.COMMON, mage.cards.s.SpineseekerCentipede.class));
cards.add(new SetCardInfo("Split Up", 32, Rarity.RARE, mage.cards.s.SplitUp.class));
cards.add(new SetCardInfo("Splitskin Doll", 33, Rarity.UNCOMMON, mage.cards.s.SplitskinDoll.class));
+ cards.add(new SetCardInfo("Sporogenic Infection", 117, Rarity.UNCOMMON, mage.cards.s.SporogenicInfection.class));
cards.add(new SetCardInfo("Stalked Researcher", 73, Rarity.COMMON, mage.cards.s.StalkedResearcher.class));
cards.add(new SetCardInfo("Stay Hidden, Stay Silent", 74, Rarity.UNCOMMON, mage.cards.s.StayHiddenStaySilent.class));
cards.add(new SetCardInfo("Strangled Cemetery", 268, Rarity.COMMON, mage.cards.s.StrangledCemetery.class));
cards.add(new SetCardInfo("Swamp", 274, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Terramorphic Expanse", 269, Rarity.COMMON, mage.cards.t.TerramorphicExpanse.class));
cards.add(new SetCardInfo("The Jolly Balloon Man", 219, Rarity.RARE, mage.cards.t.TheJollyBalloonMan.class));
+ cards.add(new SetCardInfo("The Mindskinner", 66, Rarity.RARE, mage.cards.t.TheMindskinner.class));
cards.add(new SetCardInfo("The Swarmweaver", 236, Rarity.RARE, mage.cards.t.TheSwarmweaver.class));
cards.add(new SetCardInfo("The Wandering Rescuer", 41, Rarity.MYTHIC, mage.cards.t.TheWanderingRescuer.class));
cards.add(new SetCardInfo("Thornspire Verge", 270, Rarity.RARE, mage.cards.t.ThornspireVerge.class));
@@ -196,6 +218,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("Unidentified Hovership", 37, Rarity.RARE, mage.cards.u.UnidentifiedHovership.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));
@@ -211,6 +234,7 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
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("Waltz of Rage", 165, Rarity.RARE, mage.cards.w.WaltzOfRage.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));
@@ -218,7 +242,5 @@ public final class DuskmournHouseOfHorror extends ExpansionSet {
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));
-
- cards.removeIf(setCardInfo -> setCardInfo.getName().startsWith("Overlord"));
}
}
diff --git a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java
index 293ed4ce304..c12c4a2d15d 100644
--- a/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java
+++ b/Mage.Sets/src/mage/sets/DuskmournHouseOfHorrorCommander.java
@@ -23,6 +23,7 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
cards.add(new SetCardInfo("Aesi, Tyrant of Gyre Strait", 210, Rarity.MYTHIC, mage.cards.a.AesiTyrantOfGyreStrait.class));
cards.add(new SetCardInfo("Aether Gale", 109, Rarity.RARE, mage.cards.a.AetherGale.class));
cards.add(new SetCardInfo("Aminatou's Augury", 71, Rarity.RARE, mage.cards.a.AminatousAugury.class));
+ cards.add(new SetCardInfo("Arachnogenesis", 169, Rarity.RARE, mage.cards.a.Arachnogenesis.class));
cards.add(new SetCardInfo("Arcane Denial", 110, Rarity.COMMON, mage.cards.a.ArcaneDenial.class));
cards.add(new SetCardInfo("Arcane Sanctum", 259, Rarity.UNCOMMON, mage.cards.a.ArcaneSanctum.class));
cards.add(new SetCardInfo("Arcane Signet", 92, Rarity.COMMON, mage.cards.a.ArcaneSignet.class));
@@ -37,31 +38,52 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
cards.add(new SetCardInfo("Auramancer", 97, Rarity.COMMON, mage.cards.a.Auramancer.class));
cards.add(new SetCardInfo("Azorius Chancery", 261, Rarity.UNCOMMON, mage.cards.a.AzoriusChancery.class));
cards.add(new SetCardInfo("Azorius Signet", 240, Rarity.UNCOMMON, mage.cards.a.AzoriusSignet.class));
+ cards.add(new SetCardInfo("Barren Moor", 262, Rarity.UNCOMMON, mage.cards.b.BarrenMoor.class));
+ cards.add(new SetCardInfo("Basilisk Collar", 241, Rarity.RARE, mage.cards.b.BasiliskCollar.class));
+ cards.add(new SetCardInfo("Bastion of Remembrance", 131, Rarity.UNCOMMON, mage.cards.b.BastionOfRemembrance.class));
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("Binding the Old Gods", 213, Rarity.UNCOMMON, mage.cards.b.BindingTheOldGods.class));
cards.add(new SetCardInfo("Biomass Mutation", 214, Rarity.RARE, mage.cards.b.BiomassMutation.class));
+ cards.add(new SetCardInfo("Blackcleave Cliffs", 263, Rarity.RARE, mage.cards.b.BlackcleaveCliffs.class));
+ cards.add(new SetCardInfo("Blasphemous Act", 160, Rarity.RARE, mage.cards.b.BlasphemousAct.class));
+ cards.add(new SetCardInfo("Blood Artist", 132, Rarity.UNCOMMON, mage.cards.b.BloodArtist.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("Bloodfell Caves", 264, Rarity.COMMON, mage.cards.b.BloodfellCaves.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("Braids, Arisen Nightmare", 133, Rarity.RARE, mage.cards.b.BraidsArisenNightmare.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("Brash Taunter", 161, Rarity.RARE, mage.cards.b.BrashTaunter.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("Canyon Slough", 266, Rarity.RARE, mage.cards.c.CanyonSlough.class));
+ cards.add(new SetCardInfo("Carrion Grub", 134, Rarity.COMMON, mage.cards.c.CarrionGrub.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("Cemetery Tampering", 135, Rarity.RARE, mage.cards.c.CemeteryTampering.class));
+ cards.add(new SetCardInfo("Chaos Warp", 162, Rarity.RARE, mage.cards.c.ChaosWarp.class));
cards.add(new SetCardInfo("Citanul Hierophants", 81, Rarity.RARE, mage.cards.c.CitanulHierophants.class));
+ cards.add(new SetCardInfo("Combustible Gearhulk", 163, Rarity.MYTHIC, mage.cards.c.CombustibleGearhulk.class));
cards.add(new SetCardInfo("Command Tower", 96, Rarity.COMMON, mage.cards.c.CommandTower.class));
cards.add(new SetCardInfo("Commander's Sphere", 244, Rarity.COMMON, mage.cards.c.CommandersSphere.class));
cards.add(new SetCardInfo("Convert to Slime", 37, Rarity.RARE, mage.cards.c.ConvertToSlime.class));
cards.add(new SetCardInfo("Counterspell", 114, Rarity.COMMON, mage.cards.c.Counterspell.class));
+ cards.add(new SetCardInfo("Crawling Sensation", 173, Rarity.UNCOMMON, mage.cards.c.CrawlingSensation.class));
cards.add(new SetCardInfo("Crypt Ghast", 368, Rarity.MYTHIC, mage.cards.c.CryptGhast.class));
+ cards.add(new SetCardInfo("Culling Ritual", 85, Rarity.RARE, mage.cards.c.CullingRitual.class));
cards.add(new SetCardInfo("Cultivate", 174, Rarity.COMMON, mage.cards.c.Cultivate.class));
cards.add(new SetCardInfo("Damn", 369, Rarity.MYTHIC, mage.cards.d.Damn.class));
+ cards.add(new SetCardInfo("Darkmoss Bridge", 269, Rarity.COMMON, mage.cards.d.DarkmossBridge.class));
+ cards.add(new SetCardInfo("Deadbridge Chant", 215, Rarity.MYTHIC, mage.cards.d.DeadbridgeChant.class));
+ cards.add(new SetCardInfo("Deathcap Cultivator", 175, Rarity.RARE, mage.cards.d.DeathcapCultivator.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("Decree of Pain", 136, Rarity.RARE, mage.cards.d.DecreeOfPain.class));
cards.add(new SetCardInfo("Deluge of Doom", 18, Rarity.RARE, mage.cards.d.DelugeOfDoom.class));
cards.add(new SetCardInfo("Demolisher Spawn", 31, Rarity.RARE, mage.cards.d.DemolisherSpawn.class));
cards.add(new SetCardInfo("Demon of Fate's Design", 137, Rarity.RARE, mage.cards.d.DemonOfFatesDesign.class));
@@ -69,46 +91,95 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
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("Dragonskull Summit", 271, Rarity.RARE, mage.cards.d.DragonskullSummit.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("Dryad Arbor", 273, Rarity.RARE, mage.cards.d.DryadArbor.class));
+ cards.add(new SetCardInfo("Enchanter's Bane", 164, Rarity.RARE, mage.cards.e.EnchantersBane.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("Exotic Orchard", 275, Rarity.RARE, mage.cards.e.ExoticOrchard.class));
cards.add(new SetCardInfo("Explosive Vegetation", 177, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class));
cards.add(new SetCardInfo("Extravagant Replication", 117, Rarity.RARE, mage.cards.e.ExtravagantReplication.class));
cards.add(new SetCardInfo("Ezuri's Predation", 178, Rarity.RARE, mage.cards.e.EzurisPredation.class));
+ cards.add(new SetCardInfo("Falkenrath Noble", 140, Rarity.UNCOMMON, mage.cards.f.FalkenrathNoble.class));
+ cards.add(new SetCardInfo("Fate Unraveler", 141, Rarity.RARE, mage.cards.f.FateUnraveler.class));
cards.add(new SetCardInfo("Feed the Swarm", 78, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class));
+ cards.add(new SetCardInfo("Fellwar Stone", 245, Rarity.UNCOMMON, mage.cards.f.FellwarStone.class));
cards.add(new SetCardInfo("Flooded Grove", 276, Rarity.RARE, mage.cards.f.FloodedGrove.class));
+ cards.add(new SetCardInfo("Florian, Voldaren Scion", 217, Rarity.RARE, mage.cards.f.FlorianVoldarenScion.class));
+ cards.add(new SetCardInfo("Foreboding Ruins", 277, Rarity.RARE, mage.cards.f.ForebodingRuins.class));
+ cards.add(new SetCardInfo("Geothermal Bog", 278, Rarity.COMMON, mage.cards.g.GeothermalBog.class));
+ cards.add(new SetCardInfo("Giant Adephage", 179, Rarity.MYTHIC, mage.cards.g.GiantAdephage.class));
cards.add(new SetCardInfo("Gleeful Arsonist", 27, Rarity.RARE, mage.cards.g.GleefulArsonist.class));
+ cards.add(new SetCardInfo("Gnarlwood Dryad", 180, Rarity.UNCOMMON, mage.cards.g.GnarlwoodDryad.class));
+ cards.add(new SetCardInfo("Golgari Rot Farm", 279, Rarity.COMMON, mage.cards.g.GolgariRotFarm.class));
+ cards.add(new SetCardInfo("Golgari Signet", 246, Rarity.COMMON, mage.cards.g.GolgariSignet.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("Graven Cairns", 280, Rarity.RARE, mage.cards.g.GravenCairns.class));
+ cards.add(new SetCardInfo("Gray Merchant of Asphodel", 142, Rarity.UNCOMMON, mage.cards.g.GrayMerchantOfAsphodel.class));
cards.add(new SetCardInfo("Greater Tanuki", 181, Rarity.COMMON, mage.cards.g.GreaterTanuki.class));
+ cards.add(new SetCardInfo("Grim Backwoods", 281, Rarity.RARE, mage.cards.g.GrimBackwoods.class));
+ cards.add(new SetCardInfo("Grim Flayer", 218, Rarity.RARE, mage.cards.g.GrimFlayer.class));
+ cards.add(new SetCardInfo("Grisly Salvage", 219, Rarity.COMMON, mage.cards.g.GrislySalvage.class));
+ cards.add(new SetCardInfo("Grist, the Hunger Tide", 220, Rarity.MYTHIC, mage.cards.g.GristTheHungerTide.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("Harmonize", 182, Rarity.UNCOMMON, mage.cards.h.Harmonize.class));
+ cards.add(new SetCardInfo("Harrow", 183, Rarity.COMMON, mage.cards.h.Harrow.class));
+ cards.add(new SetCardInfo("Harsh Mentor", 165, Rarity.RARE, mage.cards.h.HarshMentor.class));
+ cards.add(new SetCardInfo("Haywire Mite", 247, Rarity.UNCOMMON, mage.cards.h.HaywireMite.class));
cards.add(new SetCardInfo("Hinterland Harbor", 284, Rarity.RARE, mage.cards.h.HinterlandHarbor.class));
+ cards.add(new SetCardInfo("Hornet Queen", 184, Rarity.MYTHIC, mage.cards.h.HornetQueen.class));
cards.add(new SetCardInfo("Hydra Omnivore", 185, Rarity.MYTHIC, mage.cards.h.HydraOmnivore.class));
+ cards.add(new SetCardInfo("Infernal Grasp", 143, Rarity.UNCOMMON, mage.cards.i.InfernalGrasp.class));
cards.add(new SetCardInfo("Inkshield", 221, Rarity.RARE, mage.cards.i.Inkshield.class));
+ cards.add(new SetCardInfo("Inscription of Abundance", 186, Rarity.RARE, mage.cards.i.InscriptionOfAbundance.class));
+ cards.add(new SetCardInfo("Ishkanah, Grafwidow", 187, Rarity.MYTHIC, mage.cards.i.IshkanahGrafwidow.class));
+ cards.add(new SetCardInfo("Jungle Hollow", 285, Rarity.COMMON, mage.cards.j.JungleHollow.class));
+ cards.add(new SetCardInfo("Kaervek the Merciless", 222, Rarity.RARE, mage.cards.k.KaervekTheMerciless.class));
+ cards.add(new SetCardInfo("Kardur, Doomscourge", 223, Rarity.UNCOMMON, mage.cards.k.KardurDoomscourge.class));
+ cards.add(new SetCardInfo("Kederekt Parasite", 144, Rarity.RARE, mage.cards.k.KederektParasite.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("Leechridden Swamp", 286, Rarity.UNCOMMON, mage.cards.l.LeechriddenSwamp.class));
cards.add(new SetCardInfo("Life Insurance", 224, Rarity.RARE, mage.cards.l.LifeInsurance.class));
+ cards.add(new SetCardInfo("Light Up the Stage", 166, Rarity.UNCOMMON, mage.cards.l.LightUpTheStage.class));
cards.add(new SetCardInfo("Lightning Greaves", 93, Rarity.UNCOMMON, mage.cards.l.LightningGreaves.class));
cards.add(new SetCardInfo("Living Death", 373, Rarity.MYTHIC, mage.cards.l.LivingDeath.class));
+ cards.add(new SetCardInfo("Llanowar Wastes", 287, Rarity.RARE, mage.cards.l.LlanowarWastes.class));
+ cards.add(new SetCardInfo("Mask of Griselbrand", 145, Rarity.RARE, mage.cards.m.MaskOfGriselbrand.class));
+ cards.add(new SetCardInfo("Massacre Girl", 146, Rarity.RARE, mage.cards.m.MassacreGirl.class));
+ cards.add(new SetCardInfo("Massacre Wurm", 147, Rarity.MYTHIC, mage.cards.m.MassacreWurm.class));
+ cards.add(new SetCardInfo("Mayhem Devil", 225, Rarity.UNCOMMON, mage.cards.m.MayhemDevil.class));
cards.add(new SetCardInfo("Mesa Enchantress", 68, Rarity.RARE, mage.cards.m.MesaEnchantress.class));
cards.add(new SetCardInfo("Metamorphosis Fanatic", 21, Rarity.RARE, mage.cards.m.MetamorphosisFanatic.class));
cards.add(new SetCardInfo("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 Millipede", 188, Rarity.COMMON, mage.cards.m.MoldgrafMillipede.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("Morbid Opportunist", 148, Rarity.UNCOMMON, mage.cards.m.MorbidOpportunist.class));
cards.add(new SetCardInfo("Mosswort Bridge", 288, Rarity.RARE, mage.cards.m.MosswortBridge.class));
+ cards.add(new SetCardInfo("Mulch", 189, Rarity.COMMON, mage.cards.m.Mulch.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("Necroblossom Snarl", 290, Rarity.RARE, mage.cards.n.NecroblossomSnarl.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("Nightshade Harvester", 150, Rarity.RARE, mage.cards.n.NightshadeHarvester.class));
+ cards.add(new SetCardInfo("Noxious Gearhulk", 151, Rarity.MYTHIC, mage.cards.n.NoxiousGearhulk.class));
+ cards.add(new SetCardInfo("Nyx Weaver", 226, Rarity.UNCOMMON, mage.cards.n.NyxWeaver.class));
+ cards.add(new SetCardInfo("Ob Nixilis Reignited", 152, Rarity.MYTHIC, mage.cards.o.ObNixilisReignited.class));
cards.add(new SetCardInfo("Obscura Storefront", 291, Rarity.COMMON, mage.cards.o.ObscuraStorefront.class));
+ cards.add(new SetCardInfo("Obsessive Skinner", 191, Rarity.UNCOMMON, mage.cards.o.ObsessiveSkinner.class));
+ cards.add(new SetCardInfo("Old Stickfingers", 227, Rarity.RARE, mage.cards.o.OldStickfingers.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));
@@ -121,63 +192,103 @@ public final class DuskmournHouseOfHorrorCommander extends ExpansionSet {
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("Professor Onyx", 153, Rarity.MYTHIC, mage.cards.p.ProfessorOnyx.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("Rakdos Charm", 229, Rarity.UNCOMMON, mage.cards.r.RakdosCharm.class));
+ cards.add(new SetCardInfo("Rakdos Signet", 250, Rarity.UNCOMMON, mage.cards.r.RakdosSignet.class));
+ cards.add(new SetCardInfo("Rakdos, Lord of Riots", 230, Rarity.MYTHIC, mage.cards.r.RakdosLordOfRiots.class));
+ cards.add(new SetCardInfo("Rampaging Ferocidon", 167, Rarity.RARE, mage.cards.r.RampagingFerocidon.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("Reanimate", 155, Rarity.RARE, mage.cards.r.Reanimate.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("Scavenging Ooze", 196, Rarity.RARE, mage.cards.s.ScavengingOoze.class));
cards.add(new SetCardInfo("Scroll of Fate", 251, Rarity.RARE, mage.cards.s.ScrollOfFate.class));
cards.add(new SetCardInfo("Scute Swarm", 197, Rarity.RARE, mage.cards.s.ScuteSwarm.class));
+ cards.add(new SetCardInfo("Shadowblood Ridge", 296, Rarity.RARE, mage.cards.s.ShadowbloodRidge.class));
cards.add(new SetCardInfo("Shark Typhoon", 127, Rarity.RARE, mage.cards.s.SharkTyphoon.class));
cards.add(new SetCardInfo("Shigeki, Jukai Visionary", 198, Rarity.RARE, mage.cards.s.ShigekiJukaiVisionary.class));
+ cards.add(new SetCardInfo("Shivan Gorge", 297, Rarity.RARE, mage.cards.s.ShivanGorge.class));
cards.add(new SetCardInfo("Sigil of the Empty Throne", 103, Rarity.RARE, mage.cards.s.SigilOfTheEmptyThrone.class));
+ cards.add(new SetCardInfo("Sign in Blood", 156, Rarity.COMMON, mage.cards.s.SignInBlood.class));
cards.add(new SetCardInfo("Simic Growth Chamber", 298, Rarity.UNCOMMON, mage.cards.s.SimicGrowthChamber.class));
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("Skola Grovedancer", 199, Rarity.COMMON, mage.cards.s.SkolaGrovedancer.class));
+ cards.add(new SetCardInfo("Smoldering Marsh", 299, Rarity.RARE, mage.cards.s.SmolderingMarsh.class));
cards.add(new SetCardInfo("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("Spinerock Knoll", 300, Rarity.RARE, mage.cards.s.SpinerockKnoll.class));
cards.add(new SetCardInfo("Spirit-Sister's Call", 232, Rarity.MYTHIC, mage.cards.s.SpiritSistersCall.class));
+ cards.add(new SetCardInfo("Spiteful Visions", 233, Rarity.RARE, mage.cards.s.SpitefulVisions.class));
cards.add(new SetCardInfo("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("Stitcher's Supplier", 157, Rarity.UNCOMMON, mage.cards.s.StitchersSupplier.class));
+ cards.add(new SetCardInfo("Stormfist Crusader", 234, Rarity.RARE, mage.cards.s.StormfistCrusader.class));
+ cards.add(new SetCardInfo("Sulfurous Springs", 301, Rarity.RARE, mage.cards.s.SulfurousSprings.class));
+ cards.add(new SetCardInfo("Suspicious Bookcase", 95, Rarity.UNCOMMON, mage.cards.s.SuspiciousBookcase.class));
cards.add(new SetCardInfo("Swords to Plowshares", 106, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class));
+ cards.add(new SetCardInfo("Syr Konrad, the Grim", 158, Rarity.UNCOMMON, mage.cards.s.SyrKonradTheGrim.class));
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("Tainted Peak", 304, Rarity.UNCOMMON, mage.cards.t.TaintedPeak.class));
+ cards.add(new SetCardInfo("Tainted Wood", 305, Rarity.UNCOMMON, mage.cards.t.TaintedWood.class));
+ cards.add(new SetCardInfo("Talisman of Indulgence", 254, Rarity.UNCOMMON, mage.cards.t.TalismanOfIndulgence.class));
+ cards.add(new SetCardInfo("Talisman of Resilience", 255, Rarity.UNCOMMON, mage.cards.t.TalismanOfResilience.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("Tectonic Giant", 168, Rarity.RARE, mage.cards.t.TectonicGiant.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 Malady", 309, Rarity.RARE, mage.cards.t.TempleOfMalady.class));
+ cards.add(new SetCardInfo("Temple of Malice", 310, Rarity.RARE, mage.cards.t.TempleOfMalice.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("Theater of Horrors", 236, Rarity.RARE, mage.cards.t.TheaterOfHorrors.class));
cards.add(new SetCardInfo("They Came from the Pipes", 14, Rarity.RARE, mage.cards.t.TheyCameFromThePipes.class));
cards.add(new SetCardInfo("Thirst for Meaning", 129, Rarity.COMMON, mage.cards.t.ThirstForMeaning.class));
cards.add(new SetCardInfo("Thornwood Falls", 314, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class));
+ cards.add(new SetCardInfo("Thought Vessel", 256, Rarity.UNCOMMON, mage.cards.t.ThoughtVessel.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("Thunderfoot Baloth", 201, Rarity.RARE, mage.cards.t.ThunderfootBaloth.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("Titania, Nature's Force", 202, Rarity.MYTHIC, mage.cards.t.TitaniaNaturesForce.class));
cards.add(new SetCardInfo("Trail of Mystery", 203, Rarity.RARE, mage.cards.t.TrailOfMystery.class));
+ cards.add(new SetCardInfo("Tranquil Thicket", 318, Rarity.COMMON, mage.cards.t.TranquilThicket.class));
+ cards.add(new SetCardInfo("Tree of Tales", 319, Rarity.COMMON, mage.cards.t.TreeOfTales.class));
cards.add(new SetCardInfo("Trygon Predator", 238, Rarity.UNCOMMON, mage.cards.t.TrygonPredator.class));
+ cards.add(new SetCardInfo("Twilight Mire", 320, Rarity.RARE, mage.cards.t.TwilightMire.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("Vault of Whispers", 322, Rarity.COMMON, mage.cards.v.VaultOfWhispers.class));
cards.add(new SetCardInfo("Verge Rangers", 108, Rarity.RARE, mage.cards.v.VergeRangers.class));
+ cards.add(new SetCardInfo("Vial Smasher the Fierce", 239, Rarity.MYTHIC, mage.cards.v.VialSmasherTheFierce.class));
cards.add(new SetCardInfo("Vineglimmer Snarl", 323, Rarity.RARE, mage.cards.v.VineglimmerSnarl.class));
+ cards.add(new SetCardInfo("Viridescent Bog", 324, Rarity.RARE, mage.cards.v.ViridescentBog.class));
+ cards.add(new SetCardInfo("Whip of Erebos", 159, Rarity.RARE, mage.cards.w.WhipOfErebos.class));
+ cards.add(new SetCardInfo("Whispersilk Cloak", 257, Rarity.UNCOMMON, mage.cards.w.WhispersilkCloak.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("Witch's Clinic", 325, Rarity.RARE, mage.cards.w.WitchsClinic.class));
+ cards.add(new SetCardInfo("Woodland Cemetery", 326, Rarity.RARE, mage.cards.w.WoodlandCemetery.class));
cards.add(new SetCardInfo("Worldspine Wurm", 206, Rarity.MYTHIC, mage.cards.w.WorldspineWurm.class));
+ cards.add(new SetCardInfo("Wrenn and Seven", 207, Rarity.MYTHIC, mage.cards.w.WrennAndSeven.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.Sets/src/mage/sets/MysteryBooster2.java b/Mage.Sets/src/mage/sets/MysteryBooster2.java
index 0fdc0fda870..8b1778af764 100644
--- a/Mage.Sets/src/mage/sets/MysteryBooster2.java
+++ b/Mage.Sets/src/mage/sets/MysteryBooster2.java
@@ -100,6 +100,7 @@ public class MysteryBooster2 extends ExpansionSet {
cards.add(new SetCardInfo("Flusterstorm", 163, Rarity.RARE, mage.cards.f.Flusterstorm.class));
cards.add(new SetCardInfo("Foil", 243, Rarity.COMMON, mage.cards.f.Foil.class));
cards.add(new SetCardInfo("Forest Bear", 206, Rarity.COMMON, mage.cards.f.ForestBear.class));
+ cards.add(new SetCardInfo("Forsaken Crossroads", 264, Rarity.UNCOMMON, mage.cards.f.ForsakenCrossroads.class));
cards.add(new SetCardInfo("Future Sight", 122, Rarity.RARE, mage.cards.f.FutureSight.class));
cards.add(new SetCardInfo("Gerrard, Weatherlight Hero", 251, Rarity.RARE, mage.cards.g.GerrardWeatherlightHero.class));
cards.add(new SetCardInfo("Ghost Quarter", 109, Rarity.UNCOMMON, mage.cards.g.GhostQuarter.class));
@@ -278,6 +279,7 @@ public class MysteryBooster2 extends ExpansionSet {
cards.add(new SetCardInfo("Wish", 64, Rarity.RARE, mage.cards.w.Wish.class));
cards.add(new SetCardInfo("Wishclaw Talisman", 51, Rarity.RARE, mage.cards.w.WishclawTalisman.class));
cards.add(new SetCardInfo("Worst Fears", 52, Rarity.MYTHIC, mage.cards.w.WorstFears.class));
+ cards.add(new SetCardInfo("Wowzer, the Aspirational", 365, Rarity.RARE, mage.cards.w.WowzerTheAspirational.class));
cards.add(new SetCardInfo("Xantcha, Sleeper Agent", 253, Rarity.RARE, mage.cards.x.XantchaSleeperAgent.class));
cards.add(new SetCardInfo("Yorion, Sky Nomad", 94, Rarity.RARE, mage.cards.y.YorionSkyNomad.class));
cards.add(new SetCardInfo("Zombie Master", 188, Rarity.RARE, mage.cards.z.ZombieMaster.class));
diff --git a/Mage.Sets/src/mage/sets/Tempest.java b/Mage.Sets/src/mage/sets/Tempest.java
index 67ddcc80a58..6c694b4f6c4 100644
--- a/Mage.Sets/src/mage/sets/Tempest.java
+++ b/Mage.Sets/src/mage/sets/Tempest.java
@@ -232,6 +232,7 @@ public final class Tempest extends ExpansionSet {
cards.add(new SetCardInfo("Perish", 147, Rarity.UNCOMMON, mage.cards.p.Perish.class));
cards.add(new SetCardInfo("Phyrexian Grimoire", 301, Rarity.RARE, mage.cards.p.PhyrexianGrimoire.class));
cards.add(new SetCardInfo("Phyrexian Hulk", 302, Rarity.UNCOMMON, mage.cards.p.PhyrexianHulk.class));
+ cards.add(new SetCardInfo("Phyrexian Splicer", 303, Rarity.UNCOMMON, mage.cards.p.PhyrexianSplicer.class));
cards.add(new SetCardInfo("Pincher Beetles", 244, Rarity.COMMON, mage.cards.p.PincherBeetles.class));
cards.add(new SetCardInfo("Pine Barrens", 321, Rarity.RARE, mage.cards.p.PineBarrens.class));
cards.add(new SetCardInfo("Pit Imp", 148, Rarity.COMMON, mage.cards.p.PitImp.class));
diff --git a/Mage.Sets/src/mage/sets/Unfinity.java b/Mage.Sets/src/mage/sets/Unfinity.java
index b6afc3459e9..cf31e282786 100644
--- a/Mage.Sets/src/mage/sets/Unfinity.java
+++ b/Mage.Sets/src/mage/sets/Unfinity.java
@@ -56,6 +56,7 @@ public final class Unfinity extends ExpansionSet {
cards.add(new SetCardInfo("Slight Malfunction", 123, Rarity.COMMON, mage.cards.s.SlightMalfunction.class));
cards.add(new SetCardInfo("Starlight Spectacular", 28, Rarity.RARE, mage.cards.s.StarlightSpectacular.class));
cards.add(new SetCardInfo("Steam Vents", 283, Rarity.RARE, mage.cards.s.SteamVents.class));
+ cards.add(new SetCardInfo("Strength-Testing Hammer", 193, Rarity.UNCOMMON, mage.cards.s.StrengthTestingHammer.class));
cards.add(new SetCardInfo("Stomping Ground", 280, Rarity.RARE, mage.cards.s.StompingGround.class));
cards.add(new SetCardInfo("Swamp", 237, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_UST_VARIOUS));
cards.add(new SetCardInfo("Swamp", 242, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_UST_VARIOUS));
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DevourTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DevourTest.java
index c2687ac93ed..664549309c9 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DevourTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DevourTest.java
@@ -1,4 +1,3 @@
-
package org.mage.test.cards.abilities.keywords;
import mage.abilities.keyword.FlyingAbility;
@@ -9,6 +8,8 @@ import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
+import java.util.Objects;
+
/**
* 702.82. Devour
*
@@ -27,9 +28,11 @@ public class DevourTest extends CardTestPlayerBase {
String devourTargets,
int assertCounter,
boolean assertLion,
- boolean assertMyr,
+ boolean assertGolem,
boolean assertGinger,
- boolean assertRelic
+ boolean assertRelic,
+ boolean assertAngrath,
+ int life
) {
setStrictChooseMode(true);
@@ -46,17 +49,21 @@ public class DevourTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, devourer);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // Creature
- addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr"); // Creature Artifact
+ addCard(Zone.BATTLEFIELD, playerA, "Enatu Golem"); // Artifact Creature - gain 4 life on death
addCard(Zone.BATTLEFIELD, playerA, "Gingerbrute"); // Artifact Creature — Food Golem
addCard(Zone.BATTLEFIELD, playerA, "Darksteel Relic"); // Artifact
+ addCard(Zone.BATTLEFIELD, playerA, "Angrath, Captain of Chaos"); // Planeswalker
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, devourer);
- if (devourTargets == "") {
+ if (Objects.equals(devourTargets, "")) {
setChoice(playerA, false); // no to devour
} else {
setChoice(playerA, true); // yes to devour
addTarget(playerA, devourTargets); // devour targets.
}
+ if (!assertGolem && devourer.equals("Marrow Chomper")) {
+ setChoice(playerA, "When {this} dies, you gain 4 life"); // order triggers
+ }
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@@ -70,12 +77,15 @@ public class DevourTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Silvercoat Lion", assertLion ? 1 : 0);
assertGraveyardCount(playerA, "Silvercoat Lion", assertLion ? 0 : 1);
- assertPermanentCount(playerA, "Alpha Myr", assertMyr ? 1 : 0);
- assertGraveyardCount(playerA, "Alpha Myr", assertMyr ? 0 : 1);
+ assertPermanentCount(playerA, "Enatu Golem", assertGolem ? 1 : 0);
+ assertGraveyardCount(playerA, "Enatu Golem", assertGolem ? 0 : 1);
assertPermanentCount(playerA, "Gingerbrute", assertGinger ? 1 : 0);
assertGraveyardCount(playerA, "Gingerbrute", assertGinger ? 0 : 1);
assertPermanentCount(playerA, "Darksteel Relic", assertRelic ? 1 : 0);
assertGraveyardCount(playerA, "Darksteel Relic", assertRelic ? 0 : 1);
+ assertPermanentCount(playerA, "Angrath, Captain of Chaos", assertAngrath ? 1 : 0);
+ assertGraveyardCount(playerA, "Angrath, Captain of Chaos", assertAngrath ? 0 : 1);
+ assertLife(playerA, life);
}
private void expectedIllegalTest(
@@ -97,7 +107,7 @@ public class DevourTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, devourer);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // Creature
- addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr"); // Creature Artifact
+ addCard(Zone.BATTLEFIELD, playerA, "Enatu Golem"); // Creature Artifact
addCard(Zone.BATTLEFIELD, playerA, "Gingerbrute"); // Artifact Creature — Food Golem
addCard(Zone.BATTLEFIELD, playerA, "Darksteel Relic"); // Artifact
@@ -130,25 +140,25 @@ public class DevourTest extends CardTestPlayerBase {
@Test
public void Wurm_NoDevour() {
expectedPossibleTest(gorgerWurm, "",
- 1 * 0, true, true, true, true);
+ 1 * 0, true, true, true, true, true, 20);
}
@Test
public void Wurm_OneDevour() {
- expectedPossibleTest(gorgerWurm, "Alpha Myr",
- 1 * 1, true, false, true, true);
+ expectedPossibleTest(gorgerWurm, "Enatu Golem",
+ 1 * 1, true, false, true, true, true, 24);
}
@Test
public void Wurm_TwoDevour() {
- expectedPossibleTest(gorgerWurm, "Alpha Myr^Gingerbrute",
- 1 * 2, true, false, false, true);
+ expectedPossibleTest(gorgerWurm, "Enatu Golem^Gingerbrute",
+ 1 * 2, true, false, false, true, true, 24);
}
@Test
public void Wurm_ThreeDevour() {
- expectedPossibleTest(gorgerWurm, "Alpha Myr^Gingerbrute^Silvercoat Lion",
- 1 * 3, false, false, false, true);
+ expectedPossibleTest(gorgerWurm, "Enatu Golem^Gingerbrute^Silvercoat Lion",
+ 1 * 3, false, false, false, true, true, 24);
}
@Test
@@ -168,25 +178,25 @@ public class DevourTest extends CardTestPlayerBase {
@Test
public void Thromok_NoDevour() {
expectedPossibleTest(thromok, "",
- 0 * 0, true, true, true, true);
+ 0 * 0, true, true, true, true, true, 20);
}
@Test
public void Thromok_OneDevour() {
- expectedPossibleTest(thromok, "Alpha Myr",
- 1 * 1, true, false, true, true);
+ expectedPossibleTest(thromok, "Enatu Golem",
+ 1 * 1, true, false, true, true, true, 24);
}
@Test
public void Thromok_TwoDevour() {
- expectedPossibleTest(thromok, "Alpha Myr^Gingerbrute",
- 2 * 2, true, false, false, true);
+ expectedPossibleTest(thromok, "Enatu Golem^Gingerbrute",
+ 2 * 2, true, false, false, true, true, 24);
}
@Test
public void Thromok_ThreeDevour() {
- expectedPossibleTest(thromok, "Alpha Myr^Gingerbrute^Silvercoat Lion",
- 3 * 3, false, false, false, true);
+ expectedPossibleTest(thromok, "Enatu Golem^Gingerbrute^Silvercoat Lion",
+ 3 * 3, false, false, false, true, true, 24);
}
@Test
@@ -206,18 +216,18 @@ public class DevourTest extends CardTestPlayerBase {
@Test
public void Hobbit_NoDevour() {
expectedPossibleTest(hobbit, "",
- 3 * 0, true, true, true, true);
+ 3 * 0, true, true, true, true, true, 20);
}
@Test
public void Hobbit_OneDevour() {
expectedPossibleTest(hobbit, "Gingerbrute",
- 3 * 1, true, true, false, true);
+ 3 * 1, true, true, false, true, true, 20);
}
@Test
public void Hobbit_IllegalDevour() {
- expectedIllegalTest(hobbit, "Alpha Myr");
+ expectedIllegalTest(hobbit, "Enatu Golem");
}
// Caprichrome
@@ -236,25 +246,25 @@ public class DevourTest extends CardTestPlayerBase {
@Test
public void Caprichrome_NoDevour() {
expectedPossibleTest(caprichrome, "",
- 1 * 0, true, true, true, true);
+ 1 * 0, true, true, true, true, true, 20);
}
@Test
public void Caprichrome_OneDevour() {
- expectedPossibleTest(caprichrome, "Alpha Myr",
- 1 * 1, true, false, true, true);
+ expectedPossibleTest(caprichrome, "Enatu Golem",
+ 1 * 1, true, false, true, true, true, 24);
}
@Test
public void Caprichrome_TwoDevour() {
- expectedPossibleTest(caprichrome, "Alpha Myr^Gingerbrute",
- 1 * 2, true, false, false, true);
+ expectedPossibleTest(caprichrome, "Enatu Golem^Gingerbrute",
+ 1 * 2, true, false, false, true, true, 24);
}
@Test
public void Caprichrome_ThreeDevour() {
- expectedPossibleTest(caprichrome, "Alpha Myr^Gingerbrute^Darksteel Relic",
- 1 * 3, true, false, false, false);
+ expectedPossibleTest(caprichrome, "Enatu Golem^Gingerbrute^Darksteel Relic",
+ 1 * 3, true, false, false, false, true, 24);
}
@Test
@@ -276,31 +286,31 @@ public class DevourTest extends CardTestPlayerBase {
@Test
public void Hatchling_NoDevour() {
expectedPossibleTest(hatchling, "",
- 1 * 0, true, true, true, true);
+ 1 * 0, true, true, true, true, true, 20);
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), false);
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), false);
}
@Test
public void Hatchling_OneDevour() {
- expectedPossibleTest(hatchling, "Alpha Myr",
- 1 * 1, true, false, true, true);
+ expectedPossibleTest(hatchling, "Enatu Golem",
+ 1 * 1, true, false, true, true, true, 24);
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), true);
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), true);
}
@Test
public void Hatchling_TwoDevour() {
- expectedPossibleTest(hatchling, "Alpha Myr^Gingerbrute",
- 1 * 2, true, false, false, true);
+ expectedPossibleTest(hatchling, "Enatu Golem^Gingerbrute",
+ 1 * 2, true, false, false, true, true, 24);
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), true);
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), true);
}
@Test
public void Hatchling_ThreeDevour() {
- expectedPossibleTest(hatchling, "Alpha Myr^Gingerbrute^Silvercoat Lion",
- 1 * 3, false, false, false, true);
+ expectedPossibleTest(hatchling, "Enatu Golem^Gingerbrute^Silvercoat Lion",
+ 1 * 3, false, false, false, true, true, 24);
assertAbility(playerA, hatchling, FlyingAbility.getInstance(), true);
assertAbility(playerA, hatchling, TrampleAbility.getInstance(), true);
}
@@ -322,33 +332,65 @@ public class DevourTest extends CardTestPlayerBase {
@Test
public void Chomper_NoDevour() {
expectedPossibleTest(chomper, "",
- 2 * 0, true, true, true, true);
- assertLife(playerA, 20 + 2 * 0);
+ 2 * 0, true, true, true, true, true, 20);
}
@Test
public void Chomper_OneDevour() {
- expectedPossibleTest(chomper, "Alpha Myr",
- 2 * 1, true, false, true, true);
- assertLife(playerA, 20 + 2 * 1);
+ expectedPossibleTest(chomper, "Enatu Golem",
+ 2 * 1, true, false, true, true, true, 26);
}
@Test
public void Chomper_TwoDevour() {
- expectedPossibleTest(chomper, "Alpha Myr^Gingerbrute",
- 2 * 2, true, false, false, true);
- assertLife(playerA, 20 + 2 * 2);
+ expectedPossibleTest(chomper, "Enatu Golem^Gingerbrute",
+ 2 * 2, true, false, false, true, true, 28);
}
@Test
public void Chomper_ThreeDevour() {
- expectedPossibleTest(chomper, "Alpha Myr^Gingerbrute^Silvercoat Lion",
- 2 * 3, false, false, false, true);
- assertLife(playerA, 20 + 2 * 3);
+ expectedPossibleTest(chomper, "Enatu Golem^Gingerbrute^Silvercoat Lion",
+ 2 * 3, false, false, false, true, true, 30);
}
@Test
public void Chomper_IllegalDevour() {
expectedIllegalTest(chomper, "Darksteel Relic");
}
-}
\ No newline at end of file
+
+ // Devouring Hellion {2}{R}
+ // Creature — Hellion
+ // As Devouring Hellion enters, you may sacrifice any number of creatures and/or planeswalkers.
+ // If you do, it enters with twice that many +1/+1 counters on it.
+ private static final String hellion = "Devouring Hellion";
+
+ @Test
+ public void hellionNoDevour() {
+ expectedPossibleTest(hellion, "",
+ 0, true, true, true, true, true, 20);
+ }
+
+ @Test
+ public void hellionOneDevour() {
+ expectedPossibleTest(hellion, "Angrath, Captain of Chaos",
+ 2, true, true, true, true, false, 20);
+ }
+
+ @Test
+ public void hellionTwoDevour() {
+ expectedPossibleTest(hellion, "Enatu Golem^Angrath, Captain of Chaos",
+ 4, true, false, true, true, false, 24);
+ }
+
+ @Test
+ public void hellionThreeDevour() {
+ expectedPossibleTest(hellion, "Enatu Golem^Gingerbrute^Angrath, Captain of Chaos",
+ 6, true, false, false, true, false, 24);
+ }
+
+ @Test
+ public void hellionIllegalDevour() {
+ expectedIllegalTest(hellion, "Darksteel Relic");
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ImpendingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ImpendingTest.java
new file mode 100644
index 00000000000..33b65e5ec3d
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ImpendingTest.java
@@ -0,0 +1,226 @@
+package org.mage.test.cards.abilities.keywords;
+
+import mage.abilities.keyword.ImpendingAbility;
+import mage.constants.CardType;
+import mage.constants.PhaseStep;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.permanent.Permanent;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author TheElk801
+ */
+public class ImpendingTest extends CardTestPlayerBase {
+
+ private static final String hauntwoods = "Overlord of the Hauntwoods";
+
+ public void assertHasImpending(String name, boolean hasAbility) {
+ Permanent permanent = getPermanent(name);
+ Assert.assertEquals(
+ "Should" + (hasAbility ? "" : "n't") + " have Impending ability",
+ hasAbility, permanent.getAbilities(currentGame).containsClass(ImpendingAbility.class)
+ );
+ }
+
+ @Test
+ public void testCastRegular() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with no");
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, true);
+ assertSubtype(hauntwoods, SubType.AVATAR);
+ assertSubtype(hauntwoods, SubType.HORROR);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 0);
+ assertPowerToughness(playerA, hauntwoods, 6, 5);
+ assertHasImpending(hauntwoods, true);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ @Test
+ public void testCastImpending() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, false);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 4);
+ assertHasImpending(hauntwoods, true);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ @Test
+ public void testImpendingRemoveCounter() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, false);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 4 - 1);
+ assertHasImpending(hauntwoods, true);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ @Test
+ public void testCastImpendingRemoveAllCounters() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ setStrictChooseMode(true);
+ setStopAt(8, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, true);
+ assertSubtype(hauntwoods, SubType.AVATAR);
+ assertSubtype(hauntwoods, SubType.HORROR);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 0);
+ assertPowerToughness(playerA, hauntwoods, 6, 5);
+ assertHasImpending(hauntwoods, false);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ private static final String hexmage = "Vampire Hexmage";
+
+ @Test
+ public void testCastImpendingHexmage() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.BATTLEFIELD, playerA, hexmage);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Sacrifice", hauntwoods);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, true);
+ assertSubtype(hauntwoods, SubType.AVATAR);
+ assertSubtype(hauntwoods, SubType.HORROR);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 0);
+ assertPowerToughness(playerA, hauntwoods, 6, 5);
+ assertHasImpending(hauntwoods, true);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ @Test
+ public void testCastImpendingHexmageNextTurn() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.BATTLEFIELD, playerA, hexmage);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Sacrifice", hauntwoods);
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, true);
+ assertSubtype(hauntwoods, SubType.AVATAR);
+ assertSubtype(hauntwoods, SubType.HORROR);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 0);
+ assertPowerToughness(playerA, hauntwoods, 6, 5);
+ assertHasImpending(hauntwoods, false);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ private static final String solemnity = "Solemnity";
+
+ @Test
+ public void testCastImpendingSolemnity() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.BATTLEFIELD, playerA, solemnity);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, true);
+ assertSubtype(hauntwoods, SubType.AVATAR);
+ assertSubtype(hauntwoods, SubType.HORROR);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 0);
+ assertPowerToughness(playerA, hauntwoods, 6, 5);
+ assertHasImpending(hauntwoods, true);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+
+ @Test
+ public void testCastImpendingSolemnityNextTurn() {
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.BATTLEFIELD, playerA, solemnity);
+ addCard(Zone.HAND, playerA, hauntwoods);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, hauntwoods);
+ setChoice(playerA, "Cast with Impending");
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, hauntwoods, 1);
+ assertType(hauntwoods, CardType.ENCHANTMENT, true);
+ assertType(hauntwoods, CardType.CREATURE, true);
+ assertSubtype(hauntwoods, SubType.AVATAR);
+ assertSubtype(hauntwoods, SubType.HORROR);
+ assertCounterCount(playerA, hauntwoods, CounterType.TIME, 0);
+ assertPowerToughness(playerA, hauntwoods, 6, 5);
+ assertHasImpending(hauntwoods, false);
+
+ assertPermanentCount(playerA, "Everywhere", 1);
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/sacrifice/SacrificeTargetCostTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/sacrifice/SacrificeTargetCostTest.java
new file mode 100644
index 00000000000..4c88a4c194c
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/sacrifice/SacrificeTargetCostTest.java
@@ -0,0 +1,139 @@
+package org.mage.test.cards.cost.sacrifice;
+
+import mage.abilities.common.LicidAbility;
+import mage.abilities.costs.mana.ColoredManaCost;
+import mage.abilities.keyword.HasteAbility;
+import mage.constants.CardType;
+import mage.constants.ColoredManaSymbol;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author jimga150
+ */
+public class SacrificeTargetCostTest extends CardTestPlayerBase {
+
+ // Tests a variety of use cases with SacrificeTargetCost, making sure the right player pays the cost
+
+ @Test
+ public void testSimpleCost() {
+ // All Rats have fear.
+ // {T}, Sacrifice a Rat: Create X 1/1 black Rat creature tokens, where X is the number of Rats you control.
+ addCard(Zone.BATTLEFIELD, playerA, "Marrow-Gnawer");
+ addCard(Zone.BATTLEFIELD, playerA, "Karumonix, the Rat King");
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}");
+ setChoice(playerA, "Karumonix, the Rat King"); // Target to sacrifice
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Marrow-Gnawer", 1);
+ assertPermanentCount(playerA, "Rat Token", 1);
+ assertGraveyardCount(playerA, "Karumonix, the Rat King", 1);
+ }
+
+ @Test
+ public void testSimpleCostOtherPlayerActivate() {
+ // {1}, Sacrifice a land: Draw a card. Any player may activate this ability.
+ addCard(Zone.BATTLEFIELD, playerA, "Excavation");
+ addCard(Zone.BATTLEFIELD, playerB, "Forest");
+
+ // Player B activates Player A's Excavate ability
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}");
+ setChoice(playerB, "Forest"); // Target to sacrifice
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertHandCount(playerB, 1);
+ assertGraveyardCount(playerB, "Forest", 1);
+ }
+
+ @Test
+ public void testDoUnlessSacrificeTrigger() {
+ // When Demanding Dragon enters, it deals 5 damage to target opponent unless that player sacrifices a creature.
+ addCard(Zone.HAND, playerA, "Demanding Dragon", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
+ addCard(Zone.BATTLEFIELD, playerB, "Memnite");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Demanding Dragon");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "No"); // Sac a creature?
+
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Demanding Dragon");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "Yes"); // Sac a creature?
+ setChoice(playerB, "Memnite"); // Sac Memnite
+
+ setStrictChooseMode(true);
+ setStopAt(3, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertGraveyardCount(playerB, "Memnite", 1);
+ }
+
+ @Test
+ public void testDoUnlessSacrificeActivated() {
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
+ addCard(Zone.BATTLEFIELD, playerB, "Memnite", 1);
+ addCard(Zone.HAND, playerA, "Tergrid, God of Fright // Tergrid's Lantern");
+ addCard(Zone.HAND, playerB, "Memnarch");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tergrid's Lantern", true);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Target player");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "No"); // Sac or discard to avoid life loss?
+
+ activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Target player");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "Yes"); // Sac or discard to avoid life loss?
+ setChoice(playerB, "Yes"); // Yes - Sacrifice, No - Discard
+ setChoice(playerB, "Memnite"); // To sacrifice
+
+ setStrictChooseMode(true);
+ setStopAt(3, PhaseStep.END_TURN);
+ execute();
+
+ assertLife(playerB, currentGame.getStartingLife() - 3);
+ assertPermanentCount(playerB, "Memnite", 0);
+ assertGraveyardCount(playerB, "Memnite", 1);
+ assertHandCount(playerB, "Memnarch", 1);
+ }
+
+ /**
+ * Use special action that has opponent sac a permanent
+ */
+ @Test
+ public void SpecialActionTest() {
+ // Enchanted creature can't attack or block, and its activated abilities can't be activated.
+ // That creature's controller may sacrifice a permanent for that player to ignore this effect until end of turn.
+ addCard(Zone.HAND, playerA, "Volrath's Curse");
+
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
+ addCard(Zone.BATTLEFIELD, playerB, "Memnite");
+ addCard(Zone.BATTLEFIELD, playerB, "Memnarch");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volrath's Curse");
+ addTarget(playerA, "Memnarch");
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice a ", "Volrath's Curse");
+ setChoice(playerB, "Memnite");
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerB, "Memnite", 0);
+ assertGraveyardCount(playerB, "Memnite", 1);
+ assertPermanentCount(playerB, "Memnarch", 1);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/TergridsLanternTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/TergridsLanternTest.java
new file mode 100644
index 00000000000..23a6d62eedc
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/TergridsLanternTest.java
@@ -0,0 +1,101 @@
+package org.mage.test.cards.single.khm;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * {@link mage.cards.t.TergridGodOfFright Tergrid, God of Fright // Tergrid's Lantern}
+ * {3}{B}{B}
+ * Legendary Creature — God
+ * P/T 4/5
+ * Menace
+ * Whenever an opponent sacrifices a nontoken permanent or discards a permanent card, you may put that card from a graveyard onto the battlefield under your control.
+ *
+ * {3}{B}
+ * Legendary Artifact
+ * {T}: Target player loses 3 life unless they sacrifice a nonland permanent or discard a card.
+ * {3}{B}: Untap Tergrid’s Lantern.
+ *
+ * @author jimga150
+ */
+public class TergridsLanternTest extends CardTestPlayerBase {
+
+ private static final String tergrid = "Tergrid, God of Fright // Tergrid's Lantern";
+ private static final String tergridFirstSide = "Tergrid, God of Fright";
+ private static final String tergridSecondSide = "Tergrid's Lantern";
+
+ @Test
+ public void testLoseLife() {
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
+ addCard(Zone.BATTLEFIELD, playerB, "Memnite", 1);
+ addCard(Zone.HAND, playerA, tergrid);
+ addCard(Zone.HAND, playerB, "Memnarch");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, tergridSecondSide, true);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Target player");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "No"); // Sac or discard to avoid life loss?
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertLife(playerB, currentGame.getStartingLife() - 3);
+ assertPermanentCount(playerB, "Memnite", 1);
+ assertHandCount(playerB, "Memnarch", 1);
+ }
+
+ @Test
+ public void testSacCreature() {
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
+ addCard(Zone.BATTLEFIELD, playerB, "Memnite", 1);
+ addCard(Zone.HAND, playerA, tergrid);
+ addCard(Zone.HAND, playerB, "Memnarch");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, tergridSecondSide, true);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Target player");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "Yes"); // Sac or discard to avoid life loss?
+ setChoice(playerB, "Yes"); // Yes - Sacrifice, No - Discard
+ setChoice(playerB, "Memnite"); // To sacrifice
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertLife(playerB, currentGame.getStartingLife());
+ assertPermanentCount(playerB, "Memnite", 0);
+ assertGraveyardCount(playerB, "Memnite", 1);
+ assertHandCount(playerB, "Memnarch", 1);
+ }
+
+ @Test
+ public void testDiscard() {
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
+ addCard(Zone.BATTLEFIELD, playerB, "Memnite", 1);
+ addCard(Zone.HAND, playerA, tergrid);
+ addCard(Zone.HAND, playerB, "Memnarch");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, tergridSecondSide, true);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Target player");
+ addTarget(playerA, playerB);
+ setChoice(playerB, "Yes"); // Sac or discard to avoid life loss?
+ setChoice(playerB, "No"); // Yes - Sacrifice, No - Discard
+ setChoice(playerB, "Memnarch"); // To discard
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertLife(playerB, currentGame.getStartingLife());
+ assertPermanentCount(playerB, "Memnite", 1);
+ assertGraveyardCount(playerB, "Memnarch", 1);
+ assertHandCount(playerB, "Memnarch", 0);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/PartyThrasherTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/PartyThrasherTest.java
new file mode 100644
index 00000000000..0f8b2d7051f
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh3/PartyThrasherTest.java
@@ -0,0 +1,110 @@
+package org.mage.test.cards.single.mh3;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author jimga150
+ */
+public class PartyThrasherTest extends CardTestPlayerBase {
+
+ /**
+ * {@link mage.cards.p.PartyThrasher Party Thrasher} {1}{R}
+ * Creature — Lizard Wizard
+ * Noncreature spells you cast from exile have convoke.
+ * (Each creature you tap while casting a noncreature spell from exile
+ * pays for {1} or one mana of that creature’s color.)
+ * At the beginning of your first main phase, you may discard a card.
+ * If you do, exile the top two cards of your library, then choose one of them. You may play that card this turn.
+ * 1/4
+ */
+ private static final String partyThrasher = "Party Thrasher";
+
+ @Test
+ public void testPlayFromExile() {
+ skipInitShuffling();
+
+ addCard(Zone.LIBRARY, playerA, "Memnite");
+ addCard(Zone.LIBRARY, playerA, "Accorder's Shield");
+ addCard(Zone.BATTLEFIELD, playerA, partyThrasher, 1);
+ addCard(Zone.HAND, playerA, "Memnarch", 1);
+
+ setChoice(playerA, "Yes"); // Discard card?
+ setChoice(playerA, "Memnarch"); // Which card to pitch?
+ setChoice(playerA, "Memnite");
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Memnite");
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertGraveyardCount(playerA, "Memnarch", 1);
+ assertPermanentCount(playerA, "Memnite", 1);
+ assertExileCount(playerA, "Accorder's Shield", 1);
+ }
+
+ @Test
+ public void testTryUnplayableCard() {
+ skipInitShuffling();
+
+ addCard(Zone.LIBRARY, playerA, "Memnite");
+ addCard(Zone.LIBRARY, playerA, "Accorder's Shield");
+ addCard(Zone.BATTLEFIELD, playerA, partyThrasher, 1);
+ addCard(Zone.HAND, playerA, "Memnarch", 1);
+
+ setChoice(playerA, "Yes"); // Discard card?
+ setChoice(playerA, "Memnarch"); // Which card to pitch?
+ setChoice(playerA, "Memnite");
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Accorder's Shield");
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+
+ try {
+ execute();
+ Assert.fail("Should have failed to execute, as Accorder's Shield should not be castable");
+ } catch (Throwable e) {
+ if (!e.getMessage().contains("Can't find ability to activate command: Cast Accorder's Shield")) {
+ Assert.fail("must throw error about missing ability:\n" + e.getMessage());
+ }
+ }
+
+ }
+
+ @Test
+ public void testTryPlayFromExileNextTurn() {
+ skipInitShuffling();
+
+ addCard(Zone.LIBRARY, playerA, "Memnite");
+ addCard(Zone.LIBRARY, playerA, "Accorder's Shield");
+ addCard(Zone.BATTLEFIELD, playerA, partyThrasher, 1);
+ addCard(Zone.HAND, playerA, "Memnarch", 1);
+
+ setChoice(playerA, "Yes"); // Discard card?
+ setChoice(playerA, "Memnarch"); // Which card to pitch?
+ setChoice(playerA, "Memnite");
+
+ setChoice(playerA, "No"); // Discard card? (next turn)
+
+ castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Memnite");
+
+ setStrictChooseMode(true);
+ setStopAt(3, PhaseStep.END_TURN);
+
+ try {
+ execute();
+ Assert.fail("Should have failed to execute, as Memnite should not be castable the turn after Party Thrasher Exiled it.");
+ } catch (Throwable e) {
+ if (!e.getMessage().contains("Can't find ability to activate command: Cast Memnite")) {
+ Assert.fail("must throw error about missing ability:\n" + e.getMessage());
+ }
+ }
+
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/tmp/PhyrexianSplicerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/tmp/PhyrexianSplicerTest.java
new file mode 100644
index 00000000000..4deb381dec9
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/tmp/PhyrexianSplicerTest.java
@@ -0,0 +1,43 @@
+package org.mage.test.cards.single.tmp;
+
+import mage.abilities.keyword.TrampleAbility;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author JayDi85
+ */
+public class PhyrexianSplicerTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_Normal() {
+ // {2}, {T}, Choose flying, first strike, trample, or shadow: Until end of turn, target creature with the
+ // chosen ability loses it and another target creature gains it.
+ addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Splicer", 1); // {2}
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
+ //
+ // Flying, first strike, vigilance, trample, haste, protection from black and from red
+ addCard(Zone.BATTLEFIELD, playerA, "Akroma, Angel of Wrath");
+ // Shadow
+ addCard(Zone.BATTLEFIELD, playerA, "Augur il-Vec");
+
+ checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Wrath", TrampleAbility.class, true);
+ checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Augur il-Vec", TrampleAbility.class, false);
+
+ // move trample from one to another
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}, Choose");
+ addTarget(playerA, "Akroma, Angel of Wrath"); // loose
+ addTarget(playerA, "Augur il-Vec"); // gain
+ setChoice(playerA, "Trample");
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
+
+ checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Wrath", TrampleAbility.class, false);
+ checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Augur il-Vec", TrampleAbility.class, true);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
index cf90889e0ea..b9c5d2c9e1a 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
@@ -1125,20 +1125,16 @@ public class TestPlayer implements Player {
}
private Permanent findPermanentWithAssert(PlayerAction action, Game game, Player player, String cardName) {
- for (Permanent perm : game.getBattlefield().getAllPermanents()) {
- // need by controller
- if (!perm.getControllerId().equals(player.getId())) {
- continue;
- }
-
+ for (Permanent perm : game.getBattlefield().getAllActivePermanents(player.getId())) {
// need by alias or by name
if (!hasObjectTargetNameOrAlias(perm, cardName)) {
continue;
}
-
- // all fine
return perm;
}
+ printStart(game, "Permanents of " + player.getName());
+ printPermanents(game, game.getBattlefield().getAllActivePermanents(player.getId()), this);
+ printEnd();
Assert.fail(action.getActionName() + " - can't find permanent to check: " + cardName);
return null;
}
diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
index 7202d3d882d..400605b0428 100644
--- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
+++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
@@ -16,6 +16,7 @@ import mage.abilities.effects.common.FightTargetsEffect;
import mage.abilities.effects.common.counter.ProliferateEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.hint.common.CitysBlessingHint;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.abilities.hint.common.InitiativeHint;
import mage.abilities.hint.common.MonarchHint;
import mage.abilities.keyword.*;
@@ -142,14 +143,12 @@ 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", "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", "Balemurk Leech"); // temporary
// number
// skipListAddName(SKIP_LIST_NUMBER, set, cardName);
@@ -157,6 +156,7 @@ public class VerifyCardDataTest {
// rarity
// skipListAddName(SKIP_LIST_RARITY, set, cardName);
skipListAddName(SKIP_LIST_RARITY, "CMR", "The Prismatic Piper"); // Collation is not yet set up for CMR https://www.lethe.xyz/mtg/collation/cmr.html
+ skipListAddName(SKIP_LIST_RARITY, "DSC", "Suspicious Bookcase"); // temporary
// missing abilities
// skipListAddName(SKIP_LIST_MISSING_ABILITIES, set, cardName);
@@ -2071,6 +2071,7 @@ public class VerifyCardDataTest {
cardHints.put(CitysBlessingHint.class, "city's blessing");
cardHints.put(MonarchHint.class, "the monarch");
cardHints.put(InitiativeHint.class, "the initiative");
+ cardHints.put(CurrentDungeonHint.class, "venture into");
for (Class hintClass : cardHints.keySet()) {
String lookupText = cardHints.get(hintClass);
boolean needHint = ref.text.contains(lookupText);
@@ -2770,6 +2771,9 @@ public class VerifyCardDataTest {
public void test_checkCardConstructors() {
// create all cards, can catch additional verify and runtime checks from abilities and effects
// example: wrong code usage errors
+ //
+ // warning, look at stack trace logs, not card names -- some error code can be hidden in static methods and can be called from un-related cards
+ // use test_showCardInfo for detailed errors
Collection errorsList = new ArrayList<>();
Collection sets = Sets.getInstance().values();
for (ExpansionSet set : sets) {
@@ -2778,7 +2782,7 @@ public class VerifyCardDataTest {
Card card = CardImpl.createCard(setInfo.getCardClass(), new CardSetInfo(setInfo.getName(), set.getCode(),
setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()));
if (card == null) {
- errorsList.add("Error: broken constructor " + setInfo.getCardClass());
+ errorsList.add("Error: can't create card - " + setInfo.getCardClass() + " - see logs for errors");
continue;
}
if (!card.getExpansionSetCode().equals(set.getCode())) {
@@ -2786,7 +2790,7 @@ public class VerifyCardDataTest {
}
} catch (Throwable e) {
// CardImpl.createCard don't throw exceptions (only error logs), so that logs are useless here
- logger.error("Error: can't create card " + setInfo.getName() + ": " + e.getMessage(), e);
+ errorsList.add("Error: can't create card - " + setInfo.getCardClass() + " - see logs for errors");
}
}
}
diff --git a/Mage/src/main/java/mage/abilities/Modes.java b/Mage/src/main/java/mage/abilities/Modes.java
index bff1f93530a..fa84ea9e0db 100644
--- a/Mage/src/main/java/mage/abilities/Modes.java
+++ b/Mage/src/main/java/mage/abilities/Modes.java
@@ -38,7 +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 int moreLimit; // if multiple modes are allowed, this limits how many additional modes may be chosen
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
@@ -245,7 +245,7 @@ public class Modes extends LinkedHashMap implements Copyable
// use case: make more modes chooseable
if (moreCondition != null && moreCondition.apply(game, source)) {
- realMaxModes = this.moreLimit;
+ realMaxModes = Math.min(this.moreLimit, this.size());
}
// use case: limit max modes by opponents (example: choose one or more... each mode must target a different player)
@@ -303,12 +303,9 @@ public class Modes extends LinkedHashMap implements Copyable
this.put(mode.getId(), mode);
}
- public void setMoreCondition(Condition moreCondition) {
- this.moreCondition = moreCondition;
- }
-
- public void setMoreLimit(int moreLimit) {
+ public void setMoreCondition(int moreLimit, Condition moreCondition) {
this.moreLimit = moreLimit;
+ this.moreCondition = moreCondition;
}
private boolean isAlreadySelectedModesOutdated(Game game, Ability source) {
diff --git a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java
index 9a07d574402..8d9804f7504 100644
--- a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java
@@ -16,7 +16,7 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl {
public ActivateIfConditionActivatedAbility(Effect effect, Cost cost, Condition condition) {
this(Zone.BATTLEFIELD, effect, cost, condition, TimingRule.INSTANT);
}
-
+
public ActivateIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition) {
this(zone, effect, cost, condition, TimingRule.INSTANT);
}
@@ -34,6 +34,10 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl {
@Override
public String getRule() {
StringBuilder sb = new StringBuilder(super.getRule());
+ if (condition.toString().startsWith("You may also")) {
+ sb.append(' ').append(condition.toString()).append('.');
+ return sb.toString();
+ }
if (condition instanceof InvertCondition) {
sb.append(" You can't activate this ability ");
} else {
diff --git a/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java
index a1c9992a76a..0391eefea0a 100644
--- a/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java
@@ -7,11 +7,14 @@ import mage.constants.TimingRule;
import mage.constants.Zone;
/**
- *
* @author weirddan455
*/
public class ActivateOncePerGameActivatedAbility extends ActivatedAbilityImpl {
+ public ActivateOncePerGameActivatedAbility(Effect effect, Cost cost) {
+ this(Zone.BATTLEFIELD, effect, cost, TimingRule.INSTANT);
+ }
+
public ActivateOncePerGameActivatedAbility(Zone zone, Effect effect, Cost cost, TimingRule timingRule) {
super(zone, effect, cost);
this.timing = timingRule;
diff --git a/Mage/src/main/java/mage/abilities/common/DealtDamageAttachedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealtDamageAttachedTriggeredAbility.java
index 48227613ddd..91abbc177c2 100644
--- a/Mage/src/main/java/mage/abilities/common/DealtDamageAttachedTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/DealtDamageAttachedTriggeredAbility.java
@@ -1,18 +1,16 @@
-
package mage.abilities.common;
-import java.util.UUID;
-
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.SetTargetPointer;
import mage.constants.Zone;
import mage.game.Game;
-import mage.game.events.GameEvent.EventType;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
+import java.util.UUID;
+
/**
* @author LoneFox
*/
@@ -27,7 +25,7 @@ public class DealtDamageAttachedTriggeredAbility extends TriggeredAbilityImpl {
public DealtDamageAttachedTriggeredAbility(Zone zone, Effect effect, boolean optional, SetTargetPointer setTargetPointer) {
super(zone, effect, optional);
this.setTargetPointer = setTargetPointer;
- setTriggerPhrase("Whenever enchanted creature is dealt damage, ");
+ setTriggerPhrase(getWhen() + "enchanted creature is dealt damage, ");
}
protected DealtDamageAttachedTriggeredAbility(final DealtDamageAttachedTriggeredAbility ability) {
diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksSourceTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksSourceTriggeredAbility.java
index c073bc3e6d8..b18b1f29b2a 100644
--- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksSourceTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldOrAttacksSourceTriggeredAbility.java
@@ -19,6 +19,7 @@ public class EntersBattlefieldOrAttacksSourceTriggeredAbility extends TriggeredA
public EntersBattlefieldOrAttacksSourceTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
setTriggerPhrase("Whenever {this} enters or attacks, ");
+ this.withRuleTextReplacement(true);
}
protected EntersBattlefieldOrAttacksSourceTriggeredAbility(final EntersBattlefieldOrAttacksSourceTriggeredAbility ability) {
diff --git a/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java
index c68b3d17559..43635f5246c 100644
--- a/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/TransformsOrEntersTriggeredAbility.java
@@ -14,7 +14,7 @@ public class TransformsOrEntersTriggeredAbility extends TriggeredAbilityImpl {
public TransformsOrEntersTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
- setTriggerPhrase("Whenever this creature enters the battlefield or transforms into {this}, ");
+ setTriggerPhrase("Whenever this creature enters or transforms into {this}, ");
}
private TransformsOrEntersTriggeredAbility(final TransformsOrEntersTriggeredAbility ability) {
diff --git a/Mage/src/main/java/mage/abilities/costs/AlternativeCostImpl.java b/Mage/src/main/java/mage/abilities/costs/AlternativeCostImpl.java
index 1bccc0d6348..3d86769ed51 100644
--- a/Mage/src/main/java/mage/abilities/costs/AlternativeCostImpl.java
+++ b/Mage/src/main/java/mage/abilities/costs/AlternativeCostImpl.java
@@ -51,7 +51,10 @@ public class AlternativeCostImpl> extends Costs
if (onlyCost) {
return getText();
} else {
- return (name != null ? name : "") + (isMana ? " " : "—") + getText() + (isMana ? "" : '.');
+ String costName = (name != null ? name : "");
+ String delimiter = (!isMana || (!costName.isEmpty() && costName.substring(costName.length() - 1).matches("\\d")))
+ ? "—" : " ";
+ return costName + delimiter + getText() + (isMana ? "" : '.');
}
}
diff --git a/Mage/src/main/java/mage/abilities/costs/AlternativeSourceCostsImpl.java b/Mage/src/main/java/mage/abilities/costs/AlternativeSourceCostsImpl.java
index 0f947e5568e..7657a0a336d 100644
--- a/Mage/src/main/java/mage/abilities/costs/AlternativeSourceCostsImpl.java
+++ b/Mage/src/main/java/mage/abilities/costs/AlternativeSourceCostsImpl.java
@@ -30,11 +30,15 @@ public abstract class AlternativeSourceCostsImpl extends StaticAbility implement
}
protected AlternativeSourceCostsImpl(String name, String reminderText, Cost cost) {
+ this(name, reminderText, cost, name);
+ }
+
+ protected AlternativeSourceCostsImpl(String name, String reminderText, Cost cost, String activationKey) {
super(Zone.ALL, null);
this.name = name;
this.reminderText = reminderText;
this.alternativeCost = new AlternativeCostImpl<>(name, reminderText, cost);
- this.activationKey = getActivationKey(name);
+ this.activationKey = getActivationKey(activationKey);
}
protected AlternativeSourceCostsImpl(final AlternativeSourceCostsImpl ability) {
diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java
index 5de46d6677d..4a4836b44e0 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java
@@ -1,14 +1,13 @@
package mage.abilities.costs.common;
import mage.abilities.Ability;
-import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.SacrificeCost;
-import mage.constants.AbilityType;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import mage.players.Player;
import java.util.ArrayList;
import java.util.List;
@@ -46,19 +45,15 @@ public class SacrificeAllCost extends CostImpl implements SacrificeCost {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- UUID activator = controllerId;
- if (ability.getAbilityType().isActivatedAbility() || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
- if (((ActivatedAbilityImpl) ability).getActivatorId() != null) {
- activator = ((ActivatedAbilityImpl) ability).getActivatorId();
- } // else, Activator not filled?
+ Player controller = game.getPlayer(controllerId);
+ if (controller == null){
+ return false;
}
-
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controllerId, game)) {
- if (!game.getPlayer(activator).canPaySacrificeCost(permanent, source, controllerId, game)) {
+ if (!controller.canPaySacrificeCost(permanent, source, controllerId, game)) {
return false;
}
}
-
return true;
}
diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java
index 687bf53503d..4fa11cbffc4 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java
@@ -1,15 +1,14 @@
package mage.abilities.costs.common;
import mage.abilities.Ability;
-import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.SacrificeCost;
-import mage.constants.AbilityType;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetSacrifice;
import mage.util.CardUtil;
@@ -58,12 +57,8 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost {
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
- UUID activator = controllerId;
- if (ability.getAbilityType().isActivatedAbility() || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
- activator = ((ActivatedAbilityImpl) ability).getActivatorId();
- }
- // can be cancel by user
- if (this.getTargets().choose(Outcome.Sacrifice, activator, source.getSourceId(), source, game)) {
+ // can be cancelled by user
+ if (this.getTargets().choose(Outcome.Sacrifice, controllerId, source.getSourceId(), source, game)) {
for (UUID targetId : this.getTargets().get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent == null) {
@@ -88,17 +83,14 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost {
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
- UUID activator = controllerId;
- if (ability.getAbilityType().isActivatedAbility() || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
- if (((ActivatedAbilityImpl) ability).getActivatorId() != null) {
- activator = ((ActivatedAbilityImpl) ability).getActivatorId();
- } // else, Activator not filled?
+ Player controller = game.getPlayer(controllerId);
+ if (controller == null){
+ return false;
}
-
int validTargets = 0;
int neededTargets = this.getTargets().get(0).getNumberOfTargets();
for (Permanent permanent : game.getBattlefield().getActivePermanents(((TargetPermanent) this.getTargets().get(0)).getFilter(), controllerId, source, game)) {
- if (game.getPlayer(activator).canPaySacrificeCost(permanent, source, controllerId, game)) {
+ if (controller.canPaySacrificeCost(permanent, source, controllerId, game)) {
validTargets++;
if (validTargets >= neededTargets) {
return true;
@@ -106,10 +98,7 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost {
}
}
// solves issue #8097, if a sacrifice cost is optional and you don't have valid targets, then the cost can be paid
- if (validTargets == 0 && this.getTargets().get(0).getMinNumberOfTargets() == 0) {
- return true;
- }
- return false;
+ return validTargets == 0 && this.getTargets().get(0).getMinNumberOfTargets() == 0;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java
index b2171b96d90..800c54452b5 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java
@@ -6,8 +6,7 @@ import mage.abilities.effects.ReplacementEffectImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.counters.CounterType;
-import mage.filter.common.FilterControlledPermanent;
-import mage.filter.predicate.Predicate;
+import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
@@ -45,9 +44,9 @@ public class DevourEffect extends ReplacementEffectImpl {
// "creature" is a special case as the rule will not mention it.
//
// 's' will be added to pluralize, so far so good with the current text generation.
- private final FilterControlledPermanent filterDevoured;
+ private final FilterPermanent filterDevoured;
- public DevourEffect(int devourFactor, FilterControlledPermanent filterDevoured) {
+ public DevourEffect(int devourFactor, FilterPermanent filterDevoured) {
super(Duration.EndOfGame, Outcome.Detriment);
this.devourFactor = devourFactor;
this.filterDevoured = filterDevoured;
@@ -81,11 +80,8 @@ public class DevourEffect extends ReplacementEffectImpl {
if (creature == null || controller == null) {
return false;
}
-
- FilterControlledPermanent filter = new FilterControlledPermanent(filterDevoured.getMessage() + "s to devour");
- for (Predicate predicate : filterDevoured.getPredicates()) {
- filter.add(predicate);
- }
+ FilterPermanent filter = filterDevoured.copy();
+ filter.setMessage(filterDevoured.getMessage() + "s (to devour)");
filter.add(AnotherPredicate.instance);
Target target = new TargetSacrifice(1, Integer.MAX_VALUE, filter);
@@ -142,9 +138,9 @@ public class DevourEffect extends ReplacementEffectImpl {
text += devourFactor;
}
- text += " (As this enters the battlefield, you may sacrifice any number of "
+ text += " (As this enters, you may sacrifice any number of "
+ filterMessage + "s. "
- + "This creature enters the battlefield with ";
+ + "This creature enters with ";
if (devourFactor == Integer.MAX_VALUE) {
text += "X +1/+1 counters on it for each of those creatures";
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java
index 353ad5236c8..7f3ef03a30f 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesCreatureSourceEffect.java
@@ -35,13 +35,14 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
* existing creature types.
*/
- protected Token token;
- protected CardType retainType; // if null, loses previous types
- protected boolean loseAbilities = false;
- protected boolean loseEquipmentType = false;
- protected DynamicValue power = null;
- protected DynamicValue toughness = null;
- protected boolean durationRuleAtStart; // put duration rule at the start of the rules text rather than the end
+ private final Token token;
+ private final CardType retainType; // if null, loses previous types
+ private boolean loseAbilities = false;
+ private boolean loseEquipmentType = false;
+ private boolean keepCreatureSubtypes;
+ private DynamicValue power = null;
+ private DynamicValue toughness = null;
+ private boolean durationRuleAtStart; // put duration rule at the start of the rules text rather than the end
/**
* @param token Token as blueprint for creature to become
@@ -49,20 +50,11 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
* @param duration Duration for the effect
*/
public BecomesCreatureSourceEffect(Token token, CardType retainType, Duration duration) {
- this(token, retainType, duration, (retainType == CardType.PLANESWALKER || retainType == CardType.CREATURE));
- }
-
- /**
- * @param token Token as blueprint for creature to become
- * @param retainType If null, permanent loses its previous types, otherwise retains types with appropriate text
- * @param duration Duration for the effect
- * @param durationRuleAtStart for text rule generation
- */
- public BecomesCreatureSourceEffect(Token token, CardType retainType, Duration duration, boolean durationRuleAtStart) {
super(duration, Outcome.BecomeCreature);
this.token = token;
this.retainType = retainType;
- this.durationRuleAtStart = durationRuleAtStart;
+ this.keepCreatureSubtypes = (retainType == CardType.ENCHANTMENT); // default usage, override if needed
+ this.durationRuleAtStart = (retainType == CardType.PLANESWALKER || retainType == CardType.CREATURE);
setText();
this.addDependencyType(DependencyType.BecomeCreature);
}
@@ -73,6 +65,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
this.retainType = effect.retainType;
this.loseAbilities = effect.loseAbilities;
this.loseEquipmentType = effect.loseEquipmentType;
+ this.keepCreatureSubtypes = effect.keepCreatureSubtypes;
if (effect.power != null) {
this.power = effect.power.copy();
}
@@ -124,7 +117,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
if (loseEquipmentType) {
permanent.removeSubType(game, SubType.EQUIPMENT);
}
- if (retainType == CardType.CREATURE || retainType == CardType.ARTIFACT) {
+ if (!keepCreatureSubtypes) {
permanent.removeAllCreatureTypes(game);
}
permanent.copySubTypesFrom(game, token);
@@ -191,6 +184,16 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
return this;
}
+ /**
+ * Source becomes a creature "in addition to its other types".
+ * Not needed when retainType is ENCHANTMENT, which sets this true by default.
+ */
+ public BecomesCreatureSourceEffect withKeepCreatureSubtypes(boolean keepCreatureSubtypes) {
+ this.keepCreatureSubtypes = keepCreatureSubtypes;
+ setText();
+ return this;
+ }
+
public BecomesCreatureSourceEffect withDurationRuleAtStart(boolean durationRuleAtStart) {
this.durationRuleAtStart = durationRuleAtStart;
setText();
@@ -205,7 +208,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl {
}
sb.append("{this} becomes a ");
sb.append(token.getDescription());
- if (retainType == CardType.ENCHANTMENT) {
+ if (keepCreatureSubtypes) {
sb.append(" in addition to its other types");
}
if (!duration.toString().isEmpty() && !durationRuleAtStart) {
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtOpponentFaceDownCreaturesAnyTimeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtOpponentFaceDownCreaturesAnyTimeEffect.java
index ebc7eb65b35..e766b3ca395 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtOpponentFaceDownCreaturesAnyTimeEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtOpponentFaceDownCreaturesAnyTimeEffect.java
@@ -14,24 +14,28 @@ import mage.players.Player;
* @author notgreat
*/
public class LookAtOpponentFaceDownCreaturesAnyTimeEffect extends ContinuousEffectImpl {
- private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("face-down creatures you don't control");
- static {
- filter.add(FaceDownPredicate.instance);
- filter.add(TargetController.NOT_YOU.getControllerPredicate());
- }
+ private final FilterCreaturePermanent filter;
public LookAtOpponentFaceDownCreaturesAnyTimeEffect() {
this(Duration.WhileOnBattlefield);
}
public LookAtOpponentFaceDownCreaturesAnyTimeEffect(Duration duration) {
+ this(duration, TargetController.NOT_YOU);
+ }
+
+ public LookAtOpponentFaceDownCreaturesAnyTimeEffect(Duration duration, TargetController targetController) {
super(duration, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
- staticText = (duration.toString().isEmpty() ? "" : duration.toString() + ", ") + "you may look at face-down creatures you don't control any time";
+ staticText = makeText(duration, targetController);
+ filter = new FilterCreaturePermanent();
+ filter.add(FaceDownPredicate.instance);
+ filter.add(targetController.getControllerPredicate());
}
protected LookAtOpponentFaceDownCreaturesAnyTimeEffect(final LookAtOpponentFaceDownCreaturesAnyTimeEffect effect) {
super(effect);
+ this.filter = effect.filter.copy();
}
//Based on LookAtTopCardOfLibraryAnyTimeEffect
@@ -56,4 +60,22 @@ public class LookAtOpponentFaceDownCreaturesAnyTimeEffect extends ContinuousEffe
public LookAtOpponentFaceDownCreaturesAnyTimeEffect copy() {
return new LookAtOpponentFaceDownCreaturesAnyTimeEffect(this);
}
+
+ private static String makeText(Duration duration, TargetController targetController) {
+ StringBuilder sb = new StringBuilder();
+ if (!duration.toString().isEmpty()) {
+ sb.append(duration);
+ sb.append(", ");
+ }
+ sb.append("you may look at face-down creatures ");
+ switch (targetController) {
+ case NOT_YOU:
+ sb.append("you don't control ");
+ break;
+ case OPPONENT:
+ sb.append("your opponents control ");
+ }
+ sb.append("any time");
+ return sb.toString();
+ }
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/LookTargetHandChooseDiscardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/LookTargetHandChooseDiscardEffect.java
index 23e11e36107..e8dc09bd813 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/discard/LookTargetHandChooseDiscardEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/discard/LookTargetHandChooseDiscardEffect.java
@@ -7,6 +7,7 @@ import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
+import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
@@ -21,25 +22,28 @@ public class LookTargetHandChooseDiscardEffect extends OneShotEffect {
private final boolean upTo;
private final DynamicValue numberToDiscard;
+ private final FilterCard filter;
public LookTargetHandChooseDiscardEffect() {
this(false, 1);
}
public LookTargetHandChooseDiscardEffect(boolean upTo, int numberToDiscard) {
- this(upTo, StaticValue.get(numberToDiscard));
+ this(upTo, StaticValue.get(numberToDiscard), numberToDiscard == 1 ? StaticFilters.FILTER_CARD : StaticFilters.FILTER_CARD_CARDS);
}
- public LookTargetHandChooseDiscardEffect(boolean upTo, DynamicValue numberToDiscard) {
+ public LookTargetHandChooseDiscardEffect(boolean upTo, DynamicValue numberToDiscard, FilterCard filter) {
super(Outcome.Discard);
this.upTo = upTo;
this.numberToDiscard = numberToDiscard;
+ this.filter = filter;
}
protected LookTargetHandChooseDiscardEffect(final LookTargetHandChooseDiscardEffect effect) {
super(effect);
this.upTo = effect.upTo;
this.numberToDiscard = effect.numberToDiscard;
+ this.filter = effect.filter;
}
@Override
@@ -56,7 +60,7 @@ public class LookTargetHandChooseDiscardEffect extends OneShotEffect {
}
return true;
}
- TargetCard target = new TargetCardInHand(upTo ? 0 : num, num, num > 1 ? StaticFilters.FILTER_CARD_CARDS : StaticFilters.FILTER_CARD);
+ TargetCard target = new TargetCardInHand(upTo ? 0 : num, num, filter);
if (controller.choose(Outcome.Discard, player.getHand(), target, source, game)) {
player.discard(new CardsImpl(target.getTargets()), false, source, game);
}
diff --git a/Mage/src/main/java/mage/abilities/hint/common/CurrentDungeonHint.java b/Mage/src/main/java/mage/abilities/hint/common/CurrentDungeonHint.java
new file mode 100644
index 00000000000..5ce7d0763de
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/hint/common/CurrentDungeonHint.java
@@ -0,0 +1,43 @@
+package mage.abilities.hint.common;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.common.CitysBlessingCondition;
+import mage.abilities.hint.ConditionHint;
+import mage.abilities.hint.Hint;
+import mage.game.Game;
+import mage.game.command.Dungeon;
+import mage.players.Player;
+
+/**
+ * @author JayDi85
+ */
+public enum CurrentDungeonHint implements Hint {
+
+ instance;
+ private static final ConditionHint hint = new ConditionHint(CitysBlessingCondition.instance, "You have city's blessing");
+
+ @Override
+ public String getText(Game game, Ability ability) {
+ Player player = game.getPlayer(ability.getControllerId());
+ if (player == null) {
+ return "";
+ }
+
+ Dungeon dungeon = game.getPlayerDungeon(ability.getControllerId());
+ if (dungeon == null) {
+ return "Current dungeon: not yet entered";
+ }
+
+ String dungeonInfo = "Current dungeon: " + dungeon.getLogName();
+ if (dungeon.getCurrentRoom() != null) {
+ dungeonInfo += ", room: " + dungeon.getCurrentRoom().getName();
+ }
+
+ return dungeonInfo;
+ }
+
+ @Override
+ public Hint copy() {
+ return instance;
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/keyword/DevourAbility.java b/Mage/src/main/java/mage/abilities/keyword/DevourAbility.java
index a3b42f8807a..7f6648bc98b 100644
--- a/Mage/src/main/java/mage/abilities/keyword/DevourAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/DevourAbility.java
@@ -1,11 +1,10 @@
-
package mage.abilities.keyword;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DevourEffect;
import mage.constants.Zone;
+import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
-import mage.filter.common.FilterControlledPermanent;
/**
* 502.82. Devour
@@ -45,12 +44,12 @@ import mage.filter.common.FilterControlledPermanent;
*/
public class DevourAbility extends SimpleStaticAbility {
- private static final FilterControlledPermanent filterCreature = new FilterControlledCreaturePermanent("creature");
+ private static final FilterPermanent filterCreature = new FilterControlledCreaturePermanent("creature");
// Integer.MAX_VALUE is a special value
// for "devour X, where X is the number of devored permanents"
// see DevourEffect for the full details.
- public static DevourAbility DevourX() {
+ public static DevourAbility devourX() {
return new DevourAbility(Integer.MAX_VALUE);
}
@@ -58,7 +57,7 @@ public class DevourAbility extends SimpleStaticAbility {
this(devourFactor, filterCreature);
}
- public DevourAbility(int devourFactor, FilterControlledPermanent filterDevoured) {
+ public DevourAbility(int devourFactor, FilterPermanent filterDevoured) {
super(Zone.ALL, new DevourEffect(devourFactor, filterDevoured));
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/ImpendingAbility.java b/Mage/src/main/java/mage/abilities/keyword/ImpendingAbility.java
index a6594965d07..4d02211948b 100644
--- a/Mage/src/main/java/mage/abilities/keyword/ImpendingAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/ImpendingAbility.java
@@ -1,12 +1,33 @@
package mage.abilities.keyword;
import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.AlternativeSourceCostsImpl;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.AddContinuousEffectToGame;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
+import mage.constants.*;
+import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.permanent.Permanent;
import mage.util.CardUtil;
+import java.util.stream.Collectors;
+
/**
- * TODO: Implement this
+ * "Impending N–[cost]" is a keyword that represents multiple abilities.
+ * The official rules are as follows:
+ * (a) You may choose to pay [cost] rather than pay this spell's mana cost.
+ * (b) If you chose to pay this spell's impending cost, it enters the battlefield with N time counters on it.
+ * (c) As long as this permanent has a time counter on it, if it was cast for its impending cost, it's not a creature.
+ * (d) At the beginning of your end step, if this permanent was cast for its impending cost, remove a time counter from it. Then if it has no time counters on it, it loses impending.
*
* @author TheElk801
*/
@@ -16,14 +37,24 @@ public class ImpendingAbility extends AlternativeSourceCostsImpl {
private static final String IMPENDING_REMINDER = "If you cast this spell for its impending cost, " +
"it enters with %s time counters and isn't a creature until the last is removed. " +
"At the beginning of your end step, remove a time counter from it.";
+ private static final Condition counterCondition = new SourceHasCounterCondition(CounterType.TIME, 0, 0);
- public ImpendingAbility(String manaString) {
- this(manaString, 4);
- }
-
- public ImpendingAbility(String manaString, int amount) {
- super(IMPENDING_KEYWORD + ' ' + amount, String.format(IMPENDING_REMINDER, CardUtil.numberToText(amount)), manaString);
+ public ImpendingAbility(int amount, String manaString) {
+ super(IMPENDING_KEYWORD + ' ' + amount, String.format(IMPENDING_REMINDER, CardUtil.numberToText(amount)), new ManaCostsImpl<>(manaString), IMPENDING_KEYWORD);
this.setRuleAtTheTop(true);
+ this.addSubAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(
+ new AddCountersSourceEffect(CounterType.TIME.createInstance(amount)), ImpendingCondition.instance, ""
+ ), "").setRuleVisible(false));
+ this.addSubAbility(new SimpleStaticAbility(new ImpendingAbilityTypeEffect()).setRuleVisible(false));
+ Ability ability = new BeginningOfEndStepTriggeredAbility(
+ new RemoveCounterSourceEffect(CounterType.TIME.createInstance()),
+ TargetController.YOU, ImpendingCondition.instance, false
+ );
+ ability.addEffect(new ConditionalOneShotEffect(
+ new AddContinuousEffectToGame(new ImpendingAbilityRemoveEffect()),
+ counterCondition, "Then if it has no time counters on it, it loses impending"
+ ));
+ this.addSubAbility(ability.setRuleVisible(false));
}
private ImpendingAbility(final ImpendingAbility ability) {
@@ -35,12 +66,81 @@ public class ImpendingAbility extends AlternativeSourceCostsImpl {
return new ImpendingAbility(this);
}
- @Override
- public boolean isAvailable(Ability source, Game game) {
- return true;
- }
-
public static String getActivationKey() {
return getActivationKey(IMPENDING_KEYWORD);
}
}
+
+enum ImpendingCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return CardUtil.checkSourceCostsTagExists(game, source, ImpendingAbility.getActivationKey());
+ }
+}
+
+class ImpendingAbilityTypeEffect extends ContinuousEffectImpl {
+
+ ImpendingAbilityTypeEffect() {
+ super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
+ staticText = "As long as this permanent has a time counter on it, if it was cast for its impending cost, it's not a creature.";
+ }
+
+ private ImpendingAbilityTypeEffect(final ImpendingAbilityTypeEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ImpendingAbilityTypeEffect copy() {
+ return new ImpendingAbilityTypeEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (!ImpendingCondition.instance.apply(game, source)) {
+ return false;
+ }
+ Permanent permanent = source.getSourcePermanentIfItStillExists(game);
+ if (permanent.getCounters(game).getCount(CounterType.TIME) < 1) {
+ return false;
+ }
+ permanent.removeCardType(game, CardType.CREATURE);
+ permanent.removeAllCreatureTypes(game);
+ return true;
+ }
+}
+
+class ImpendingAbilityRemoveEffect extends ContinuousEffectImpl {
+
+ ImpendingAbilityRemoveEffect() {
+ super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.LoseAbility);
+ }
+
+ private ImpendingAbilityRemoveEffect(final ImpendingAbilityRemoveEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ImpendingAbilityRemoveEffect copy() {
+ return new ImpendingAbilityRemoveEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = source.getSourcePermanentIfItStillExists(game);
+ if (permanent == null) {
+ discard();
+ return false;
+ }
+ permanent.removeAbilities(
+ permanent
+ .getAbilities(game)
+ .stream()
+ .filter(ImpendingAbility.class::isInstance)
+ .collect(Collectors.toList()),
+ source.getSourceId(), game
+ );
+ return true;
+ }
+}
diff --git a/Mage/src/main/java/mage/constants/MageObjectType.java b/Mage/src/main/java/mage/constants/MageObjectType.java
index f0ff79b9671..b870492232b 100644
--- a/Mage/src/main/java/mage/constants/MageObjectType.java
+++ b/Mage/src/main/java/mage/constants/MageObjectType.java
@@ -43,7 +43,8 @@ package mage.constants;
* @author LevelX2
*/
public enum MageObjectType {
- ABILITY_STACK("Ability on the Stack", false, false, false),
+ ABILITY_STACK_FROM_CARD("Ability on the Stack", false, false, false),
+ ABILITY_STACK_FROM_TOKEN("Ability on the Stack", false, false, true),
CARD("Card", false, true, false),
COPY_CARD("Copy of a Card", false, true, false),
TOKEN("Token", true, true, true),
diff --git a/Mage/src/main/java/mage/designations/Initiative.java b/Mage/src/main/java/mage/designations/Initiative.java
index da72667065a..244ac075bfe 100644
--- a/Mage/src/main/java/mage/designations/Initiative.java
+++ b/Mage/src/main/java/mage/designations/Initiative.java
@@ -3,6 +3,7 @@ package mage.designations;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
+import mage.abilities.hint.common.CurrentDungeonHint;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Controllable;
@@ -113,6 +114,7 @@ class InitiativeVentureTriggeredAbility extends TriggeredAbilityImpl {
InitiativeVentureTriggeredAbility() {
super(Zone.ALL, new InitiativeUndercityEffect());
+ addHint(CurrentDungeonHint.instance);
}
private InitiativeVentureTriggeredAbility(final InitiativeVentureTriggeredAbility ability) {
diff --git a/Mage/src/main/java/mage/filter/FilterCard.java b/Mage/src/main/java/mage/filter/FilterCard.java
index c4d2f98183c..ccdb72f6e52 100644
--- a/Mage/src/main/java/mage/filter/FilterCard.java
+++ b/Mage/src/main/java/mage/filter/FilterCard.java
@@ -73,7 +73,9 @@ public class FilterCard extends FilterObject {
throw new UnsupportedOperationException("You may not modify a locked filter");
}
+ // verify check
checkPredicateIsSuitableForCardFilter(predicate);
+ Predicates.makeSurePredicateCompatibleWithFilter(predicate, Card.class);
extraPredicates.add(predicate);
}
diff --git a/Mage/src/main/java/mage/filter/FilterPermanent.java b/Mage/src/main/java/mage/filter/FilterPermanent.java
index 0177accc9f8..9eaee653392 100644
--- a/Mage/src/main/java/mage/filter/FilterPermanent.java
+++ b/Mage/src/main/java/mage/filter/FilterPermanent.java
@@ -5,6 +5,7 @@ import mage.constants.SubType;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.Predicate;
+import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -12,7 +13,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
-import java.util.stream.Collectors;
/**
* @author North
@@ -64,6 +64,10 @@ public class FilterPermanent extends FilterObject implements FilterIn
if (isLockedFilter()) {
throw new UnsupportedOperationException("You may not modify a locked filter");
}
+
+ // verify check
+ Predicates.makeSurePredicateCompatibleWithFilter(predicate, Permanent.class);
+
extraPredicates.add(predicate);
}
diff --git a/Mage/src/main/java/mage/filter/FilterPlayer.java b/Mage/src/main/java/mage/filter/FilterPlayer.java
index 0fa56b3a2a7..766cba8253b 100644
--- a/Mage/src/main/java/mage/filter/FilterPlayer.java
+++ b/Mage/src/main/java/mage/filter/FilterPlayer.java
@@ -4,6 +4,7 @@ import mage.abilities.Ability;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.Predicate;
+import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.players.Player;
@@ -36,6 +37,10 @@ public class FilterPlayer extends FilterImpl {
if (isLockedFilter()) {
throw new UnsupportedOperationException("You may not modify a locked filter");
}
+
+ // verify check
+ Predicates.makeSurePredicateCompatibleWithFilter(predicate, Player.class);
+
extraPredicates.add(predicate);
return this;
}
diff --git a/Mage/src/main/java/mage/filter/FilterStackObject.java b/Mage/src/main/java/mage/filter/FilterStackObject.java
index bfdd56d54fd..aa3b506c1ae 100644
--- a/Mage/src/main/java/mage/filter/FilterStackObject.java
+++ b/Mage/src/main/java/mage/filter/FilterStackObject.java
@@ -1,10 +1,13 @@
package mage.filter;
import mage.abilities.Ability;
+import mage.cards.Card;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.Predicate;
+import mage.filter.predicate.Predicates;
import mage.game.Game;
+import mage.game.stack.Spell;
import mage.game.stack.StackObject;
import java.util.ArrayList;
@@ -43,6 +46,11 @@ public class FilterStackObject extends FilterObject {
if (isLockedFilter()) {
throw new UnsupportedOperationException("You may not modify a locked filter");
}
+
+ // verify check
+ // Spell implements Card interface, so it can use some default predicates like owner
+ Predicates.makeSurePredicateCompatibleWithFilter(predicate, StackObject.class, Spell.class, Card.class);
+
extraPredicates.add(predicate);
}
diff --git a/Mage/src/main/java/mage/filter/predicate/Predicate.java b/Mage/src/main/java/mage/filter/predicate/Predicate.java
index e4e64de3963..6b7b5382f31 100644
--- a/Mage/src/main/java/mage/filter/predicate/Predicate.java
+++ b/Mage/src/main/java/mage/filter/predicate/Predicate.java
@@ -1,4 +1,3 @@
-
package mage.filter.predicate;
import java.io.Serializable;
diff --git a/Mage/src/main/java/mage/filter/predicate/Predicates.java b/Mage/src/main/java/mage/filter/predicate/Predicates.java
index 0f2a0c9cbbd..bf3213c8290 100644
--- a/Mage/src/main/java/mage/filter/predicate/Predicates.java
+++ b/Mage/src/main/java/mage/filter/predicate/Predicates.java
@@ -2,6 +2,8 @@ package mage.filter.predicate;
import mage.game.Game;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -11,7 +13,7 @@ import java.util.List;
*
* All methods returns serializable predicates as long as they're given serializable parameters.
*
- * @author North
+ * @author North, JayDi85
*/
public final class Predicates {
@@ -246,4 +248,48 @@ public final class Predicates {
extraPredicates.forEach(p -> collectAllComponents(p, res));
}
}
+
+ /**
+ * Verify check: try to find filters usage
+ * Example use case: Player predicate was used for Permanent filter
+ * Example error: java.lang.ClassCastException: mage.game.permanent.PermanentToken cannot be cast to mage.players.Player
+ */
+ public static void makeSurePredicateCompatibleWithFilter(Predicate predicate, Class... compatibleClasses) {
+ List list = new ArrayList<>();
+ Predicates.collectAllComponents(predicate, list);
+ list.forEach(p -> {
+ Class predicateGenericParamClass = findGenericParam(predicate);
+ if (predicateGenericParamClass == null) {
+ throw new IllegalArgumentException("Somthing wrong. Can't find predicate's generic param for " + predicate.getClass());
+ }
+ if (Arrays.stream(compatibleClasses).anyMatch(f -> predicateGenericParamClass.isAssignableFrom(f))) {
+ // predicate is fine
+ } else {
+ // How-to fix: use correct predicates (same type, e.g. getControllerPredicate() instead getPlayerPredicate())
+ throw new IllegalArgumentException(String.format(
+ "Wrong code usage: predicate [%s] with generic param [%s] can't be added to filter, allow only %s",
+ predicate.getClass(),
+ predicateGenericParamClass,
+ Arrays.toString(compatibleClasses)
+ ));
+ }
+ });
+ }
+
+ private static Class findGenericParam(Predicate predicate) {
+ Type[] interfaces = predicate.getClass().getGenericInterfaces();
+ for (Type type : interfaces) {
+ if (type instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) type;
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ if (actualTypeArguments.length > 0) {
+ Type actualType = actualTypeArguments[0];
+ if (actualType instanceof Class) {
+ return (Class) actualType;
+ }
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/Mage/src/main/java/mage/game/FakeGame.java b/Mage/src/main/java/mage/game/FakeGame.java
new file mode 100644
index 00000000000..7bee3465e6a
--- /dev/null
+++ b/Mage/src/main/java/mage/game/FakeGame.java
@@ -0,0 +1,63 @@
+package mage.game;
+
+import mage.constants.MultiplayerAttackOption;
+import mage.constants.RangeOfInfluence;
+import mage.game.match.MatchType;
+import mage.game.mulligan.MulliganType;
+
+/**
+ * Fake game for tests and data check, do nothing.
+ *
+ * @author JayDi85
+ */
+public class FakeGame extends GameImpl {
+
+ private int numPlayers;
+
+ public FakeGame() {
+ super(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 20, 7);
+ }
+
+ public FakeGame(final FakeGame game) {
+ super(game);
+ this.numPlayers = game.numPlayers;
+ }
+
+ @Override
+ public MatchType getGameType() {
+ return new FakeGameType();
+ }
+
+ @Override
+ public int getNumPlayers() {
+ return numPlayers;
+ }
+
+ @Override
+ public FakeGame copy() {
+ return new FakeGame(this);
+ }
+
+}
+
+class FakeGameType extends MatchType {
+
+ public FakeGameType() {
+ this.name = "Test Game Type";
+ this.maxPlayers = 10;
+ this.minPlayers = 3;
+ this.numTeams = 0;
+ this.useAttackOption = true;
+ this.useRange = true;
+ this.sideboardingAllowed = true;
+ }
+
+ protected FakeGameType(final FakeGameType matchType) {
+ super(matchType);
+ }
+
+ @Override
+ public FakeGameType copy() {
+ return new FakeGameType(this);
+ }
+}
\ No newline at end of file
diff --git a/Mage/src/main/java/mage/game/FakeMatch.java b/Mage/src/main/java/mage/game/FakeMatch.java
new file mode 100644
index 00000000000..44cb401b961
--- /dev/null
+++ b/Mage/src/main/java/mage/game/FakeMatch.java
@@ -0,0 +1,21 @@
+package mage.game;
+
+import mage.game.match.MatchImpl;
+import mage.game.match.MatchOptions;
+
+/**
+ * Fake match for tests and data check, do nothing.
+ *
+ * @author JayDi85
+ */
+public class FakeMatch extends MatchImpl {
+
+ public FakeMatch() {
+ super(new MatchOptions("fake match", "fake game type", true, 2));
+ }
+
+ @Override
+ public void startGame() throws GameException {
+ throw new IllegalStateException("Can't start fake match");
+ }
+}
diff --git a/Mage/src/main/java/mage/game/Game.java b/Mage/src/main/java/mage/game/Game.java
index 5e5f5b58ca5..c6d8c2b0aa0 100644
--- a/Mage/src/main/java/mage/game/Game.java
+++ b/Mage/src/main/java/mage/game/Game.java
@@ -88,7 +88,7 @@ public interface Game extends MageItem, Serializable, Copyable {
Dungeon getDungeon(UUID objectId);
- Dungeon getPlayerDungeon(UUID objectId);
+ Dungeon getPlayerDungeon(UUID playerId);
UUID getControllerId(UUID objectId);
@@ -456,7 +456,12 @@ public interface Game extends MageItem, Serializable, Copyable {
Dungeon addDungeon(Dungeon dungeon, UUID playerId);
- void ventureIntoDungeon(UUID playerId, boolean undercity);
+ /**
+ * Enter to dungeon or go to next room
+ *
+ * @param isEnterToUndercity - enter to Undercity instead choose a new dungeon
+ */
+ void ventureIntoDungeon(UUID playerId, boolean isEnterToUndercity);
void temptWithTheRing(UUID playerId);
diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java
index ba5d909dcf1..8c122146d71 100644
--- a/Mage/src/main/java/mage/game/GameImpl.java
+++ b/Mage/src/main/java/mage/game/GameImpl.java
@@ -560,14 +560,14 @@ public abstract class GameImpl implements Game {
}
@Override
- public void ventureIntoDungeon(UUID playerId, boolean undercity) {
+ public void ventureIntoDungeon(UUID playerId, boolean isEnterToUndercity) {
if (playerId == null) {
return;
}
if (replaceEvent(GameEvent.getEvent(GameEvent.EventType.VENTURE, playerId, null, playerId))) {
return;
}
- this.getOrCreateDungeon(playerId, undercity).moveToNextRoom(playerId, this);
+ this.getOrCreateDungeon(playerId, isEnterToUndercity).moveToNextRoom(playerId, this);
fireEvent(GameEvent.getEvent(GameEvent.EventType.VENTURED, playerId, null, playerId));
}
@@ -584,6 +584,9 @@ public abstract class GameImpl implements Game {
return emblem;
}
TheRingEmblem newEmblem = new TheRingEmblem(playerId);
+
+ // TODO: add image info
+
state.addCommandObject(newEmblem);
return newEmblem;
}
@@ -1971,7 +1974,9 @@ public abstract class GameImpl implements Game {
ability.setSourceId(newEmblem.getId());
}
- state.addCommandObject(newEmblem); // TODO: generate image for emblem here?
+ // image info setup in setSourceObject
+
+ state.addCommandObject(newEmblem);
}
/**
@@ -1999,6 +2004,9 @@ public abstract class GameImpl implements Game {
for (Ability ability : newPlane.getAbilities()) {
ability.setSourceId(newPlane.getId());
}
+
+ // image info setup in setSourceObject
+
state.addCommandObject(newPlane);
informPlayers("You have planeswalked to " + newPlane.getLogName());
@@ -2020,6 +2028,7 @@ public abstract class GameImpl implements Game {
@Override
public Dungeon addDungeon(Dungeon dungeon, UUID playerId) {
dungeon.setControllerId(playerId);
+ dungeon.setSourceObject();
state.addCommandObject(dungeon);
return dungeon;
}
diff --git a/Mage/src/main/java/mage/game/command/Dungeon.java b/Mage/src/main/java/mage/game/command/Dungeon.java
index a5f28744cfb..71efbbb617e 100644
--- a/Mage/src/main/java/mage/game/command/Dungeon.java
+++ b/Mage/src/main/java/mage/game/command/Dungeon.java
@@ -13,6 +13,8 @@ import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.hint.HintUtils;
import mage.cards.FrameStyle;
+import mage.cards.repository.TokenInfo;
+import mage.cards.repository.TokenRepository;
import mage.choices.Choice;
import mage.choices.ChoiceHintType;
import mage.choices.ChoiceImpl;
@@ -87,6 +89,11 @@ public class Dungeon extends CommandObjectImpl {
}
public void moveToNextRoom(UUID playerId, Game game) {
+ Dungeon dungeon = game.getPlayerDungeon(playerId);
+ if (dungeon == null) {
+ return;
+ }
+
if (currentRoom == null) {
currentRoom = dungeonRooms.get(0);
} else {
@@ -94,7 +101,7 @@ public class Dungeon extends CommandObjectImpl {
}
Player player = game.getPlayer(getControllerId());
if (player != null) {
- game.informPlayers(player.getLogName() + " has entered " + currentRoom.getName());
+ game.informPlayers(player.getLogName() + " has entered " + currentRoom.getName() + " (dungeon: " + dungeon.getLogName() + ")");
}
game.fireEvent(GameEvent.getEvent(
GameEvent.EventType.ROOM_ENTERED, currentRoom.getId(), null, playerId
@@ -139,14 +146,14 @@ public class Dungeon extends CommandObjectImpl {
choice.setChoices(dungeonNames);
player.choose(Outcome.Neutral, choice, game);
if (choice.getChoice() != null) {
- return createDungeon(choice.getChoice());
+ return createDungeon(choice.getChoice(), true);
} else {
// on disconnect
- return createDungeon("Tomb of Annihilation");
+ return createDungeon("Tomb of Annihilation", true);
}
}
- public static Dungeon createDungeon(String name) {
+ public static Dungeon createDungeon(String name, boolean isNameMustExists) {
switch (name) {
case "Tomb of Annihilation":
return new TombOfAnnihilationDungeon();
@@ -155,7 +162,26 @@ public class Dungeon extends CommandObjectImpl {
case "Dungeon of the Mad Mage":
return new DungeonOfTheMadMageDungeon();
default:
- throw new UnsupportedOperationException("A dungeon should have been chosen");
+ if (isNameMustExists) {
+ throw new UnsupportedOperationException("A dungeon should have been chosen");
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public void setSourceObject() {
+ // choose set code due source
+ TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForClass(this.getClass().getName(), null);
+ if (foundInfo != null) {
+ this.setExpansionSetCode(foundInfo.getSetCode());
+ this.setUsesVariousArt(false);
+ this.setCardNumber("");
+ this.setImageFileName(""); // use default
+ this.setImageNumber(foundInfo.getImageNumber());
+ } else {
+ // how-to fix: add dungeon to the tokens-database
+ throw new IllegalArgumentException("Wrong code usage: can't find token info for the dungeon: " + this.getClass().getName());
}
}
diff --git a/Mage/src/main/java/mage/game/command/DungeonRoom.java b/Mage/src/main/java/mage/game/command/DungeonRoom.java
index ba2174a7ecc..121264cef47 100644
--- a/Mage/src/main/java/mage/game/command/DungeonRoom.java
+++ b/Mage/src/main/java/mage/game/command/DungeonRoom.java
@@ -77,6 +77,11 @@ public class DungeonRoom {
}
public DungeonRoom chooseNextRoom(UUID playerId, Game game) {
+ Dungeon dungeon = game.getPlayerDungeon(playerId);
+ if (dungeon == null) {
+ return null;
+ }
+
switch (nextRooms.size()) {
case 0:
return null;
@@ -90,8 +95,8 @@ public class DungeonRoom {
return null;
}
return player.chooseUse(
- Outcome.Neutral, "Choose which room to go to",
- null, room1.name, room2.name, null, game
+ Outcome.Neutral, "Choose which room to go to in",
+ "dungeon: " + dungeon.getLogName(), room1.name, room2.name, null, game
) ? room1 : room2;
default:
throw new UnsupportedOperationException("there shouldn't be more than two rooms to go to");
diff --git a/Mage/src/main/java/mage/target/TargetSpell.java b/Mage/src/main/java/mage/target/TargetSpell.java
index 439df15989a..4ded8d97a8d 100644
--- a/Mage/src/main/java/mage/target/TargetSpell.java
+++ b/Mage/src/main/java/mage/target/TargetSpell.java
@@ -1,4 +1,3 @@
-
package mage.target;
import mage.abilities.Ability;
@@ -110,7 +109,7 @@ public class TargetSpell extends TargetObject {
private boolean canBeChosen(StackObject stackObject, UUID sourceControllerId, Ability source, Game game) {
return stackObject instanceof Spell
&& game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
- && filter.match(stackObject, sourceControllerId, source, game);
+ && canTarget(sourceControllerId, stackObject.getId(), source, game);
}
@Override
diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt
index 55ca242188c..a763fb8efbb 100644
--- a/Utils/mtg-cards-data.txt
+++ b/Utils/mtg-cards-data.txt
@@ -53982,6 +53982,7 @@ Forceful Cultivator|Alchemy: Kamigawa|29|M|{2}{G}{G}|Creature - Snake Shaman|2|3
Imperial Blademaster|Alchemy: Kamigawa|30|R|{1}{R}{W}|Creature - Human Samurai|2|3|Double strike$Whenever a Samurai or Warrior you control attacks alone, draft a card from Imperial Blademaster's spellbook.|
Acrobatic Cheerleader|Duskmourn: House of Horror|1|C|{1}{W}|Creature - Human Survivor|2|2|Survival -- At the beginning of your second main phase, if Acrobatic Cheerleader is tapped, put a flying counter on it. This ability triggers only once.|
Cult Healer|Duskmourn: House of Horror|2|C|{2}{W}|Creature - Human Doctor|3|3|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, Cult Healer gains lifelink until end of turn.|
+Dazzling Theater // Prop Room|Duskmourn: House of Horror|3|R|{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.)$Creature spells you cast have convoke.$Prop Room${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.)$Untap each creature you control during each other player's untap step.|
Dollmaker's Shop // Porcelain Gallery|Duskmourn: House of Horror|4|M|{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.)$Whenever one or more non-Toy creatures you control attack a player, create a 1/1 white Toy artifact creature token.$Porcelain Gallery${4}{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.)$Creatures you control have base power and toughness each equal to the number of creatures you control.|
Emerge from the Cocoon|Duskmourn: House of Horror|5|C|{4}{W}|Sorcery|||Return target creature card from your graveyard to the battlefield. You gain 3 life.|
Enduring Innocence|Duskmourn: House of Horror|6|R|{1}{W}{W}|Enchantment Creature - Sheep Glimmer|2|1|Lifelink$Whenever one or more other creatures you control with power 2 or less enter, draw a card. This ability triggers only once each turn.$When Enduring Innocence dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment.|
@@ -54003,8 +54004,10 @@ Optimistic Scavenger|Duskmourn: House of Horror|21|U|{W}|Creature - Human Scout|
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.|
Patched Plaything|Duskmourn: House of Horror|24|U|{2}{W}|Artifact Creature - Toy|4|3|Double strike$Patched Plaything enters with two -1/-1 counters on it if you cast it from your hand.|
+Possessed Goat|Duskmourn: House of Horror|25|C|{W}|Creature - Goat|1|1|{3}, Discard a card: Put three +1/+1 counters on Possessed Goat and it becomes a black Demon in addition to its other colors and types. Activate only once.|
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.|
+Seized from Slumber|Duskmourn: House of Horror|28|C|{4}{W}|Instant|||This spell costs {3} less to cast if it targets a tapped creature.$Destroy target creature.|
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}|
@@ -54025,6 +54028,7 @@ Clammy Prowler|Duskmourn: House of Horror|45|C|{3}{U}|Enchantment Creature - Hor
Creeping Peeper|Duskmourn: House of Horror|46|C|{1}{U}|Creature - Eye|2|1|{T}: Add {U}. Spend this mana only to cast an enchantment spell, unlock a door, or turn a permanent face up.|
Cursed Windbreaker|Duskmourn: House of Horror|47|U|{2}{U}|Artifact - Equipment|||When Cursed Windbreaker enters, manifest dread, then attach Cursed Windbreaker to that creature.$Equipped creature has flying.$Equip {3}|
Daggermaw Megalodon|Duskmourn: House of Horror|48|C|{4}{U}{U}|Creature - Shark|5|7|Vigilance$Islandcycling {2}|
+Don't Make a Sound|Duskmourn: House of Horror|49|C|{1}{U}|Instant|||Counter target spell unless its controller pays {2}. If they do, surveil 2.|
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.|
@@ -54037,8 +54041,10 @@ Fear of Isolation|Duskmourn: House of Horror|58|U|{1}{U}|Enchantment Creature -
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.|
+Glimmerburst|Duskmourn: House of Horror|62|C|{3}{U}|Instant|||Draw two cards. Create a 1/1 white Glimmer enchantment creature token.|
Leyline of Transformation|Duskmourn: House of Horror|63|R|{2}{U}{U}|Enchantment|||If 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.|
+Meat Locker // Drowned Diner|Duskmourn: House of Horror|65|C|{2}{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.)$When you unlock this door, tap up to one target creature and put two stun counters on it.$Drowned Diner${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.)$When you unlock this door, draw three cards, then discard a card.|
The Mindskinner|Duskmourn: House of Horror|66|R|{U}{U}{U}|Legendary Enchantment Creature - Nightmare|10|1|The Mindskinner can't be blocked.$If a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards.|
Mirror Room // Fractured Realm|Duskmourn: House of Horror|67|M|{2}{U}|Enchantment - Room|||(You may cast 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 token that's a copy of target creature you control, except it's a Reflection in addition to its other creature types.$Fractured Realm${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.)$If a triggered ability of a permanent you control triggers, that ability triggers an additional time.|
Overlord of the Floodpits|Duskmourn: House of Horror|68|M|{3}{U}{U}|Enchantment Creature - Avatar Horror|5|3|Impending 4--{1}{U}{U}$Flying$Whenever Overlord of the Floodpits enters or attacks, draw two cards, then discard a card.|
@@ -54052,6 +54058,7 @@ The Tale of Tamiyo|Duskmourn: House of Horror|75|R|{2}{U}|Legendary Enchantment
Tunnel Surveyor|Duskmourn: House of Horror|76|C|{2}{U}|Creature - Human Detective|2|2|When 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.|
+Underwater Tunnel // Slimy Aquarium|Duskmourn: House of Horror|79|C|{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.)$When you unlock this door, surveil 2.$Slimy Aquarium${3}{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.)$When you unlock this door, manifest dread, then put a +1/+1 counter on that creature.|
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.|
@@ -54060,11 +54067,12 @@ Balemurk Leech|Duskmourn: House of Horror|84|C|{1}{B}|Creature - Leech|2|2|Eerie
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.|
+Cracked Skull|Duskmourn: House of Horror|88|C|{2}{B}|Enchantment - Aura|||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.|
+Derelict Attic // Widow's Walk|Duskmourn: House of Horror|93|C|{2}{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, you draw two cards and you lose 2 life.$Widow's Walk${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 a creature you control attacks alone, it gets +1/+0 and gains deathtouch until end of turn.|
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.|
Fanatic of the Harrowing|Duskmourn: House of Horror|96|C|{3}{B}|Creature - Human Cleric|2|2|When Fanatic of the Harrowing enters, each player discards a card. If you discarded a card this way, draw a card.|
@@ -54097,7 +54105,8 @@ Vile Mutilator|Duskmourn: House of Horror|122|U|{5}{B}{B}|Creature - Demon|6|5|A
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.|
+Betrayer's Bargain|Duskmourn: House of Horror|126|U|{1}{R}|Instant|||As an additional cost to cast this spell, sacrifice a creature or enchantment or pay {2}.$Betrayer's Bargain deals 5 damage to target creature. If that creature would die this turn, exile it instead.|
+Boilerbilges Ripper|Duskmourn: House of Horror|127|C|{4}{R}|Creature - Human Assassin|4|4|When Boilerbilges Ripper enters, you may sacrifice another creature or enchantment. When you do, Boilerbilges Ripper deals 2 damage to any target.|
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.|
Clockwork Percussionist|Duskmourn: House of Horror|130|C|{R}|Artifact Creature - Monkey Toy|1|1|Haste$When Clockwork Percussionist dies, exile the top card of your library. You may play it until the end of your next turn.|
@@ -54128,6 +54137,7 @@ Ripchain Razorkin|Duskmourn: House of Horror|154|C|{3}{R}|Creature - Human Berse
The Rollercrusher Ride|Duskmourn: House of Horror|155|M|{X}{2}{R}|Legendary Enchantment|||Delirium -- If a source you control would deal noncombat damage to a permanent or player while there are four or more card types among cards in your graveyard, it deals double that damage instead.$When The Rollercrusher Ride enters, it deals X damage to each of up to X target creatures.|
Scorching Dragonfire|Duskmourn: House of Horror|156|C|{1}{R}|Instant|||Scorching Dragonfire deals 3 damage to target creature or planeswalker. If that creature or planeswalker would die this turn, exile it instead.|
Screaming Nemesis|Duskmourn: House of Horror|157|M|{2}{R}|Creature - Spirit|3|3|Haste$Whenever 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.|
+Ticket Booth // Tunnel of Hate|Duskmourn: House of Horror|158|C|{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, manifest dread.$Tunnel of Hate${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.)$Whenever you attack, target attacking creature gains double strike until end of 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.|
@@ -54156,10 +54166,11 @@ Hedge Shredder|Duskmourn: House of Horror|183|R|{2}{G}{G}|Artifact - Vehicle|5|5
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.|
+Monstrous Emergence|Duskmourn: House of Horror|191|C|{1}{G}|Sorcery|||As an additional cost to cast this spell, choose a creature you control or reveal a creature card from your hand.$Monstrous Emergence deals damage equal to the power of the creature you chose or the card you revealed to target creature.|
Omnivorous Flytrap|Duskmourn: House of Horror|192|R|{2}{G}|Creature - Plant|2|4|Delirium -- Whenever 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.|
@@ -54173,7 +54184,7 @@ Twitching Doll|Duskmourn: House of Horror|201|R|{1}{G}|Artifact Creature - Spide
Tyvar, the Pummeler|Duskmourn: House of Horror|202|M|{1}{G}{G}|Legendary Creature - Elf Warrior|3|3|Tap another untapped creature you control: Tyvar, 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.|
+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 lands 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.|
@@ -54189,18 +54200,21 @@ Inquisitive Glimmer|Duskmourn: House of Horror|217|U|{W}{U}|Enchantment Creature
Intruding Soulrager|Duskmourn: House of Horror|218|U|{U}{R}|Creature - Spirit|2|2|Vigilance${T}, Sacrifice a Room: Intruding Soulrager deals 2 damage to each opponent. Draw a card.|
The Jolly Balloon Man|Duskmourn: House of Horror|219|R|{1}{R}{W}|Legendary Creature - Human Clown|1|4|Haste${1}, {T}: Create a token that's a copy of another target creature you control, except it's a 1/1 red Balloon creature in addition to its other colors and types and it has flying and haste. Sacrifice it at the beginning of the next end step. Activate only as a sorcery.|
Kaito, Bane of Nightmares|Duskmourn: House of Horror|220|M|{2}{U}{B}|Legendary Planeswalker - Kaito|4|Ninjutsu {1}{U}{B}$During your turn, as long as Kaito has one or more loyalty counters on him, he's a 3/4 Ninja creature and has hexproof.$+1: You get an emblem with "Ninjas you control get +1/+1."$0: Surveil 2. Then draw a card for each opponent who lost life this turn.$-2: Tap target creature. Put two stun counters on it.|
+Marina Vendrell|Duskmourn: House of Horror|221|R|{W}{U}{B}{R}{G}|Legendary Creature - Human Warlock|3|5|When Marina Vendrell enters, reveal the top seven cards of your library. Put all enchantment cards from among them into your hand and the rest on the bottom of your library in a random order.${T}: Lock or unlock a door of target Room you control. Activate only as a sorcery.|
Midnight Mayhem|Duskmourn: House of Horror|222|U|{2}{R}{W}|Sorcery|||Create three 1/1 red Gremlin creature tokens. Gremlins you control gain menace, lifelink, and haste until end of turn.|
Nashi, Searcher in the Dark|Duskmourn: House of Horror|223|R|{U}{B}|Legendary Creature - Rat Ninja Wizard|2|2|Menace$Whenever Nashi, Searcher in the Dark deals combat damage to a player, you mill that many cards. You may put any number of legendary and/or enchantment cards from among them into your hand. If you put no cards into your hand this way, put a +1/+1 counter on Nashi.|
Niko, Light of Hope|Duskmourn: House of Horror|224|M|{2}{W}{U}|Legendary Creature - Human Wizard|3|4|When Niko, Light of Hope enters, create two Shard tokens.${2}, {T}: Exile target nonlegendary creature you control. Shards you control become copies of it until the beginning of the next end step. Return it to the battlefield under its owner's control at the beginning of the next end step.|
Oblivious Bookworm|Duskmourn: House of Horror|225|U|{G}{U}|Creature - Human Wizard|2|3|At the beginning of your end step, you may draw a card. If you do, discard a card unless a permanent entered the battlefield face down under your control this turn or you turned a permanent face up this turn.|
Peer Past the Veil|Duskmourn: House of Horror|226|R|{2}{R}{G}|Instant|||Discard your hand. Then draw X cards, where X is the number of card types among cards in your graveyard.|
-Restricted Office // Lecture Hall|Duskmourn: House of Horror|227|R|{2}{W}{W}|Enchantment - Room|||(You may cast 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.|
+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 door, 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}|
+Roaring Furnace // Steaming Sauna|Duskmourn: House of Horror|230|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.|
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.|
+Shroudstomper|Duskmourn: House of Horror|233|U|{3}{W}{W}{B}{B}|Creature - Elemental|5|5|Deathtouch$Whenever Shroudstomper enters or attacks, each opponent loses 2 life. You gain 2 life and draw a card.|
Skullsnap Nuisance|Duskmourn: House of Horror|234|U|{U}{B}|Creature - Insect Skeleton|1|4|Flying$Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1.|
-Smoky Lounge // Misty Salon|Duskmourn: House of Horror|235|U|{2}{R}|Enchantment - Room|||(You may cast 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 first main phase, add {R}{R}. Spend this mana only to cast Room spells and unlock doors.$Misty Salon${3}{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.)$When you unlock this door, you create an X/X blue Spirit creature token with flying, where X is the number of unlocked doors among Rooms you control.|
+Smoky Lounge // Misty Salon|Duskmourn: House of Horror|235|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.)$At the beginning of your first main phase, add {R}{R}. Spend this mana only to cast Room spells and unlock doors.$Misty Salon${3}{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.)$When you unlock this door, create an X/X blue Spirit creature token with flying, where X is the number of unlocked doors among Rooms you control.|
The Swarmweaver|Duskmourn: House of Horror|236|R|{2}{B}{G}|Legendary Artifact Creature - Scarecrow|2|3|When The Swarmweaver enters, create two 1/1 black and green Insect creature tokens with flying.$Delirium -- As long as there are four or more card types among cards in your graveyard, Insects and Spiders you control get +1/+1 and have deathtouch.|
Undead Sprinter|Duskmourn: House of Horror|237|R|{B}{R}|Creature - Zombie|2|2|Trample, haste$You may cast Undead Sprinter from your graveyard if a non-Zombie creature died this turn. If you do, Undead Sprinter enters with a +1/+1 counter on it.|
Victor, Valgavoth's Seneschal|Duskmourn: House of Horror|238|R|{1}{W}{B}|Legendary Creature - Human Warlock|3|3|Eerie -- Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.|
@@ -54242,7 +54256,6 @@ 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.|
@@ -54617,7 +54630,7 @@ Zimone's Hypothesis|Duskmourn: House of Horror Commander|15|R|{3}{U}{U}|Instant|
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.|
+Demonic Covenant|Duskmourn: House of Horror Commander|19|R|{4}{B}{B}|Kindred Enchantment - Demon|||Whenever one or more Demons you control attack a player, you draw a card and lose 1 life.$At the beginning of your end step, create a 5/5 black Demon creature token with flying, then mill two cards. If two cards that share all their card types were milled this way, sacrifice Demonic Covenant.|
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|
@@ -54626,13 +54639,13 @@ Sadistic Shell Game|Duskmourn: House of Horror Commander|24|R|{4}{B}|Sorcery|||S
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.|
+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|
+Formless Genesis|Duskmourn: House of Horror Commander|34|R|{2}{G}|Kindred Sorcery - Shapeshifter|||Changeling$Create an X/X colorless Shapeshifter creature token with changeling and deathtouch, where X is the number of land cards in your graveyard.$Retrace|
Shriekwood Devourer|Duskmourn: House of Horror Commander|35|R|{5}{G}{G}|Creature - Treefolk|7|5|Trample$Whenever you attack with one or more creatures, untap up to X lands, where X is the greatest power among those creatures.|
Ursine Monstrosity|Duskmourn: House of Horror Commander|36|R|{2}{G}|Creature - Bear Mutant|3|3|Trample$At the beginning of combat on your turn, mill a card and choose an opponent at random. Ursine Monstrosity attacks that player this combat if able. Until end of turn, Ursine Monstrosity gains indestructible and gets +1/+1 for each card type among cards in your graveyard.|
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.|
@@ -54656,6 +54669,7 @@ Citanul Hierophants|Duskmourn: House of Horror Commander|81|R|{3}{G}|Creature -
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.|
+Culling Ritual|Duskmourn: House of Horror Commander|85|R|{2}{B}{G}|Sorcery|||Destroy each nonland permanent with mana value 2 or less. Add {B} or {G} for each permanent destroyed this way.|
Deathreap Ritual|Duskmourn: House of Horror Commander|86|U|{2}{B}{G}|Enchantment|||Morbid -- At the beginning of each end step, if a creature died this turn, you may draw a card.|
Diabolic Vision|Duskmourn: House of Horror Commander|87|U|{U}{B}|Sorcery|||Look at the top five cards of your library. Put one of them into your hand and the rest on top of your library in any order.|
Growth Spiral|Duskmourn: House of Horror Commander|88|C|{G}{U}|Instant|||Draw a card. You may put a land card from your hand onto the battlefield.|
@@ -54665,7 +54679,7 @@ Utter End|Duskmourn: House of Horror Commander|91|R|{2}{W}{B}|Instant|||Exile ta
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.|
+Suspicious Bookcase|Duskmourn: House of Horror Commander|95|U|{2}|Artifact Creature - Wall|0|4|Defender${3}, {T}: Target creature can't be blocked this turn.|
Command Tower|Duskmourn: House of Horror Commander|96|C||Land|||{T}: Add one mana of any color in your commander's color identity.|
Auramancer|Duskmourn: House of Horror Commander|97|C|{2}{W}|Creature - Human Wizard|2|2|When Auramancer enters, you may return target enchantment card from your graveyard to your hand.|
Cast Out|Duskmourn: House of Horror Commander|98|U|{3}{W}|Enchantment|||Flash$When Cast Out enters, exile target nonland permanent an opponent controls until Cast Out leaves the battlefield.$Cycling {W}|
@@ -54701,84 +54715,187 @@ Shark Typhoon|Duskmourn: House of Horror Commander|127|R|{5}{U}|Enchantment|||Wh
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.|
+Bastion of Remembrance|Duskmourn: House of Horror Commander|131|U|{2}{B}|Enchantment|||When Bastion of Remembrance enters, create a 1/1 white Human Soldier creature token.$Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life.|
+Blood Artist|Duskmourn: House of Horror Commander|132|U|{1}{B}|Creature - Vampire|0|1|Whenever Blood Artist or another creature dies, target player loses 1 life and you gain 1 life.|
+Braids, Arisen Nightmare|Duskmourn: House of Horror Commander|133|R|{1}{B}{B}|Legendary Creature - Nightmare|3|3|At the beginning of your end step, you may sacrifice an artifact, creature, enchantment, land, or planeswalker. If you do, each opponent may sacrifice a permanent that shares a card type with it. For each opponent who doesn't, that player loses 2 life and you draw a card.|
+Carrion Grub|Duskmourn: House of Horror Commander|134|C|{3}{B}|Creature - Insect|0|5|Carrion Grub gets +X/+0, where X is the greatest power among creature cards in your graveyard.$When Carrion Grub enters, mill four cards.|
+Cemetery Tampering|Duskmourn: House of Horror Commander|135|R|{2}{B}|Enchantment|||Hideaway 5$At the beginning of your upkeep, you may mill three cards. Then if there are twenty or more cards in your graveyard, you may play the exiled card without paying its mana cost.|
+Decree of Pain|Duskmourn: House of Horror Commander|136|R|{6}{B}{B}|Sorcery|||Destroy all creatures. They can't be regenerated. Draw a card for each creature destroyed this way.$Cycling {3}{B}{B}$When you cycle Decree of Pain, all creatures get -2/-2 until end of turn.|
Demon of Fate's Design|Duskmourn: House of Horror Commander|137|R|{4}{B}{B}|Enchantment Creature - Demon|6|6|Flying, trample$Once during each of your turns, you may cast an enchantment spell by paying life equal to its mana value rather than paying its mana cost.${2}{B}, Sacrifice another enchantment: Demon of Fate's Design gets +X/+0 until end of turn, where X is the sacrificed enchantment's mana value.|
Doomwake Giant|Duskmourn: House of Horror Commander|138|R|{4}{B}|Enchantment Creature - Giant|4|6|Constellation -- Whenever Doomwake Giant or another enchantment you control enters, creatures your opponents control get -1/-1 until end of turn.|
The Eldest Reborn|Duskmourn: House of Horror Commander|139|U|{4}{B}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- Each opponent sacrifices a creature or planeswalker.$II -- Each opponent discards a card.$III -- Put target creature or planeswalker card from a graveyard onto the battlefield under your control.|
+Falkenrath Noble|Duskmourn: House of Horror Commander|140|U|{3}{B}|Creature - Vampire Noble|2|2|Flying$Whenever Falkenrath Noble or another creature dies, target player loses 1 life and you gain 1 life.|
+Fate Unraveler|Duskmourn: House of Horror Commander|141|R|{3}{B}|Enchantment Creature - Hag|3|4|Whenever an opponent draws a card, Fate Unraveler deals 1 damage to that player.|
+Gray Merchant of Asphodel|Duskmourn: House of Horror Commander|142|U|{3}{B}{B}|Creature - Zombie|2|4|When Gray Merchant of Asphodel enters, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way.|
+Infernal Grasp|Duskmourn: House of Horror Commander|143|U|{1}{B}|Instant|||Destroy target creature. You lose 2 life.|
+Kederekt Parasite|Duskmourn: House of Horror Commander|144|R|{B}|Creature - Horror|1|1|Whenever an opponent draws a card, if you control a red permanent, you may have Kederekt Parasite deal 1 damage to that player.|
+Mask of Griselbrand|Duskmourn: House of Horror Commander|145|R|{1}{B}{B}|Legendary Artifact - Equipment|||Equipped creature has flying and lifelink.$Whenever equipped creature dies, you may pay X life, where X is its power. If you do, draw X cards.$Equip {3}|
+Massacre Girl|Duskmourn: House of Horror Commander|146|R|{3}{B}{B}|Legendary Creature - Human Assassin|4|4|Menace$When Massacre Girl enters, each other creature gets -1/-1 until end of turn. Whenever a creature dies this turn, each creature other than Massacre Girl gets -1/-1 until end of turn.|
+Massacre Wurm|Duskmourn: House of Horror Commander|147|M|{3}{B}{B}{B}|Creature - Phyrexian Wurm|6|5|When Massacre Wurm enters, creatures your opponents control get -2/-2 until end of turn.$Whenever a creature an opponent controls dies, that player loses 2 life.|
+Morbid Opportunist|Duskmourn: House of Horror Commander|148|U|{2}{B}|Creature - Human Rogue|1|3|Whenever one or more other creatures die, draw a card. This ability triggers only once each turn.|
Nightmare Shepherd|Duskmourn: House of Horror Commander|149|R|{2}{B}{B}|Enchantment Creature - Demon|4|4|Flying$Whenever another nontoken creature you control dies, you may exile it. If you do, create a token that's a copy of that creature, except it's 1/1 and it's a Nightmare in addition to its other types.|
+Nightshade Harvester|Duskmourn: House of Horror Commander|150|R|{3}{B}|Creature - Elf Shaman|2|2|Whenever a land an opponent controls enters, that player loses 1 life. Put a +1/+1 counter on Nightshade Harvester.|
+Noxious Gearhulk|Duskmourn: House of Horror Commander|151|M|{4}{B}{B}|Artifact Creature - Construct|5|4|Menace$When Noxious Gearhulk enters, you may destroy another target creature. If a creature is destroyed this way, you gain life equal to its toughness.|
+Ob Nixilis Reignited|Duskmourn: House of Horror Commander|152|M|{3}{B}{B}|Legendary Planeswalker - Nixilis|5|+1: You draw a card and you lose 1 life.$-3: Destroy target creature.$-8: Target opponent gets an emblem with "Whenever a player draws a card, you lose 2 life."|
+Professor Onyx|Duskmourn: House of Horror Commander|153|M|{4}{B}{B}|Legendary Planeswalker - Liliana|5|Magecraft -- Whenever you cast or copy an instant or sorcery spell, each opponent loses 2 life and you gain 2 life.$+1: You lose 1 life. Look at the top three cards of your library. Put one of them into your hand and the rest into your graveyard.$-3: Each opponent sacrifices a creature with the greatest power among creatures that player controls.$-8: Each opponent may discard a card. If they don't, they lose 3 life. Repeat this process six more times.|
Read the Bones|Duskmourn: House of Horror Commander|154|C|{2}{B}|Sorcery|||Scry 2, then draw two cards. You lose 2 life.|
+Reanimate|Duskmourn: House of Horror Commander|155|R|{B}|Sorcery|||Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its mana value.|
+Sign in Blood|Duskmourn: House of Horror Commander|156|C|{B}{B}|Sorcery|||Target player draws two cards and loses 2 life.|
+Stitcher's Supplier|Duskmourn: House of Horror Commander|157|U|{B}|Creature - Zombie|1|1|When Stitcher's Supplier enters or dies, mill three cards.|
+Syr Konrad, the Grim|Duskmourn: House of Horror Commander|158|U|{3}{B}{B}|Legendary Creature - Human Knight|5|4|Whenever another creature dies, or a creature card is put into a graveyard from anywhere other than the battlefield, or a creature card leaves your graveyard, Syr Konrad, the Grim deals 1 damage to each opponent.${1}{B}: Each player mills a card.|
+Whip of Erebos|Duskmourn: House of Horror Commander|159|R|{2}{B}{B}|Legendary Enchantment Artifact|||Creatures you control have lifelink.${2}{B}{B}, {T}: Return target creature card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step. If it would leave the battlefield, exile it instead of putting it anywhere else. Activate only as a sorcery.|
+Blasphemous Act|Duskmourn: House of Horror Commander|160|R|{8}{R}|Sorcery|||This spell costs {1} less to cast for each creature on the battlefield.$Blasphemous Act deals 13 damage to each creature.|
+Brash Taunter|Duskmourn: House of Horror Commander|161|R|{4}{R}|Creature - Goblin|1|1|Indestructible$Whenever Brash Taunter is dealt damage, it deals that much damage to target opponent.${2}{R}, {T}: Brash Taunter fights another target creature.|
+Chaos Warp|Duskmourn: House of Horror Commander|162|R|{2}{R}|Instant|||The owner of target permanent shuffles it into their library, then reveals the top card of their library. If it's a permanent card, they put it onto the battlefield.|
+Combustible Gearhulk|Duskmourn: House of Horror Commander|163|M|{4}{R}{R}|Artifact Creature - Construct|6|6|First strike$When Combustible Gearhulk enters, target opponent may have you draw three cards. If the player doesn't, you mill three cards, then Combustible Gearhulk deals damage to that player equal to the total mana value of those cards.|
+Enchanter's Bane|Duskmourn: House of Horror Commander|164|R|{1}{R}|Enchantment|||At the beginning of your end step, target enchantment deals damage equal to its mana value to its controller unless that player sacrifices it.|
+Harsh Mentor|Duskmourn: House of Horror Commander|165|R|{1}{R}|Creature - Human Cleric|2|2|Whenever an opponent activates an ability of an artifact, creature, or land on the battlefield, if it isn't a mana ability, Harsh Mentor deals 2 damage to that player.|
+Light Up the Stage|Duskmourn: House of Horror Commander|166|U|{2}{R}|Sorcery|||Spectacle {R}$Exile the top two cards of your library. Until the end of your next turn, you may play those cards.|
+Rampaging Ferocidon|Duskmourn: House of Horror Commander|167|R|{2}{R}|Creature - Dinosaur|3|3|Menace$Players can't gain life.$Whenever another creature enters, Rampaging Ferocidon deals 1 damage to that creature's controller.|
+Tectonic Giant|Duskmourn: House of Horror Commander|168|R|{2}{R}{R}|Creature - Elemental Giant|3|4|Whenever Tectonic Giant attacks or becomes the target of a spell an opponent controls, choose one --$* Tectonic Giant deals 3 damage to each opponent.$* Exile the top two cards of your library. Choose one of them. Until the end of your next turn, you may play that card.|
+Arachnogenesis|Duskmourn: House of Horror Commander|169|R|{2}{G}|Instant|||Create X 1/2 green Spider creature tokens with reach, where X is the number of creatures attacking you. Prevent all combat damage that would be dealt this turn by non-Spider creatures.|
Ashaya, Soul of the Wild|Duskmourn: House of Horror Commander|170|M|{3}{G}{G}|Legendary Creature - Elemental|*|*|Ashaya, Soul of the Wild's power and toughness are each equal to the number of lands you control.$Nontoken creatures you control are Forest lands in addition to their other types.|
Augur of Autumn|Duskmourn: House of Horror Commander|171|R|{1}{G}{G}|Creature - Human Druid|2|3|You may look at the top card of your library any time.$You may play lands from the top of your library.$Coven -- As long as you control three or more creatures with different powers, you may cast creature spells from the top of your library.|
Beanstalk Giant|Duskmourn: House of Horror Commander|172|U|{6}{G}|Creature - Giant|*|*|Beanstalk Giant's power and toughness are each equal to the number of lands you control.|
Fertile Footsteps|Duskmourn: House of Horror Commander|172|U|{2}{G}|Sorcery - Adventure|*|*|Search your library for a basic land card, put it onto the battlefield, then shuffle.|
+Crawling Sensation|Duskmourn: House of Horror Commander|173|U|{2}{G}|Enchantment|||At the beginning of your upkeep, you may mill two cards.$Whenever one or more land cards are put into your graveyard from anywhere for the first time each turn, create a 1/1 green Insect creature token.|
Cultivate|Duskmourn: House of Horror Commander|174|C|{2}{G}|Sorcery|||Search your library for up to two basic land cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle.|
+Deathcap Cultivator|Duskmourn: House of Horror Commander|175|R|{1}{G}|Creature - Human Druid|2|1|{T}: Add {B} or {G}.$Delirium -- Deathcap Cultivator has deathtouch as long as there are four or more card types among cards in your graveyard.|
Deathmist Raptor|Duskmourn: House of Horror Commander|176|M|{1}{G}{G}|Creature - Dinosaur Beast|3|3|Deathtouch$Whenever a permanent you control is turned face up, you may return Deathmist Raptor from your graveyard to the battlefield face up or face down.$Megamorph {4}{G}|
Explosive Vegetation|Duskmourn: House of Horror Commander|177|U|{3}{G}|Sorcery|||Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle.|
Ezuri's Predation|Duskmourn: House of Horror Commander|178|R|{5}{G}{G}{G}|Sorcery|||For each creature your opponents control, create a 4/4 green Phyrexian Beast creature token. Each of those tokens fights a different one of those creatures.|
+Giant Adephage|Duskmourn: House of Horror Commander|179|M|{5}{G}{G}|Creature - Insect|7|7|Trample$Whenever Giant Adephage deals combat damage to a player, create a token that's a copy of Giant Adephage.|
+Gnarlwood Dryad|Duskmourn: House of Horror Commander|180|U|{G}|Creature - Dryad Horror|1|1|Deathtouch$Delirium -- Gnarlwood Dryad gets +2/+2 as long as there are four or more card types among cards in your graveyard.|
Greater Tanuki|Duskmourn: House of Horror Commander|181|C|{4}{G}{G}|Enchantment Creature - Dog|6|5|Trample$Channel -- {2}{G}, Discard Greater Tanuki: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.|
+Harmonize|Duskmourn: House of Horror Commander|182|U|{2}{G}{G}|Sorcery|||Draw three cards.|
+Harrow|Duskmourn: House of Horror Commander|183|C|{2}{G}|Instant|||As an additional cost to cast this spell, sacrifice a land.$Search your library for up to two basic land cards, put them onto the battlefield, then shuffle.|
+Hornet Queen|Duskmourn: House of Horror Commander|184|M|{4}{G}{G}{G}|Creature - Insect|2|2|Flying, deathtouch$When Hornet Queen enters, create four 1/1 green Insect creature tokens with flying and deathtouch.|
Hydra Omnivore|Duskmourn: House of Horror Commander|185|M|{4}{G}{G}|Creature - Hydra|8|8|Whenever Hydra Omnivore deals combat damage to an opponent, it deals that much damage to each other opponent.|
+Inscription of Abundance|Duskmourn: House of Horror Commander|186|R|{1}{G}|Instant|||Kicker {2}{G}$Choose one. If this spell was kicked, choose any number instead.$* Put two +1/+1 counters on target creature.$* Target player gains X life, where X is the greatest power among creatures they control.$* Target creature you control fights target creature you don't control.|
+Ishkanah, Grafwidow|Duskmourn: House of Horror Commander|187|M|{4}{G}|Legendary Creature - Spider|3|5|Reach$Delirium -- When Ishkanah, Grafwidow enters, if there are four or more card types among cards in your graveyard, create three 1/2 green Spider creature tokens with reach.${6}{B}: Target opponent loses 1 life for each Spider you control.|
+Moldgraf Millipede|Duskmourn: House of Horror Commander|188|C|{4}{G}|Creature - Insect Horror|2|2|When Moldgraf Millipede enters, mill three cards, then put a +1/+1 counter on Moldgraf Millipede for each creature card in your graveyard.|
+Mulch|Duskmourn: House of Horror Commander|189|C|{1}{G}|Sorcery|||Reveal the top four cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard.|
Multani, Yavimaya's Avatar|Duskmourn: House of Horror Commander|190|M|{4}{G}{G}|Legendary Creature - Elemental Avatar|0|0|Reach, trample$Multani, Yavimaya's Avatar gets +1/+1 for each land you control and each land card in your graveyard.${1}{G}, Return two lands you control to their owner's hand: Return Multani from your graveyard to your hand.|
+Obsessive Skinner|Duskmourn: House of Horror Commander|191|U|{1}{G}|Creature - Human Rogue|1|1|When Obsessive Skinner enters, put a +1/+1 counter on target creature.$Delirium -- At the beginning of each opponent's upkeep, if there are four or more card types among cards in your graveyard, put a +1/+1 counter on target creature.|
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.|
+Scavenging Ooze|Duskmourn: House of Horror Commander|196|R|{1}{G}|Creature - Ooze|2|2|{G}: Exile target card from a graveyard. If it was a creature card, put a +1/+1 counter on Scavenging Ooze and you gain 1 life.|
Scute Swarm|Duskmourn: House of Horror Commander|197|R|{2}{G}|Creature - Insect|1|1|Landfall -- Whenever a land you control enters, create a 1/1 green Insect creature token. If you control six or more lands, create a token that's a copy of Scute Swarm instead.|
Shigeki, Jukai Visionary|Duskmourn: House of Horror Commander|198|R|{1}{G}|Legendary Enchantment Creature - Snake Druid|1|3|{1}{G}, {T}, Return Shigeki, Jukai Visionary to its owner's hand: Reveal the top four cards of your library. You may put a land card from among them onto the battlefield tapped. Put the rest into your graveyard.$Channel -- {X}{X}{G}{G}, Discard Shigeki: Return X target nonlegendary cards from your graveyard to your hand.|
+Skola Grovedancer|Duskmourn: House of Horror Commander|199|C|{1}{G}|Enchantment Creature - Satyr Druid|2|2|Whenever a land card is put into your graveyard from anywhere, you gain 1 life.${2}{G}: Mill a card.|
Temur War Shaman|Duskmourn: House of Horror Commander|200|R|{4}{G}{G}|Creature - Human Shaman|4|5|When Temur War Shaman enters, manifest the top card of your library.$Whenever a permanent you control is turned face up, if it's a creature, you may have it fight target creature you don't control.|
+Thunderfoot Baloth|Duskmourn: House of Horror Commander|201|R|{4}{G}{G}|Creature - Beast|5|5|Trample$Lieutenant -- As long as you control your commander, Thunderfoot Baloth gets +2/+2 and other creatures you control get +2/+2 and have trample.|
+Titania, Nature's Force|Duskmourn: House of Horror Commander|202|M|{4}{G}{G}|Legendary Creature - Elemental|6|6|You may play Forests from your graveyard.$Whenever a Forest you control enters, create a 5/3 green Elemental creature token.$Whenever an Elemental you control dies, you may mill three cards.|
Trail of Mystery|Duskmourn: House of Horror Commander|203|R|{1}{G}|Enchantment|||Whenever a face-down creature you control enters, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle.$Whenever a permanent you control is turned face up, if it's a creature, it gets +2/+2 until end of turn.|
Whisperwood Elemental|Duskmourn: House of Horror Commander|204|M|{3}{G}{G}|Creature - Elemental|4|4|At the beginning of your end step, manifest the top card of your library.$Sacrifice Whisperwood Elemental: Until end of turn, face-up nontoken creatures you control gain "When this creature dies, manifest the top card of your library."|
Wilderness Reclamation|Duskmourn: House of Horror Commander|205|U|{3}{G}|Enchantment|||At the beginning of your end step, untap all lands you control.|
Worldspine Wurm|Duskmourn: House of Horror Commander|206|M|{8}{G}{G}{G}|Creature - Wurm|15|15|Trample$When Worldspine Wurm dies, create three 5/5 green Wurm creature tokens with trample.$When Worldspine Wurm is put into a graveyard from anywhere, shuffle it into its owner's library.|
+Wrenn and Seven|Duskmourn: House of Horror Commander|207|M|{3}{G}{G}|Legendary Planeswalker - Wrenn|5|+1: Reveal the top four cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard.$0: Put any number of land cards from your hand onto the battlefield tapped.$-3: Create a green Treefolk creature token with reach and "This creature's power and toughness are each equal to the number of lands you control."$-8: Return all permanent cards from your graveyard to your hand. You get an emblem with "You have no maximum hand size."|
Yavimaya Elder|Duskmourn: House of Horror Commander|208|C|{1}{G}{G}|Creature - Human Druid|2|1|When Yavimaya Elder dies, you may search your library for up to two basic land cards, reveal them, put them into your hand, then shuffle.${2}, Sacrifice Yavimaya Elder: Draw a card.|
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.|
+Binding the Old Gods|Duskmourn: House of Horror Commander|213|U|{2}{B}{G}|Enchantment - Saga|||(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)$I -- Destroy target nonland permanent an opponent controls.$II -- Search your library for a Forest card, put it onto the battlefield tapped, then shuffle.$III -- Creatures you control gain deathtouch until end of turn.|
Biomass Mutation|Duskmourn: House of Horror Commander|214|R|{X}{G/U}{G/U}|Instant|||Creatures you control have base power and toughness X/X until end of turn.|
+Deadbridge Chant|Duskmourn: House of Horror Commander|215|M|{4}{B}{G}|Enchantment|||When Deadbridge Chant enters, mill ten cards.$At the beginning of your upkeep, choose a card at random in your graveyard. If it's a creature card, return it to the battlefield. Otherwise, return it to your hand.|
Eureka Moment|Duskmourn: House of Horror Commander|216|C|{2}{G}{U}|Instant|||Draw two cards. You may put a land card from your hand onto the battlefield.|
+Florian, Voldaren Scion|Duskmourn: House of Horror Commander|217|R|{1}{B}{R}|Legendary Creature - Vampire Noble|3|3|First strike$At the beginning of your second main phase, look at the top X cards of your library, where X is the total amount of life your opponents lost this turn. Exile one of those cards and put the rest on the bottom of your library in a random order. You may play the exiled card this turn.|
+Grim Flayer|Duskmourn: House of Horror Commander|218|R|{B}{G}|Creature - Human Warrior|2|2|Trample$Whenever Grim Flayer deals combat damage to a player, surveil 3.$Delirium -- Grim Flayer gets +2/+2 as long as there are four or more card types among cards in your graveyard.|
+Grisly Salvage|Duskmourn: House of Horror Commander|219|C|{B}{G}|Instant|||Reveal the top five cards of your library. You may put a creature or land card from among them into your hand. Put the rest into your graveyard.|
+Grist, the Hunger Tide|Duskmourn: House of Horror Commander|220|M|{1}{B}{G}|Legendary Planeswalker - Grist|3|As long as Grist, the Hunger Tide isn't on the battlefield, it's a 1/1 Insect creature in addition to its other types.$+1: Create a 1/1 black and green Insect creature token, then mill a card. If an Insect card was milled this way, put a loyalty counter on Grist and repeat this process.$-2: You may sacrifice a creature. When you do, destroy target creature or planeswalker.$-5: Each opponent loses life equal to the number of creature cards in your graveyard.|
Inkshield|Duskmourn: House of Horror Commander|221|R|{3}{W}{B}|Instant|||Prevent all combat damage that would be dealt to you this turn. For each 1 damage prevented this way, create a 2/1 white and black Inkling creature token with flying.|
+Kaervek the Merciless|Duskmourn: House of Horror Commander|222|R|{5}{B}{R}|Legendary Creature - Human Shaman|5|4|Whenever an opponent casts a spell, Kaervek the Merciless deals damage equal to that spell's mana value to any target.|
+Kardur, Doomscourge|Duskmourn: House of Horror Commander|223|U|{2}{B}{R}|Legendary Creature - Demon Berserker|4|3|When Kardur, Doomscourge enters, until your next turn, creatures your opponents control attack each combat if able and attack a player other than you if able.$Whenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.|
Life Insurance|Duskmourn: House of Horror Commander|224|R|{3}{W}{B}|Enchantment|||Extort$Whenever a nontoken creature dies, you lose 1 life and create a Treasure token.|
+Mayhem Devil|Duskmourn: House of Horror Commander|225|U|{1}{B}{R}|Creature - Devil|3|3|Whenever a player sacrifices a permanent, Mayhem Devil deals 1 damage to any target.|
+Nyx Weaver|Duskmourn: House of Horror Commander|226|U|{1}{B}{G}|Enchantment Creature - Spider|2|3|Reach$At the beginning of your upkeep, mill two cards.${1}{B}{G}, Exile Nyx Weaver: Return target card from your graveyard to your hand.|
+Old Stickfingers|Duskmourn: House of Horror Commander|227|R|{X}{B}{G}|Legendary Creature - Horror|*|*|When you cast this spell, reveal cards from the top of your library until you reveal X creature cards. Put all creature cards revealed this way into your graveyard, then put the rest on the bottom of your library in a random order.$Old Stickfingers's power and toughness are each equal to the number of creature cards in your graveyard.|
Oversimplify|Duskmourn: House of Horror Commander|228|R|{3}{G}{U}|Sorcery|||Exile all creatures. Each player creates a 0/0 green and blue Fractal creature token and puts a number of +1/+1 counters on it equal to the total power of creatures they controlled that were exiled this way.|
+Rakdos Charm|Duskmourn: House of Horror Commander|229|U|{B}{R}|Instant|||Choose one --$* Exile target player's graveyard.$* Destroy target artifact.$* Each creature deals 1 damage to its controller.|
+Rakdos, Lord of Riots|Duskmourn: House of Horror Commander|230|M|{B}{B}{R}{R}|Legendary Creature - Demon|6|6|You can't cast this spell unless an opponent lost life this turn.$Flying, trample$Creature spells you cast cost {1} less to cast for each 1 life your opponents have lost this turn.|
Rashmi, Eternities Crafter|Duskmourn: House of Horror Commander|231|M|{2}{G}{U}|Legendary Creature - Elf Druid|2|3|Whenever you cast your first spell each turn, reveal the top card of your library. You may cast it without paying its mana cost if it's a spell with lesser mana value. If you don't cast it, put it into your hand.|
Spirit-Sister's Call|Duskmourn: House of Horror Commander|232|M|{3}{W}{B}|Enchantment|||At the beginning of your end step, choose target permanent card in your graveyard. You may sacrifice a permanent that shares a card type with the chosen card. If you do, return the chosen card from your graveyard to the battlefield and it gains "If this permanent would leave the battlefield, exile it instead of putting it anywhere else."|
+Spiteful Visions|Duskmourn: House of Horror Commander|233|R|{2}{B/R}{B/R}|Enchantment|||At the beginning of each player's draw step, that player draws an additional card.$Whenever a player draws a card, Spiteful Visions deals 1 damage to that player.|
+Stormfist Crusader|Duskmourn: House of Horror Commander|234|R|{B}{R}|Creature - Human Knight|2|2|Menace$At the beginning of your upkeep, each player draws a card and loses 1 life.|
Tatyova, Benthic Druid|Duskmourn: House of Horror Commander|235|U|{3}{G}{U}|Legendary Creature - Merfolk Druid|3|3|Landfall -- Whenever a land you control enters, you gain 1 life and draw a card.|
+Theater of Horrors|Duskmourn: House of Horror Commander|236|R|{1}{B}{R}|Enchantment|||At the beginning of your upkeep, exile the top card of your library.$During your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with Theater of Horrors.${3}{R}: Theater of Horrors deals 1 damage to target opponent or planeswalker.|
Time Wipe|Duskmourn: House of Horror Commander|237|R|{2}{W}{W}{U}|Sorcery|||Return a creature you control to its owner's hand, then destroy all creatures.|
Trygon Predator|Duskmourn: House of Horror Commander|238|U|{1}{G}{U}|Creature - Beast|2|3|Flying$Whenever Trygon Predator deals combat damage to a player, you may destroy target artifact or enchantment that player controls.|
+Vial Smasher the Fierce|Duskmourn: House of Horror Commander|239|M|{1}{B}{R}|Legendary Creature - Goblin Berserker|2|3|Whenever you cast your first spell each turn, choose an opponent at random. Vial Smasher the Fierce deals damage equal to that spell's mana value to that player or a planeswalker that player controls.$Partner|
Azorius Signet|Duskmourn: House of Horror Commander|240|U|{2}|Artifact|||{1}, {T}: Add {W}{U}.|
+Basilisk Collar|Duskmourn: House of Horror Commander|241|R|{1}|Artifact - Equipment|||Equipped creature has deathtouch and lifelink.$Equip {2}|
Brainstone|Duskmourn: House of Horror Commander|242|U|{1}|Artifact|||{2}, {T}, Sacrifice Brainstone: Draw three cards, then put two cards from your hand on top of your library in any order.|
Burnished Hart|Duskmourn: House of Horror Commander|243|U|{3}|Artifact Creature - Elk|2|2|{3}, Sacrifice Burnished Hart: Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle.|
Commander's Sphere|Duskmourn: House of Horror Commander|244|C|{3}|Artifact|||{T}: Add one mana of any color in your commander's color identity.$Sacrifice Commander's Sphere: Draw a card.|
+Fellwar Stone|Duskmourn: House of Horror Commander|245|U|{2}|Artifact|||{T}: Add one mana of any color that a land an opponent controls could produce.|
+Golgari Signet|Duskmourn: House of Horror Commander|246|C|{2}|Artifact|||{1}, {T}: Add {B}{G}.|
+Haywire Mite|Duskmourn: House of Horror Commander|247|U|{1}|Artifact Creature - Insect|1|1|When Haywire Mite dies, you gain 2 life.${G}, Sacrifice Haywire Mite: Exile target noncreature artifact or noncreature enchantment.|
Mind Stone|Duskmourn: House of Horror Commander|248|U|{2}|Artifact|||{T}: Add {C}.${1}, {T}, Sacrifice Mind Stone: Draw a card.|
Orzhov Signet|Duskmourn: House of Horror Commander|249|U|{2}|Artifact|||{1}, {T}: Add {W}{B}.|
+Rakdos Signet|Duskmourn: House of Horror Commander|250|U|{2}|Artifact|||{1}, {T}: Add {B}{R}.|
Scroll of Fate|Duskmourn: House of Horror Commander|251|R|{3}|Artifact|||{T}: Manifest a card from your hand.|
Simic Signet|Duskmourn: House of Horror Commander|252|U|{2}|Artifact|||{1}, {T}: Add {G}{U}.|
Solemn Simulacrum|Duskmourn: House of Horror Commander|253|R|{4}|Artifact Creature - Golem|2|2|When Solemn Simulacrum enters, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.$When Solemn Simulacrum dies, you may draw a card.|
+Talisman of Indulgence|Duskmourn: House of Horror Commander|254|U|{2}|Artifact|||{T}: Add {C}.${T}: Add {B} or {R}. Talisman of Indulgence deals 1 damage to you.|
+Talisman of Resilience|Duskmourn: House of Horror Commander|255|U|{2}|Artifact|||{T}: Add {C}.${T}: Add {B} or {G}. Talisman of Resilience deals 1 damage to you.|
+Thought Vessel|Duskmourn: House of Horror Commander|256|U|{2}|Artifact|||You have no maximum hand size.${T}: Add {C}.|
+Whispersilk Cloak|Duskmourn: House of Horror Commander|257|U|{3}|Artifact - Equipment|||Equipped creature can't be blocked and has shroud.$Equip {2}|
Adarkar Wastes|Duskmourn: House of Horror Commander|258|R||Land|||{T}: Add {C}.${T}: Add {W} or {U}. Adarkar Wastes deals 1 damage to you.|
Arcane Sanctum|Duskmourn: House of Horror Commander|259|U||Land|||Arcane Sanctum enters tapped.${T}: Add {W}, {U}, or {B}.|
Ash Barrens|Duskmourn: House of Horror Commander|260|C||Land|||{T}: Add {C}.$Basic landcycling {1}|
Azorius Chancery|Duskmourn: House of Horror Commander|261|U||Land|||Azorius Chancery enters tapped.$When Azorius Chancery enters, return a land you control to its owner's hand.${T}: Add {W}{U}.|
+Barren Moor|Duskmourn: House of Horror Commander|262|U||Land|||Barren Moor enters tapped.${T}: Add {B}.$Cycling {B}|
+Blackcleave Cliffs|Duskmourn: House of Horror Commander|263|R||Land|||Blackcleave Cliffs enters tapped unless you control two or fewer other lands.${T}: Add {B} or {R}.|
+Bloodfell Caves|Duskmourn: House of Horror Commander|264|C||Land|||Bloodfell Caves enters tapped.$When Bloodfell Caves enters, you gain 1 life.${T}: Add {B} or {R}.|
Bojuka Bog|Duskmourn: House of Horror Commander|265|C||Land|||Bojuka Bog enters tapped.$When Bojuka Bog enters, exile target player's graveyard.${T}: Add {B}.|
+Canyon Slough|Duskmourn: House of Horror Commander|266|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$Canyon Slough enters tapped.$Cycling {2}|
Castle Vantress|Duskmourn: House of Horror Commander|267|R||Land|||Castle Vantress enters tapped unless you control an Island.${T}: Add {U}.${2}{U}{U}, {T}: Scry 2.|
Caves of Koilos|Duskmourn: House of Horror Commander|268|R||Land|||{T}: Add {C}.${T}: Add {W} or {B}. Caves of Koilos deals 1 damage to you.|
+Darkmoss Bridge|Duskmourn: House of Horror Commander|269|C||Artifact Land|||Darkmoss Bridge enters tapped.$Indestructible${T}: Add {B} or {G}.|
Dimir Aqueduct|Duskmourn: House of Horror Commander|270|U||Land|||Dimir Aqueduct enters tapped.$When Dimir Aqueduct enters, return a land you control to its owner's hand.${T}: Add {U}{B}.|
+Dragonskull Summit|Duskmourn: House of Horror Commander|271|R||Land|||Dragonskull Summit enters tapped unless you control a Swamp or a Mountain.${T}: Add {B} or {R}.|
Drownyard Temple|Duskmourn: House of Horror Commander|272|R||Land|||{T}: Add {C}.${3}: Return Drownyard Temple from your graveyard to the battlefield tapped.|
+Dryad Arbor|Duskmourn: House of Horror Commander|273|R||Land Creature - Forest Dryad|1|1|(Dryad Arbor isn't a spell, it's affected by summoning sickness, and it has "{T}: Add {G}.")|
Evolving Wilds|Duskmourn: House of Horror Commander|274|C||Land|||{T}, Sacrifice Evolving Wilds: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle.|
+Exotic Orchard|Duskmourn: House of Horror Commander|275|R||Land|||{T}: Add one mana of any color that a land an opponent controls could produce.|
Flooded Grove|Duskmourn: House of Horror Commander|276|R||Land|||{T}: Add {C}.${G/U}, {T}: Add {G}{G}, {G}{U}, or {U}{U}.|
+Foreboding Ruins|Duskmourn: House of Horror Commander|277|R||Land|||As Foreboding Ruins enters, you may reveal a Swamp or Mountain card from your hand. If you don't, Foreboding Ruins enters tapped.${T}: Add {B} or {R}.|
+Geothermal Bog|Duskmourn: House of Horror Commander|278|C||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$Geothermal Bog enters tapped.|
+Golgari Rot Farm|Duskmourn: House of Horror Commander|279|C||Land|||Golgari Rot Farm enters tapped.$When Golgari Rot Farm enters, return a land you control to its owner's hand.${T}: Add {B}{G}.|
+Graven Cairns|Duskmourn: House of Horror Commander|280|R||Land|||{T}: Add {C}.${B/R}, {T}: Add {B}{B}, {B}{R}, or {R}{R}.|
+Grim Backwoods|Duskmourn: House of Horror Commander|281|R||Land|||{T}: Add {C}.${2}{B}{G}, {T}, Sacrifice a creature: Draw a card.|
Halimar Depths|Duskmourn: House of Horror Commander|282|C||Land|||Halimar Depths enters tapped.$When Halimar Depths enters, look at the top three cards of your library, then put them back in any order.${T}: Add {U}.|
Hall of Heliod's Generosity|Duskmourn: House of Horror Commander|283|R||Legendary Land|||{T}: Add {C}.${1}{W}, {T}: Put target enchantment card from your graveyard on top of your library.|
Hinterland Harbor|Duskmourn: House of Horror Commander|284|R||Land|||Hinterland Harbor enters tapped unless you control a Forest or an Island.${T}: Add {G} or {U}.|
+Jungle Hollow|Duskmourn: House of Horror Commander|285|C||Land|||Jungle Hollow enters tapped.$When Jungle Hollow enters, you gain 1 life.${T}: Add {B} or {G}.|
+Leechridden Swamp|Duskmourn: House of Horror Commander|286|U||Land - Swamp|||({T}: Add {B}.)$Leechridden Swamp enters tapped.${B}, {T}: Each opponent loses 1 life. Activate only if you control two or more black permanents.|
+Llanowar Wastes|Duskmourn: House of Horror Commander|287|R||Land|||{T}: Add {C}.${T}: Add {B} or {G}. Llanowar Wastes deals 1 damage to you.|
Mosswort Bridge|Duskmourn: House of Horror Commander|288|R||Land|||Hideaway 4$Mosswort Bridge enters tapped.${T}: Add {G}.${G}, {T}: You may play the exiled card without paying its mana cost if creatures you control have total power 10 or greater.|
Myriad Landscape|Duskmourn: House of Horror Commander|289|U||Land|||Myriad Landscape enters tapped.${T}: Add {C}.${2}, {T}, Sacrifice Myriad Landscape: Search your library for up to two basic land cards that share a land type, put them onto the battlefield tapped, then shuffle.|
+Necroblossom Snarl|Duskmourn: House of Horror Commander|290|R||Land|||As Necroblossom Snarl enters, you may reveal a Swamp or Forest card from your hand. If you don't, Necroblossom Snarl enters tapped.${T}: Add {B} or {G}.|
Obscura Storefront|Duskmourn: House of Horror Commander|291|C||Land|||When Obscura Storefront enters, sacrifice it. When you do, search your library for a basic Plains, Island, or Swamp card, put it onto the battlefield tapped, then shuffle and you gain 1 life.|
Orzhov Basilica|Duskmourn: House of Horror Commander|292|U||Land|||Orzhov Basilica enters tapped.$When Orzhov Basilica enters, return a land you control to its owner's hand.${T}: Add {W}{B}.|
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}.|
+Shadowblood Ridge|Duskmourn: House of Horror Commander|296|R||Land|||{1}, {T}: Add {B}{R}.|
+Shivan Gorge|Duskmourn: House of Horror Commander|297|R||Legendary Land|||{T}: Add {C}.${2}{R}, {T}: Shivan Gorge deals 1 damage to each opponent.|
Simic Growth Chamber|Duskmourn: House of Horror Commander|298|U||Land|||Simic Growth Chamber enters tapped.$When Simic Growth Chamber enters, return a land you control to its owner's hand.${T}: Add {G}{U}.|
+Smoldering Marsh|Duskmourn: House of Horror Commander|299|R||Land - Swamp Mountain|||({T}: Add {B} or {R}.)$Smoldering Marsh enters tapped unless you control two or more basic lands.|
+Spinerock Knoll|Duskmourn: House of Horror Commander|300|R||Land|||Hideaway 4$Spinerock Knoll enters tapped.${T}: Add {R}.${R}, {T}: You may play the exiled card without paying its mana cost if an opponent was dealt 7 or more damage this turn.|
+Sulfurous Springs|Duskmourn: House of Horror Commander|301|R||Land|||{T}: Add {C}.${T}: Add {B} or {R}. Sulfurous Springs deals 1 damage to you.|
Tainted Field|Duskmourn: House of Horror Commander|302|U||Land|||{T}: Add {C}.${T}: Add {W} or {B}. Activate only if you control a Swamp.|
Tainted Isle|Duskmourn: House of Horror Commander|303|U||Land|||{T}: Add {C}.${T}: Add {U} or {B}. Activate only if you control a Swamp.|
+Tainted Peak|Duskmourn: House of Horror Commander|304|U||Land|||{T}: Add {C}.${T}: Add {B} or {R}. Activate only if you control a Swamp.|
+Tainted Wood|Duskmourn: House of Horror Commander|305|U||Land|||{T}: Add {C}.${T}: Add {B} or {G}. Activate only if you control a Swamp.|
Tangled Islet|Duskmourn: House of Horror Commander|306|C||Land - Forest Island|||({T}: Add {G} or {U}.)$Tangled Islet enters tapped.|
Temple of Deceit|Duskmourn: House of Horror Commander|307|R||Land|||Temple of Deceit enters tapped.$When Temple of Deceit enters, scry 1.${T}: Add {U} or {B}.|
Temple of Enlightenment|Duskmourn: House of Horror Commander|308|R||Land|||Temple of Enlightenment enters tapped.$When Temple of Enlightenment enters, scry 1.${T}: Add {W} or {U}.|
+Temple of Malady|Duskmourn: House of Horror Commander|309|R||Land|||Temple of Malady enters tapped.$When Temple of Malady enters, scry 1.${T}: Add {B} or {G}.|
+Temple of Malice|Duskmourn: House of Horror Commander|310|R||Land|||Temple of Malice enters tapped.$When Temple of Malice enters, scry 1.${T}: Add {B} or {R}.|
Temple of Mystery|Duskmourn: House of Horror Commander|311|R||Land|||Temple of Mystery enters tapped.$When Temple of Mystery enters, scry 1.${T}: Add {G} or {U}.|
Temple of Silence|Duskmourn: House of Horror Commander|312|R||Land|||Temple of Silence enters tapped.$When Temple of Silence enters, scry 1.${T}: Add {W} or {B}.|
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.|
@@ -54786,8 +54903,15 @@ Thornwood Falls|Duskmourn: House of Horror Commander|314|C||Land|||Thornwood Fal
Thriving Heath|Duskmourn: House of Horror Commander|315|C||Land|||Thriving Heath enters tapped. As it enters, choose a color other than white.${T}: Add {W} or one mana of the chosen color.|
Thriving Isle|Duskmourn: House of Horror Commander|316|C||Land|||Thriving Isle enters tapped. As it enters, choose a color other than blue.${T}: Add {U} or one mana of the chosen color.|
Thriving Moor|Duskmourn: House of Horror Commander|317|C||Land|||Thriving Moor enters tapped. As it enters, choose a color other than black.${T}: Add {B} or one mana of the chosen color.|
+Tranquil Thicket|Duskmourn: House of Horror Commander|318|C||Land|||Tranquil Thicket enters tapped.${T}: Add {G}.$Cycling {G}|
+Tree of Tales|Duskmourn: House of Horror Commander|319|C||Artifact Land|||{T}: Add {G}.|
+Twilight Mire|Duskmourn: House of Horror Commander|320|R||Land|||{T}: Add {C}.${B/G}, {T}: Add {B}{B}, {B}{G}, or {G}{G}.|
Underground River|Duskmourn: House of Horror Commander|321|R||Land|||{T}: Add {C}.${T}: Add {U} or {B}. Underground River deals 1 damage to you.|
+Vault of Whispers|Duskmourn: House of Horror Commander|322|C||Artifact Land|||{T}: Add {B}.|
Vineglimmer Snarl|Duskmourn: House of Horror Commander|323|R||Land|||As Vineglimmer Snarl enters, you may reveal a Forest or Island card from your hand. If you don't, Vineglimmer Snarl enters tapped.${T}: Add {G} or {U}.|
+Viridescent Bog|Duskmourn: House of Horror Commander|324|R||Land|||{1}, {T}: Add {B}{G}.|
+Witch's Clinic|Duskmourn: House of Horror Commander|325|R||Land|||{T}: Add {C}.${2}, {T}: Target commander gains lifelink until end of turn.|
+Woodland Cemetery|Duskmourn: House of Horror Commander|326|R||Land|||Woodland Cemetery enters tapped unless you control a Swamp or a Forest.${T}: Add {B} or {G}.|
Yavimaya Coast|Duskmourn: House of Horror Commander|327|R||Land|||{T}: Add {C}.${T}: Add {G} or {U}. Yavimaya Coast deals 1 damage to you.|
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}|