diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index e016bd951f8..799a5b06142 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -2436,13 +2436,23 @@ public class GameAction { damageMap.triggerExcessDamage(isCombat, lethalDamage, game, cause, lkiCache); // lose life simultaneously - if (isCombat) { - for (Player p : game.getPlayers()) { - p.dealCombatDamage(); + Map lifeLostAllDamageMap = Maps.newHashMap(); + for (Player p : game.getPlayers()) { + int lost = p.processDamage(); + if (lost > 0) { + lifeLostAllDamageMap.put(p, lost); } + } + + if (isCombat) { game.getTriggerHandler().runWaitingTriggers(); } + if (!lifeLostAllDamageMap.isEmpty()) { // Run triggers if any player actually lost life + final Map runParams = AbilityKey.mapFromPIMap(lifeLostAllDamageMap); + game.getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams, false); + } + if (cause != null) { // Remember objects as needed final Card sourceLKI = game.getChangeZoneLKIInfo(cause.getHostCard()); diff --git a/forge-game/src/main/java/forge/game/ability/AbilityKey.java b/forge-game/src/main/java/forge/game/ability/AbilityKey.java index 9dd6cccaa9b..3722b796c20 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityKey.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityKey.java @@ -1,13 +1,12 @@ package forge.game.ability; -import java.util.EnumMap; -import java.util.Map; - import forge.game.GameEntity; import forge.game.card.Card; - import forge.game.player.Player; +import java.util.EnumMap; +import java.util.Map; + /** * Keys for Ability parameter maps. */ @@ -84,6 +83,7 @@ public enum AbilityKey { LastStateGraveyard("LastStateGraveyard"), LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged LifeGained("LifeGained"), + Map("Map"), Mana("Mana"), MergedCards("MergedCards"), Mode("Mode"), @@ -193,4 +193,11 @@ public enum AbilityKey { runParams.put(Affected, gameEntity); return runParams; } + + public static Map mapFromPIMap(Map map) { + final Map runParams = newMap(); + + runParams.put(Map, map); + return runParams; + } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseCardEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseCardEffect.java index c40b0273535..87719ec938b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseCardEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChooseCardEffect.java @@ -125,9 +125,7 @@ public class ChooseCardEffect extends SpellAbilityEffect { for (final String type : partyTypes) { CardCollection valids = CardLists.filter(p.getCardsIn(ZoneType.Battlefield), CardPredicates.isType(type)); - for (Card alreadyChosen : chosen) { - valids.remove(alreadyChosen); - } + valids.removeAll(chosen); if (!valids.isEmpty()) { final String prompt = Localizer.getInstance().getMessage("lblChoose") + " " + Lang.nounWithNumeralExceptOne(1, type); diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeEffect.java index 5927cd04d8a..c179f83b10d 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeEffect.java @@ -1,11 +1,15 @@ package forge.game.ability.effects; -import java.util.List; - +import com.google.common.collect.Maps; +import forge.game.ability.AbilityKey; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.trigger.TriggerType; + +import java.util.List; +import java.util.Map; public class LifeExchangeEffect extends SpellAbilityEffect { @@ -56,17 +60,27 @@ public class LifeExchangeEffect extends SpellAbilityEffect { source.addRemembered(diff); } + final Map lossMap = Maps.newHashMap(); if ((life1 > life2) && p1.canLoseLife() && p2.canGainLife()) { final int diff = life1 - life2; - p1.loseLife(diff, false, false); + final int lost = p1.loseLife(diff, false, false); p2.gainLife(diff, source, sa); + if (lost > 0) { + lossMap.put(p1, lost); + } } else if ((life2 > life1) && p2.canLoseLife() && p1.canGainLife()) { final int diff = life2 - life1; - p2.loseLife(diff, false, false); + final int lost = p2.loseLife(diff, false, false); p1.gainLife(diff, source, sa); + if (lost > 0) { + lossMap.put(p2, lost); + } } else { - // they are equal, so nothing to do + // they are equal or can't be exchanged, so nothing to do + } + if (!lossMap.isEmpty()) { // Run triggers if any player actually lost life + final Map runParams = AbilityKey.mapFromPIMap(lossMap); + source.getGame().getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams, false); } } - } diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java index c3d8c5359ca..0f4e75fb715 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeExchangeVariantEffect.java @@ -1,13 +1,17 @@ package forge.game.ability.effects; -import java.util.List; - +import com.google.common.collect.Maps; import forge.game.Game; +import forge.game.ability.AbilityKey; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.event.GameEventCardStatsChanged; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.trigger.TriggerType; + +import java.util.List; +import java.util.Map; public class LifeExchangeVariantEffect extends SpellAbilityEffect { @@ -68,9 +72,16 @@ public class LifeExchangeVariantEffect extends SpellAbilityEffect { if ((pLife > num) && p.canLoseLife()) { final int diff = pLife - num; - p.loseLife(diff, false, false); + final int lost = p.loseLife(diff, false, false); source.addNewPT(power, toughness, timestamp, 0); game.fireEvent(new GameEventCardStatsChanged(source)); + + if (lost > 0) { // Run triggers if player actually lost life + final Map lossMap = Maps.newHashMap(); + lossMap.put(p, lost); + final Map runParams = AbilityKey.mapFromPIMap(lossMap); + source.getGame().getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams, false); + } } else if ((num > pLife) && p.canGainLife()) { final int diff = num - pLife; p.gainLife(diff, source, sa); diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java index a2afc3381ea..35bda39450a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java @@ -1,12 +1,17 @@ package forge.game.ability.effects; +import com.google.common.collect.Maps; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.trigger.TriggerType; import forge.util.Lang; import org.apache.commons.lang3.StringUtils; +import java.util.Map; + public class LifeLoseEffect extends SpellAbilityEffect { /* (non-Javadoc) @@ -41,13 +46,23 @@ public class LifeLoseEffect extends SpellAbilityEffect { final int lifeAmount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("LifeAmount"), sa); + final Map lossMap = Maps.newHashMap(); for (final Player p : getTargetPlayers(sa)) { if (!p.isInGame()) { continue; } - lifeLost += p.loseLife(lifeAmount, false, false); + final int lost = p.loseLife(lifeAmount, false, false); + if (lost > 0) { + lossMap.put(p, lost); + } + lifeLost += lost; } sa.setSVar("AFLifeLost", "Number$" + lifeLost); + + if (!lossMap.isEmpty()) { // Run triggers if any player actually lost life + final Map runParams = AbilityKey.mapFromPIMap(lossMap); + sa.getHostCard().getGame().getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams, false); + } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java index 82fbb2d2d44..f1b709fb688 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeSetEffect.java @@ -1,16 +1,22 @@ package forge.game.ability.effects; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import forge.game.ability.AbilityKey; +import forge.game.ability.AbilityUtils; +import forge.game.ability.SpellAbilityEffect; +import forge.game.card.Card; +import forge.game.player.Player; +import forge.game.player.PlayerCollection; +import forge.game.player.PlayerController; +import forge.game.spellability.SpellAbility; +import forge.game.trigger.TriggerType; +import forge.util.Lang; +import forge.util.Localizer; + import java.util.ArrayList; import java.util.List; - -import com.google.common.collect.Lists; - -import forge.game.ability.AbilityUtils; -import forge.game.ability.SpellAbilityEffect; -import forge.game.player.Player; -import forge.game.player.PlayerCollection; -import forge.game.spellability.SpellAbility; -import forge.util.Localizer; +import java.util.Map; public class LifeSetEffect extends SpellAbilityEffect { @@ -19,10 +25,38 @@ public class LifeSetEffect extends SpellAbilityEffect { */ @Override public void resolve(SpellAbility sa) { + final Card source = sa.getHostCard(); final boolean redistribute = sa.hasParam("Redistribute"); - final int lifeAmount = redistribute ? 0 : AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("LifeAmount"), sa); + final int lifeAmount = redistribute ? 0 : AbilityUtils.calculateAmount(source, sa.getParam("LifeAmount"), sa); final List lifetotals = new ArrayList<>(); - final PlayerCollection players = getTargetPlayers(sa); + final PlayerController pc = sa.getActivatingPlayer().getController(); + + PlayerCollection players = new PlayerCollection(); + if (sa.hasParam("PlayerChoices")) { + PlayerCollection choices = AbilityUtils.getDefinedPlayers(source, sa.getParam("PlayerChoices"), sa); + int n = 1; + int min = 1; + if (sa.hasParam("ChoiceAmount")) { + if (sa.getParam("ChoiceAmount").equals("Any")) { + n = choices.size(); + min = 0; + } else { + n = AbilityUtils.calculateAmount(source, sa.getParam("ChoiceAmount"), sa); + min = n; + } + } + final String prompt = sa.hasParam("ChoicePrompt") ? sa.getParam("ChoicePrompt") : + Localizer.getInstance().getMessage("lblChoosePlayer"); + List chosen = pc.chooseEntitiesForEffect(choices, min, n, null, sa, prompt, null, + null); + players.addAll(chosen); + } else { + players = getTargetPlayers(sa); + } + + if (players.isEmpty()) { + return; + } if (redistribute) { for (final Player p : players) { @@ -33,23 +67,33 @@ public class LifeSetEffect extends SpellAbilityEffect { } } + final Map lossMap = Maps.newHashMap(); for (final Player p : players.threadSafeIterable()) { if (!p.isInGame()) { continue; } + final int preLife = p.getLife(); if (!redistribute) { p.setLife(lifeAmount, sa); } else { List validChoices = getDistribution(players, true, lifetotals); - int life = sa.getActivatingPlayer().getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblLifeTotal") + ": " + p, validChoices, p); + int life = pc.chooseNumber(sa, Localizer.getInstance().getMessage("lblLifeTotal") + ": " + p, validChoices, p); p.setLife(life, sa); lifetotals.remove((Integer) life); players.remove(p); } + final int diff = preLife - p.getLife(); + if (diff > 0) { + lossMap.put(p, diff); + } + } + if (!lossMap.isEmpty()) { // Run triggers if any player actually lost life + final Map runParams = AbilityKey.mapFromPIMap(lossMap); + source.getGame().getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams, false); } } - private static List getDistribution(PlayerCollection players, boolean top, List remainingChoices) { + private static List getDistribution(List players, boolean top, List remainingChoices) { // distribution was successful if (players.isEmpty()) { // carry signal back @@ -95,23 +139,18 @@ public class LifeSetEffect extends SpellAbilityEffect { */ @Override protected String getStackDescription(SpellAbility sa) { + if (sa.hasParam("Redistribute")) { + if (sa.hasParam("SpellDescription")) { + return sa.getParam("SpellDescription"); + } else { + return ("Please add StackDescription or SpellDescription for Redistribute in LifeSetEffect."); + } + } final StringBuilder sb = new StringBuilder(); final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("LifeAmount"), sa); - final boolean redistribute = sa.hasParam("Redistribute"); - List tgtPlayers = getTargetPlayers(sa); - if (!redistribute) { - for (final Player player : tgtPlayers) { - sb.append(player).append(" "); - } - sb.append("life total becomes ").append(amount).append("."); - } else { - sb.append("Redistribute "); - for (final Player player : tgtPlayers) { - sb.append(player).append(" "); - } - sb.append("life totals."); - } + sb.append(Lang.joinHomogenous(getTargetPlayers(sa))); + sb.append(" life total becomes ").append(amount).append("."); return sb.toString(); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java index d8d5153e2f3..25d8f308700 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java @@ -4,18 +4,21 @@ import java.util.*; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import forge.GameCommand; import forge.card.CardType; import forge.game.Game; import forge.game.GameEntityCounterTable; import forge.game.GameObject; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.*; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityStackInstance; +import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; import forge.util.collect.FCollection; @@ -81,9 +84,12 @@ public class RepeatEachEffect extends SpellAbilityEffect { if (sa.hasParam("ChangeZoneTable")) { sa.setChangeZoneTable(new CardZoneTable()); } + if (sa.hasParam("LoseLifeMap")) { + sa.setLoseLifeMap(Maps.newHashMap()); + } if (loopOverCards) { - if (sa.hasParam("ChooseOrder") && repeatCards.size() >= 2) { + if (sa.hasParam("ChooseOrder") && repeatCards.size() > 1) { final Player chooser = sa.getParam("ChooseOrder").equals("True") ? player : AbilityUtils.getDefinedPlayers(source, sa.getParam("ChooseOrder"), sa).get(0); repeatCards = chooser.getController().orderMoveToZoneList(repeatCards, ZoneType.None, sa); @@ -207,5 +213,13 @@ public class RepeatEachEffect extends SpellAbilityEffect { sa.getChangeZoneTable().triggerChangesZoneAll(game, sa); sa.setChangeZoneTable(null); } + if (sa.hasParam("LoseLifeMap")) { + Map lossMap = sa.getLoseLifeMap(); + if (!lossMap.isEmpty()) { + final Map runParams2 = AbilityKey.mapFromPIMap(lossMap); + game.getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams2, false); + } + sa.setLoseLifeMap(null); + } } } diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 5d45f6ecfa4..f71a724b424 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -680,7 +680,7 @@ public class CardFactory { List creatureTypes = null; final CardCloneStates result = new CardCloneStates(in, sa); - final String newName = sa.getParamOrDefault("NewName", null); + final String newName = sa.getParam("NewName"); ColorSet colors = null; if (sa.hasParam("AddTypes")) { diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 1d662f1a684..0729f6de972 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -1274,8 +1274,13 @@ public class CardView extends GameEntityView { String rulesText = null; if (type.isVanguard() && rules != null) { - rulesText = "Hand Modifier: " + rules.getHand() + - "\r\nLife Modifier: " + rules.getLife(); + boolean decHand = rules.getHand() < 0; + boolean decLife = rules.getLife() < 0; + String handSize = Localizer.getInstance().getMessageorUseDefault("lblHandSize", "Hand Size") + + (!decHand ? ": +" : ": ") + rules.getHand(); + String startingLife = Localizer.getInstance().getMessageorUseDefault("lblStartingLife", "Starting Life") + + (!decLife ? ": +" : ": ") + rules.getLife(); + rulesText = handSize + "\r\n" + startingLife; } set(TrackableProperty.RulesText, rulesText); } diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index b0e37ace58b..70a1796f0d7 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -465,13 +465,21 @@ public class PhaseHandler implements java.io.Serializable { throw new IllegalStateException("Phase.nextPhase() is called, but Stack isn't empty."); } + final Map lossMap = Maps.newHashMap(); for (Player p : game.getPlayers()) { int burn = p.getManaPool().clearPool(true).size(); if (p.getManaPool().hasBurn()) { - p.loseLife(burn, false, true); + final int lost = p.loseLife(burn, false, true); + if (lost > 0) { + lossMap.put(p, lost); + } } } + if (!lossMap.isEmpty()) { // Run triggers if any player actually lost life + final Map runLifeLostParams = AbilityKey.mapFromPIMap(lossMap); + game.getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runLifeLostParams, false); + } switch (phase) { case UPKEEP: diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index fbfe4c1a214..364a0ab174b 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -620,13 +620,26 @@ public class Player extends GameEntity implements Comparable { return false; } - loseLife(lifePayment, false, false); + final int lost = loseLife(lifePayment, false, false); cause.setPaidLife(lifePayment); // Run triggers final Map runParams = AbilityKey.mapFromPlayer(this); runParams.put(AbilityKey.LifeAmount, lifePayment); game.getTriggerHandler().runTrigger(TriggerType.PayLife, runParams, false); + if (lost > 0) { // Run triggers if player actually lost life + boolean runAll = false; + Map lossMap = cause.getLoseLifeMap(); + if (lossMap == null) { + lossMap = Maps.newHashMap(); + runAll = true; + } + lossMap.put(this, lost); + if (runAll) { + final Map runParams2 = AbilityKey.mapFromPIMap(lossMap); + game.getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams2, false); + } + } return true; } @@ -691,12 +704,7 @@ public class Player extends GameEntity implements Comparable { } else if (!hasKeyword("Damage doesn't cause you to lose life.")) { // rule 118.2. Damage dealt to a player normally causes that player to lose that much life. - if (isCombat) { - // currently all abilities treat is as single event - simultaneousDamage += amount; - } else { - loseLife(amount, true, false); - } + simultaneousDamage += amount; } if (isCombat) { @@ -829,9 +837,10 @@ public class Player extends GameEntity implements Comparable { return restDamage; } - public final void dealCombatDamage() { - loseLife(simultaneousDamage, true, false); + public final int processDamage() { + int lost = loseLife(simultaneousDamage, true, false); simultaneousDamage = 0; + return lost; } /** diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java index 2b40be93cfc..0a4371621ee 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceToken.java @@ -39,12 +39,6 @@ public class ReplaceToken extends ReplacementEffect { return false; } - /*/ - if (!matchesValidParam("ValidToken", runParams.get(AbilityKey.Token))) { - return false; - } - //*/ - if (filterAmount((TokenCreateTable) runParams.get(AbilityKey.Token)) <= 0) { return false; } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 66ab466585d..1294a05c7b4 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -66,7 +66,6 @@ import forge.game.staticability.StaticAbilityCastWithFlash; import forge.game.staticability.StaticAbilityMustTarget; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; -import forge.game.trigger.WrappedAbility; import forge.game.zone.ZoneType; import forge.util.Aggregates; import forge.util.CardTranslation; @@ -186,6 +185,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private CardDamageMap preventMap; private GameEntityCounterTable counterTable; private CardZoneTable changeZoneTable; + private Map loseLifeMap; public CardCollection getLastStateBattlefield() { return lastStateBattlefield; @@ -1843,14 +1843,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit */ public CardCollectionView findTargetedCards() { // First search for targeted cards associated with current ability - if (targetChosen.isTargetingAnyCard()) { - return targetChosen.getTargetCards(); + if (getTargets().isTargetingAnyCard()) { + return getTargets().getTargetCards(); } // Next search for source cards of targeted SAs associated with current ability - if (targetChosen.isTargetingAnySpell()) { + if (getTargets().isTargetingAnySpell()) { CardCollection res = new CardCollection(); - for (final SpellAbility ability : targetChosen.getTargetSpells()) { + for (final SpellAbility ability : getTargets().getTargetSpells()) { res.add(ability.getHostCard()); } return res; @@ -1872,16 +1872,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public SpellAbility getSATargetingCard() { - return targetChosen.isTargetingAnyCard() ? this : getParentTargetingCard(); + return getTargets().isTargetingAnyCard() ? this : getParentTargetingCard(); } public SpellAbility getParentTargetingCard() { SpellAbility parent = getParent(); - if (parent instanceof WrappedAbility) { - parent = ((WrappedAbility) parent).getWrappedAbility(); - } while (parent != null) { - if (parent.targetChosen.isTargetingAnyCard()) { + if (parent.getTargets().isTargetingAnyCard()) { return parent; } parent = parent.getParent(); @@ -1890,13 +1887,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public SpellAbility getSATargetingSA() { - return targetChosen.isTargetingAnySpell() ? this : getParentTargetingSA(); + return getTargets().isTargetingAnySpell() ? this : getParentTargetingSA(); } public SpellAbility getParentTargetingSA() { SpellAbility parent = getParent(); while (parent != null) { - if (parent.targetChosen.isTargetingAnySpell()) + if (parent.getTargets().isTargetingAnySpell()) return parent; parent = parent.getParent(); } @@ -1904,7 +1901,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public SpellAbility getSATargetingPlayer() { - return targetChosen.isTargetingAnyPlayer() ? this : getParentTargetingPlayer(); + return getTargets().isTargetingAnyPlayer() ? this : getParentTargetingPlayer(); } public SpellAbility getParentTargetingPlayer() { @@ -2357,6 +2354,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return null; } + public Map getLoseLifeMap() { + if (loseLifeMap != null) { + return loseLifeMap; + } else if (getParent() != null) { + return getParent().getLoseLifeMap(); + } + return null; + } + public void setDamageMap(final CardDamageMap map) { damageMap = map; } @@ -2369,6 +2375,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public void setChangeZoneTable(final CardZoneTable table) { changeZoneTable = table; } + public void setLoseLifeMap(final Map map) { + loseLifeMap = map; + } public SpellAbility getOriginalAbility() { return grantorOriginal; diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerLifeLostAll.java b/forge-game/src/main/java/forge/game/trigger/TriggerLifeLostAll.java new file mode 100644 index 00000000000..c64ab892e02 --- /dev/null +++ b/forge-game/src/main/java/forge/game/trigger/TriggerLifeLostAll.java @@ -0,0 +1,117 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.game.trigger; + +import com.google.common.collect.Maps; +import forge.game.ability.AbilityKey; +import forge.game.ability.AbilityUtils; +import forge.game.card.Card; +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; +import forge.util.Expressions; + +import java.util.Map; + +/** + *

+ * Trigger_LifeLostAll class. + *

+ * + * 4/27/2023 - this trigger is written for only Ob Nixilis, Captive Kingpin – any future uses will probably need + * additional logic + * + * @author Forge (Northmoc) + * @version $Id$ + */ +public class TriggerLifeLostAll extends Trigger { + + /** + *

+ * Constructor for Trigger_LifeLost. + *

+ * + * @param params + * a {@link java.util.HashMap} object. + * @param host + * a {@link forge.game.card.Card} object. + * @param intrinsic + * the intrinsic + */ + public TriggerLifeLostAll(final Map params, final Card host, final boolean intrinsic) { + super(params, host, intrinsic); + } + + /** {@inheritDoc} + * @param runParams*/ + @Override + public final boolean performTest(final Map runParams) { + final Map testMap = filteredMap((Map) runParams.get(AbilityKey.Map)); + if (testMap.isEmpty()) { + return false; + } + return true; + } + + /** {@inheritDoc} */ + @Override + public final void setTriggeringObjects(final SpellAbility sa, Map runParams) { + final Map map = (Map) runParams.get(AbilityKey.Map); + + sa.setTriggeringObject(AbilityKey.Map, filteredMap(map)); + sa.setTriggeringObject(AbilityKey.Player, map.keySet()); + } + + @Override + public String getImportantStackObjects(SpellAbility sa) { + StringBuilder sb = new StringBuilder(); + final Map map = (Map) sa.getTriggeringObject(AbilityKey.Map); + int n = 0; + for (final Map.Entry e : map.entrySet()) { + sb.append(e.getKey()).append(": ").append(e.getValue()); + n++; + if (map.size() > n) { + sb.append(", "); + } + } + return sb.toString(); + } + + private Map filteredMap(Map map) { + Map passMap = Maps.newHashMap(); + if (hasParam("ValidPlayer")) { + for (final Map.Entry e : map.entrySet()) { + if (matchesValidParam("ValidPlayer", e.getKey())) { + passMap.put(e.getKey(), e.getValue()); + } + } + if (passMap.isEmpty()) { + return passMap; + } + } + if (hasParam("ValidAmountEach")) { + final String comp = getParam("ValidAmountEach"); + final int value = AbilityUtils.calculateAmount(getHostCard(), comp.substring(2), this); + for (final Map.Entry e : passMap.entrySet()) { + if (!Expressions.compare(e.getValue(), comp.substring(0, 2), value)) { + return Maps.newHashMap(); + } + } + } + return passMap; + } +} diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerType.java b/forge-game/src/main/java/forge/game/trigger/TriggerType.java index 990af336a5b..90b6f1f21e6 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerType.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerType.java @@ -83,6 +83,7 @@ public enum TriggerType { LandPlayed(TriggerLandPlayed.class), LifeGained(TriggerLifeGained.class), LifeLost(TriggerLifeLost.class), + LifeLostAll(TriggerLifeLostAll.class), LosesGame(TriggerLosesGame.class), ManaAdded(TriggerManaAdded.class), MilledAll(TriggerMilledAll.class), diff --git a/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.atlas b/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.atlas index 53e8ad00ba8..f31b3130f98 100644 --- a/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.atlas +++ b/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.atlas @@ -41,4 +41,19 @@ MageTower size: 26, 49 Skep xy: 110,281 - size: 37, 33 \ No newline at end of file + size: 37, 33 +MageTowerBlue + xy: 2,327 + size: 32, 32 +MageTowerRed + xy: 36,328 + size: 32, 32 +MageTowerBlack + xy: 63,328 + size: 32, 32 +MageTowerGreen + xy: 92,328 + size: 32, 32 +MageTowerWhite + xy: 121,328 + size: 32, 32 \ No newline at end of file diff --git a/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.png b/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.png index 27ff37c3a25..0ef3a70fc38 100644 Binary files a/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.png and b/forge-gui/res/adventure/common/maps/tileset/buildingsbosses.png differ diff --git a/forge-gui/res/adventure/common/world/points_of_interest.json b/forge-gui/res/adventure/common/world/points_of_interest.json index 118acbf1ece..3d404110e68 100644 --- a/forge-gui/res/adventure/common/world/points_of_interest.json +++ b/forge-gui/res/adventure/common/world/points_of_interest.json @@ -2068,7 +2068,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerRed", "map": "../common/maps/map/magetower/magetower_1.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2084,7 +2084,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlack", "map": "../common/maps/map/magetower/magetower_2.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2100,7 +2100,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerRed", "map": "../common/maps/map/magetower/magetower_3.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2116,7 +2116,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerWhite", "map": "../common/maps/map/magetower/magetower_4.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2132,7 +2132,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerGreen", "map": "../common/maps/map/magetower/magetower_5.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2148,7 +2148,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlack", "map": "../common/maps/map/magetower/magetower_6.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2163,8 +2163,8 @@ "name": "MageTowerC8", "type": "dungeon", "count": 3, - "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "spriteAtlas": "../common/maps/tileset/buildings.atlas", + "sprite": "MageTowerBlue", "map": "../common/maps/map/magetower/magetower_8.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2180,7 +2180,7 @@ "type": "dungeon", "count": 1, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlue", "map": "../common/maps/map/magetower/magetower_13.tmx", "radiusFactor": 0.2, "questTags": [ @@ -2196,7 +2196,7 @@ "type": "dungeon", "count": 3, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlue", "map": "../common/maps/map/magetower/magetower_14.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2212,7 +2212,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlue", "map": "../common/maps/map/magetower/magetower_1.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2228,7 +2228,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlack", "map": "../common/maps/map/magetower/magetower_2.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2244,7 +2244,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerRed", "map": "../common/maps/map/magetower/magetower_3.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2260,7 +2260,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerWhite", "map": "../common/maps/map/magetower/magetower_4.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2276,7 +2276,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerGreen", "map": "../common/maps/map/magetower/magetower_5.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2292,7 +2292,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlack", "map": "../common/maps/map/magetower/magetower_6.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2308,7 +2308,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlue", "map": "../common/maps/map/magetower/magetower_8.tmx", "radiusFactor": 0.8, "questTags": [ @@ -2324,7 +2324,7 @@ "type": "dungeon", "count": 2, "spriteAtlas": "../common/maps/tileset/buildingsbosses.atlas", - "sprite": "MageTower", + "sprite": "MageTowerBlue", "map": "../common/maps/map/magetower/magetower_14.tmx", "radiusFactor": 0.8, "questTags": [ diff --git a/forge-gui/res/cardsfolder/a/anathemancer.txt b/forge-gui/res/cardsfolder/a/anathemancer.txt index 8dbd98abf0a..214e982028e 100644 --- a/forge-gui/res/cardsfolder/a/anathemancer.txt +++ b/forge-gui/res/cardsfolder/a/anathemancer.txt @@ -4,7 +4,6 @@ Types:Creature Zombie Wizard PT:2/2 K:Unearth:5 B R T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDamage | TriggerDescription$ When CARDNAME enters the battlefield, it deals damage to target player equal to the number of nonbasic lands that player controls. -SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Player | TgtPrompt$ Select target player | NumDmg$ X | RememberTargets$ True | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:X:Count$Valid Land.nonBasic+RememberedPlayerCtrl +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Player | TgtPrompt$ Select target player | NumDmg$ X +SVar:X:Count$Valid Land.nonBasic+TargetedPlayerCtrl Oracle:When Anathemancer enters the battlefield, it deals damage to target player equal to the number of nonbasic lands that player controls.\nUnearth {5}{B}{R} ({5}{B}{R}: Return this card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step or if it would leave the battlefield. Unearth only as a sorcery.) diff --git a/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt b/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt index 619c0c388b8..79517835716 100644 --- a/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt +++ b/forge-gui/res/cardsfolder/a/aurelia_exemplar_of_justice.txt @@ -5,9 +5,8 @@ PT:2/5 K:Flying K:Mentor T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ DBPump | TriggerDescription$ At the beginning of combat on your turn, choose up to one target creature you control. Until end of turn, that creature gets +2/+0, gains trample if it's red, and gains vigilance if it's white. -SVar:DBPump:DB$ Pump | ValidTgts$ Creature.YouCtrl | NumAtt$ 2 | RememberTargets$ True | SubAbility$ DBPump1 -SVar:DBPump1:DB$ Pump | Defined$ Remembered | KW$ Trample | ConditionDefined$ Remembered | ConditionPresent$ Card.Red | SubAbility$ DBPump2 -SVar:DBPump2:DB$ Pump | Defined$ Remembered | KW$ Vigilance | ConditionDefined$ Remembered | ConditionPresent$ Card.White | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:DBPump:DB$ Pump | ValidTgts$ Creature.YouCtrl | NumAtt$ 2 | SubAbility$ DBPump1 +SVar:DBPump1:DB$ Pump | Defined$ Targeted | KW$ Trample | ConditionDefined$ Targeted | ConditionPresent$ Card.Red | SubAbility$ DBPump2 +SVar:DBPump2:DB$ Pump | Defined$ Targeted | KW$ Vigilance | ConditionDefined$ Targeted | ConditionPresent$ Card.White DeckHas:Ability$Counters Oracle:Flying\nMentor (Whenever this creature attacks, put a +1/+1 counter on target attacking creature with lesser power.)\nAt the beginning of combat on your turn, choose up to one target creature you control. Until end of turn, that creature gets +2/+0, gains trample if it's red, and gains vigilance if it's white. diff --git a/forge-gui/res/cardsfolder/e/echoing_courage.txt b/forge-gui/res/cardsfolder/e/echoing_courage.txt index 85f57facf19..09cf537a493 100644 --- a/forge-gui/res/cardsfolder/e/echoing_courage.txt +++ b/forge-gui/res/cardsfolder/e/echoing_courage.txt @@ -1,7 +1,6 @@ Name:Echoing Courage ManaCost:1 G Types:Instant -A:SP$ Pump | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SubAbility$ DBPumpAll | RememberTargets$ True | ForgetOtherTargets$ True | SpellDescription$ Target creature and all other creatures with the same name as that creature get +2/+2 until end of turn. -SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Remembered.Creature+Other+sameName | NumAtt$ +2 | NumDef$ +2 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:SP$ Pump | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | SubAbility$ DBPumpAll | SpellDescription$ Target creature and all other creatures with the same name as that creature get +2/+2 until end of turn. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Targeted.Creature+Other+sameName | NumAtt$ +2 | NumDef$ +2 Oracle:Target creature and all other creatures with the same name as that creature get +2/+2 until end of turn. diff --git a/forge-gui/res/cardsfolder/e/echoing_decay.txt b/forge-gui/res/cardsfolder/e/echoing_decay.txt index adbc2125a50..1f89a20abf3 100644 --- a/forge-gui/res/cardsfolder/e/echoing_decay.txt +++ b/forge-gui/res/cardsfolder/e/echoing_decay.txt @@ -1,8 +1,7 @@ Name:Echoing Decay ManaCost:1 B Types:Instant -A:SP$ Pump | Cost$ 1 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | RememberTargets$ True | NumAtt$ -2 | NumDef$ -2 | SubAbility$ DBPumpAll | SpellDescription$ Target creature and all other creatures with the same name as that creature get -2/-2 until end of turn. -SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Remembered.sameName+Other | NumAtt$ -2 | NumDef$ -2 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:SP$ Pump | Cost$ 1 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -2 | NumDef$ -2 | SubAbility$ DBPumpAll | SpellDescription$ Target creature and all other creatures with the same name as that creature get -2/-2 until end of turn. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Targeted.sameName+Other | NumAtt$ -2 | NumDef$ -2 AI:RemoveDeck:All Oracle:Target creature and all other creatures with the same name as that creature get -2/-2 until end of turn. diff --git a/forge-gui/res/cardsfolder/e/elvish_healer.txt b/forge-gui/res/cardsfolder/e/elvish_healer.txt index b173d1617ce..eab2b928057 100644 --- a/forge-gui/res/cardsfolder/e/elvish_healer.txt +++ b/forge-gui/res/cardsfolder/e/elvish_healer.txt @@ -2,9 +2,8 @@ Name:Elvish Healer ManaCost:2 W Types:Creature Elf Cleric PT:1/2 -A:AB$ PreventDamage | Cost$ T | ValidTgts$ Any | Amount$ X | RememberTargets$ True | SubAbility$ DBCleanup | SpellDescription$ Prevent the next 1 damage that would be dealt to any target this turn. If it's a green creature, prevent the next 2 damage instead. -SVar:X:Remembered$Valid Creature.Green/Plus.1 -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ PreventDamage | Cost$ T | ValidTgts$ Any | Amount$ X | SpellDescription$ Prevent the next 1 damage that would be dealt to any target this turn. If it's a green creature, prevent the next 2 damage instead. +SVar:X:Targeted$Valid Creature.Green/Plus.1 AI:RemoveDeck:Random DeckHints:Color$Green Oracle:{T}: Prevent the next 1 damage that would be dealt to any target this turn. If it's a green creature, prevent the next 2 damage instead. diff --git a/forge-gui/res/cardsfolder/f/fatal_lore.txt b/forge-gui/res/cardsfolder/f/fatal_lore.txt index 0260db54ff6..fd86a53e4d7 100644 --- a/forge-gui/res/cardsfolder/f/fatal_lore.txt +++ b/forge-gui/res/cardsfolder/f/fatal_lore.txt @@ -4,6 +4,6 @@ Types:Sorcery A:SP$ Charm | Cost$ 2 B B | Chooser$ Opponent | Choices$ DrawThree,DestroyAndDraw SVar:DrawThree:DB$ Draw | NumCards$ 3 | Defined$ You | SpellDescription$ You draw three cards. SVar:DestroyAndDraw:DB$ Destroy | ValidTgts$ Creature.ChosenCtrl | TgtPrompt$ Select target creature | TargetMin$ 0 | TargetMax$ 2 | NoRegen$ True | SpellDescription$ You destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated. | SubAbility$ ChooserDraws -SVar:ChooserDraws:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer +SVar:ChooserDraws:DB$ Draw | NumCards$ 3 | Defined$ ChosenPlayer | UpTo$ True AI:RemoveDeck:All Oracle:An opponent chooses one —\n• You draw three cards.\n• You destroy up to two target creatures that player controls. They can't be regenerated. That player draws up to three cards. diff --git a/forge-gui/res/cardsfolder/f/forge_devil.txt b/forge-gui/res/cardsfolder/f/forge_devil.txt index b7b7cdcbce5..27ffd445a94 100644 --- a/forge-gui/res/cardsfolder/f/forge_devil.txt +++ b/forge-gui/res/cardsfolder/f/forge_devil.txt @@ -3,6 +3,7 @@ ManaCost:R Types:Creature Devil PT:1/1 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDealDamage | TriggerDescription$ When CARDNAME enters the battlefield, it deals 1 damage to target creature and 1 damage to you. -SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | SubAbility$ DBDamageYou -SVar:DBDamageYou:DB$ DealDamage | Defined$ You | NumDmg$ 1 +SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | DamageMap$ True | SubAbility$ DBDamageYou +SVar:DBDamageYou:DB$ DealDamage | Defined$ You | NumDmg$ 1 | SubAbility$ DBDamageResolve +SVar:DBDamageResolve:DB$ DamageResolve Oracle:When Forge Devil enters the battlefield, it deals 1 damage to target creature and 1 damage to you. diff --git a/forge-gui/res/cardsfolder/h/hordewing_skaab.txt b/forge-gui/res/cardsfolder/h/hordewing_skaab.txt index e1e46e616b8..60827464684 100644 --- a/forge-gui/res/cardsfolder/h/hordewing_skaab.txt +++ b/forge-gui/res/cardsfolder/h/hordewing_skaab.txt @@ -4,7 +4,7 @@ Types:Creature Zombie Horror PT:3/3 K:Flying S:Mode$ Continuous | Affected$ Zombie.YouCtrl+Other | AddKeyword$ Flying | Description$ Other Zombies you control have flying. -T:Mode$ DamageAll | ValidSource$ Creature.Zombie+YouCtrl | ValidTarget$ Player.Opponent | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever one or more Zombies you control deal combat damage to one or more of your opponents, you may draw cards equal to the number of opponents dealt damage this way. If you do, discard that many cards. +T:Mode$ DamageAll | ValidSource$ Creature.Zombie+YouCtrl | ValidTarget$ Opponent | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever one or more Zombies you control deal combat damage to one or more of your opponents, you may draw cards equal to the number of opponents dealt damage this way. If you do, discard that many cards. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X | RememberDrawn$ True | SubAbility$ DBDiscard SVar:DBDiscard:DB$ Discard | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GEX | Defined$ You | Mode$ TgtChoose | NumCards$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/forge-gui/res/cardsfolder/i/ill_gotten_gains.txt b/forge-gui/res/cardsfolder/i/ill_gotten_gains.txt index 152f9807407..a20f5a87514 100644 --- a/forge-gui/res/cardsfolder/i/ill_gotten_gains.txt +++ b/forge-gui/res/cardsfolder/i/ill_gotten_gains.txt @@ -2,8 +2,7 @@ Name:Ill-Gotten Gains ManaCost:2 B B Types:Sorcery A:SP$ Discard | Cost$ 2 B B | Mode$ Hand | Defined$ Player | SubAbility$ DBExile | SpellDescription$ Exile CARDNAME. Each player discards their hand, then returns up to three cards from their graveyard to their hand. -SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | SubAbility$ DBChangeZoneChoose -SVar:DBChangeZoneChoose:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBChangeZone -SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeNum$ 3 | ChangeType$ Card | DefinedPlayer$ Remembered | Hidden$ True +SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeNum$ 3 | ChangeType$ Card | DefinedPlayer$ Player | Hidden$ True AI:RemoveDeck:All Oracle:Exile Ill-Gotten Gains. Each player discards their hand, then returns up to three cards from their graveyard to their hand. diff --git a/forge-gui/res/cardsfolder/i/intellect_devourer.txt b/forge-gui/res/cardsfolder/i/intellect_devourer.txt index 05e70cfb4e5..497559e7740 100644 --- a/forge-gui/res/cardsfolder/i/intellect_devourer.txt +++ b/forge-gui/res/cardsfolder/i/intellect_devourer.txt @@ -3,10 +3,6 @@ ManaCost:3 B Types:Creature Horror PT:2/4 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ Devour Intellect — When CARDNAME enters the battlefield, each opponent exiles a card from their hand until CARDNAME leaves the battlefield. -SVar:TrigExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | DefinedPlayer$ Opponent | Mandatory$ True | ChangeType$ Card | Hidden$ True | Duration$ UntilHostLeavesPlay | IsCurse$ True | RememberChanged$ True -S:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreColor$ True | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Body Thief — You may play lands and cast spells from among cards exiled with CARDNAME. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it. -T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.Self | Execute$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TrigExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | DefinedPlayer$ Opponent | Mandatory$ True | ChangeType$ Card | Hidden$ True | Duration$ UntilHostLeavesPlay | IsCurse$ True +S:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreColor$ True | Affected$ Card.ExiledWithSource | AffectedZone$ Exile | Description$ Body Thief — You may play lands and cast spells from among cards exiled with CARDNAME. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it. Oracle:Devour Intellect — When Intellect Devourer enters the battlefield, each opponent exiles a card from their hand until Intellect Devourer leaves the battlefield.\nBody Thief — You may play lands and cast spells from among cards exiled with Intellect Devourer. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it. diff --git a/forge-gui/res/cardsfolder/i/intet_the_dreamer.txt b/forge-gui/res/cardsfolder/i/intet_the_dreamer.txt index 67b1ba92009..9e00adea7cd 100644 --- a/forge-gui/res/cardsfolder/i/intet_the_dreamer.txt +++ b/forge-gui/res/cardsfolder/i/intet_the_dreamer.txt @@ -3,15 +3,11 @@ ManaCost:3 U R G Types:Legendary Creature Dragon PT:6/6 K:Flying -T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may pay {2}{U}. If you do, exile the top card of your library face down. You may look at that card for as long as it remains exiled. You may play that card without paying its mana cost for as long as CARDNAME remains on the battlefield. +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may pay {2}{U}. If you do, exile the top card of your library face down. You may look at that card for as long as it remains exiled. You may play that card without paying its mana cost for as long as NICKNAME remains on the battlefield. SVar:TrigExile:AB$ ChangeZone | Cost$ 2 U | Defined$ TopOfLibrary | Origin$ Library | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | SubAbility$ DBEffect -SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STMayLookAt | Triggers$ LeavesExile | Duration$ Permanent | SubAbility$ DBEffect2 +SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STMayLookAt | ForgetOnMoved$ Exile | Duration$ Permanent | SubAbility$ DBEffect2 SVar:STMayLookAt:Mode$ Continuous | EffectZone$ Command | Affected$ Card.IsRemembered | MayLookAt$ You | AffectedZone$ Exile | Description$ You may look at that card for as long as it remains exiled. -SVar:LeavesExile:Mode$ ChangesZone | TriggerZones$ Command | Origin$ Exile | Destination$ Any | ValidCard$ Card.IsRemembered | Static$ True | Execute$ ExileSelf -SVar:ExileSelf:DB$ ChangeZone | Origin$ Command | Destination$ Exile -SVar:DBEffect2:DB$ Effect | Name$ Intet, the Dreamer Effect | StaticAbilities$ STMayPlay | Triggers$ PlayedExiled,ExiledLandPlayed | RememberObjects$ Remembered | Duration$ UntilHostLeavesPlay | SubAbility$ DBCleanup +SVar:DBEffect2:DB$ Effect | Name$ Intet, the Dreamer Effect | StaticAbilities$ STMayPlay | ForgetOnMoved$ Exile | RememberObjects$ Remembered | Duration$ UntilHostLeavesPlay | SubAbility$ DBCleanup SVar:STMayPlay:Mode$ Continuous | EffectZone$ Command | Affected$ Card.IsRemembered | MayPlay$ True | MayPlayWithoutManaCost$ True | AffectedZone$ Exile | Description$ You may play that card without paying its mana cost for as long as Intet remains on the battlefield. -SVar:PlayedExiled:Mode$ SpellCast | TriggerZones$ Command | ValidCard$ Card.IsRemembered | Static$ True | Execute$ ExileSelf -SVar:ExiledLandPlayed:Mode$ LandPlayed | TriggerZones$ Command | ValidCard$ Card.IsRemembered | Static$ True | Execute$ ExileSelf SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True Oracle:Flying\nWhenever Intet, the Dreamer deals combat damage to a player, you may pay {2}{U}. If you do, exile the top card of your library face down. You may look at that card for as long as it remains exiled. You may play that card without paying its mana cost for as long as Intet remains on the battlefield. diff --git a/forge-gui/res/cardsfolder/i/intimidation_bolt.txt b/forge-gui/res/cardsfolder/i/intimidation_bolt.txt index 6c51dce5eed..a8fdd4ff1cb 100644 --- a/forge-gui/res/cardsfolder/i/intimidation_bolt.txt +++ b/forge-gui/res/cardsfolder/i/intimidation_bolt.txt @@ -1,8 +1,7 @@ Name:Intimidation Bolt ManaCost:1 R W Types:Instant -A:SP$ DealDamage | Cost$ 1 R W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 3 | RememberTargets$ True | SubAbility$ DBPumpAll | SpellDescription$ CARDNAME deals 3 damage to target creature. Other creatures can't attack this turn. -SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Remembered.Creature+Other | KW$ HIDDEN CARDNAME can't attack. | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:SP$ DealDamage | Cost$ 1 R W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 3 | SubAbility$ DBPumpAll | SpellDescription$ CARDNAME deals 3 damage to target creature. Other creatures can't attack this turn. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Targeted.Creature+Other | KW$ HIDDEN CARDNAME can't attack. AI:RemoveDeck:All Oracle:Intimidation Bolt deals 3 damage to target creature. Other creatures can't attack this turn. diff --git a/forge-gui/res/cardsfolder/k/killing_wave.txt b/forge-gui/res/cardsfolder/k/killing_wave.txt index 186baae64c8..821496674f5 100644 --- a/forge-gui/res/cardsfolder/k/killing_wave.txt +++ b/forge-gui/res/cardsfolder/k/killing_wave.txt @@ -1,8 +1,14 @@ Name:Killing Wave ManaCost:X B Types:Sorcery -A:SP$ RepeatEach | Cost$ X B | RepeatCards$ Creature | Zone$ Battlefield | RepeatSubAbility$ DBSacUnless | SpellDescription$ For each creature, its controller sacrifices it unless they pay X life. -SVar:DBSacUnless:DB$ Sacrifice | Defined$ Player | SacValid$ Remembered.Self | UnlessCost$ PayLife | UnlessPayer$ RememberedController | Random$ True | StackDescription$ Sacrifice {c:Remembered} +A:SP$ RepeatEach | Cost$ X B | RepeatPlayers$ Player | RepeatSubAbility$ DBChooseKeep | SubAbility$ DBRepeatPay | SpellDescription$ For each creature, its controller sacrifices it unless they pay X life. +SVar:DBChooseKeep:DB$ ChooseCard | Defined$ Remembered | Choices$ Creature.RememberedPlayerCtrl | MinAmount$ 0 | Amount$ Count$Valid Creature.RememberedPlayerCtrl | RememberChosen$ True +SVar:DBRepeatPay:DB$ RepeatEach | RepeatPlayers$ Player | LoseLifeMap$ True | RepeatSubAbility$ DBPay | SubAbility$ DBSacAll +SVar:DBPay:DB$ Pump | ForgetObjects$ Valid Creature.RememberedPlayerCtrl | UnlessCost$ PayLife | UnlessPayer$ Remembered +SVar:DBSacAll:DB$ SacrificeAll | ValidCards$ Creature.IsNotRemembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$xPaid +SVar:Y:SVar$X/Times.Z +SVar:Z:Count$Valid Creature.RememberedPlayerCtrl+IsRemembered AI:RemoveDeck:All Oracle:For each creature, its controller sacrifices it unless they pay X life. diff --git a/forge-gui/res/cardsfolder/m/mindclaw_shaman.txt b/forge-gui/res/cardsfolder/m/mindclaw_shaman.txt index 8a2c7a96bd6..b5780d8dbb0 100644 --- a/forge-gui/res/cardsfolder/m/mindclaw_shaman.txt +++ b/forge-gui/res/cardsfolder/m/mindclaw_shaman.txt @@ -3,7 +3,6 @@ ManaCost:4 R Types:Creature Viashino Shaman PT:2/2 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReveal | TriggerDescription$ When CARDNAME enters the battlefield, target opponent reveals their hand. You may cast an instant or sorcery spell from among those cards without paying its mana cost. -SVar:TrigReveal:DB$ RevealHand | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | RememberTargets$ True | SubAbility$ TrigPlay -SVar:TrigPlay:DB$ Play | Valid$ Card.RememberedPlayerCtrl | ValidSA$ Instant,Sorcery | ValidZone$ Hand | WithoutManaCost$ True | Optional$ True | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TrigReveal:DB$ RevealHand | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | SubAbility$ TrigPlay +SVar:TrigPlay:DB$ Play | Valid$ Card.TargetedPlayerCtrl | ValidSA$ Instant,Sorcery | ValidZone$ Hand | WithoutManaCost$ True | Optional$ True Oracle:When Mindclaw Shaman enters the battlefield, target opponent reveals their hand. You may cast an instant or sorcery spell from among those cards without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/n/night_market_lookout.txt b/forge-gui/res/cardsfolder/n/night_market_lookout.txt index b2249ee56ce..2bf23350964 100644 --- a/forge-gui/res/cardsfolder/n/night_market_lookout.txt +++ b/forge-gui/res/cardsfolder/n/night_market_lookout.txt @@ -3,7 +3,7 @@ ManaCost:B Types:Creature Human Rogue PT:1/1 T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigDrain | TriggerDescription$ Whenever CARDNAME becomes tapped, each opponent loses 1 life and you gain 1 life. -SVar:TrigDrain:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife +SVar:TrigDrain:DB$ LoseLife | Defined$ Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 DeckHas:Ability$LifeGain Oracle:Whenever Night Market Lookout becomes tapped, each opponent loses 1 life and you gain 1 life. diff --git a/forge-gui/res/cardsfolder/n/nightveil_specter.txt b/forge-gui/res/cardsfolder/n/nightveil_specter.txt index 1b3ae2f5522..d6c87a422da 100644 --- a/forge-gui/res/cardsfolder/n/nightveil_specter.txt +++ b/forge-gui/res/cardsfolder/n/nightveil_specter.txt @@ -4,10 +4,6 @@ Types:Creature Specter PT:2/3 K:Flying T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, that player exiles the top card of their library. -SVar:TrigExile:DB$ Dig | Defined$ TriggeredTarget | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True -S:Mode$ Continuous | MayPlay$ True | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play lands and cast spells from among cards exiled with CARDNAME. -T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.Self | Execute$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TrigExile:DB$ Dig | Defined$ TriggeredTarget | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile +S:Mode$ Continuous | MayPlay$ True | Affected$ Card.ExiledWithSource | AffectedZone$ Exile | Description$ You may play lands and cast spells from among cards exiled with CARDNAME. Oracle:Flying\nWhenever Nightveil Specter deals combat damage to a player, that player exiles the top card of their library.\nYou may play lands and cast spells from among cards exiled with Nightveil Specter. diff --git a/forge-gui/res/cardsfolder/n/nissa_steward_of_elements.txt b/forge-gui/res/cardsfolder/n/nissa_steward_of_elements.txt index 43995244c0e..2174eef7165 100644 --- a/forge-gui/res/cardsfolder/n/nissa_steward_of_elements.txt +++ b/forge-gui/res/cardsfolder/n/nissa_steward_of_elements.txt @@ -5,8 +5,7 @@ Loyalty:X SVar:X:Count$xPaid A:AB$ Scry | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | ScryNum$ 2 | SpellDescription$ Scry 2. A:AB$ Dig | Cost$ AddCounter<0/LOYALTY> | Planeswalker$ True | DigNum$ 1 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Land,Creature.cmcLEY | ForceRevealToController$ True | PromptToSkipOptionalAbility$ True | AILogic$ AlwaysConfirm | OptionalAbilityPrompt$ Would you like to put the permanent onto the battlefield? | DestinationZone$ Battlefield | LibraryPosition2$ 0 | SpellDescription$ Look at the top card of your library. If it's a land card or a creature card with mana value less than or equal to the number of loyalty counters on Nissa, Steward of Elements, you may put that card onto the battlefield. -A:AB$ Untap | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Land.YouCtrl | TargetMin$ 0 | TargetMax$ 2 | RememberTargets$ True | SubAbility$ Animate | SpellDescription$ Untap up to two target lands you control. They become 5/5 Elemental creatures with flying and haste until end of turn. They're still lands. -SVar:Animate:DB$ Animate | Defined$ Remembered | Power$ 5 | Toughness$ 5 | Types$ Creature,Elemental | Keywords$ Flying & Haste | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ Untap | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Land.YouCtrl | TargetMin$ 0 | TargetMax$ 2 | SubAbility$ Animate | SpellDescription$ Untap up to two target lands you control. They become 5/5 Elemental creatures with flying and haste until end of turn. They're still lands. +SVar:Animate:DB$ Animate | Defined$ Targeted | Power$ 5 | Toughness$ 5 | Types$ Creature,Elemental | Keywords$ Flying & Haste SVar:Y:Count$CardCounters.LOYALTY Oracle:[+2]: Scry 2.\n[0]: Look at the top card of your library. If it's a land card or a creature card with mana value less than or equal to the number of loyalty counters on Nissa, Steward of Elements, you may put that card onto the battlefield.\n[-6]: Untap up to two target lands you control. They become 5/5 Elemental creatures with flying and haste until end of turn. They're still lands. diff --git a/forge-gui/res/cardsfolder/n/nissa_vastwood_seer_nissa_sage_animist.txt b/forge-gui/res/cardsfolder/n/nissa_vastwood_seer_nissa_sage_animist.txt index 15b7c6e5dba..124cb005ca5 100644 --- a/forge-gui/res/cardsfolder/n/nissa_vastwood_seer_nissa_sage_animist.txt +++ b/forge-gui/res/cardsfolder/n/nissa_vastwood_seer_nissa_sage_animist.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Elf Scout PT:2/2 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a basic Forest card, reveal it, put it into your hand, then shuffle. SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Forest.Basic | ChangeNum$ 1 | ShuffleNonMandatory$ True -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | IsPresent$ Land.YouCtrl | PresentCompare$ GE7 | Execute$ TrigExile | TriggerDescription$ Whenever a land enters the battlefield under your control, if you control seven or more lands, exile CARDNAME, then return her to the battlefield transformed under her owner's control. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | IsPresent$ Land.YouCtrl | PresentCompare$ GE7 | Execute$ TrigExile | TriggerDescription$ Whenever a land enters the battlefield under your control, if you control seven or more lands, exile NICKNAME, then return her to the battlefield transformed under her owner's control. SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | SubAbility$ DBReturn SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield | Transformed$ True | ForgetOtherRemembered$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True @@ -20,7 +20,6 @@ Types:Legendary Planeswalker Nissa Loyalty:3 A:AB$ Dig | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | DigNum$ 1 | Reveal$ True | ChangeNum$ All | ChangeValid$ Land | DestinationZone$ Battlefield | DestinationZone2$ Hand | SpellDescription$ Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand. A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ ashaya_the_awoken_world | TokenOwner$ You | SpellDescription$ Create Ashaya, the Awoken World, a legendary 4/4 green Elemental creature token. -A:AB$ Untap | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Land | TgtPrompt$ Choose target land | TargetMin$ 0 | TargetMax$ 6 | RememberTargets$ True | SubAbility$ DBAnimate | SpellDescription$ Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. -SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Power$ 6 | Toughness$ 6 | Types$ Creature,Elemental | Duration$ Permanent | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ Untap | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Land | TgtPrompt$ Choose target land | TargetMin$ 0 | TargetMax$ 6 | SubAbility$ DBAnimate | SpellDescription$ Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Power$ 6 | Toughness$ 6 | Types$ Creature,Elemental | Duration$ Permanent Oracle:[+1]: Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand.\n[-2]: Create Ashaya, the Awoken World, a legendary 4/4 green Elemental creature token.\n[-7]: Untap up to six target lands. They become 6/6 Elemental creatures. They're still lands. diff --git a/forge-gui/res/cardsfolder/r/reverse_the_sands.txt b/forge-gui/res/cardsfolder/r/reverse_the_sands.txt index 6cfd02348d2..5c26624107a 100644 --- a/forge-gui/res/cardsfolder/r/reverse_the_sands.txt +++ b/forge-gui/res/cardsfolder/r/reverse_the_sands.txt @@ -1,6 +1,6 @@ Name:Reverse the Sands ManaCost:6 W W Types:Sorcery -A:SP$ SetLife | Cost$ 6 W W | Defined$ Player | Redistribute$ True | SpellDescription$ Redistribute any number of players' life totals. (Each of those players gets one life total back.) +A:SP$ SetLife | PlayerChoices$ Player | ChoiceAmount$ Any | ChoicePrompt$ Choose any number of players | Redistribute$ True | SpellDescription$ Redistribute any number of players' life totals. (Each of those players gets one life total back.) AI:RemoveDeck:All Oracle:Redistribute any number of players' life totals. (Each of those players gets one life total back.) diff --git a/forge-gui/res/cardsfolder/t/the_ruinous_powers.txt b/forge-gui/res/cardsfolder/t/the_ruinous_powers.txt index bc8fd85adeb..e1297c833a7 100644 --- a/forge-gui/res/cardsfolder/t/the_ruinous_powers.txt +++ b/forge-gui/res/cardsfolder/t/the_ruinous_powers.txt @@ -7,7 +7,7 @@ SVar:DBExile:DB$ Dig | Defined$ ChosenPlayer | DigNum$ 1 | DestinationZone$ Exil SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | Triggers$ TriggerCastDoM | ForgetOnMoved$ Exile | ForgetOnCast$ False | RememberObjects$ Remembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearChosenPlayer$ True | ClearRemembered$ True SVar:STPlay:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreColor$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Until end of turn, you may play that card and you may spend mana as though it were mana of any color to cast it. -SVar:TriggerCastDoM:Mode$ SpellCast | ValidCard$ Card.IsRemembered | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigLoseLife | OneOff$ True | Secondary$ True | TriggerDescription$ When you cast a spell this way, its owner loses life equal to its mana value. +SVar:TriggerCastDoM:Mode$ SpellCast | ValidCard$ Card.IsRemembered | ValidSA$ Spell.MayPlaySource | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigLoseLife | OneOff$ True | Secondary$ True | TriggerDescription$ When you cast a spell this way, its owner loses life equal to its mana value. SVar:TrigLoseLife:DB$ LoseLife | Defined$ TriggeredCardOwner | LifeAmount$ X SVar:X:TriggeredStackInstance$CardManaCostLKI Oracle:At the beginning of your upkeep, choose an opponent at random. Exile the top card of that player's library. Until end of turn, you may play that card and you may spend mana as though it were mana of any color to cast it. When you cast a spell this way, its owner loses life equal to its mana value. diff --git a/forge-gui/res/cardsfolder/t/theater_of_horrors.txt b/forge-gui/res/cardsfolder/t/theater_of_horrors.txt index c01ca4b72c6..c78e4963d9c 100644 --- a/forge-gui/res/cardsfolder/t/theater_of_horrors.txt +++ b/forge-gui/res/cardsfolder/t/theater_of_horrors.txt @@ -2,12 +2,8 @@ Name:Theater of Horrors ManaCost:1 B R Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigExile | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, exile the top card of your library. -SVar:TrigExile:DB$ Dig | Defined$ You | DestinationZone$ Exile | DigNum$ 1 | ChangeNum$ All | RememberChanged$ True -S:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayPlay$ True | Condition$ PlayerTurn | CheckSVar$ X | Description$ During your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with CARDNAME. +SVar:TrigExile:DB$ Dig | Defined$ You | DestinationZone$ Exile | DigNum$ 1 | ChangeNum$ All +S:Mode$ Continuous | Affected$ Card.ExiledWithSource | AffectedZone$ Exile | MayPlay$ True | Condition$ PlayerTurn | CheckSVar$ X | Description$ During your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with CARDNAME. SVar:X:Count$LifeOppsLostThisTurn -T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.Self | Execute$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True A:AB$ DealDamage | Cost$ 3 R | ValidTgts$ Opponent,Planeswalker | TgtPrompt$ Select target opponent or planeswalker | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to target opponent or planeswalker. Oracle:At the beginning of your upkeep, exile the top card of your library.\nDuring your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with Theater of Horrors.\n{3}{R}: Theater of Horrors deals 1 damage to target opponent or planeswalker. diff --git a/forge-gui/res/cardsfolder/t/tree_of_perdition.txt b/forge-gui/res/cardsfolder/t/tree_of_perdition.txt index e926314637f..58f28ca5ba7 100644 --- a/forge-gui/res/cardsfolder/t/tree_of_perdition.txt +++ b/forge-gui/res/cardsfolder/t/tree_of_perdition.txt @@ -3,5 +3,5 @@ ManaCost:3 B Types:Creature Plant PT:0/13 K:Defender -A:AB$ ExchangeLifeVariant | Cost$ T | ConditionPresent$ Creature.StrictlySelf | ValidTgts$ Opponent | Mode$ Toughness | SpellDescription$ Exchange target opponent's life total with CARDNAME's toughness. | StackDescription$ SpellDescription +A:AB$ ExchangeLifeVariant | Cost$ T | ConditionPresent$ Creature.StrictlySelf | ValidTgts$ Opponent | Mode$ Toughness | SpellDescription$ Exchange target opponent's life total with CARDNAME's toughness. | StackDescription$ REP target opponent_{p:Targeted} Oracle:Defender\n{T}: Exchange target opponent's life total with Tree of Perdition's toughness. diff --git a/forge-gui/res/cardsfolder/upcoming/fires_of_mount_doom.txt b/forge-gui/res/cardsfolder/upcoming/fires_of_mount_doom.txt index 27b7da7010f..a1d8e1036f3 100644 --- a/forge-gui/res/cardsfolder/upcoming/fires_of_mount_doom.txt +++ b/forge-gui/res/cardsfolder/upcoming/fires_of_mount_doom.txt @@ -5,10 +5,10 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | NumDmg$ 2 | SubAbility$ ChompEquip SVar:ChompEquip:DB$ DestroyAll | ValidCards$ Targeted.Equipment+Attached A:AB$ Dig | Cost$ 2 R | DigNum$ 1 | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Exile the top card of your library. You may play that card this turn. When you play a card this way, CARDNAME deals 2 damage to each player. -SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | Triggers$ TriggerCastDoM,TriggerLandPlayed | ForgetOnMoved$ Exile | ForgetOnCast$ False | RememberObjects$ Remembered | SubAbility$ DBCleanup +SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | Triggers$ TriggerCastDoM,TriggerLandPlayed | RememberObjects$ Remembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play that card this turn. When you play a card this way, CARDNAME deals 2 damage to each player. -SVar:TriggerCastDoM:Mode$ SpellCast | ValidCard$ Card.IsRemembered | OneOff$ True | ValidActivatingPlayer$ You | Execute$ TrigDealDamage | TriggerDescription$ When you play a card this way, CARDNAME deals 2 damage to each player. +SVar:TriggerCastDoM:Mode$ SpellCast | ValidCard$ Card.IsRemembered | ValidSA$ Spell.MayPlaySource | OneOff$ True | ValidActivatingPlayer$ You | Execute$ TrigDealDamage | TriggerDescription$ When you play a card this way, CARDNAME deals 2 damage to each player. SVar:TriggerLandPlayed:Mode$ LandPlayed | ValidCard$ Land.IsRemembered | OneOff$ True | Execute$ TrigDealDamage | Secondary$ True | TriggerDescription$ When you play a card this way, CARDNAME deals 2 damage to each player. SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player | NumDmg$ 2 Oracle:When Fires of Mount Doom enters the battlefield, it deals 2 damage to target creature an opponent controls. Destroy all Equipment attached to that creature.\n{2}{R}: Exile the top card of your library. You may play that card this turn. When you play a card this way, Fires of Mount Doom deals 2 damage to each player. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/ob_nixilis_captive_kingpin.txt b/forge-gui/res/cardsfolder/upcoming/ob_nixilis_captive_kingpin.txt new file mode 100644 index 00000000000..9b92838686a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ob_nixilis_captive_kingpin.txt @@ -0,0 +1,14 @@ +Name:Ob Nixilis, Captive Kingpin +ManaCost:2 B R +Types:Legendary Creature Demon +PT:4/3 +KFlying +K:Trample +T:Mode$ LifeLostAll | ValidPlayer$ Opponent | ValidAmountEach$ EQ1 | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more opponents each lose exactly 1 life, put a +1/+1 counter on CARDNAME. Exile the top card of your library. Until your next end step, you may play that card. +SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | SubAbility$ DBExileTop +SVar:DBExileTop:DB$ Dig | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | RememberObjects$ Remembered | Duration$ UntilYourNextEndStep | SubAbility$ DBCleanup | ForgetOnMoved$ Exile +SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Until your next end step, you may play that card. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Counters +Oracle:Flying, trample\nWhenever one or more opponents each lose exactly 1 life, put a +1/+1 counter on Ob Nixilis, Captive Kingpin. Exile the top card of your library. Until your next end step, you may play that card. diff --git a/forge-gui/res/cardsfolder/w/waking_the_trolls.txt b/forge-gui/res/cardsfolder/w/waking_the_trolls.txt index 2b47e159230..9f6490eec83 100644 --- a/forge-gui/res/cardsfolder/w/waking_the_trolls.txt +++ b/forge-gui/res/cardsfolder/w/waking_the_trolls.txt @@ -4,10 +4,9 @@ Types:Enchantment Saga K:Saga:3:DBDestroy,DBChangeZone,DBPump SVar:DBDestroy:DB$ Destroy | ValidTgts$ Land | TgtPrompt$ Choose target land. | SpellDescription$ Destroy target land. SVar:DBChangeZone:DB$ ChangeZone | ValidTgts$ Land | TgtPrompt$ Choose target land card. | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | SpellDescription$ Put target land card from a graveyard onto the battlefield under your control. -SVar:DBPump:DB$ Pump | ValidTgts$ Player.Opponent | RememberTargets$ True | IsCurse$ True | TgtPrompt$ Choose target player. | SubAbility$ DBToken | SpellDescription$ Choose target player. If they control fewer lands than you, create a number of 4/4 green Troll Warrior creature tokens with trample equal to the difference. -SVar:DBToken:DB$ Token | TokenAmount$ X | TokenScript$ g_4_4_troll_warrior_trample | TokenOwner$ You | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:DBPump:DB$ Pump | ValidTgts$ Opponent | IsCurse$ True | SubAbility$ DBToken | SpellDescription$ Choose target player. If they control fewer lands than you, create a number of 4/4 green Troll Warrior creature tokens with trample equal to the difference. +SVar:DBToken:DB$ Token | TokenAmount$ X | TokenScript$ g_4_4_troll_warrior_trample | TokenOwner$ You SVar:X:Count$Valid Land.YouCtrl/Minus.Y -SVar:Y:Count$Valid Land.RememberedPlayerCtrl +SVar:Y:Count$Valid Land.TargetedPlayerCtrl DeckHas:Ability$Token Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — Destroy target land.\nII — Put target land card from a graveyard onto the battlefield under your control.\nIII — Choose target opponent. If they control fewer lands than you, create a number of 4/4 green Troll Warrior creature tokens with trample equal to the difference. diff --git a/forge-gui/res/cardsfolder/w/winnow.txt b/forge-gui/res/cardsfolder/w/winnow.txt index 7158ea1e7a9..23127ec32a2 100644 --- a/forge-gui/res/cardsfolder/w/winnow.txt +++ b/forge-gui/res/cardsfolder/w/winnow.txt @@ -1,10 +1,9 @@ Name:Winnow ManaCost:1 W Types:Instant -A:SP$ Destroy | Cost$ 1 W | ValidTgts$ Permanent.nonLand | RememberTargets$ True | ConditionCheckSVar$ WinnowCheck | ConditionSVarCompare$ GE2 | SubAbility$ DBDraw | SpellDescription$ Destroy target nonland permanent if another permanent with the same name is on the battlefield. Draw a card. -SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:WinnowCheck:Count$Valid Permanent.sharesNameWith Remembered +A:SP$ Destroy | Cost$ 1 W | ValidTgts$ Permanent.nonLand | ConditionCheckSVar$ WinnowCheck | ConditionSVarCompare$ GE2 | SubAbility$ DBDraw | SpellDescription$ Destroy target nonland permanent if another permanent with the same name is on the battlefield. Draw a card. +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 +SVar:WinnowCheck:Count$Valid Permanent.sharesNameWith Targeted AI:RemoveDeck:All AI:RemoveDeck:Random Oracle:Destroy target nonland permanent if another permanent with the same name is on the battlefield.\nDraw a card. diff --git a/forge-gui/res/cardsfolder/x/xira_the_golden_sting.txt b/forge-gui/res/cardsfolder/x/xira_the_golden_sting.txt index b978c34a940..d1ef42c4e6a 100644 --- a/forge-gui/res/cardsfolder/x/xira_the_golden_sting.txt +++ b/forge-gui/res/cardsfolder/x/xira_the_golden_sting.txt @@ -5,7 +5,7 @@ PT:3/3 K:Flying K:Haste T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigEggCounter | TriggerDescription$ Whenever CARDNAME attacks, put an egg counter on another target creature without an egg counter on it. When that creature dies, if it has an egg counter on it, draw a card and create a 1/1 black Insect creature token with flying. -SVar:TrigEggCounter:DB$ PutCounter | CounterType$ EGG | CounterNum$ 1 | ValidTgts$ Creature.Other+counters_EQ0_EGG | RememberTargets$ True | TgtPrompt$ Put an egg counter on another target creature without an egg counter on it. | SubAbility$ DelayedTrigger +SVar:TrigEggCounter:DB$ PutCounter | CounterType$ EGG | CounterNum$ 1 | ValidTgts$ Creature.Other+counters_EQ0_EGG | TgtPrompt$ Put an egg counter on another target creature without an egg counter on it. | SubAbility$ DelayedTrigger SVar:DelayedTrigger:DB$ DelayedTrigger | Mode$ ChangesZone | RememberObjects$ Targeted | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.IsTriggerRemembered+counters_GE1_EGG | Execute$ TrigDraw | TriggerDescription$ When this creature dies, if it has an egg counter on it, draw a card and create a 1/1 black Insect creature token with flying. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBToken SVar:DBToken:DB$ Token | TokenScript$ b_1_1_insect_flying diff --git a/forge-gui/res/editions/Commander Masters.txt b/forge-gui/res/editions/Commander Masters.txt index 815772e10d8..b50ef2de03c 100644 --- a/forge-gui/res/editions/Commander Masters.txt +++ b/forge-gui/res/editions/Commander Masters.txt @@ -9,100 +9,191 @@ ScryfallCode=CMM 1 S The Prismatic Piper @Seb McKinnon 2 M Kozilek, the Great Distortion @Aleksi Briclot 3 M Morophon, the Boundless @Victor Adame Minguez +5 M Ulamog, the Ceaseless Hunger @Michael Komarck 6 C Ulamog's Crusher @Todd Lockwood 10 R Alms Collector @Bram Sels -11 R Anafenza, Kin-Tree Spirit @Ryan Yee +11 U Anafenza, Kin-Tree Spirit @Ryan Yee 13 R Angelic Field Marshal @Scott Murphy +14 M Avacyn, Angel of Hope @Jason Chan 16 R Balan, Wandering Knight @Svetlin Velinov -17 U Battle Screech @Anastasia Ovchinnikova +17 C Battle Screech @Anastasia Ovchinnikova 18 U Cartographer's Hawk @Donato Giancola +21 U Darksteel Mutation @Daniel Ljunggren 22 U Elite Scaleguard @Steve Prescott +24 R Flawless Maneuver @Zoltan Boros 27 R Grand Abolisher @Eric Deschamps +28 R Heavenly Blademaster @Zack Stella +29 M Heliod, Sun-Crowned @Lius Lasahido +32 R Jazal Goldmane @Aaron Miller +34 U Kemba, Kha Regent @Ernanda Souza 35 U Kirtar's Wrath @Kev Walker 37 M Land Tax @Chuck Lukacs +39 M Loyal Retainers @Kieran Yanner +42 R Mangara, the Diplomat @Howard Lyon +45 R Nahiri, the Lithomancer @Eric Deschamps 50 U Pianna, Nomad Captain @D. Alexander Gregory 51 R Puresteel Paladin @Jason Chan +53 R Righteous Confluence @Kieran Yanner +54 R Sephara, Sky's Blade @Livia Prima +55 R Sevinne's Reclamation @Zoltan Boros +56 C Shelter @Alayna Danner +57 M Smothering Tithe @Mark Behm +59 R Steelshaper's Gift @Greg Hildebrandt 60 R Sublime Exhalation @Lake Hurwitz +68 R Wakening Sun's Avatar @Tyler Jacobson +71 R Zetalpa, Primal Dawn @Chris Rallis 73 R Aminatou's Augury @Seb McKinnon 74 R Azami, Lady of Scrolls @Ittoku -75 R Braids, Conjurer Adept @Zoltan Boros & Gabor Szikszai -79 R Capture of Jingzhou @Jack Wei +76 R Braids, Conjurer Adept @Zoltan Boros & Gabor Szikszai +77 M Bribery @Kai Carpenter +79 M Capture of Jingzhou @Jack Wei +80 R Commandeer @John Matson 84 R Cyclonic Rift @Chris Rahn +85 R Day's Undoing @Jonas De Ro 89 R Evacuation @Franz Vohwinkel 92 R Faerie Artisans @Tony Foti +94 R Fierce Guardianship @Randy Vargas +103 R Lorthos, the Tidemaker @Kekai Kotaki 105 R Minds Aglow @Yeong-Hao Han 108 R Mystic Confluence @Kieran Yanner 110 R Personal Tutor @Julie Dillon +113 U Reality Shift @Howard Lyon 118 R Sai, Master Thopterist @Adam Paquette 120 M Spellseeker @Igor Kieryluk 122 R Stormsurge Kraken @Svetlin Velinov +123 M Sun Quan, Lord of Wu @Xu Xiaoming 125 R Teferi, Temporal Archmage @Tyler Jacobson 128 R Torrential Gearhulk @Svetlin Velinov 130 M Urza, Lord High Artificer @Grzegorz Rutkowski 134 C Windrider Wizard @Slawomir Maniak 137 M Archfiend of Despair @Josh Hass +139 R Bloodchief Ascension @Adi Granov 144 R Chainer, Dementia Master @Mark Zug 146 R Curtains' Call @James Ryman +147 R Deadly Rollick @Izzy +148 R Decree of Pain @Carl Critchlow +150 M Demonic Tutor @Zack Stella +151 R Demonlord Belzenlok @Tyler Jacobson +155 R Endrek Sahr, Master Breeder @Lucas Graciano +156 U Exsanguinate @Marie Magny 157 U Extinguish All Hope @Aaron J. Riley 161 R Ghoulcaller Gisa @Karla Ortiz +165 M Grave Pact @Billy Christian +167 R Imp's Mischief @Thomas M. Baxa 169 R Kindred Dominance @Bram Sels -176 M Ob Nixilis of the Black Oath @Daarken +173 M Mikaeus, the Unhallowed @Chris Rahn +176 R Ob Nixilis of the Black Oath @Daarken +177 R Ogre Slumlord @Trevor Claxton +180 R Rankle, Master of Pranks @Dmitry Burmak +181 M Razaketh, the Foulblooded @Chris Rallis +184 R Rune-Scarred Demon @Michael Komarck +187 R Sower of Discord @Wisnu Tan 191 R Toxic Deluge @Svetlin Velinov +193 M Twilight Prophet @Seb McKinnon +196 R Vindictive Lich @Toma Feizo Gas 197 R Wake the Dead @Christopher Moeller 200 R Wretched Confluence @Kieran Yanner 202 U Yargle, Glutton of Urborg @Jehan Choo 205 R Ashling the Pilgrim @Wayne Reynolds +206 R Avatar of Slaughter @Jason A. Engle +207 M Balefire Dragon @Eric Deschamps 208 C Blood Aspirant @Tyler Walpole 213 R Daretti, Scrap Savant @Dan Scott +214 R Deflecting Swat @Izzy 218 R Drakuseth, Maw of Flames @Grzegorz Rutkowski 222 R Fiery Confluence @Kieran Yanner +227 R Godo, Bandit Warlord @Paolo Parente +228 R Grenzo, Havoc Raiser @Svetlin Velinov 231 R Heartless Hidetsugu @Carl Critchlow 232 R Hellkite Charger @Jaime Jones 236 M Insurrection @Mark Zug 238 R Krenko, Mob Boss @Karl Kopinski 241 R Magus of the Wheel @Carl Frank +244 M Neheb, the Eternal @Chris Rahn 245 R Nesting Dragon @Jehan Choo -259 M Star of Extinction @Chris Rahn +246 M Purphoros, God of the Forge @Eric Deschamps +247 U Rakka Mar @Jason Chan +252 M Savage Beating @Matt Thompson +253 R Scourge of the Throne @Michael Komarck +259 R Star of Extinction @Chris Rahn +260 U Storm-Kiln Artist @Manuel Castañón +263 R Tempt with Vengeance @Ryan Barger 265 R Treasure Nabber @Alex Konstad 267 U Vandalblast @Seb McKinnon +272 R Arachnogenesis @Johannes Voss 274 R Azusa, Lost but Seeking @Winona Nelson +276 R Bloodspore Thrinax @Ralph Horsley +280 M Craterhoof Behemoth @Chris Rahn +283 M Doubling Season @Chuck Lukacs 289 M Finale of Devastation @Bayard Wu +290 R Freyalise, Llanowar's Fury @Adam Paquette +292 R Ghalta, Primal Hunger @Chase Stone 294 M The Great Henge @Adam Paquette 295 R Heroic Intervention @James Ryman 297 C Ilysian Caryatid @Winona Nelson 299 R Jolrael, Mwonvuli Recluse @Izzy +300 C Kodama's Reach @John Avon 303 R Lifeblood Hydra @Alex Horley-Orlandelli 308 R Obscuring Haze @Campbell White 309 R Ohran Frostfang @Torstein Nordstrand 310 M Omnath, Locus of Mana @Mike Bierek 316 R Regal Behemoth @Jakub Kasper -317 R Rishkar, Peema Renegade @Todd Lockwood +317 U Rishkar, Peema Renegade @Todd Lockwood +319 R Sakiko, Mother of Summer @Livia Prima 320 M Selvala, Heart of the Wilds @Tyler Jacobson 321 C Skyshroud Claim @Anna Steinbauer +324 R Song of the Dryads @Lars Grant-West +325 R Stonehoof Chieftain @Camille Alquier +327 R Tooth and Nail @Greg Hildebrandt +329 R Verdant Confluence @Kieran Yanner 331 R Wayward Swordtooth @Chris Rahn 334 R Yisan, the Wanderer Bard @Chase Stone +337 R Experiment Kraj @Mark Tedin +338 R Gisela, Blade of Goldnight @Jason Chan +339 U Hamza, Guardian of Arashin @Wisnu Tan +340 R Hanna, Ship's Navigator @Chris Rallis 342 R Karador, Ghost Chieftain @Todd Lockwood +343 R Kykar, Wind's Fury @G-host Lee 344 R Maelstrom Wanderer @Victor Adame Minguez -348 M Mizzix of the Izmagnus @Cliff Childs +347 R Mirri, Weatherlight Duelist @Magali Villeneuve +348 R Mizzix of the Izmagnus @Cliff Childs +349 R Nekusar, the Mindrazer @Mark Winters 350 R Queen Marchesa @Kieran Yanner +353 M The Scarab God @Lius Lasahido +354 R Sek'Kuar, Deathkeeper @Jesper Ejsing +355 R Sidisi, Brood Tyrant @Karl Kopinski 361 M The Ur-Dragon @Jaime Jones -367 C Arcane Signet @Dan Scott +362 R Xantcha, Sleeper Agent @Mark Winters +363 R Yennett, Cryptic Sovereign @Chris Rahn +364 R Yuriko, the Tiger's Shadow @Yongjae Choi +365 R Zacama, Primal Calamity @Jaime Jones +366 R Zilortha, Strength Incarnate @Chase Stone +367 U Arcane Signet @Dan Scott +368 U Ashnod's Altar @Greg Staples 371 R Boompile @Filip Burburan 372 C Brass Knuckles @Yeong-Hao Han 375 R Champion's Helm @Alan Pollack +376 R Chromatic Lantern @Jung Park 379 R Emerald Medallion @Daniel Ljunggren +381 M Extraplanar Lens @Lars Grant-West 382 U Fellwar Stone @John Avon +387 R Gilded Lotus @Volkan Baǵa 388 R Hammer of Nazahn @Victor Adame Minguez +392 R Idol of Oblivion @Piotr Dura 393 M The Immortal Sun @Kieran Yanner +394 R Inspiring Statuary @Kirsten Zirngibl 395 R Jet Medallion @Daniel Ljunggren 396 M Jeweled Lotus @Alayna Danner 401 R Pearl Medallion @Daniel Ljunggren 405 R Ruby Medallion @Daniel Ljunggren 407 R Sapphire Medallion @Daniel Ljunggren +408 R Scytheclaw @James Paick 410 U Sol Ring @Mike Bierek +413 R Sword of the Animist @Daniel Ljunggren 415 U Thran Dynamo @Ron Spears 420 C Command Tower @Ryan Yee 423 C Path of Ancestry @Alayna Danner +425 U Reliquary Tower @Jesper Ejsing 426 U Rogue's Passage @Christine Choi 429 C Thriving Bluff @Johannes Voss 430 C Thriving Grove @Ravenna Tran @@ -125,99 +216,207 @@ ScryfallCode=CMM 450 L Forest @Rebecca Guay 451 L Forest @Mark Poole 452 M Kozilek, the Great Distortion @Aleksi Briclot +453 M Morophon, the Boundless @Victor Adame Minguez +454 M Ulamog, the Ceaseless Hunger @Michael Komarck 455 R Alms Collector @Bram Sels 456 R Angelic Field Marshal @Scott Murphy +457 M Avacyn, Angel of Hope @Jason Chan 458 R Balan, Wandering Knight @Svetlin Velinov +459 R Flawless Maneuver @Zoltan Boros 460 R Grand Abolisher @Eric Deschamps +461 R Heavenly Blademaster @Zack Stella 462 M Heliod, Sun-Crowned @Lius Lasahido +463 R Jazal Goldmane @Aaron Miller 464 M Land Tax @Chuck Lukacs +465 M Loyal Retainers @Kieran Yanner +466 R Mangara, the Diplomat @Howard Lyon +467 R Nahiri, the Lithomancer @Eric Deschamps +468 R Odric, Master Tactician @Michael Komarck 469 R Puresteel Paladin @Jason Chan +470 R Righteous Confluence @Kieran Yanner +471 R Sephara, Sky's Blade @Livia Prima +472 R Sevinne's Reclamation @Zoltan Boros +473 M Smothering Tithe @Mark Behm 475 R Sublime Exhalation @Lake Hurwitz +476 R Wakening Sun's Avatar @Tyler Jacobson +478 R Zetalpa, Primal Dawn @Chris Rallis 479 R Aminatou's Augury @Seb McKinnon +480 R Azami, Lady of Scrolls @Ittoku 481 R Braids, Conjurer Adept @Zoltan Boros & Gabor Szikszai -483 R Capture of Jingzhou @Jack Wei +482 M Bribery @Kai Carpenter +483 M Capture of Jingzhou @Jack Wei +484 R Commandeer @John Matson +485 R Cyclonic Rift @Chris Rahn +487 R Evacuation @Franz Vohwinkel 488 R Faerie Artisans @Tony Foti 490 R Lorthos, the Tidemaker @Kekai Kotaki 491 R Minds Aglow @Yeong-Hao Han 492 R Mystic Confluence @Kieran Yanner 493 R Personal Tutor @Julie Dillon +494 R Sai, Master Thopterist @Adam Paquette 495 M Spellseeker @Igor Kieryluk 497 R Stormsurge Kraken @Svetlin Velinov +498 M Sun Quan, Lord of Wu @Xu Xiaoming 500 R Teferi, Temporal Archmage @Tyler Jacobson +501 R Torrential Gearhulk @Svetlin Velinov 502 M Urza, Lord High Artificer @Grzegorz Rutkowski 503 M Archfiend of Despair @Josh Hass +504 R Bloodchief Ascension @Adi Granov 505 R Chainer, Dementia Master @Mark Zug +506 R Curtains' Call @James Ryman 507 R Deadly Rollick @Izzy -517 M Ob Nixilis of the Black Oath @Daarken +509 M Demonic Tutor @Zack Stella +510 R Demonlord Belzenlok @Tyler Jacobson +511 R Endrek Sahr, Master Breeder @Lucas Graciano +512 R Ghoulcaller Gisa @Karla Ortiz +513 M Grave Pact @Billy Christian +514 R Imp's Mischief @Thomas M. Baxa +515 R Kindred Dominance @Bram Sels +516 M Mikaeus, the Unhallowed @Chris Rahn +517 R Ob Nixilis of the Black Oath @Daarken +518 R Ogre Slumlord @Trevor Claxton +519 R Rankle, Master of Pranks @Dmitry Burmak +520 M Razaketh, the Foulblooded @Chris Rallis 522 R Sower of Discord @Wisnu Tan 523 R Toxic Deluge @Svetlin Velinov +524 M Twilight Prophet @Seb McKinnon +525 R Vindictive Lich @Toma Feizo Gas 526 R Wake the Dead @Christopher Moeller 527 R Wretched Confluence @Kieran Yanner +528 R Ashling the Pilgrim @Wayne Reynolds 529 R Avatar of Slaughter @Jason A. Engle +530 M Balefire Dragon @Eric Deschamps 531 R Daretti, Scrap Savant @Dan Scott +532 R Deflecting Swat @Izzy +534 R Divergent Transformations @Kev Walker +535 R Drakuseth, Maw of Flames @Grzegorz Rutkowski +536 R Fiery Confluence @Kieran Yanner +537 R Godo, Bandit Warlord @Paolo Parente +538 R Grenzo, Havoc Raiser @Svetlin Velinov +539 R Heartless Hidetsugu @Carl Critchlow +540 R Hellkite Charger @Jaime Jones +541 R Inferno Titan @Kev Walker 542 M Insurrection @Mark Zug 543 R Krenko, Mob Boss @Karl Kopinski 544 R Magus of the Wheel @Carl Frank +545 M Neheb, the Eternal @Chris Rahn 546 R Nesting Dragon @Jehan Choo -548 R Savage Beating @Matt Thompson -550 M Star of Extinction @Chris Rahn +547 M Purphoros, God of the Forge @Eric Deschamps +548 M Savage Beating @Matt Thompson +549 R Scourge of the Throne @Michael Komarck +550 R Star of Extinction @Chris Rahn +551 R Tempt with Vengeance @Ryan Barger 552 R Treasure Nabber @Alex Konstad 554 R Azusa, Lost but Seeking @Winona Nelson +555 R Bloodspore Thrinax @Ralph Horsley +556 M Craterhoof Behemoth @Chris Rahn +557 M Doubling Season @Chuck Lukacs +558 R Ezuri's Predation @Uriah Voth 559 M Finale of Devastation @Bayard Wu +560 R Freyalise, Llanowar's Fury @Adam Paquette +561 R Ghalta, Primal Hunger @Chase Stone +562 M The Great Henge @Adam Paquette 563 R Heroic Intervention @James Ryman 564 R Jolrael, Mwonvuli Recluse @Izzy 565 R Lifeblood Hydra @Alex Horley-Orlandelli 566 R Obscuring Haze @Campbell White +567 R Ohran Frostfang @Torstein Nordstrand 568 M Omnath, Locus of Mana @Mike Bierek 569 R Regal Behemoth @Jakub Kasper 571 M Selvala, Heart of the Wilds @Tyler Jacobson +572 R Song of the Dryads @Lars Grant-West +573 R Stonehoof Chieftain @Camille Alquier +574 R Tooth and Nail @Greg Hildebrandt +575 R Verdant Confluence @Kieran Yanner 576 R Wayward Swordtooth @Chris Rahn 577 R Yisan, the Wanderer Bard @Chase Stone 578 R Experiment Kraj @Mark Tedin +579 R Gisela, Blade of Goldnight @Jason Chan +580 R Hanna, Ship's Navigator @Chris Rallis 581 R Karador, Ghost Chieftain @Todd Lockwood +582 R Kykar, Wind's Fury @G-host Lee 583 R Maelstrom Wanderer @Victor Adame Minguez -586 M Mizzix of the Izmagnus @Cliff Childs -587 M Nekusar, the Mindrazer @Mark Winters +584 R Meren of Clan Nel Toth @Mark Winters +585 R Mirri, Weatherlight Duelist @Magali Villeneuve +586 R Mizzix of the Izmagnus @Cliff Childs +587 R Nekusar, the Mindrazer @Mark Winters 588 R Queen Marchesa @Kieran Yanner +589 R Rafiq of the Many @Michael Komarck +590 M The Scarab God @Lius Lasahido +591 R Sek'Kuar, Deathkeeper @Jesper Ejsing +592 R Sidisi, Brood Tyrant @Karl Kopinski +593 R Teysa Karlov @Magali Villeneuve 594 M The Ur-Dragon @Jaime Jones +595 R Xantcha, Sleeper Agent @Mark Winters +599 R Zilortha, Strength Incarnate @Chase Stone 600 R Boompile @Filip Burburan 601 R Champion's Helm @Alan Pollack 602 R Chromatic Lantern @Jung Park 603 R Emerald Medallion @Daniel Ljunggren +604 M Extraplanar Lens @Lars Grant-West 606 R Hammer of Nazahn @Victor Adame Minguez +607 R Idol of Oblivion @Piotr Dura 608 M The Immortal Sun @Kieran Yanner +609 R Inspiring Statuary @Kirsten Zirngibl 610 R Jet Medallion @Daniel Ljunggren 611 M Jeweled Lotus @Alayna Danner 612 R Pearl Medallion @Daniel Ljunggren 613 R Ruby Medallion @Daniel Ljunggren 614 R Sapphire Medallion @Daniel Ljunggren -625 R Grand Abolisher @ +616 R Sword of the Animist @Daniel Ljunggren +623 U Darksteel Mutation @Richard Kane Ferguson +625 R Grand Abolisher @Richard Kane Ferguson 627 R Puresteel Paladin @Richard Kane Ferguson +629 R Steelshaper's Gift @Paolo Parente 633 R Personal Tutor @Jeff Miracola -635 M Spellseeker @ +634 U Reality Shift @Warren Mahy +635 M Spellseeker @Douglas Shuler +636 R Bloodchief Ascension @Warren Mahy +639 M Grave Pact @Kev Walker 640 R Kindred Dominance @Thomas M. Baxa 643 R Magus of the Wheel @Scott M. Fischer +644 U Storm-Kiln Artist @Chuck Lukacs 645 R Treasure Nabber @Pete Venters -646 U Vandalblast @ -651 R Regal Behemoth @ +646 U Vandalblast @Dermot Power +649 C Kodama's Reach @Ron Spencer +650 R Ohran Frostfang @Ron Spears +651 R Regal Behemoth @Kev Walker +652 R Tooth and Nail @Eric Velhagen 653 U Arcane Signet @Drew Tucker 654 R Champion's Helm @Paolo Parente -656 R Extraplanar Lens @Ron Spears +656 M Extraplanar Lens @Ron Spears 657 U Fellwar Stone @Randy Gallegos -658 U Thran Dynamo @ -661 C Path of Ancestry @ +658 U Thran Dynamo @Chuck Lukacs +659 C Command Tower @Donato Giancola +661 C Path of Ancestry @Mark Poole 663 U Reliquary Tower @Mark Poole 668 M Kozilek, the Great Distortion @Grant Griffin +669 M Morophon, the Boundless @Jack Hughes +670 M Ulamog, the Ceaseless Hunger @Cosmin Podar 671 U Kemba, Kha Regent @Peter Diamond +672 R Azami, Lady of Scrolls @Grant Griffin +673 R Talrand, Sky Summoner @Tyler Walpole +674 M Urza, Lord High Artificer @Grant Griffin +675 M Mikaeus, the Unhallowed @Benjamin Ee +677 R Grenzo, Havoc Raiser @Tyler Walpole +678 M Neheb, the Eternal @Alex Stone 679 R Azusa, Lost but Seeking @Benjamin Ee -680 M Omnath, Locus of Mana @ +680 M Omnath, Locus of Mana @Alex Dos Diaz 681 M Selvala, Heart of the Wilds @Jack Hughes +682 R Gisela, Blade of Goldnight @Alex Dos Diaz 683 R Kykar, Wind's Fury @April Prime -684 R Maelstrom Wanderer @ +684 R Maelstrom Wanderer @Benjamin Ee +685 R Meren of Clan Nel Toth @Vance Kelly +688 R Teysa Karlov @Jack Hughes 689 M The Ur-Dragon @Tyler Walpole +692 R Flawless Maneuver @Warren Mahy 693 M Smothering Tithe @Jeff Miracola -695 R Deadly Rollick @Izzy -699 M Insurrection @ +694 R Fierce Guardianship @ +695 R Deadly Rollick @Ron Spencer +696 M Demonic Tutor @Donato Giancola +697 M Balefire Dragon @Scott M. Fischer +698 R Deflecting Swat @Greg Staples +699 M Insurrection @Jeff Miracola 700 M Finale of Devastation @Daren Bader 701 R Obscuring Haze @Daren Bader 702 M Jeweled Lotus @Olena Richards @@ -234,8 +433,12 @@ ScryfallCode=CMM 781 M Commodore Guff @Matt Stewart 782 M Sliver Gravemother @Chris Rahn 1057 M Kozilek, the Great Distortion @Grant Griffin -1060 M Urza, Lord High Artificer @ -1063 M Omnath, Locus of Mana @ +1058 M Morophon, the Boundless @Jack Hughes +1059 M Ulamog, the Ceaseless Hunger @Cosmin Podar +1060 M Urza, Lord High Artificer @Grant Griffin +1061 M Mikaeus, the Unhallowed @Benjamin Ee +1062 M Neheb, the Eternal @Alex Stone +1063 M Omnath, Locus of Mana @Alex Dos Diaz 1064 M Selvala, Heart of the Wilds @Jack Hughes 1065 M The Ur-Dragon @Tyler Walpole 1066 M Jeweled Lotus @Olena Richards diff --git a/forge-gui/res/editions/The List.txt b/forge-gui/res/editions/The List.txt index 0d024109fb8..6112904fede 100644 --- a/forge-gui/res/editions/The List.txt +++ b/forge-gui/res/editions/The List.txt @@ -781,14 +781,14 @@ F567 R Puresteel Angel @Lukas Litzsinger 773 R Repay in Kind @Vance Kovacs 774 R Volrath's Dungeon @Stephen Daniele 775 C Dragon's Approach @Andrew Mar -776 U Dragon's Rage Channeler @Martina Fackova +776 U Dragon's Rage Channeler @Martina Fačková 777 M Goldspan Dragon @Andrew Mar 778 R Lathliss, Dragon Queen @Alex Konstad 779 U Magic Missile @PINDURSKI 780 U Thundering Sparkmage @Billy Christian 781 R Worldgorger Dragon @Wayne England 782 U Devoted Druid @Kimonas Theodossiou -783 U Druid's Call @Greg Hildebrandt +783 U Druid's Call @Greg Hildebrandt & Tim Hildebrandt 784 U Edgewall Innkeeper @Matt Stewart 785 R Gilt-Leaf Archdruid @Steve Prescott 786 M Old Gnawbone @Filip Burburan @@ -1095,3 +1095,78 @@ F567 R Puresteel Angel @Lukas Litzsinger 1087 R Sea of Clouds @Florian de Gesincourt 1088 R The World Tree @Anastasia Ovchinnikova 1089 U Zhalfirin Void @Chase Stone +1090 U All That Glitters @Iain McCaig +1091 U Baird, Steward of Argive @Christine Choi +1092 C Battleflight Eagle @Kev Walker +1093 R Court of Grace @Denman Rooke +1094 R Darien, King of Kjeldor @Michael Phillippi +1095 C Doomed Traveler @Lars Grant-West +1096 R Earnest Fellowship @Heather Hudson +1097 U Far Traveler @Alix Branwyn +1098 C Fortifying Provisions @Scott Murphy +1099 U Generous Gift @Kev Walker +1100 M Kenrith, the Returned King @Kieran Yanner +1101 R Knight-Captain of Eos @Chris Rahn +1102 R Knight Exemplar @Jason Chan +1103 C Oaken Brawler @Jim Murray +1104 R Ancestral Memories @Dan Frazier +1105 R Arcane Melee @Jaime Jones +1106 R Commandeer @John Matson +1107 R Counterlash @Austin Hsu +1108 R Denying Wind @Tony Szczudlo +1109 R Exhaustion @DiTerlizzi +1110 R Mindlock Orb @rk post +1111 R Oath of Scholars @Michael Sutfin +1112 R Rayne, Academy Chancellor @Matthew D. Wilson +1113 C Stormwatch Eagle @Aaron Boyd +1114 R Stroke of Genius @Stephen Daniele +1115 C Traveler's Cloak @Rebecca Guay +1116 C Barrow Ghoul @Bryan Talbot +1117 C Barrow Witches @Alex Brock +1118 U Bog Wraith @Daarken +1119 U Evil Eye of Urborg @Clint Langley +1120 U Grim Strider @Christine Choi +1121 U Orc Sureshot @Kev Walker +1122 R Pitiless Horde @Viktor Titov +1123 U Crush the Weak @Lucas Graciano +1124 R Dwarven Bloodboiler @Arnie Swekel +1125 C Dwarven Grunt @Mike Ploog +1126 U Dwarven Miner @Jock +1127 U Glittering Stockpile @Brock Grossman +1128 U Hoarding Dragon @Matt Cavotta +1129 C Miner's Bane @Adam Paquette +1130 U Orcish Artillery @Jeff Miracola +1131 R Reforge the Soul @Jaime Jones +1132 C Battlewand Oak @Steve Prescott +1133 U Blossom Prancer @Ryan Yee +1134 R Budoka Gardener @Kev Walker +1135 C Courage in Crisis @Micah Epstein +1136 R Dauntless Dourbark @Jeremy Jarvis +1137 U Elven Palisade @Mark Zug +1138 R Elven Warhounds @Kev Walker +1139 U Gather Courage @Brian Despain +1140 R Leaf-Crowned Elder @Wayne Reynolds +1141 U Murasa Ranger @Eric Deschamps +1142 R Nemata, Grove Guardian @John Avon +1143 R Unstoppable Ash @Brian Snõddy +1144 R Ancient Spider @Greg Staples +1145 R Doomsday Specter @Donato Giancola +1146 U Empyrean Eagle @Jason A. Engle +1147 R Ghastlord of Fugue @Mike Dringenberg +1148 R Gluttonous Troll @Joe Slucher +1149 R Jared Carthalion, True Heir @Lius Lasahido +1150 C Old Ghastbark @Thomas M. Baxa +1151 R Tolsimir, Friend to Wolves @Ryan Pancoast +1152 R Angelheart Vial @Chippy +1153 R Dolmen Gate @Richard Sardinha +1154 R Doom Cannon @Matthew Mitchell +1155 R Eye of Doom @Yeong-Hao Han +1156 R Forebear's Blade @Scott Murphy +1157 R Jinxed Ring @M. W. Kaluta +1158 R Rakdos Riteknife @Jim Nelson +1159 M Ring of Three Wishes @Mark Winters +1160 R Sword of Vengeance @Dan Scott +1161 R Tower of Calamities @Aleksi Briclot +1162 R Tower of Fortunes @Matt Cavotta +1163 R Wheel of Torture @Henry Van Der Linde +1164 U Forbidding Watchtower @Aleksi Briclot diff --git a/forge-gui/res/formats/Casual/Premodern.txt b/forge-gui/res/formats/Casual/Premodern.txt index 3213d670fa5..0decb40c04a 100644 --- a/forge-gui/res/formats/Casual/Premodern.txt +++ b/forge-gui/res/formats/Casual/Premodern.txt @@ -3,4 +3,4 @@ Name:Premodern Order:106 Type:Casual Sets:4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, WTH, TMP, STH, EXO, USG, ULG, 6ED, UDS, MMQ, NMS, PCY, INV, PLS, 7ED, APC, ODY, TOR, JUD, ONS, LGN, SCG -Banned:Amulet of Quoz; Balance; Brainstorm; Bronze Tablet; Channel; Demonic Consultation; Earthcraft; Entomb; Flash; Force of Will; Goblin Recruiter; Grim Monolith; Jeweled Bird; Mana Vault; Memory Jar; Mind Twist; Mind's Desire; Mystical Tutor; Necropotence; Rebirth; Strip Mine; Tempest Efreet; Tendrils of Agony; Time Spiral; Timmerian Fiends; Tolarian Academy; Vampiric Tutor; Windfall; Worldgorger Dragon; Yawgmoth's Bargain; Yawgmoth's Will \ No newline at end of file +Banned:Amulet of Quoz; Balance; Brainstorm; Bronze Tablet; Channel; Demonic Consultation; Earthcraft; Entomb; Flash; Force of Will; Goblin Recruiter; Grim Monolith; Jeweled Bird; Land Tax; Mana Vault; Memory Jar; Mind Twist; Mind's Desire; Mystical Tutor; Necropotence; Rebirth; Strip Mine; Tempest Efreet; Tendrils of Agony; Time Spiral; Timmerian Fiends; Tolarian Academy; Vampiric Tutor; Windfall; Worldgorger Dragon; Yawgmoth's Bargain; Yawgmoth's Will \ No newline at end of file diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index c7a023e0be1..1a49029b78c 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -2237,6 +2237,8 @@ lblSelectThisCardConfirm=Wähle diese Karte? #CardView.java lblMainGame=Hauptspiel lblSubgame=Unterspiel (Auslöser {0}) +lblHandSize=Handgröße +lblStartingLife=Leben beginnen #PlayerView.java lblCommanderCastCard=Wurde bereits {0} mal aus der Kommandozone gespielt lblCommanderCastPlayer={0} spielte {1} mal aus der Kommandozone diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 4f49f4eb537..3db1e4d8ba2 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -2242,6 +2242,8 @@ lblSelectThisCardConfirm=Select this card? #CardView.java lblMainGame=Main game lblSubgame=Subgame ({0} parent) +lblHandSize=Hand Size +lblStartingLife=Starting Life #PlayerView.java lblCommanderCastCard=Cast from command zone {0} times lblCommanderCastPlayer={0} cast from command zone {1} times diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 44fe1b33308..8f2900058ac 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -2238,6 +2238,8 @@ lblSelectThisCardConfirm=¿Selecciona esta carta? #CardView.java lblMainGame=Juego principal lblSubgame=Subjuego (padre {0}) +lblHandSize=Tamaño de la mano +lblStartingLife=La vida inicial #PlayerView.java lblCommanderCastCard=Lanzado desde la zona de comandante {0} veces lblCommanderCastPlayer={0} lanzado desde la zona de comandante {1} veces diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index d7db71bdacc..b40c7ecd6ad 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -2240,6 +2240,8 @@ lblSelectThisCardConfirm=Sélectionner cette carte ? #CardView.java lblMainGame=Jeu principal lblSubgame=Sous-jeu ({0} parent) +lblHandSize=Taille de la main +lblStartingLife=Début de la vie #PlayerView.java lblCommanderCastCard=Lancer depuis la zone de commande {0} fois lblCommanderCastPlayer={0} lancer de la zone de commande {1} fois diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index 36675f409cb..ec00c889d38 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -2237,6 +2237,8 @@ lblSelectThisCardConfirm=Vuoi scegliere questa carta? #CardView.java lblMainGame=Gioco principale lblSubgame=Sottopartita (da {0}) +lblHandSize=Dimensione delle mani +lblStartingLife=La vita iniziale #PlayerView.java lblCommanderCastCard=Lanciato dalla zona di comando {0} volte lblCommanderCastPlayer={0} è stato lanciato dalla zona di comando {1} volte diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index 8f8ffe0ad14..ce172950b02 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -2237,6 +2237,8 @@ lblSelectThisCardConfirm=このカードを選択しますか? #CardView.java lblMainGame=メインゲーム lblSubgame={0}つ上のサブゲーム +lblHandSize=ハンドサイズ +lblStartingLife=人生を始める #PlayerView.java lblCommanderCastCard=コマンド領域からキャスト:{0}回 lblCommanderCastPlayer={0}が {1}回コマンド領域からキャストした diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index cbf5491e4d7..cd5185a5336 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -2304,6 +2304,8 @@ lblSelectThisCardConfirm=Escolher este cartão? #CardView.java lblMainGame=Jogo Principal lblSubgame=Subjogo ({0} pai) +lblHandSize=Tamanho da mão +lblStartingLife=Começando a vida #PlayerView.java lblCommanderCastCard=Conjurado da zona de comando {0} vezes lblCommanderCastPlayer={0} conjurou da zona de comando {1} vezes diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 6fb1807dd17..76b12f413e7 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -2242,6 +2242,8 @@ lblSelectThisCardConfirm=选择这张牌? #CardView.java lblMainGame=主游戏 lblSubgame=子游戏({0}个父游戏) +lblHandSize=手尺寸 +lblStartingLife=开始生活 #PlayerView.java lblCommanderCastCard=从指挥官区域释放过{0}次 lblCommanderCastPlayer={0}从指挥官区域释放过{1}次