diff --git a/.github/workflows/test-build.yaml b/.github/workflows/test-build.yaml index 48082ff9a2b..48949da0e0c 100644 --- a/.github/workflows/test-build.yaml +++ b/.github/workflows/test-build.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [ '8', '11' ] + java: [ '11' ] name: Test with Java ${{ matrix.Java }} steps: - uses: actions/checkout@v3 diff --git a/forge-adventure/fallback_skin/title_bg_lq.png b/forge-adventure/fallback_skin/title_bg_lq.png index 22183d1f0b3..daeccff1431 100644 Binary files a/forge-adventure/fallback_skin/title_bg_lq.png and b/forge-adventure/fallback_skin/title_bg_lq.png differ diff --git a/forge-adventure/fallback_skin/title_bg_lq_portrait.png b/forge-adventure/fallback_skin/title_bg_lq_portrait.png index 08809b42adf..658ecdf2c4a 100644 Binary files a/forge-adventure/fallback_skin/title_bg_lq_portrait.png and b/forge-adventure/fallback_skin/title_bg_lq_portrait.png differ diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 1ae072133f1..185e1a3d1dc 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -790,6 +790,7 @@ public class AiAttackController { if (bAssault) { return prefDefender; } + // 2. attack planeswalkers List pwDefending = c.getDefendingPlaneswalkers(); if (!pwDefending.isEmpty()) { @@ -797,7 +798,7 @@ public class AiAttackController { return pwNearUlti != null ? pwNearUlti : ComputerUtilCard.getBestPlaneswalkerAI(pwDefending); } - // Get the preferred battle (prefer own battles, then ally battles) + // 3. Get the preferred battle (prefer own battles, then ally battles) final CardCollection defBattles = c.getDefendingBattles(); List ownBattleDefending = CardLists.filter(defBattles, CardPredicates.isController(ai)); List allyBattleDefending = CardLists.filter(defBattles, CardPredicates.isControlledByAnyOf(ai.getAllies())); @@ -1164,10 +1165,8 @@ public class AiAttackController { attritionalAttackers.remove(attritionalAttackers.size() - 1); } } - attackRounds += 1; - if (humanLife <= 0) { - doAttritionalAttack = true; - } + attackRounds++; + doAttritionalAttack = humanLife <= 0; } // ********************* // end attritional attack calculation @@ -1328,6 +1327,114 @@ public class AiAttackController { return aiAggression; } + private class SpellAbilityFactors { + Card attacker = null; + boolean canBeKilled = false; // indicates if the attacker can be killed + boolean canBeKilledByOne = false; // indicates if the attacker can be killed by a single blocker + boolean canKillAll = true; // indicates if the attacker can kill all single blockers + boolean canKillAllDangerous = true; // indicates if the attacker can kill all single blockers with wither or infect + boolean isWorthLessThanAllKillers = true; + boolean hasAttackEffect = false; + boolean hasCombatEffect = false; + boolean dangerousBlockersPresent = false; + boolean canTrampleOverDefenders = false; + int numberOfPossibleBlockers = 0; + int defPower = 0; + + SpellAbilityFactors(Card c) { + attacker = c; + } + + private boolean canBeBlocked() { + return numberOfPossibleBlockers > 2 + || (numberOfPossibleBlockers >= 1 && CombatUtil.canAttackerBeBlockedWithAmount(attacker, 1, defendingOpponent)) + || (numberOfPossibleBlockers == 2 && CombatUtil.canAttackerBeBlockedWithAmount(attacker, 2, defendingOpponent)); + } + + private void calculate(final List defenders, final Combat combat) { + hasAttackEffect = attacker.getSVar("HasAttackEffect").equals("TRUE") || attacker.hasKeyword(Keyword.ANNIHILATOR); + // is there a gain in attacking even when the blocker is not killed (Lifelink, Wither,...) + hasCombatEffect = attacker.getSVar("HasCombatEffect").equals("TRUE") || "Blocked".equals(attacker.getSVar("HasAttackEffect")) + || attacker.isWitherDamage() || attacker.hasKeyword(Keyword.LIFELINK) || attacker.hasKeyword(Keyword.AFFLICT); + + // contains only the defender's blockers that can actually block the attacker + CardCollection validBlockers = CardLists.filter(defenders, defender1 -> CombatUtil.canBlock(attacker, defender1)); + + canTrampleOverDefenders = attacker.hasKeyword(Keyword.TRAMPLE) && attacker.getNetCombatDamage() > Aggregates.sum(validBlockers, Card::getNetToughness); + + // used to check that CanKillAllDangerous check makes sense in context where creatures with dangerous abilities are present + dangerousBlockersPresent = validBlockers.anyMatch( + CardPredicates.hasKeyword(Keyword.WITHER) + .or(CardPredicates.hasKeyword(Keyword.INFECT)) + .or(CardPredicates.hasKeyword(Keyword.LIFELINK)) + ); + + // total power of the defending creatures, used in predicting whether a gang block can kill the attacker + defPower = CardLists.getTotalPower(validBlockers, true, false); + + // look at the attacker in relation to the blockers to establish a + // number of factors about the attacking context that will be relevant + // to the attackers decision according to the selected strategy + for (final Card blocker : validBlockers) { + // if both isWorthLessThanAllKillers and canKillAllDangerous are false there's nothing more to check + if (isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) { + numberOfPossibleBlockers += 1; + if (isWorthLessThanAllKillers && ComputerUtilCombat.canDestroyAttacker(ai, attacker, blocker, combat, false) + && !(attacker.hasKeyword(Keyword.UNDYING) && attacker.getCounters(CounterEnumType.P1P1) == 0)) { + canBeKilledByOne = true; // there is a single creature on the battlefield that can kill the creature + // see if the defending creature is of higher or lower + // value. We don't want to attack only to lose value + if (isWorthLessThanAllKillers && !attacker.hasSVar("SacMe") + && ComputerUtilCard.evaluateCreature(blocker) <= ComputerUtilCard.evaluateCreature(attacker)) { + isWorthLessThanAllKillers = false; + } + } + // see if this attacking creature can destroy this defender, if + // not record that it can't kill everything + if (canKillAllDangerous && !ComputerUtilCombat.canDestroyBlocker(ai, blocker, attacker, combat, false)) { + canKillAll = false; + + if (blocker.getSVar("HasCombatEffect").equals("TRUE") || blocker.getSVar("HasBlockEffect").equals("TRUE") + || blocker.hasKeyword(Keyword.WITHER) || blocker.hasKeyword(Keyword.INFECT) || blocker.hasKeyword(Keyword.LIFELINK)) { + canKillAllDangerous = false; + // there is a creature that can survive an attack from this creature + // and combat will have negative effects + } + + // Check if maybe we are too reckless in adding this attacker + if (canKillAllDangerous) { + boolean avoidAttackingIntoBlock = ai.getController().isAI() + && ((PlayerControllerAi) ai.getController()).getAi().getBooleanProperty(AiProps.TRY_TO_AVOID_ATTACKING_INTO_CERTAIN_BLOCK); + boolean attackerWillDie = defPower >= attacker.getNetToughness(); + boolean uselessAttack = !hasCombatEffect && !hasAttackEffect; + boolean noContributionToAttack = attackers.size() <= defenders.size() || attacker.getNetPower() <= 0; + + // We are attacking too recklessly if we can't kill a single blocker and: + // - our creature will die for sure (chump attack) + // - our attack will not do anything special (no attack/combat effect to proc) + // - we can't deal damage to our opponent with sheer number of attackers and/or our attacker's power is 0 or less + if (attackerWillDie || (avoidAttackingIntoBlock && uselessAttack && noContributionToAttack)) { + canKillAllDangerous = false; + } + } + } + } + } + + // performance-wise it doesn't seem worth it to check attackVigilance() instead (only includes a single niche card) + if (!attacker.hasKeyword(Keyword.VIGILANCE) && ComputerUtilCard.canBeKilledByRoyalAssassin(ai, attacker)) { + canKillAllDangerous = false; + canBeKilled = true; + canBeKilledByOne = true; + isWorthLessThanAllKillers = false; + hasCombatEffect = false; + } else if ((canKillAllDangerous || !canBeKilled) && ComputerUtilCard.canBeBlockedProfitably(defendingOpponent, attacker, true)) { + canKillAllDangerous = false; + canBeKilled = true; + } + } + } + /** *

* shouldAttack. @@ -1342,14 +1449,6 @@ public class AiAttackController { * @return a boolean. */ public final boolean shouldAttack(final Card attacker, final List defenders, final Combat combat, final GameEntity defender) { - boolean canBeKilled = false; // indicates if the attacker can be killed - boolean canBeKilledByOne = false; // indicates if the attacker can be killed by a single blocker - boolean canKillAll = true; // indicates if the attacker can kill all single blockers - boolean canKillAllDangerous = true; // indicates if the attacker can kill all single blockers with wither or infect - boolean isWorthLessThanAllKillers = true; - boolean canBeBlocked = false; - int numberOfPossibleBlockers = 0; - // Is it a creature that has a more valuable ability with a tap cost than what it can do by attacking? if (attacker.hasSVar("NonCombatPriority") && !attacker.hasKeyword(Keyword.VIGILANCE)) { // For each level of priority, enemy has to have life as much as the creature's power @@ -1360,7 +1459,7 @@ public class AiAttackController { // Check if the card actually has an ability the AI can and wants to play, if not, attacking is fine! for (SpellAbility sa : attacker.getSpellAbilities()) { // Do not attack if we can afford using the ability. - if (sa.isActivatedAbility()) { + if (sa.isActivatedAbility() && sa.getPayCosts().hasTapCost()) { if (ComputerUtilCost.canPayCost(sa, ai, false)) { return false; } @@ -1374,115 +1473,29 @@ public class AiAttackController { if (!isEffectiveAttacker(ai, attacker, combat, defender)) { return false; } - boolean hasAttackEffect = attacker.getSVar("HasAttackEffect").equals("TRUE") || attacker.hasKeyword(Keyword.ANNIHILATOR); - // is there a gain in attacking even when the blocker is not killed (Lifelink, Wither,...) - boolean hasCombatEffect = attacker.getSVar("HasCombatEffect").equals("TRUE") || "Blocked".equals(attacker.getSVar("HasAttackEffect")); - if (!hasCombatEffect) { - if (attacker.isWitherDamage() || attacker.hasKeyword(Keyword.LIFELINK) || attacker.hasKeyword(Keyword.AFFLICT)) { - hasCombatEffect = true; - } - } - - // contains only the defender's blockers that can actually block the attacker - CardCollection validBlockers = CardLists.filter(defenders, defender1 -> CombatUtil.canBlock(attacker, defender1)); - - boolean canTrampleOverDefenders = attacker.hasKeyword(Keyword.TRAMPLE) && attacker.getNetCombatDamage() > Aggregates.sum(validBlockers, Card::getNetToughness); - - // used to check that CanKillAllDangerous check makes sense in context where creatures with dangerous abilities are present - boolean dangerousBlockersPresent = validBlockers.anyMatch( - CardPredicates.hasKeyword(Keyword.WITHER) - .or(CardPredicates.hasKeyword(Keyword.INFECT)) - .or(CardPredicates.hasKeyword(Keyword.LIFELINK)) - ); - - // total power of the defending creatures, used in predicting whether a gang block can kill the attacker - int defPower = CardLists.getTotalPower(validBlockers, true, false); - - // look at the attacker in relation to the blockers to establish a - // number of factors about the attacking context that will be relevant - // to the attackers decision according to the selected strategy - for (final Card blocker : validBlockers) { - // if both isWorthLessThanAllKillers and canKillAllDangerous are false there's nothing more to check - if (isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) { - numberOfPossibleBlockers += 1; - if (isWorthLessThanAllKillers && ComputerUtilCombat.canDestroyAttacker(ai, attacker, blocker, combat, false) - && !(attacker.hasKeyword(Keyword.UNDYING) && attacker.getCounters(CounterEnumType.P1P1) == 0)) { - canBeKilledByOne = true; // there is a single creature on the battlefield that can kill the creature - // see if the defending creature is of higher or lower - // value. We don't want to attack only to lose value - if (isWorthLessThanAllKillers && !attacker.hasSVar("SacMe") - && ComputerUtilCard.evaluateCreature(blocker) <= ComputerUtilCard.evaluateCreature(attacker)) { - isWorthLessThanAllKillers = false; - } - } - // see if this attacking creature can destroy this defender, if - // not record that it can't kill everything - if (canKillAllDangerous && !ComputerUtilCombat.canDestroyBlocker(ai, blocker, attacker, combat, false)) { - canKillAll = false; - if (blocker.getSVar("HasCombatEffect").equals("TRUE") || blocker.getSVar("HasBlockEffect").equals("TRUE")) { - canKillAllDangerous = false; - } else { - if (blocker.hasKeyword(Keyword.WITHER) || blocker.hasKeyword(Keyword.INFECT) - || blocker.hasKeyword(Keyword.LIFELINK)) { - canKillAllDangerous = false; - // there is a creature that can survive an attack from this creature - // and combat will have negative effects - } - - // Check if maybe we are too reckless in adding this attacker - if (canKillAllDangerous) { - boolean avoidAttackingIntoBlock = ai.getController().isAI() - && ((PlayerControllerAi) ai.getController()).getAi().getBooleanProperty(AiProps.TRY_TO_AVOID_ATTACKING_INTO_CERTAIN_BLOCK); - boolean attackerWillDie = defPower >= attacker.getNetToughness(); - boolean uselessAttack = !hasCombatEffect && !hasAttackEffect; - boolean noContributionToAttack = this.attackers.size() <= defenders.size() || attacker.getNetPower() <= 0; - - // We are attacking too recklessly if we can't kill a single blocker and: - // - our creature will die for sure (chump attack) - // - our attack will not do anything special (no attack/combat effect to proc) - // - we can't deal damage to our opponent with sheer number of attackers and/or our attacker's power is 0 or less - if (attackerWillDie || (avoidAttackingIntoBlock && uselessAttack && noContributionToAttack)) { - canKillAllDangerous = false; - } - } - } - } - } - } - - if (!attacker.hasKeyword(Keyword.VIGILANCE) && ComputerUtilCard.canBeKilledByRoyalAssassin(ai, attacker)) { - canKillAllDangerous = false; - canBeKilled = true; - canBeKilledByOne = true; - isWorthLessThanAllKillers = false; - hasCombatEffect = false; - } else if ((canKillAllDangerous || !canBeKilled) && ComputerUtilCard.canBeBlockedProfitably(defendingOpponent, attacker, true)) { - canKillAllDangerous = false; - canBeKilled = true; + SpellAbilityFactors saf = new SpellAbilityFactors(attacker); + if (aiAggression != 5) { + saf.calculate(defenders, combat); } // if the creature cannot block and can kill all opponents they might as // well attack, they do nothing staying back - if (canKillAll && isWorthLessThanAllKillers && !CombatUtil.canBlock(attacker)) { + if (saf.canKillAll && saf.isWorthLessThanAllKillers && !CombatUtil.canBlock(attacker)) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking because they can't block, expecting to kill or damage player"); return true; - } else if (!canBeKilled && !dangerousBlockersPresent && canTrampleOverDefenders) { + } + if (!saf.canBeKilled && !saf.dangerousBlockersPresent && saf.canTrampleOverDefenders) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = expecting to survive and get some Trample damage through"); return true; } - if (numberOfPossibleBlockers > 2 - || (numberOfPossibleBlockers >= 1 && CombatUtil.canAttackerBeBlockedWithAmount(attacker, 1, defendingOpponent)) - || (numberOfPossibleBlockers == 2 && CombatUtil.canAttackerBeBlockedWithAmount(attacker, 2, defendingOpponent))) { - canBeBlocked = true; - } // decide if the creature should attack based on the prevailing strategy choice in aiAggression switch (aiAggression) { case 6: // Exalted: expecting to at least kill a creature of equal value or not be blocked - if ((canKillAll && isWorthLessThanAllKillers) || !canBeBlocked) { + if ((saf.canKillAll && saf.isWorthLessThanAllKillers) || !saf.canBeBlocked()) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting to kill creature, or is unblockable"); return true; @@ -1493,32 +1506,32 @@ public class AiAttackController { System.out.println(attacker.getName() + " = all out attacking"); return true; case 4: // expecting to at least trade with something, or can attack "for free", expecting no counterattack - if (canKillAll || (dangerousBlockersPresent && canKillAllDangerous && !canBeKilledByOne) || !canBeBlocked - || (defPower == 0 && !ComputerUtilCombat.lifeInDanger(ai, combat))) { + if (saf.canKillAll || (saf.dangerousBlockersPresent && saf.canKillAllDangerous && !saf.canBeKilledByOne) || !saf.canBeBlocked() + || saf.defPower == 0) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting to at least trade with something"); return true; } break; case 3: // expecting to at least kill a creature of equal value or not be blocked - if ((canKillAll && isWorthLessThanAllKillers) - || (((dangerousBlockersPresent && canKillAllDangerous) || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne) - || !canBeBlocked) { + if ((saf.canKillAll && saf.isWorthLessThanAllKillers) + || (((saf.dangerousBlockersPresent && saf.canKillAllDangerous) || saf.hasAttackEffect || saf.hasCombatEffect) && !saf.canBeKilledByOne) + || !saf.canBeBlocked()) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting to kill creature or cause damage, or is unblockable"); return true; } break; case 2: // attack expecting to attract a group block or destroying a single blocker and surviving - if (!canBeBlocked || ((canKillAll || hasAttackEffect || hasCombatEffect) && !canBeKilledByOne && - ((dangerousBlockersPresent && canKillAllDangerous) || !canBeKilled))) { + if (!saf.canBeBlocked() || ((saf.canKillAll || saf.hasAttackEffect || saf.hasCombatEffect) && !saf.canBeKilledByOne && + ((saf.dangerousBlockersPresent && saf.canKillAllDangerous) || !saf.canBeKilled))) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block"); return true; } break; case 1: // unblockable creatures only - if (!canBeBlocked || (numberOfPossibleBlockers == 1 && canKillAll && !canBeKilledByOne)) { + if (!saf.canBeBlocked() || (saf.numberOfPossibleBlockers == 1 && saf.canKillAll && !saf.canBeKilledByOne)) { if (LOG_AI_ATTACKS) System.out.println(attacker.getName() + " = attacking expecting not to be blocked"); return true; diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 5e4b05faa86..91317e57a54 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -53,6 +53,7 @@ import forge.game.combat.CombatUtil; import forge.game.keyword.Keyword; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; +import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementLayer; @@ -918,7 +919,7 @@ public class ComputerUtil { } } else if (isOptional && source.getActivatingPlayer().isOpponentOf(ai)) { if ("Pillar Tombs of Aku".equals(host.getName())) { - if (!ai.canLoseLife() || ai.cantLose()) { + if (!ai.canLoseLife() || ai.cantLoseForZeroOrLessLife()) { return sacrificed; // sacrifice none } } else { @@ -2686,7 +2687,7 @@ public class ComputerUtil { return Iterables.getFirst(votes.keySet(), null); case "FeatherOrQuill": // try to mill opponent with Quill vote - if (opponent && !controller.cantLose()) { + if (opponent && !controller.cantLoseCheck(GameLossReason.Milled)) { int numQuill = votes.get("Quill").size(); if (numQuill + 1 >= controller.getCardsIn(ZoneType.Library).size()) { return controller.isCardInPlay("Laboratory Maniac") ? "Feather" : "Quill"; @@ -3249,7 +3250,7 @@ public class ComputerUtil { // performance shortcut // TODO if checking upcoming turn it should be a permanent effect - if (ai.cantLose()) { + if (ai.cantLoseForZeroOrLessLife()) { return remainingLife; } @@ -3308,8 +3309,7 @@ public class ComputerUtil { repParams.put(AbilityKey.EffectOnly, true); repParams.put(AbilityKey.CounterTable, table); repParams.put(AbilityKey.CounterMap, table.column(c)); - List list = c.getGame().getReplacementHandler().getReplacementList(ReplacementType.Moved, repParams, ReplacementLayer.CantHappen); - return !list.isEmpty(); + return c.getGame().getReplacementHandler().cantHappenCheck(ReplacementType.Moved, repParams); } public static boolean shouldSacrificeThreatenedCard(Player ai, Card c, SpellAbility sa) { diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java b/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java index b08e4e3bd3e..589a28781e4 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java @@ -353,7 +353,7 @@ public class ComputerUtilAbility { } // 1. increase chance of using Surge effects // 2. non-surged versions are usually inefficient - if (source.getOracleText().contains("surge cost") && !sa.isSurged()) { + if (source.hasKeyword(Keyword.SURGE) && !sa.isSurged()) { p -= 9; } // move snap-casted spells to front @@ -386,8 +386,10 @@ public class ComputerUtilAbility { } if (ApiType.DestroyAll == sa.getApi()) { + // check boardwipe earlier p += 4; } else if (ApiType.Mana == sa.getApi()) { + // keep mana abilities for paying p -= 9; } @@ -398,7 +400,7 @@ public class ComputerUtilAbility { return p; } - }; + } public static List sortCreatureSpells(final List all) { // try to smoothen power creep by making CMC less of a factor diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index 050574ba77c..3929f8c4702 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -389,7 +389,7 @@ public class ComputerUtilCard { if (Iterables.size(list) == 1) { return Iterables.get(list, 0); } - return Aggregates.itemWithMax(Iterables.filter(list, CardPredicates.LANDS), ComputerUtilCard.landEvaluator); + return Aggregates.itemWithMax(Iterables.filter(list, Card::hasPlayableLandFace), ComputerUtilCard.landEvaluator); } /** @@ -1752,7 +1752,7 @@ public class ComputerUtilCard { pumped.addPTBoost(power + berserkPower, toughness, timestamp, 0); if (!kws.isEmpty()) { - pumped.addChangedCardKeywords(kws, null, false, timestamp, 0, false); + pumped.addChangedCardKeywords(kws, null, false, timestamp, null, false); } if (!hiddenKws.isEmpty()) { pumped.addHiddenExtrinsicKeywords(timestamp, 0, hiddenKws); @@ -1773,7 +1773,7 @@ public class ComputerUtilCard { } } final long timestamp2 = c.getGame().getNextTimestamp(); //is this necessary or can the timestamp be re-used? - pumped.addChangedCardKeywordsInternal(toCopy, null, false, timestamp2, 0, false); + pumped.addChangedCardKeywordsInternal(toCopy, null, false, timestamp2, null, false); pumped.updateKeywordsCache(pumped.getCurrentState()); applyStaticContPT(ai.getGame(), pumped, new CardCollection(c)); return pumped; diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index a25568f1e73..bd63ed91c50 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -724,7 +724,6 @@ public class ComputerUtilCombat { return totalDamageOfBlockers(attacker, blockers) >= getDamageToKill(attacker, false); } - // Will this trigger trigger? /** *

* combatTriggerWillTrigger. diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index debf378a313..e663feb77da 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -391,6 +391,10 @@ public abstract class GameState { } newText.append("|MergedCards:").append(TextUtil.join(mergedCardNames, ",")); } + + if (c.getClassLevel() > 1) { + newText.append("|ClassLevel:").append(c.getClassLevel()); + } } if (zoneType == ZoneType.Exile) { @@ -1179,9 +1183,8 @@ public abstract class GameState { zone.setCards(kv.getValue()); } } - for (Card cmd : p.getCommanders()) { - p.getZone(ZoneType.Command).add(Player.createCommanderEffect(p.getGame(), cmd)); - } + if (!p.getCommanders().isEmpty()) + p.createCommanderEffect(); //Original one was lost, and the one made by addCommander would have been erased by setCards. updateManaPool(p, state.manaPool, true, false); updateManaPool(p, state.persistentMana, false, true); @@ -1327,10 +1330,7 @@ public abstract class GameState { c.setExiledWith(c); // This seems to be the way it's set up internally. Potentially not needed here? c.setExiledBy(c.getController()); } else if (info.startsWith("IsCommander")) { - c.setCommander(true); - List cmd = Lists.newArrayList(player.getCommanders()); - cmd.add(c); - player.setCommanders(cmd); + player.addCommander(c); } else if (info.startsWith("IsRingBearer")) { c.setRingBearer(true); player.setRingBearer(c); @@ -1398,6 +1398,8 @@ public abstract class GameState { c.setTurnInZone(turn); } else if (info.equals("IsToken")) { c.setGamePieceType(GamePieceType.TOKEN); + } else if (info.equals("ClassLevel:")) { + c.setClassLevel(Integer.parseInt(info.substring(info.indexOf(':') + 1))); } } diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index a0840e36e77..d311f927525 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -722,6 +722,7 @@ public class DamageDealAi extends DamageAiBase { if (sa.canTarget(enemy) && sa.canAddMoreTarget()) { if ((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai)) || (isSorcerySpeed(sa, ai) && phase.is(PhaseType.MAIN2)) + || ("BurnCreatures".equals(logic) && !enemy.getCreaturesInPlay().isEmpty()) || immediately) { boolean pingAfterAttack = "PingAfterAttack".equals(logic) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai); boolean isPWAbility = sa.isPwAbility() && sa.getPayCosts().hasSpecificCostType(CostPutCounter.class); diff --git a/forge-ai/src/main/java/forge/ai/ability/DrawAi.java b/forge-ai/src/main/java/forge/ai/ability/DrawAi.java index 072125b3340..453f45ac6f5 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DrawAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DrawAi.java @@ -38,6 +38,7 @@ import forge.game.card.CounterType; import forge.game.cost.*; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; +import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.player.PlayerCollection; @@ -325,7 +326,7 @@ public class DrawAi extends SpellAbilityAi { } // try to kill opponent - if (oppA.cantLose() || !oppA.canDraw()) { + if (oppA.cantLoseCheck(GameLossReason.Milled) || !oppA.canDraw()) { continue; } diff --git a/forge-ai/src/main/java/forge/ai/ability/FlipACoinAi.java b/forge-ai/src/main/java/forge/ai/ability/FlipACoinAi.java index efa2a43fdb3..1dce017bc3a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/FlipACoinAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/FlipACoinAi.java @@ -28,7 +28,7 @@ public class FlipACoinAi extends SpellAbilityAi { } sa.resetTargets(); for (Player o : ai.getOpponents()) { - if (sa.canTarget(o) && o.canLoseLife() && !o.cantLose()) { + if (sa.canTarget(o) && o.canLoseLife() && !o.cantLoseForZeroOrLessLife()) { sa.getTargets().add(o); return true; } diff --git a/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java b/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java index f020dd25ca3..778446f6f38 100644 --- a/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java @@ -199,7 +199,7 @@ public class LifeLoseAi extends SpellAbilityAi { // try first to find Opponent that can lose life and lose the game if (!opps.isEmpty()) { for (Player opp : opps) { - if (opp.canLoseLife() && !opp.cantLose()) { + if (opp.canLoseLife() && !opp.cantLoseForZeroOrLessLife()) { sa.getTargets().add(opp); return true; } diff --git a/forge-ai/src/main/java/forge/ai/ability/PoisonAi.java b/forge-ai/src/main/java/forge/ai/ability/PoisonAi.java index 78359bbd9f6..4e3a4428b14 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PoisonAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PoisonAi.java @@ -7,6 +7,7 @@ import forge.game.card.CounterEnumType; import forge.game.card.CounterType; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; +import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.player.PlayerCollection; import forge.game.player.PlayerPredicates; @@ -85,7 +86,7 @@ public class PoisonAi extends SpellAbilityAi { if (!tgts.isEmpty()) { // try to select a opponent that can lose through poison counters PlayerCollection betterTgts = tgts.filter(input -> { - if (input.cantLose()) { + if (input.cantLoseCheck(GameLossReason.Poisoned)) { return false; } else if (!input.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) { return false; @@ -106,7 +107,7 @@ public class PoisonAi extends SpellAbilityAi { if (tgts.isEmpty()) { if (mandatory) { // AI is uneffected - if (ai.canBeTargetedBy(sa) && ai.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) { + if (ai.canBeTargetedBy(sa) && !ai.canReceiveCounters(CounterType.get(CounterEnumType.POISON))) { sa.getTargets().add(ai); return true; } @@ -115,7 +116,7 @@ public class PoisonAi extends SpellAbilityAi { if (!allies.isEmpty()) { // some ally would be unaffected PlayerCollection betterAllies = allies.filter(input -> { - if (input.cantLose()) { + if (input.cantLoseCheck(GameLossReason.Poisoned)) { return true; } return !input.canReceiveCounters(CounterType.get(CounterEnumType.POISON)); diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java index f697679e0af..408d820eaa5 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java @@ -17,6 +17,7 @@ import forge.ai.LobbyPlayerAi; import forge.card.CardRarity; import forge.card.CardRules; import forge.game.*; +import forge.game.ability.effects.DetachedCardEffect; import forge.game.card.*; import forge.game.card.token.TokenInfo; import forge.game.combat.Combat; @@ -66,11 +67,7 @@ public class GameCopier { } public Game makeCopy() { - if (origGame.EXPERIMENTAL_RESTORE_SNAPSHOT) { - return snapshot.makeCopy(); - } else { - return makeCopy(null, null); - } + return makeCopy(null, null); } public Game makeCopy(PhaseType advanceToPhase, Player aiPlayer) { if (origGame.EXPERIMENTAL_RESTORE_SNAPSHOT) { @@ -115,7 +112,6 @@ public class GameCopier { for (Mana m : origPlayer.getManaPool()) { newPlayer.getManaPool().addMana(m, false); } - newPlayer.setCommanders(origPlayer.getCommanders()); // will be fixed up below playerMap.put(origPlayer, newPlayer); } @@ -129,27 +125,10 @@ public class GameCopier { copyGameState(newGame, aiPlayer); - for (Player p : newGame.getPlayers()) { - List commanders = Lists.newArrayList(); - for (final Card c : p.getCommanders()) { - commanders.add(gameObjectMap.map(c)); - } - p.setCommanders(commanders); - ((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(true); - } for (Player origPlayer : playerMap.keySet()) { Player newPlayer = playerMap.get(origPlayer); - for (final Card c : origPlayer.getCommanders()) { - Card newCommander = gameObjectMap.map(c); - int castTimes = origPlayer.getCommanderCast(c); - for (int i = 0; i < castTimes; i++) { - newPlayer.incCommanderCast(newCommander); - } - } - for (Map.Entry entry : origPlayer.getCommanderDamage()) { - Card newCommander = gameObjectMap.map(entry.getKey()); - newPlayer.addCommanderDamage(newCommander, entry.getValue()); - } + origPlayer.copyCommandersToSnapshot(newPlayer, gameObjectMap::map); + ((PlayerZoneBattlefield) newPlayer.getZone(ZoneType.Battlefield)).setTriggers(true); } newGame.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); @@ -328,7 +307,11 @@ public class GameCopier { // The issue is that it requires parsing the original card from scratch from the paper card. We should // improve the copier to accurately copy the card from its actual state, so that the paper card shouldn't // be needed. Once the below code accurately copies the card, remove the USE_FROM_PAPER_CARD code path. - Card newCard = new Card(newGame.nextCardId(), c.getPaperCard(), newGame); + Card newCard; + if (c instanceof DetachedCardEffect) + newCard = new DetachedCardEffect((DetachedCardEffect) c, newGame, true); + else + newCard = new Card(newGame.nextCardId(), c.getPaperCard(), newGame); newCard.setOwner(newOwner); newCard.setName(c.getName()); newCard.setCommander(c.isCommander()); diff --git a/forge-core/src/main/java/forge/card/CardEdition.java b/forge-core/src/main/java/forge/card/CardEdition.java index 83673de5470..c24c5d0b011 100644 --- a/forge-core/src/main/java/forge/card/CardEdition.java +++ b/forge-core/src/main/java/forge/card/CardEdition.java @@ -132,8 +132,11 @@ public final class CardEdition implements Comparable { SPECIAL_SLOT("special slot"), //to help with convoluted boosters PRECON_PRODUCT("precon product"), BORDERLESS("borderless"), + BORDERLESS_PROFILE("borderless profile"), + BORDERLESS_FRAME("borderless frame"), ETCHED("etched"), SHOWCASE("showcase"), + FULL_ART("full art"), EXTENDED_ART("extended art"), ALTERNATE_ART("alternate art"), ALTERNATE_FRAME("alternate frame"), diff --git a/forge-core/src/main/java/forge/card/CardFace.java b/forge-core/src/main/java/forge/card/CardFace.java index 41e487afdff..2fbf01e2664 100644 --- a/forge-core/src/main/java/forge/card/CardFace.java +++ b/forge-core/src/main/java/forge/card/CardFace.java @@ -156,6 +156,9 @@ final class CardFace implements ICardFace, Cloneable { return null; return this.functionalVariants.get(variant); } + @Override public Map getFunctionalVariants() { + return this.functionalVariants; + } CardFace getOrCreateFunctionalVariant(String variant) { if (this.functionalVariants == null) { this.functionalVariants = new HashMap<>(); diff --git a/forge-core/src/main/java/forge/card/CardRulesPredicates.java b/forge-core/src/main/java/forge/card/CardRulesPredicates.java index 70023b36766..cc31ba35f09 100644 --- a/forge-core/src/main/java/forge/card/CardRulesPredicates.java +++ b/forge-core/src/main/java/forge/card/CardRulesPredicates.java @@ -323,6 +323,17 @@ public final class CardRulesPredicates { if (face == null) { return false; } + if (face.hasFunctionalVariants()) { + for (Map.Entry v : face.getFunctionalVariants().entrySet()) { + //Not a very pretty implementation, but an ICardFace doesn't have a specific variant, so they all need to be checked. + String origOracle = v.getValue().getOracleText(); + if(op(origOracle, operand)) + return true; + String name = v.getValue().getName() + " $" + v.getKey(); + if(op(CardTranslation.getTranslatedOracle(name), operand)) + return true; + } + } if (op(face.getOracleText(), operand) || op(CardTranslation.getTranslatedOracle(face.getName()), operand)) { return true; } @@ -332,6 +343,16 @@ public final class CardRulesPredicates { if (face == null) { return false; } + if (face.hasFunctionalVariants()) { + for (Map.Entry v : face.getFunctionalVariants().entrySet()) { + String origType = v.getValue().getType().toString(); + if(op(origType, operand)) + return true; + String name = v.getValue().getName() + " $" + v.getKey(); + if(op(CardTranslation.getTranslatedType(name, origType), operand)) + return true; + } + } return (op(CardTranslation.getTranslatedType(face.getName(), face.getType().toString()), operand) || op(face.getType().toString(), operand)); } diff --git a/forge-core/src/main/java/forge/card/CardType.java b/forge-core/src/main/java/forge/card/CardType.java index ae289765fe2..0cc9727153a 100644 --- a/forge-core/src/main/java/forge/card/CardType.java +++ b/forge-core/src/main/java/forge/card/CardType.java @@ -47,6 +47,7 @@ public final class CardType implements Comparable, CardTypeView { public static final CardTypeView EMPTY = new CardType(false); public enum CoreType { + Kindred(false, "kindreds"), // always printed first Artifact(true, "artifacts"), Battle(true, "battles"), Conspiracy(false, "conspiracies"), @@ -60,7 +61,6 @@ public final class CardType implements Comparable, CardTypeView { Planeswalker(true, "planeswalkers"), Scheme(false, "schemes"), Sorcery(false, "sorceries"), - Kindred(false, "kindreds"), Vanguard(false, "vanguards"); public final boolean isPermanent; diff --git a/forge-core/src/main/java/forge/card/ICardFace.java b/forge-core/src/main/java/forge/card/ICardFace.java index 24fb2c86611..494e234c6df 100644 --- a/forge-core/src/main/java/forge/card/ICardFace.java +++ b/forge-core/src/main/java/forge/card/ICardFace.java @@ -1,5 +1,7 @@ package forge.card; +import java.util.Map; + /** * TODO: Write javadoc for this type. * @@ -9,4 +11,5 @@ public interface ICardFace extends ICardCharacteristics, ICardRawAbilites, Compa boolean hasFunctionalVariants(); ICardFace getFunctionalVariant(String variant); + Map getFunctionalVariants(); } diff --git a/forge-core/src/main/java/forge/item/BoosterSlot.java b/forge-core/src/main/java/forge/item/BoosterSlot.java index eb4c5388ec2..df89d961a28 100644 --- a/forge-core/src/main/java/forge/item/BoosterSlot.java +++ b/forge-core/src/main/java/forge/item/BoosterSlot.java @@ -45,7 +45,7 @@ public class BoosterSlot { } public String replaceSlot() { - double rand = Math.random() * 100; + float rand = (float) Math.random(); for (Float key : slotPercentages.keySet()) { if (rand < key) { System.out.println("Replaced a base slot! " + slotName + " -> " + slotPercentages.get(key)); diff --git a/forge-core/src/main/java/forge/item/IPaperCard.java b/forge-core/src/main/java/forge/item/IPaperCard.java index e30a3535a59..e653c7f2b36 100644 --- a/forge-core/src/main/java/forge/item/IPaperCard.java +++ b/forge-core/src/main/java/forge/item/IPaperCard.java @@ -37,5 +37,22 @@ public interface IPaperCard extends InventoryItem, Serializable { String getCardRSpecImageKey(); String getCardGSpecImageKey(); - public boolean isRebalanced(); + boolean isRebalanced(); + + @Override + default String getTranslationKey() { + if(!NO_FUNCTIONAL_VARIANT.equals(getFunctionalVariant())) + return getName() + " $" + getFunctionalVariant(); + return getName(); + } + + @Override + default String getUntranslatedType() { + return getRules().getType().toString(); + } + + @Override + default String getUntranslatedOracle() { + return getRules().getOracleText(); + } } \ No newline at end of file diff --git a/forge-core/src/main/java/forge/item/InventoryItem.java b/forge-core/src/main/java/forge/item/InventoryItem.java index df8e20a1818..4de644d0489 100644 --- a/forge-core/src/main/java/forge/item/InventoryItem.java +++ b/forge-core/src/main/java/forge/item/InventoryItem.java @@ -17,13 +17,18 @@ */ package forge.item; -import forge.util.IHasName; +import forge.util.ITranslatable; /** * Interface to define a player's inventory may hold. Should include * CardPrinted, Booster, Pets, Plants... etc */ -public interface InventoryItem extends IHasName { +public interface InventoryItem extends ITranslatable { String getItemType(); String getImageKey(boolean altState); + + @Override + default String getUntranslatedType() { + return getItemType(); + } } diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index 64107935513..a09e0fd85e9 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -138,11 +138,6 @@ public class PaperCard implements Comparable, InventoryItemFromSet, return unFoiledVersion; } -// @Override -// public String getImageKey() { -// return getImageLocator(getImageName(), getArtIndex(), true, false); -// } - @Override public String getItemType() { final Localizer localizer = Localizer.getInstance(); diff --git a/forge-core/src/main/java/forge/item/generation/BoosterGenerator.java b/forge-core/src/main/java/forge/item/generation/BoosterGenerator.java index 679a2f6eea4..0d7f78c7f75 100644 --- a/forge-core/src/main/java/forge/item/generation/BoosterGenerator.java +++ b/forge-core/src/main/java/forge/item/generation/BoosterGenerator.java @@ -410,6 +410,11 @@ public class BoosterGenerator { BoosterSlot boosterSlot = boosterSlots.get(slotType); String determineSheet = boosterSlot.replaceSlot(); + if (determineSheet.endsWith("+")) { + determineSheet = determineSheet.substring(0, determineSheet.length() - 1); + convertCardFoil = true; + } + String setCode = template.getEdition(); // Ok, so we have a sheet now. Most should be standard sheets, but some named edition sheets diff --git a/forge-core/src/main/java/forge/util/CardTranslation.java b/forge-core/src/main/java/forge/util/CardTranslation.java index ed6d976115e..3912e2daf83 100644 --- a/forge-core/src/main/java/forge/util/CardTranslation.java +++ b/forge-core/src/main/java/forge/util/CardTranslation.java @@ -28,6 +28,15 @@ public class CardTranslation { for (String line : translationFile.readLines()) { String[] matches = line.split("\\|"); if (matches.length >= 2) { + if (matches[0].indexOf('$') > 0) { + //Functional variant, e.g. "Garbage Elemental $C" + String[] variantSplit = matches[0].split("\\s*\\$", 2); + if(variantSplit.length > 1) { + //Add the base name to the translated names. + translatednames.put(variantSplit[0], matches[1]); + matches[0] = variantSplit[0] + " $" + variantSplit[1]; //Standardize storage. + } + } translatednames.put(matches[0], matches[1]); } if (matches.length >= 3) { @@ -53,7 +62,7 @@ public class CardTranslation { if (name.contains(" // ")) { int splitIndex = name.indexOf(" // "); String leftname = name.substring(0, splitIndex); - String rightname = name.substring(splitIndex + 4, name.length()); + String rightname = name.substring(splitIndex + 4); return translatednames.getOrDefault(leftname, leftname) + " // " + translatednames.getOrDefault(rightname, rightname); } try { @@ -74,6 +83,10 @@ public class CardTranslation { return name; } + public static String getTranslatedName(ITranslatable card) { + return getTranslatedName(card.getUntranslatedName()); + } + private static String translateTokenName(String name) { if (translatedTokenNames == null) translatedTokenNames = new HashMap<>(); @@ -203,6 +216,12 @@ public class CardTranslation { return originaltype; } + public static String getTranslatedType(ITranslatable item) { + if (!needsTranslation()) + return item.getUntranslatedType(); + return translatedtypes.getOrDefault(item.getTranslationKey(), item.getUntranslatedType()); + } + public static String getTranslatedOracle(String name) { if (needsTranslation()) { String toracle = translatedoracles.get(name); @@ -212,13 +231,30 @@ public class CardTranslation { return ""; } - public static HashMap getTranslationTexts(String cardname, String altcardname) { - if (!needsTranslation()) return null; + public static String getTranslatedOracle(ITranslatable card) { + if(!needsTranslation()) + return ""; //card.getUntranslatedOracle(); + //Fallbacks and english versions of oracle texts are handled elsewhere. + return translatedoracles.getOrDefault(card.getTranslationKey(), ""); + } + + public static HashMap getTranslationTexts(ITranslatable card) { + return getTranslationTexts(card, null); + } + + public static HashMap getTranslationTexts(ITranslatable cardMain, ITranslatable cardOther) { + if(!needsTranslation()) return null; HashMap translations = new HashMap<>(); - translations.put("name", getTranslatedName(cardname)); - translations.put("oracle", getTranslatedOracle(cardname)); - translations.put("altname", getTranslatedName(altcardname)); - translations.put("altoracle", getTranslatedOracle(altcardname)); + translations.put("name", getTranslatedName(cardMain)); + translations.put("oracle", getTranslatedOracle(cardMain)); + if(cardOther == null) { + translations.put("altname", ""); + translations.put("altoracle", ""); + } + else { + translations.put("altname", getTranslatedName(cardOther)); + translations.put("altoracle", getTranslatedOracle(cardOther)); + } return translations; } @@ -248,14 +284,17 @@ public class CardTranslation { return result; } - public static void buildOracleMapping(String faceName, String oracleText) { - if (!needsTranslation() || oracleMappings.containsKey(faceName)) return; - String translatedText = getTranslatedOracle(faceName); + public static void buildOracleMapping(String faceName, String oracleText, String variantName) { + String translationKey = faceName; + if(variantName != null) + translationKey = faceName + " $" + variantName; + if (!needsTranslation() || oracleMappings.containsKey(translationKey)) return; + String translatedText = getTranslatedOracle(translationKey); if (translatedText.isEmpty()) { // english card only, fall back return; } - String translatedName = getTranslatedName(faceName); + String translatedName = getTranslatedName(translationKey); List > mapping = new ArrayList<>(); String [] splitOracleText = oracleText.split("\\\\n"); String [] splitTranslatedText = translatedText.split("\r\n\r\n"); @@ -269,17 +308,17 @@ public class CardTranslation { } mapping.add(Pair.of(toracle, ttranslated)); } - oracleMappings.put(faceName, mapping); + oracleMappings.put(translationKey, mapping); } - public static String translateMultipleDescriptionText(String descText, String cardName) { + public static String translateMultipleDescriptionText(String descText, ITranslatable card) { if (!needsTranslation()) return descText; String [] splitDescText = descText.split("\n"); String result = descText; for (String text : splitDescText) { text = text.trim(); if (text.isEmpty()) continue; - String translated = translateSingleDescriptionText(text, cardName); + String translated = translateSingleDescriptionText(text, card); if (!text.equals(translated)) { result = TextUtil.fastReplace(result, text, translated); } else { @@ -288,7 +327,7 @@ public class CardTranslation { if (splitKeywords.length <= 1) continue; for (String keyword : splitKeywords) { if (keyword.contains(" ")) continue; - translated = translateSingleDescriptionText(keyword, cardName); + translated = translateSingleDescriptionText(keyword, card); if (!keyword.equals(translated)) { result = TextUtil.fastReplace(result, keyword, translated); } @@ -298,13 +337,13 @@ public class CardTranslation { return result; } - public static String translateSingleDescriptionText(String descText, String cardName) { + public static String translateSingleDescriptionText(String descText, ITranslatable card) { if (descText == null) return ""; if (!needsTranslation()) return descText; if (translatedCaches.containsKey(descText)) return translatedCaches.get(descText); - List > mapping = oracleMappings.get(cardName); + List > mapping = oracleMappings.get(card.getTranslationKey()); if (mapping == null) return descText; String result = descText; if (!mapping.isEmpty()) { diff --git a/forge-core/src/main/java/forge/util/ITranslatable.java b/forge-core/src/main/java/forge/util/ITranslatable.java new file mode 100644 index 00000000000..6bbba27afb3 --- /dev/null +++ b/forge-core/src/main/java/forge/util/ITranslatable.java @@ -0,0 +1,22 @@ +package forge.util; + +public interface ITranslatable extends IHasName { + default String getTranslationKey() { + return getName(); + } + + //Fallback methods - used if no translation is found for the given key. + + default String getUntranslatedName() { + return getName(); + } + + default String getUntranslatedType() { + return ""; + } + + default String getUntranslatedOracle() { + return ""; + } + +} diff --git a/forge-game/src/main/java/forge/game/CardTraitBase.java b/forge-game/src/main/java/forge/game/CardTraitBase.java index c01f1c7c0d9..2cc4a8ad73e 100644 --- a/forge-game/src/main/java/forge/game/CardTraitBase.java +++ b/forge-game/src/main/java/forge/game/CardTraitBase.java @@ -22,11 +22,13 @@ import forge.game.card.CardView; import forge.game.card.IHasCardView; import forge.game.keyword.Keyword; import forge.game.keyword.KeywordInterface; +import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.zone.ZoneType; import forge.util.Expressions; +import forge.util.ITranslatable; /** * Base class for Triggers,ReplacementEffects and StaticAbilities. @@ -234,6 +236,13 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, return true; } } + } else if (o instanceof GameLossReason) { + for (String s : valids) { + GameLossReason valid = GameLossReason.smartValueOf(s); + if (((GameLossReason) o).name().equals(valid.name())) { + return true; + } + } } return false; @@ -302,7 +311,10 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, if ("True".equalsIgnoreCase(params.get("Bloodthirst")) != hostController.hasBloodthirst()) return false; } if (params.containsKey("FatefulHour")) { - if ("True".equalsIgnoreCase(params.get("FatefulHour")) != (hostController.getLife() > 5)) return false; + if ("True".equalsIgnoreCase(params.get("FatefulHour")) != (hostController.getLife() <= 5)) return false; + } + if (params.containsKey("Monarch")) { + if ("True".equalsIgnoreCase(params.get("Monarch")) != hostController.isMonarch()) return false; } if (params.containsKey("Revolt")) { if ("True".equalsIgnoreCase(params.get("Revolt")) != hostController.hasRevolt()) return false; @@ -412,15 +424,20 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, if (params.containsKey("PresentZone")) { presentZone = ZoneType.smartValueOf(params.get("PresentZone")); } - CardCollection list = new CardCollection(); - if (presentPlayer.equals("You") || presentPlayer.equals("Any")) { - list.addAll(hostController.getCardsIn(presentZone)); - } - if (presentPlayer.equals("Opponent") || presentPlayer.equals("Any")) { - list.addAll(hostController.getOpponents().getCardsIn(presentZone)); - } - if (presentPlayer.equals("Any")) { - list.addAll(hostController.getAllies().getCardsIn(presentZone)); + CardCollection list; + if (params.containsKey("PresentDefined")) { + list = AbilityUtils.getDefinedCards(getHostCard(), params.get("PresentDefined"), this); + } else { + list = new CardCollection(); + if (presentPlayer.equals("You") || presentPlayer.equals("Any")) { + list.addAll(hostController.getCardsIn(presentZone)); + } + if (presentPlayer.equals("Opponent") || presentPlayer.equals("Any")) { + list.addAll(hostController.getOpponents().getCardsIn(presentZone)); + } + if (presentPlayer.equals("Any")) { + list.addAll(hostController.getAllies().getCardsIn(presentZone)); + } } list = CardLists.getValidCards(list, sIsPresent, hostController, this.getHostCard(), this); @@ -553,6 +570,9 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, } protected IHasSVars getSVarFallback() { + if (this.getKeyword() != null && this.getKeyword().getStatic() != null) { + return this.getKeyword().getStatic(); + } if (getCardState() != null) return getCardState(); return getHostCard(); @@ -623,6 +643,14 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, return getCardState().getView().getState(); } + public ITranslatable getHostName(CardTraitBase node) { + // if alternate state is viewed while card uses original + if (node.isIntrinsic() && node.cardState != null && !node.cardState.getStateName().equals(getHostCard().getCurrentStateName())) { + return node.cardState; + } + return node.getHostCard(); + } + public Card getOriginalHost() { if (getCardState() != null) return getCardState().getCard(); diff --git a/forge-game/src/main/java/forge/game/ForgeScript.java b/forge-game/src/main/java/forge/game/ForgeScript.java index fd71564f00a..9c972c7c9e3 100644 --- a/forge-game/src/main/java/forge/game/ForgeScript.java +++ b/forge-game/src/main/java/forge/game/ForgeScript.java @@ -1,5 +1,6 @@ package forge.game; +import forge.card.CardTypeView; import forge.card.ColorSet; import forge.card.MagicColor; import forge.card.mana.ManaAtom; @@ -18,6 +19,7 @@ import forge.game.spellability.SpellAbilityPredicates; import forge.game.spellability.TargetChoices; import forge.game.staticability.StaticAbility; import forge.game.staticability.StaticAbilityCastWithFlash; +import forge.game.staticability.StaticAbilityColorlessDamageSource; import forge.game.trigger.Trigger; import forge.game.zone.ZoneType; import forge.util.Expressions; @@ -31,36 +33,30 @@ public class ForgeScript { public static boolean cardStateHasProperty(CardState cardState, String property, Player sourceController, Card source, CardTraitBase spellAbility) { - final boolean isColorlessSource = cardState.getCard().hasKeyword("Colorless Damage Source", cardState); - final ColorSet colors = cardState.getCard().getColor(cardState); + boolean withSource = property.endsWith("Source"); + final ColorSet colors; + if (withSource && StaticAbilityColorlessDamageSource.colorlessDamageSource(cardState)) { + colors = ColorSet.getNullColor(); + } else { + colors = cardState.getCard().getColor(cardState); + } + + final CardTypeView type = cardState.getTypeWithChanges(); if (property.contains("White") || property.contains("Blue") || property.contains("Black") || property.contains("Red") || property.contains("Green")) { boolean mustHave = !property.startsWith("non"); - boolean withSource = property.endsWith("Source"); - if (withSource && isColorlessSource) { - return false; - } - final String colorName = property.substring(mustHave ? 0 : 3, property.length() - (withSource ? 6 : 0)); int desiredColor = MagicColor.fromName(colorName); boolean hasColor = colors.hasAnyColor(desiredColor); return mustHave == hasColor; - } else if (property.contains("Colorless")) { // ... Card is colorless + } else if (property.contains("Colorless")) { boolean non = property.startsWith("non"); - boolean withSource = property.endsWith("Source"); - if (non && withSource && isColorlessSource) { - return false; - } return non != colors.isColorless(); - } else if (property.contains("MultiColor")) { + } else if (property.startsWith("MultiColor")) { // ... Card is multicolored - if (property.endsWith("Source") && isColorlessSource) - return false; - return property.startsWith("non") != colors.isMulticolor(); - } else if (property.contains("EnemyColor")) { - if (property.endsWith("Source") && isColorlessSource) - return false; + return colors.isMulticolor(); + } else if (property.startsWith("EnemyColor")) { if (colors.countColors() != 2) { return false; } @@ -71,44 +67,36 @@ public class ForgeScript { } } return false; - } else if (property.contains("AllColors")) { - if (property.endsWith("Source") && isColorlessSource) - return false; - return property.startsWith("non") != colors.isAllColors(); - } else if (property.contains("MonoColor")) { // ... Card is monocolored - if (property.endsWith("Source") && isColorlessSource) - return false; - return property.startsWith("non") != colors.isMonoColor(); + } else if (property.startsWith("AllColors")) { + return colors.isAllColors(); + } else if (property.startsWith("MonoColor")) { + return colors.isMonoColor(); } else if (property.startsWith("ChosenColor")) { - if (property.endsWith("Source") && isColorlessSource) - return false; return source.hasChosenColor() && colors.hasAnyColor(MagicColor.fromName(source.getChosenColor())); } else if (property.startsWith("AnyChosenColor")) { - if (property.endsWith("Source") && isColorlessSource) - return false; return source.hasChosenColor() && colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor()); } else if (property.equals("AssociatedWithChosenColor")) { final String color = source.getChosenColor(); switch (color) { case "white": - return cardState.getTypeWithChanges().getLandTypes().contains("Plains"); + return type.hasSubtype("Plains"); case "blue": - return cardState.getTypeWithChanges().getLandTypes().contains("Island"); + return type.hasSubtype("Island"); case "black": - return cardState.getTypeWithChanges().getLandTypes().contains("Swamp"); + return type.hasSubtype("Swamp"); case "red": - return cardState.getTypeWithChanges().getLandTypes().contains("Mountain"); + return type.hasSubtype("Mountain"); case "green": - return cardState.getTypeWithChanges().getLandTypes().contains("Forest"); + return type.hasSubtype("Forest"); default: return false; } } else if (property.equals("Outlaw")) { - return cardState.getTypeWithChanges().isOutlaw(); + return type.isOutlaw(); } else if (property.startsWith("non")) { // ... Other Card types - return !cardState.getTypeWithChanges().hasStringType(property.substring(3)); + return !type.hasStringType(property.substring(3)); } else if (property.equals("CostsPhyrexianMana")) { return cardState.getManaCost().hasPhyrexian(); } else if (property.startsWith("HasSVar")) { @@ -117,19 +105,19 @@ public class ForgeScript { } else if (property.equals("ChosenType")) { String chosenType = source.getChosenType(); if (chosenType.startsWith("Non")) { - return !cardState.getTypeWithChanges().hasStringType(StringUtils.capitalize(chosenType.substring(3))); + return !type.hasStringType(StringUtils.capitalize(chosenType.substring(3))); } - return cardState.getTypeWithChanges().hasStringType(chosenType); + return type.hasStringType(chosenType); } else if (property.equals("IsNotChosenType")) { - return !cardState.getTypeWithChanges().hasStringType(source.getChosenType()); + return !type.hasStringType(source.getChosenType()); } else if (property.equals("ChosenType2")) { - return cardState.getTypeWithChanges().hasStringType(source.getChosenType2()); + return type.hasStringType(source.getChosenType2()); } else if (property.equals("IsNotChosenType2")) { - return !cardState.getTypeWithChanges().hasStringType(source.getChosenType2()); + return !type.hasStringType(source.getChosenType2()); } else if (property.equals("NotedType")) { boolean found = false; for (String s : source.getNotedTypes()) { - if (cardState.getTypeWithChanges().hasStringType(s)) { + if (type.hasStringType(s)) { found = true; break; } @@ -185,7 +173,7 @@ public class ForgeScript { int x = AbilityUtils.calculateAmount(source, rhs, spellAbility); return Expressions.compare(y, property, x); - } else return cardState.getTypeWithChanges().hasStringType(property); + } else return type.hasStringType(property); } public static boolean spellAbilityHasProperty(SpellAbility sa, String property, Player sourceController, @@ -241,6 +229,10 @@ public class ForgeScript { return sa.isMorphUp(); } else if (property.equals("ManifestUp")) { return sa.isManifestUp(); + } else if (property.equals("Unlock")) { + return sa.isUnlock(); + } else if (property.equals("isTurnFaceUp")) { + return sa.isTurnFaceUp(); } else if (property.equals("isCastFaceDown")) { return sa.isCastFaceDown(); } else if (property.equals("Modular")) { diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 8d1db2d0452..a6e7ccb9c9a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -170,7 +170,6 @@ public class GameAction { Card copied = null; Card lastKnownInfo = null; - Card commanderEffect = null; // The effect card of commander replacement effect // get the LKI from above like ChangeZoneEffect if (params != null && params.containsKey(AbilityKey.CardLKI)) { @@ -320,23 +319,8 @@ public class GameAction { // Temporary disable commander replacement effect // 903.9a if (fromBattlefield && !toBattlefield && c.isCommander() && c.hasMergedCard()) { - // Find the commander replacement effect "card" - CardCollectionView comCards = c.getOwner().getCardsIn(ZoneType.Command); - for (final Card effCard : comCards) { - for (final ReplacementEffect re : effCard.getReplacementEffects()) { - if (re.hasParam("CommanderMoveReplacement") && c.getMergedCards().contains(effCard.getEffectSource())) { - commanderEffect = effCard; - break; - } - } - if (commanderEffect != null) break; - } // Disable the commander replacement effect - if (commanderEffect != null) { - for (final ReplacementEffect re : commanderEffect.getReplacementEffects()) { - re.setSuppressed(true); - } - } + c.getOwner().setCommanderReplacementSuppressed(true); } // in addition to actual tokens, cards "made" by digital-only mechanics @@ -502,17 +486,17 @@ public class GameAction { if (c.getCastSA() != null && !c.getCastSA().isIntrinsic() && c.getCastSA().getKeyword() != null) { KeywordInterface ki = c.getCastSA().getKeyword(); ki.setHostCard(copied); - copied.addChangedCardKeywordsInternal(ImmutableList.of(ki), null, false, copied.getGameTimestamp(), 0, true); + copied.addChangedCardKeywordsInternal(ImmutableList.of(ki), null, false, copied.getGameTimestamp(), null, true); } // TODO hot fix for non-intrinsic offspring - Multimap addKw = MultimapBuilder.hashKeys().arrayListValues().build(); + Multimap addKw = MultimapBuilder.hashKeys().arrayListValues().build(); for (KeywordInterface kw : c.getKeywords(Keyword.OFFSPRING)) { if (!kw.isIntrinsic()) { - addKw.put(kw.getStaticId(), kw); + addKw.put(kw.getStatic(), kw); } } if (!addKw.isEmpty()) { - for (Map.Entry> e : addKw.asMap().entrySet()) { + for (Map.Entry> e : addKw.asMap().entrySet()) { copied.addChangedCardKeywordsInternal(e.getValue(), null, false, copied.getGameTimestamp(), e.getKey(), true); } } @@ -530,11 +514,7 @@ public class GameAction { // Move components of merged permanent here // Also handle 723.3e and 903.9a boolean wasToken = c.isToken(); - if (commanderEffect != null) { - for (final ReplacementEffect re : commanderEffect.getReplacementEffects()) { - re.setSuppressed(false); - } - } + c.getOwner().setCommanderReplacementSuppressed(false); // Change zone of original card so components isToken() and isCommander() return correct value // when running replacement effects here c.setZone(zoneTo); @@ -622,7 +602,7 @@ public class GameAction { // 400.7g try adding keyword back into card if it doesn't already have it if (zoneTo.is(ZoneType.Stack) && cause != null && cause.isSpell() && !cause.isIntrinsic() && c.equals(cause.getHostCard())) { if (cause.getKeyword() != null && !copied.getKeywords().contains(cause.getKeyword())) { - copied.addChangedCardKeywordsInternal(ImmutableList.of(cause.getKeyword()), null, false, game.getNextTimestamp(), 0, true); + copied.addChangedCardKeywordsInternal(ImmutableList.of(cause.getKeyword()), null, false, game.getNextTimestamp(), null, true); } } @@ -713,7 +693,6 @@ public class GameAction { if (wasFacedown) { Card revealLKI = CardCopyService.getLKICopy(c); revealLKI.forceTurnFaceUp(); - reveal(new CardCollection(revealLKI), revealLKI.getOwner(), true, "Face-down card leaves the battlefield: "); copied.setState(CardStateName.Original, true); @@ -1400,10 +1379,10 @@ public class GameAction { || game.getRules().hasAppliedVariant(GameType.Brawl) || game.getRules().hasAppliedVariant(GameType.Planeswalker)) && !checkAgain) { for (final Card c : p.getCardsIn(ZoneType.Graveyard).threadSafeIterable()) { - checkAgain |= stateBasedAction903_9a(c); + checkAgain |= stateBasedAction_Commander(c, mapParams); } for (final Card c : p.getCardsIn(ZoneType.Exile).threadSafeIterable()) { - checkAgain |= stateBasedAction903_9a(c); + checkAgain |= stateBasedAction_Commander(c, mapParams); } } @@ -1508,6 +1487,7 @@ public class GameAction { if (!c.isSaga()) { return false; } + // needs to be effect, because otherwise it might be a cost? if (!c.canBeSacrificedBy(null, true)) { return false; } @@ -1515,7 +1495,6 @@ public class GameAction { return false; } if (!game.getStack().hasSourceOnStack(c, SpellAbilityPredicates.isChapter())) { - // needs to be effect, because otherwise it might be a cost? sacrificeList.add(c); checkAgain = true; } @@ -1538,6 +1517,7 @@ public class GameAction { } return checkAgain; } + private boolean stateBasedAction_Role(Card c, CardCollection removeList) { if (!c.hasCardAttachments()) { return false; @@ -1553,7 +1533,6 @@ public class GameAction { if (rolesByPlayer.size() <= 1) { continue; } - // sort by game timestamp rolesByPlayer.sort(CardPredicates.compareByGameTimestamp()); removeList.addAll(rolesByPlayer.subList(0, rolesByPlayer.size() - 1)); checkAgain = true; @@ -1634,14 +1613,15 @@ public class GameAction { return checkAgain; } - private boolean stateBasedAction903_9a(Card c) { + private boolean stateBasedAction_Commander(Card c, Map mapParams) { + // CR 903.9a if (c.isRealCommander() && c.canMoveToCommandZone()) { // FIXME: need to flush the tracker to make sure the Commander is properly updated c.getGame().getTracker().flush(); c.setMoveToCommandZone(false); if (c.getOwner().getController().confirmAction(c.getFirstSpellAbility(), PlayerActionConfirmMode.ChangeZoneToAltDestination, c.getName() + ": If a commander is in a graveyard or in exile and that card was put into that zone since the last time state-based actions were checked, its owner may put it into the command zone.", null)) { - moveTo(c.getOwner().getZone(ZoneType.Command), c, null); + moveTo(c.getOwner().getZone(ZoneType.Command), c, null, mapParams); return true; } } @@ -1781,7 +1761,6 @@ public class GameAction { } private boolean handlePlaneswalkerRule(Player p, CardCollection noRegCreats) { - // get all Planeswalkers final List list = p.getPlaneswalkersInPlay(); boolean recheck = false; @@ -2585,7 +2564,6 @@ public class GameAction { player.addCompletedDungeon(dungeon); ceaseToExist(dungeon, true); - // Run RoomEntered trigger final Map runParams = AbilityKey.mapFromCard(dungeon); runParams.put(AbilityKey.Player, player); game.getTriggerHandler().runTrigger(TriggerType.DungeonCompleted, runParams, false); diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index e321a159155..786067cd1d9 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -339,7 +339,7 @@ public final class GameActionUtil { newSA.setMayPlay(o); final StringBuilder sb = new StringBuilder(sa.getDescription()); - if (!source.equals(host)) { + if (!source.equals(host) && host.getCardForUi() != null) { sb.append(" by "); if (host.isImmutable() && host.getEffectSource() != null) { sb.append(host.getEffectSource()); @@ -620,7 +620,10 @@ public final class GameActionUtil { result.getPayCosts().add(cost); reset = true; } - result.setOptionalKeywordAmount(ki, v); + + if (result != null) { + result.setOptionalKeywordAmount(ki, v); + } } else if (o.startsWith("Offspring")) { String[] k = o.split(":"); final Cost cost = new Cost(k[1], false); @@ -839,6 +842,10 @@ public final class GameActionUtil { CardCollection subList = new CardCollection(); for (Card c : list) { Player decider = dest == ZoneType.Battlefield ? c.getController() : c.getOwner(); + if (sa != null && sa.hasParam("GainControl")) { + // TODO this doesn't account for changes from e.g. Gather Specimens yet + decider = AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("GainControl"), sa).get(0); + } if (decider.equals(p)) { subList.add(c); } diff --git a/forge-game/src/main/java/forge/game/GameRules.java b/forge-game/src/main/java/forge/game/GameRules.java index 1a0216d09a8..5cc761138ff 100644 --- a/forge-game/src/main/java/forge/game/GameRules.java +++ b/forge-game/src/main/java/forge/game/GameRules.java @@ -95,6 +95,10 @@ public class GameRules { this.appliedVariants.addAll(appliedVariants); } + public void addAppliedVariant(final GameType variant) { + this.appliedVariants.add(variant); + } + public boolean hasAppliedVariant(final GameType variant) { return appliedVariants.contains(variant); } diff --git a/forge-game/src/main/java/forge/game/GameSnapshot.java b/forge-game/src/main/java/forge/game/GameSnapshot.java index 55a06681cf1..001215df41c 100644 --- a/forge-game/src/main/java/forge/game/GameSnapshot.java +++ b/forge-game/src/main/java/forge/game/GameSnapshot.java @@ -80,25 +80,7 @@ public class GameSnapshot { for (Player p : fromGame.getPlayers()) { Player toPlayer = findBy(toGame, p); - - List commanders = Lists.newArrayList(); - - // Commander cast times are stored in the player, not the card - toPlayer.resetCommanderStats(); - for (final Card c : p.getCommanders()) { - Card newCommander = findBy(toGame, c); - commanders.add(newCommander); - int castTimes = p.getCommanderCast(c); - for (int i = 0; i < castTimes; i++) { - toPlayer.incCommanderCast(newCommander); - } - } - for (Map.Entry entry : p.getCommanderDamage()) { - Card commander = findBy(toGame, entry.getKey()); - int damage = entry.getValue(); - toPlayer.addCommanderDamage(commander, damage); - } - toPlayer.setCommanders(commanders); + p.copyCommandersToSnapshot(toPlayer, c -> findBy(toGame, c)); ((PlayerZoneBattlefield) toPlayer.getZone(ZoneType.Battlefield)).setTriggers(true); } toGame.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); @@ -204,8 +186,6 @@ public class GameSnapshot { // Copy mana pool copyManaPool(origPlayer, newPlayer); - - newPlayer.setCommanders(origPlayer.getCommanders()); // will be fixed up below } private void copyManaPool(Player fromPlayer, Player toPlayer) { diff --git a/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java b/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java index f89593abf9c..e65ef5006f2 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityApiBased.java @@ -30,16 +30,7 @@ public class AbilityApiBased extends AbilityActivated { @Override public String getStackDescription() { - StringBuilder sb = new StringBuilder(); - if (this.hostCard.hasPromisedGift() && this.isSpell() && !this.hostCard.isPermanent()) { - sb.append("Gift a "). - append(this.getAdditionalAbility("GiftAbility").getParam("GiftDescription")). - append(" to ").append(this.hostCard.getPromisedGift()). - append(". "); - } - - sb.append(effect.getStackDescriptionWithSubs(mapParams, this)); - return sb.toString(); + return effect.getStackDescriptionWithSubs(mapParams, this); } /* (non-Javadoc) 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 bf55ddfc735..b38511f39dd 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityKey.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityKey.java @@ -88,6 +88,7 @@ public enum AbilityKey { LastStateGraveyard("LastStateGraveyard"), LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged LifeGained("LifeGained"), + LoseReason("LoseReason"), Map("Map"), Mana("Mana"), MergedCards("MergedCards"), diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 1140dfef976..bac2620b331 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1,6 +1,8 @@ package forge.game.ability; import com.google.common.collect.*; +import com.google.common.math.IntMath; + import forge.card.CardStateName; import forge.card.CardType; import forge.card.ColorSet; @@ -1541,6 +1543,11 @@ public class AbilityUtils { host.clearRemembered(); } host.addRemembered(sa.getTargets()); + if (sa.hasParam("IncludeAllComponentCards")) { + for (Card c : sa.getTargets().getTargetCards()) { + host.addRemembered(c.getAllComponentCards(false)); + } + } } if (sa.hasParam("RememberCostMana")) { @@ -1626,6 +1633,14 @@ public class AbilityUtils { return doXMath(calculateAmount(c, sq[v ? 1 : 2], ctb), expr, c, ctb); } + // Count$IsPrime .. + if (sq[0].startsWith("IsPrime")) { + final String[] compString = sq[0].split(" "); + final int lhs = calculateAmount(c, compString[1], ctb); + boolean v = IntMath.isPrime(lhs); + return doXMath(calculateAmount(c, sq[v ? 1 : 2], ctb), expr, c, ctb); + } + if (ctb instanceof SpellAbility) { final SpellAbility sa = (SpellAbility) ctb; diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index ff7170bff06..052223b214c 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -60,6 +60,11 @@ public abstract class SpellAbilityEffect { // prelude for when this is root ability if (!(sa instanceof AbilitySub)) { sb.append(sa.getHostCard()).append(" -"); + if (sa.getHostCard().hasPromisedGift()) { + sb.append(" Gift "). + append(sa.getAdditionalAbility("GiftAbility").getParam("GiftDescription")). + append(" to ").append(sa.getHostCard().getPromisedGift()).append(". "); + } } sb.append(" "); } @@ -78,8 +83,7 @@ public abstract class SpellAbilityEffect { if (params.containsKey("SpellDescription")) { if (rawSDesc.contains(",,,,,,")) rawSDesc = rawSDesc.replaceAll(",,,,,,", " "); if (rawSDesc.contains(",,,")) rawSDesc = rawSDesc.replaceAll(",,,", " "); - String spellDesc = CardTranslation.translateSingleDescriptionText(rawSDesc, - sa.getHostCard().getName()); + String spellDesc = CardTranslation.translateSingleDescriptionText(rawSDesc, sa.getHostCard()); //trim reminder text from StackDesc int idxL = spellDesc.indexOf(" ("); @@ -109,7 +113,7 @@ public abstract class SpellAbilityEffect { } else { final String condDesc = sa.getParam("ConditionDescription"); final String afterDesc = sa.getParam("AfterDescription"); - final String baseDesc = CardTranslation.translateSingleDescriptionText(this.getStackDescription(sa), sa.getHostCard().getName()); + final String baseDesc = CardTranslation.translateSingleDescriptionText(this.getStackDescription(sa), sa.getHostCard()); if (condDesc != null) { sb.append(condDesc).append(" "); } @@ -242,6 +246,15 @@ public abstract class SpellAbilityEffect { } } } + if (resultUnique == null) + return null; + if (sa.hasParam("IncludeAllComponentCards")) { + CardCollection components = new CardCollection(); + for (Card c : resultUnique) { + components.addAll(c.getAllComponentCards(false)); + } + resultUnique.addAll(components); + } return resultUnique; } @@ -446,6 +459,11 @@ public abstract class SpellAbilityEffect { card.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "AtEOT"), card.getGame().getNextTimestamp(), 0); } + protected static SpellAbility getExileSpellAbility(final Card card) { + String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; + return AbilityFactory.getAbility(effect, card); + } + protected static SpellAbility getForgetSpellAbility(final Card card) { String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard"; String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile" @@ -459,6 +477,7 @@ public abstract class SpellAbilityEffect { public static void addForgetOnMovedTrigger(final Card card, final String zone) { String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | ExcludedDestinations$ Stack,Exile | Destination$ Any | TriggerZones$ Command | Static$ True"; + // CR 400.8 Exiled card becomes new object when it's exiled String trig2 = "Mode$ Exiled | ValidCard$ Card.IsRemembered | ValidCause$ SpellAbility.!EffectSource | TriggerZones$ Command | Static$ True"; final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); @@ -480,17 +499,15 @@ public abstract class SpellAbilityEffect { protected static void addExileOnMovedTrigger(final Card card, final String zone) { String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True"; - String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); - parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); + parsedTrigger.setOverridingAbility(getExileSpellAbility(card)); card.addTrigger(parsedTrigger); } protected static void addExileOnCounteredTrigger(final Card card) { String trig = "Mode$ Countered | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True"; - String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); - parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); + parsedTrigger.setOverridingAbility(getExileSpellAbility(card)); card.addTrigger(parsedTrigger); } @@ -502,6 +519,13 @@ public abstract class SpellAbilityEffect { card.addTrigger(parsedTrigger); } + protected static void addExileCounterTrigger(final Card card, final String counterType) { + String trig = "Mode$ CounterRemoved | TriggerZones$ Command | ValidCard$ Card.EffectSource | CounterType$ " + counterType + " | NewCounterAmount$ 0 | Static$ True"; + final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); + parsedTrigger.setOverridingAbility(getExileSpellAbility(card)); + card.addTrigger(parsedTrigger); + } + protected static void addForgetCounterTrigger(final Card card, final String counterType) { String trig = "Mode$ CounterRemoved | TriggerZones$ Command | ValidCard$ Card.IsRemembered | CounterType$ " + counterType + " | NewCounterAmount$ 0 | Static$ True"; String trig2 = "Mode$ PhaseOut | TriggerZones$ Command | ValidCard$ Card.phasedOutIsRemembered | Static$ True"; @@ -518,9 +542,8 @@ public abstract class SpellAbilityEffect { protected static void addExileOnLostTrigger(final Card card) { String trig = "Mode$ LosesGame | ValidPlayer$ You | TriggerController$ Player | TriggerZones$ Command | Static$ True"; - String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); - parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); + parsedTrigger.setOverridingAbility(getExileSpellAbility(card)); card.addTrigger(parsedTrigger); } @@ -860,6 +883,8 @@ public abstract class SpellAbilityEffect { } else { game.getUpkeep().addUntilEnd(controller, until); } + } else if ("UntilNextEndStep".equals(duration)) { + game.getEndOfTurn().addAt(until); } else if ("UntilYourNextEndStep".equals(duration)) { game.getEndOfTurn().addUntil(controller, until); } else if ("UntilYourNextTurn".equals(duration)) { @@ -895,6 +920,9 @@ public abstract class SpellAbilityEffect { } else if ("UntilHostLeavesPlayOrEOT".equals(duration)) { host.addLeavesPlayCommand(until); game.getEndOfTurn().addUntil(until); + } else if ("UntilHostLeavesPlayOrEndOfCombat".equals(duration)) { + host.addLeavesPlayCommand(until); + game.getEndOfCombat().addUntil(until); } else if ("UntilLoseControlOfHost".equals(duration)) { host.addLeavesPlayCommand(until); host.addChangeControllerCommand(until); diff --git a/forge-game/src/main/java/forge/game/ability/effects/AbandonEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AbandonEffect.java index 7641de47351..ecaf17d9c32 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AbandonEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AbandonEffect.java @@ -2,7 +2,6 @@ package forge.game.ability.effects; import java.util.Map; -import forge.game.Game; import forge.game.ability.AbilityKey; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; @@ -29,22 +28,16 @@ public class AbandonEffect extends SpellAbilityEffect { return; } - final Game game = controller.getGame(); - if (sa.hasParam("RememberAbandoned")) { source.addRemembered(source); } - game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); controller.getZone(ZoneType.Command).remove(source); - game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); - controller.getZone(ZoneType.SchemeDeck).add(source); - // Run triggers final Map runParams = AbilityKey.newMap(); runParams.put(AbilityKey.Scheme, source); - game.getTriggerHandler().runTrigger(TriggerType.Abandoned, runParams, false); + controller.getGame().getTriggerHandler().runTrigger(TriggerType.Abandoned, runParams, false); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/AlterAttributeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AlterAttributeEffect.java index fc0150f2b91..9750437f7fe 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AlterAttributeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AlterAttributeEffect.java @@ -2,10 +2,13 @@ package forge.game.ability.effects; import java.util.Map; +import forge.game.GameLogEntryType; +import forge.game.GameType; import forge.game.ability.AbilityKey; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardCollection; +import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.util.Lang; @@ -63,6 +66,26 @@ public class AlterAttributeEffect extends SpellAbilityEffect { c.getGame().getTriggerHandler().runTrigger(TriggerType.BecomesSaddled, runParams, false); } break; + case "Commander": + //This implementation doesn't let a card make someone else's creature your commander. But that's an edge case among edge cases. + Player p = c.getOwner(); + if (c.isCommander() == activate || p.getCommanders().contains(c) == activate) + break; //Isn't changing status. + if (activate) { + if(!c.getGame().getRules().hasCommander()) { + System.out.println("Commander status applied in non-commander format. Applying Commander variant."); + c.getGame().getRules().addAppliedVariant(GameType.Commander); + } + p.addCommander(c); + //Seems important enough to mention in the game log. + c.getGame().getGameLog().add(GameLogEntryType.STACK_RESOLVE, String.format("%s is now %s's commander.", c.getPaperCard().getName(), p)); + } + else { + p.removeCommander(c); + c.getGame().getGameLog().add(GameLogEntryType.STACK_RESOLVE, String.format("%s is no longer %s's commander.", c.getPaperCard().getName(), p)); + } + altered = true; + break; // Other attributes: renown, monstrous, suspected, etc diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java index 955d78ad30c..2ebd33cbf00 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java @@ -28,7 +28,6 @@ public class AnimateAllEffect extends AnimateEffectBase { public void resolve(final SpellAbility sa) { final Card host = sa.getHostCard(); - // AF specific sa Integer power = null; if (sa.hasParam("Power")) { power = AbilityUtils.calculateAmount(host, sa.getParam("Power"), sa); diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java index 2bd45869040..02c685f628f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java @@ -126,7 +126,7 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect { params.put("Category", "Keywords"); c.addPerpetual(params); } - c.addChangedCardKeywords(keywords, removeKeywords, removeAll, timestamp, 0); + c.addChangedCardKeywords(keywords, removeKeywords, removeAll, timestamp, null); } // do this after changing types in case it wasn't a creature before diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 82da7842f1b..d575b8fa318 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -461,8 +461,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { origin.addAll(ZoneType.listValueOf(sa.getParam("Origin"))); } - int libraryPosition = sa.hasParam("LibraryPosition") ? - AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0; + int libraryPosition = sa.hasParam("LibraryPosition") ? AbilityUtils.calculateAmount(hostCard, sa.getParam("LibraryPosition"), sa) : 0; if (sa.hasParam("DestinationAlternative")) { Pair pair = handleAltDest(sa, hostCard, destination, libraryPosition, activator); destination = pair.getKey(); @@ -503,6 +502,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect { final boolean shuffle = sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle")); boolean combatChanged = false; + if (sa.hasParam("ShuffleNonMandatory") && + !activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoyouWantShuffleTheLibrary"), null)) { + return; + } + Player chooser = activator; if (sa.hasParam("Chooser")) { chooser = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("Chooser"), sa).get(0); @@ -535,8 +539,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } final String prompt = TextUtil.concatWithSpace(Localizer.getInstance().getMessage("lblDoYouWantMoveTargetFromOriToDest", CardTranslation.getTranslatedName(gameCard.getName()), Lang.joinHomogenous(origin, ZoneType::getTranslatedName), destination.getTranslatedName())); - if (optional && !chooser.getController().confirmAction(sa, null, prompt, null)) + if (optional && !chooser.getController().confirmAction(sa, null, prompt, null)) { continue; + } final Zone originZone = game.getZoneOf(gameCard); @@ -670,7 +675,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (sa.hasParam("Unearth") && movedCard.isInPlay()) { movedCard.setUnearthed(true); movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false, - game.getNextTimestamp(), 0, true); + game.getNextTimestamp(), null, true); registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard)); addLeaveBattlefieldReplacement(movedCard, sa, "Exile"); } @@ -1045,28 +1050,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { player.addController(controlTimestamp, searchControlPlayer.getValue()); } - decider.incLibrarySearched(); // should only count the number of searching player's own library - // Panglacial Wurm - CardCollection canCastWhileSearching = CardLists.getKeyword(fetchList, - "While you're searching your library, you may cast CARDNAME from your library."); - decider.getController().tempShowCards(canCastWhileSearching); - for (final Card tgtCard : canCastWhileSearching) { - List sas = AbilityUtils.getSpellsFromPlayEffect(tgtCard, decider, CardStateName.Original, true); - if (sas.isEmpty()) { - continue; - } - SpellAbility tgtSA = decider.getController().getAbilityToPlay(tgtCard, sas); - if (!decider.getController().confirmAction(tgtSA, null, Localizer.getInstance().getMessage("lblDoYouWantPlayCard", CardTranslation.getTranslatedName(tgtCard.getName())), null)) { - continue; - } - // if played, that card cannot be found - if (decider.getController().playSaFromPlayEffect(tgtSA)) { - fetchList.remove(tgtCard); - } - //some kind of reset here? - } - decider.getController().endTempShowCards(); + decider.incLibrarySearched(); + + handleCastWhileSearching(fetchList, decider); } final Map runParams = AbilityKey.mapFromPlayer(decider); runParams.put(AbilityKey.Target, Lists.newArrayList(player)); @@ -1506,6 +1493,29 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } } + private void handleCastWhileSearching(final CardCollection fetchList, final Player decider) { + // Panglacial Wurm + CardCollection canCastWhileSearching = CardLists.getKeyword(fetchList, + "While you're searching your library, you may cast CARDNAME from your library."); + decider.getController().tempShowCards(canCastWhileSearching); + for (final Card tgtCard : canCastWhileSearching) { + List sas = AbilityUtils.getSpellsFromPlayEffect(tgtCard, decider, CardStateName.Original, true); + if (sas.isEmpty()) { + continue; + } + SpellAbility tgtSA = decider.getController().getAbilityToPlay(tgtCard, sas); + if (!decider.getController().confirmAction(tgtSA, null, Localizer.getInstance().getMessage("lblDoYouWantPlayCard", CardTranslation.getTranslatedName(tgtCard.getName())), null)) { + continue; + } + // if played, that card cannot be found + if (decider.getController().playSaFromPlayEffect(tgtSA)) { + fetchList.remove(tgtCard); + } + //some kind of reset here? + } + decider.getController().endTempShowCards(); + } + private static class HiddenOriginChoices { boolean shuffleMandatory; boolean searchedLibrary; diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index b771f5ff556..312d9e9bdec 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -151,7 +151,7 @@ public class CloneEffect extends SpellAbilityEffect { } if (!pumpKeywords.isEmpty()) { - tgtCard.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, ts, 0); + tgtCard.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, ts, null); TokenEffectBase.addPumpUntil(sa, tgtCard, ts); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java index 42e9d573111..219fde3d177 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java @@ -174,7 +174,7 @@ public class ControlGainEffect extends SpellAbilityEffect { } if (keywords != null) { - tgtC.addChangedCardKeywords(keywords, Lists.newArrayList(), false, tStamp, 0); + tgtC.addChangedCardKeywords(keywords, Lists.newArrayList(), false, tStamp, null); game.fireEvent(new GameEventCardStatsChanged(tgtC)); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java index b0aa3745307..185f3ffc130 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java @@ -204,7 +204,7 @@ public class CopyPermanentEffect extends TokenEffectBase { Player chooser = activator; if (sa.hasParam("Chooser")) { final String choose = sa.getParam("Chooser"); - chooser = AbilityUtils.getDefinedPlayers(sa.getHostCard(), choose, sa).get(0); + chooser = AbilityUtils.getDefinedPlayers(host, choose, sa).get(0); } // For Mimic Vat with mutated creature, need to choose one imprinted card @@ -268,7 +268,6 @@ public class CopyPermanentEffect extends TokenEffectBase { if (!useZoneTable) { triggerList.triggerChangesZoneAll(game, sa); - triggerList.clear(); } if (combatChanged.isTrue()) { game.updateCombatForView(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java index 5313fb709c0..abe685a5853 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java @@ -86,13 +86,12 @@ public class CountersPutEffect extends SpellAbilityEffect { // skip the StringBuilder if no targets are chosen ("up to" scenario) if (sa.usesTargeting()) { final List targetCards = getTargetCards(sa); - if (targetCards.size() == 0) { + if (targetCards.isEmpty()) { return stringBuilder.toString(); } } - final String key = forEach ? "ForEachNum" : "CounterNum"; - final int amount = AbilityUtils.calculateAmount(card, sa.getParamOrDefault(key, "1"), sa); + final int amount = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("CounterNum", "1"), sa); if (sa.hasParam("Bolster")) { stringBuilder.append("bolsters ").append(amount).append("."); @@ -303,7 +302,7 @@ public class CountersPutEffect extends SpellAbilityEffect { for (int i = 0; i < num; i++) { CounterType ct = chooseTypeFromList(sa, options, obj, pc); typesToAdd.add(ct); - options = options.replace(ct.getName(),""); + options = options.replace(ct.getName(), ""); } for (CounterType ct : typesToAdd) { if (obj instanceof Player) { @@ -333,7 +332,7 @@ public class CountersPutEffect extends SpellAbilityEffect { CardCollectionView counterCards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), type.split("_")[1], activator, card, sa); - List counterTypes = Lists.newArrayList(); + List counterTypes = Lists.newArrayList(); for (Card c : counterCards) { for (final Map.Entry map : c.getCounters().entrySet()) { if (!counterTypes.contains(map.getKey())) { @@ -352,7 +351,23 @@ public class CountersPutEffect extends SpellAbilityEffect { typesToAdd.add(CounterType.getType(type)); } } + int remaining = counterAmount; for (CounterType ct : typesToAdd) { + if (sa.hasParam("SplitAmount")) { + if (typesToAdd.size() - typesToAdd.indexOf(ct) > 1) { + Map params = Maps.newHashMap(); + params.put("Target", obj); + params.put("CounterType", counterType); + counterAmount = pc.chooseNumber(sa, ct.toString() + ": " + + Localizer.getInstance().getMessage("lblHowManyCounters"), 0, remaining, params); + if (counterAmount == 0) { + continue; + } + remaining -= counterAmount; + } else { + counterAmount = remaining; + } + } if (obj instanceof Player) { ((Player) obj).addCounter(ct, counterAmount, placer, table); } @@ -478,11 +493,9 @@ public class CountersPutEffect extends SpellAbilityEffect { } // Adapt need extra logic - if (sa.hasParam("Adapt")) { - if (!(gameCard.getCounters(CounterEnumType.P1P1) == 0 - || StaticAbilityAdapt.anyWithAdapt(sa, gameCard))) { - continue; - } + if (sa.hasParam("Adapt") && + !(gameCard.getCounters(CounterEnumType.P1P1) == 0 || StaticAbilityAdapt.anyWithAdapt(sa, gameCard))) { + continue; } if (sa.isKeyword(Keyword.TRIBUTE)) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java index c17351cdcb4..78645ddd050 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageAllEffect.java @@ -56,8 +56,7 @@ public class DamageAllEffect extends DamageBaseEffect { final Card sourceLKI = card.getGame().getChangeZoneLKIInfo(card); final Game game = sa.getActivatingPlayer().getGame(); - final String damage = sa.getParam("NumDmg"); - final int dmg = AbilityUtils.calculateAmount(source, damage, sa); + final int dmg = AbilityUtils.calculateAmount(source, sa.getParam("NumDmg"), sa); //Remember params from this effect have been moved to dealDamage in GameAction Player targetPlayer = sa.getTargets().getFirstTargetedPlayer(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DebuffEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DebuffEffect.java index 186774e5cc5..8fa6a875df5 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DebuffEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DebuffEffect.java @@ -150,7 +150,7 @@ public class DebuffEffect extends SpellAbilityEffect { } removedKW.addAll(kws); - tgtC.addChangedCardKeywords(addedKW, removedKW, false, timestamp, 0); + tgtC.addChangedCardKeywords(addedKW, removedKW, false, timestamp, null); if (!"Permanent".equals(sa.getParam("Duration"))) { final GameCommand until = new GameCommand() { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DetachedCardEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DetachedCardEffect.java index 22c6dbaed75..ff393cd2f91 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DetachedCardEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DetachedCardEffect.java @@ -1,7 +1,9 @@ package forge.game.ability.effects; import forge.card.GamePieceType; +import forge.game.Game; import forge.game.card.Card; +import forge.game.player.Player; //Class for an effect that acts as its own card instead of being attached to a card //Example: Commander Effect @@ -19,6 +21,29 @@ public class DetachedCardEffect extends Card { setEffectSource(card0); } + public DetachedCardEffect(Player owner, String name) { + super(owner.getGame().nextCardId(), null, owner.getGame()); + this.card = null; + + this.setName(name); + this.setOwner(owner); + this.setGamePieceType(GamePieceType.EFFECT); + } + + public DetachedCardEffect(DetachedCardEffect from, boolean assignNewId) { + this(from, from.getGame(), assignNewId); + } + + public DetachedCardEffect(DetachedCardEffect from, Game game, boolean assignNewId) { + super(assignNewId ? game.nextCardId() : from.id, from.getPaperCard(), game); + this.setName(from.getName()); + this.setGamePieceType(GamePieceType.EFFECT); + if(from.getGame() == game) { + this.setOwner(from.getOwner()); + this.setEffectSource(from.getEffectSource()); + } + } + @Override public Card getCardForUi() { return card; //use linked card for the sake of UI display logic diff --git a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java index ef993b52cd3..a6fe6f0f877 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java @@ -251,6 +251,10 @@ public class EffectEffect extends SpellAbilityEffect { addExileOnLostTrigger(eff); } + if (sa.hasParam("ExileOnCounter")) { + addExileCounterTrigger(eff, sa.getParam("ExileOnCounter")); + } + // Set Imprinted if (effectImprinted != null) { eff.addImprintedCards(AbilityUtils.getDefinedCards(hostCard, effectImprinted, sa)); diff --git a/forge-game/src/main/java/forge/game/ability/effects/GameLossEffect.java b/forge-game/src/main/java/forge/game/ability/effects/GameLossEffect.java index 4b6960e6b2c..e90069eeced 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/GameLossEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/GameLossEffect.java @@ -3,7 +3,6 @@ package forge.game.ability.effects; import java.util.List; import forge.game.ability.SpellAbilityEffect; -import forge.game.card.Card; import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -28,10 +27,8 @@ public class GameLossEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - final Card card = sa.getHostCard(); - for (final Player p : getTargetPlayers(sa)) { - p.loseConditionMet(GameLossReason.SpellEffect, card.getName()); + p.loseConditionMet(GameLossReason.SpellEffect, sa.getHostCard().getName()); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java b/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java index df74dca2c46..a8ff07b67b3 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java @@ -14,7 +14,7 @@ public class HauntEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { Card host = sa.getHostCard(); - if (host.isPermanent()) { + if (host.isPermanent() && sa.hasTriggeringObject(AbilityKey.NewCard)) { // get new version instead of battlefield lki host = (Card) sa.getTriggeringObject(AbilityKey.NewCard); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/MakeCardEffect.java b/forge-game/src/main/java/forge/game/ability/effects/MakeCardEffect.java index 7bb160975e5..c33eb7d3b35 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/MakeCardEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/MakeCardEffect.java @@ -40,7 +40,7 @@ public class MakeCardEffect extends SpellAbilityEffect { List faces = new ArrayList<>(); List pack = null; List names = Lists.newArrayList(); - + final String desc = sa.getParamOrDefault("OptionPrompt", ""); if (sa.hasParam("Optional") && sa.hasParam("OptionPrompt") && //for now, OptionPrompt is needed !player.getController().confirmAction(sa, null, Localizer.getInstance().getMessage(desc), null)) { @@ -172,7 +172,7 @@ public class MakeCardEffect extends SpellAbilityEffect { CardCollection madeCards = new CardCollection(); final boolean wCounter = sa.hasParam("WithCounter"); final boolean battlefield = zone.equals(ZoneType.Battlefield); - + for (final Card c : cards) { if (wCounter && battlefield) { int numCtr = AbilityUtils.calculateAmount(source, sa.getParamOrDefault("WithCounterNum", "1"), sa); @@ -227,7 +227,7 @@ public class MakeCardEffect extends SpellAbilityEffect { } } - private List parseFaces (final SpellAbility sa, final String param) { + private List parseFaces(final SpellAbility sa, final String param) { List parsedFaces = new ArrayList<>(); for (String s : sa.getParam(param).split(",")) { // Cardnames that include "," must use ";" instead (i.e. Tovolar; Dire Overlord) @@ -241,7 +241,7 @@ public class MakeCardEffect extends SpellAbilityEffect { return parsedFaces; } - private Card finishMaking (final SpellAbility sa, final Card made, final Card source) { + private Card finishMaking(final SpellAbility sa, final Card made, final Card source) { if (sa.hasParam("FaceDown")) made.turnFaceDown(true); if (sa.hasParam("RememberMade")) source.addRemembered(made); if (sa.hasParam("ImprintMade")) source.addImprintedCard(made); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java index cc71c01040c..739620d6d60 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManifestBaseEffect.java @@ -24,57 +24,74 @@ public abstract class ManifestBaseEffect extends SpellAbilityEffect { final Game game = source.getGame(); // Usually a number leaving possibility for X, Sacrifice X land: Manifest X creatures. final int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(source, sa.getParam("Amount"), sa) : 1; + final int times = sa.hasParam("Times") ? AbilityUtils.calculateAmount(source, sa.getParam("Times"), sa) : 1; - for (final Player p : getTargetPlayers(sa, "DefinedPlayer")) { - CardCollection tgtCards; - boolean fromLibrary = false; - if (sa.hasParam("Choices") || sa.hasParam("ChoiceZone")) { - ZoneType choiceZone = ZoneType.Hand; - if (sa.hasParam("ChoiceZone")) { - choiceZone = ZoneType.smartValueOf(sa.getParam("ChoiceZone")); - fromLibrary = choiceZone.equals(ZoneType.Library); - } - CardCollectionView choices = p.getCardsIn(choiceZone); - if (sa.hasParam("Choices")) { - choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, source, sa); - } - if (choices.isEmpty()) { - continue; - } + for (int i = 0; i < times; i++) { + for (final Player p : getTargetPlayers(sa, "DefinedPlayer")) { + CardCollection tgtCards; + Card toGrave = null; + boolean fromLibrary = false; + if (sa.hasParam("Choices") || sa.hasParam("ChoiceZone")) { + ZoneType choiceZone = ZoneType.Hand; + if (sa.hasParam("ChoiceZone")) { + choiceZone = ZoneType.smartValueOf(sa.getParam("ChoiceZone")); + fromLibrary = choiceZone.equals(ZoneType.Library); + } + CardCollectionView choices = p.getCardsIn(choiceZone); + if (sa.hasParam("Choices")) { + choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, source, sa); + } + if (choices.isEmpty()) { + continue; + } - String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : getDefaultMessage() + " "; + String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : getDefaultMessage() + " "; - tgtCards = new CardCollection(p.getController().chooseCardsForEffect(choices, sa, title, amount, amount, false, null)); - } else if ("TopOfLibrary".equals(sa.getParamOrDefault("Defined", "TopOfLibrary"))) { - tgtCards = p.getTopXCardsFromLibrary(amount); - fromLibrary = true; - } else { - tgtCards = getTargetCards(sa); - if (tgtCards.allMatch(CardPredicates.inZone(ZoneType.Library))) { + tgtCards = new CardCollection(p.getController().chooseCardsForEffect(choices, sa, title, amount, amount, false, null)); + } else if (sa.hasParam("Dread")) { + tgtCards = p.getTopXCardsFromLibrary(2); + if (!tgtCards.isEmpty()) { + Card manifest = p.getController().chooseSingleEntityForEffect(tgtCards, sa, getDefaultMessage(), null); + tgtCards.remove(manifest); + toGrave = tgtCards.isEmpty() ? null : tgtCards.getFirst(); + tgtCards = new CardCollection(manifest); + } fromLibrary = true; + } else if ("TopOfLibrary".equals(sa.getParamOrDefault("Defined", "TopOfLibrary"))) { + tgtCards = p.getTopXCardsFromLibrary(amount); + fromLibrary = true; + } else { + tgtCards = getTargetCards(sa); + if (tgtCards.allMatch(CardPredicates.inZone(ZoneType.Library))) { + fromLibrary = true; + } } - } - if (sa.hasParam("Shuffle")) { - CardLists.shuffle(tgtCards); - } + if (sa.hasParam("Shuffle")) { + CardLists.shuffle(tgtCards); + } - if (fromLibrary) { - for (Card c : tgtCards) { - // CR 701.34d If an effect instructs a player to manifest multiple cards from their library, those cards are manifested one at a time. + if (fromLibrary) { + for (Card c : tgtCards) { + // CR 701.34d If an effect instructs a player to manifest multiple cards from their library, those cards are manifested one at a time. + Map moveParams = AbilityKey.newMap(); + CardZoneTable triggerList = AbilityKey.addCardZoneTableParams(moveParams, sa); + internalEffect(c, p, sa, moveParams); + if (sa.hasParam("Dread") && toGrave != null) { + game.getAction().moveToGraveyard(toGrave, sa, moveParams); + toGrave = null; + } + triggerList.triggerChangesZoneAll(game, sa); + } + } else { + // manifest from other zones should be done at the same time Map moveParams = AbilityKey.newMap(); CardZoneTable triggerList = AbilityKey.addCardZoneTableParams(moveParams, sa); - internalEffect(c, p, sa, moveParams); + for (Card c : tgtCards) { + internalEffect(c, p, sa, moveParams); + } triggerList.triggerChangesZoneAll(game, sa); } - } else { - // manifest from other zones should be done at the same time - Map moveParams = AbilityKey.newMap(); - CardZoneTable triggerList = AbilityKey.addCardZoneTableParams(moveParams, sa); - for (Card c : tgtCards) { - internalEffect(c, p, sa, moveParams); - } - triggerList.triggerChangesZoneAll(game, sa); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ProtectAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ProtectAllEffect.java index e342dd64834..5f7700b86ff 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ProtectAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ProtectAllEffect.java @@ -86,7 +86,7 @@ public class ProtectAllEffect extends SpellAbilityEffect { CardCollectionView list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), valid, sa.getActivatingPlayer(), host, sa); for (final Card tgtC : list) { - tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, 0, true); + tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, null, true); if (!"Permanent".equals(sa.getParam("Duration"))) { // If not Permanent, remove protection at EOT diff --git a/forge-game/src/main/java/forge/game/ability/effects/ProtectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ProtectEffect.java index 5f71cb24246..10235488e75 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ProtectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ProtectEffect.java @@ -153,7 +153,7 @@ public class ProtectEffect extends SpellAbilityEffect { continue; } - tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, 0, true); + tgtC.addChangedCardKeywords(gainsKWList, null, false, timestamp, null, true); if (!"Permanent".equals(sa.getParam("Duration"))) { // If not Permanent, remove protection at EOT diff --git a/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java index 3515f274df3..4a44c77d979 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java @@ -68,7 +68,7 @@ public class PumpAllEffect extends SpellAbilityEffect { params.put("Category", "Keywords"); tgtC.addPerpetual(params); } - tgtC.addChangedCardKeywords(kws, null, false, timestamp, 0); + tgtC.addChangedCardKeywords(kws, null, false, timestamp, null); } if (redrawPT) { tgtC.updatePowerToughnessForView(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java index e76511dcc29..180a6b67322 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PumpEffect.java @@ -78,7 +78,7 @@ public class PumpEffect extends SpellAbilityEffect { params.put("Category", "Keywords"); gameCard.addPerpetual(params); } - gameCard.addChangedCardKeywords(kws, Lists.newArrayList(), false, timestamp, 0); + gameCard.addChangedCardKeywords(kws, Lists.newArrayList(), false, timestamp, null); } if (!hiddenKws.isEmpty()) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java index 82fa064dc41..84c937f9a80 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java @@ -48,7 +48,7 @@ public class ReplaceEffect extends SpellAbilityEffect { for (Player key : AbilityUtils.getDefinedPlayers(card, sa.getParam("VarKey"), sa)) { m.put(key, m.getOrDefault(key, 0) + AbilityUtils.calculateAmount(card, varValue, sa)); } - } else { + } else if (varName != null) { params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa)); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 45706a32ad3..4611047be93 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -96,6 +96,15 @@ public class SetStateEffect extends SpellAbilityEffect { continue; } + if (sa.hasParam("RevealFirst")) { + Card lki = CardCopyService.getLKICopy(tgtCard); + lki.forceTurnFaceUp(); + game.getAction().reveal(new CardCollection(lki), lki.getOwner(), true, Localizer.getInstance().getMessage("lblRevealFaceDownCards")); + if (sa.hasParam("ValidNewFace") && !lki.isValid(sa.getParam("ValidNewFace").split(","), p, host, sa)) { + continue; + } + } + // facedown cards that are not Permanent, can't turn faceup there if ("TurnFaceUp".equals(mode) && gameCard.isFaceDown() && gameCard.isInPlay()) { if (gameCard.hasMergedCard()) { @@ -118,7 +127,6 @@ public class SetStateEffect extends SpellAbilityEffect { Card lki = CardCopyService.getLKICopy(gameCard); lki.forceTurnFaceUp(); game.getAction().reveal(new CardCollection(lki), lki.getOwner(), true, Localizer.getInstance().getMessage("lblFaceDownCardCantTurnFaceUp")); - continue; } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SubgameEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SubgameEffect.java index a5aa82bba4d..69a042ca6de 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SubgameEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SubgameEffect.java @@ -71,7 +71,6 @@ public class SubgameEffect extends SpellAbilityEffect { } // Commander - List commanders = Lists.newArrayList(); final CardCollectionView commandCards = maingamePlayer.getCardsIn(ZoneType.Command); for (final Card card : commandCards) { if (card.isCommander()) { @@ -85,15 +84,10 @@ public class SubgameEffect extends SpellAbilityEffect { cmd.setChosenColors(chosenColors); subgame.getAction().notifyOfValue(cmdColorsa, cmd, Localizer.getInstance().getMessage("lblPlayerPickedChosen", player.getName(), Lang.joinHomogenous(chosenColors)), player); } - cmd.setCommander(true); com.add(cmd); - commanders.add(cmd); - com.add(Player.createCommanderEffect(subgame, cmd)); + player.addCommander(cmd); } } - if (!commanders.isEmpty()) { - player.setCommanders(commanders); - } // Conspiracies // 720.2 doesn't mention Conspiracy cards so I guess they don't move diff --git a/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java index e692e7f54a8..dde3c4f3912 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SurveilEffect.java @@ -33,6 +33,9 @@ public class SurveilEffect extends SpellAbilityEffect { if (sa.hasParam("Amount")) { num = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa); } + if (num == 0) { + return; + } boolean isOptional = sa.hasParam("Optional"); diff --git a/forge-game/src/main/java/forge/game/ability/effects/TokenEffectBase.java b/forge-game/src/main/java/forge/game/ability/effects/TokenEffectBase.java index 8c72b3c5168..a7b06f64d00 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/TokenEffectBase.java +++ b/forge-game/src/main/java/forge/game/ability/effects/TokenEffectBase.java @@ -177,7 +177,7 @@ public abstract class TokenEffectBase extends SpellAbilityEffect { } if (!pumpKeywords.isEmpty()) { - moved.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, timestamp, 0); + moved.addChangedCardKeywords(pumpKeywords, Lists.newArrayList(), false, timestamp, null); addPumpUntil(sa, moved, timestamp); } diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 895cbc5cde6..ccaab0dba50 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -75,7 +75,7 @@ import java.util.Map.Entry; * @author Forge * @version $Id$ */ -public class Card extends GameEntity implements Comparable, IHasSVars { +public class Card extends GameEntity implements Comparable, IHasSVars, ITranslatable { private Game game; private final IPaperCard paperCard; @@ -805,9 +805,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { // Check replacement effects Map repParams = AbilityKey.mapFromAffected(this); - List list = game.getReplacementHandler().getReplacementList(ReplacementType.TurnFaceUp, - repParams, ReplacementLayer.CantHappen); - if (!list.isEmpty()) return false; + if (game.getReplacementHandler().cantHappenCheck(ReplacementType.TurnFaceUp, repParams)) return false; CardCollectionView cards = hasMergedCard() ? getMergedCards() : new CardCollection(this); boolean retResult = false; @@ -1321,6 +1319,26 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } + /** + * Gives a collection of all cards that are melded, merged, or are otherwise representing + * a single permanent alongside this one. + * @param includeSelf Whether this card is included in the resulting CardCollection. + */ + public final CardCollection getAllComponentCards(boolean includeSelf) { + CardCollection out = new CardCollection(); + if(includeSelf) + out.add(this); + if(this.getMeldedWith() != null) + out.add(this.getMeldedWith()); + if(mergedTo != null) //Should be safe to recurse here so long as mergedTo remains a one-way relationship. + out.addAll(mergedTo.getAllComponentCards(true)); + if(this.hasMergedCard()) + out.addAll(mergedCards); + if(!includeSelf) //mergedCards includes self. + out.remove(this); + return out; + } + public final void moveMergedToSubgame(SpellAbility cause) { if (hasMergedCard()) { Zone zone = getZone(); @@ -1677,7 +1695,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { if (!Keyword.smartValueOf(counterType.toString().split(":")[0]).isMultipleRedundant()) { num = getCounters(counterType); } - addChangedCardKeywords(Collections.nCopies(num, counterType.toString()), null, false, timestamp, 0, updateView); + addChangedCardKeywords(Collections.nCopies(num, counterType.toString()), null, false, timestamp, null, updateView); return true; } @@ -2226,7 +2244,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { sbLong.append("\r\n"); } sb.append(sbLong); - return CardTranslation.translateMultipleDescriptionText(sb.toString(), getName()); + return CardTranslation.translateMultipleDescriptionText(sb.toString(), this); } // convert a keyword list to the String that should be displayed in game @@ -2410,9 +2428,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { String pip = mc.getFirstPhyrexianPip(); String[] parts = pip.substring(1, pip.length() - 1).split("/"); final StringBuilder rem = new StringBuilder(); - rem.append(pip).append(" can be paid with {").append(parts[1]).append("}"); + rem.append(pip).append(" can be paid with {").append(parts[0]).append("}"); if (parts.length > 2) { - rem.append(", {").append(parts[2]).append("},"); + rem.append(", {").append(parts[1]).append("},"); } rem.append(" or 2 life. "); if (mc.getPhyrexianCount() > 1) { @@ -2631,7 +2649,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { sbLong.append("\r\n"); } sb.append(sbLong); - return CardTranslation.translateMultipleDescriptionText(sb.toString(), getName()); + return CardTranslation.translateMultipleDescriptionText(sb.toString(), this); } private String kickerDesc(String keyword, String remText) { @@ -3193,7 +3211,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } - sb.append(CardTranslation.translateMultipleDescriptionText(sbBefore.toString(), state.getName())); + sb.append(CardTranslation.translateMultipleDescriptionText(sbBefore.toString(), state)); // add Spells there to main StringBuilder sb.append(strSpell); @@ -3222,7 +3240,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } - sb.append(CardTranslation.translateMultipleDescriptionText(sbAfter.toString(), state.getName())); + sb.append(CardTranslation.translateMultipleDescriptionText(sbAfter.toString(), state)); return sb; } @@ -3550,8 +3568,10 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public final void setCopiedPermanent(final Card c) { if (copiedPermanent == c) { return; } copiedPermanent = c; - if(c != null) + if(c != null) { currentState.setOracleText(c.getOracleText()); + currentState.setFunctionalVariantName(c.getCurrentState().getFunctionalVariantName()); + } //Could fetch the card rules oracle text in an "else" clause here, //but CardRules isn't aware of the card's state. May be better to //just stash the original oracle text if this comes up. @@ -4074,7 +4094,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return state.getType(); } - // TODO add changed type by card text public Iterable getChangedCardTypes() { // If there are no changed types, just return an empty immutable list, which actually // produces a surprisingly large speedup by avoid lots of temp objects and making iteration @@ -4586,19 +4605,13 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return StaticAbilityCombatDamageToughness.combatDamageToughness(this); } - // How much combat damage does the card deal - public final StatBreakdown getNetCombatDamageBreakdown() { - if (hasKeyword("CARDNAME assigns no combat damage")) { - return new StatBreakdown(); - } - - if (toughnessAssignsDamage()) { - return getNetToughnessBreakdown(); - } - return getNetPowerBreakdown(); + public final boolean assignNoCombatDamage() { + return StaticAbilityAssignNoCombatDamage.assignNoCombatDamage(this); } + + // How much combat damage does the card deal public final int getNetCombatDamage() { - return getNetCombatDamageBreakdown().getTotal(); + return assignNoCombatDamage() ? 0 : (toughnessAssignsDamage() ? getNetToughnessBreakdown() : getNetPowerBreakdown()).getTotal(); } private int intensity = 0; @@ -4641,7 +4654,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } else if (category.equals("Keywords")) { boolean removeAll = p.containsKey("RemoveAll") && (boolean) p.get("RemoveAll") == true; addChangedCardKeywords((List) p.get("AddKeywords"), Lists.newArrayList(), removeAll, - (long) p.get("Timestamp"), (long) 0); + (long) p.get("Timestamp"), null); } else if (category.equals("Types")) { addChangedCardTypes((CardType) p.get("AddTypes"), (CardType) p.get("RemoveTypes"), false, (Set) p.get("RemoveXTypes"), @@ -4751,9 +4764,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { // Check replacement effects Map repParams = AbilityKey.mapFromAffected(this); repParams.put(AbilityKey.IsCombat, attacker); // right name for parameter? - List list = getGame().getReplacementHandler().getReplacementList(ReplacementType.Tap, repParams, ReplacementLayer.CantHappen); - - return list.isEmpty(); + return !getGame().getReplacementHandler().cantHappenCheck(ReplacementType.Tap, repParams); } public final boolean tap(boolean tapAnimation, SpellAbility cause, Player tapper) { @@ -4949,7 +4960,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { KeywordInterface result = storedKeywordByText.get(triple); if (result == null) { result = ki.copy(this, false); - result.setStaticId(stAb.getId()); + result.setStatic(stAb); result.setIdx(idx); result.setIntrinsic(true); storedKeywordByText.put(triple, result); @@ -5072,11 +5083,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final void addChangedCardKeywords(final List keywords, final List removeKeywords, - final boolean removeAllKeywords, final long timestamp, final long staticId) { - addChangedCardKeywords(keywords, removeKeywords, removeAllKeywords, timestamp, staticId, true); + final boolean removeAllKeywords, final long timestamp, final StaticAbility st) { + addChangedCardKeywords(keywords, removeKeywords, removeAllKeywords, timestamp, st, true); } public final void addChangedCardKeywords(final List keywords, final List removeKeywords, - final boolean removeAllKeywords, final long timestamp, final long staticId, final boolean updateView) { + final boolean removeAllKeywords, final long timestamp, final StaticAbility st, final boolean updateView) { List kws = Lists.newArrayList(); if (keywords != null) { long idx = 1; @@ -5090,14 +5101,14 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } if (canHave) { - kws.add(getKeywordForStaticAbility(kw, staticId, idx)); + kws.add(getKeywordForStaticAbility(kw, st, idx)); } idx++; } } final KeywordsChange newCks = new KeywordsChange(kws, removeKeywords, removeAllKeywords); - changedCardKeywords.put(timestamp, staticId, newCks); + changedCardKeywords.put(timestamp, st == null ? 0l : st.getId(), newCks); if (updateView) { updateKeywords(); @@ -5106,12 +5117,13 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } - public final KeywordInterface getKeywordForStaticAbility(String kw, final long staticId, final long idx) { + public final KeywordInterface getKeywordForStaticAbility(String kw, final StaticAbility st, final long idx) { KeywordInterface result; + long staticId = st == null ? 0 : st.getId(); Triple triple = Triple.of(kw, staticId, idx); if (staticId < 1 || !storedKeywords.containsKey(triple)) { result = Keyword.getInstance(kw); - result.setStaticId(staticId); + result.setStatic(st); result.setIdx(idx); result.createTraits(this, false); if (staticId > 0) { @@ -5124,8 +5136,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final void addKeywordForStaticAbility(KeywordInterface kw) { - if (kw.getStaticId() > 0) { - storedKeywords.put(Triple.of(kw.getOriginal(), kw.getStaticId(), kw.getIdx()), kw); + if (kw.getStatic() != null) { + storedKeywords.put(Triple.of(kw.getOriginal(), (long)kw.getStatic().getId(), kw.getIdx()), kw); } } @@ -5170,8 +5182,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public final void addChangedCardKeywordsInternal( final Collection keywords, final Collection removeKeywords, final boolean removeAllKeywords, - final long timestamp, final long staticId, final boolean updateView) { + final long timestamp, final StaticAbility st, final boolean updateView) { final KeywordsChange newCks = new KeywordsChange(keywords, removeKeywords, removeAllKeywords); + long staticId = st == null ? 0 : st.getId(); changedCardKeywords.put(timestamp, staticId, newCks); if (updateView) { @@ -5688,7 +5701,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { // Just phased in, time to run the phased in trigger getGame().getTriggerHandler().registerActiveTrigger(this, false); - getGame().getTriggerHandler().runTrigger(TriggerType.PhaseIn, runParams, false); + getGame().getTriggerHandler().runTrigger(TriggerType.PhaseIn, runParams, true); } game.updateLastStateForCard(this); @@ -5808,9 +5821,15 @@ public class Card extends GameEntity implements Comparable, IHasSVars { if (StringUtils.isNumeric(s)) { count += Integer.parseInt(s); } else { - String svar = StringUtils.join(parse); - if (state.hasSVar(svar)) { - count += AbilityUtils.calculateAmount(this, state.getSVar(svar), null); + StaticAbility st = inst.getStatic(); + // TODO make keywordinterface inherit from CardTrait somehow, or invent new interface + if (st != null && st.hasSVar(s)) { + count += AbilityUtils.calculateAmount(this, st.getSVar(s), null); + } else { + String svar = StringUtils.join(parse); + if (state.hasSVar(svar)) { + count += AbilityUtils.calculateAmount(this, state.getSVar(svar), null); + } } } } @@ -6352,10 +6371,17 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final String getImageKey() { - return getCardForUi().currentState.getImageKey(); + Card uiCard = getCardForUi(); + if(uiCard == null) + return ""; + return uiCard.currentState.getImageKey(); } public final void setImageKey(final String iFN) { - getCardForUi().currentState.setImageKey(iFN); + Card uiCard = getCardForUi(); + if(uiCard == null) + this.currentState.setImageKey(iFN); //Shouldn't really matter; the card isn't supposed to show in the UI anyway. + else + uiCard.currentState.setImageKey(iFN); } public final void setImageKey(final IPaperCard ipc, final CardStateName stateName) { if (ipc == null) @@ -6382,7 +6408,10 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public String getImageKey(CardStateName state) { - CardState c = getCardForUi().states.get(state); + Card uiCard = getCardForUi(); + if(uiCard == null) + return ""; + CardState c = uiCard.states.get(state); return (c != null ? c.getImageKey() : ""); } @@ -6545,7 +6574,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { suspectedTimestamp = getGame().getNextTimestamp(); // use this for CantHaveKeyword - addChangedCardKeywords(ImmutableList.of("Menace"), ImmutableList.of(), false, suspectedTimestamp, 0, true); + addChangedCardKeywords(ImmutableList.of("Menace"), ImmutableList.of(), false, suspectedTimestamp, null, true); if (suspectedStatic == null) { String effect = "Mode$ CantBlockBy | ValidBlocker$ Creature.Self | Description$ CARDNAME can't block."; @@ -6696,7 +6725,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { new CardType(Collections.singletonList("Creature"), true), false, EnumSet.of(RemoveType.EnchantmentTypes), bestowTimestamp, 0, updateView, false); addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.newArrayList(), - false, bestowTimestamp, 0, updateView); + false, bestowTimestamp, null, updateView); } public final void unanimateBestow() { @@ -7558,6 +7587,23 @@ public class Card extends GameEntity implements Comparable, IHasSVars { currentState.setOracleText(oracleText); } + @Override + public String getTranslationKey() { + return currentState.getTranslationKey(); + } + @Override + public String getUntranslatedName() { + return this.getName(); + } + @Override + public String getUntranslatedType() { + return currentState.getUntranslatedType(); + } + @Override + public String getUntranslatedOracle() { + return currentState.getUntranslatedOracle(); + } + @Override public CardView getView() { return view; diff --git a/forge-game/src/main/java/forge/game/card/CardCopyService.java b/forge-game/src/main/java/forge/game/card/CardCopyService.java index 1034a0192b4..b81b1799477 100644 --- a/forge-game/src/main/java/forge/game/card/CardCopyService.java +++ b/forge-game/src/main/java/forge/game/card/CardCopyService.java @@ -7,6 +7,7 @@ import forge.card.CardType; import forge.game.Game; import forge.game.GameEntity; import forge.game.ability.ApiType; +import forge.game.ability.effects.DetachedCardEffect; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import io.sentry.Breadcrumb; @@ -108,7 +109,11 @@ public class CardCopyService { if (assignNewId) { id = newOwner == null ? 0 : newOwner.getGame().nextCardId(); } - final Card c = new Card(id, in.getPaperCard(), in.getGame()); + final Card c; + if(in instanceof DetachedCardEffect) + c = new DetachedCardEffect((DetachedCardEffect) in, assignNewId); + else + c = new Card(id, in.getPaperCard(), in.getGame()); c.setOwner(newOwner); c.setSetCode(in.getSetCode()); @@ -217,7 +222,11 @@ public class CardCopyService { bread.setData("Player", copyFrom.getController().getName()); Sentry.addBreadcrumb(bread); - final Card newCopy = new Card(copyFrom.getId(), copyFrom.getPaperCard(), copyFrom.getGame(), null); + final Card newCopy; + if(copyFrom instanceof DetachedCardEffect) + newCopy = new DetachedCardEffect((DetachedCardEffect) copyFrom, false); + else + newCopy = new Card(copyFrom.getId(), copyFrom.getPaperCard(), copyFrom.getGame(), null); cachedMap.put(copyFrom.getId(), newCopy); newCopy.setSetCode(copyFrom.getSetCode()); newCopy.setOwner(copyFrom.getOwner()); 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 d3f7023543e..f00d3c7ab3a 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -356,13 +356,16 @@ public class CardFactory { } private static void readCardFace(Card c, ICardFace face) { + String variantName = null; //If it's a functional variant card, switch to that first. if(face.hasFunctionalVariants()) { - String variantName = c.getPaperCard().getFunctionalVariant(); + variantName = c.getPaperCard().getFunctionalVariant(); if (!IPaperCard.NO_FUNCTIONAL_VARIANT.equals(variantName)) { ICardFace variant = face.getFunctionalVariant(variantName); - if (variant != null) + if (variant != null) { face = variant; + c.getCurrentState().setFunctionalVariantName(variantName); + } else System.err.printf("Tried to apply unknown or unsupported variant - Card: \"%s\"; Variant: %s\n", face.getName(), variantName); } @@ -370,7 +373,7 @@ public class CardFactory { // Build English oracle and translated oracle mapping if (c.getId() >= 0) { - CardTranslation.buildOracleMapping(face.getName(), face.getOracleText()); + CardTranslation.buildOracleMapping(face.getName(), face.getOracleText(), variantName); } // Name first so Senty has the Card name diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index b8954b02970..672f6d6e521 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1067,8 +1067,8 @@ public class CardFactoryUtil { pump.setSubAbility(remove); remove.setSubAbility(cleanup); trigger.setOverridingAbility(trigMake); - - inst.addTrigger(trigger); + + inst.addTrigger(trigger); } else if (keyword.startsWith("Echo")) { final String[] k = keyword.split(":"); final String cost = k[1]; @@ -1381,7 +1381,7 @@ public class CardFactoryUtil { String hideawayDig = "DB$ Dig | Defined$ You | DigNum$ " + n + " | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True | RestRandomOrder$ True"; String hideawayEffect = "DB$ Effect | StaticAbilities$ STHideawayEffectLookAtCard | ForgetOnMoved$ Exile | RememberObjects$ Remembered | Duration$ Permanent"; String cleanupStr = "DB$ Cleanup | ClearRemembered$ True"; - + String lookAtCard = "Mode$ Continuous | Affected$ Card.IsRemembered | MayLookAt$ EffectSourceController | EffectZone$ Command | AffectedZone$ Exile | Description$ Any player who has controlled the permanent that exiled this card may look at this card in the exile zone."; SpellAbility digSA = AbilityFactory.getAbility(hideawayDig, card); @@ -1597,7 +1597,7 @@ public class CardFactoryUtil { trigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); trigger.setSVar("Offspring", "Count$OptionalKeywordAmount"); - inst.addTrigger(trigger); + inst.addTrigger(trigger); } else if (keyword.startsWith("Partner:")) { // Partner With final String[] k = keyword.split(":"); @@ -2354,7 +2354,17 @@ public class CardFactoryUtil { final String effect = "DB$ PutCounter | Defined$ ReplacedCard | CounterType$ TIME | CounterNum$ " + m + " | ETB$ True | SpellDescription$ " + desc; - final ReplacementEffect re = createETBReplacement(card, ReplacementLayer.Other, effect, false, true, intrinsic, "Card.Self+impended", ""); + SpellAbility repAb = AbilityFactory.getAbility(effect, card); + + String staticEffect = "DB$ Effect | StaticAbilities$ NoCreature | ExileOnCounter$ TIME | Duration$ UntilHostLeavesPlay"; + + String staticNoCreature = "Mode$ Continuous | Affected$ Card.EffectSource+counters_GE1_TIME | RemoveType$ Creature | Description$ EFFECTSOURCE isn't a creature."; + + AbilitySub effectAb = (AbilitySub)AbilityFactory.getAbility(staticEffect, card); + effectAb.setSVar("NoCreature", staticNoCreature); + repAb.setSubAbility(effectAb); + + final ReplacementEffect re = createETBReplacement(card, ReplacementLayer.Other, repAb, false, true, intrinsic, "Card.Self+impended", ""); inst.addReplacement(re); } else if (keyword.equals("Jump-start")) { @@ -2438,7 +2448,7 @@ public class CardFactoryUtil { re.setOverridingAbility(saCounter); - inst.addReplacement(re); + inst.addReplacement(re); } else if (keyword.equals("Rebound")) { String repeffstr = "Event$ Moved | ValidLKI$ Card.Self+wasCastFromHand+YouOwn+YouCtrl " + " | Origin$ Stack | Destination$ Graveyard | Fizzle$ False " @@ -2729,7 +2739,7 @@ public class CardFactoryUtil { sbRem.append(i + 1 == bCost.getCostParts().size() ? "." : " and "); i++; } - remTxt = sbRem.toString(); + remTxt = sbRem.toString(); } sbDesc.append(onlyMana ? " " : "—").append(bCost.toSimpleString()).append(!onlyMana ? "." : ""); sbDesc.append(" (").append(remTxt).append(")"); @@ -2821,12 +2831,7 @@ public class CardFactoryUtil { final String[] k = keyword.split(":"); final Cost disturbCost = new Cost(k[1], true); - SpellAbility newSA; - if (host.getAlternateState().getType().hasSubtype("Aura")) { - newSA = host.getAlternateState().getFirstAbility().copyWithDefinedCost(disturbCost); - } else { - newSA = new SpellPermanent(host, host.getAlternateState(), disturbCost); - } + SpellAbility newSA = host.getAlternateState().getFirstSpellAbilityWithFallback().copyWithDefinedCost(disturbCost); newSA.setCardState(host.getAlternateState()); StringBuilder sbCost = new StringBuilder("Disturb"); @@ -3137,7 +3142,7 @@ public class CardFactoryUtil { } else if (keyword.startsWith("Freerunning")) { final String[] k = keyword.split(":"); final Cost freerunningCost = new Cost(k[1], false); - final SpellAbility newSA = card.getFirstSpellAbility().copyWithDefinedCost(freerunningCost); + final SpellAbility newSA = card.getFirstSpellAbilityWithFallback().copyWithDefinedCost(freerunningCost); if (host.isInstant() || host.isSorcery()) { newSA.putParam("Secondary", "True"); @@ -3463,7 +3468,7 @@ public class CardFactoryUtil { } else if (keyword.startsWith("Prowl")) { final String[] k = keyword.split(":"); final Cost prowlCost = new Cost(k[1], false); - final SpellAbility newSA = card.getFirstSpellAbility().copyWithDefinedCost(prowlCost); + final SpellAbility newSA = card.getFirstSpellAbilityWithFallback().copyWithDefinedCost(prowlCost); if (host.isInstant() || host.isSorcery()) { newSA.putParam("Secondary", "True"); @@ -3993,11 +3998,8 @@ public class CardFactoryUtil { String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.withoutHorsemanship | Secondary$ True " + " | Description$ Horsemanship (" + inst.getReminderText() + ")"; inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); - } else if (keyword.startsWith("Impending")) { - String effect = "Mode$ Continuous | Affected$ Card.Self+counters_GE1_TIME | RemoveType$ Creature | Secondary$ True"; - inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); } else if (keyword.equals("Intimidate")) { - String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.nonArtifact+notSharesColorWith | Secondary$ True " + + String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.nonArtifact+!SharesColorWith | Secondary$ True " + " | Description$ Intimidate (" + inst.getReminderText() + ")"; inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); } else if (keyword.startsWith("Landwalk")) { diff --git a/forge-game/src/main/java/forge/game/card/CardLists.java b/forge-game/src/main/java/forge/game/card/CardLists.java index 536a3df78fb..8b9e79efae7 100644 --- a/forge-game/src/main/java/forge/game/card/CardLists.java +++ b/forge-game/src/main/java/forge/game/card/CardLists.java @@ -414,7 +414,7 @@ public class CardLists { public static int getTotalPower(Iterable cardList, boolean ignoreNegativePower, boolean crew) { int total = 0; for (final Card crd : cardList) { - if (crew && StaticAbilityCrewValue.hasAnyCrewValue(crd)) { + if (crew) { if (StaticAbilityCrewValue.crewsWithToughness(crd)) { total += ignoreNegativePower ? Math.max(0, crd.getNetToughness()) : crd.getNetToughness(); } else { diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 50dded21f8f..d314c85fbbd 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -670,6 +670,11 @@ public class CardProperty { if (cards.isEmpty() || !card.equals(cards.get(0))) { return false; } + } else if (property.startsWith("TopLibraryLand")) { + CardCollection cards = CardLists.filter(card.getOwner().getCardsIn(ZoneType.Library), CardPredicates.Presets.LANDS); + if (cards.isEmpty() || !card.equals(cards.get(0))) { + return false; + } } else if (property.startsWith("TopLibrary")) { final CardCollectionView cards = card.getOwner().getCardsIn(ZoneType.Library); if (cards.isEmpty() || !card.equals(cards.get(0))) { @@ -717,7 +722,6 @@ public class CardProperty { } final String restriction = property.split("SharesColorWith ")[1]; - switch (restriction) { case "MostProminentColor": byte mask = CardFactoryUtil.getMostProminentColors(game.getCardsIn(ZoneType.Battlefield)); @@ -769,19 +773,6 @@ public class CardProperty { byte mostProm = CardFactoryUtil.getMostProminentColors(game.getCardsIn(ZoneType.Battlefield)); return ColorSet.fromMask(mostProm).hasAnyColor(MagicColor.fromName(color)); - } else if (property.startsWith("notSharesColorWith")) { - if (property.equals("notSharesColorWith")) { - if (card.sharesColorWith(source)) { - return false; - } - } else { - final String restriction = property.split("notSharesColorWith ")[1]; - for (final Card c : sourceController.getCardsIn(ZoneType.Battlefield)) { - if (c.isValid(restriction, sourceController, source, spellAbility) && card.sharesColorWith(c)) { - return false; - } - } - } } else if (property.startsWith("MostProminentCreatureTypeInLibrary")) { final CardCollectionView list = sourceController.getCardsIn(ZoneType.Library); for (String s : CardFactoryUtil.getMostProminentCreatureType(list)) { @@ -840,6 +831,14 @@ public class CardProperty { return false; } } else { + // Special case to prevent list from comparing with itself + if (property.startsWith("sharesCardTypeWithOther")) { + final String restriction = property.split("sharesCardTypeWithOther ")[1]; + CardCollection list = AbilityUtils.getDefinedCards(source, restriction, spellAbility); + list.remove(card); + return Iterables.any(list, CardPredicates.sharesCardTypeWith(card)); + } + final String restriction = property.split("sharesCardTypeWith ")[1]; switch (restriction) { case "Imprinted": @@ -1499,6 +1498,14 @@ public class CardProperty { if (card.getCMC() % 2 != 1) { return false; } + } else if (property.equals("powerEven")) { + if (card.getNetPower() % 2 != 0) { + return false; + } + } else if (property.equals("powerOdd")) { + if (card.getNetPower() % 2 != 1) { + return false; + } } else if (property.equals("cmcChosenEvenOdd")) { if (!source.hasChosenEvenOdd()) { return false; @@ -1620,8 +1627,7 @@ public class CardProperty { } } if (property.startsWith("attacking ")) { // generic "attacking [DefinedGameEntity]" - FCollection defined = AbilityUtils.getDefinedEntities(source, property.split(" ")[1], - spellAbility); + FCollection defined = AbilityUtils.getDefinedEntities(source, property.split(" ")[1], spellAbility); final GameEntity defender = combat.getDefenderByAttacker(card); if (!defined.contains(defender)) { return false; diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index ab3bd85180e..ebbb765a436 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -44,20 +44,24 @@ import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityPredicates; +import forge.game.spellability.SpellPermanent; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.util.Iterables; +import forge.util.ITranslatable; import forge.util.collect.FCollection; import forge.util.collect.FCollectionView; import io.sentry.Breadcrumb; import io.sentry.Sentry; +import org.apache.commons.lang3.StringUtils; -public class CardState extends GameObject implements IHasSVars { +public class CardState extends GameObject implements IHasSVars, ITranslatable { private String name = ""; private CardType type = new CardType(false); private ManaCost manaCost = ManaCost.NO_COST; private byte color = MagicColor.COLORLESS; private String oracleText = ""; + private String functionalVariantName = null; private int basePower = 0; private int baseToughness = 0; private String basePowerString = null; @@ -202,6 +206,16 @@ public class CardState extends GameObject implements IHasSVars { view.setOracleText(oracleText); } + public String getFunctionalVariantName() { + return functionalVariantName; + } + public void setFunctionalVariantName(String functionalVariantName) { + if(functionalVariantName != null && functionalVariantName.isEmpty()) + functionalVariantName = null; + this.functionalVariantName = functionalVariantName; + view.setFunctionalVariantName(functionalVariantName); + } + public final int getBasePower() { return basePower; @@ -364,6 +378,15 @@ public class CardState extends GameObject implements IHasSVars { return Iterables.getFirst(getNonManaAbilities(), null); } + public final SpellAbility getFirstSpellAbilityWithFallback() { + SpellAbility sa = getFirstSpellAbility(); + if (sa != null || getTypeWithChanges().isLand()) { + return sa; + } + // this happens if it's transformed backside (e.g. Disturbed) + return new SpellPermanent(getCard(), this); + } + public final boolean hasSpellAbility(final SpellAbility sa) { return getSpellAbilities().contains(sa); } @@ -605,6 +628,7 @@ public class CardState extends GameObject implements IHasSVars { setManaCost(source.getManaCost()); setColor(source.getColor()); setOracleText(source.getOracleText()); + setFunctionalVariantName(source.getFunctionalVariantName()); setBasePower(source.getBasePower()); setBaseToughness(source.getBaseToughness()); setBaseLoyalty(source.getBaseLoyalty()); @@ -804,4 +828,21 @@ public class CardState extends GameObject implements IHasSVars { } return cloakUp; } + + @Override + public String getTranslationKey() { + if(StringUtils.isNotEmpty(functionalVariantName)) + return name + " $" + functionalVariantName; + return name; + } + + @Override + public String getUntranslatedType() { + return getType().toString(); + } + + @Override + public String getUntranslatedOracle() { + return getOracleText(); + } } 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 b2a7d5f85a6..5caefa96aac 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -1161,7 +1161,7 @@ public class CardView extends GameEntityView { return (zone + ' ' + CardTranslation.getTranslatedName(name) + " (" + getId() + ")").trim(); } - public class CardStateView extends TrackableObject { + public class CardStateView extends TrackableObject implements ITranslatable { private static final long serialVersionUID = 6673944200513430607L; private final CardStateName state; @@ -1314,6 +1314,13 @@ public class CardView extends GameEntityView { set(TrackableProperty.OracleText, oracleText.replace("\\n", "\r\n\r\n").trim()); } + public String getFunctionalVariantName() { + return get(TrackableProperty.FunctionalVariant); + } + void setFunctionalVariantName(String functionalVariant) { + set(TrackableProperty.FunctionalVariant, functionalVariant); + } + public String getRulesText() { return get(TrackableProperty.RulesText); } @@ -1737,6 +1744,25 @@ public class CardView extends GameEntityView { public boolean isAttraction() { return getType().isAttraction(); } + + @Override + public String getTranslationKey() { + String key = getName(); + String variant = getFunctionalVariantName(); + if(StringUtils.isNotEmpty(variant)) + key = key + " $" + variant; + return key; + } + + @Override + public String getUntranslatedType() { + return getType().toString(); + } + + @Override + public String getUntranslatedOracle() { + return getOracleText(); + } } //special methods for updating card and player properties as needed and returning the new collection diff --git a/forge-game/src/main/java/forge/game/card/CardZoneTable.java b/forge-game/src/main/java/forge/game/card/CardZoneTable.java index 324e6e40dff..7fef845a4a9 100644 --- a/forge-game/src/main/java/forge/game/card/CardZoneTable.java +++ b/forge-game/src/main/java/forge/game/card/CardZoneTable.java @@ -102,15 +102,16 @@ public class CardZoneTable extends ForwardingTable runParams = AbilityKey.newMap(); runParams.put(AbilityKey.Cards, new CardZoneTable(this)); runParams.put(AbilityKey.Cause, cause); diff --git a/forge-game/src/main/java/forge/game/card/CounterEnumType.java b/forge-game/src/main/java/forge/game/card/CounterEnumType.java index 0d289ba605f..1a8645dedad 100644 --- a/forge-game/src/main/java/forge/game/card/CounterEnumType.java +++ b/forge-game/src/main/java/forge/game/card/CounterEnumType.java @@ -327,6 +327,8 @@ public enum CounterEnumType { POLYP("POLYP", 236, 185, 198), + POSSESSION("POSSN", 60, 65, 85), + PREY("PREY", 240, 0, 0), PUPA("PUPA", 0, 223, 203), @@ -345,6 +347,8 @@ public enum CounterEnumType { QUEST("QUEST", 251, 189, 0), + RELEASE("RELEASE", 200, 210, 50), + REPRIEVE("REPR", 240, 120, 50), REJECTION("REJECT", 212, 235, 242), diff --git a/forge-game/src/main/java/forge/game/event/GameEventSpellAbilityCast.java b/forge-game/src/main/java/forge/game/event/GameEventSpellAbilityCast.java index 54e075c63c7..a64240e989d 100644 --- a/forge-game/src/main/java/forge/game/event/GameEventSpellAbilityCast.java +++ b/forge-game/src/main/java/forge/game/event/GameEventSpellAbilityCast.java @@ -11,14 +11,12 @@ public class GameEventSpellAbilityCast extends GameEvent { public final SpellAbility sa; public final SpellAbilityStackInstance si; - public final boolean replicate; public final int stackIndex; - public GameEventSpellAbilityCast(SpellAbility sp, SpellAbilityStackInstance si, int stackIndex, boolean replicate) { + public GameEventSpellAbilityCast(SpellAbility sp, SpellAbilityStackInstance si, int stackIndex) { sa = sp; this.si = si; this.stackIndex = stackIndex; - this.replicate = replicate; } /* (non-Javadoc) diff --git a/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java b/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java index ddf50034acc..659f6c8c221 100644 --- a/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java +++ b/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java @@ -25,7 +25,7 @@ public abstract class KeywordInstance> implements K private Keyword keyword; private String original; - private long staticId = 0; + private StaticAbility st = null; private long idx = -1; private List triggers = Lists.newArrayList(); @@ -366,12 +366,12 @@ public abstract class KeywordInstance> implements K sa.setIntrinsic(value); } } - - public long getStaticId() { - return this.staticId; + + public StaticAbility getStatic() { + return this.st; } - public void setStaticId(long v) { - this.staticId = v; + public void setStatic(StaticAbility st) { + this.st = st; } public long getIdx() { diff --git a/forge-game/src/main/java/forge/game/keyword/KeywordInterface.java b/forge-game/src/main/java/forge/game/keyword/KeywordInterface.java index 2143903e42f..f2352a7129c 100644 --- a/forge-game/src/main/java/forge/game/keyword/KeywordInterface.java +++ b/forge-game/src/main/java/forge/game/keyword/KeywordInterface.java @@ -23,8 +23,10 @@ public interface KeywordInterface extends Cloneable { String getReminderText(); int getAmount(); - long getStaticId(); - void setStaticId(long v); + + StaticAbility getStatic(); + void setStatic(StaticAbility st); + long getIdx(); void setIdx(long i); 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 a9153d07836..7c73f8e3ae0 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -264,12 +264,6 @@ public class PhaseHandler implements java.io.Serializable { p.resetNumDrawnThisDrawStep(); } playerTurn.drawCard(); - for (Player p : game.getPlayers()) { - if (p.isOpponentOf(playerTurn) && - p.hasKeyword("You draw a card during each opponent's draw step.")) { - p.drawCard(); - } - } break; case MAIN1: diff --git a/forge-game/src/main/java/forge/game/phase/Untap.java b/forge-game/src/main/java/forge/game/phase/Untap.java index eedbd5b20c5..4511625cb89 100644 --- a/forge-game/src/main/java/forge/game/phase/Untap.java +++ b/forge-game/src/main/java/forge/game/phase/Untap.java @@ -229,7 +229,7 @@ public class Untap extends Phase { final Map runParams = AbilityKey.newMap(); runParams.put(AbilityKey.Map, untapMap); game.getTriggerHandler().runTrigger(TriggerType.UntapAll, runParams, false); - } // end doUntap + } private static boolean optionalUntap(final Card c) { boolean untap = true; @@ -298,6 +298,10 @@ public class Untap extends Phase { runParams.put(AbilityKey.Cards, phasedOut); turn.getGame().getTriggerHandler().runTrigger(TriggerType.PhaseOutAll, runParams, false); } + if (!toPhase.isEmpty()) { + // collect now before some zone change during Untap resets triggers + turn.getGame().getTriggerHandler().collectTriggerForWaiting(); + } } private static void doDayTime(final Player previous) { diff --git a/forge-game/src/main/java/forge/game/player/GameLossReason.java b/forge-game/src/main/java/forge/game/player/GameLossReason.java index 1e8f9432281..d33630e5e87 100644 --- a/forge-game/src/main/java/forge/game/player/GameLossReason.java +++ b/forge-game/src/main/java/forge/game/player/GameLossReason.java @@ -39,33 +39,21 @@ public enum GameLossReason { OpponentWon, IntentionalDraw // Not a real "game loss" as such, but a reason not to continue playing. + ; - /* - * DoorToNothingness, // Door To Nothingness's ability activated - * - * // TODO: Implement game logics for the ones below Transcendence20Life, // - * When you have 20 or more life, you lose the game. FailedToPayPactUpkeep, - * // Pacts from Future Sight series (cost 0 but you must pay their real - * cost at next turn's upkeep, otherwise GL) PhageTheUntouchableDamage, // - * Whenever Phage deals combat damage to a player, that player loses the - * game. PhageTheUntouchableWrongETB, // When Phage the Untouchable ETB, if - * you didn't cast it from your hand, you lose the game. - * NefariousLichLeavesTB, // When Nefarious Lich leaves the battlefield, you - * lose the game. NefariousLichCannotExileGrave, // If damage would be dealt - * to you, exile that many cards from your graveyard instead. If you can't, - * you lose the game. LichWasPutToGraveyard, // When Lich is put into a - * graveyard from the battlefield, you lose the game. FinalFortune, // same - * as Warrior's Oath - lose at the granted extra turn's end step - * ImmortalCoilEmptyGraveyard, // When there are no cards in your graveyard, - * you lose the game. ForbiddenCryptEmptyGraveyard, // If you would draw a - * card, return a card from your graveyard to your hand instead. If you - * can't, you lose the game. - * - * // Amulet of quoz skipped for using ante, // Form of the Squirrel and - * Rocket-Powered Turbo Slug skipped for being part of UN- set + /** + * Parses a string into an enum member. + * @param string to parse + * @return enum equivalent */ + public static GameLossReason smartValueOf(String value) { + final String valToCompate = value.trim(); + for (final GameLossReason v : GameLossReason.values()) { + if (v.name().compareToIgnoreCase(valToCompate) == 0) { + return v; + } + } - // refer to - // http://gatherer.wizards.com/Pages/Search/Default.aspx?output=standard&text=+[%22lose+the+game%22] - // for more cards when they are printed + throw new RuntimeException("Element " + value + " not found in GameLossReason enum"); + } } 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 bae89b2a0de..db1a546be9a 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -62,6 +62,7 @@ import org.apache.commons.lang3.tuple.Pair; import java.util.*; import java.util.Map.Entry; +import java.util.function.Function; /** *

@@ -172,8 +173,9 @@ public class Player extends GameEntity implements Comparable { private int teamNumber = -1; private Card activeScheme = null; - private List commanders = Lists.newArrayList(); - private Map commanderCast = Maps.newHashMap(); + private final CardCollection commanders = new CardCollection(); + private final Map commanderCast = Maps.newHashMap(); + private DetachedCardEffect commanderEffect = null; private final Game game; private boolean triedToDrawFromEmptyLibrary = false; private CardCollection lostOwnership = new CardCollection(); @@ -286,7 +288,6 @@ public class Player extends GameEntity implements Comparable { activeScheme = getZone(ZoneType.SchemeDeck).get(0); game.getAction().moveToCommand(activeScheme, cause); - game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); final Map runParams = AbilityKey.newMap(); runParams.put(AbilityKey.Scheme, activeScheme); @@ -501,52 +502,43 @@ public class Player extends GameEntity implements Comparable { } public final int loseLife(int toLose, final boolean damage, final boolean manaBurn) { - int lifeLost = 0; - if (!canLoseLife()) { + // Rule 118.4 + // this is for players being able to pay 0 life nothing to do + // no trigger for lost no life + if (toLose <= 0 || !canLoseLife()) { return 0; } - if (toLose > 0) { - int oldLife = life; - // Run applicable replacement effects - final Map repParams = AbilityKey.mapFromAffected(this); - repParams.put(AbilityKey.Amount, toLose); - repParams.put(AbilityKey.IsDamage, damage); + int oldLife = life; + // Run applicable replacement effects + final Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.Amount, toLose); + repParams.put(AbilityKey.IsDamage, damage); - switch (getGame().getReplacementHandler().run(ReplacementType.LifeReduced, repParams)) { - case NotReplaced: - break; - case Updated: - // check if this is still the affected player - if (this.equals(repParams.get(AbilityKey.Affected))) { - toLose = (int) repParams.get(AbilityKey.Amount); - // there is nothing that changes lifegain into lifeloss this way - if (toLose <= 0) { - return 0; - } - } else { + switch (getGame().getReplacementHandler().run(ReplacementType.LifeReduced, repParams)) { + case NotReplaced: + break; + case Updated: + // check if this is still the affected player + if (this.equals(repParams.get(AbilityKey.Affected))) { + toLose = (int) repParams.get(AbilityKey.Amount); + // there is nothing that changes lifegain into lifeloss this way + if (toLose <= 0) { return 0; } - break; - default: + } else { return 0; } + break; + default: + return 0; + } - life -= toLose; - view.updateLife(this); - lifeLost = toLose; - if (manaBurn) { - game.fireEvent(new GameEventManaBurn(this, lifeLost, true)); - } else { - game.fireEvent(new GameEventPlayerLivesChanged(this, oldLife, life)); - } - } else if (toLose == 0) { - // Rule 118.4 - // this is for players being able to pay 0 life nothing to do - // no trigger for lost no life - return 0; + life -= toLose; + view.updateLife(this); + if (manaBurn) { + game.fireEvent(new GameEventManaBurn(this, toLose, true)); } else { - System.out.println("Player - trying to lose negative life"); - return 0; + game.fireEvent(new GameEventPlayerLivesChanged(this, oldLife, life)); } boolean firstLost = lifeLostThisTurn == 0; @@ -561,7 +553,7 @@ public class Player extends GameEntity implements Comparable { game.getTriggerHandler().runTrigger(TriggerType.LifeChanged, runParams, false); - return lifeLost; + return toLose; } public final boolean canLoseLife() { @@ -693,7 +685,7 @@ public class Player extends GameEntity implements Comparable { if (infect) { poisonCounters += amount; } - else if (!hasKeyword("Damage doesn't cause you to lose life.")) { + else { // rule 118.2. Damage dealt to a player normally causes that player to lose that much life. simultaneousDamage += amount; } @@ -1117,23 +1109,7 @@ public class Player extends GameEntity implements Comparable { } public void surveil(int num, SpellAbility cause, Map params) { - final Map repParams = AbilityKey.mapFromAffected(this); - repParams.put(AbilityKey.Source, cause); - repParams.put(AbilityKey.SurveilNum, num); - if (params != null) { - repParams.putAll(params); - } - - switch (getGame().getReplacementHandler().run(ReplacementType.Surveil, repParams)) { - case NotReplaced: - break; - case Updated: { - num = (int) repParams.get(AbilityKey.SurveilNum); - break; - } - default: - return; - } + num += StaticAbilitySurveilNum.surveilNumMod(this); final CardCollection topN = getTopXCardsFromLibrary(num); @@ -1840,6 +1816,7 @@ public class Player extends GameEntity implements Comparable { lastDrawnCard = c; return lastDrawnCard; } + public final Card getRingBearer() { return ringBearer; } @@ -1862,6 +1839,7 @@ public class Player extends GameEntity implements Comparable { ringBearer.setRingBearer(false); ringBearer = null; } + public final String getNamedCard() { return namedCard; } @@ -1974,7 +1952,6 @@ public class Player extends GameEntity implements Comparable { public final void altWinBySpellEffect(final String sourceName) { if (cantWin()) { - System.out.println("Tried to win, but currently can't."); return; } setOutcome(PlayerOutcome.altWin(sourceName)); @@ -1982,16 +1959,14 @@ public class Player extends GameEntity implements Comparable { public final boolean loseConditionMet(final GameLossReason state, final String spellName) { if (state != GameLossReason.OpponentWon) { - if (cantLose()) { - System.out.println("Tried to lose, but currently can't."); - return false; - } - // Replacement effects - if (game.getReplacementHandler().run(ReplacementType.GameLoss, AbilityKey.mapFromAffected(this)) != ReplacementResult.NotReplaced) { + Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.LoseReason, state); + if (game.getReplacementHandler().run(ReplacementType.GameLoss, repParams) != ReplacementResult.NotReplaced) { return false; } } + //final String spellName = sa != null ? sa.getHostCard().getName() : null; setOutcome(PlayerOutcome.loss(state, spellName)); return true; } @@ -2004,32 +1979,39 @@ public class Player extends GameEntity implements Comparable { setOutcome(PlayerOutcome.draw()); } + public final boolean conceded() { + return getOutcome() != null && getOutcome().lossState == GameLossReason.Conceded; + } + public final boolean cantLose() { - if (getOutcome() != null && getOutcome().lossState == GameLossReason.Conceded) { + if (conceded()) { return false; } - return hasKeyword("You can't lose the game."); + return cantLoseCheck(null); } public final boolean cantLoseForZeroOrLessLife() { - return cantLose() || hasKeyword("You don't lose the game for having 0 or less life."); + if (conceded()) { + return false; + } + return cantLoseCheck(GameLossReason.LifeReachedZero); + } + + public final boolean cantLoseCheck(final GameLossReason state) { + // Replacement effects + Map repParams = AbilityKey.mapFromAffected(this); + repParams.put(AbilityKey.LoseReason, state); + return game.getReplacementHandler().cantHappenCheck(ReplacementType.GameLoss, repParams); } public final boolean cantWin() { - boolean isAnyOppLoseProof = false; - for (Player p : game.getPlayers()) { - if (p == this || p.getOutcome() != null) { - continue; // except self and already dead - } - isAnyOppLoseProof |= p.hasKeyword("You can't lose the game."); - } - return hasKeyword("You can't win the game.") || isAnyOppLoseProof; + return game.getReplacementHandler().cantHappenCheck(ReplacementType.GameWin, AbilityKey.mapFromAffected(this)); } public final boolean checkLoseCondition() { // Just in case player already lost - if (getOutcome() != null) { - return getOutcome().lossState != null; + if (hasLost()) { + return true; } // check this first because of Lich's Mirror (704.7) @@ -2038,26 +2020,27 @@ public class Player extends GameEntity implements Comparable { if (triedToDrawFromEmptyLibrary) { triedToDrawFromEmptyLibrary = false; // one-shot check // Mine, Mine, Mine! prevents decking - if (!hasKeyword("You don't lose the game for drawing from an empty library.")) { - return loseConditionMet(GameLossReason.Milled, null); + if (loseConditionMet(GameLossReason.Milled, null)) { + return true; } } // Rule 704.5a - If a player has 0 or less life, he or she loses the game. final boolean hasNoLife = getLife() <= 0; - if (hasNoLife && !cantLoseForZeroOrLessLife()) { - return loseConditionMet(GameLossReason.LifeReachedZero, null); + if (hasNoLife && loseConditionMet(GameLossReason.LifeReachedZero, null)) { + return true; } // Rule 704.5c - If a player has ten or more poison counters, he or she loses the game. - if (getCounters(CounterEnumType.POISON) >= 10) { - return loseConditionMet(GameLossReason.Poisoned, null); + // 704.6b In a Two-Headed Giant game, if a team has fifteen or more poison counters, that team loses the game. See rule 810, “Two-Headed Giant Variant.” + if (getCounters(CounterEnumType.POISON) >= 10 && loseConditionMet(GameLossReason.Poisoned, null)) { + return true; } if (game.getRules().hasAppliedVariant(GameType.Commander)) { for (Entry entry : getCommanderDamage()) { - if (entry.getValue() >= 21) { - return loseConditionMet(GameLossReason.CommanderDamage, null); + if (entry.getValue() >= 21 && loseConditionMet(GameLossReason.CommanderDamage, null)) { + return true; } } } @@ -2755,12 +2738,99 @@ public class Player extends GameEntity implements Comparable { public List getCommanders() { return commanders; } - public void setCommanders(List commanders0) { - if (commanders0 == commanders) { return; } - commanders = commanders0; + public void setCommanders(List commanders) { + boolean needsUpdate = false; + //Remove any existing commanders not in the new list. + for(Card oldCommander : this.commanders) { + if(commanders.contains(oldCommander)) + continue; + needsUpdate = true; + this.commanders.remove(oldCommander); + oldCommander.setCommander(false); + } + if(this.commanderEffect == null && !commanders.isEmpty()) + this.createCommanderEffect(); + //Add any new commanders that aren't in the existing list. + for(Card newCommander : commanders) { + assert(this.equals(newCommander.getOwner())); + if(this.commanders.contains(newCommander)) + continue; + + needsUpdate = true; + this.commanders.add(newCommander); + newCommander.setCommander(true); + } + if(needsUpdate) { + view.updateCommander(this); + } + } + + public void copyCommandersToSnapshot(Player toPlayer, Function mapper) { + //Seems like the rest of the logic for copying players should be in this class too. + //For now, doing this here can retain the links between commander effects and commanders. + + toPlayer.resetCommanderStats(); + toPlayer.commanders.clear(); + for (final Card c : this.getCommanders()) { + Card newCommander = mapper.apply(c); + if(newCommander == null) + throw new RuntimeException("Unable to find commander in game snapshot: " + c); + toPlayer.commanders.add(newCommander); + newCommander.setCommander(true); + } + for (Map.Entry entry : this.commanderCast.entrySet()) { + //Have to iterate over this separately in case commanders change mid-game. + Card commander = mapper.apply(entry.getKey()); + toPlayer.commanderCast.put(commander, entry.getValue()); + } + for (Map.Entry entry : this.getCommanderDamage()) { + Card commander = mapper.apply(entry.getKey()); + if(commander == null) //Ceased to exist? + continue; + int damage = entry.getValue(); + toPlayer.addCommanderDamage(commander, damage); + } + if (this.commanderEffect != null) { + Card commanderEffect = mapper.apply(this.commanderEffect); + toPlayer.commanderEffect = (DetachedCardEffect) commanderEffect; + } + } + + public void addCommander(Card commander) { + assert(this.equals(commander.getOwner())); //Making someone else's card your commander isn't currently supported. + if(this.commanders.contains(commander)) + return; + this.commanders.add(commander); + if(this.commanderEffect == null) + this.createCommanderEffect(); + commander.setCommander(true); view.updateCommander(this); } + public void removeCommander(Card commander) { + if(!this.commanders.remove(commander)) + return; + commander.setCommander(false); + view.updateCommander(this); + } + + /** + * Toggles whether the commander replacement effect is active. + * (i.e. the option to send your commander to the command zone when + * it would otherwise be sent to your library) + *

+ * Used when moving a merged permanent with a commander component. + * Causes the commander replacement to only be applied after the merged + * permanent is split up, rather than causing every component card to be moved. + */ + public void setCommanderReplacementSuppressed(boolean suppress) { + if(this.commanderEffect == null) + return; + for (final ReplacementEffect re : this.commanderEffect.getReplacementEffects()) { + re.setSuppressed(suppress); + } + } + public Iterable> getCommanderDamage() { return commanderDamage.entrySet(); } @@ -2913,7 +2983,6 @@ public class Player extends GameEntity implements Comparable { // Commander if (!registeredPlayer.getCommanders().isEmpty()) { - List commanders = Lists.newArrayList(); for (PaperCard pc : registeredPlayer.getCommanders()) { Card cmd = Card.fromPaperCard(pc, this); boolean color = false; @@ -2937,20 +3006,16 @@ public class Player extends GameEntity implements Comparable { Lang.joinHomogenous(chosenColors)), p); } cmd.setCollectible(true); - cmd.setCommander(true); com.add(cmd); - commanders.add(cmd); - com.add(createCommanderEffect(game, cmd)); + this.addCommander(cmd); } - this.setCommanders(commanders); } else if (registeredPlayer.getPlaneswalker() != null) { // Planeswalker Card cmd = Card.fromPaperCard(registeredPlayer.getPlaneswalker(), this); cmd.setCollectible(true); cmd.setCommander(true); com.add(cmd); - setCommanders(Lists.newArrayList(cmd)); - com.add(createCommanderEffect(game, cmd)); + this.addCommander(cmd); } // Conspiracies @@ -3128,49 +3193,56 @@ public class Player extends GameEntity implements Comparable { return eff; } - public static DetachedCardEffect createCommanderEffect(Game game, Card commander) { - final String name = Lang.getInstance().getPossesive(commander.getName()) + " Commander Effect"; - DetachedCardEffect eff = new DetachedCardEffect(commander, name); + public void createCommanderEffect() { + PlayerZone com = getZone(ZoneType.Command); + if(this.commanderEffect != null) + com.remove(this.commanderEffect); - if (game.getRules().hasAppliedVariant(GameType.Oathbreaker) && commander.getRules().canBeSignatureSpell()) { + DetachedCardEffect eff = new DetachedCardEffect(this, "Commander Effect"); + + String validCommander = "Card.IsCommander+YouOwn"; + if (game.getRules().hasAppliedVariant(GameType.Oathbreaker)) { //signature spells can only reside on the stack or in the command zone String effStr = "DB$ ChangeZone | Origin$ Stack | Destination$ Command | Defined$ ReplacedCard"; - String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Destination$ Graveyard,Exile,Hand,Library | " + + String moved = "Event$ Moved | ValidCard$ Spell.IsCommander+YouOwn | Secondary$ True | Destination$ Graveyard,Exile,Hand,Library | " + "Description$ If a signature spell would be put into another zone from the stack, put it into the command zone instead."; ReplacementEffect re = ReplacementHandler.parseReplacement(moved, eff, true); re.setOverridingAbility(AbilityFactory.getAbility(effStr, eff)); eff.addReplacementEffect(re); + //TODO: Actual recognition for signature spells as their own thing, separate from commanders. + validCommander = "Permanent.IsCommander+YouOwn"; + //signature spells can only be cast if your oathbreaker is in on the battlefield under your control - String castRestriction = "Mode$ CantBeCast | ValidCard$ Card.EffectSource+YouOwn | EffectZone$ Command | IsPresent$ Card.IsCommander+YouOwn+YouCtrl | PresentZone$ Battlefield | PresentCompare$ EQ0 | " + + String castRestriction = "Mode$ CantBeCast | ValidCard$ Spell.IsCommander+YouOwn | EffectZone$ Command | IsPresent$ Permanent.IsCommander+YouOwn+YouCtrl | PresentZone$ Battlefield | PresentCompare$ EQ0 | " + "Description$ Signature spell can only be cast if your oathbreaker is on the battlefield under your control."; eff.addStaticAbility(castRestriction); } - else { - String effStr = "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"; - String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | CommanderMoveReplacement$ True "; - if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) { - moved += " | Destination$ Graveyard,Exile | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead."; - } - else if (game.getRules().hasAppliedVariant(GameType.Oathbreaker)) { - moved += " | Destination$ Graveyard,Exile,Hand,Library | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead."; - } else { - // rule 903.9b - moved += " | Destination$ Hand,Library | Description$ If a commander would be put into its owner's hand or library from anywhere, its owner may put it into the command zone instead."; - } - ReplacementEffect re = ReplacementHandler.parseReplacement(moved, eff, true); - re.setOverridingAbility(AbilityFactory.getAbility(effStr, eff)); - eff.addReplacementEffect(re); + String effStr = "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"; + + String moved = "Event$ Moved | ValidCard$ " + validCommander + " | Secondary$ True | Optional$ True | OptionalDecider$ You | CommanderMoveReplacement$ True "; + if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) { + moved += " | Destination$ Graveyard,Exile | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead."; } + else if (game.getRules().hasAppliedVariant(GameType.Oathbreaker)) { + moved += " | Destination$ Graveyard,Exile,Hand,Library | Description$ If a commander would be exiled or put into hand, graveyard, or library from anywhere, that player may put it into the command zone instead."; + } else { + // rule 903.9b + moved += " | Destination$ Hand,Library | Description$ If a commander would be put into its owner's hand or library from anywhere, its owner may put it into the command zone instead."; + } + ReplacementEffect re = ReplacementHandler.parseReplacement(moved, eff, true); + re.setOverridingAbility(AbilityFactory.getAbility(effStr, eff)); + eff.addReplacementEffect(re); - String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.YouOwn+EffectSource | AffectedZone$ Command"; + String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.IsCommander+YouOwn | AffectedZone$ Command"; if (game.getRules().hasAppliedVariant(GameType.Planeswalker)) { //support paying for Planeswalker with any color mana mayBePlayedAbility += " | MayPlayIgnoreColor$ True"; } eff.addStaticAbility(mayBePlayedAbility); - return eff; + this.commanderEffect = eff; + com.add(eff); } public void createPlanechaseEffects(Game game) { diff --git a/forge-game/src/main/java/forge/game/player/PlayerPredicates.java b/forge-game/src/main/java/forge/game/player/PlayerPredicates.java index 93942877ee9..3bd1fbc3f35 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerPredicates.java +++ b/forge-game/src/main/java/forge/game/player/PlayerPredicates.java @@ -95,5 +95,4 @@ public final class PlayerPredicates { } public static final Predicate NOT_LOST = p -> p.getOutcome() == null || p.getOutcome().hasWon(); - public static final Predicate CANT_WIN = p -> p.hasKeyword("You can't win the game."); } diff --git a/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java b/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java index 5619cd45401..a6157f088c3 100644 --- a/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java +++ b/forge-game/src/main/java/forge/game/player/RegisteredPlayer.java @@ -10,7 +10,6 @@ import forge.item.IPaperCard; import forge.item.PaperCard; import forge.util.Iterables; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -19,10 +18,10 @@ public class RegisteredPlayer { private final Deck originalDeck; // never return or modify this instance (it's a reference to game resources) private Deck currentDeck; - private static final Iterable EmptyList = Collections.unmodifiableList(new ArrayList<>()); - + private static final Iterable EmptyList = Collections.emptyList(); + private LobbyPlayer player = null; - + private int startingLife = 20; private int startingHand = 7; private int manaShards = 0; @@ -40,7 +39,7 @@ public class RegisteredPlayer { private Integer id = null; private boolean randomFoil = false; private boolean enableETBCountersEffect = false; - + public RegisteredPlayer(Deck deck0) { originalDeck = deck0; restoreDeck(); @@ -49,7 +48,6 @@ public class RegisteredPlayer { public final Integer getId() { return id; } - public final void setId(Integer id0) { id = id0; } @@ -57,19 +55,10 @@ public class RegisteredPlayer { public final Deck getDeck() { return currentDeck; } - + public final int getStartingLife() { return startingLife; } - public final Iterable getCardsOnBattlefield() { - return Iterables.concat(cardsOnBattlefield == null ? EmptyList : cardsOnBattlefield, - extraCardsOnBattlefield == null ? EmptyList : extraCardsOnBattlefield); - } - - public final Iterable getExtraCardsInCommandZone() { - return extraCardsInCommandZone == null ? EmptyList : extraCardsInCommandZone; - } - public final void setStartingLife(int startingLife) { this.startingLife = startingLife; } @@ -77,7 +66,6 @@ public class RegisteredPlayer { public final int getManaShards() { return manaShards; } - public final void setManaShards(int manaShards) { this.manaShards = manaShards; } @@ -89,6 +77,15 @@ public class RegisteredPlayer { enableETBCountersEffect = value; } + public final Iterable getCardsOnBattlefield() { + return Iterables.concat(cardsOnBattlefield == null ? EmptyList : cardsOnBattlefield, + extraCardsOnBattlefield == null ? EmptyList : extraCardsOnBattlefield); + } + + public final Iterable getExtraCardsInCommandZone() { + return extraCardsInCommandZone == null ? EmptyList : extraCardsInCommandZone; + } + public final void setCardsOnBattlefield(Iterable cardsOnTable) { this.cardsOnBattlefield = cardsOnTable; } @@ -137,7 +134,6 @@ public class RegisteredPlayer { public int getTeamNumber() { return teamNumber; } - public void setTeamNumber(int teamNumber0) { this.teamNumber = teamNumber0; } @@ -153,7 +149,7 @@ public class RegisteredPlayer { final Set appliedVariants, final Deck deck, //General vars final Iterable schemes, final boolean playerIsArchenemy, //Archenemy specific vars final Iterable planes, final CardPool vanguardAvatar) { //Planechase and Vanguard - + RegisteredPlayer start = new RegisteredPlayer(deck); if (appliedVariants.contains(GameType.Archenemy) && playerIsArchenemy) { start.setStartingLife(40); // 904.5: The Archenemy has 40 life. @@ -192,7 +188,6 @@ public class RegisteredPlayer { public LobbyPlayer getPlayer() { return player; } - public RegisteredPlayer setPlayer(LobbyPlayer player0) { this.player = player0; return this; @@ -219,7 +214,6 @@ public class RegisteredPlayer { setStartingLife(getStartingLife() + avatar.getRules().getLife()); setStartingHand(getStartingHand() + avatar.getRules().getHand()); } - } public PaperCard getPlaneswalker() { diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java index 9b600675aea..9e75465bac5 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceAddCounter.java @@ -109,7 +109,6 @@ public class ReplaceAddCounter extends ReplacementEffect { @Override public boolean modeCheck(ReplacementType event, Map runParams) { - // TODO Auto-generated method stub if (super.modeCheck(event, runParams)) { return true; } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java b/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java index 0b3d35d3e33..2730b0bc920 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGameLoss.java @@ -30,6 +30,10 @@ public class ReplaceGameLoss extends ReplacementEffect { return false; } + if (!matchesValidParam("ValidLoseReason", runParams.get(AbilityKey.LoseReason))) { + return false; + } + return true; } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceGameWin.java b/forge-game/src/main/java/forge/game/replacement/ReplaceGameWin.java new file mode 100644 index 00000000000..5fb5b10d5cf --- /dev/null +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceGameWin.java @@ -0,0 +1,26 @@ +package forge.game.replacement; + +import java.util.Map; + +import forge.game.ability.AbilityKey; +import forge.game.card.Card; + +public class ReplaceGameWin extends ReplacementEffect { + + public ReplaceGameWin(Map map, Card host, boolean intrinsic) { + super(map, host, intrinsic); + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.HashMap) + */ + @Override + public boolean canReplace(Map runParams) { + if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) { + return false; + } + + return true; + } + +} diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java b/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java deleted file mode 100644 index 7f804f91c84..00000000000 --- a/forge-game/src/main/java/forge/game/replacement/ReplaceSurveil.java +++ /dev/null @@ -1,49 +0,0 @@ -package forge.game.replacement; - -import java.util.Map; - -import forge.game.ability.AbilityKey; -import forge.game.card.Card; -import forge.game.spellability.SpellAbility; - -/** - * TODO: Write javadoc for this type. - * - */ -public class ReplaceSurveil extends ReplacementEffect { - - /** - * - * ReplaceProduceMana. - * @param mapParams   HashMap - * @param host   Card - */ - public ReplaceSurveil(final Map mapParams, final Card host, final boolean intrinsic) { - super(mapParams, host, intrinsic); - } - - /* (non-Javadoc) - * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map) - */ - @Override - public boolean canReplace(Map runParams) { - if (((int) runParams.get(AbilityKey.SurveilNum)) <= 0) { - return false; - } - if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Affected))) { - return false; - } - - return true; - } - - /* (non-Javadoc) - * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility) - */ - @Override - public void setReplacingObjects(Map runParams, SpellAbility sa) { - sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); - sa.setReplacingObject(AbilityKey.SurveilNum, runParams.get(AbilityKey.SurveilNum)); - } - -} diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java index bb74c9c2871..1836337d45a 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementEffect.java @@ -23,6 +23,7 @@ import java.util.Objects; import com.google.common.collect.*; +import forge.util.ITranslatable; import org.apache.commons.lang3.StringUtils; import forge.game.Game; @@ -221,15 +222,11 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { public String getDescription() { if (hasParam("Description") && !this.isSuppressed()) { String desc = AbilityUtils.applyDescriptionTextChangeEffects(getParam("Description"), this); - String currentName; - if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) { - currentName = cardState.getName(); - } else { - currentName = getHostCard().getName(); - } - desc = CardTranslation.translateSingleDescriptionText(desc, currentName); - desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName)); - desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); + ITranslatable nameSource = getHostName(this); + desc = CardTranslation.translateMultipleDescriptionText(desc, nameSource); + String translatedName = CardTranslation.getTranslatedName(nameSource); + desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName); + desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(translatedName)); if (desc.contains("EFFECTSOURCE")) { desc = TextUtil.fastReplace(desc, "EFFECTSOURCE", getHostCard().getEffectSource().toString()); } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index e7dde774508..7aad71a4e05 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -19,6 +19,7 @@ package forge.game.replacement; import java.util.*; +import com.google.common.base.MoreObjects; import forge.game.card.*; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -143,7 +144,7 @@ public class ReplacementHandler { return true; } - }); + }, affectedCard != null && affectedCard.isInZone(ZoneType.Sideboard)); if (checkAgain) { if (affectedLKI != null && affectedCard != null) { @@ -168,6 +169,10 @@ public class ReplacementHandler { return possibleReplacers; } + public boolean cantHappenCheck(final ReplacementType event, final Map runParams) { + return !getReplacementList(event, runParams, ReplacementLayer.CantHappen).isEmpty(); + } + /** * * Runs any applicable replacement effects. @@ -322,7 +327,7 @@ public class ReplacementHandler { replacementEffect.getParam("OptionalDecider"), effectSA).get(0); } - String name = CardTranslation.getTranslatedName(host.getCardForUi().getName()); + String name = CardTranslation.getTranslatedName(MoreObjects.firstNonNull(host.getCardForUi(), host).getName()); String effectDesc = TextUtil.fastReplace(replacementEffect.getDescription(), "CARDNAME", name); final String question = runParams.containsKey(AbilityKey.Card) ? Localizer.getInstance().getMessage("lblApplyCardReplacementEffectToCardConfirm", name, runParams.get(AbilityKey.Card).toString(), effectDesc) diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java index 537b118693c..6e82f21b81d 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java @@ -28,6 +28,7 @@ public enum ReplacementType { Explore(ReplaceExplore.class), GainLife(ReplaceGainLife.class), GameLoss(ReplaceGameLoss.class), + GameWin(ReplaceGameWin.class), Learn(ReplaceLearn.class), LifeReduced(ReplaceLifeReduced.class), LoseMana(ReplaceLoseMana.class), @@ -43,7 +44,6 @@ public enum ReplacementType { RollPlanarDice(ReplaceRollPlanarDice.class), Scry(ReplaceScry.class), SetInMotion(ReplaceSetInMotion.class), - Surveil(ReplaceSurveil.class), Tap(ReplaceTap.class), Transform(ReplaceTransform.class), TurnFaceUp(ReplaceTurnFaceUp.class), diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index 647e9a0ee35..8fd49d86057 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -409,14 +409,6 @@ public class AbilityManaPart implements java.io.Serializable { continue; } - if (restriction.equals("FaceDownOrTurnFaceUp")) { - if ((sa.isSpell() && sa.getHostCard().isCreature() && sa.isCastFaceDown()) - || sa.isTurnFaceUp()) { - return true; - } - continue; - } - if (restriction.equals("MorphOrManifest")) { if ((sa.isSpell() && sa.getHostCard().isCreature() && sa.isCastFaceDown()) || sa.isManifestUp() || sa.isMorphUp()) { diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityStatic.java b/forge-game/src/main/java/forge/game/spellability/AbilityStatic.java index 16d94d6350a..ed43e2e7611 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityStatic.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityStatic.java @@ -21,11 +21,8 @@ import forge.card.mana.ManaCost; import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.cost.Cost; -import forge.game.replacement.ReplacementEffect; -import forge.game.replacement.ReplacementLayer; import forge.game.replacement.ReplacementType; -import java.util.List; import java.util.Map; /** @@ -63,9 +60,7 @@ public abstract class AbilityStatic extends Ability implements Cloneable { // Initial usage is Karlov Watchdog preventing disguise/morph/cloak/manifest turning face up if (this.isTurnFaceUp()) { Map repParams = AbilityKey.mapFromAffected(c); - List list = c.getGame().getReplacementHandler().getReplacementList - (ReplacementType.TurnFaceUp, repParams, ReplacementLayer.CantHappen); - if (!list.isEmpty()) return false; + if (c.getGame().getReplacementHandler().cantHappenCheck(ReplacementType.TurnFaceUp, repParams)) return false; } return this.getRestrictions().canPlay(c, this); diff --git a/forge-game/src/main/java/forge/game/spellability/AbilitySub.java b/forge-game/src/main/java/forge/game/spellability/AbilitySub.java index b8c6168a171..8784541995d 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilitySub.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilitySub.java @@ -19,7 +19,6 @@ package forge.game.spellability; import java.util.Map; -import forge.card.CardStateName; import forge.game.IHasSVars; import forge.game.ability.AbilityFactory; import forge.game.ability.ApiType; @@ -107,7 +106,8 @@ public final class AbilitySub extends SpellAbility implements java.io.Serializab @Override protected IHasSVars getSVarFallback() { - if (getCardState() != null && getCardStateName().equals(CardStateName.RightSplit)) { + // fused or spliced + if (getRootAbility().getCardState() != getCardState()) { return getCardState(); } return super.getSVarFallback(); diff --git a/forge-game/src/main/java/forge/game/spellability/Spell.java b/forge-game/src/main/java/forge/game/spellability/Spell.java index c3cfcce3e9d..13a379afaa5 100644 --- a/forge-game/src/main/java/forge/game/spellability/Spell.java +++ b/forge-game/src/main/java/forge/game/spellability/Spell.java @@ -17,7 +17,6 @@ */ package forge.game.spellability; -import java.util.List; import java.util.Map; import forge.game.card.CardCopyService; @@ -32,8 +31,6 @@ import forge.game.card.CardFactory; import forge.game.cost.Cost; import forge.game.cost.CostPayment; import forge.game.player.Player; -import forge.game.replacement.ReplacementEffect; -import forge.game.replacement.ReplacementLayer; import forge.game.replacement.ReplacementType; import forge.game.staticability.StaticAbilityCantBeCast; import forge.game.zone.ZoneType; @@ -216,7 +213,6 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable final Map repParams = AbilityKey.mapFromAffected(getHostCard()); repParams.put(AbilityKey.SpellAbility, this); repParams.put(AbilityKey.Cause, sa); - List list = getHostCard().getGame().getReplacementHandler().getReplacementList(ReplacementType.Counter, repParams, ReplacementLayer.CantHappen); - return list.isEmpty(); + return !getHostCard().getGame().getReplacementHandler().cantHappenCheck(ReplacementType.Counter, repParams); } } 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 a9d7c3c1a7a..3d2474931ef 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -552,6 +552,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return hasParam("CloakUp"); } + public boolean isUnlock() { + return hasParam("Unlock"); + } + public boolean isCycling() { return isKeyword(Keyword.CYCLING) || isKeyword(Keyword.TYPECYCLING); } @@ -706,7 +710,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit mana.getSourceCard().getController(), mana.getSourceCard(), null)) { final long timestamp = host.getGame().getNextTimestamp(); final List kws = Arrays.asList(mana.getAddedKeywords().split(" & ")); - host.addChangedCardKeywords(kws, null, false, timestamp, 0); + host.addChangedCardKeywords(kws, null, false, timestamp, null); if (mana.addsKeywordsUntil()) { final GameCommand untilEOT = new GameCommand() { private static final long serialVersionUID = -8285169579025607693L; @@ -989,16 +993,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } String desc = node.getDescription(); if (node.getHostCard() != null) { - String currentName; - // if alternate state is viewed while card uses original - if (node.isIntrinsic() && node.cardState != null && node.cardState.getCard() == node.getHostCard()) { - currentName = node.cardState.getName(); - } else { - currentName = node.getHostCard().getName(); - } - desc = CardTranslation.translateMultipleDescriptionText(desc, currentName); - desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName)); - desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); + ITranslatable nameSource = getHostName(node); + desc = CardTranslation.translateMultipleDescriptionText(desc, nameSource); + String translatedName = CardTranslation.getTranslatedName(nameSource); + desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName); + desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(translatedName)); if (node.getOriginalHost() != null) { desc = TextUtil.fastReplace(desc, "ORIGINALHOST", node.getOriginalHost().getName()); } @@ -2596,7 +2595,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public boolean hasOptionalKeywordAmount(KeywordInterface kw) { - return this.optionalKeywordAmount.contains(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId())); + long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId(); + return this.optionalKeywordAmount.contains(kw.getKeyword(), Pair.of(kw.getIdx(), staticId)); } public boolean hasOptionalKeywordAmount(Keyword kw) { return this.optionalKeywordAmount.containsRow(kw); @@ -2606,13 +2606,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } public int getOptionalKeywordAmount(KeywordInterface kw) { - return ObjectUtils.firstNonNull(this.optionalKeywordAmount.get(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId())), 0); + long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId(); + return ObjectUtils.firstNonNull(this.optionalKeywordAmount.get(kw.getKeyword(), Pair.of(kw.getIdx(), staticId)), 0); } public int getOptionalKeywordAmount(Keyword kw) { return this.optionalKeywordAmount.row(kw).values().stream().mapToInt(i->i).sum(); } public void setOptionalKeywordAmount(KeywordInterface kw, int amount) { - this.optionalKeywordAmount.put(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId()), amount); + long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId(); + this.optionalKeywordAmount.put(kw.getKeyword(), Pair.of(kw.getIdx(), staticId), amount); } public void clearOptionalKeywordAmount() { optionalKeywordAmount.clear(); diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java index 9474eae2bbc..327296f0d9c 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -45,11 +45,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.Zone; import forge.game.zone.ZoneType; -import forge.util.CardTranslation; -import forge.util.Expressions; -import forge.util.FileSection; -import forge.util.Lang; -import forge.util.TextUtil; +import forge.util.*; /** * The Class StaticAbility. @@ -187,15 +183,11 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone @Override public final String toString() { if (hasParam("Description") && !this.isSuppressed()) { - String currentName; - if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) { - currentName = cardState.getName(); - } else { - currentName = getHostCard().getName(); - } - String desc = CardTranslation.translateSingleDescriptionText(getParam("Description"), currentName); - desc = TextUtil.fastReplace(desc, "CARDNAME", CardTranslation.getTranslatedName(currentName)); - desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); + ITranslatable nameSource = getHostName(this); + String desc = CardTranslation.translateSingleDescriptionText(getParam("Description"), nameSource); + String translatedName = CardTranslation.getTranslatedName(nameSource); + desc = TextUtil.fastReplace(desc, "CARDNAME", translatedName); + desc = TextUtil.fastReplace(desc, "NICKNAME", Lang.getInstance().getNickName(translatedName)); return desc; } else { diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityAssignNoCombatDamage.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityAssignNoCombatDamage.java new file mode 100644 index 00000000000..3302897af98 --- /dev/null +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityAssignNoCombatDamage.java @@ -0,0 +1,34 @@ +package forge.game.staticability; + +import forge.game.card.Card; +import forge.game.card.CardCollection; +import forge.game.zone.ZoneType; + +public class StaticAbilityAssignNoCombatDamage { + + static String MODE = "AssignNoCombatDamage"; + + public static boolean assignNoCombatDamage(final Card card) { + CardCollection list = new CardCollection(card.getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)); + list.add(card); + for (final Card ca : list) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.checkConditions(MODE)) { + continue; + } + if (applyAssignNoCombatDamage(stAb, card)) { + return true; + } + } + } + return false; + } + + public static boolean applyAssignNoCombatDamage(final StaticAbility stAb, final Card card) { + if (!stAb.matchesValidParam("ValidCard", card)) { + return false; + } + return true; + } + +} diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityColorlessDamageSource.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityColorlessDamageSource.java new file mode 100644 index 00000000000..4e8fbc6777c --- /dev/null +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityColorlessDamageSource.java @@ -0,0 +1,32 @@ +package forge.game.staticability; + +import forge.game.card.Card; +import forge.game.card.CardState; +import forge.game.zone.ZoneType; + +public class StaticAbilityColorlessDamageSource { + + static String MODE = "ColorlessDamageSource"; + + public static boolean colorlessDamageSource(final CardState state) { + final Card card = state.getCard(); + for (final Card ca : card.getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.checkConditions(MODE)) { + continue; + } + if (applyColorlessDamageSource(stAb, card)) { + return true; + } + } + } + return false; + } + + public static boolean applyColorlessDamageSource(final StaticAbility stAb, final Card card) { + if (!stAb.matchesValidParam("ValidCard", card)) { + return false; + } + return true; + } +} diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 1df3d92dd1a..50c9454f2d0 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -22,6 +22,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import forge.GameCommand; import forge.card.*; +import forge.card.mana.ManaCost; import forge.game.Game; import forge.game.StaticEffect; import forge.game.StaticEffects; @@ -31,6 +32,7 @@ import forge.game.card.*; import forge.game.cost.Cost; import forge.game.keyword.Keyword; import forge.game.keyword.KeywordInterface; +import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; import forge.game.player.PlayerCollection; import forge.game.replacement.ReplacementEffect; @@ -423,26 +425,30 @@ public final class StaticAbilityContinuous { if (params.containsKey("AddAllCreatureTypes")) { addAllCreatureTypes = true; } - if (params.containsKey("RemoveSuperTypes")) { - remove.add(RemoveType.SuperTypes); - } - if (params.containsKey("RemoveCardTypes")) { - remove.add(RemoveType.CardTypes); - } - if (params.containsKey("RemoveSubTypes")) { - remove.add(RemoveType.SubTypes); - } - if (params.containsKey("RemoveLandTypes")) { - remove.add(RemoveType.LandTypes); - } - if (params.containsKey("RemoveCreatureTypes")) { - remove.add(RemoveType.CreatureTypes); - } - if (params.containsKey("RemoveArtifactTypes")) { - remove.add(RemoveType.ArtifactTypes); - } - if (params.containsKey("RemoveEnchantmentTypes")) { - remove.add(RemoveType.EnchantmentTypes); + + // overwrite doesn't work without new value (e.g. Conspiracy missing choice) + if (addTypes == null || !addTypes.isEmpty()) { + if (params.containsKey("RemoveSuperTypes")) { + remove.add(RemoveType.SuperTypes); + } + if (params.containsKey("RemoveCardTypes")) { + remove.add(RemoveType.CardTypes); + } + if (params.containsKey("RemoveSubTypes")) { + remove.add(RemoveType.SubTypes); + } + if (params.containsKey("RemoveLandTypes")) { + remove.add(RemoveType.LandTypes); + } + if (params.containsKey("RemoveCreatureTypes")) { + remove.add(RemoveType.CreatureTypes); + } + if (params.containsKey("RemoveArtifactTypes")) { + remove.add(RemoveType.ArtifactTypes); + } + if (params.containsKey("RemoveEnchantmentTypes")) { + remove.add(RemoveType.EnchantmentTypes); + } } } @@ -511,7 +517,7 @@ public final class StaticAbilityContinuous { // modify players for (final Player p : affectedPlayers) { // add keywords - if (addKeywords != null) { + if (addKeywords != null && !addKeywords.isEmpty()) { p.addChangedKeywords(addKeywords, removeKeywords, se.getTimestamp(), stAb.getId()); } @@ -719,7 +725,7 @@ public final class StaticAbilityContinuous { } // add keywords - if (addKeywords != null || removeKeywords != null || removeAllAbilities) { + if ((addKeywords != null && !addKeywords.isEmpty()) || removeKeywords != null || removeAllAbilities) { List newKeywords = null; if (addKeywords != null) { newKeywords = Lists.newArrayList(addKeywords); @@ -742,8 +748,20 @@ public final class StaticAbilityContinuous { newKeywords.addAll(extraKeywords); newKeywords = newKeywords.stream().map(input -> { + int reduced = 0; + if (stAb.hasParam("ReduceCost")) { + reduced = AbilityUtils.calculateAmount(hostCard, stAb.getParam("ReduceCost"), stAb); + } if (input.contains("CardManaCost")) { - input = input.replace("CardManaCost", affectedCard.getManaCost().getShortString()); + ManaCost cost; + if (reduced > 0) { + ManaCostBeingPaid mcbp = new ManaCostBeingPaid(affectedCard.getManaCost()); + mcbp.decreaseGenericMana(reduced); + cost = mcbp.toManaCost(); + } else { + cost = affectedCard.getManaCost(); + } + input = input.replace("CardManaCost", cost.getShortString()); } else if (input.contains("ConvertedManaCost")) { final String costcmc = Integer.toString(affectedCard.getCMC()); input = input.replace("ConvertedManaCost", costcmc); @@ -753,7 +771,7 @@ public final class StaticAbilityContinuous { } affectedCard.addChangedCardKeywords(newKeywords, removeKeywords, - removeAllAbilities, se.getTimestamp(), stAb.getId(), true); + removeAllAbilities, se.getTimestamp(), stAb, true); } // add HIDDEN keywords @@ -877,7 +895,7 @@ public final class StaticAbilityContinuous { } // add Types - if (addTypes != null || removeTypes != null || addAllCreatureTypes || !remove.isEmpty()) { + if ((addTypes != null && !addTypes.isEmpty()) || (removeTypes != null && !removeTypes.isEmpty()) || addAllCreatureTypes || !remove.isEmpty()) { affectedCard.addChangedCardTypes(addTypes, removeTypes, addAllCreatureTypes, remove, se.getTimestamp(), stAb.getId(), true, stAb.hasParam("CharacteristicDefining")); } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCrewValue.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCrewValue.java index b810b8391b5..1ffd68eefa6 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCrewValue.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCrewValue.java @@ -8,25 +8,6 @@ public class StaticAbilityCrewValue { static String MODE = "CrewValue"; - public static boolean hasAnyCrewValue(final Card card) { - final Game game = card.getGame(); - for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { - for (final StaticAbility stAb : ca.getStaticAbilities()) { - if (!stAb.checkConditions(MODE)) { - continue; - } - if (hasAnyCrewValue(stAb, card)) { - return true; - } - } - } - return false; - } - - public static boolean hasAnyCrewValue(final StaticAbility stAb, final Card card) { - return stAb.matchesValidParam("ValidCard", card); - } - public static boolean crewsWithToughness(final Card card) { final Game game = card.getGame(); for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java index dd292c40bab..7b8ef7c8cb4 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java @@ -60,6 +60,10 @@ public class StaticAbilityPanharmonicon { continue; } // it can't trigger more times than the limit allows + if (t.hasParam("GameActivationLimit") && + t.getActivationsThisGame() + n + 1 >= Integer.parseInt(t.getParam("GameActivationLimit"))) { + break; + } if (t.hasParam("ActivationLimit") && t.getActivationsThisTurn() + n + 1 >= Integer.parseInt(t.getParam("ActivationLimit"))) { break; diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilitySurveilNum.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilitySurveilNum.java new file mode 100644 index 00000000000..a39c9391d3a --- /dev/null +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilitySurveilNum.java @@ -0,0 +1,36 @@ +package forge.game.staticability; + +import forge.game.Game; +import forge.game.card.Card; +import forge.game.player.Player; +import forge.game.zone.ZoneType; + +public class StaticAbilitySurveilNum { + + static String MODE = "SurveilNum"; + + public static int surveilNumMod(Player p) { + final Game game = p.getGame(); + int mod = 0; + for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.checkConditions(MODE)) { + continue; + } + mod += getSurveilMod(stAb, p); + } + } + return mod; + } + + public static int getSurveilMod(final StaticAbility stAb, final Player p) { + if (!stAb.matchesValidParam("ValidPlayer", p)) { + return 0; + } + if (stAb.hasParam("Optional") && !p.getController().confirmStaticApplication(stAb.getHostCard(), null, stAb.toString() + "?", null)) { + return 0; + } + return Integer.parseInt(stAb.getParam("Num")); + } + +} diff --git a/forge-game/src/main/java/forge/game/trigger/Trigger.java b/forge-game/src/main/java/forge/game/trigger/Trigger.java index ee02e814adc..cd57524b07a 100644 --- a/forge-game/src/main/java/forge/game/trigger/Trigger.java +++ b/forge-game/src/main/java/forge/game/trigger/Trigger.java @@ -35,6 +35,7 @@ import forge.game.spellability.SpellAbility; import forge.game.zone.CostPaymentStack; import forge.game.zone.ZoneType; import forge.util.CardTranslation; +import forge.util.ITranslatable; import forge.util.Iterables; import forge.util.Lang; import forge.util.TextUtil; @@ -119,17 +120,13 @@ public abstract class Trigger extends TriggerReplacementBase { public String toString(boolean active) { if (hasParam("TriggerDescription") && !this.isSuppressed()) { StringBuilder sb = new StringBuilder(); - String currentName; - if (this.isIntrinsic() && cardState != null && cardState.getCard() == getHostCard()) { - currentName = cardState.getName(); - } else { - currentName = getHostCard().getName(); - } + ITranslatable nameSource = getHostName(this); String desc = getParam("TriggerDescription"); if (!desc.contains("ABILITY")) { - desc = CardTranslation.translateSingleDescriptionText(getParam("TriggerDescription"), currentName); - desc = TextUtil.fastReplace(desc,"CARDNAME", CardTranslation.getTranslatedName(currentName)); - desc = TextUtil.fastReplace(desc,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); + desc = CardTranslation.translateSingleDescriptionText(getParam("TriggerDescription"), nameSource); + String translatedName = CardTranslation.getTranslatedName(nameSource); + desc = TextUtil.fastReplace(desc,"CARDNAME", translatedName); + desc = TextUtil.fastReplace(desc,"NICKNAME", Lang.getInstance().getNickName(translatedName)); if (desc.contains("ORIGINALHOST") && this.getOriginalHost() != null) { desc = TextUtil.fastReplace(desc, "ORIGINALHOST", this.getOriginalHost().getName()); } @@ -220,10 +217,10 @@ public abstract class Trigger extends TriggerReplacementBase { } result = TextUtil.fastReplace(result, "ABILITY", saDesc); - String currentName = sa.getHostCard().getName(); - result = CardTranslation.translateMultipleDescriptionText(result, currentName); - result = TextUtil.fastReplace(result,"CARDNAME", CardTranslation.getTranslatedName(currentName)); - result = TextUtil.fastReplace(result,"NICKNAME", Lang.getInstance().getNickName(CardTranslation.getTranslatedName(currentName))); + result = CardTranslation.translateMultipleDescriptionText(result, sa.getHostCard()); + String translatedName = CardTranslation.getTranslatedName(sa.getHostCard()); + result = TextUtil.fastReplace(result,"CARDNAME", translatedName); + result = TextUtil.fastReplace(result,"NICKNAME", Lang.getInstance().getNickName(translatedName)); } return result; diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerFullyUnlock.java b/forge-game/src/main/java/forge/game/trigger/TriggerFullyUnlock.java new file mode 100644 index 00000000000..c81b2846b66 --- /dev/null +++ b/forge-game/src/main/java/forge/game/trigger/TriggerFullyUnlock.java @@ -0,0 +1,41 @@ +package forge.game.trigger; + +import java.util.Map; + +import forge.game.ability.AbilityKey; +import forge.game.card.Card; +import forge.game.spellability.SpellAbility; +import forge.util.Localizer; + +public class TriggerFullyUnlock extends Trigger { + + public TriggerFullyUnlock(final Map params, final Card host, final boolean intrinsic) { + super(params, host, intrinsic); + } + + @Override + public boolean performTest(Map runParams) { + if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) { + return false; + } + + if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) { + return false; + } + return true; + } + + @Override + public void setTriggeringObjects(SpellAbility sa, Map runParams) { + sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card, AbilityKey.Player); + } + + @Override + public String getImportantStackObjects(SpellAbility sa) { + StringBuilder sb = new StringBuilder(); + sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": ").append(sa.getTriggeringObject(AbilityKey.Player)); + sb.append(", ").append(Localizer.getInstance().getMessage("lblCard")).append(": ").append(sa.getTriggeringObject(AbilityKey.Card)); + return sb.toString(); + } + +} diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java b/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java index 6860d5ac06a..f56f6ca2a87 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerTurnFaceUp.java @@ -57,6 +57,9 @@ public class TriggerTurnFaceUp extends Trigger { if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) { return false; } + if (!matchesValidParam("ValidCause", runParams.get(AbilityKey.Cause))) { + return false; + } return true; } 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 f7e2c5a17dc..f97dd52fef8 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerType.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerType.java @@ -85,6 +85,7 @@ public enum TriggerType { FlippedCoin(TriggerFlippedCoin.class), Forage(TriggerForage.class), Foretell(TriggerForetell.class), + FullyUnlock(TriggerFullyUnlock.class), GiveGift(TriggerGiveGift.class), Immediate(TriggerImmediate.class), Investigated(TriggerInvestigated.class), diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index ab1e6b65bed..971491b9725 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -548,7 +548,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable itemManager0, Collection sets0, Collection limitedSets0, boolean allowReprints0) { this(itemManager0, sets0, allowReprints0); - this.limitedSets.addAll(limitedSets0); + if (limitedSets0 != null) { + this.limitedSets.addAll(limitedSets0); + } } @Override diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FCardImageRenderer.java b/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FCardImageRenderer.java index 32f9e7c2821..5186889f9dc 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FCardImageRenderer.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FCardImageRenderer.java @@ -203,9 +203,9 @@ public class FCardImageRenderer { if (card.isSplitCard()) { boolean needTranslation = !"en-US".equals(FModel.getPreferences().getPref(FPref.UI_LANGUAGE)); final CardStateView leftState = card.getLeftSplitState(); - final String leftText = needTranslation ? CardTranslation.getTranslatedOracle(leftState.getName()) : leftState.getOracleText(); + final String leftText = needTranslation ? CardTranslation.getTranslatedOracle(leftState) : leftState.getOracleText(); final CardStateView rightState = card.getRightSplitState(); - String rightText = needTranslation ? CardTranslation.getTranslatedOracle(rightState.getName()) : rightState.getOracleText(); + String rightText = needTranslation ? CardTranslation.getTranslatedOracle(rightState) : rightState.getOracleText(); boolean isAftermath = (rightState.getKeywordKey().contains("Aftermath")); BufferedImage leftArt = null; BufferedImage rightArt = null; @@ -247,9 +247,9 @@ public class FCardImageRenderer { } else if (card.isFlipCard()) { boolean needTranslation = !card.isToken() || !(card.getCloneOrigin() == null); final CardStateView state = card.getState(false); - final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null); + final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null); final CardStateView flipState = card.getState(true); - final String flipText = card.getText(flipState, needTranslation ? CardTranslation.getTranslationTexts(flipState.getName(), "") : null); + final String flipText = card.getText(flipState, needTranslation ? CardTranslation.getTranslationTexts(flipState) : null); CARD_ART_RATIO = 1.728f; updateAreaSizes(ratio, ratio); int heightAdjust = OUTER_BORDER_THICKNESS + PT_SIZE / 2; @@ -261,16 +261,16 @@ public class FCardImageRenderer { } else if (card.isAdventureCard()) { boolean needTranslation = !card.isToken() || !(card.getCloneOrigin() == null); final CardStateView state = card.getState(false); - final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null); + final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null); final CardStateView advState = card.getState(true); - final String advText = card.getText(advState, needTranslation ? CardTranslation.getTranslationTexts(advState.getName(), "") : null); + final String advText = card.getText(advState, needTranslation ? CardTranslation.getTranslationTexts(advState) : null); CARD_ART_RATIO = 1.37f; updateAreaSizes(ratio, ratio); drawAdvCardImage(g, state, text, advState, advText, width, height, art); } else { boolean needTranslation = !card.isToken() || !(card.getCloneOrigin() == null); final CardStateView state = card.getState(altState); - final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null); + final String text = card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null); CARD_ART_RATIO = 1.37f; if (art != null && Math.abs((float)art.getWidth() / (float)art.getHeight() - CARD_ART_RATIO) > 0.1f) { CARD_ART_RATIO = (float)art.getWidth() / (float)art.getHeight(); diff --git a/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java b/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java index 50196e0c069..e5883ab5c63 100644 --- a/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java +++ b/forge-gui-desktop/src/test/java/forge/deck/DeckRecognizerTest.java @@ -1268,7 +1268,7 @@ public class DeckRecognizerTest extends CardMockTestCase { tokenCard = cardToken.getCard(); assertEquals(cardToken.getQuantity(), 2); assertEquals(tokenCard.getName(), "Counterspell"); - assertEquals(tokenCard.getEdition(), "MB2"); + assertEquals(tokenCard.getEdition(), "DSC"); assertTrue(cardToken.cardRequestHasNoCode()); } @@ -1593,7 +1593,7 @@ public class DeckRecognizerTest extends CardMockTestCase { //assertEquals(cardToken.getTokenSection(), DeckSection.Main); //fix test since signature spell is allowed on commander section PaperCard tc = cardToken.getCard(); assertEquals(tc.getName(), "Counterspell"); - assertEquals(tc.getEdition(), "MB2"); + assertEquals(tc.getEdition(), "DSC"); assertTrue(cardToken.cardRequestHasNoCode()); // Setting Original Core diff --git a/forge-gui-mobile-dev/fallback_skin/title_bg_lq.png b/forge-gui-mobile-dev/fallback_skin/title_bg_lq.png index 22183d1f0b3..b449094c336 100644 Binary files a/forge-gui-mobile-dev/fallback_skin/title_bg_lq.png and b/forge-gui-mobile-dev/fallback_skin/title_bg_lq.png differ diff --git a/forge-gui-mobile-dev/fallback_skin/title_bg_lq_portrait.png b/forge-gui-mobile-dev/fallback_skin/title_bg_lq_portrait.png index 08809b42adf..5f124048671 100644 Binary files a/forge-gui-mobile-dev/fallback_skin/title_bg_lq_portrait.png and b/forge-gui-mobile-dev/fallback_skin/title_bg_lq_portrait.png differ diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 9404683db2c..dae2e3edef2 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -63,7 +63,7 @@ public class Forge implements ApplicationListener { static Batch animationBatch; static TextureRegion lastScreenTexture; private static boolean sceneWasSwapped = false; - public static boolean restrictAdvMenus = false; + public static boolean advFreezePlayerControls = false; private static Clipboard clipboard; private static IDeviceAdapter deviceAdapter; private static int screenWidth; diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index 1b0ef7f1e70..c391bd3561f 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -153,7 +153,7 @@ public class GuiMobile implements IGuiBase { @Override public void showImageDialog(final ISkinImage image, final String message, final String title) { if (Forge.isMobileAdventureMode) { - FThreads.invokeInEdtNowOrLater(() -> MapStage.getInstance().showImageDialog("Achievement Earned\n"+message, (FBufferedImage)image)); + FThreads.invokeInEdtNowOrLater(() -> MapStage.getInstance().showImageDialog("Achievement Earned\n"+message, (FBufferedImage)image, null)); return; } new WaitCallback() { diff --git a/forge-gui-mobile/src/forge/adventure/character/EntryActor.java b/forge-gui-mobile/src/forge/adventure/character/EntryActor.java index e0ab361151a..94d30e9de2f 100644 --- a/forge-gui-mobile/src/forge/adventure/character/EntryActor.java +++ b/forge-gui-mobile/src/forge/adventure/character/EntryActor.java @@ -43,7 +43,7 @@ public class EntryActor extends MapActor{ { if(targetMap==null||targetMap.isEmpty()) { - stage.exitDungeon(); + stage.exitDungeon(false); } else { diff --git a/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java b/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java index 7cce26ab98b..841a6a0807e 100644 --- a/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/PlayerSprite.java @@ -1,6 +1,7 @@ package forge.adventure.character; import com.badlogic.gdx.math.Vector2; +import forge.Forge; import forge.adventure.player.AdventurePlayer; import forge.adventure.scene.Scene; import forge.adventure.stage.GameStage; @@ -58,6 +59,8 @@ public class PlayerSprite extends CharacterSprite { @Override public void act(float delta) { super.act(delta); + if (Forge.advFreezePlayerControls) + return; direction.setLength(playerSpeed * delta * playerSpeedModifier*playerSpeedEquipmentModifier); Vector2 previousDirection = getMovementDirection().cpy(); Scene previousScene = forge.Forge.getCurrentScene(); diff --git a/forge-gui-mobile/src/forge/adventure/character/PortalActor.java b/forge-gui-mobile/src/forge/adventure/character/PortalActor.java index cdcce79539c..b3ad332b674 100644 --- a/forge-gui-mobile/src/forge/adventure/character/PortalActor.java +++ b/forge-gui-mobile/src/forge/adventure/character/PortalActor.java @@ -39,7 +39,7 @@ public class PortalActor extends EntryActor { } if (currentAnimationType == PortalAnimationTypes.Active) { if (targetMap == null || targetMap.isEmpty()) { - stage.exitDungeon(); + stage.exitDungeon(false); } else { if (targetMap.equals(currentMap)) { stage.spawn(entryTargetObject); diff --git a/forge-gui-mobile/src/forge/adventure/data/ItemData.java b/forge-gui-mobile/src/forge/adventure/data/ItemData.java index 2505f4cdb00..aaff00409cf 100644 --- a/forge-gui-mobile/src/forge/adventure/data/ItemData.java +++ b/forge-gui-mobile/src/forge/adventure/data/ItemData.java @@ -23,6 +23,7 @@ public class ItemData { public boolean usableOnWorldMap; public boolean usableInPoi; + public boolean isCracked; public String commandOnUse; public int shardsNeeded; public DialogData dialogOnUse; diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index 6f0f774ffc0..a1a5b56e3ef 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -12,7 +12,6 @@ import forge.adventure.data.*; import forge.adventure.pointofintrest.PointOfInterestChanges; import forge.adventure.scene.AdventureDeckEditor; import forge.adventure.scene.DeckEditScene; -import forge.adventure.stage.GameHUD; import forge.adventure.stage.GameStage; import forge.adventure.stage.MapStage; import forge.adventure.stage.WorldStage; @@ -614,16 +613,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent { String count = itemCount == null ? "" : String.valueOf(itemCount); TextraLabel actor = Controls.newTextraLabel("[%95]" + icon + "[WHITE]" + symbol + count + " " + message); actor.setPosition(x, y); - actor.addAction(Actions.after( - Actions.sequence( - Actions.parallel( - Actions.moveBy(0f, 5f, 4f), - Actions.fadeIn(2f) - ), - Actions.fadeOut(3f), - Actions.removeActor() - ))); - GameHUD.getInstance().addActor(actor); + actor.addAction(Actions.sequence( + Actions.parallel(Actions.moveBy(0f, 5f, 3f), Actions.fadeIn(2f)), + Actions.hide(), + Actions.removeActor()) + ); + getCurrentGameStage().addActor(actor); } public void addCard(PaperCard card) { cards.add(card); @@ -635,11 +630,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent { case Card: cards.add(reward.getCard()); newCards.add(reward.getCard()); - if (reward.isNoSell()) { + if (reward.isAutoSell()) { + autoSellCards.add(reward.getCard()); + refreshEditor(); + } else if (reward.isNoSell()) { noSellCards.add(reward.getCard()); - AdventureDeckEditor editor = ((AdventureDeckEditor) DeckEditScene.getInstance().getScreen()); - if (editor != null) - editor.refresh(); + refreshEditor(); } break; case Gold: @@ -663,6 +659,12 @@ public class AdventurePlayer implements Serializable, SaveFileContent { } } + private void refreshEditor() { + AdventureDeckEditor editor = ((AdventureDeckEditor) DeckEditScene.getInstance().getScreen()); + if (editor != null) + editor.refresh(); + } + private void addGold(int goldCount) { gold += goldCount; onGoldChangeList.emit(); @@ -742,11 +744,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent { public boolean defeated() { gold = (int) (gold - (gold * difficultyData.goldLoss)); - int newLife = (int) (life - (maxLife * difficultyData.lifeLoss)); - life = Math.max(1, newLife); + life = (int) (life - (maxLife * difficultyData.lifeLoss)); onLifeTotalChangeList.emit(); onGoldChangeList.emit(); - return newLife < 1; + return life < 1; //If true, the player would have had 0 or less, and thus is actually "defeated" if the caller cares about it } @@ -783,8 +784,11 @@ public class AdventurePlayer implements Serializable, SaveFileContent { } public void setShards(int number) { - shards = number; - onShardsChangeList.emit(); + boolean changed = shards != number; + if (changed) { + shards = number; + onShardsChangeList.emit(); + } } public void addBlessing(EffectData bless) { @@ -838,6 +842,20 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return false; } + public ItemData getRandomEquippedArmor() { + Array armor = new Array<>(); + for (String name : equippedItems.values()) { + ItemData data = ItemData.getItem(name); + if (data != null + && ("Boots".equalsIgnoreCase(data.equipmentSlot) + || "Body".equalsIgnoreCase(data.equipmentSlot) + || "Neck".equalsIgnoreCase(data.equipmentSlot))) { + armor.add(data); + } + } + return armor.random(); + } + public ItemData getEquippedAbility1() { for (String name : equippedItems.values()) { ItemData data = ItemData.getItem(name); @@ -875,6 +893,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return difficultyData; } + public boolean isHardorInsaneDifficulty() { + return "Hard".equalsIgnoreCase(difficultyData.name) || "Insane".equalsIgnoreCase(difficultyData.name); + } + public void renameDeck(String text) { deck = (Deck) deck.copyTo(text); decks[selectedDeckIndex] = deck; diff --git a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java index 5c30836fa13..10110c414ef 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java +++ b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java @@ -16,7 +16,12 @@ import forge.assets.FSkinFont; import forge.assets.FSkinImage; import forge.card.CardEdition; import forge.card.CardZoom; -import forge.deck.*; +import forge.deck.AddBasicLandsDialog; +import forge.deck.CardPool; +import forge.deck.Deck; +import forge.deck.DeckFormat; +import forge.deck.DeckSection; +import forge.deck.FDeckViewer; import forge.game.GameType; import forge.gamemodes.limited.BoosterDraft; import forge.item.InventoryItem; @@ -31,10 +36,13 @@ import forge.menu.FPopupMenu; import forge.model.FModel; import forge.screens.FScreen; import forge.screens.TabPageScreen; -import forge.toolbox.*; +import forge.toolbox.FContainer; +import forge.toolbox.FEvent; +import forge.toolbox.FLabel; +import forge.toolbox.FOptionPane; +import forge.toolbox.GuiChoose; import forge.util.Callback; import forge.util.ItemPool; -import forge.util.Localizer; import forge.util.Utils; import org.apache.commons.lang3.StringUtils; @@ -48,7 +56,7 @@ public class AdventureDeckEditor extends TabPageScreen { Deck contents = new Deck(); protected ContentPreviewPage(Deck cardsToShow) { - super(ItemManagerConfig.QUEST_EDITOR_POOL, Localizer.getInstance().getMessage("lblInventory"), CATALOG_ICON); + super(ItemManagerConfig.QUEST_EDITOR_POOL, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON); contents = cardsToShow; } @@ -66,7 +74,7 @@ public class AdventureDeckEditor extends TabPageScreen { private static class DraftPackPage extends CatalogPage { protected DraftPackPage() { - super(ItemManagerConfig.DRAFT_PACK, Localizer.getInstance().getMessage("lblPackN", String.valueOf(1)), FSkinImage.PACK); + super(ItemManagerConfig.DRAFT_PACK, Forge.getLocalizer().getMessage("lblPackN", String.valueOf(1)), FSkinImage.PACK); } @Override @@ -134,13 +142,13 @@ public class AdventureDeckEditor extends TabPageScreen { private static class StoreCatalogPage extends CatalogPage { protected StoreCatalogPage() { - super(ItemManagerConfig.QUEST_EDITOR_POOL, Localizer.getInstance().getMessage("lblInventory"), CATALOG_ICON); + super(ItemManagerConfig.QUEST_EDITOR_POOL, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON); Current.player().onGoldChange(() -> lblGold.setText(String.valueOf(AdventurePlayer.current().getGold()))); } @Override protected void buildMenu(final FDropDownMenu menu, final PaperCard card) { - addItem(menu, "Sell for ", String.valueOf(AdventurePlayer.current().cardSellPrice(card)), SIDEBOARD_ICON, false, true, new Callback() { + addItem(menu, Forge.getLocalizer().getMessage("lblSellFor"), String.valueOf(AdventurePlayer.current().cardSellPrice(card)), SIDEBOARD_ICON, false, true, new Callback() { @Override public void run(Integer result) { if (result == null || result <= 0) { @@ -169,7 +177,7 @@ public class AdventureDeckEditor extends TabPageScreen { private static class CollectionCatalogPage extends CatalogPage { protected CollectionCatalogPage() { - super(ItemManagerConfig.QUEST_EDITOR_POOL, Localizer.getInstance().getMessage("lblInventory"), CATALOG_ICON); + super(ItemManagerConfig.QUEST_EDITOR_POOL, Forge.getLocalizer().getMessage("lblInventory"), CATALOG_ICON); } @Override @@ -184,6 +192,8 @@ public class AdventureDeckEditor extends TabPageScreen { if (!cardManager.isInfinite()) { removeCard(card, result); } + if (Current.player().autoSellCards.contains(card)) + Current.player().autoSellCards.remove(card); getMainDeckPage().addCard(card, result); } }); @@ -198,6 +208,8 @@ public class AdventureDeckEditor extends TabPageScreen { if (!cardManager.isInfinite()) { removeCard(card, result); } + if (Current.player().autoSellCards.contains(card)) + Current.player().autoSellCards.remove(card); getSideboardPage().addCard(card, result); } }); @@ -208,17 +220,17 @@ public class AdventureDeckEditor extends TabPageScreen { int sellableCount = Current.player().getSellableCards().count(card); if (noSellCount > 0) { - FMenuItem unsellableCount = new FMenuItem("Unsellable (" + noSellCount + ")", null, null); + FMenuItem unsellableCount = new FMenuItem(Forge.getLocalizer().getMessage("lblUnsellableCount", noSellCount), null, null); unsellableCount.setEnabled(false); menu.addItem(unsellableCount); } if (sellableCount > 0) { - FMenuItem moveToAutosell = new FMenuItem("Move to Autosell (" + autoSellCount + " / " + sellableCount + ")", Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> Current.player().autoSellCards.add(card)); + FMenuItem moveToAutosell = new FMenuItem(Forge.getLocalizer().getMessage("lbltoSell", autoSellCount, sellableCount), Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> Current.player().autoSellCards.add(card)); moveToAutosell.setEnabled(sellableCount - autoSellCount > 0); menu.addItem(moveToAutosell); - FMenuItem moveToCatalog = new FMenuItem("Move back to Catalog (" + autoSellCount + " / " + sellableCount + ")", Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> Current.player().autoSellCards.remove(card)); + FMenuItem moveToCatalog = new FMenuItem(Forge.getLocalizer().getMessage("lbltoInventory", autoSellCount, sellableCount), Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> Current.player().autoSellCards.remove(card)); moveToCatalog.setEnabled(autoSellCount > 0); menu.addItem(moveToCatalog); } @@ -533,28 +545,28 @@ public class AdventureDeckEditor extends TabPageScreen { } if (!isShop && catalogPage != null && !(catalogPage instanceof ContentPreviewPage)) { if (catalogPage.showNoSellCards) { - FMenuItem hideNoSell = new FMenuItem("Hide No-Sell cards", Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> catalogPage.toggleNoSellCards(false)); + FMenuItem hideNoSell = new FMenuItem(Forge.getLocalizer().getMessage("lblHideNoSell"), Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> catalogPage.toggleNoSellCards(false)); addItem(hideNoSell); hideNoSell.setEnabled(catalogPage.showAutoSellCards || catalogPage.showCollectionCards); } else { - addItem(new FMenuItem("Show No-Sell cards", Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.toggleNoSellCards(true))); + addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblShowNoSell"), Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.toggleNoSellCards(true))); } if (catalogPage.showAutoSellCards) { - FMenuItem hideAutoSell = new FMenuItem("Hide Auto-Sell cards", Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> catalogPage.toggleAutoSellCards(false)); + FMenuItem hideAutoSell = new FMenuItem(Forge.getLocalizer().getMessage("lblHideAutoSell"), Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> catalogPage.toggleAutoSellCards(false)); addItem(hideAutoSell); hideAutoSell.setEnabled(catalogPage.showCollectionCards || catalogPage.showNoSellCards); } else { - addItem(new FMenuItem("Show Auto-Sell cards", Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.toggleAutoSellCards(true))); + addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblShowAutoSell"), Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.toggleAutoSellCards(true))); } if (catalogPage.showCollectionCards) { - FMenuItem hideCollection = new FMenuItem("Hide Collection cards", Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> catalogPage.toggleCollectionCards(false)); + FMenuItem hideCollection = new FMenuItem(Forge.getLocalizer().getMessage("lblHideCollection"), Forge.hdbuttons ? FSkinImage.HDMINUS : FSkinImage.MINUS, e1 -> catalogPage.toggleCollectionCards(false)); addItem(hideCollection); hideCollection.setEnabled(catalogPage.showAutoSellCards || catalogPage.showNoSellCards); } else { - addItem(new FMenuItem("Show Collection cards", Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.toggleCollectionCards(true))); + addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblShowCollection"), Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.toggleCollectionCards(true))); } if (!catalogPage.showNoSellCards || !catalogPage.showAutoSellCards || !catalogPage.showCollectionCards) { - addItem(new FMenuItem("Show All cards", Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.showAllCards())); + addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblShowAll"), Forge.hdbuttons ? FSkinImage.HDPLUS : FSkinImage.PLUS, e1 -> catalogPage.showAllCards())); } } ((DeckEditorPage) getSelectedPage()).buildDeckMenu(this); diff --git a/forge-gui-mobile/src/forge/adventure/scene/DeckEditScene.java b/forge-gui-mobile/src/forge/adventure/scene/DeckEditScene.java index db2fcfa3645..6315979fe7d 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DeckEditScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DeckEditScene.java @@ -2,6 +2,8 @@ package forge.adventure.scene; import com.badlogic.gdx.scenes.scene2d.Stage; import forge.adventure.data.AdventureEventData; +import forge.adventure.player.AdventurePlayer; +import forge.item.PaperCard; import forge.screens.FScreen; /** @@ -60,4 +62,11 @@ public class DeckEditScene extends ForgeScene { return screen; } + public boolean isAutoSell(PaperCard pc) { + return AdventurePlayer.current().getAutoSellCards().contains(pc); + } + + public boolean isNoSell(PaperCard pc) { + return AdventurePlayer.current().getNoSellCards().contains(pc); + } } diff --git a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java index dc2f75f743b..6c711650c75 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java @@ -134,13 +134,14 @@ public class DuelScene extends ForgeScene { Runnable endRunnable = null; void afterGameEnd(String enemyName, boolean winner) { - Forge.restrictAdvMenus = winner; + Forge.advFreezePlayerControls = winner; endRunnable = () -> Gdx.app.postRunnable(() -> { GameHUD.getInstance().switchAudio(); dungeonEffect = null; callbackExit = false; Forge.clearTransitionScreen(); Forge.clearCurrentScreen(); + Forge.advFreezePlayerControls = false; Scene last = Forge.switchToLast(); Current.player().getStatistic().setResult(enemyName, winner); @@ -301,7 +302,7 @@ public class DuelScene extends ForgeScene { } else if (this.eventData != null) { deck = eventData.nextOpponent.getDeck(); } else { - deck = currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Insane") || Current.player().getDifficulty().name.equalsIgnoreCase("Hard")); + deck = currentEnemy.copyPlayerDeck ? this.playerDeck : currentEnemy.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().isHardorInsaneDifficulty()); } RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(playerCount, appliedVariants, deck, null, false, null, null); @@ -409,9 +410,7 @@ public class DuelScene extends ForgeScene { this.eventData = eventData; if (eventData != null && eventData.eventRules == null) eventData.eventRules = new AdventureEventData.AdventureEventRules(AdventureEventController.EventFormat.Constructed, 1.0f); - this.arenaBattleChallenge = isArena - && (Current.player().getDifficulty().name.equalsIgnoreCase("Hard") - || Current.player().getDifficulty().name.equalsIgnoreCase("Insane")); + this.arenaBattleChallenge = isArena && Current.player().isHardorInsaneDifficulty(); if (eventData != null && eventData.registeredDeck != null) this.playerDeck = eventData.registeredDeck; else diff --git a/forge-gui-mobile/src/forge/adventure/scene/HudScene.java b/forge-gui-mobile/src/forge/adventure/scene/HudScene.java index 79312c2fc66..c832752a584 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/HudScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/HudScene.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.controllers.Controller; import com.badlogic.gdx.graphics.GL20; +import forge.Forge; import forge.adventure.stage.GameHUD; import forge.adventure.stage.GameStage; import forge.adventure.stage.IAfterMatch; @@ -80,6 +81,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.keyDown(keycode); } @@ -93,6 +96,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.keyUp(keycode); } @@ -112,6 +117,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.keyTyped(character); } @@ -121,6 +128,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.touchDown(screenX, screenY, pointer, button); } @@ -139,6 +148,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.touchDragged(screenX, screenY, pointer); } @@ -148,6 +159,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.mouseMoved(screenX, screenY); } @@ -157,6 +170,8 @@ public abstract class HudScene extends Scene implements InputProcessor, IAfterMa return true; if (isInHudOnlyMode()) return false; + if (Forge.advFreezePlayerControls) + return false; return stage.scrolled(amountX, amountY); } diff --git a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java index 2f4ecc78bf6..b7651596470 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java @@ -161,7 +161,7 @@ public class InventoryScene extends UIScene { ConsoleCommandInterpreter.getInstance().command(data.commandOnUse); if (data.dialogOnUse != null && data.dialogOnUse.text != null && !data.dialogOnUse.text.isEmpty()) { MapDialog dialog = new MapDialog(data.dialogOnUse, MapStage.getInstance(),0,null); - MapStage.instance.showDialog(); + MapStage.getInstance().showDialog(); dialog.activate(); ChangeListener listen = new ChangeListener() { @Override @@ -218,10 +218,13 @@ public class InventoryScene extends UIScene { } } + public void clearItemDescription() { + itemDescription.setText(""); + } private void setSelected(Button actor) { selected = actor; if (actor == null) { - itemDescription.setText(""); + clearItemDescription(); deleteButton.setDisabled(true); equipButton.setDisabled(true); useButton.setDisabled(true); @@ -246,7 +249,7 @@ public class InventoryScene extends UIScene { if (Current.player().getShards() < data.shardsNeeded) useButton.setDisabled(true); - if (data.equipmentSlot == null || data.equipmentSlot.isEmpty()) { + if (data.equipmentSlot == null || data.equipmentSlot.isEmpty() || data.isCracked) { equipButton.setDisabled(true); } else { equipButton.setDisabled(false); @@ -261,7 +264,8 @@ public class InventoryScene extends UIScene { button.layout(); } } - itemDescription.setText(data.name + "\n[%98]" + data.getDescription()); + String status = data.isCracked ? " (" + Forge.getLocalizer().getMessage("lblCracked") + ")" : ""; + itemDescription.setText(data.name + status + "\n[%98]" + data.getDescription()); } else if (deckLocation.containsKey(actor)){ Deck data = (deckLocation.get(actor)); diff --git a/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java b/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java index b0ce2df43b8..80098a750fe 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/RewardScene.java @@ -133,7 +133,7 @@ public class RewardScene extends UIScene { } //save RAM ImageCache.unloadCardTextures(true); - Forge.restrictAdvMenus = false; + Forge.advFreezePlayerControls = false; if (this.collectionPool != null) { this.collectionPool.clear(); this.collectionPool = null; diff --git a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java index 2ac83e3c0c1..135ead8abbd 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java @@ -112,7 +112,7 @@ public class SaveLoadScene extends UIScene { } public class SaveSlot extends Selectable { - private int slotNumber; + private final int slotNumber; public SaveSlot(int slotNumber) { super(Controls.newTextButton("...")); @@ -163,27 +163,19 @@ public class SaveLoadScene extends UIScene { if (slot > 0) lastSelectedSlot = slot; if (previews.containsKey(slot)) { - WorldSaveHeader header = previews.get(slot); - if (header.preview != null) { - previewImage.setDrawable(new TextureRegionDrawable(new Texture(header.preview))); + WorldSaveHeader worldSaveHeader = previews.get(slot); + if (worldSaveHeader.preview != null) { + previewImage.setDrawable(new TextureRegionDrawable(new Texture(worldSaveHeader.preview))); previewImage.setScaling(Scaling.fit); previewImage.layout(); previewImage.setVisible(true); previewDate.setVisible(true); - if (header.saveDate != null) - previewDate.setText("[%98]" + DateFormat.getDateInstance().format(header.saveDate) + " " + DateFormat.getTimeInstance(DateFormat.SHORT).format(header.saveDate)); + if (worldSaveHeader.saveDate != null) + previewDate.setText("[%98]" + DateFormat.getDateInstance().format(worldSaveHeader.saveDate) + " " + DateFormat.getTimeInstance(DateFormat.SHORT).format(worldSaveHeader.saveDate)); else previewDate.setText(""); - if (header.name.contains(Character.toString(ASCII_179))) { - String[] split = TextUtil.split(header.name, ASCII_179); - try { - playerLocation.setText(split[1]); - } catch (Exception e) { - playerLocation.setText(""); - } - } else { - playerLocation.setText(""); - } + //getLocation + playerLocation.setText(getSplitHeaderName(worldSaveHeader, true)); } } else { if (previewImage != null) @@ -206,7 +198,7 @@ public class SaveLoadScene extends UIScene { //Access to screen should be disabled, but stop the process just in case. //Saving needs to be disabled inside maps until we can capture and load exact map state //Otherwise location based events for quests can be skipped by saving and then loading outside the map - Dialog noSave = createGenericDialog("", Forge.getLocalizer().getMessage("lblGameNotSaved"), Forge.getLocalizer().getMessage("lblOK"),null, null, null); + Dialog noSave = createGenericDialog("", Forge.getLocalizer().getMessage("lblGameNotSaved"), Forge.getLocalizer().getMessage("lblOK"), null, null, null); showDialog(noSave); return; } @@ -311,26 +303,32 @@ public class SaveLoadScene extends UIScene { try (FileInputStream fos = new FileInputStream(name.getAbsolutePath()); InflaterInputStream inf = new InflaterInputStream(fos); ObjectInputStream oos = new ObjectInputStream(inf)) { - - int slot = WorldSave.filenameToSlot(name.getName()); - WorldSaveHeader header = (WorldSaveHeader) oos.readObject(); - if (header.name.contains(Character.toString(ASCII_179))) { - String[] split = TextUtil.split(header.name, ASCII_179); - buttons.get(slot).actor.setText(split[0]); - //playerLocation.setText(split[1]); - } else { - buttons.get(slot).actor.setText(header.name); - } - previews.put(slot, header); + WorldSaveHeader worldSaveHeader = (WorldSaveHeader) oos.readObject(); + //get header name + buttons.get(slot).actor.setText(getSplitHeaderName(worldSaveHeader, false)); + previews.put(slot, worldSaveHeader); } } catch (ClassNotFoundException | IOException | GdxRuntimeException e) { + //e.printStackTrace(); } } } } + private String getSplitHeaderName(WorldSaveHeader worldSaveHeader, boolean getLocation) { + String noMapData = "[RED]No Map Data!"; + if (worldSaveHeader.name.contains(Character.toString(ASCII_179))) { + String[] split = TextUtil.split(worldSaveHeader.name, ASCII_179); + if (getLocation) + return split.length > 1 ? split[1] : noMapData; + else + return split[0]; + } + return getLocation ? noMapData : worldSaveHeader.name; + } + public enum Modes { Save, Load, @@ -379,6 +377,28 @@ public class SaveLoadScene extends UIScene { } public String getSaveFileSuffix() { - return ASCII_179 + GameScene.instance().getAdventurePlayerLocation(true, true); + String difficulty; + switch (AdventurePlayer.current().getDifficulty().name) { + case "easy": + case "Easy": + difficulty = "[%99][CYAN]\uFF0A[WHITE]"; + break; + case "normal": + case "Normal": + difficulty = "[%99][GREEN]\uFF0A[WHITE]"; + break; + case "hard": + case "Hard": + difficulty = "[%99][GOLD]\uFF0A[WHITE]"; + break; + case "insane": + case "Insane": + difficulty = "[%99][RED]\uFF0A[WHITE]"; + break; + default: + difficulty = "[%99][WHITE]"; + break; + } + return ASCII_179 + difficulty + GameScene.instance().getAdventurePlayerLocation(true, true); } } diff --git a/forge-gui-mobile/src/forge/adventure/scene/ShopScene.java b/forge-gui-mobile/src/forge/adventure/scene/ShopScene.java index 329764fee4b..71e39a05666 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/ShopScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/ShopScene.java @@ -54,13 +54,15 @@ public class ShopScene extends ForgeScene { int cards = 0; for (PaperCard cardToSell: Current.player().autoSellCards.toFlatList()) { cards++; - profit += AdventurePlayer.current().cardSellPrice(cardToSell); + profit += getCardPrice(cardToSell); } if (!confirmAutosell(profit, cards, changes.getTownPriceModifier())) { return; } } AdventurePlayer.current().doAutosell(); + if (screen != null) + screen.refresh(); } private boolean confirmAutosell(int profit, int cards, float townPriceModifier) { @@ -71,4 +73,7 @@ public class ShopScene extends ForgeScene { AdventurePlayer.current().loadChanges(changes); this.changes = changes; } + public int getCardPrice(PaperCard pc) { + return AdventurePlayer.current().cardSellPrice(pc); + } } diff --git a/forge-gui-mobile/src/forge/adventure/stage/Console.java b/forge-gui-mobile/src/forge/adventure/stage/Console.java index 8d573d4c245..015d9126e9c 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/Console.java +++ b/forge-gui-mobile/src/forge/adventure/stage/Console.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.Align; +import forge.Forge; import forge.adventure.util.Controls; public class Console extends Window { @@ -17,8 +18,10 @@ public class Console extends Window { setVisible(false); getStage().unfocus(input); } else { - setVisible(true); - getStage().setKeyboardFocus(input); + if (!Forge.advFreezePlayerControls) { + setVisible(true); + getStage().setKeyboardFocus(input); + } } } diff --git a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java index fd1e12a6f90..4ef484a0f2f 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java +++ b/forge-gui-mobile/src/forge/adventure/stage/ConsoleCommandInterpreter.java @@ -193,7 +193,7 @@ public class ConsoleCommandInterpreter { }); registerCommand(new String[]{"leave"}, s -> { if (!MapStage.getInstance().isInMap()) return "not on a map"; - MapStage.getInstance().exitDungeon(); + MapStage.getInstance().exitDungeon(false); return "Got out"; }); registerCommand(new String[]{"debug", "collision"}, s -> { @@ -254,7 +254,7 @@ public class ConsoleCommandInterpreter { }); registerCommand(new String[]{"dumpEnemyDeckColors"}, s -> { for (EnemyData E : new Array.ArrayIterator<>(WorldData.getAllEnemies())) { - Deck D = E.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard")); + Deck D = E.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().isHardorInsaneDifficulty()); DeckProxy DP = new DeckProxy(D, "Constructed", GameType.Constructed, null); ColorSet colorSet = DP.getColor(); System.out.printf("%s: Colors: %s (%s%s%s%s%s%s)\n", D.getName(), DP.getColor(), @@ -270,7 +270,7 @@ public class ConsoleCommandInterpreter { }); registerCommand(new String[]{"dumpEnemyDeckList"}, s -> { for (EnemyData E : new Array.ArrayIterator<>(WorldData.getAllEnemies())) { - Deck D = E.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard")); + Deck D = E.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().isHardorInsaneDifficulty()); DeckProxy DP = new DeckProxy(D, "Constructed", GameType.Constructed, null); System.out.printf("Deck: %s\n%s\n\n", D.getName(), DP.getDeck().getMain().toCardList("\n") ); @@ -279,7 +279,7 @@ public class ConsoleCommandInterpreter { }); registerCommand(new String[]{"dumpEnemyColorIdentity"}, s -> { for (EnemyData E : new Array.ArrayIterator<>(WorldData.getAllEnemies())) { - Deck D = E.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().getDifficulty().name.equalsIgnoreCase("Hard")); + Deck D = E.generateDeck(Current.player().isFantasyMode(), Current.player().isUsingCustomDeck() || Current.player().isHardorInsaneDifficulty()); DeckProxy DP = new DeckProxy(D, "Constructed", GameType.Constructed, null); System.out.printf("%s Colors: %s | Deck Colors: %s (%s)%s\n", E.name, E.colors, DP.getColorIdentity().toEnumSet().toString(), DP.getName() , E.boss ? " - BOSS" : ""); diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java index 3d7823fd465..5021ce566ee 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java +++ b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java @@ -8,10 +8,20 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.*; +import com.badlogic.gdx.scenes.scene2d.Action; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Group; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.Touchable; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; -import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.Dialog; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.Touchpad; import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; @@ -28,8 +38,19 @@ import forge.adventure.character.CharacterSprite; import forge.adventure.data.AdventureQuestData; import forge.adventure.data.ItemData; import forge.adventure.player.AdventurePlayer; -import forge.adventure.scene.*; -import forge.adventure.util.*; +import forge.adventure.scene.DeckSelectScene; +import forge.adventure.scene.GameScene; +import forge.adventure.scene.InventoryScene; +import forge.adventure.scene.MapViewScene; +import forge.adventure.scene.QuestLogScene; +import forge.adventure.scene.Scene; +import forge.adventure.scene.TileMapScene; +import forge.adventure.util.AdventureQuestController; +import forge.adventure.util.Config; +import forge.adventure.util.Controls; +import forge.adventure.util.Current; +import forge.adventure.util.KeyBinding; +import forge.adventure.util.UIActor; import forge.adventure.world.WorldSave; import forge.deck.Deck; import forge.gui.GuiBase; @@ -60,7 +81,7 @@ public class GameHUD extends Stage { private final Console console; float TOUCHPAD_SCALE = 70f, referenceX; float opacity = 1f; - private boolean debugMap; + private boolean debugMap, transluscent, hidden; private final Dialog dialog; private boolean dialogOnlyInput; @@ -70,6 +91,10 @@ public class GameHUD extends Stage { private String lifepointsTextColor = ""; private final ScrollPane scrollPane; private final ScrollPane notificationPane; + private final Group mapGroup = new Group(); + private final Group hudGroup = new Group(); + private final Group menuGroup = new Group(); + private final Group avatarGroup = new Group(); private GameHUD(GameStage gameStage) { super(new ScalingViewport(Scaling.stretch, Scene.getIntendedWidth(), Scene.getIntendedHeight()), gameStage.getBatch()); @@ -134,9 +159,9 @@ public class GameHUD extends Stage { shards.skipToTheEnd(); money = ui.findActor("money"); money.skipToTheEnd(); - shards.setText("[%95][+Shards] 0"); - money.setText("[%95][+Gold] "); - lifePoints.setText("[%95][+Life] 20/20"); + shards.setText("[%95][+Shards]"); + money.setText("[%95][+Gold]"); + lifePoints.setText("[%95][+Life]"); keys = Controls.newTextraLabel(""); scrollPane = new ScrollPane(keys); scrollPane.setPosition(2, 2); @@ -144,6 +169,7 @@ public class GameHUD extends Stage { addActor(scrollPane); AdventurePlayer.current().onLifeChange(() -> { String effect = "{EMERGE}"; + String effectEnd = "{ENDEMERGE}"; String heartbeat = ""; //colored lifepoints if (Current.player().getLife() >= Current.player().getMaxLife()) { @@ -152,20 +178,16 @@ public class GameHUD extends Stage { } else if (Current.player().getLife() <= 5) { //color red if critical effect = ""; + effectEnd = ""; heartbeat = "{HEARTBEAT=0.5;0.5}"; lifepointsTextColor = "{ENDHEARTBEAT}[RED]"; - } - else { + } else { lifepointsTextColor = "[WHITE]"; } - lifePoints.restart("[%95]" + heartbeat + "[+Life]" + lifepointsTextColor + effect + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()); - + lifePoints.restart("[%95]" + heartbeat + "[+Life]" + lifepointsTextColor + effect + " " + AdventurePlayer.current().getLife() + effectEnd + "/" + AdventurePlayer.current().getMaxLife()); }); - AdventurePlayer.current().onShardsChange(() -> { - - shards.restart("[%95][+Shards] {EMERGE}" + AdventurePlayer.current().getShards()); - }); - AdventurePlayer.current().onGoldChange(() -> money.restart("[%95][+Gold] {EMERGE}" + AdventurePlayer.current().getGold())); + AdventurePlayer.current().onShardsChange(() -> shards.restart("[%95][+Shards]{EMERGE} " + AdventurePlayer.current().getShards() + "{ENDEMERGE}")); + AdventurePlayer.current().onGoldChange(() -> money.restart("[%95][+Gold]{EMERGE} " + AdventurePlayer.current().getGold() + "{ENDEMERGE}")); AdventurePlayer.current().onEquipmentChanged(this::updateAbility); addActor(ui); addActor(miniMapPlayer); @@ -173,11 +195,9 @@ public class GameHUD extends Stage { console.setBounds(0, GuiBase.isAndroid() ? getHeight() : 0, getWidth(), getHeight() / 2); console.setVisible(false); ui.addActor(console); - if (GuiBase.isAndroid()) { - avatar.addListener(new ConsoleToggleListener()); - avatarborder.addListener(new ConsoleToggleListener()); - gamehud.addListener(new ConsoleToggleListener()); - } + avatar.addListener(new ConsoleToggleListener()); + avatarborder.addListener(new ConsoleToggleListener()); + gamehud.addListener(new ConsoleToggleListener()); WorldSave.getCurrentSave().onLoad(this::enter); eventTouchDown = new InputEvent(); @@ -189,17 +209,42 @@ public class GameHUD extends Stage { notificationPane = new ScrollPane(notificationText); notificationPane.setTouchable(Touchable.childrenOnly); - notificationPane.setBounds(5, GuiBase.isAndroid() ? getHeight() : -notificationText.getPrefHeight(), getWidth()*0.4f, 25); + notificationPane.setBounds(5, GuiBase.isAndroid() ? getHeight() : -notificationText.getPrefHeight(), getWidth() * 0.4f, 25); notificationPane.setStyle(Controls.getSkin().get("paper", ScrollPane.ScrollPaneStyle.class)); notificationPane.getColor().a = 0f; ui.addActor(notificationPane); + //MAP + mapGroup.addActor(miniMap); + mapGroup.addActor(mapborder); + mapGroup.addActor(openMapActor); + mapGroup.addActor(miniMapPlayer); + ui.addActor(mapGroup); + //HUD + hudGroup.addActor(gamehud); + hudGroup.addActor(lifePoints); + hudGroup.addActor(shards); + hudGroup.addActor(money); + hudGroup.addActor(blank); + ui.addActor(hudGroup); + //MENU + menuGroup.addActor(deckActor); + menuGroup.addActor(menuActor); + menuGroup.addActor(logbookActor); + menuGroup.addActor(inventoryActor); + menuGroup.addActor(exitToWorldMapActor); + menuGroup.addActor(bookmarkActor); + ui.addActor(menuGroup); + //AVATAR + avatarGroup.addActor(avatar); + avatarGroup.addActor(avatarborder); + ui.addActor(avatarGroup); } private void openMap() { if (console.isVisible()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; Forge.switchScene(MapViewScene.instance()); } @@ -207,7 +252,7 @@ public class GameHUD extends Stage { private void logbook() { if (console.isVisible()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; Forge.switchScene(QuestLogScene.instance(Forge.getCurrentScene())); } @@ -300,8 +345,8 @@ public class GameHUD extends Stage { miniMapPlayer.setPosition(miniMap.getX() + xPosMini - miniMapPlayer.getWidth() / 2, miniMap.getY() + yPosMini - miniMapPlayer.getHeight() / 2); miniMapPlayer.setVisible(miniMap.isVisible() && - !Controls.actorContainsVector(notificationPane, new Vector2(miniMapPlayer.getX(),miniMapPlayer.getY())) - && (!Controls.actorContainsVector(console, new Vector2(miniMapPlayer.getX(),miniMapPlayer.getY())) + !Controls.actorContainsVector(notificationPane, new Vector2(miniMapPlayer.getX(), miniMapPlayer.getY())) + && (!Controls.actorContainsVector(console, new Vector2(miniMapPlayer.getX(), miniMapPlayer.getY())) || !console.isVisible())); // prevent drawing on top of console or notifications if (!MapStage.getInstance().isInMap()) @@ -356,7 +401,7 @@ public class GameHUD extends Stage { switch (GameScene.instance().getAdventurePlayerLocation(false, false)) { case "capital": case "town": - if(MapStage.getInstance().isInMap()) { + if (MapStage.getInstance().isInMap()) { int rep = TileMapScene.instance().getPointOfInterestChanges().getMapReputation(); String reputationText = TileMapScene.instance().rootPoint.getDisplayName() + "\nReputation: " + (rep > 0 ? "[GREEN]" : rep < 0 ? "[RED]" : "[WHITE]") + rep + "[/]"; if (fromWorldMap) { @@ -405,6 +450,7 @@ public class GameHUD extends Stage { } if (MapStage.getInstance().isInMap()) updateBookmarkActor(MapStage.getInstance().getChanges().isBookmarked()); + avatarGroup.setZIndex(ui.getChildren().size); } void clearAbility() { @@ -436,6 +482,8 @@ public class GameHUD extends Stage { TextraButton button = Controls.newTextButton("[%90][+" + data.iconName + "][+Shards][BLACK]" + data.shardsNeeded, () -> { if (console.isVisible()) return; + if (Forge.advFreezePlayerControls) + return; boolean isInPoi = MapStage.getInstance().isInMap(); if (!(isInPoi && data.usableInPoi || !isInPoi && data.usableOnWorldMap)) return; @@ -573,7 +621,7 @@ public class GameHUD extends Stage { private void openDeck() { if (console.isVisible()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; Forge.switchScene(DeckSelectScene.instance()); } @@ -581,7 +629,7 @@ public class GameHUD extends Stage { private void openInventory() { if (console.isVisible()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; WorldSave.getCurrentSave().header.createPreview(); Forge.switchScene(InventoryScene.instance()); @@ -594,7 +642,7 @@ public class GameHUD extends Stage { return; if (!MapStage.getInstance().canEscape()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; dialog.getButtonTable().clear(); dialog.getContentTable().clear(); @@ -618,7 +666,7 @@ public class GameHUD extends Stage { return; if (!MapStage.getInstance().canEscape()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; if (MapStage.getInstance().isInMap()) { if (MapStage.getInstance().getChanges().isBookmarked()) { @@ -658,16 +706,11 @@ public class GameHUD extends Stage { private void menu() { if (console.isVisible()) return; - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; gameStage.openMenu(); } - private void setVisibility(Actor actor, boolean visible) { - if (actor != null) - actor.setVisible(visible); - } - private void setDisabled(Actor actor, boolean value, String enabled, String disabled) { if (actor instanceof TextraButton) { ((TextraButton) actor).setDisabled(value); @@ -678,40 +721,70 @@ public class GameHUD extends Stage { private void setAlpha(Actor actor, boolean visible) { if (actor != null) { if (visible) - actor.getColor().a = 1f; + actor.addAction(Actions.alpha(1f, 0.5f)); else - actor.getColor().a = 0.4f; + actor.addAction(Actions.alpha(actor == mapGroup ? 0f : 0.4f, 0.5f)); } } public void showHideMap(boolean visible) { - setVisibility(miniMap, visible); - setVisibility(mapborder, visible); - setVisibility(openMapActor, visible); - setVisibility(miniMapPlayer, visible); - setVisibility(gamehud, visible); + transluscent = !visible; + setAlpha(mapGroup, visible); + setAlpha(hudGroup, visible); + setAlpha(menuGroup, visible); + setAlpha(avatarGroup, visible); - setAlpha(lifePoints, visible); - setAlpha(shards, visible); - setAlpha(money, visible); - - setVisibility(blank, visible); setDisabled(exitToWorldMapActor, !MapStage.getInstance().isInMap(), "[%120][+ExitToWorldMap]", "\uFF0F"); setDisabled(bookmarkActor, !MapStage.getInstance().isInMap(), "[%120][+Bookmark]", "\uFF0F"); - setAlpha(avatarborder, visible); - setAlpha(avatar, visible); - setAlpha(deckActor, visible); - setAlpha(menuActor, visible); - setAlpha(logbookActor, visible); - setAlpha(inventoryActor, visible); - setAlpha(exitToWorldMapActor, visible); - setAlpha(bookmarkActor, visible); + for (TextraButton button : abilityButtonMap) { setAlpha(button, visible); } opacity = visible ? 1f : 0.4f; } + public void setHUDOpacity(boolean translucent) { + if (translucent) { + if (!MapStage.getInstance().isInMap()) + return; //WorldStage opacity issue + setAlpha(hudGroup, false); + setAlpha(menuGroup, false); + setAlpha(avatarGroup, false); + for (TextraButton button : abilityButtonMap) { + setAlpha(button, false); + } + transluscent = true; + } else { + setAlpha(hudGroup, true); + setAlpha(menuGroup, true); + setAlpha(avatarGroup, true); + for (TextraButton button : abilityButtonMap) { + setAlpha(button, true); + } + transluscent = false; + } + } + + public void showHideHUD(boolean hide) { + if (hide) { + hudGroup.addAction(Actions.fadeOut(0.5f)); + menuGroup.addAction(Actions.fadeOut(0.5f)); + if (!MapStage.getInstance().isInMap()) + mapGroup.addAction(Actions.fadeOut(0.5f)); + if (MapStage.getInstance().isInMap()) + avatarGroup.addAction(Actions.alpha(0.4f, 0.5f)); + hidden = true; + } else { + float alpha = MapStage.getInstance().isInMap() ? 0.4f : 1f; + avatarGroup.addAction(Actions.alpha(alpha, 0.5f)); + hudGroup.addAction(Actions.alpha(alpha, 0.5f)); + menuGroup.addAction(Actions.alpha(alpha, 0.5f)); + if (!MapStage.getInstance().isInMap()) + mapGroup.addAction(Actions.fadeIn(0.5f)); + hidden = false; + } + } + void toggleConsole() { console.toggle(); if (console.isVisible()) { @@ -811,7 +884,7 @@ public class GameHUD extends Stage { @Override public boolean act(float v) { if (exitDungeon) { - MapStage.getInstance().exitDungeon(); + MapStage.getInstance().exitDungeon(false); setDisabled(exitToWorldMapActor, true, "[%120][+ExitToWorldMap]", "\uFF0F"); setDisabled(bookmarkActor, true, "[%120][+Bookmark]", "\uFF0F"); } @@ -863,9 +936,21 @@ public class GameHUD extends Stage { @Override public boolean longPress(Actor actor, float x, float y) { - toggleConsole(); + if (GuiBase.isAndroid()) + toggleConsole(); return super.longPress(actor, x, y); } + + @Override + public void tap(InputEvent event, float x, float y, int count, int button) { + if (console.isVisible()) + return; + if (count > 1 && button == 0) + showHideHUD(!hidden); + else if (button == 0) + setHUDOpacity(!transluscent); + super.tap(event, x, y, count, button); + } } public void updateMusic() { @@ -929,13 +1014,13 @@ public class GameHUD extends Stage { notificationText.setWrap(false); notificationText.setText(text); notificationText.setColor(Color.BLACK); - notificationText.setWidth(Math.min(notificationText.getPrefWidth(), Forge.isLandscapeMode()?getWidth() * 0.25f : getWidth() - 25)); + notificationText.setWidth(Math.min(notificationText.getPrefWidth(), Forge.isLandscapeMode() ? getWidth() * 0.25f : getWidth() - 25)); notificationText.setWrap(true); notificationText.layout(); notificationPane.setSize(notificationText.getWidth() + 10, notificationText.getPrefHeight() + 20); - notificationPane.setPosition(5, Forge.isLandscapeMode()? -notificationPane.getHeight(): getHeight()); + notificationPane.setPosition(5, Forge.isLandscapeMode() ? -notificationPane.getHeight() : getHeight()); notificationPane.getColor().a = 1f; notificationPane.layout(); @@ -950,22 +1035,22 @@ public class GameHUD extends Stage { newNotification = Actions.after(Actions.sequence(preconfigureNotification, Actions.moveTo(5, 0, 2f), Actions.delay(10f), - Actions.alpha(0f,3f), - Actions.sizeTo(0,0))); + Actions.alpha(0f, 3f), + Actions.sizeTo(0, 0))); } else { newNotification = Actions.after(Actions.sequence(preconfigureNotification, Actions.moveToAligned(5, getHeight(), Align.topLeft, 2f), Actions.delay(10f), - Actions.alpha(0f,3f), - Actions.sizeTo(0,0))); + Actions.alpha(0f, 3f), + Actions.sizeTo(0, 0))); } notificationPane.addAction(newNotification); } - public void clearNotifications(){ + public void clearNotifications() { notificationText.setText(""); - notificationPane.setBounds(5, Forge.isLandscapeMode() ? -notificationText.getPrefHeight() : getHeight(), getWidth()*0.4f, 25); + notificationPane.setBounds(5, Forge.isLandscapeMode() ? -notificationText.getPrefHeight() : getHeight(), getWidth() * 0.4f, 25); notificationPane.setStyle(Controls.getSkin().get("paper", ScrollPane.ScrollPaneStyle.class)); notificationPane.getColor().a = 0f; } diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameStage.java b/forge-gui-mobile/src/forge/adventure/stage/GameStage.java index 0536a3ed3b7..148900967b3 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/GameStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/GameStage.java @@ -2,6 +2,7 @@ package forge.adventure.stage; import com.badlogic.gdx.Input; import com.badlogic.gdx.controllers.Controller; +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Rectangle; @@ -24,6 +25,8 @@ import com.github.tommyettinger.textra.TextraLabel; import com.github.tommyettinger.textra.TypingAdapter; import com.github.tommyettinger.textra.TypingLabel; import forge.Forge; +import forge.Graphics; +import forge.adventure.character.CharacterSprite; import forge.adventure.character.MapActor; import forge.adventure.character.PlayerSprite; import forge.adventure.data.DialogData; @@ -33,7 +36,9 @@ import forge.adventure.pointofintrest.PointOfInterest; import forge.adventure.scene.Scene; import forge.adventure.scene.StartScene; import forge.adventure.scene.TileMapScene; +import forge.adventure.util.Config; import forge.adventure.util.Controls; +import forge.adventure.util.Current; import forge.adventure.util.KeyBinding; import forge.adventure.util.MapDialog; import forge.adventure.util.Paths; @@ -46,7 +51,9 @@ import forge.card.ColorSet; import forge.deck.Deck; import forge.deck.DeckProxy; import forge.game.GameType; +import forge.gui.FThreads; import forge.gui.GuiBase; +import forge.screens.TransitionScreen; import forge.util.MyRandom; import java.util.HashMap; @@ -144,12 +151,12 @@ public abstract class GameStage extends Stage { showDialog(); } - public void showImageDialog(String message, FBufferedImage fb) { + public void showImageDialog(String message, FBufferedImage fb, Runnable runnable) { dialog.getContentTable().clear(); dialog.getButtonTable().clear(); dialog.clearListeners(); - if (fb.getTexture() != null) { + if (fb != null && fb.getTexture() != null) { TextureRegion tr = new TextureRegion(fb.getTexture()); tr.flip(true, true); Image image = new Image(tr); @@ -166,9 +173,13 @@ public abstract class GameStage extends Stage { Timer.schedule(new Timer.Task() { @Override public void run() { - fb.dispose(); + if (fb != null) + fb.dispose(); } }, 0.5f); + if (runnable != null) { + runnable.run(); + } })).width(240f); dialog.setKeepWithinStage(true); setDialogStage(GameHUD.getInstance()); @@ -562,8 +573,14 @@ public abstract class GameStage extends Stage { return false; } + @Override + public boolean touchCancelled(int screenX, int screenY, int pointer, int button) { + stop(); + return super.touchCancelled(screenX, screenY, pointer, button); + } + public void openMenu() { - if (Forge.restrictAdvMenus) + if (Forge.advFreezePlayerControls) return; WorldSave.getCurrentSave().header.createPreview(); Forge.switchScene(StartScene.instance()); @@ -634,4 +651,41 @@ public abstract class GameStage extends Stage { teleported(position); } + public void resetPlayerLocation() + { + PointOfInterest poi = Current.world().findPointsOfInterest("Spawn"); + if (poi != null) { + Forge.advFreezePlayerControls = true; + getPlayerSprite().setAnimation(CharacterSprite.AnimationTypes.Death); + getPlayerSprite().playEffect(Paths.EFFECT_BLOOD, 0.5f); + Timer.schedule(new Timer.Task() { + @Override + public void run() { + showImageDialog(Current.generateDefeatMessage(), getDefeatBadge(), + () -> FThreads.invokeInEdtNowOrLater(() -> Forge.setTransitionScreen(new TransitionScreen(() -> { + Forge.advFreezePlayerControls = false; + WorldStage.getInstance().setPosition(new Vector2(poi.getPosition().x - 16f, poi.getPosition().y + 16f)); + WorldStage.getInstance().loadPOI(poi); + WorldSave.getCurrentSave().autoSave(); + Forge.clearTransitionScreen(); + }, Forge.takeScreenshot(), "")))); + } + }, 1f); + }//Spawn shouldn't be null + } + private FBufferedImage getDefeatBadge() { + FileHandle defeat = Config.instance().getFile("ui/defeat.png"); + if (defeat.exists()) { + TextureRegion tr = new TextureRegion(Forge.getAssets().getTexture(defeat, true, false)); + tr.flip(true, false); + return new FBufferedImage(176, 200) { + @Override + protected void draw(Graphics g, float w, float h) { + g.drawImage(tr, 0, 0, 176, 200); + } + }; + } + return null; + } + } diff --git a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java index 42928ee39f8..7d762f4b7f8 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java @@ -605,7 +605,7 @@ public class MapStage extends GameStage { })); break; case "exit": - addMapActor(obj, new OnCollide(MapStage.this::exitDungeon)); + addMapActor(obj, new OnCollide(() -> MapStage.this.exitDungeon(false))); break; case "dialog": if (obj instanceof TiledMapTileMapObject) { @@ -749,13 +749,14 @@ public class MapStage extends GameStage { } } - public boolean exitDungeon() { - WorldSave.getCurrentSave().autoSave(); + public boolean exitDungeon(boolean defeated) { AdventureQuestController.instance().updateQuestsLeave(); clearIsInMap(); AdventureQuestController.instance().showQuestDialogs(this); isLoadingMatch = false; effect = null; //Reset dungeon effects. + if (defeated) + WorldStage.getInstance().resetPlayerLocation(); Forge.switchScene(GameScene.instance()); return true; } @@ -799,18 +800,18 @@ public class MapStage extends GameStage { AdventureQuestController.instance().updateQuestsLose(currentMob); AdventureQuestController.instance().showQuestDialogs(MapStage.this); boolean defeated = Current.player().defeated(); - if (canFailDungeon && defeated) { - //If hardcore mode is added, check and redirect to game over screen here - dungeonFailedDialog(); - exitDungeon(); - } + //If hardcore mode is added, check and redirect to game over screen here + if (canFailDungeon && !defeated) + dungeonFailedDialog(true); + else + exitDungeon(defeated); MapStage.this.stop(); currentMob = null; }); } } - private void dungeonFailedDialog() { + private void dungeonFailedDialog(boolean exit) { dialog.getButtonTable().clear(); dialog.getContentTable().clear(); dialog.clearListeners(); @@ -829,7 +830,8 @@ public class MapStage extends GameStage { public void clicked(InputEvent event, float x, float y) { L.skipToTheEnd(); super.clicked(event, x, y); - //exitDungeon(); + if (exit) + exitDungeon(false); } }); dialog.getButtonTable().add(ok).width(240f); @@ -932,7 +934,7 @@ public class MapStage extends GameStage { @Override protected void onActing(float delta) { - if (isPaused() || isDialogOnlyInput()) + if (isPaused() || isDialogOnlyInput() || Forge.advFreezePlayerControls) return; Iterator it = enemies.iterator(); @@ -1076,7 +1078,7 @@ public class MapStage extends GameStage { int duration = mob.getData().boss ? 400 : 200; if (Controllers.getCurrent() != null && Controllers.getCurrent().canVibrate()) Controllers.getCurrent().startVibration(duration, 1); - Forge.restrictAdvMenus = true; + Forge.advFreezePlayerControls = true; player.clearCollisionHeight(); startPause(0.8f, () -> { if (started) diff --git a/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java b/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java index aba1a56aea1..5788d45fc44 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java @@ -67,7 +67,7 @@ public class WorldStage extends GameStage implements SaveFileContent { boolean collided = false; @Override protected void onActing(float delta) { - if (isPaused() || MapStage.getInstance().isDialogOnlyInput()) + if (isPaused() || MapStage.getInstance().isDialogOnlyInput() || Forge.advFreezePlayerControls) return; drawNavigationArrow(); if (player.isMoving()) { @@ -122,7 +122,7 @@ public class WorldStage extends GameStage implements SaveFileContent { int duration = mob.getData().boss ? 400 : 200; if (Controllers.getCurrent() != null && Controllers.getCurrent().canVibrate()) Controllers.getCurrent().startVibration(duration, 1); - Forge.restrictAdvMenus = true; + Forge.advFreezePlayerControls = true; player.clearCollisionHeight(); startPause(0.8f, () -> { Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2"); @@ -188,11 +188,14 @@ public class WorldStage extends GameStage implements SaveFileContent { currentMob.setAnimation(CharacterSprite.AnimationTypes.Attack); startPause(0.5f, () -> { currentMob.resetCollisionHeight(); - Current.player().defeated(); + boolean defeated = Current.player().defeated(); AdventureQuestController.instance().updateQuestsLose(currentMob); AdventureQuestController.instance().showQuestDialogs(MapStage.getInstance()); WorldStage.this.removeEnemy(currentMob); currentMob = null; + if (defeated) { + WorldStage.getInstance().resetPlayerLocation(); + } }); } } @@ -209,17 +212,9 @@ public class WorldStage extends GameStage implements SaveFileContent { if (point == collidingPoint) { continue; } - try { - WorldSave.getCurrentSave().autoSave(); - TileMapScene.instance().load(point.getPointOfInterest()); - stop(); - TileMapScene.instance().setFromWorldMap(true); - Forge.switchScene(TileMapScene.instance()); - point.getMapSprite().checkOut(); - } catch (Exception e) { - System.err.println("Error loading map..."); - e.printStackTrace(); - } + WorldSave.getCurrentSave().autoSave(); + loadPOI(point.getPointOfInterest()); + point.getMapSprite().checkOut(); } else { if (point == collidingPoint) { collidingPoint = null; @@ -229,6 +224,18 @@ public class WorldStage extends GameStage implements SaveFileContent { } } + public void loadPOI(PointOfInterest poi) { + try { + TileMapScene.instance().load(poi); + stop(); + TileMapScene.instance().setFromWorldMap(true); + Forge.switchScene(TileMapScene.instance()); + } catch (Exception e) { + System.err.println("Error loading map..."); + e.printStackTrace(); + } + } + @Override public boolean isColliding(Rectangle boundingRect) { if (currentModifications.containsKey(PlayerModification.Fly)) diff --git a/forge-gui-mobile/src/forge/adventure/util/Config.java b/forge-gui-mobile/src/forge/adventure/util/Config.java index 5e97187bdb5..d2bf9ca66c6 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Config.java +++ b/forge-gui-mobile/src/forge/adventure/util/Config.java @@ -139,6 +139,30 @@ public class Config { return configData; } + public int getBlurDivisor() { + int val = 1; + try { + switch(settingsData.videomode) { + case "720p": + case "768p": + val = 8; + break; + case "900p": + case "1080p": + val = 16; + break; + case "1440p": + case "2160p": + val = 32; + break; + default: + break; + } + } catch (Exception e) { + return val; + } + return val; + } public String getPrefix() { return prefix; } diff --git a/forge-gui-mobile/src/forge/adventure/util/Current.java b/forge-gui-mobile/src/forge/adventure/util/Current.java index 4978d00cca5..013835e9948 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Current.java +++ b/forge-gui-mobile/src/forge/adventure/util/Current.java @@ -1,6 +1,9 @@ package forge.adventure.util; +import forge.Forge; +import forge.adventure.data.ItemData; import forge.adventure.player.AdventurePlayer; +import forge.adventure.scene.InventoryScene; import forge.adventure.world.World; import forge.adventure.world.WorldSave; import forge.deck.Deck; @@ -24,5 +27,18 @@ public class Current { public static void setLatestDeck(Deck generateDeck) { deck=generateDeck; } + public static String generateDefeatMessage() {; + String message = Forge.getLocalizer().getMessage("lblYouDied", player().getName()); + if (player().isHardorInsaneDifficulty()) { + ItemData itemData = player().getRandomEquippedArmor(); + if (itemData != null) { + itemData.isCracked = true; + player().equip(itemData); //unequip... + InventoryScene.instance().clearItemDescription(); + message += "\n{GRADIENT=RED;GRAY;1;1}" + itemData.name + " {ENDGRADIENT}" + Forge.getLocalizer().getMessage("lblCracked"); + } + } + return message; + } } diff --git a/forge-gui-mobile/src/forge/adventure/util/Reward.java b/forge-gui-mobile/src/forge/adventure/util/Reward.java index 105081a7db6..1c94fd9bc33 100644 --- a/forge-gui-mobile/src/forge/adventure/util/Reward.java +++ b/forge-gui-mobile/src/forge/adventure/util/Reward.java @@ -16,48 +16,81 @@ public class Reward { Shards, CardPack } + Type type; PaperCard card; ItemData item; Deck deck; - boolean isNoSell; + boolean isNoSell, isAutoSell; private final int count; public Reward(ItemData item) { - type = Type.Item; + type = Type.Item; this.item = item; - count = 1; + count = 1; } + public Reward(int count) { - type = Type.Gold; + type = Type.Gold; this.count = count; } + public Reward(PaperCard card) { - this(card,false); + this(card, false); } + public Reward(PaperCard card, boolean isNoSell) { - type = Type.Card; + type = Type.Card; this.card = card; - count = 0; + count = 0; this.isNoSell = isNoSell; } + public Reward(Type type, int count) { - this.type = type; + this.type = type; this.count = count; } + public Reward(Deck deck) { this(deck, false); } + public Reward(Deck deck, boolean isNoSell) { - type = Type.CardPack; + type = Type.CardPack; this.deck = deck; - count = 0; + count = 0; this.isNoSell = isNoSell; } - public PaperCard getCard() { return card; } - public ItemData getItem() { return item; } - public Deck getDeck() { return deck; } - public Type getType() { return type; } - public int getCount() { return count; } - public boolean isNoSell() { return isNoSell; } + + public PaperCard getCard() { + return card; + } + + public ItemData getItem() { + return item; + } + + public Deck getDeck() { + return deck; + } + + public Type getType() { + return type; + } + + public int getCount() { + return count; + } + + public boolean isNoSell() { + return isNoSell; + } + + public boolean isAutoSell() { + return isAutoSell; + } + + public void setAutoSell(boolean val) { + isAutoSell = val; + } } diff --git a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java index dccdf742a5e..579e2ee6da2 100644 --- a/forge-gui-mobile/src/forge/adventure/util/RewardActor.java +++ b/forge-gui-mobile/src/forge/adventure/util/RewardActor.java @@ -59,6 +59,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb ImageToolTip tooltip; HoldTooltip holdTooltip; Reward reward; + public TextraButton autoSell; ShaderProgram shaderGrayscale = Forge.getGraphics().getShaderGrayscale(); ShaderProgram shaderRoundRect = Forge.getGraphics().getShaderRoundedRect(); @@ -77,7 +78,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb private boolean hover, hasbackface; boolean loaded = true; boolean alternate = false, shown = false; - boolean isRewardShop, showOverlay; + boolean isRewardShop, showOverlay, isLoot; TextraLabel overlayLabel; public int renderedCount = 0; //Counter for cards that require rendering a preview. @@ -181,12 +182,25 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb this.flipOnClick = flippable; this.reward = reward; this.isRewardShop = RewardScene.Type.Shop.equals(type); + this.isLoot = RewardScene.Type.Loot.equals(type); this.showOverlay = showOverlay; if (backTexture == null) { backTexture = FSkin.getSleeves().get(0); } switch (reward.type) { case Card: { + if (!reward.isNoSell) { + autoSell = Controls.newTextButton("[%85][GRAY]\uFF04"); + float scale = autoSell.getWidth(); + autoSell.setSize(scale, scale*1.2f); + autoSell.addListener(new ClickListener() { + public void clicked(InputEvent event, float x, float y) { + reward.setAutoSell(!reward.isAutoSell()); + String c = reward.isAutoSell() ? "[%85][GREEN]" : "[%85][GRAY]"; + autoSell.setText(c+"\uFF04"); + } + }); + } hasbackface = reward.getCard().hasBackFace(); if (ImageCache.imageKeyFileExists(reward.getCard().getImageKey(false)) && !Forge.enableUIMask.equals("Art")) { int count = 0; @@ -709,6 +723,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb } catch (Exception e) { } } + if (autoSell != null) + autoSell.remove(); } public void flip() { @@ -717,6 +733,11 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb clicked = true; flipProcess = 0; SoundSystem.instance.play(SoundEffectType.FlipCard, false); + if (isLoot && autoSell != null) { + autoSell.setPosition(this.getX(), this.getY()); + getStage().addActor(autoSell); + autoSell.setVisible(false); + } } public void sold() { @@ -745,6 +766,8 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb addListener(tooltip); } } + if (autoSell != null && !autoSell.isVisible() && flipProcess == 1) + autoSell.setVisible(true); // flipProcess=(float)Gdx.input.getX()/ (float)Gdx.graphics.getWidth(); } diff --git a/forge-gui-mobile/src/forge/adventure/world/WorldSaveHeader.java b/forge-gui-mobile/src/forge/adventure/world/WorldSaveHeader.java index be6ef762410..1f214b702c6 100644 --- a/forge-gui-mobile/src/forge/adventure/world/WorldSaveHeader.java +++ b/forge-gui-mobile/src/forge/adventure/world/WorldSaveHeader.java @@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.utils.Disposable; +import forge.adventure.util.Config; import forge.util.BlurUtils; import forge.Forge; import forge.Graphics; @@ -63,7 +64,7 @@ public class WorldSaveHeader implements java.io.Serializable, Disposable { Pixmap pixmap = Pixmap.createFromFrameBuffer(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); if (Forge.lastPreview != null) Forge.lastPreview.dispose(); - Pixmap blurred = BlurUtils.blur(pixmap, 4, 2, false, true); + Pixmap blurred = BlurUtils.blur(pixmap, 4, 2, false, Config.instance().getBlurDivisor()); Forge.lastPreview = new Texture(blurred); Pixmap scaled = new Pixmap(WorldSaveHeader.previewImageWidth, (int) (WorldSaveHeader.previewImageWidth / (Scene.getIntendedWidth() / (float) Scene.getIntendedHeight())), Pixmap.Format.RGBA8888); scaled.drawPixmap(pixmap, diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index 91a0d116e70..b76cefdc408 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -670,12 +670,13 @@ public class CardImageRenderer { CardView cv = card.getBackup(); if (cv == null || isFaceDown) cv = card; - text = cv.getText(cv.getState(true), needTranslation ? CardTranslation.getTranslationTexts(cv.getName(), "") : null); + CardStateView csv = cv.getState(true); + text = cv.getText(csv, needTranslation ? CardTranslation.getTranslationTexts(csv) : null); } else { text = !card.isSplitCard() ? - card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state.getName(), "") : null) : - card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null); + card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state) : null) : + card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState(), card.getRightSplitState()) : null); } } else { if (noText) @@ -684,12 +685,13 @@ public class CardImageRenderer { CardView cv = card.getBackup(); if (cv == null || isFaceDown) cv = card; - text = cv.getText(cv.getState(false), needTranslation ? CardTranslation.getTranslationTexts(cv.getName(), "") : null); + CardStateView csv = cv.getState(false); + text = cv.getText(csv, needTranslation ? CardTranslation.getTranslationTexts(csv) : null); } else { text = !card.isSplitCard() ? - card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state.getName(), "") : null) : - card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null); + card.getText(state, needTranslation ? state == null ? null : CardTranslation.getTranslationTexts(state) : null) : + card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState(), card.getRightSplitState()) : null); } } if (StringUtils.isEmpty(text)) { diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index 8917ff5488f..435d6375790 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -10,6 +10,7 @@ import forge.Forge; import forge.Forge.KeyInputAdapter; import forge.Graphics; import forge.ImageKeys; +import forge.adventure.scene.ShopScene; import forge.assets.*; import forge.assets.FSkinColor.Colors; import forge.card.*; @@ -965,6 +966,7 @@ public class ImageView extends ItemView { private class ItemInfo extends FDisplayObject implements Entry { private final T item; + private Integer cardPrice; private final Group group; private int index; private CardStackPosition pos; @@ -996,6 +998,17 @@ public class ImageView extends ItemView { return 1; } + private void drawCardLabel(Graphics g, String message, Color bgColor, float x, float y, float w, float h) { + FSkinFont skinFont = FSkinFont.forHeight(w / 7); + float fontheight = skinFont.getLineHeight(); + float ymod = h / 2 - fontheight / 2; + float oldAlpha = g.getfloatAlphaComposite(); + g.setAlphaComposite(0.4f); + g.fillRect(bgColor, x, y + ymod, w, fontheight); + g.setAlphaComposite(oldAlpha); + g.drawText(message, skinFont, Color.WHITE, x, y, w, h, false, Align.center, true); + } + @Override public void draw(Graphics g) { final float x = getLeft() - group.getScrollLeft(); @@ -1043,6 +1056,20 @@ public class ImageView extends ItemView { String value = String.valueOf(draftRank); g.drawText(value, FSkinFont.forHeight(rankSize / 4), Color.WHITE, x, y, w, h, true, Align.center, true); } + + if (Forge.isMobileAdventureMode) { + if (Forge.getCurrentScene() instanceof ShopScene) { + if (cardPrice == null) + cardPrice = ((ShopScene) Forge.getCurrentScene()).getCardPrice((PaperCard) item); + drawCardLabel(g, "$" + cardPrice, Color.GOLD, x, y ,w ,h); + } /*else if (Forge.getCurrentScene() instanceof DeckEditScene) { + if (((DeckEditScene) Forge.getCurrentScene()).isAutoSell((PaperCard) item)) { + drawCardLabel(g, Forge.getLocalizer().getMessage("lblAutoSell"), Color.GREEN, x, y, w, h); + } else if (((DeckEditScene) Forge.getCurrentScene()).isNoSell((PaperCard) item)) { + drawCardLabel(g, Forge.getLocalizer().getMessage("lblNoSell"), Color.RED, x, y, w, h); + } + }*///TODO FIX Distinction + } } else if (item instanceof ConquestCommander) { CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos); } else if (deckSelectMode) { diff --git a/forge-gui-mobile/src/forge/screens/TransitionScreen.java b/forge-gui-mobile/src/forge/screens/TransitionScreen.java index d684bb9d2b5..177cdc5b3d7 100644 --- a/forge-gui-mobile/src/forge/screens/TransitionScreen.java +++ b/forge-gui-mobile/src/forge/screens/TransitionScreen.java @@ -31,13 +31,17 @@ public class TransitionScreen extends FContainer { Texture vsTexture; String enemyAtlasPath, playerAvatarName, enemyAvatarName; private String message = "", playerRecord = "", enemyRecord = ""; - boolean matchTransition, isloading, isIntro, isFadeMusic, isArenaScene; + boolean matchTransition, isloading, isIntro, isFadeMusic, isArenaScene, isAlternate; GlyphLayout layout; public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading) { this(proc, screen, enterMatch, loading, false, false); } + public TransitionScreen(Runnable proc, TextureRegion screen, String message) {//simple for custom transition + this(proc, screen, true, false, false, false, false, message, null, "", "", "", "", ""); + } + public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, String loadingMessage) { this(proc, screen, enterMatch, loading, false, false, loadingMessage, null, "", "", "", "", ""); } @@ -51,6 +55,9 @@ public class TransitionScreen extends FContainer { } public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic, String loadingMessage, TextureRegion player, String enemyAtlas, String playerName, String enemyName, String playerRecord, String enemyRecord) { + this(proc, screen, false, enterMatch, loading, intro, fadeMusic, loadingMessage, player, enemyAtlas, playerName, enemyName, playerRecord, enemyRecord); + } + public TransitionScreen(Runnable proc, TextureRegion screen, boolean alternate, boolean enterMatch, boolean loading, boolean intro, boolean fadeMusic, String loadingMessage, TextureRegion player, String enemyAtlas, String playerName, String enemyName, String playerRecord, String enemyRecord) { progressBar = new FProgressBar(); progressBar.setMaximum(100); progressBar.setPercentMode(true); @@ -62,6 +69,7 @@ public class TransitionScreen extends FContainer { isloading = loading; isIntro = intro; isFadeMusic = fadeMusic; + isAlternate = alternate; message = loadingMessage; this.playerRecord = playerRecord; this.enemyRecord = enemyRecord; @@ -99,7 +107,7 @@ public class TransitionScreen extends FContainer { } private class BGAnimation extends ForgeAnimation { - float DURATION = isArenaScene ? 1.2f : 0.6f; + float DURATION = isArenaScene || isAlternate ? 1.2f : 0.6f; private float progress = 0; TextureRegion enemyAvatar; @@ -119,7 +127,12 @@ public class TransitionScreen extends FContainer { e.printStackTrace(); } } - if (isloading) { + if (isAlternate) { + g.fillRect(Color.BLACK, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); + if (textureRegion != null) { + g.drawPortalFade(textureRegion, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight(), Math.min(percentage, 1f), true); + } + } else if (isloading) { g.fillRect(Color.BLACK, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); FSkinTexture bgTexture = Forge.isMobileAdventureMode ? FSkinTexture.ADV_BG_TEXTURE : FSkinTexture.BG_TEXTURE; if (bgTexture != null) { diff --git a/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java b/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java index 10178690641..eb0c42edec6 100644 --- a/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java +++ b/forge-gui-mobile/src/forge/toolbox/FGestureAdapter.java @@ -167,6 +167,11 @@ public abstract class FGestureAdapter extends InputAdapter { return false; } + @Override + public boolean touchCancelled(int x, int y, int pointer, int button) { + return touchUp((float)x, (float)y, pointer, button); + } + @Override public boolean touchUp(int x, int y, int pointer, int button) { return touchUp((float)x, (float)y, pointer, button); diff --git a/forge-gui-mobile/src/forge/util/BlurUtils.java b/forge-gui-mobile/src/forge/util/BlurUtils.java index ea9f303aab4..732995dcfed 100644 --- a/forge-gui-mobile/src/forge/util/BlurUtils.java +++ b/forge-gui-mobile/src/forge/util/BlurUtils.java @@ -270,12 +270,12 @@ public class BlurUtils { pixmap.getWidth(), pixmap.getHeight(), radius, iterations, disposePixmap); } - public static Pixmap blur(Pixmap pixmap, int radius, int iterations, boolean disposePixmap, boolean crop) { + public static Pixmap blur(Pixmap pixmap, int radius, int iterations, boolean disposePixmap, int div) { int x = (int)(pixmap.getWidth()*0.35f); int y = (int)(pixmap.getHeight()*0.35f); int width = pixmap.getWidth()-x; int height = pixmap.getHeight()-y; - return blur(pixmap, x/2, y/2, width, height, 0, 0, width/4, height/4, radius, iterations, disposePixmap); + return blur(pixmap, x/2, y/2, width, height, 0, 0, width/div, height/div, radius, iterations, disposePixmap); } /** diff --git a/forge-gui/res/adventure/common/custom_cards/fifth_head_of_the_hydra.txt b/forge-gui/res/adventure/common/custom_cards/fifth_head_of_the_hydra.txt index c7f82c9eadb..4428e0a4fd2 100644 --- a/forge-gui/res/adventure/common/custom_cards/fifth_head_of_the_hydra.txt +++ b/forge-gui/res/adventure/common/custom_cards/fifth_head_of_the_hydra.txt @@ -4,8 +4,8 @@ Types:Creature Hydra Colors:green,blue PT:1/4 K:Defender -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. T:Mode$ Phase | Phase$ End Of Turn | ValidPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ At the beginning of each opponents end step, that player exiles the top 4 cards from their library SVar:TrigDig:DB$ Dig | Defined$ ActivePlayer | DigNum$ 4 | DestinationZone$ Exile | ChangeNum$ All R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | ValidCard$ Card.Self | ReplaceWith$ Exile | Description$ If CARDNAME would leave the battlefield, instead exile it with three time counters on it. It gains suspend. diff --git a/forge-gui/res/adventure/common/custom_cards/first_head_of_the_hydra.txt b/forge-gui/res/adventure/common/custom_cards/first_head_of_the_hydra.txt index dadc9769dd1..146d4249956 100644 --- a/forge-gui/res/adventure/common/custom_cards/first_head_of_the_hydra.txt +++ b/forge-gui/res/adventure/common/custom_cards/first_head_of_the_hydra.txt @@ -4,8 +4,8 @@ Types:Creature Hydra Colors:green,blue PT:1/4 K:Defender -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. T:Mode$ Phase | Phase$ Draw | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of your draw step, draw an additional card. SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ You R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | ValidCard$ Card.Self | ReplaceWith$ Exile | Description$ If CARDNAME would leave the battlefield, instead exile it with three time counters on it. It gains suspend. diff --git a/forge-gui/res/adventure/common/custom_cards/fourth_head_of_the_hydra.txt b/forge-gui/res/adventure/common/custom_cards/fourth_head_of_the_hydra.txt index a636a8bd019..67634449189 100644 --- a/forge-gui/res/adventure/common/custom_cards/fourth_head_of_the_hydra.txt +++ b/forge-gui/res/adventure/common/custom_cards/fourth_head_of_the_hydra.txt @@ -4,8 +4,8 @@ Types:Creature Hydra Colors:green,blue PT:1/4 K:Defender -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ At the beginning of your upkeep, you gain 2 life and your opponents lose 2 life. SVar:TrigDrain:DB$ LoseLife | Defined$ Opponent | LifeAmount$ 2 | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 diff --git a/forge-gui/res/adventure/common/custom_cards/second_head_of_the_hydra.txt b/forge-gui/res/adventure/common/custom_cards/second_head_of_the_hydra.txt index 2ef356f3072..82de9316375 100644 --- a/forge-gui/res/adventure/common/custom_cards/second_head_of_the_hydra.txt +++ b/forge-gui/res/adventure/common/custom_cards/second_head_of_the_hydra.txt @@ -4,8 +4,8 @@ Types:Creature Hydra Colors:green,blue PT:1/4 K:Defender -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. S:Mode$ CantBeCast | ValidCard$ Card.nonCreature | Caster$ Opponent | NumLimitEachTurn$ 1 | Description$ Your opponents can't cast more than one noncreature spell each turn. R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | ValidCard$ Card.Self | ReplaceWith$ Exile | Description$ If CARDNAME would leave the battlefield, instead exile it with three time counters on it. It gains suspend. SVar:Exile:DB$ ChangeZone | Hidden$ True | WithCountersType$ TIME | WithCountersAmount$ 3 | Origin$ All | Destination$ Exile | Defined$ ReplacedCard | SubAbility$ GiveSuspend diff --git a/forge-gui/res/adventure/common/custom_cards/sixth_head_of_the_hydra.txt b/forge-gui/res/adventure/common/custom_cards/sixth_head_of_the_hydra.txt index 344de5c5636..4e951c976f0 100644 --- a/forge-gui/res/adventure/common/custom_cards/sixth_head_of_the_hydra.txt +++ b/forge-gui/res/adventure/common/custom_cards/sixth_head_of_the_hydra.txt @@ -4,8 +4,8 @@ Types:Creature Hydra Colors:green,blue PT:1/4 K:Defender -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. S:Mode$ AttackRestrict | MaxAttackers$ 6 | ValidDefender$ You | Description$ No more than six creatures can attack you each combat. R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | ValidCard$ Card.Self | ReplaceWith$ Exile | Description$ If CARDNAME would leave the battlefield, instead exile it with three time counters on it. It gains suspend. SVar:Exile:DB$ ChangeZone | Hidden$ True | WithCountersType$ TIME | WithCountersAmount$ 3 | Origin$ All | Destination$ Exile | Defined$ ReplacedCard | SubAbility$ GiveSuspend diff --git a/forge-gui/res/adventure/common/custom_cards/sorins_boss_effect.txt b/forge-gui/res/adventure/common/custom_cards/sorins_boss_effect.txt index c9e425695f8..faed4930aaf 100644 --- a/forge-gui/res/adventure/common/custom_cards/sorins_boss_effect.txt +++ b/forge-gui/res/adventure/common/custom_cards/sorins_boss_effect.txt @@ -3,10 +3,11 @@ ManaCost:no cost Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | CheckSVar$ YourLife | SVarCompare$ GE40 | Execute$ TrigSeek | TriggerDescription$ As long as Sorin's life total is 40 or more, Sorin seeks two nonland cards every upkeep and can't lose the game and his opponents can't win the game. SVar:TrigSeek:DB$ Seek | Num$ 2 | Type$ Card.nonLand -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | CheckSVar$ YourLife | EffectZone$ Command | SVarCompare$ GE40 | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | EffectZone$ Command | CheckSVar$ YourLife | Secondary$ True | SVarCompare$ GE40 | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Command | ValidPlayer$ You | Layer$ CantHappen | CheckSVar$ YourLife | SVarCompare$ GE40 | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | EffectZone$ Command | CheckSVar$ YourLife | Secondary$ True | SVarCompare$ GE40 | Description$ You can't lose the game and your opponents can't win the game. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | CheckSVar$ YourLifeCompare | SVarCompare$ EQ2 | Execute$ TrigConjure | TriggerDescription$ As long as Sorin's life total is between 20 and 40, at Sorin's upkeep, conjure a card from Sorin's Spellbook into exile with 2 time counters on it, it gains suspend. -SVar:TrigConjure:DB$ MakeCard | Conjure$ True | AtRandom$ True | Spellbook$ Sorin; Grim Nemesis,Sorin; Imperious Bloodlord,Sorin; Lord of Innistrad,Sorin Markov,Sorin; Solemn Visitor,Sorin the Mirthless,Sorin; Vampire Lord,Sorin; Vengeful Bloodlord,Timothar; Baron of Bats,Olivia Voldaren,Patriarch's Bidding,Licia; Sanguine Tribune,Astarion; the Decadent,Strefan; Maurer Progenitor,Evelyn; the Covetous,Anje; Maid of Dishonor,Edgar Markov | WithCounters$ TIME | WithCountersAmount$ 2 | Zone$ Exile | RememberMade$ True | SubAbility$ GiveSuspend +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | AtRandom$ True | Spellbook$ Sorin; Grim Nemesis,Sorin; Imperious Bloodlord,Sorin; Lord of Innistrad,Sorin Markov,Sorin; Solemn Visitor,Sorin the Mirthless,Sorin; Vampire Lord,Sorin; Vengeful Bloodlord,Timothar; Baron of Bats,Olivia Voldaren,Patriarch's Bidding,Licia; Sanguine Tribune,Astarion; the Decadent,Strefan; Maurer Progenitor,Evelyn; the Covetous,Anje; Maid of Dishonor,Edgar Markov,Swords to Plowshares,Cruel Celebrant,Olivia's Wrath,Markov Baron,Champion of Dusk,Vein Ripper,Anguished Unmaking,Mortify,Void Rend,Terminate,Despark,Bedevil,Utter End,Ruinous Ultimatum,Sign in Blood,Reanimate,Victimize | Zone$ Exile | RememberMade$ True | SubAbility$ DBPutCounter +SVar:DBPutCounter:DB$ PutCounter | Defined$ Remembered | CounterNum$ 3 | CounterType$ TIME | SubAbility$ GiveSuspend SVar:GiveSuspend:DB$ Pump | Defined$ Remembered | KW$ Suspend | PumpZone$ Exile | Duration$ Permanent | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True S:Mode$ Continuous | EffectZone$ Command | Affected$ Vampire.YouCtrl | AddPower$ 2 | AddToughness$ 2 | CheckSVar$ YourLife | SVarCompare$ LT20 | AddKeyword$ Lifelink | Description$ As long as Sorin's life total is lower than 20, Sorin's Vampires get +2/+2 and have lifelink. diff --git a/forge-gui/res/adventure/common/custom_cards/third_head_of_the_hydra.txt b/forge-gui/res/adventure/common/custom_cards/third_head_of_the_hydra.txt index 4a4167b85d6..aac29c864a8 100644 --- a/forge-gui/res/adventure/common/custom_cards/third_head_of_the_hydra.txt +++ b/forge-gui/res/adventure/common/custom_cards/third_head_of_the_hydra.txt @@ -4,8 +4,8 @@ Types:Creature Hydra PT:1/4 Colors:green,blue K:Defender -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. K:ETBReplacement:Other:AddExtraCounter:Mandatory:Battlefield:Hydra.Other+YouCtrl SVar:AddExtraCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Other Hydras you control enter with two extra +1/+1 counters on them. R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | ValidCard$ Card.Self | ReplaceWith$ Exile | Description$ If CARDNAME would leave the battlefield, instead exile it with three time counters on it. It gains suspend. diff --git a/forge-gui/res/adventure/common/ui/arena_bg.png b/forge-gui/res/adventure/common/ui/arena_bg.png index 98272501e2f..90cf3c0b9aa 100644 Binary files a/forge-gui/res/adventure/common/ui/arena_bg.png and b/forge-gui/res/adventure/common/ui/arena_bg.png differ diff --git a/forge-gui/res/adventure/common/ui/arena_bg_portrait.png b/forge-gui/res/adventure/common/ui/arena_bg_portrait.png index abaaf7d32dc..15fd5c07060 100644 Binary files a/forge-gui/res/adventure/common/ui/arena_bg_portrait.png and b/forge-gui/res/adventure/common/ui/arena_bg_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/buyshards.png b/forge-gui/res/adventure/common/ui/buyshards.png index 8bafd8f2c7b..959d112dde4 100644 Binary files a/forge-gui/res/adventure/common/ui/buyshards.png and b/forge-gui/res/adventure/common/ui/buyshards.png differ diff --git a/forge-gui/res/adventure/common/ui/defeat.png b/forge-gui/res/adventure/common/ui/defeat.png new file mode 100644 index 00000000000..59909296d9a Binary files /dev/null and b/forge-gui/res/adventure/common/ui/defeat.png differ diff --git a/forge-gui/res/adventure/common/ui/heal.png b/forge-gui/res/adventure/common/ui/heal.png index 671e9755de2..9c0d776e48d 100644 Binary files a/forge-gui/res/adventure/common/ui/heal.png and b/forge-gui/res/adventure/common/ui/heal.png differ diff --git a/forge-gui/res/adventure/common/ui/leave.png b/forge-gui/res/adventure/common/ui/leave.png index ed74211e5ba..806f3b688ba 100644 Binary files a/forge-gui/res/adventure/common/ui/leave.png and b/forge-gui/res/adventure/common/ui/leave.png differ diff --git a/forge-gui/res/adventure/common/ui/market.png b/forge-gui/res/adventure/common/ui/market.png index 0fde64347d9..1cbdd77aafa 100644 Binary files a/forge-gui/res/adventure/common/ui/market.png and b/forge-gui/res/adventure/common/ui/market.png differ diff --git a/forge-gui/res/adventure/common/ui/market_portrait.png b/forge-gui/res/adventure/common/ui/market_portrait.png index 5f8f00651ae..29a6422f2fd 100644 Binary files a/forge-gui/res/adventure/common/ui/market_portrait.png and b/forge-gui/res/adventure/common/ui/market_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/reward.png b/forge-gui/res/adventure/common/ui/reward.png index ce2b4033464..15adb193294 100644 Binary files a/forge-gui/res/adventure/common/ui/reward.png and b/forge-gui/res/adventure/common/ui/reward.png differ diff --git a/forge-gui/res/adventure/common/ui/reward_portrait.png b/forge-gui/res/adventure/common/ui/reward_portrait.png index d49f55dfcdb..df64c1564ca 100644 Binary files a/forge-gui/res/adventure/common/ui/reward_portrait.png and b/forge-gui/res/adventure/common/ui/reward_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/sell.png b/forge-gui/res/adventure/common/ui/sell.png index b9c0b906a11..12de01a5b12 100644 Binary files a/forge-gui/res/adventure/common/ui/sell.png and b/forge-gui/res/adventure/common/ui/sell.png differ diff --git a/forge-gui/res/adventure/common/ui/shardalley.png b/forge-gui/res/adventure/common/ui/shardalley.png new file mode 100644 index 00000000000..bbc9fe55d4c Binary files /dev/null and b/forge-gui/res/adventure/common/ui/shardalley.png differ diff --git a/forge-gui/res/adventure/common/ui/shardalley_portrait.png b/forge-gui/res/adventure/common/ui/shardalley_portrait.png new file mode 100644 index 00000000000..5aa69207a6a Binary files /dev/null and b/forge-gui/res/adventure/common/ui/shardalley_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/shardtrader.json b/forge-gui/res/adventure/common/ui/shardtrader.json index 81f18a7420d..5f9dcabbc5d 100644 --- a/forge-gui/res/adventure/common/ui/shardtrader.json +++ b/forge-gui/res/adventure/common/ui/shardtrader.json @@ -5,7 +5,7 @@ "elements": [ { "type": "Image", - "image": "ui/market.png", + "image": "ui/shardalley.png", "width": 480, "height": 270 }, diff --git a/forge-gui/res/adventure/common/ui/shardtrader_portrait.json b/forge-gui/res/adventure/common/ui/shardtrader_portrait.json index ee9464962d4..f839583c24c 100644 --- a/forge-gui/res/adventure/common/ui/shardtrader_portrait.json +++ b/forge-gui/res/adventure/common/ui/shardtrader_portrait.json @@ -5,7 +5,7 @@ "elements": [ { "type": "Image", - "image": "ui/market_portrait.png", + "image": "ui/shardalley_portrait.png", "width": 270, "height": 480 }, diff --git a/forge-gui/res/adventure/common/ui/spellsmith.png b/forge-gui/res/adventure/common/ui/spellsmith.png index ed25d43b861..c5b3b207067 100644 Binary files a/forge-gui/res/adventure/common/ui/spellsmith.png and b/forge-gui/res/adventure/common/ui/spellsmith.png differ diff --git a/forge-gui/res/adventure/common/ui/spellsmith_portrait.png b/forge-gui/res/adventure/common/ui/spellsmith_portrait.png index 4797091e012..f5cdf8a2bdd 100644 Binary files a/forge-gui/res/adventure/common/ui/spellsmith_portrait.png and b/forge-gui/res/adventure/common/ui/spellsmith_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/tavern.png b/forge-gui/res/adventure/common/ui/tavern.png index 399a47d7aa1..0fb99236b08 100644 Binary files a/forge-gui/res/adventure/common/ui/tavern.png and b/forge-gui/res/adventure/common/ui/tavern.png differ diff --git a/forge-gui/res/adventure/common/ui/tavern_portrait.png b/forge-gui/res/adventure/common/ui/tavern_portrait.png index b9b5feba16f..9d19b4ef714 100644 Binary files a/forge-gui/res/adventure/common/ui/tavern_portrait.png and b/forge-gui/res/adventure/common/ui/tavern_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/tavernevent.png b/forge-gui/res/adventure/common/ui/tavernevent.png index 4f85cafed4a..e1860502714 100644 Binary files a/forge-gui/res/adventure/common/ui/tavernevent.png and b/forge-gui/res/adventure/common/ui/tavernevent.png differ diff --git a/forge-gui/res/adventure/common/ui/title_bg.png b/forge-gui/res/adventure/common/ui/title_bg.png index f84a2ee9872..63ea7718d88 100644 Binary files a/forge-gui/res/adventure/common/ui/title_bg.png and b/forge-gui/res/adventure/common/ui/title_bg.png differ diff --git a/forge-gui/res/adventure/common/ui/title_bg_portrait.png b/forge-gui/res/adventure/common/ui/title_bg_portrait.png index 26d1eb82189..62b997da387 100644 Binary files a/forge-gui/res/adventure/common/ui/title_bg_portrait.png and b/forge-gui/res/adventure/common/ui/title_bg_portrait.png differ diff --git a/forge-gui/res/adventure/common/ui/vs.png b/forge-gui/res/adventure/common/ui/vs.png index baf89cf61c9..d17b26c1c5b 100644 Binary files a/forge-gui/res/adventure/common/ui/vs.png and b/forge-gui/res/adventure/common/ui/vs.png differ diff --git a/forge-gui/res/cardsfolder/a/absorb_identity.txt b/forge-gui/res/cardsfolder/a/absorb_identity.txt index 9c7d9983da7..07953aa2cc6 100644 --- a/forge-gui/res/cardsfolder/a/absorb_identity.txt +++ b/forge-gui/res/cardsfolder/a/absorb_identity.txt @@ -2,8 +2,7 @@ Name:Absorb Identity ManaCost:1 U Types:Instant A:SP$ ChangeZone | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Hand | RememberLKI$ True | SubAbility$ CloneArmy | SpellDescription$ Return target creature to its owner's hand. You may have Shapeshifters you control become copies of that creature until end of turn. -SVar:CloneArmy:DB$ RepeatEach | UseImprinted$ True | RepeatCards$ Shapeshifter.YouCtrl | RepeatSubAbility$ DBCopy | SubAbility$ DBCleanup | Optional$ True | OptionPrompt$ Do you want Shapeshifters you control to become copies of that creature until end of turn? -SVar:DBCopy:DB$ Clone | Defined$ Remembered | CloneTarget$ Imprinted | Duration$ UntilEndOfTurn +SVar:CloneArmy:DB$ Clone | Defined$ Remembered | CloneTarget$ Valid Shapeshifter.YouCtrl | Duration$ UntilEndOfTurn | SubAbility$ DBCleanup | Optional$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHints:Type$Shapeshifter Oracle:Return target creature to its owner's hand. You may have Shapeshifters you control become copies of that creature until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/abstergo_entertainment.txt b/forge-gui/res/cardsfolder/a/abstergo_entertainment.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/abstergo_entertainment.txt rename to forge-gui/res/cardsfolder/a/abstergo_entertainment.txt diff --git a/forge-gui/res/cardsfolder/a/abyssal_persecutor.txt b/forge-gui/res/cardsfolder/a/abyssal_persecutor.txt index ddb8e9c53d9..c8d1a17a993 100644 --- a/forge-gui/res/cardsfolder/a/abyssal_persecutor.txt +++ b/forge-gui/res/cardsfolder/a/abyssal_persecutor.txt @@ -4,7 +4,7 @@ Types:Creature Demon PT:6/6 K:Flying K:Trample -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't win the game. | Description$ You can't win the game and your opponents can't lose the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't lose the game. | Secondary$ True | Description$ You can't win the game and your opponents can't lose the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't win the game and your opponents can't lose the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't win the game and your opponents can't lose the game. AI:RemoveDeck:All Oracle:Flying, trample\nYou can't win the game and your opponents can't lose the game. diff --git a/forge-gui/res/cardsfolder/a/ace_flockbringer.txt b/forge-gui/res/cardsfolder/a/ace_flockbringer.txt new file mode 100644 index 00000000000..ab7d62f6e22 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/ace_flockbringer.txt @@ -0,0 +1,10 @@ +Name:Ace Flockbringer +ManaCost:1 W U +Types:Creature Bird Scout +PT:3/3 +K:Flying +T:Mode$ SpellCast | ValidCard$ Creature.withoutFlying | ActivationLimit$ 1 | ValidActivatingPlayer$ You | Execute$ TrigConjure | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell without flying, conjure a duplicate of it into your hand. The duplicate perpetually gains flying. This ability triggers only once each turn. +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | DefinedName$ TriggeredCard | Zone$ Hand | RememberMade$ True | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Remembered | PumpZone$ Hand | KW$ Flying | Duration$ Perpetual | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +Oracle:Flying\nWhenever you cast a creature spell without flying, conjure a duplicate of it into your hand. The duplicate perpetually gains flying. This ability triggers only once each turn. diff --git a/forge-gui/res/cardsfolder/upcoming/adewale_breaker_of_chains.txt b/forge-gui/res/cardsfolder/a/adewale_breaker_of_chains.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/adewale_breaker_of_chains.txt rename to forge-gui/res/cardsfolder/a/adewale_breaker_of_chains.txt diff --git a/forge-gui/res/cardsfolder/upcoming/adrestia.txt b/forge-gui/res/cardsfolder/a/adrestia.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/adrestia.txt rename to forge-gui/res/cardsfolder/a/adrestia.txt diff --git a/forge-gui/res/cardsfolder/upcoming/agate_assault.txt b/forge-gui/res/cardsfolder/a/agate_assault.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/agate_assault.txt rename to forge-gui/res/cardsfolder/a/agate_assault.txt diff --git a/forge-gui/res/cardsfolder/upcoming/agate_blade_assassin.txt b/forge-gui/res/cardsfolder/a/agate_blade_assassin.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/agate_blade_assassin.txt rename to forge-gui/res/cardsfolder/a/agate_blade_assassin.txt diff --git a/forge-gui/res/cardsfolder/upcoming/agate_instigator.txt b/forge-gui/res/cardsfolder/a/agate_instigator.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/agate_instigator.txt rename to forge-gui/res/cardsfolder/a/agate_instigator.txt diff --git a/forge-gui/res/cardsfolder/upcoming/alania_divergent_storm.txt b/forge-gui/res/cardsfolder/a/alania_divergent_storm.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/alania_divergent_storm.txt rename to forge-gui/res/cardsfolder/a/alania_divergent_storm.txt diff --git a/forge-gui/res/cardsfolder/upcoming/alanias_pathmaker.txt b/forge-gui/res/cardsfolder/a/alanias_pathmaker.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/alanias_pathmaker.txt rename to forge-gui/res/cardsfolder/a/alanias_pathmaker.txt diff --git a/forge-gui/res/cardsfolder/upcoming/alchemists_talent.txt b/forge-gui/res/cardsfolder/a/alchemists_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/alchemists_talent.txt rename to forge-gui/res/cardsfolder/a/alchemists_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/alexios_deimos_of_kosmos.txt b/forge-gui/res/cardsfolder/a/alexios_deimos_of_kosmos.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/alexios_deimos_of_kosmos.txt rename to forge-gui/res/cardsfolder/a/alexios_deimos_of_kosmos.txt diff --git a/forge-gui/res/cardsfolder/a/amped_raptor.txt b/forge-gui/res/cardsfolder/a/amped_raptor.txt index 2936d04b431..ec8a69a86b4 100644 --- a/forge-gui/res/cardsfolder/a/amped_raptor.txt +++ b/forge-gui/res/cardsfolder/a/amped_raptor.txt @@ -6,6 +6,6 @@ K:First Strike T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEnergy | TriggerDescription$ When CARDNAME enters, you get {E}{E} (two energy counters). Then if you cast it from your hand, exile cards from the top of your library until you exile a nonland card. You may cast that card by paying an amount of {E} equal to its mana value rather than paying its mana cost. SVar:TrigEnergy:DB$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 2 | SubAbility$ DBDigUntil SVar:DBDigUntil:DB$ DigUntil | ConditionDefined$ TriggeredCard | ConditionPresent$ Card.wasCastFromYourHandByYou | Valid$ Card.nonLand | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | SubAbility$ DBPlay -SVar:DBPlay:DB$ Play | Defined$ Remembered | ValidSA$ Spell | PlayCost$ PayEnergy | Optional$ True | SubAbility$ DBChange | SubAbility$ DBCleanup +SVar:DBPlay:DB$ Play | Defined$ Remembered | ValidSA$ Spell | PlayCost$ PayEnergy | Optional$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True Oracle:First strike\nWhen Amped Raptor enters, you get {E}{E} (two energy counters). Then if you cast it from your hand, exile cards from the top of your library until you exile a nonland card. You may cast that card by paying an amount of {E} equal to its mana value rather than paying its mana cost. diff --git a/forge-gui/res/cardsfolder/a/angel_of_serenity.txt b/forge-gui/res/cardsfolder/a/angel_of_serenity.txt index 1c96a606c7d..023de579147 100644 --- a/forge-gui/res/cardsfolder/a/angel_of_serenity.txt +++ b/forge-gui/res/cardsfolder/a/angel_of_serenity.txt @@ -3,7 +3,7 @@ ManaCost:4 W W W Types:Creature Angel PT:5/6 K:Flying -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters, you may exile up to three other target creatures from the battlefield and/or creature cards from graveyards. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME leaves the battlefield, return the exiled cards to their owners' hands. SVar:TrigExile:DB$ ChangeZone | TargetMin$ 0 | TargetMax$ 3 | IsCurse$ True | ValidTgts$ Creature.Other | TgtPrompt$ Choose another target creature | RememberChanged$ True | Origin$ Battlefield,Graveyard | Destination$ Exile SVar:TrigReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Hand | SubAbility$ DBCleanup diff --git a/forge-gui/res/cardsfolder/a/angels_grace.txt b/forge-gui/res/cardsfolder/a/angels_grace.txt index 630ee855288..91b03672649 100644 --- a/forge-gui/res/cardsfolder/a/angels_grace.txt +++ b/forge-gui/res/cardsfolder/a/angels_grace.txt @@ -2,8 +2,9 @@ Name:Angel's Grace ManaCost:W Types:Instant K:Split second -A:SP$ Effect | StaticAbilities$ STCantLose | ReplacementEffects$ SelflessDamage | AILogic$ Fog | SpellDescription$ You can't lose the game this turn and your opponents can't win the game this turn. Until end of turn, damage that would reduce your life total to less than 1 reduces it to 1 instead. -SVar:STCantLose:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. & Your opponents can't win the game. | Description$ You can't lose the game. Your opponents can't win the game. +A:SP$ Effect | ReplacementEffects$ DBYouCantLose,DBOppCantWin,SelflessDamage | AILogic$ Fog | SpellDescription$ You can't lose the game this turn and your opponents can't win the game this turn. Until end of turn, damage that would reduce your life total to less than 1 reduces it to 1 instead. +SVar:DBYouCantLose:Event$ GameLoss | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +SVar:DBOppCantWin:Event$ GameWin | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. SVar:SelflessDamage:Event$ LifeReduced | ValidPlayer$ You.lifeGE1 | Result$ LT1 | IsDamage$ True | ReplaceWith$ ReduceLoss | Description$ Until end of turn, damage that would reduce your life total to less than 1 reduces it to 1 instead. SVar:ReduceLoss:DB$ ReplaceEffect | VarName$ Amount | VarValue$ X SVar:X:ReplaceCount$Amount/LimitMax.Difference diff --git a/forge-gui/res/cardsfolder/upcoming/anthem_of_champions.txt b/forge-gui/res/cardsfolder/a/anthem_of_champions.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/anthem_of_champions.txt rename to forge-gui/res/cardsfolder/a/anthem_of_champions.txt diff --git a/forge-gui/res/cardsfolder/upcoming/apple_of_eden_isu_relic.txt b/forge-gui/res/cardsfolder/a/apple_of_eden_isu_relic.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/apple_of_eden_isu_relic.txt rename to forge-gui/res/cardsfolder/a/apple_of_eden_isu_relic.txt diff --git a/forge-gui/res/cardsfolder/upcoming/arbaaz_mir.txt b/forge-gui/res/cardsfolder/a/arbaaz_mir.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/arbaaz_mir.txt rename to forge-gui/res/cardsfolder/a/arbaaz_mir.txt diff --git a/forge-gui/res/cardsfolder/a/archival_whorl.txt b/forge-gui/res/cardsfolder/a/archival_whorl.txt new file mode 100644 index 00000000000..7067ceb5867 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/archival_whorl.txt @@ -0,0 +1,10 @@ +Name:Archival Whorl +ManaCost:3 U U +Types:Sorcery +K:Gift +SVar:GiftAbility:DB$ MakeCard | Name$ Rhystic Study | Defined$ Promised | Zone$ Battlefield | GiftDescription$ a Rhystic Study +A:SP$ ChangeZoneAll | Origin$ Graveyard,Hand | Destination$ Library | ChangeType$ Card.YouOwn | Shuffle$ True | SubAbility$ DBDraw | SpellDescription$ Shuffle your hand and graveyard into your library, then draw seven cards. If the gift wasn't promised, each other player also shuffles their hand and graveyard into their library, then draws seven cards. +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 7 | SubAbility$ DBChangeZoneAllOpponents +SVar:DBChangeZoneAllOpponents:DB$ ChangeZoneAll | ConditionPresent$ Card.PromisedGift | ConditionCompare$ EQ0 | Origin$ Graveyard,Hand | Destination$ Library | ChangeType$ Card.OwnedBy Player.Other | Shuffle$ True | SubAbility$ DBDrawBis +SVar:DBDrawBis:DB$ Draw | Defined$ Player.Other | ConditionPresent$ Card.PromisedGift | ConditionCompare$ EQ0 | NumCards$ 7 +Oracle:Gift a Rhystic Study\nShuffle your hand and graveyard into your library, then draw seven cards. If the gift wasn't promised, each other player also shuffles their hand and graveyard into their library, then draws seven cards. diff --git a/forge-gui/res/cardsfolder/a/archon_of_coronation.txt b/forge-gui/res/cardsfolder/a/archon_of_coronation.txt index f26376419a4..a21b851b094 100644 --- a/forge-gui/res/cardsfolder/a/archon_of_coronation.txt +++ b/forge-gui/res/cardsfolder/a/archon_of_coronation.txt @@ -5,5 +5,5 @@ PT:5/5 K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMonarch | TriggerDescription$ When CARDNAME enters, you become the monarch. SVar:TrigMonarch:DB$ BecomeMonarch | Defined$ You -S:Mode$ Continuous | Affected$ You | Condition$ Monarch | AddKeyword$ Damage doesn't cause you to lose life. | Description$ As long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.) +R:Event$ LifeReduced | ValidPlayer$ You | IsDamage$ True | Monarch$ True | Layer$ CantHappen | Description$ As long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.) Oracle:Flying\nWhen Archon of Coronation enters, you become the monarch.\nAs long as you're the monarch, damage doesn't cause you to lose life. (When a creature deals combat damage to you, its controller still becomes the monarch.) diff --git a/forge-gui/res/cardsfolder/a/armament_corps.txt b/forge-gui/res/cardsfolder/a/armament_corps.txt index a98a8efd3f4..5d454c9f175 100644 --- a/forge-gui/res/cardsfolder/a/armament_corps.txt +++ b/forge-gui/res/cardsfolder/a/armament_corps.txt @@ -3,7 +3,7 @@ ManaCost:2 W B G Types:Creature Human Soldier PT:4/4 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPutCounter | TriggerDescription$ When CARDNAME enters, distribute two +1/+1 counters among one or two target creatures you control. -SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature to distribute counters to | CounterType$ P1P1 | CounterNum$ 2 | TargetMin$ 1 | TargetMax$ 2 | DividedAsYouChoose$ 2 +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control to distribute counters to | CounterType$ P1P1 | CounterNum$ 2 | TargetMin$ 1 | TargetMax$ 2 | DividedAsYouChoose$ 2 SVar:PlayMain1:TRUE DeckHas:Ability$Counters Oracle:When Armament Corps enters, distribute two +1/+1 counters among one or two target creatures you control. diff --git a/forge-gui/res/cardsfolder/upcoming/arna_kennerud_skycaptain.txt b/forge-gui/res/cardsfolder/a/arna_kennerud_skycaptain.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/arna_kennerud_skycaptain.txt rename to forge-gui/res/cardsfolder/a/arna_kennerud_skycaptain.txt diff --git a/forge-gui/res/cardsfolder/upcoming/arno_dorian.txt b/forge-gui/res/cardsfolder/a/arno_dorian.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/arno_dorian.txt rename to forge-gui/res/cardsfolder/a/arno_dorian.txt diff --git a/forge-gui/res/cardsfolder/upcoming/arthur_marigold_knight.txt b/forge-gui/res/cardsfolder/a/arthur_marigold_knight.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/arthur_marigold_knight.txt rename to forge-gui/res/cardsfolder/a/arthur_marigold_knight.txt diff --git a/forge-gui/res/cardsfolder/upcoming/artists_talent.txt b/forge-gui/res/cardsfolder/a/artists_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/artists_talent.txt rename to forge-gui/res/cardsfolder/a/artists_talent.txt diff --git a/forge-gui/res/cardsfolder/a/ashling_the_extinguisher.txt b/forge-gui/res/cardsfolder/a/ashling_the_extinguisher.txt index bbfd5f55ca0..5630f9e8050 100644 --- a/forge-gui/res/cardsfolder/a/ashling_the_extinguisher.txt +++ b/forge-gui/res/cardsfolder/a/ashling_the_extinguisher.txt @@ -3,6 +3,6 @@ ManaCost:2 B B Types:Legendary Creature Elemental Shaman PT:4/4 T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDestroy | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, choose target creature that player controls. The player sacrifices that creature. -SVar:TrigDestroy:DB$ SacrificeAll | Defined ThisTargeted | ValidTgts$ Creature.ControlledBy TriggeredTarget | TgtPrompt$ Select target creature that player controls +SVar:TrigDestroy:DB$ SacrificeAll | Defined$ Targeted | ValidTgts$ Creature.ControlledBy TriggeredTarget | TgtPrompt$ Select target creature that player controls SVar:MustBeBlocked:True Oracle:Whenever Ashling, the Extinguisher deals combat damage to a player, choose target creature that player controls. The player sacrifices that creature. diff --git a/forge-gui/res/cardsfolder/upcoming/assassin_den.txt b/forge-gui/res/cardsfolder/a/assassin_den.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/assassin_den.txt rename to forge-gui/res/cardsfolder/a/assassin_den.txt diff --git a/forge-gui/res/cardsfolder/upcoming/assassin_gauntlet.txt b/forge-gui/res/cardsfolder/a/assassin_gauntlet.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/assassin_gauntlet.txt rename to forge-gui/res/cardsfolder/a/assassin_gauntlet.txt diff --git a/forge-gui/res/cardsfolder/upcoming/assassin_initiate.txt b/forge-gui/res/cardsfolder/a/assassin_initiate.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/assassin_initiate.txt rename to forge-gui/res/cardsfolder/a/assassin_initiate.txt diff --git a/forge-gui/res/cardsfolder/a/ateoclock.txt b/forge-gui/res/cardsfolder/a/ateoclock.txt new file mode 100644 index 00000000000..793f88e5b83 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/ateoclock.txt @@ -0,0 +1,11 @@ +Name:Ate-o'-Clock +ManaCost:2 G +Types:Instant +K:Replicate:2 G +A:SP$ CopyPermanent | Choices$ Creature.token+YouCtrl | NumCopies$ 1 | Populate$ True | SubAbility$ DBProlif | SpellDescription$ Populate. Proliferate. Investigate. Regenerate target creature. +SVar:DBProlif:DB$ Proliferate | SubAbility$ DBInvestigate +SVar:DBInvestigate:DB$ Investigate | SubAbility$ DBRegen +SVar:DBRegen:DB$ Regenerate | ValidTgts$ Creature | TgtPrompt$ Select target creature +DeckHas:Ability$Proliferate +DeckHints:Ability$Token|Counters +Oracle:Populate. Proliferate. Investigate.\nRegenerate target creature.\nReplicate {2}{G} (When you cast this spell, copy it for each time you paid its replicate cost. You may choose new targets for the copy.) diff --git a/forge-gui/res/cardsfolder/upcoming/auditore_ambush.txt b/forge-gui/res/cardsfolder/a/auditore_ambush.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/auditore_ambush.txt rename to forge-gui/res/cardsfolder/a/auditore_ambush.txt diff --git a/forge-gui/res/cardsfolder/upcoming/aveline_de_grandpre.txt b/forge-gui/res/cardsfolder/a/aveline_de_grandpre.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/aveline_de_grandpre.txt rename to forge-gui/res/cardsfolder/a/aveline_de_grandpre.txt diff --git a/forge-gui/res/cardsfolder/a/awestruck_cygnet.txt b/forge-gui/res/cardsfolder/a/awestruck_cygnet.txt new file mode 100644 index 00000000000..595f61df422 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/awestruck_cygnet.txt @@ -0,0 +1,10 @@ +Name:Awestruck Cygnet +ManaCost:W +Types:Creature Bird Scout +PT:2/1 +K:Starting intensity:0 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.YouCtrl+withFlying | IsPresent$ Card.Self+namedAwestruck Cygnet | TriggerZones$ Battlefield | Execute$ TrigIntensify | TriggerDescription$ Whenever a creature you control with flying enters, if this creature is named Awestruck Cygnet, cards you own named Awestruck Cygnet intensify by 1. +SVar:TrigIntensify:DB$ Intensify | AllDefined$ Card.namedAwestruck Cygnet+YouOwn +S:Mode$ Continuous | Affected$ Card.Self | SetPower$ 5 | CheckSVar$ X | SetName$ Radiant Swan | SVarCompare$ GE3 | AddKeyword$ Flying & Vigilance | SetToughness$ 3 | Description$ As long as this card's intensity is 3 or more, it has base power and toughness 5/4, has flying and vigilance, and is named Radiant Swan. +SVar:X:Count$Intensity +Oracle:Starting intensity 0\nWhenever a creature you control with flying enters, if this creature is named Awestruck Cygnet, cards you own named Awestruck Cygnet intensify by 1.\nAs long as this card's intensity is 3 or more, it has base power and toughness 5/4, has flying and vigilance, and is named Radiant Swan. diff --git a/forge-gui/res/cardsfolder/upcoming/aya_of_alexandria.txt b/forge-gui/res/cardsfolder/a/aya_of_alexandria.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/aya_of_alexandria.txt rename to forge-gui/res/cardsfolder/a/aya_of_alexandria.txt diff --git a/forge-gui/res/cardsfolder/upcoming/azure_beastbinder.txt b/forge-gui/res/cardsfolder/a/azure_beastbinder.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/azure_beastbinder.txt rename to forge-gui/res/cardsfolder/a/azure_beastbinder.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bakersbane_duo.txt b/forge-gui/res/cardsfolder/b/bakersbane_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bakersbane_duo.txt rename to forge-gui/res/cardsfolder/b/bakersbane_duo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ballad_of_the_black_flag.txt b/forge-gui/res/cardsfolder/b/ballad_of_the_black_flag.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ballad_of_the_black_flag.txt rename to forge-gui/res/cardsfolder/b/ballad_of_the_black_flag.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bandits_talent.txt b/forge-gui/res/cardsfolder/b/bandits_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bandits_talent.txt rename to forge-gui/res/cardsfolder/b/bandits_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bark_knuckle_boxer.txt b/forge-gui/res/cardsfolder/b/bark_knuckle_boxer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bark_knuckle_boxer.txt rename to forge-gui/res/cardsfolder/b/bark_knuckle_boxer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/barkform_harvester.txt b/forge-gui/res/cardsfolder/b/barkform_harvester.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/barkform_harvester.txt rename to forge-gui/res/cardsfolder/b/barkform_harvester.txt diff --git a/forge-gui/res/cardsfolder/upcoming/basim_ibn_ishaq.txt b/forge-gui/res/cardsfolder/b/basim_ibn_ishaq.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/basim_ibn_ishaq.txt rename to forge-gui/res/cardsfolder/b/basim_ibn_ishaq.txt diff --git a/forge-gui/res/cardsfolder/upcoming/battlefield_improvisation.txt b/forge-gui/res/cardsfolder/b/battlefield_improvisation.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/battlefield_improvisation.txt rename to forge-gui/res/cardsfolder/b/battlefield_improvisation.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bayek_of_siwa.txt b/forge-gui/res/cardsfolder/b/bayek_of_siwa.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bayek_of_siwa.txt rename to forge-gui/res/cardsfolder/b/bayek_of_siwa.txt diff --git a/forge-gui/res/cardsfolder/upcoming/baylen_the_haymaker.txt b/forge-gui/res/cardsfolder/b/baylen_the_haymaker.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/baylen_the_haymaker.txt rename to forge-gui/res/cardsfolder/b/baylen_the_haymaker.txt diff --git a/forge-gui/res/cardsfolder/b/because_i_have_willed_it.txt b/forge-gui/res/cardsfolder/b/because_i_have_willed_it.txt index 3c50d0d4575..34594559395 100644 --- a/forge-gui/res/cardsfolder/b/because_i_have_willed_it.txt +++ b/forge-gui/res/cardsfolder/b/because_i_have_willed_it.txt @@ -3,6 +3,6 @@ ManaCost:no cost Types:Ongoing Scheme S:Mode$ ReduceCost | EffectZone$ Command | ValidCard$ Card | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Spells you cast cost {1} less to cast. T:Mode$ Phase | Phase$ End Of Turn | ValidPlayer$ Player.Opponent | Execute$ Abandon | TriggerZones$ Command | CheckSVar$ X | SVarCompare$ GE4 | TriggerDescription$ At the beginning of your opponents' end step, if they cast four or more spells this turn, abandon this scheme. -SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Abandon:DB$ Abandon SVar:X:Count$ThisTurnCast_Card.YouDontCtrl Oracle:(An ongoing scheme remains face up until it's abandoned.)\nSpells you cast cost {1} less to cast.\nAt the beginning of your opponents' end step, if they cast four or more spells this turn, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/become_anonymous.txt b/forge-gui/res/cardsfolder/b/become_anonymous.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/become_anonymous.txt rename to forge-gui/res/cardsfolder/b/become_anonymous.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bello_bard_of_the_brambles.txt b/forge-gui/res/cardsfolder/b/bello_bard_of_the_brambles.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bello_bard_of_the_brambles.txt rename to forge-gui/res/cardsfolder/b/bello_bard_of_the_brambles.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bellowing_crier.txt b/forge-gui/res/cardsfolder/b/bellowing_crier.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bellowing_crier.txt rename to forge-gui/res/cardsfolder/b/bellowing_crier.txt diff --git a/forge-gui/res/cardsfolder/upcoming/beza_the_bounding_spring.txt b/forge-gui/res/cardsfolder/b/beza_the_bounding_spring.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/beza_the_bounding_spring.txt rename to forge-gui/res/cardsfolder/b/beza_the_bounding_spring.txt diff --git a/forge-gui/res/cardsfolder/b/black_tulip.txt b/forge-gui/res/cardsfolder/b/black_tulip.txt new file mode 100644 index 00000000000..2cd697a39b9 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/black_tulip.txt @@ -0,0 +1,5 @@ +Name:Black Tulip +ManaCost:0 +Types:Artifact +A:AB$ Mana | Cost$ T Exile<1/CARDNAME> | Produced$ Any | Amount$ 3 | AILogic$ BlackLotus | CheckSVar$ Count$YourTurns | SVarCompare$ GE6 | SpellDescription$ Add three mana of any one color. You can't activate this ability until you've begun your sixth turn of the game (Keep track if this is in your deck!) +Oracle:{T}, Exile Black Tulip: Add three mana of any one color. You can't activate this ability until you've begun your sixth turn of the game (Keep track if this is in your deck!) diff --git a/forge-gui/res/cardsfolder/upcoming/blacksmiths_talent.txt b/forge-gui/res/cardsfolder/b/blacksmiths_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/blacksmiths_talent.txt rename to forge-gui/res/cardsfolder/b/blacksmiths_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bleeding_effect.txt b/forge-gui/res/cardsfolder/b/bleeding_effect.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bleeding_effect.txt rename to forge-gui/res/cardsfolder/b/bleeding_effect.txt diff --git a/forge-gui/res/cardsfolder/b/blessed_hippogriff_tyrs_blesing.txt b/forge-gui/res/cardsfolder/b/blessed_hippogriff_tyrs_blessing.txt similarity index 97% rename from forge-gui/res/cardsfolder/b/blessed_hippogriff_tyrs_blesing.txt rename to forge-gui/res/cardsfolder/b/blessed_hippogriff_tyrs_blessing.txt index 36869d55963..ed69ea65029 100644 --- a/forge-gui/res/cardsfolder/b/blessed_hippogriff_tyrs_blesing.txt +++ b/forge-gui/res/cardsfolder/b/blessed_hippogriff_tyrs_blessing.txt @@ -10,7 +10,7 @@ Oracle:Flying\nWhenever Blessed Hippogriff attacks, target attacking creature wi ALTERNATE -Name:Tyr's Blesing +Name:Tyr's Blessing ManaCost:W Types:Instant Adventure A:SP$ Pump | ValidTgts$ Creature | KW$ Indestructible | SpellDescription$ Target creature gains indestructible until end of turn. diff --git a/forge-gui/res/cardsfolder/b/blinkmoth_urn.txt b/forge-gui/res/cardsfolder/b/blinkmoth_urn.txt index a7e7960f4b9..6bda722612f 100644 --- a/forge-gui/res/cardsfolder/b/blinkmoth_urn.txt +++ b/forge-gui/res/cardsfolder/b/blinkmoth_urn.txt @@ -1,7 +1,7 @@ Name:Blinkmoth Urn ManaCost:5 Types:Artifact -T:Mode$ Phase | Phase$ Main1 | ValidPlayer$ Player | TriggerZones$ Battlefield | IsPresent$ Card.Self+untapped | Execute$ TrigGetMana | TriggerDescription$ At the beginning of each player's precombat main phase, if CARDNAME is untapped, that player adds {C} for each artifact they control. +T:Mode$ Phase | Phase$ Main1 | ValidPlayer$ Player | TriggerZones$ Battlefield | PresentDefined$ Self | IsPresent$ Card.untapped | Execute$ TrigGetMana | TriggerDescription$ At the beginning of each player's precombat main phase, if CARDNAME is untapped, that player adds {C} for each artifact they control. SVar:TrigGetMana:DB$ Mana | Produced$ C | Amount$ X | Defined$ TriggeredPlayer SVar:X:Count$Valid Artifact.ActivePlayerCtrl AI:RemoveDeck:Random diff --git a/forge-gui/res/cardsfolder/upcoming/bloodroot_apothecary.txt b/forge-gui/res/cardsfolder/b/bloodroot_apothecary.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bloodroot_apothecary.txt rename to forge-gui/res/cardsfolder/b/bloodroot_apothecary.txt diff --git a/forge-gui/res/cardsfolder/b/bloodsplatter_vampire.txt b/forge-gui/res/cardsfolder/b/bloodsplatter_vampire.txt new file mode 100644 index 00000000000..9346f59b367 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/bloodsplatter_vampire.txt @@ -0,0 +1,8 @@ +Name:Bloodspatter Vampire +ManaCost:1 B +Types:Creature Vampire +PT:2/1 +K:Flying +R:Event$ CreateToken | ActiveZones$ Battlefield | ValidPlayer$ Opponent | ValidToken$ Clue | ReplaceWith$ TokenReplace | Description$ If an opponent would create a Clue, they create a Blood instead. +SVar:TokenReplace:DB$ ReplaceToken | Type$ ReplaceToken | ValidCard$ Clue | TokenScript$ c_a_blood_draw +Oracle:Flying\nIf an opponent would create a Clue, they create a Blood instead. (It's an artifact with {1}, {T}, Discard a card, Sacrifice this artifact: Draw a card.) diff --git a/forge-gui/res/cardsfolder/upcoming/blooming_blast.txt b/forge-gui/res/cardsfolder/b/blooming_blast.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/blooming_blast.txt rename to forge-gui/res/cardsfolder/b/blooming_blast.txt diff --git a/forge-gui/res/cardsfolder/b/bone_dancer.txt b/forge-gui/res/cardsfolder/b/bone_dancer.txt index 6334553f6c4..a0cd5b94e98 100644 --- a/forge-gui/res/cardsfolder/b/bone_dancer.txt +++ b/forge-gui/res/cardsfolder/b/bone_dancer.txt @@ -4,6 +4,7 @@ Types:Creature Zombie PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ DBChangeZone | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may put the top creature card of defending player's graveyard onto the battlefield under your control. If you do, CARDNAME assigns no combat damage this turn. SVar:DBChangeZone:DB$ ChangeZoneAll | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.TopGraveyardCreature+DefenderCtrl | GainControl$ True | ChangeNum$ 1 | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:NeedsOrderedGraveyard:OPPONENT Oracle:Whenever Bone Dancer attacks and isn't blocked, you may put the top creature card of defending player's graveyard onto the battlefield under your control. If you do, Bone Dancer assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/bonebind_orator.txt b/forge-gui/res/cardsfolder/b/bonebind_orator.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bonebind_orator.txt rename to forge-gui/res/cardsfolder/b/bonebind_orator.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bonecache_overseer.txt b/forge-gui/res/cardsfolder/b/bonecache_overseer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bonecache_overseer.txt rename to forge-gui/res/cardsfolder/b/bonecache_overseer.txt diff --git a/forge-gui/res/cardsfolder/b/bottomless_vault.txt b/forge-gui/res/cardsfolder/b/bottomless_vault.txt index 0e5ae2589d5..63166b8332a 100644 --- a/forge-gui/res/cardsfolder/b/bottomless_vault.txt +++ b/forge-gui/res/cardsfolder/b/bottomless_vault.txt @@ -4,7 +4,7 @@ Types:Land R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True K:You may choose not to untap CARDNAME during your untap step. -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Card.Self+tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. SVar:TrigStore:DB$ PutCounter | Defined$ Self | CounterType$ STORAGE | CounterNum$ 1 A:AB$ Mana | Cost$ T SubCounter | Produced$ B | Amount$ X | AILogic$ ManaRitualBattery | SpellDescription$ Add {B} for each storage counter removed this way. SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/b/bramblearmor_brawler.txt b/forge-gui/res/cardsfolder/b/bramblearmor_brawler.txt new file mode 100644 index 00000000000..b9a78d5948e --- /dev/null +++ b/forge-gui/res/cardsfolder/b/bramblearmor_brawler.txt @@ -0,0 +1,9 @@ +Name:Bramblearmor Brawler +ManaCost:2 G G +Types:Creature Raccoon Warrior +PT:5/5 +K:Trample +R:Event$ Counter | ValidCard$ Card.Self | ValidSA$ Spell | Layer$ CantHappen | Description$ This spell can't be countered. +T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Player.Opponent | Execute$ TrigPerpetualP1P1 | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a noncreature spell, creature cards in your library perpetually get +1/+1. +SVar:TrigPerpetualP1P1:DB$ PumpAll | ValidCards$ Creature.YouOwn | PumpZone$ Library | NumAtt$ 1 | NumDef$ 1 | Duration$ Perpetual +Oracle:This spell can't be countered.\nTrample\nWhenever an opponent casts a noncreature spell, creature cards in your library perpetually get +1/+1. diff --git a/forge-gui/res/cardsfolder/upcoming/brambleguard_captain.txt b/forge-gui/res/cardsfolder/b/brambleguard_captain.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brambleguard_captain.txt rename to forge-gui/res/cardsfolder/b/brambleguard_captain.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brambleguard_veteran.txt b/forge-gui/res/cardsfolder/b/brambleguard_veteran.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brambleguard_veteran.txt rename to forge-gui/res/cardsfolder/b/brambleguard_veteran.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brave_kin_duo.txt b/forge-gui/res/cardsfolder/b/brave_kin_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brave_kin_duo.txt rename to forge-gui/res/cardsfolder/b/brave_kin_duo.txt diff --git a/forge-gui/res/cardsfolder/b/brave_meadowguard.txt b/forge-gui/res/cardsfolder/b/brave_meadowguard.txt new file mode 100644 index 00000000000..6147149fac7 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/brave_meadowguard.txt @@ -0,0 +1,9 @@ +Name:Brave Meadowguard +ManaCost:1 R +Types:Creature Mouse Soldier +PT:1/1 +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigConjure | TriggerDescription$ When CARDNAME enters, conjure a card named Might of the Meek into your hand. +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Name$ Might of the Meek | Zone$ Hand +T:Mode$ BecomesTarget | ValidTarget$ Card.Self | ValidSource$ SpellAbility.YouCtrl | TriggerZones$ Battlefield | FirstTime$ True | Execute$ TrigCounter | TriggerDescription$ Valiant — Whenever CARDNAME becomes the target of a spell or ability you control for the first time each turn, put a +1/+1 counter on it. +SVar:TrigCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +Oracle:When Brave Meadowguard enters, conjure a card named Might of the Meek into your hand.\nValiant — Whenever Brave Meadowguard becomes the target of a spell or ability you control for the first time each turn, put a +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/upcoming/brazen_collector.txt b/forge-gui/res/cardsfolder/b/brazen_collector.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brazen_collector.txt rename to forge-gui/res/cardsfolder/b/brazen_collector.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brightblade_stoat.txt b/forge-gui/res/cardsfolder/b/brightblade_stoat.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brightblade_stoat.txt rename to forge-gui/res/cardsfolder/b/brightblade_stoat.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brightcap_badger.txt b/forge-gui/res/cardsfolder/b/brightcap_badger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brightcap_badger.txt rename to forge-gui/res/cardsfolder/b/brightcap_badger.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brotherhood_ambushers.txt b/forge-gui/res/cardsfolder/b/brotherhood_ambushers.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brotherhood_ambushers.txt rename to forge-gui/res/cardsfolder/b/brotherhood_ambushers.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brotherhood_headquarters.txt b/forge-gui/res/cardsfolder/b/brotherhood_headquarters.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brotherhood_headquarters.txt rename to forge-gui/res/cardsfolder/b/brotherhood_headquarters.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brotherhood_patriarch.txt b/forge-gui/res/cardsfolder/b/brotherhood_patriarch.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brotherhood_patriarch.txt rename to forge-gui/res/cardsfolder/b/brotherhood_patriarch.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brotherhood_regalia.txt b/forge-gui/res/cardsfolder/b/brotherhood_regalia.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brotherhood_regalia.txt rename to forge-gui/res/cardsfolder/b/brotherhood_regalia.txt diff --git a/forge-gui/res/cardsfolder/upcoming/brotherhood_spy.txt b/forge-gui/res/cardsfolder/b/brotherhood_spy.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/brotherhood_spy.txt rename to forge-gui/res/cardsfolder/b/brotherhood_spy.txt diff --git a/forge-gui/res/cardsfolder/upcoming/builders_talent.txt b/forge-gui/res/cardsfolder/b/builders_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/builders_talent.txt rename to forge-gui/res/cardsfolder/b/builders_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bumbleflowers_sharepot.txt b/forge-gui/res/cardsfolder/b/bumbleflowers_sharepot.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bumbleflowers_sharepot.txt rename to forge-gui/res/cardsfolder/b/bumbleflowers_sharepot.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bureau_headmaster.txt b/forge-gui/res/cardsfolder/b/bureau_headmaster.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bureau_headmaster.txt rename to forge-gui/res/cardsfolder/b/bureau_headmaster.txt diff --git a/forge-gui/res/cardsfolder/upcoming/burrowguard_mentor.txt b/forge-gui/res/cardsfolder/b/burrowguard_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/burrowguard_mentor.txt rename to forge-gui/res/cardsfolder/b/burrowguard_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bushy_bodyguard.txt b/forge-gui/res/cardsfolder/b/bushy_bodyguard.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/bushy_bodyguard.txt rename to forge-gui/res/cardsfolder/b/bushy_bodyguard.txt diff --git a/forge-gui/res/cardsfolder/b/buxton_decorated_host.txt b/forge-gui/res/cardsfolder/b/buxton_decorated_host.txt new file mode 100644 index 00000000000..4e48cf4fdde --- /dev/null +++ b/forge-gui/res/cardsfolder/b/buxton_decorated_host.txt @@ -0,0 +1,11 @@ +Name:Buxton, Decorated Host +ManaCost:3 G W +Types:Legendary Creature Rabbit Noble +PT:4/4 +K:Convoke +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Creature.tapped+YouCtrl | Execute$ TrigSeek | TriggerDescription$ At the beginning of your end step, if you control a tapped creature, seek a nonland permanent card with mana value X or less, where X is the number of tapped creatures you control. Put that card onto the battlefield. +SVar:TrigSeek:DB$ Seek | Type$ Permanent.nonLand+cmcLEX | RememberFound$ True | SubAbility$ DBPut +SVar:DBPut:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ Remembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$Valid Creature.tapped+YouCtrl +Oracle:Convoke\nAt the beginning of your end step, if you control a tapped creature, seek a nonland permanent card with mana value X or less, where X is the number of tapped creatures you control. Put that card onto the battlefield. diff --git a/forge-gui/res/cardsfolder/upcoming/byway_barterer.txt b/forge-gui/res/cardsfolder/b/byway_barterer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/byway_barterer.txt rename to forge-gui/res/cardsfolder/b/byway_barterer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/cache_grab.txt b/forge-gui/res/cardsfolder/c/cache_grab.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/cache_grab.txt rename to forge-gui/res/cardsfolder/c/cache_grab.txt diff --git a/forge-gui/res/cardsfolder/upcoming/caduceus_staff_of_hermes.txt b/forge-gui/res/cardsfolder/c/caduceus_staff_of_hermes.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/caduceus_staff_of_hermes.txt rename to forge-gui/res/cardsfolder/c/caduceus_staff_of_hermes.txt diff --git a/forge-gui/res/cardsfolder/upcoming/calamitous_tide.txt b/forge-gui/res/cardsfolder/c/calamitous_tide.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/calamitous_tide.txt rename to forge-gui/res/cardsfolder/c/calamitous_tide.txt diff --git a/forge-gui/res/cardsfolder/upcoming/calamity_of_cinders.txt b/forge-gui/res/cardsfolder/c/calamity_of_cinders.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/calamity_of_cinders.txt rename to forge-gui/res/cardsfolder/c/calamity_of_cinders.txt diff --git a/forge-gui/res/cardsfolder/c/call_forth_the_tempest.txt b/forge-gui/res/cardsfolder/c/call_forth_the_tempest.txt index d1a2fb34289..34ec29670e0 100644 --- a/forge-gui/res/cardsfolder/c/call_forth_the_tempest.txt +++ b/forge-gui/res/cardsfolder/c/call_forth_the_tempest.txt @@ -4,5 +4,5 @@ Types:Sorcery K:Cascade K:Cascade A:SP$ DamageAll | NumDmg$ X | ValidCards$ Creature.OppCtrl | ValidDescription$ each creature your opponents controls | SpellDescription$ CARDNAME deals damage to each creature your opponents control equal to the total mana value of other spells you've cast this turn. -SVar:X:Count$ThisTurnCast_Card.YouCtrl+Other$SumCMC +SVar:X:Count$ThisTurnCast_Card.YouCtrl+!CastSaSource$SumCMC Oracle:Cascade, cascade (When you cast this spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order. Then do it again.)\nCall Forth the Tempest deals damage to each creature your opponents control equal to the total mana value of other spells you've cast this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/camellia_the_seedmiser.txt b/forge-gui/res/cardsfolder/c/camellia_the_seedmiser.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/camellia_the_seedmiser.txt rename to forge-gui/res/cardsfolder/c/camellia_the_seedmiser.txt diff --git a/forge-gui/res/cardsfolder/upcoming/caretakers_talent.txt b/forge-gui/res/cardsfolder/c/caretakers_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/caretakers_talent.txt rename to forge-gui/res/cardsfolder/c/caretakers_talent.txt diff --git a/forge-gui/res/cardsfolder/c/carrion_rats.txt b/forge-gui/res/cardsfolder/c/carrion_rats.txt index 5f5f16c2234..f7af5a4b974 100644 --- a/forge-gui/res/cardsfolder/c/carrion_rats.txt +++ b/forge-gui/res/cardsfolder/c/carrion_rats.txt @@ -2,8 +2,9 @@ Name:Carrion Rats ManaCost:B Types:Creature Rat PT:2/1 -T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigNoCombatDamage | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile a card from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. -T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ TrigNoCombatDamage | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile a card from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. -SVar:TrigNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | UnlessCost$ ExileFromGrave<1/Card> | UnlessPayer$ Player | UnlessSwitched$ True +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBNoCombatDamage | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile a card from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. +T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ DBNoCombatDamage | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile a card from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT | UnlessCost$ ExileFromGrave<1/Card> | UnlessPayer$ Player | UnlessSwitched$ True +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. AI:RemoveDeck:All Oracle:Whenever Carrion Rats attacks or blocks, any player may exile a card from their graveyard. If a player does, Carrion Rats assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/c/carrion_wurm.txt b/forge-gui/res/cardsfolder/c/carrion_wurm.txt index c708cd2e02a..0f829ed32b9 100644 --- a/forge-gui/res/cardsfolder/c/carrion_wurm.txt +++ b/forge-gui/res/cardsfolder/c/carrion_wurm.txt @@ -2,7 +2,8 @@ Name:Carrion Wurm ManaCost:3 B B Types:Creature Zombie Wurm PT:6/5 -T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigNoCombatDamage | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile three cards from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. -T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ TrigNoCombatDamage | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile three cards from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. -SVar:TrigNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | UnlessCost$ ExileFromGrave<3/Card> | UnlessPayer$ Player | UnlessSwitched$ True +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBNoCombatDamage | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile three cards from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. +T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ DBNoCombatDamage | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, any player may exile three cards from their graveyard. If a player does, CARDNAME assigns no combat damage this turn. +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT | UnlessCost$ ExileFromGrave<3/Card> | UnlessPayer$ Player | UnlessSwitched$ True +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. Oracle:Whenever Carrion Wurm attacks or blocks, any player may exile three cards from their graveyard. If a player does, Carrion Wurm assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/c/carrionette.txt b/forge-gui/res/cardsfolder/c/carrionette.txt index 49b22661af2..448531b2442 100644 --- a/forge-gui/res/cardsfolder/c/carrionette.txt +++ b/forge-gui/res/cardsfolder/c/carrionette.txt @@ -2,6 +2,5 @@ Name:Carrionette ManaCost:1 B Types:Creature Skeleton PT:1/1 -A:AB$ ChangeZone | Cost$ 2 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | UnlessCost$ 2 | UnlessPayer$ TargetedController | ActivationZone$ Graveyard | UnlessResolveSubs$ WhenNotPaid | SubAbility$ ExileME | SpellDescription$ Exile CARDNAME and target creature unless that creature's controller pays {2}. Activate only if CARDNAME is in your graveyard. -SVar:ExileME:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | Defined$ Self +A:AB$ ChangeZone | Cost$ 2 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | ThisDefinedAndTgts$ Self | Origin$ Battlefield | Destination$ Exile | UnlessCost$ 2 | UnlessPayer$ TargetedController | ActivationZone$ Graveyard | SpellDescription$ Exile CARDNAME and target creature unless that creature's controller pays {2}. Activate only if CARDNAME is in your graveyard. Oracle:{2}{B}{B}: Exile Carrionette and target creature unless that creature's controller pays {2}. Activate only if Carrionette is in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/carrot_cake.txt b/forge-gui/res/cardsfolder/c/carrot_cake.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/carrot_cake.txt rename to forge-gui/res/cardsfolder/c/carrot_cake.txt diff --git a/forge-gui/res/cardsfolder/c/celestine_reef.txt b/forge-gui/res/cardsfolder/c/celestine_reef.txt index 24e9e1220cd..e492c72794b 100644 --- a/forge-gui/res/cardsfolder/c/celestine_reef.txt +++ b/forge-gui/res/cardsfolder/c/celestine_reef.txt @@ -3,9 +3,9 @@ ManaCost:no cost Types:Plane Luvion S:Mode$ CantAttack | EffectZone$ Command | ValidCard$ Creature.withoutFlying+!hasKeywordLandwalk:Island | Description$ Creatures without flying or islandwalk can't attack. T:Mode$ ChaosEnsues | TriggerZones$ Command | Execute$ RolledChaos | TriggerDescription$ Whenever chaos ensues, until a player planeswalks, you can't lose the game and your opponents can't win the game. -SVar:RolledChaos:DB$ Effect | StaticAbilities$ STCantlose,STCantWin | Triggers$ TrigPlaneswalk | Duration$ Permanent -SVar:STCantlose:Mode$ Continuous | EffectZone$ Command | Affected$ You | AddKeyword$ You can't lose the game. | Description$ Until a player planeswalks, you can't lose the game and your opponents can't win the game. -SVar:STCantWin:Mode$ Continuous | EffectZone$ Command | Affected$ Opponent | AddKeyword$ You can't win the game. +SVar:RolledChaos:DB$ Effect | ReplacementEffects$ DBYouCantLose,DBOppCantWin | Triggers$ TrigPlaneswalk | Duration$ Permanent +SVar:DBYouCantLose:Event$ GameLoss | ValidPlayer$ You | Layer$ CantHappen | Description$ Until a player planeswalks, you can't lose the game and your opponents can't win the game. +SVar:DBOppCantWin:Event$ GameWin | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ Until a player planeswalks, you can't lose the game and your opponents can't win the game. SVar:TrigPlaneswalk:Mode$ PlaneswalkedTo | Execute$ DBCleanup | Static$ True SVar:DBCleanup:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile SVar:AIRollPlanarDieParams:Mode$ Always diff --git a/forge-gui/res/cardsfolder/upcoming/chain_assassination.txt b/forge-gui/res/cardsfolder/c/chain_assassination.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/chain_assassination.txt rename to forge-gui/res/cardsfolder/c/chain_assassination.txt diff --git a/forge-gui/res/cardsfolder/c/champions_of_archery_join_the_group.txt b/forge-gui/res/cardsfolder/c/champions_of_archery_join_the_group.txt new file mode 100644 index 00000000000..e6ae0115ed0 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/champions_of_archery_join_the_group.txt @@ -0,0 +1,19 @@ +Name:Champions of Archery +ManaCost:3 R +Types:Legendary Creature Human Archer +PT:1/4 +K:Reach +S:Mode$ Continuous | Affected$ Card.IsCommander+YouCtrl | AddPower$ +X | Description$ Commanders you control get +X/+0, where X is the number of commanders you control. +SVar:X:Count$Valid Card.IsCommander+YouCtrl +AlternateMode:Adventure +Oracle:Reach\nCommanders you control get +X/+0, where X is the number of commanders you control. + +ALTERNATE + +Name:Join the Group +ManaCost:2 R +Types:Sorcery Adventure +A:SP$ ChangeZone | Origin$ Hand | Destination$ Command | Optional$ You | ChangeType$ Card.Creature+Legendary+YouOwn | ChangeNum$ 1 | ChangeTypeDesc$ a legendary creature card | SelectPrompt$ Select a legendary creature card in your hand | RememberChanged$ True | SubAbility$ YouAreCommander | StackDescription$ REP You_{p:You} & your hand_their hand & also your_also {p:You}'s | SpellDescription$ You may put a legendary creature card from your hand into the command zone. It's also your commander. +SVar:YouAreCommander:DB$ AlterAttribute | Defined$ Remembered | Attributes$ Commander | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:You may put a legendary creature card from your hand into the command zone. It's also your commander. diff --git a/forge-gui/res/cardsfolder/c/charged_conjuration.txt b/forge-gui/res/cardsfolder/c/charged_conjuration.txt new file mode 100644 index 00000000000..37856f1e62b --- /dev/null +++ b/forge-gui/res/cardsfolder/c/charged_conjuration.txt @@ -0,0 +1,8 @@ +Name:Charged Conjuration +ManaCost:3 R +Types:Enchantment +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigAnimate | TriggerDescription$ At the beginning of your upkeep, instant and sorcery cards in your hand perpetually gain "This spell costs {1} less to cast." +SVar:TrigAnimate:DB$ AnimateAll | ValidCards$ Sorcery.YouOwn,Instant.YouOwn | Zone$ Hand | staticAbilities$ ReduceCost | Duration$ Perpetual +SVar:ReduceCost:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | Description$ This spell costs {1} less to cast. +A:AB$ MakeCard | Cost$ Sac<1/CARDNAME> | Conjure$ True | Spellbook$ Empty the Warrens,Galvanic Relay,Grapeshot | SorcerySpeed$ True | Zone$ Hand | SpellDescription$ Conjure a card of your choice from Charged Conjuration's spellbook into your hand. Activate only as a sorcery. +Oracle:At the beginning of your upkeep, instant and sorcery cards in your hand perpetually gain "This spell costs {1} less to cast."\nSacrifice this enchantment: Conjure a card of your choice from Charged Conjuration's spellbook into your hand. Activate only as a sorcery. diff --git a/forge-gui/res/cardsfolder/c/chittering_skullspeaker.txt b/forge-gui/res/cardsfolder/c/chittering_skullspeaker.txt new file mode 100644 index 00000000000..d672e660b3e --- /dev/null +++ b/forge-gui/res/cardsfolder/c/chittering_skullspeaker.txt @@ -0,0 +1,11 @@ +Name:Chittering Skullspeaker +ManaCost:1 B +Types:Creature Squirrel Warlock +PT:1/1 +K:Starting intensity:0 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigIntensify | TriggerDescription$ When CARDNAME enters, cards you own named Chittering Skullspeaker intensify by 1. Then you draw X cards and lose X life, where X is CARDNAME's intensity. +SVar:TrigIntensify:DB$ Intensify | AllDefined$ Card.YouOwn+namedChittering Skullspeaker | DefinedDesc$ all cards they own named Chittering Skullspeaker | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ X | SubAbility$ DBLoseLife +SVar:DBLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ X +SVar:X:Count$Intensity +Oracle:Starting intensity 0\nWhen Chittering Skullspeaker enters, cards you own named Chittering Skullspeaker intensify by 1. Then you draw X cards and lose X life, where X is Chittering Skullspeaker's intensity. diff --git a/forge-gui/res/cardsfolder/c/cindercone_smite.txt b/forge-gui/res/cardsfolder/c/cindercone_smite.txt new file mode 100644 index 00000000000..43c9fead4f7 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/cindercone_smite.txt @@ -0,0 +1,7 @@ +Name:Cindercone Smite +ManaCost:R +Types:Sorcery +A:SP$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 2 | SubAbility$ DBTreasure | SpellDescription$ CARDNAME deals 2 damage to target creature +SVar:DBTreasure:DB$ Token | ConditionCheckSVar$ X | TokenScript$ c_a_treasure_sac | SpellDescription$ Then create a Treasure token if you weren't the starting player. +SVar:X:Count$StartingPlayer.0.1 +Oracle:Cindercone Smite deals 2 damage to target creature. Then create a Treasure token if you weren't the starting player. diff --git a/forge-gui/res/cardsfolder/upcoming/cindering_cutthroat.txt b/forge-gui/res/cardsfolder/c/cindering_cutthroat.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/cindering_cutthroat.txt rename to forge-gui/res/cardsfolder/c/cindering_cutthroat.txt diff --git a/forge-gui/res/cardsfolder/c/cleansing_meditation.txt b/forge-gui/res/cardsfolder/c/cleansing_meditation.txt index 492d8a470b4..e03d95587bc 100644 --- a/forge-gui/res/cardsfolder/c/cleansing_meditation.txt +++ b/forge-gui/res/cardsfolder/c/cleansing_meditation.txt @@ -1,9 +1,10 @@ Name:Cleansing Meditation ManaCost:1 W W Types:Sorcery -A:SP$ DestroyAll | ValidCards$ Enchantment | SubAbility$ ThresholdDestruction | ConditionCheckSVar$ X | ConditionSVarCompare$ LT7 | SpellDescription$ Destroy all enchantments. -SVar:ThresholdDestruction:DB$ DestroyAll | ValidCards$ Enchantment | SubAbility$ ThresholdReturn | ConditionCheckSVar$ X | ConditionSVarCompare$ GE7 | RememberDestroyed$ True | StackDescription$ Threshold — If seven or more cards are in your graveyard, instead destroy all enchantments, | SpellDescription$ Threshold — If seven or more cards are in your graveyard, instead destroy all enchantments, then return all cards in your graveyard destroyed this way to the battlefield. -SVar:ThresholdReturn:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered+YouCtrl | Origin$ Graveyard | Destination$ Battlefield | StackDescription$ then return all cards in your graveyard destroyed this way to the battlefield. | SubAbility$ DBCleanup +A:SP$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE7 | TrueSubAbility$ ThreshDestruction | FalseSubAbility$ Destruction | SpellDescription$ Destroy all enchantments. Threshold — If seven or more cards are in your graveyard, instead destroy all enchantments, then return all cards in your graveyard destroyed this way to the battlefield. +SVar:Destruction:DB$ DestroyAll | ValidCards$ Enchantment +SVar:ThreshDestruction:DB$ DestroyAll | ValidCards$ Enchantment | SubAbility$ ThreshReturn | RememberDestroyed$ True | StackDescription$ Threshold — If seven or more cards are in your graveyard, instead destroy all enchantments, +SVar:ThreshReturn:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered+YouCtrl | Origin$ Graveyard | Destination$ Battlefield | StackDescription$ then return all cards in your graveyard destroyed this way to the battlefield. | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$ValidGraveyard Card.YouCtrl Oracle:Destroy all enchantments.\nThreshold — If seven or more cards are in your graveyard, instead destroy all enchantments, then return all cards in your graveyard destroyed this way to the battlefield. diff --git a/forge-gui/res/cardsfolder/upcoming/clement_the_worrywort.txt b/forge-gui/res/cardsfolder/c/clement_the_worrywort.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/clement_the_worrywort.txt rename to forge-gui/res/cardsfolder/c/clement_the_worrywort.txt diff --git a/forge-gui/res/cardsfolder/upcoming/clifftop_lookout.txt b/forge-gui/res/cardsfolder/c/clifftop_lookout.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/clifftop_lookout.txt rename to forge-gui/res/cardsfolder/c/clifftop_lookout.txt diff --git a/forge-gui/res/cardsfolder/c/cloak_of_confusion.txt b/forge-gui/res/cardsfolder/c/cloak_of_confusion.txt index 724668bd96f..dd18a5ebb3d 100644 --- a/forge-gui/res/cardsfolder/c/cloak_of_confusion.txt +++ b/forge-gui/res/cardsfolder/c/cloak_of_confusion.txt @@ -3,8 +3,9 @@ ManaCost:1 B Types:Enchantment Aura K:Enchant creature you control A:SP$ Attach | Cost$ 1 B | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | AILogic$ Pump -T:Mode$ AttackerUnblocked | ValidCard$ Creature.EnchantedBy | Execute$ CloakofConfusionPump | OptionalDecider$ You | TriggerDescription$ Whenever enchanted creature attacks and isn't blocked, you may have it assign no combat damage this turn. If you do, defending player discards a card at random. -SVar:CloakofConfusionPump:DB$ Pump | Defined$ TriggeredAttackerLKICopy | KW$ HIDDEN CARDNAME assigns no combat damage | SubAbility$ CloakofConfusionDiscard +T:Mode$ AttackerUnblocked | ValidCard$ Creature.EnchantedBy | Execute$ DBNoCombatDamage | OptionalDecider$ You | TriggerDescription$ Whenever enchanted creature attacks and isn't blocked, you may have it assign no combat damage this turn. If you do, defending player discards a card at random. +SVar:DBNoCombatDamage:DB$ Effect | RememberObjects$ TriggeredAttackerLKICopy | StaticAbilities$ SNoCombatDamage | ForgetOnMoved$ Battlefield | SubAbility$ CloakofConfusionDiscard +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.IsRemembered | Description$ Remembered creature assigns no combat damage this turn. SVar:CloakofConfusionDiscard:DB$ Discard | Defined$ TriggeredDefendingPlayer | Mode$ Random | NumCards$ 1 AI:RemoveDeck:All Oracle:Enchant creature you control\nWhenever enchanted creature attacks and isn't blocked, you may have it assign no combat damage this turn. If you do, defending player discards a card at random. diff --git a/forge-gui/res/cardsfolder/c/cloudsteel_kirin.txt b/forge-gui/res/cardsfolder/c/cloudsteel_kirin.txt index aa7f6d5ae09..4663efeb49d 100644 --- a/forge-gui/res/cardsfolder/c/cloudsteel_kirin.txt +++ b/forge-gui/res/cardsfolder/c/cloudsteel_kirin.txt @@ -3,8 +3,8 @@ ManaCost:2 W Types:Artifact Creature Equipment Kirin PT:3/2 K:Flying -S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddKeyword$ Flying | AddStaticAbility$ YouCantLose & OppCantWin | Description$ Equipped creature has flying and "You can't lose the game and your opponents can't win the game." -SVar:YouCantLose:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game. -SVar:OppCantWin:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Description$ Opponents can't win the game. +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddKeyword$ Flying | AddReplacementEffect$ YouCantLose & OppCantWin | Description$ Equipped creature has flying and "You can't lose the game and your opponents can't win the game." +SVar:YouCantLose:Event$ GameLoss | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game. +SVar:OppCantWin:Event$ GameWin | ValidPlayer$ Opponent | Layer$ CantHappen | Description$ Opponents can't win the game. K:Reconfigure:5 Oracle:Flying\nEquipped creature has flying and "You can't lose the game and your opponents can't win the game."\nReconfigure {5} diff --git a/forge-gui/res/cardsfolder/upcoming/coiling_rebirth.txt b/forge-gui/res/cardsfolder/c/coiling_rebirth.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/coiling_rebirth.txt rename to forge-gui/res/cardsfolder/c/coiling_rebirth.txt diff --git a/forge-gui/res/cardsfolder/upcoming/communal_brewing.txt b/forge-gui/res/cardsfolder/c/communal_brewing.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/communal_brewing.txt rename to forge-gui/res/cardsfolder/c/communal_brewing.txt diff --git a/forge-gui/res/cardsfolder/upcoming/conduct_electricity.txt b/forge-gui/res/cardsfolder/c/conduct_electricity.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/conduct_electricity.txt rename to forge-gui/res/cardsfolder/c/conduct_electricity.txt diff --git a/forge-gui/res/cardsfolder/upcoming/consumed_by_greed.txt b/forge-gui/res/cardsfolder/c/consumed_by_greed.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/consumed_by_greed.txt rename to forge-gui/res/cardsfolder/c/consumed_by_greed.txt diff --git a/forge-gui/res/cardsfolder/upcoming/corpseberry_cultivator.txt b/forge-gui/res/cardsfolder/c/corpseberry_cultivator.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/corpseberry_cultivator.txt rename to forge-gui/res/cardsfolder/c/corpseberry_cultivator.txt diff --git a/forge-gui/res/cardsfolder/upcoming/coruscation_mage.txt b/forge-gui/res/cardsfolder/c/coruscation_mage.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/coruscation_mage.txt rename to forge-gui/res/cardsfolder/c/coruscation_mage.txt diff --git a/forge-gui/res/cardsfolder/c/cottontail_caretaker.txt b/forge-gui/res/cardsfolder/c/cottontail_caretaker.txt new file mode 100644 index 00000000000..022c6688505 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/cottontail_caretaker.txt @@ -0,0 +1,9 @@ +Name:Cottontail Caretaker +ManaCost:1 W +Types:Creature Rabbit Citizen +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ When CARDNAME enters, choose a white creature card in your hand. That card perpetually gains offspring {1}. +SVar:TrigChoose:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Card.Creature+YouOwn+White | ChoiceTitle$ Choose a white creature card in your hand | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ ChosenCard | PumpZone$ Hand | KW$ Offspring:1 | Duration$ Perpetual | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +Oracle:When Cottontail Caretaker enters, choose a white creature card in your hand. That card perpetually gains offspring {1}. diff --git a/forge-gui/res/cardsfolder/c/courageous_resolve.txt b/forge-gui/res/cardsfolder/c/courageous_resolve.txt index b45bf5c9ae8..b8793abd6bb 100644 --- a/forge-gui/res/cardsfolder/c/courageous_resolve.txt +++ b/forge-gui/res/cardsfolder/c/courageous_resolve.txt @@ -3,8 +3,9 @@ ManaCost:2 W Types:Instant A:SP$ Pump | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to one target creature you control | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDraw | KW$ Protection:Player.PlayerUID_ChosenPlayerUID:ChosenPlayerName | DefinedKW$ Opponent | SpellDescription$ Up to one target creature you control gains protection from each of your opponents until end of turn. Draw a card. (It can't be blocked, targeted, dealt damage, enchanted, or equipped by anything controlled by those players.) SVar:DBDraw:DB$ Draw | SubAbility$ DBEffect -SVar:DBEffect:DB$ Effect | StaticAbilities$ STKeepLife,STCantLose | ConditionCheckSVar$ FatefulHour | ConditionSVarCompare$ LE5 | AILogic$ Fog | SpellDescription$ Fateful hour — If you have 5 or less life, you can't lose life this turn, you can't lose the game this turn, and your opponents can't win the game this turn. +SVar:DBEffect:DB$ Effect | StaticAbilities$ STKeepLife | ReplacementEffects$ DBYouCantLose,DBOppCantWin | ConditionCheckSVar$ FatefulHour | ConditionSVarCompare$ LE5 | AILogic$ Fog | SpellDescription$ Fateful hour — If you have 5 or less life, you can't lose life this turn, you can't lose the game this turn, and your opponents can't win the game this turn. SVar:STKeepLife:Mode$ CantLoseLife | ValidPlayer$ You | Description$ You can't lose life this turn. -SVar:STCantLose:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. & Your opponents can't win the game. | Description$ You can't lose the game. Your opponents can't win the game. +SVar:DBYouCantLose:Event$ GameLoss | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +SVar:DBOppCantWin:Event$ GameWin | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. SVar:FatefulHour:Count$YourLifeTotal Oracle:Up to one target creature you control gains protection from each of your opponents until end of turn. Draw a card. (It can't be blocked, targeted, dealt damage, enchanted, or equipped by anything controlled by those players.)\nFateful hour — If you have 5 or less life, you can't lose life this turn, you can't lose the game this turn, and your opponents can't win the game this turn. diff --git a/forge-gui/res/cardsfolder/c/covetous_castaway_ghostly_castigator.txt b/forge-gui/res/cardsfolder/c/covetous_castaway_ghostly_castigator.txt index b911c4cd995..b814528a2d6 100644 --- a/forge-gui/res/cardsfolder/c/covetous_castaway_ghostly_castigator.txt +++ b/forge-gui/res/cardsfolder/c/covetous_castaway_ghostly_castigator.txt @@ -17,8 +17,8 @@ Colors:blue Types:Creature Spirit PT:3/4 K:Flying -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters, shuffle up to three target cards from your graveyard into your library. -SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouOwn | TgtPrompt$ Select up to three target cards from your graveyard | TargetMin$ 0 | TargetMax$ 3 | Shuffle$ True +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters, you may shuffle up to three target cards from your graveyard into your library. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouOwn | TgtPrompt$ Select up to three target cards from your graveyard | TargetMin$ 0 | TargetMax$ 3 | Shuffle$ True | ShuffleNonMandatory$ True R:Event$ Moved | ValidCard$ Card.Self | Destination$ Graveyard | ReplaceWith$ Exile | Description$ If CARDNAME would be put into a graveyard from anywhere, exile it instead. SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard -Oracle:Flying\nWhen Ghostly Castigator enters, shuffle up to three target cards from your graveyard into your library.\nIf Ghostly Castigator would be put into a graveyard from anywhere, exile it instead. +Oracle:Flying\nWhen Ghostly Castigator enters, you may shuffle up to three target cards from your graveyard into your library.\nIf Ghostly Castigator would be put into a graveyard from anywhere, exile it instead. diff --git a/forge-gui/res/cardsfolder/upcoming/cruelclaws_heist.txt b/forge-gui/res/cardsfolder/c/cruelclaws_heist.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/cruelclaws_heist.txt rename to forge-gui/res/cardsfolder/c/cruelclaws_heist.txt diff --git a/forge-gui/res/cardsfolder/upcoming/crumb_and_get_it.txt b/forge-gui/res/cardsfolder/c/crumb_and_get_it.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/crumb_and_get_it.txt rename to forge-gui/res/cardsfolder/c/crumb_and_get_it.txt diff --git a/forge-gui/res/cardsfolder/upcoming/crystal_skull_isu_spyglass.txt b/forge-gui/res/cardsfolder/c/crystal_skull_isu_spyglass.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/crystal_skull_isu_spyglass.txt rename to forge-gui/res/cardsfolder/c/crystal_skull_isu_spyglass.txt diff --git a/forge-gui/res/cardsfolder/upcoming/curious_forager.txt b/forge-gui/res/cardsfolder/c/curious_forager.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/curious_forager.txt rename to forge-gui/res/cardsfolder/c/curious_forager.txt diff --git a/forge-gui/res/cardsfolder/upcoming/daggerfang_duo.txt b/forge-gui/res/cardsfolder/d/daggerfang_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/daggerfang_duo.txt rename to forge-gui/res/cardsfolder/d/daggerfang_duo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/daring_waverider.txt b/forge-gui/res/cardsfolder/d/daring_waverider.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/daring_waverider.txt rename to forge-gui/res/cardsfolder/d/daring_waverider.txt diff --git a/forge-gui/res/cardsfolder/upcoming/darkstar_augur.txt b/forge-gui/res/cardsfolder/d/darkstar_augur.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/darkstar_augur.txt rename to forge-gui/res/cardsfolder/d/darkstar_augur.txt diff --git a/forge-gui/res/cardsfolder/d/darkstar_banisher.txt b/forge-gui/res/cardsfolder/d/darkstar_banisher.txt new file mode 100644 index 00000000000..6b8e6ead1f0 --- /dev/null +++ b/forge-gui/res/cardsfolder/d/darkstar_banisher.txt @@ -0,0 +1,11 @@ +Name:Darkstar Banisher +ManaCost:1 W B +Types:Creature Bat Cleric +PT:2/2 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target nonland permanent with mana value 3 or less an opponent controls. +SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Permanent.nonLand+OppCtrl+cmcLE3 | RememberChanged$ True | TgtPrompt$ Select target nonland permanent with mana value 3 or less an opponent controls +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When CARDNAME leaves the battlefield, the exiled card's owner seeks a card that shares a card type with the exiled card. +SVar:TrigSeek:DB$ Seek | Defined$ RememberedOwner | Type$ Card.sharesCardTypeWith Remembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Flying\nWhen Darkstar Banisher enters, exile target nonland permanent with mana value 3 or less an opponent controls.\nWhen Darkstar Banisher leaves the battlefield, the exiled card's owner seeks a card that shares a card type with the exiled card. diff --git a/forge-gui/res/cardsfolder/upcoming/dawns_truce.txt b/forge-gui/res/cardsfolder/d/dawns_truce.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dawns_truce.txt rename to forge-gui/res/cardsfolder/d/dawns_truce.txt diff --git a/forge-gui/res/cardsfolder/upcoming/dazzling_denial.txt b/forge-gui/res/cardsfolder/d/dazzling_denial.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dazzling_denial.txt rename to forge-gui/res/cardsfolder/d/dazzling_denial.txt diff --git a/forge-gui/res/cardsfolder/d/dazzling_flameweaver.txt b/forge-gui/res/cardsfolder/d/dazzling_flameweaver.txt new file mode 100644 index 00000000000..91c67491458 --- /dev/null +++ b/forge-gui/res/cardsfolder/d/dazzling_flameweaver.txt @@ -0,0 +1,12 @@ +Name:Dazzling Flameweaver +ManaCost:2 B R +Types:Creature Lizard Warlock +PT:4/4 +K:Menace +K:Ward:PayLife<3> +T:Mode$ DamageDoneOnce | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigConjure | TriggerZones$ Battlefield | TriggerDescription$ Whenever one or more creatures you control deal combat damage to a player, conjure a random card from CARDNAME's spellbook into exile. You may play that card this turn. +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | AtRandom$ True | Spellbook$ Blade Juggler,Body Count,Dead Revels,Drill Bit,Hackrobat,Light Up the Stage,Rafter Demon,Rix Maadi Reveler,Skewer the Critics,Spawn of Mayhem,Spikewheel Acrobat | RememberMade$ True | SubAbility$ DBEffect | Zone$ Exile +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBCleanup | ExileOnMoved$ Exile +SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play the exiled card this turn. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Menace\nWard — Pay 3 life.\nWhenever one or more creatures you control deal combat damage to a player, conjure a random card from Dazzling Flameweaver's spellbook into exile. You may play that card this turn. diff --git a/forge-gui/res/cardsfolder/d/deep_dish_pizza.txt b/forge-gui/res/cardsfolder/d/deep_dish_pizza.txt new file mode 100644 index 00000000000..d89d3a90ae8 --- /dev/null +++ b/forge-gui/res/cardsfolder/d/deep_dish_pizza.txt @@ -0,0 +1,9 @@ +Name:Deep Dish Pizza +ManaCost:no cost +Types:Artifact Food +K:Suspend:2:2 +A:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME> | LifeAmount$ 3 | SubAbility$ DBDraw | SpellDescription$ Gain 3 life, draw three cards, and CARDNAME deals 3 damage to each opponent. +SVar:DBDraw:DB$ Draw | NumCards$ 3 | SubAbility$ DBDamage +SVar:DBDamage:DB$ DealDamage | Defined$ Opponent | NumDmg$ 3 +DeckHas:Ability$LifeGain|Sacrifice +Oracle:Suspend 2—{2} (Deep Dish Pizza has no mana cost and must be suspended.)\n{2}, {T}, Sacrifice Deep Dish Pizza: Gain 3 life, draw three cards, and Deep Dish Pizza deals 3 damage to each opponent. diff --git a/forge-gui/res/cardsfolder/d/delifs_cone.txt b/forge-gui/res/cardsfolder/d/delifs_cone.txt index ac2f87123a6..ed5216d0155 100644 --- a/forge-gui/res/cardsfolder/d/delifs_cone.txt +++ b/forge-gui/res/cardsfolder/d/delifs_cone.txt @@ -3,8 +3,9 @@ ManaCost:0 Types:Artifact A:AB$ Effect | Cost$ T Sac<1/CARDNAME> | ValidTgts$ Creature.YouCtrl | Triggers$ TrigAttackerUnblocked | RememberObjects$ Targeted | ForgetOnMoved$ Battlefield | SpellDescription$ This turn, when target creature you control attacks and isn't blocked, you may gain life equal to its power. If you do, it assigns no combat damage this turn. SVar:TrigAttackerUnblocked:Mode$ AttackerUnblocked | ValidCard$ Card.IsRemembered | Execute$ GainLife | OptionalDecider$ You | TriggerDescription$ This turn, when that creature attacks and isn't blocked, you may gain life equal to its power. If you do, it assigns no combat damage this turn. -SVar:GainLife:DB$ GainLife | Defined$ You | LifeAmount$ DelifX | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ HIDDEN CARDNAME assigns no combat damage | StackDescription$ {c:Remembered} assigns no combat damage this turn. +SVar:GainLife:DB$ GainLife | Defined$ You | LifeAmount$ DelifX | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ SNoCombatDamage | ForgetOnMoved$ Battlefield +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.IsRemembered | Description$ Remembered creature assigns no combat damage this turn. SVar:DelifX:Remembered$CardPower AI:RemoveDeck:All Oracle:{T}, Sacrifice Delif's Cone: This turn, when target creature you control attacks and isn't blocked, you may gain life equal to its power. If you do, it assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/d/delifs_cube.txt b/forge-gui/res/cardsfolder/d/delifs_cube.txt index 2f8b325c7b4..bb95186cc49 100644 --- a/forge-gui/res/cardsfolder/d/delifs_cube.txt +++ b/forge-gui/res/cardsfolder/d/delifs_cube.txt @@ -2,8 +2,9 @@ Name:Delif's Cube ManaCost:1 Types:Artifact A:AB$ Effect | Cost$ 2 T | ValidTgts$ Creature.YouCtrl | Triggers$ TrigAttackerUnblocked | ExileOnMoved$ Battlefield | RememberObjects$ Targeted | SpellDescription$ This turn, when target creature you control attacks and isn't blocked, it assigns no combat damage this turn and you put a cube counter on CARDNAME. -SVar:TrigAttackerUnblocked:Mode$ AttackerUnblocked | ValidCard$ Card.IsRemembered | Execute$ DBPump | TriggerDescription$ This turn, when targeted creature attacks and isn't blocked, it assigns no combat damage this turn and you put a cube counter on EFFECTSOURCE. -SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ HIDDEN CARDNAME assigns no combat damage | SubAbility$ PutCounter +SVar:TrigAttackerUnblocked:Mode$ AttackerUnblocked | ValidCard$ Card.IsRemembered | Execute$ DBNoCombatDamage | TriggerDescription$ This turn, when targeted creature attacks and isn't blocked, it assigns no combat damage this turn and you put a cube counter on EFFECTSOURCE. +SVar:DBNoCombatDamage:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ SNoCombatDamage | ForgetOnMoved$ Battlefield | SubAbility$ PutCounter +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.IsRemembered | Description$ Remembered creature assigns no combat damage this turn. SVar:PutCounter:DB$ PutCounter | Defined$ EffectSource | CounterType$ CUBE | CounterNum$ 1 A:AB$ Regenerate | Cost$ 2 SubCounter<1/CUBE> | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Regenerate target creature. AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/upcoming/desmond_miles.txt b/forge-gui/res/cardsfolder/d/desmond_miles.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/desmond_miles.txt rename to forge-gui/res/cardsfolder/d/desmond_miles.txt diff --git a/forge-gui/res/cardsfolder/upcoming/desynchronization.txt b/forge-gui/res/cardsfolder/d/desynchronization.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/desynchronization.txt rename to forge-gui/res/cardsfolder/d/desynchronization.txt diff --git a/forge-gui/res/cardsfolder/upcoming/detained_by_legionnaires.txt b/forge-gui/res/cardsfolder/d/detained_by_legionnaires.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/detained_by_legionnaires.txt rename to forge-gui/res/cardsfolder/d/detained_by_legionnaires.txt diff --git a/forge-gui/res/cardsfolder/d/devious_cover_up.txt b/forge-gui/res/cardsfolder/d/devious_cover_up.txt index 73f1b2f340c..01c2755b84b 100644 --- a/forge-gui/res/cardsfolder/d/devious_cover_up.txt +++ b/forge-gui/res/cardsfolder/d/devious_cover_up.txt @@ -2,5 +2,5 @@ Name:Devious Cover-Up ManaCost:2 U U Types:Instant A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | Destination$ Exile | SubAbility$ DBChangeZone | SpellDescription$ Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may shuffle up to four target cards from your graveyard into your library. -SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouCtrl | TgtPrompt$ Select target card from your graveyard | TargetMin$ 0 | TargetMax$ 4 | Shuffle$ True +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouCtrl | TgtPrompt$ Select target card from your graveyard | TargetMin$ 0 | TargetMax$ 4 | Shuffle$ True | ShuffleNonMandatory$ True Oracle:Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may shuffle up to four target cards from your graveyard into your library. diff --git a/forge-gui/res/cardsfolder/upcoming/dewdrop_cure.txt b/forge-gui/res/cardsfolder/d/dewdrop_cure.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dewdrop_cure.txt rename to forge-gui/res/cardsfolder/d/dewdrop_cure.txt diff --git a/forge-gui/res/cardsfolder/d/dimir_strandcatcher.txt b/forge-gui/res/cardsfolder/d/dimir_strandcatcher.txt index d50099bd47d..73a1db1b672 100644 --- a/forge-gui/res/cardsfolder/d/dimir_strandcatcher.txt +++ b/forge-gui/res/cardsfolder/d/dimir_strandcatcher.txt @@ -8,8 +8,8 @@ SVar:TrigSurveil:DB$ Surveil | Amount$ X T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | CheckSVar$ Y | SVarCompare$ GE3 | Execute$ TrigDraw | TriggerDescription$ At the beginning of each end step, if three or more cards were put into your graveyard from anywhere other than the battlefield this turn, draw a card. SVar:TrigDraw:DB$ Draw SVar:X:PlayerCountPropertyYou$OpponentsAttackedThisCombat -SVar:Y:Count$ThisTurnEntered_Graveyard_Card.YouOwn/Minus.CountHand -SVar:CountHand:Count$ThisTurnEntered_Graveyard_from_Battlefield_Card.YouOwn +SVar:Y:Count$ThisTurnEntered_Graveyard_Card.YouOwn/Minus.Z +SVar:Z:Count$ThisTurnEntered_Graveyard_from_Battlefield_Card.YouOwn DeckHints:Ability$Mill DeckHas:Ability$Surveil|Graveyard Oracle:Flying\nWhenever you attack, surveil X, where X is the number of opponents being attacked.\nAt the beginning of each end step, if three or more cards were put into your graveyard from anywhere other than the battlefield this turn, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/dire_downdraft.txt b/forge-gui/res/cardsfolder/d/dire_downdraft.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dire_downdraft.txt rename to forge-gui/res/cardsfolder/d/dire_downdraft.txt diff --git a/forge-gui/res/cardsfolder/upcoming/diresight.txt b/forge-gui/res/cardsfolder/d/diresight.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/diresight.txt rename to forge-gui/res/cardsfolder/d/diresight.txt diff --git a/forge-gui/res/cardsfolder/d/disguise_agent.txt b/forge-gui/res/cardsfolder/d/disguise_agent.txt new file mode 100644 index 00000000000..efb76589dcc --- /dev/null +++ b/forge-gui/res/cardsfolder/d/disguise_agent.txt @@ -0,0 +1,6 @@ +Name:Disguise Agent +ManaCost:1 U +Types:Creature Vedalken Detective +PT:1/3 +S:Mode$ Continuous | Affected$ Card.YouOwn+IsCommander | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | AddKeyword$ Disguise:CardManaCost | Description$ Commanders you own have disguise. Their disguise cost is equal to their mana cost. +Oracle:Commanders you own have disguise. Their disguise cost is equal to their mana cost. diff --git a/forge-gui/res/cardsfolder/upcoming/distract_the_guards.txt b/forge-gui/res/cardsfolder/d/distract_the_guards.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/distract_the_guards.txt rename to forge-gui/res/cardsfolder/d/distract_the_guards.txt diff --git a/forge-gui/res/cardsfolder/d/dog_umbra.txt b/forge-gui/res/cardsfolder/d/dog_umbra.txt index 6ce4a84b29b..86b18b326e6 100644 --- a/forge-gui/res/cardsfolder/d/dog_umbra.txt +++ b/forge-gui/res/cardsfolder/d/dog_umbra.txt @@ -5,5 +5,5 @@ K:Flash K:Enchant creature A:SP$ Attach | ValidTgts$ Creature S:Mode$ Continuous | Affected$ Creature.EnchantedBy+ControlledBy Player.Other | AddHiddenKeyword$ CARDNAME can't attack or block. | Description$ As long as another player controls enchanted creature, it can't attack or block. Otherwise, CARDNAME has umbra armor. (If enchanted creature would be destroyed, instead remove all damage from it and destroy this Aura.) -S:Mode$ Continuous | Affected$ Card.Self | IsPresent$ Creature.YouCtrl+EnchantedBy | AddKeyword$ Umbra Armor | Secondary$ True | Description$ As long as another player controls enchanted creature, it can't attack or block. Otherwise, CARDNAME has umbra armor. (If enchanted creature would be destroyed, instead remove all damage from it and destroy this Aura.) +S:Mode$ Continuous | Affected$ Card.Self | IsPresent$ Creature.YouCtrl+EnchantedBy | AddKeyword$ Umbra armor | Secondary$ True | Description$ As long as another player controls enchanted creature, it can't attack or block. Otherwise, CARDNAME has umbra armor. (If enchanted creature would be destroyed, instead remove all damage from it and destroy this Aura.) Oracle:Flash\nEnchant creature\nAs long as another player controls enchanted creature, it can't attack or block. Otherwise, Dog Umbra has umbra armor. (If enchanted creature would be destroyed, instead remove all damage from it and destroy this Aura.) diff --git a/forge-gui/res/cardsfolder/d/domesticated_mammoth.txt b/forge-gui/res/cardsfolder/d/domesticated_mammoth.txt index b96f6e33acc..68eea20e590 100644 --- a/forge-gui/res/cardsfolder/d/domesticated_mammoth.txt +++ b/forge-gui/res/cardsfolder/d/domesticated_mammoth.txt @@ -3,6 +3,6 @@ ManaCost:1 G Types:Snow Creature Mammoth PT:4/5 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | Static$ True | TriggerDescription$ CARDNAME enters with a token copy of Pacifism attached to it. -SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ pacifism | TokenOwner$ You | AttachedTo$ Self +SVar:TrigToken:DB$ CopyPermanent | DefinedName$ Pacifism | AttachedTo$ Self DeckHas:Ability$Token Oracle:Domesticated Mammoth enters with a token copy of Pacifism attached to it. diff --git a/forge-gui/res/cardsfolder/upcoming/dour_port_mage.txt b/forge-gui/res/cardsfolder/d/dour_port_mage.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dour_port_mage.txt rename to forge-gui/res/cardsfolder/d/dour_port_mage.txt diff --git a/forge-gui/res/cardsfolder/upcoming/downwind_ambusher.txt b/forge-gui/res/cardsfolder/d/downwind_ambusher.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/downwind_ambusher.txt rename to forge-gui/res/cardsfolder/d/downwind_ambusher.txt diff --git a/forge-gui/res/cardsfolder/upcoming/dragonhawk_fates_tempest.txt b/forge-gui/res/cardsfolder/d/dragonhawk_fates_tempest.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dragonhawk_fates_tempest.txt rename to forge-gui/res/cardsfolder/d/dragonhawk_fates_tempest.txt diff --git a/forge-gui/res/cardsfolder/d/dream_thief.txt b/forge-gui/res/cardsfolder/d/dream_thief.txt index bad18d17131..af0ad8fcd7b 100644 --- a/forge-gui/res/cardsfolder/d/dream_thief.txt +++ b/forge-gui/res/cardsfolder/d/dream_thief.txt @@ -5,5 +5,5 @@ PT:2/1 K:Flying T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters, draw a card if you've cast another blue spell this turn. SVar:TrigDraw:DB$ Draw | Defined$ You | ConditionCheckSVar$ X -SVar:X:Count$ThisTurnCast_Card.Other+Blue+YouCtrl +SVar:X:Count$ThisTurnCast_Card.!CastSaSource+Blue+YouCtrl Oracle:Flying\nWhen Dream Thief enters, draw a card if you've cast another blue spell this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/dreamdew_entrancer.txt b/forge-gui/res/cardsfolder/d/dreamdew_entrancer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/dreamdew_entrancer.txt rename to forge-gui/res/cardsfolder/d/dreamdew_entrancer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/driftgloom_coyote.txt b/forge-gui/res/cardsfolder/d/driftgloom_coyote.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/driftgloom_coyote.txt rename to forge-gui/res/cardsfolder/d/driftgloom_coyote.txt diff --git a/forge-gui/res/cardsfolder/upcoming/druid_of_the_spade.txt b/forge-gui/res/cardsfolder/d/druid_of_the_spade.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/druid_of_the_spade.txt rename to forge-gui/res/cardsfolder/d/druid_of_the_spade.txt diff --git a/forge-gui/res/cardsfolder/d/dusk_feaster.txt b/forge-gui/res/cardsfolder/d/dusk_feaster.txt index 6a58f6f9363..726c5ab91ce 100644 --- a/forge-gui/res/cardsfolder/d/dusk_feaster.txt +++ b/forge-gui/res/cardsfolder/d/dusk_feaster.txt @@ -2,8 +2,7 @@ Name:Dusk Feaster ManaCost:5 B B Types:Creature Vampire PT:4/5 -S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 2 | EffectZone$ All | CheckSVar$ X | SVarCompare$ GE4 | Description$ Delirium — This spell costs {2} less to cast if there are four or more card types among cards in your graveyard. -SVar:X:Count$ValidGraveyard Card.YouOwn$CardTypes +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 2 | EffectZone$ All | Condition$ Delirium | Description$ Delirium — This spell costs {2} less to cast if there are four or more card types among cards in your graveyard. K:Flying DeckHints:Ability$Graveyard|Discard DeckHas:Ability$Delirium diff --git a/forge-gui/res/cardsfolder/d/dwarven_hold.txt b/forge-gui/res/cardsfolder/d/dwarven_hold.txt index 3332bd5ece0..0a4a5c1e1ce 100644 --- a/forge-gui/res/cardsfolder/d/dwarven_hold.txt +++ b/forge-gui/res/cardsfolder/d/dwarven_hold.txt @@ -4,7 +4,7 @@ Types:Land R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True K:You may choose not to untap CARDNAME during your untap step. -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Card.Self+tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. SVar:TrigStore:DB$ PutCounter | Defined$ Self | CounterType$ STORAGE | CounterNum$ 1 A:AB$ Mana | Cost$ T SubCounter | Produced$ R | Amount$ X | AILogic$ ManaRitualBattery | SpellDescription$ Add {R} for each storage counter removed this way. SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/d/dwarven_vigilantes.txt b/forge-gui/res/cardsfolder/d/dwarven_vigilantes.txt index 3112b656c60..c5ee9c1a294 100644 --- a/forge-gui/res/cardsfolder/d/dwarven_vigilantes.txt +++ b/forge-gui/res/cardsfolder/d/dwarven_vigilantes.txt @@ -4,6 +4,7 @@ Types:Creature Dwarf PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may have it deal damage equal to its power to target creature. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:X:Count$CardPower Oracle:Whenever Dwarven Vigilantes attacks and isn't blocked, you may have it deal damage equal to its power to target creature. If you do, Dwarven Vigilantes assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/eagle_vision.txt b/forge-gui/res/cardsfolder/e/eagle_vision.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/eagle_vision.txt rename to forge-gui/res/cardsfolder/e/eagle_vision.txt diff --git a/forge-gui/res/cardsfolder/upcoming/early_winter.txt b/forge-gui/res/cardsfolder/e/early_winter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/early_winter.txt rename to forge-gui/res/cardsfolder/e/early_winter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/echoing_assault.txt b/forge-gui/res/cardsfolder/e/echoing_assault.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/echoing_assault.txt rename to forge-gui/res/cardsfolder/e/echoing_assault.txt diff --git a/forge-gui/res/cardsfolder/upcoming/eddymurk_crab.txt b/forge-gui/res/cardsfolder/e/eddymurk_crab.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/eddymurk_crab.txt rename to forge-gui/res/cardsfolder/e/eddymurk_crab.txt diff --git a/forge-gui/res/cardsfolder/upcoming/edward_kenway.txt b/forge-gui/res/cardsfolder/e/edward_kenway.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/edward_kenway.txt rename to forge-gui/res/cardsfolder/e/edward_kenway.txt diff --git a/forge-gui/res/cardsfolder/upcoming/eivor_wolf_kissed.txt b/forge-gui/res/cardsfolder/e/eivor_wolf_kissed.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/eivor_wolf_kissed.txt rename to forge-gui/res/cardsfolder/e/eivor_wolf_kissed.txt diff --git a/forge-gui/res/cardsfolder/e/elemental_my_dear.txt b/forge-gui/res/cardsfolder/e/elemental_my_dear.txt new file mode 100644 index 00000000000..b35dcaa9e7d --- /dev/null +++ b/forge-gui/res/cardsfolder/e/elemental_my_dear.txt @@ -0,0 +1,12 @@ +Name:Elemental, My Dear +ManaCost:X U U +Types:Sorcery +A:SP$ Investigate | Num$ X | SubAbility$ DBToken | SpellDescription$ Investigate X times, then create an 0/0 Blue Elemental creature token. +SVar:DBToken:DB$ Token | TokenScript$ u_0_0_elemental | RememberTokens$ True | SubAbility$ DBPutCounters +SVar:DBPutCounters:DB$ PutCounter | Defined$ Remembered | CounterType$ P1P1 | CounterNum$ Y | StackDescription$ SpellDescription | SubAbility$ DBCleanup | SpellDescription$ Put +1/+1 counters on that token equal to the number of Clues you control. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$xPaid +SVar:Y:Count$Valid Clue.YouCtrl +DeckHas:Ability$Token|Counters & Type$Elemental|Clue +DeckHints:Type$Clue +Oracle:Investigate X times, then create an 0/0 Blue Elemental creature token. Put +1/+1 counters on that token equal to the number of Clues you control. diff --git a/forge-gui/res/cardsfolder/e/elspeths_smite.txt b/forge-gui/res/cardsfolder/e/elspeths_smite.txt index d503c1659c8..e39d0268bf8 100644 --- a/forge-gui/res/cardsfolder/e/elspeths_smite.txt +++ b/forge-gui/res/cardsfolder/e/elspeths_smite.txt @@ -1,5 +1,5 @@ Name:Elspeth's Smite ManaCost:W Types:Instant -A:SP$ DealDamage | ValidTgts$ Creature.attacking,Creature.blocking | TgtPrompt$ Select target attacking or blocking creature | NumDmg$ 3 | ReplaceDyingDefined$ Targeted.Creature | SpellDescription$ CARDNAME deals 3 damage to target attacking or blocking creature. If that creature would die this turn, exile it instead. +A:SP$ DealDamage | ValidTgts$ Creature.attacking,Creature.blocking | TgtPrompt$ Select target attacking or blocking creature | NumDmg$ 3 | ReplaceDyingDefined$ Targeted | SpellDescription$ CARDNAME deals 3 damage to target attacking or blocking creature. If that creature would die this turn, exile it instead. Oracle:Elspeth's Smite deals 3 damage to target attacking or blocking creature. If that creature would die this turn, exile it instead. diff --git a/forge-gui/res/cardsfolder/upcoming/eluge_the_shoreless_sea.txt b/forge-gui/res/cardsfolder/e/eluge_the_shoreless_sea.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/eluge_the_shoreless_sea.txt rename to forge-gui/res/cardsfolder/e/eluge_the_shoreless_sea.txt diff --git a/forge-gui/res/cardsfolder/upcoming/emberheart_challenger.txt b/forge-gui/res/cardsfolder/e/emberheart_challenger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/emberheart_challenger.txt rename to forge-gui/res/cardsfolder/e/emberheart_challenger.txt diff --git a/forge-gui/res/cardsfolder/upcoming/emrakul's messenger.txt b/forge-gui/res/cardsfolder/e/emrakul's messenger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/emrakul's messenger.txt rename to forge-gui/res/cardsfolder/e/emrakul's messenger.txt diff --git a/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt b/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt index c8d187a9692..67f47a7892a 100644 --- a/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt +++ b/forge-gui/res/cardsfolder/e/enhanced_surveillance.txt @@ -1,9 +1,7 @@ Name:Enhanced Surveillance ManaCost:1 U Types:Enchantment -R:Event$ Surveil | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ AddTwoMore | Description$ You may look at an additional two cards each time you surveil. -SVar:AddTwoMore:DB$ ReplaceEffect | VarName$ SurveilNum | VarValue$ X -SVar:X:ReplaceCount$SurveilNum/Plus.2 +S:Mode$ SurveilNum | Num$ 2 | ValidPlayer$ You | Optional$ True | Description$ You may look at an additional two cards each time you surveil. A:AB$ ChangeZoneAll | Cost$ Exile<1/CARDNAME> | ChangeType$ Card.YouOwn | Origin$ Graveyard | Destination$ Library | Shuffle$ True | SpellDescription$ Shuffle your graveyard into your library. DeckNeeds:Ability$Surveil Oracle:You may look at an additional two cards each time you surveil.\nExile Enhanced Surveillance: Shuffle your graveyard into your library. diff --git a/forge-gui/res/cardsfolder/e/eomer_marshal_of_rohan.txt b/forge-gui/res/cardsfolder/e/eomer_marshal_of_rohan.txt index a1ad40d23de..53137f167cd 100644 --- a/forge-gui/res/cardsfolder/e/eomer_marshal_of_rohan.txt +++ b/forge-gui/res/cardsfolder/e/eomer_marshal_of_rohan.txt @@ -3,7 +3,7 @@ ManaCost:2 R R Types:Legendary Creature Human Knight PT:4/4 K:Haste -T:Mode$ ChangesZoneAll | Origin$ Battlefield | Destination$ Graveyard | ValidCards$ Creature.attackingLKI+Legendary+Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigUntapAll | ActivationLimit$ 1 | TriggerDescription$ Whenever one or more other attacking legendary creatures you control die, untap all creatures you control. After this phase, there is an additional combat phase. This ability triggers only once each turn. +T:Mode$ ChangesZoneAll | Origin$ Battlefield | Destination$ Graveyard | ValidCards$ Creature.attacking+Legendary+Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigUntapAll | ActivationLimit$ 1 | TriggerDescription$ Whenever one or more other attacking legendary creatures you control die, untap all creatures you control. After this phase, there is an additional combat phase. This ability triggers only once each turn. SVar:TrigUntapAll:DB$ UntapAll | ValidCards$ Creature.YouCtrl | SubAbility$ DBAddCombat SVar:DBAddCombat:DB$ AddPhase | ExtraPhase$ Combat | AfterPhase$ EndCombat DeckHints:Type$Legendary diff --git a/forge-gui/res/cardsfolder/e/epicenter.txt b/forge-gui/res/cardsfolder/e/epicenter.txt index e8042cdf87a..fbdff9df38b 100644 --- a/forge-gui/res/cardsfolder/e/epicenter.txt +++ b/forge-gui/res/cardsfolder/e/epicenter.txt @@ -1,7 +1,8 @@ Name:Epicenter ManaCost:4 R Types:Sorcery -A:SP$ Sacrifice | ConditionCheckSVar$ X | ConditionSVarCompare$ LE6 | ValidTgts$ Player | SacValid$ Land | SacMessage$ Land | SubAbility$ DBWasteLand | SpellDescription$ Target player sacrifices a Land. Threshold — Each player sacrifices all lands they control instead if seven or more cards are in your graveyard -SVar:DBWasteLand:DB$ SacrificeAll | Condition$ Threshold | ValidCards$ Land +A:SP$ Branch | ValidTgts$ Player | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE7 | TrueSubAbility$ ThreshWaste | FalseSubAbility$ WasteLand | SpellDescription$ Target player sacrifices a Land. Threshold — Each player sacrifices all lands they control instead if seven or more cards are in your graveyard. +SVar:WasteLand:DB$ Sacrifice | Defined$ Targeted | SacValid$ Land | SacMessage$ Land +SVar:ThreshWaste:DB$ SacrificeAll | ValidCards$ Land SVar:X:Count$InYourYard Oracle:Target player sacrifices a land.\nThreshold — Each player sacrifices all lands they control instead if seven or more cards are in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/escape_detection.txt b/forge-gui/res/cardsfolder/e/escape_detection.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/escape_detection.txt rename to forge-gui/res/cardsfolder/e/escape_detection.txt diff --git a/forge-gui/res/cardsfolder/upcoming/escarpment_fortress.txt b/forge-gui/res/cardsfolder/e/escarpment_fortress.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/escarpment_fortress.txt rename to forge-gui/res/cardsfolder/e/escarpment_fortress.txt diff --git a/forge-gui/res/cardsfolder/upcoming/essence_channeler.txt b/forge-gui/res/cardsfolder/e/essence_channeler.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/essence_channeler.txt rename to forge-gui/res/cardsfolder/e/essence_channeler.txt diff --git a/forge-gui/res/cardsfolder/e/euru_acorn_scrounger.txt b/forge-gui/res/cardsfolder/e/euru_acorn_scrounger.txt new file mode 100644 index 00000000000..c382198b507 --- /dev/null +++ b/forge-gui/res/cardsfolder/e/euru_acorn_scrounger.txt @@ -0,0 +1,10 @@ +Name:Euru, Acorn Scrounger +ManaCost:2 B G +Types:Legendary Creature Squirrel Soldier +PT:3/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigImmediateTrig | TriggerDescription$When CARDNAME enters, you may forage. When you do, conjure a card named Chitterspitter onto the battlefield. +SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ Forage | Execute$ TrigConjure | SpellDescription$ When you do, conjure a card named Chitterspitter onto the battlefield. +SVar:TrigConjure:DB$ MakeCard | Name$ Chitterspitter | TokenCard$ True | Zone$ Battlefield +T:Mode$ DamageDoneOnce | ValidSource$ Squirrel.YouCtrl | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigPutCounterAll | TriggerZones$ Battlefield | TriggerDescription$ Whenever one or more Squirrels you control deal combat damage to a player, you may sacrifice a token. If you do, put an acorn counter on each permanent you control named Chitterspitter. +SVar:TrigPutCounterAll:AB$ PutCounterAll | Cost$ Sac<1/Permanent.token/token> | ValidCards$ Permanent.YouCtrl+namedChitterspitter | CounterType$ ACORN | CounterNum$ 1 +Oracle:When Euru, Acorn Scrounger enters, you may forage. When you do, conjure a card named Chitterspitter onto the battlefield.\nWhenever one or more Squirrels you control deal combat damage to a player, you may sacrifice a token. If you do, put an acorn counter on each permanent you control named Chitterspitter. diff --git a/forge-gui/res/cardsfolder/upcoming/evercoat_ursine.txt b/forge-gui/res/cardsfolder/e/evercoat_ursine.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/evercoat_ursine.txt rename to forge-gui/res/cardsfolder/e/evercoat_ursine.txt diff --git a/forge-gui/res/cardsfolder/e/everybody_lives.txt b/forge-gui/res/cardsfolder/e/everybody_lives.txt index 8e9b6424858..7fed39bb841 100644 --- a/forge-gui/res/cardsfolder/e/everybody_lives.txt +++ b/forge-gui/res/cardsfolder/e/everybody_lives.txt @@ -3,7 +3,8 @@ ManaCost:1 W Types:Instant A:SP$ PumpAll | ValidCards$ Creature | KW$ Hexproof & Indestructible | SubAbility$ DBPump | SpellDescription$ All creatures gain hexproof and indestructible until end of turn. SVar:DBPump:DB$ Pump | Defined$ Player | KW$ Hexproof | SubAbility$ DBEffect | SpellDescription$ Players gain hexproof until end of turn. -SVar:DBEffect:DB$ Effect | StaticAbilities$ STCantLose,STKeepLife | SpellDescription$ Players can't lose life this turn and players can't lose the game or win the game this turn. -SVar:STCantLose:Mode$ Continuous | Affected$ Player | AddKeyword$ You can't lose the game. & Your opponents can't win the game. | Description$ Players can't lose life this turn and players can't lose the game or win the game this turn. +SVar:DBEffect:DB$ Effect | ReplacementEffects$ DBCantLose,DBCantWin | StaticAbilities$ STKeepLife | SpellDescription$ Players can't lose life this turn and players can't lose the game or win the game this turn. +SVar:DBCantLose:Event$ GameLoss | ValidPlayer$ Player | Layer$ CantHappen | Description$ Players can't lose the game or win the game this turn. +SVar:DBCantWin:Event$ GameWin | ValidPlayer$ Player | Layer$ CantHappen | Secondary$ True | Description$ Players can't lose the game or win the game this turn. SVar:STKeepLife:Mode$ CantLoseLife | ValidPlayer$ Player | Description$ Players can't lose life this turn. Oracle:All creatures gain hexproof and indestructible until end of turn. Players gain hexproof until end of turn.\nPlayers can't lose life this turn and players can't lose the game or win the game this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/evie_frye.txt b/forge-gui/res/cardsfolder/e/evie_frye.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/evie_frye.txt rename to forge-gui/res/cardsfolder/e/evie_frye.txt diff --git a/forge-gui/res/cardsfolder/upcoming/excalibur_sword_of_eden.txt b/forge-gui/res/cardsfolder/e/excalibur_sword_of_eden.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/excalibur_sword_of_eden.txt rename to forge-gui/res/cardsfolder/e/excalibur_sword_of_eden.txt diff --git a/forge-gui/res/cardsfolder/e/extinction_event.txt b/forge-gui/res/cardsfolder/e/extinction_event.txt index 2f196aebb24..fb49ac5c482 100644 --- a/forge-gui/res/cardsfolder/e/extinction_event.txt +++ b/forge-gui/res/cardsfolder/e/extinction_event.txt @@ -1,7 +1,6 @@ Name:Extinction Event ManaCost:3 B Types:Sorcery -A:SP$ GenericChoice | Choices$ Odd,Even | Defined$ You | StackDescription$ SpellDescription | SpellDescription$ Choose odd or even. Exile each creature with mana value of the chosen quality. (Zero is even.) -SVar:Odd:DB$ ChangeZoneAll | ChangeType$ Creature.cmcOdd | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Odd -SVar:Even:DB$ ChangeZoneAll | ChangeType$ Creature.cmcEven | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Even +A:SP$ ChooseEvenOdd | StackDescription$ SpellDescription | SubAbility$ DBExile | SpellDescription$ Choose odd or even. Exile each creature with mana value of the chosen quality. (Zero is even.) +SVar:DBExile:DB$ ChangeZoneAll | ChangeType$ Creature.cmcChosenEvenOdd | Origin$ Battlefield | Destination$ Exile Oracle:Choose odd or even. Exile each creature with mana value of the chosen quality. (Zero is even.) diff --git a/forge-gui/res/cardsfolder/upcoming/ezio_auditore_da_firenze.txt b/forge-gui/res/cardsfolder/e/ezio_auditore_da_firenze.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ezio_auditore_da_firenze.txt rename to forge-gui/res/cardsfolder/e/ezio_auditore_da_firenze.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ezio_brash_novice.txt b/forge-gui/res/cardsfolder/e/ezio_brash_novice.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ezio_brash_novice.txt rename to forge-gui/res/cardsfolder/e/ezio_brash_novice.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fall_of_the_first_civilization.txt b/forge-gui/res/cardsfolder/f/fall_of_the_first_civilization.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fall_of_the_first_civilization.txt rename to forge-gui/res/cardsfolder/f/fall_of_the_first_civilization.txt diff --git a/forge-gui/res/cardsfolder/f/farrels_mantle.txt b/forge-gui/res/cardsfolder/f/farrels_mantle.txt index ac24fabf591..53889e5f6f4 100644 --- a/forge-gui/res/cardsfolder/f/farrels_mantle.txt +++ b/forge-gui/res/cardsfolder/f/farrels_mantle.txt @@ -3,8 +3,9 @@ ManaCost:2 W Types:Enchantment Aura K:Enchant creature A:SP$ Attach | Cost$ 2 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | AILogic$ Pump -T:Mode$ AttackerUnblocked | ValidCard$ Creature.EnchantedBy | Execute$ FarrelDmg | TriggerController$ EnchantedController | OptionalDecider$ EnchantedController | TriggerDescription$ Whenever enchanted creature attacks and isn't blocked, its controller may have it deal damage equal to its power plus 2 to another target creature. If that player does, the attacking creature assigns no combat damage this turn. -SVar:FarrelDmg:DB$ DealDamage | ValidTgts$ Creature.NotTriggeredAttacker | TgtPrompt$ Select another target creature | NumDmg$ FarrelX | DamageSource$ TriggeredAttackerLKICopy | SubAbility$ FarrelPump -SVar:FarrelPump:DB$ Pump | Defined$ TriggeredAttackerLKICopy | KW$ HIDDEN CARDNAME assigns no combat damage +T:Mode$ AttackerUnblocked | ValidCard$ Creature.EnchantedBy | Execute$ FarrelDmg | OptionalDecider$ EnchantedController | TriggerDescription$ Whenever enchanted creature attacks and isn't blocked, its controller may have it deal damage equal to its power plus 2 to another target creature. If that player does, the attacking creature assigns no combat damage this turn. +SVar:FarrelDmg:DB$ DealDamage | ValidTgts$ Creature.NotTriggeredAttacker | TgtPrompt$ Select another target creature | NumDmg$ FarrelX | DamageSource$ TriggeredAttackerLKICopy | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | RememberObjects$ TriggeredAttackerLKICopy | StaticAbilities$ SNoCombatDamage | ForgetOnMoved$ Battlefield +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.IsRemembered | Description$ Remembered creature assigns no combat damage this turn. SVar:FarrelX:TriggeredAttacker$CardPower/Plus.2 Oracle:Enchant creature\nWhenever enchanted creature attacks and isn't blocked, its controller may have it deal damage equal to its power plus 2 to another target creature. If that player does, the attacking creature assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/f/farrels_zealot.txt b/forge-gui/res/cardsfolder/f/farrels_zealot.txt index 5578d0209c9..fec6bccbee3 100644 --- a/forge-gui/res/cardsfolder/f/farrels_zealot.txt +++ b/forge-gui/res/cardsfolder/f/farrels_zealot.txt @@ -4,5 +4,6 @@ Types:Creature Human PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may have it deal 3 damage to target creature. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 3 | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. Oracle:Whenever Farrel's Zealot attacks and isn't blocked, you may have it deal 3 damage to target creature. If you do, Farrel's Zealot assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/f/farsight_mask.txt b/forge-gui/res/cardsfolder/f/farsight_mask.txt index 2122772ca1b..4cf16960038 100644 --- a/forge-gui/res/cardsfolder/f/farsight_mask.txt +++ b/forge-gui/res/cardsfolder/f/farsight_mask.txt @@ -1,6 +1,6 @@ Name:Farsight Mask ManaCost:5 Types:Artifact -T:Mode$ DamageDone | ValidSource$ Card.OppCtrl,Emblem.OppCtrl | ValidTarget$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | IsPresent$ Card.Self+untapped | TriggerDescription$ Whenever a source an opponent controls deals damage to you, if CARDNAME is untapped, you may draw a card. +T:Mode$ DamageDone | ValidSource$ Card.OppCtrl,Emblem.OppCtrl | ValidTarget$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | PresentDefined$ Self | IsPresent$ Card.untapped | TriggerDescription$ Whenever a source an opponent controls deals damage to you, if CARDNAME is untapped, you may draw a card. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 Oracle:Whenever a source an opponent controls deals damage to you, if Farsight Mask is untapped, you may draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/feather_of_flight.txt b/forge-gui/res/cardsfolder/f/feather_of_flight.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/feather_of_flight.txt rename to forge-gui/res/cardsfolder/f/feather_of_flight.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fecund_greenshell.txt b/forge-gui/res/cardsfolder/f/fecund_greenshell.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fecund_greenshell.txt rename to forge-gui/res/cardsfolder/f/fecund_greenshell.txt diff --git a/forge-gui/res/cardsfolder/upcoming/feed_the_cycle.txt b/forge-gui/res/cardsfolder/f/feed_the_cycle.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/feed_the_cycle.txt rename to forge-gui/res/cardsfolder/f/feed_the_cycle.txt diff --git a/forge-gui/res/cardsfolder/f/feign_death.txt b/forge-gui/res/cardsfolder/f/feign_death.txt index b8a29a88627..c887f725e71 100644 --- a/forge-gui/res/cardsfolder/f/feign_death.txt +++ b/forge-gui/res/cardsfolder/f/feign_death.txt @@ -3,6 +3,5 @@ ManaCost:B Types:Instant A:SP$ Animate | Triggers$ DiesTrigger | ValidTgts$ Creature | StackDescription$ Until end of turn, {c:Targeted} gains "When this creature dies, return it to the battlefield tapped under its owner's control with a +1/+1 counter on it." | SpellDescription$ Until end of turn, target creature gains "When this creature dies, return it to the battlefield tapped under its owner's control with a +1/+1 counter on it." SVar:DiesTrigger:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When this creature dies, return it to the battlefield tapped under its owner's control with a +1/+1 counter on it. -SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ TriggeredNewCardLKICopy | SubAbility$ TrigPuCounter -SVar:TrigPuCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 | Defined$ TriggeredNewCardLKICopy +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ TriggeredNewCardLKICopy | WithCountersType$ P1P1 Oracle:Until end of turn, target creature gains "When this creature dies, return it to the battlefield tapped under its owner's control with a +1/+1 counter on it." diff --git a/forge-gui/res/cardsfolder/upcoming/fell.txt b/forge-gui/res/cardsfolder/f/fell.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fell.txt rename to forge-gui/res/cardsfolder/f/fell.txt diff --git a/forge-gui/res/cardsfolder/upcoming/festival_of_embers.txt b/forge-gui/res/cardsfolder/f/festival_of_embers.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/festival_of_embers.txt rename to forge-gui/res/cardsfolder/f/festival_of_embers.txt diff --git a/forge-gui/res/cardsfolder/f/fetching_garden.txt b/forge-gui/res/cardsfolder/f/fetching_garden.txt new file mode 100644 index 00000000000..6685fc8d97e --- /dev/null +++ b/forge-gui/res/cardsfolder/f/fetching_garden.txt @@ -0,0 +1,6 @@ +Name:Fetching Garden +ManaCost:no cost +Types:Land Forest Plains +R:Event$ Moved | ValidCard$ Card.Self | ValidCause$ LandAbility.YouCtrl | Origin$ Hand | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped if it was played from your hand. +SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True +Oracle:Fetching Garden enters tapped if it was played from your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/finch_formation.txt b/forge-gui/res/cardsfolder/f/finch_formation.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/finch_formation.txt rename to forge-gui/res/cardsfolder/f/finch_formation.txt diff --git a/forge-gui/res/cardsfolder/upcoming/finneas_ace_archer.txt b/forge-gui/res/cardsfolder/f/finneas_ace_archer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/finneas_ace_archer.txt rename to forge-gui/res/cardsfolder/f/finneas_ace_archer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fireglass_mentor.txt b/forge-gui/res/cardsfolder/f/fireglass_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fireglass_mentor.txt rename to forge-gui/res/cardsfolder/f/fireglass_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fishers_talent.txt b/forge-gui/res/cardsfolder/f/fishers_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fishers_talent.txt rename to forge-gui/res/cardsfolder/f/fishers_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/flamecache_gecko.txt b/forge-gui/res/cardsfolder/f/flamecache_gecko.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/flamecache_gecko.txt rename to forge-gui/res/cardsfolder/f/flamecache_gecko.txt diff --git a/forge-gui/res/cardsfolder/f/floral_spuzzem.txt b/forge-gui/res/cardsfolder/f/floral_spuzzem.txt index 752bb98e35e..9b770f72465 100644 --- a/forge-gui/res/cardsfolder/f/floral_spuzzem.txt +++ b/forge-gui/res/cardsfolder/f/floral_spuzzem.txt @@ -3,6 +3,7 @@ ManaCost:3 G Types:Creature Elemental PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ TrigDestroy | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may destroy target artifact defending player controls. If you do, CARDNAME assigns no combat damage this turn. -SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. Oracle:Whenever Floral Spuzzem attacks and isn't blocked, you may destroy target artifact defending player controls. If you do, Floral Spuzzem assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/flowerfoot_swordmaster.txt b/forge-gui/res/cardsfolder/f/flowerfoot_swordmaster.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/flowerfoot_swordmaster.txt rename to forge-gui/res/cardsfolder/f/flowerfoot_swordmaster.txt diff --git a/forge-gui/res/cardsfolder/upcoming/flubs_the_fool.txt b/forge-gui/res/cardsfolder/f/flubs_the_fool.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/flubs_the_fool.txt rename to forge-gui/res/cardsfolder/f/flubs_the_fool.txt diff --git a/forge-gui/res/cardsfolder/upcoming/for_the_common_good.txt b/forge-gui/res/cardsfolder/f/for_the_common_good.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/for_the_common_good.txt rename to forge-gui/res/cardsfolder/f/for_the_common_good.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fortune_tellers_talent.txt b/forge-gui/res/cardsfolder/f/fortune_tellers_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fortune_tellers_talent.txt rename to forge-gui/res/cardsfolder/f/fortune_tellers_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fountainport.txt b/forge-gui/res/cardsfolder/f/fountainport.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fountainport.txt rename to forge-gui/res/cardsfolder/f/fountainport.txt diff --git a/forge-gui/res/cardsfolder/upcoming/fountainport_bell.txt b/forge-gui/res/cardsfolder/f/fountainport_bell.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/fountainport_bell.txt rename to forge-gui/res/cardsfolder/f/fountainport_bell.txt diff --git a/forge-gui/res/cardsfolder/f/fountainport_charmer.txt b/forge-gui/res/cardsfolder/f/fountainport_charmer.txt new file mode 100644 index 00000000000..1eccdd5c9a3 --- /dev/null +++ b/forge-gui/res/cardsfolder/f/fountainport_charmer.txt @@ -0,0 +1,9 @@ +Name:Fountainport Charmer +ManaCost:2 G +Types:Creature Frog Bard +PT:3/3 +K:Offspring:1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAnimate | TriggerDescription$ When CARDNAME enters, creature cards in your hand perpetually gain "This spell costs {1} less to cast." +SVar:TrigAnimate:DB$ AnimateAll | ValidCards$ Creature.YouOwn | Zone$ Hand | staticAbilities$ ReduceCost | Duration$ Perpetual +SVar:ReduceCost:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | Description$ This spell costs {1} less to cast. +Oracle:Offspring {1}\nWhen Fountainport Charmer enters, creature cards in your hand perpetually gain "This spell costs {1} less to cast." diff --git a/forge-gui/res/cardsfolder/f/frankensteins_monster.txt b/forge-gui/res/cardsfolder/f/frankensteins_monster.txt index a40e651dfff..3ddbf2387c6 100644 --- a/forge-gui/res/cardsfolder/f/frankensteins_monster.txt +++ b/forge-gui/res/cardsfolder/f/frankensteins_monster.txt @@ -5,13 +5,9 @@ PT:0/1 R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ ExileCreature | Description$ As CARDNAME enters, exile X creature cards from your graveyard. If you can't, put CARDNAME into its owner's graveyard instead of onto the battlefield. For each creature card exiled this way, CARDNAME enters with a +2/+0, +1/+1, or +0/+2 counter on it. SVar:ExileCreature:DB$ ChooseCard | ETB$ True | Choices$ Creature.YouOwn+NotDefinedReplacedSimultaneousETB | ChoiceZone$ Graveyard | Amount$ X | Mandatory$ True | ConditionCheckSVar$ CheckYard | ConditionSVarCompare$ GEX | SubAbility$ DBExile SVar:DBExile:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Graveyard | Destination$ Exile | RememberChanged$ True | SubAbility$ Movetoyard -SVar:Movetoyard:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Graveyard | Defined$ Self | ConditionCheckSVar$ CheckExiled | ConditionSVarCompare$ LTX | Imprint$ True | ETB$ True | SubAbility$ ChooseCounters -SVar:ChooseCounters:DB$ Repeat | MaxRepeat$ X | ETB$ True | RepeatSubAbility$ DBChooseCounter | ConditionCheckSVar$ CheckExiled | ConditionSVarCompare$ EQX | SubAbility$ MovetoPlay -SVar:DBChooseCounter:DB$ GenericChoice | Choices$ SVarP1P1,SVarP2P0,SVarP0P2 -SVar:SVarP1P1:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 | ETB$ True | SpellDescription$ +1/+1 -SVar:SVarP2P0:DB$ PutCounter | CounterType$ P2P0 | CounterNum$ 1 | ETB$ True | SpellDescription$ +2/+0 -SVar:SVarP0P2:DB$ PutCounter | CounterType$ P0P2 | CounterNum$ 1 | ETB$ True | SpellDescription$ +0/+2 -SVar:MovetoPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ Self | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCleanup +SVar:Movetoyard:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Graveyard | Defined$ Self | ConditionCheckSVar$ CheckExiled | ConditionSVarCompare$ LTX | Imprint$ True | ETB$ True | SubAbility$ DBChooseCounter +SVar:DBChooseCounter:DB$ PutCounter | CounterTypes$ P2P0,P1P1,P0P2 | CounterNum$ X | SplitAmount$ True | ETB$ True | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBUpdate +SVar:DBUpdate:DB$ ReplaceEffect | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True SVar:X:Count$xPaid SVar:CheckExiled:Count$ValidExile Card.IsRemembered diff --git a/forge-gui/res/cardsfolder/upcoming/frilled_sparkshooter.txt b/forge-gui/res/cardsfolder/f/frilled_sparkshooter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/frilled_sparkshooter.txt rename to forge-gui/res/cardsfolder/f/frilled_sparkshooter.txt diff --git a/forge-gui/res/cardsfolder/f/fumiko_the_lowblood.txt b/forge-gui/res/cardsfolder/f/fumiko_the_lowblood.txt index 8c803c8c690..9357ef692d8 100644 --- a/forge-gui/res/cardsfolder/f/fumiko_the_lowblood.txt +++ b/forge-gui/res/cardsfolder/f/fumiko_the_lowblood.txt @@ -2,7 +2,7 @@ Name:Fumiko the Lowblood ManaCost:2 R R Types:Legendary Creature Human Samurai PT:3/2 -S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Bushido:N | CalcKeywordN$ N | Description$ CARDNAME has bushido X, where X is the number of attacking creatures. -SVar:N:Count$Valid Creature.attacking +S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Bushido:X | Description$ CARDNAME has bushido X, where X is the number of attacking creatures. +SVar:X:Count$Valid Creature.attacking S:Mode$ MustAttack | ValidCreature$ Creature.OppCtrl | Description$ Creatures your opponents control attack each combat if able. Oracle:Fumiko the Lowblood has bushido X, where X is the number of attacking creatures. (Whenever this creature blocks or becomes blocked, it gets +X/+X until end of turn.)\nCreatures your opponents control attack each combat if able. diff --git a/forge-gui/res/cardsfolder/upcoming/galewind_moose.txt b/forge-gui/res/cardsfolder/g/galewind_moose.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/galewind_moose.txt rename to forge-gui/res/cardsfolder/g/galewind_moose.txt diff --git a/forge-gui/res/cardsfolder/g/garna_bloodfist_of_keld.txt b/forge-gui/res/cardsfolder/g/garna_bloodfist_of_keld.txt index 6ef421398a0..e98d549a33b 100644 --- a/forge-gui/res/cardsfolder/g/garna_bloodfist_of_keld.txt +++ b/forge-gui/res/cardsfolder/g/garna_bloodfist_of_keld.txt @@ -6,6 +6,6 @@ T:Mode$ ChangesZone | ValidCard$ Creature.Other+YouCtrl | Origin$ Battlefield | SVar:TrigBranch:DB$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE1 | TrueSubAbility$ DBDraw | FalseSubAbility$ DBDamage SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 SVar:DBDamage:DB$ DealDamage | Defined$ Opponent | NumDmg$ 1 -SVar:X:TriggeredCard$Valid Creature.attackingLKI +SVar:X:TriggeredCard$Valid Creature.attacking DeckHas:Ability$Sacrifice Oracle:Whenever another creature you control dies, draw a card if it was attacking. Otherwise, Garna, Bloodfist of Keld deals 1 damage to each opponent. diff --git a/forge-gui/res/cardsfolder/g/gaze_of_pain.txt b/forge-gui/res/cardsfolder/g/gaze_of_pain.txt index 41e89711789..25c2cf0dda9 100644 --- a/forge-gui/res/cardsfolder/g/gaze_of_pain.txt +++ b/forge-gui/res/cardsfolder/g/gaze_of_pain.txt @@ -3,8 +3,9 @@ ManaCost:1 B Types:Sorcery A:SP$ Effect | Triggers$ TrigAttackerUnblocked | SpellDescription$ Until end of turn, whenever a creature you control attacks and isn't blocked, you may choose to have it deal damage equal to its power to a target creature. If you do, it assigns no combat damage this turn. SVar:TrigAttackerUnblocked:Mode$ AttackerUnblocked | ValidCard$ Creature.YouCtrl | Execute$ Damage | OptionalDecider$ You | TriggerDescription$ Until end of turn, whenever a creature you control attacks and isn't blocked, you may choose to have it deal damage equal to its power to a target creature. If you do, it assigns no combat damage this turn. -SVar:Damage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ TriggeredAttackerLKICopy | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:Damage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | RememberObjects$ TriggeredAttackerLKICopy | StaticAbilities$ SNoCombatDamage | ForgetOnMoved$ Battlefield +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.IsRemembered | Description$ Remembered creature assigns no combat damage this turn. SVar:X:TriggeredAttacker$CardPower AI:RemoveDeck:All Oracle:Until end of turn, whenever a creature you control attacks and isn't blocked, you may choose to have it deal damage equal to its power to a target creature. If you do, it assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/g/generated_horizons.txt b/forge-gui/res/cardsfolder/g/generated_horizons.txt index 42585923995..9114acdf112 100644 --- a/forge-gui/res/cardsfolder/g/generated_horizons.txt +++ b/forge-gui/res/cardsfolder/g/generated_horizons.txt @@ -2,5 +2,5 @@ Name:Generated Horizons ManaCost:2 G G Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of your upkeep, you create a Forest land token. -SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_l_forest | TokenOwner$ You +SVar:TrigToken:DB$ CopyPermanent | DefinedName$ Forest Oracle:At the beginning of your upkeep, create a Forest land token. diff --git a/forge-gui/res/cardsfolder/g/genesis_chamber.txt b/forge-gui/res/cardsfolder/g/genesis_chamber.txt index 20a4268e79b..e279c8018ba 100644 --- a/forge-gui/res/cardsfolder/g/genesis_chamber.txt +++ b/forge-gui/res/cardsfolder/g/genesis_chamber.txt @@ -1,7 +1,7 @@ Name:Genesis Chamber ManaCost:2 Types:Artifact -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken | TriggerZones$ Battlefield | Execute$ TrigToken | IsPresent$ Card.Self+untapped | TriggerDescription$ Whenever a nontoken creature enters, if CARDNAME is untapped, that creature's controller creates a 1/1 colorless Myr artifact creature token. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken | TriggerZones$ Battlefield | Execute$ TrigToken | PresentDefined$ Self | IsPresent$ Card.untapped | TriggerDescription$ Whenever a nontoken creature enters, if CARDNAME is untapped, that creature's controller creates a 1/1 colorless Myr artifact creature token. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ TriggeredCardController | TokenScript$ c_1_1_a_myr AI:RemoveDeck:Random DeckHas:Ability$Token diff --git a/forge-gui/res/cardsfolder/upcoming/genku_future_shaper.txt b/forge-gui/res/cardsfolder/g/genku_future_shaper.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/genku_future_shaper.txt rename to forge-gui/res/cardsfolder/g/genku_future_shaper.txt diff --git a/forge-gui/res/cardsfolder/upcoming/gev_scaled_scorch.txt b/forge-gui/res/cardsfolder/g/gev_scaled_scorch.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/gev_scaled_scorch.txt rename to forge-gui/res/cardsfolder/g/gev_scaled_scorch.txt diff --git a/forge-gui/res/cardsfolder/g/ghostly_flame.txt b/forge-gui/res/cardsfolder/g/ghostly_flame.txt index a437df3e23e..7ec1884bad6 100644 --- a/forge-gui/res/cardsfolder/g/ghostly_flame.txt +++ b/forge-gui/res/cardsfolder/g/ghostly_flame.txt @@ -1,6 +1,6 @@ Name:Ghostly Flame ManaCost:B R Types:Enchantment -S:Mode$ Continuous | Affected$ Permanent.Black,Permanent.Red,Spell.Red,Spell.Black | AffectedZone$ Stack,Battlefield | AddHiddenKeyword$ Colorless Damage Source | Description$ Black and/or red permanents and spells are colorless sources of damage. +S:Mode$ ColorlessDamageSource | ValidCard$ Permanent.Black+inZoneBattlefield,Permanent.Red+inZoneBattlefield,Spell.Black+inZoneStack,Spell.Red+inZoneStack | Description$ Black and/or red permanents and spells are colorless sources of damage. SVar:NonStackingEffect:True Oracle:Black and/or red permanents and spells are colorless sources of damage. diff --git a/forge-gui/res/cardsfolder/g/gideon_of_the_trials.txt b/forge-gui/res/cardsfolder/g/gideon_of_the_trials.txt index 9a51a41f8ea..a3c339ee2da 100644 --- a/forge-gui/res/cardsfolder/g/gideon_of_the_trials.txt +++ b/forge-gui/res/cardsfolder/g/gideon_of_the_trials.txt @@ -7,7 +7,7 @@ SVar:RPrevent:Event$ DamageDone | Prevent$ True | ValidSource$ Card.IsRemembered A:AB$ Animate | Cost$ AddCounter<0/LOYALTY> | Defined$ Self | Power$ 4 | Toughness$ 4 | Keywords$ Indestructible | Types$ Creature,Human,Soldier | SubAbility$ GideonPrevent | Planeswalker$ True | SpellDescription$ Until end of turn, CARDNAME becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn. SVar:GideonPrevent:DB$ Effect | ReplacementEffects$ RGideon | Duration$ UntilHostLeavesPlayOrEOT SVar:RGideon:Event$ DamageDone | Prevent$ True | ValidTarget$ Card.EffectSource | Description$ Prevent all damage that would be dealt to EFFECTSOURCE. -A:AB$ Effect | Cost$ AddCounter<0/LOYALTY> | Name$ Emblem — Gideon of the Trials | StaticAbilities$ STPump1,STPump2 | Planeswalker$ True | Ultimate$ True | Duration$ Permanent | AILogic$ Always | Stackable$ False | SpellDescription$ You get an emblem with "As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game." -SVar:STPump1:Mode$ Continuous | EffectZone$ Command | Affected$ You | IsPresent$ Planeswalker.Gideon+YouCtrl | AddKeyword$ You can't lose the game. | Description$ As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game. -SVar:STPump2:Mode$ Continuous | EffectZone$ Command | Affected$ Player.Opponent | IsPresent$ Planeswalker.Gideon+YouCtrl | AddKeyword$ You can't win the game. +A:AB$ Effect | Cost$ AddCounter<0/LOYALTY> | Name$ Emblem — Gideon of the Trials | ReplacementEffects$ DBYouCantLose,DBOppCantWin | Planeswalker$ True | Ultimate$ True | Duration$ Permanent | AILogic$ Always | Stackable$ False | SpellDescription$ You get an emblem with "As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game." +SVar:DBYouCantLose:Event$ GameLoss | ValidPlayer$ You | Layer$ CantHappen | IsPresent$ Planeswalker.Gideon+YouCtrl | Description$ As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game. +SVar:DBOppCantWin:Event$ GameWin | ValidPlayer$ Opponent | Layer$ CantHappen | IsPresent$ Planeswalker.Gideon+YouCtrl | Secondary$ True | Description$ As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game. Oracle:[+1]: Until your next turn, prevent all damage target permanent would deal.\n[0]: Until end of turn, Gideon of the Trials becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.\n[0]: You get an emblem with "As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game." diff --git a/forge-gui/res/cardsfolder/upcoming/glarb_calamitys_augur.txt b/forge-gui/res/cardsfolder/g/glarb_calamitys_augur.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/glarb_calamitys_augur.txt rename to forge-gui/res/cardsfolder/g/glarb_calamitys_augur.txt diff --git a/forge-gui/res/cardsfolder/upcoming/glidedive_duo.txt b/forge-gui/res/cardsfolder/g/glidedive_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/glidedive_duo.txt rename to forge-gui/res/cardsfolder/g/glidedive_duo.txt diff --git a/forge-gui/res/cardsfolder/g/gobland.txt b/forge-gui/res/cardsfolder/g/gobland.txt new file mode 100644 index 00000000000..3976404419d --- /dev/null +++ b/forge-gui/res/cardsfolder/g/gobland.txt @@ -0,0 +1,7 @@ +Name:Gobland +ManaCost:no cost +Colors:red +Types:Land Creature Mountain Goblin +PT:2/1 +K:CARDNAME can't block. +Oracle:(Gobland isn’t a spell, it's affected by summoning sickness, and it has "{T}: Add {R}.")\nGobland can’t block. diff --git a/forge-gui/res/cardsfolder/g/goblin_vandal.txt b/forge-gui/res/cardsfolder/g/goblin_vandal.txt index bdbd8674ba3..d8d4bfd2f54 100644 --- a/forge-gui/res/cardsfolder/g/goblin_vandal.txt +++ b/forge-gui/res/cardsfolder/g/goblin_vandal.txt @@ -3,6 +3,7 @@ ManaCost:R Types:Creature Goblin Rogue PT:1/1 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may pay {R}. If you do, destroy target artifact defending player controls and CARDNAME assigns no combat damage this turn. -SVar:TrigDestroy:AB$ Destroy | Cost$ R | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact defending player controls | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:TrigDestroy:AB$ Destroy | Cost$ R | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact defending player controls | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. Oracle:Whenever Goblin Vandal attacks and isn't blocked, you may pay {R}. If you do, destroy target artifact defending player controls and Goblin Vandal assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/g/golgari_brownscale.txt b/forge-gui/res/cardsfolder/g/golgari_brownscale.txt index b0810d7787f..fdadceb6ca2 100644 --- a/forge-gui/res/cardsfolder/g/golgari_brownscale.txt +++ b/forge-gui/res/cardsfolder/g/golgari_brownscale.txt @@ -3,6 +3,6 @@ ManaCost:1 G G Types:Creature Lizard PT:2/3 T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Hand | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME is put into your hand from your graveyard, you gain 2 life. -K:Dredge:2 SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 +K:Dredge:2 Oracle:When Golgari Brownscale is put into your hand from your graveyard, you gain 2 life.\nDredge 2 (If you would draw a card, you may mill two cards instead. If you do, return this card from your graveyard to your hand.) diff --git a/forge-gui/res/cardsfolder/upcoming/gossips_talent.txt b/forge-gui/res/cardsfolder/g/gossips_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/gossips_talent.txt rename to forge-gui/res/cardsfolder/g/gossips_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/gourmands_talent.txt b/forge-gui/res/cardsfolder/g/gourmands_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/gourmands_talent.txt rename to forge-gui/res/cardsfolder/g/gourmands_talent.txt diff --git a/forge-gui/res/cardsfolder/h/hallow.txt b/forge-gui/res/cardsfolder/h/hallow.txt index 3732aec9b54..f728aeb7561 100644 --- a/forge-gui/res/cardsfolder/h/hallow.txt +++ b/forge-gui/res/cardsfolder/h/hallow.txt @@ -1,9 +1,11 @@ Name:Hallow ManaCost:W Types:Instant -A:SP$ Effect | ValidTgts$ Card | TargetType$ Spell | TgtZone$ Stack | TgtPrompt$ Select target spell to prevent damage from | ReplacementEffects$ PreventDmg | ExileOnMoved$ Stack | RememberObjects$ TargetedSource | SpellDescription$ Prevent all damage target spell would deal this turn. You gain life equal to the damage prevented this way. +A:SP$ Effect | ValidTgts$ Card | TargetType$ Spell | TgtZone$ Stack | TgtPrompt$ Select target spell to prevent damage from | ReplacementEffects$ PreventDmg | Triggers$ TargetMoved | RememberObjects$ TargetedSource | SpellDescription$ Prevent all damage target spell would deal this turn. You gain life equal to the damage prevented this way. SVar:PreventDmg:Event$ DamageDone | ValidSource$ Card.IsRemembered | ReplaceWith$ GainLifeYou | PreventionEffect$ True | Description$ Prevent all damage that would be dealt by targeted spell this turn. You gain life equal to the damage prevented this way. SVar:GainLifeYou:DB$ GainLife | Defined$ You | LifeAmount$ X SVar:X:ReplaceCount$DamageAmount +SVar:TargetMoved:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | ExcludedDestinations$ Battlefield | Execute$ ExileEffect | Static$ True +SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile AI:RemoveDeck:All Oracle:Prevent all damage target spell would deal this turn. You gain life equal to the damage prevented this way. diff --git a/forge-gui/res/cardsfolder/h/halving_season.txt b/forge-gui/res/cardsfolder/h/halving_season.txt new file mode 100644 index 00000000000..bf8ea327ed3 --- /dev/null +++ b/forge-gui/res/cardsfolder/h/halving_season.txt @@ -0,0 +1,9 @@ +Name:Halving Season +ManaCost:4 B +Types:Enchantment +R:Event$ CreateToken | ActiveZones$ Battlefield | ValidToken$ Card.OppCtrl | ReplaceWith$ HalveToken | EffectOnly$ True | Description$ If an opponent would create one or more tokens, they create half that many of each of those kinds of tokens instead, rounded down. +SVar:HalveToken:DB$ ReplaceToken | Type$ Amount | Amount$ HalfDown | ValidCard$ Card.OppCtrl +R:Event$ AddCounter | ActiveZones$ Battlefield | ValidSource$ Opponent | ValidObject$ Permanent.inZoneBattlefield,Player | ReplaceWith$ HalfCounters | Description$ If an opponent would put one or more counters on a permanent or player, they put half that many of each of those kinds of counters on that permanent or player instead, rounded down. +SVar:HalfCounters:DB$ ReplaceCounter | ValidSource$ Opponent | Amount$ Y +SVar:Y:ReplaceCount$CounterNum/HalfDown +Oracle:If an opponent would create one or more tokens, they create half that many of each of those kinds of tokens instead, rounded down.\nIf an opponent would put one or more counters on a permanent or player, they put half that many of each of those kinds of counters on that permanent or player instead, rounded down. diff --git a/forge-gui/res/cardsfolder/upcoming/harnesser_of_storms.txt b/forge-gui/res/cardsfolder/h/harnesser_of_storms.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/harnesser_of_storms.txt rename to forge-gui/res/cardsfolder/h/harnesser_of_storms.txt diff --git a/forge-gui/res/cardsfolder/upcoming/harvestrite_host.txt b/forge-gui/res/cardsfolder/h/harvestrite_host.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/harvestrite_host.txt rename to forge-gui/res/cardsfolder/h/harvestrite_host.txt diff --git a/forge-gui/res/cardsfolder/upcoming/havi_the_all_father.txt b/forge-gui/res/cardsfolder/h/havi_the_all_father.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/havi_the_all_father.txt rename to forge-gui/res/cardsfolder/h/havi_the_all_father.txt diff --git a/forge-gui/res/cardsfolder/upcoming/haytham_kenway.txt b/forge-gui/res/cardsfolder/h/haytham_kenway.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/haytham_kenway.txt rename to forge-gui/res/cardsfolder/h/haytham_kenway.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hazardroot_herbalist.txt b/forge-gui/res/cardsfolder/h/hazardroot_herbalist.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hazardroot_herbalist.txt rename to forge-gui/res/cardsfolder/h/hazardroot_herbalist.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hazel_of_the_rootbloom.txt b/forge-gui/res/cardsfolder/h/hazel_of_the_rootbloom.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hazel_of_the_rootbloom.txt rename to forge-gui/res/cardsfolder/h/hazel_of_the_rootbloom.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hazels_brewmaster.txt b/forge-gui/res/cardsfolder/h/hazels_brewmaster.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hazels_brewmaster.txt rename to forge-gui/res/cardsfolder/h/hazels_brewmaster.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hazels_nocturne.txt b/forge-gui/res/cardsfolder/h/hazels_nocturne.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hazels_nocturne.txt rename to forge-gui/res/cardsfolder/h/hazels_nocturne.txt diff --git a/forge-gui/res/cardsfolder/upcoming/head_of_the_homestead.txt b/forge-gui/res/cardsfolder/h/head_of_the_homestead.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/head_of_the_homestead.txt rename to forge-gui/res/cardsfolder/h/head_of_the_homestead.txt diff --git a/forge-gui/res/cardsfolder/upcoming/headsplitter.txt b/forge-gui/res/cardsfolder/h/headsplitter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/headsplitter.txt rename to forge-gui/res/cardsfolder/h/headsplitter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/heaped_harvest.txt b/forge-gui/res/cardsfolder/h/heaped_harvest.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/heaped_harvest.txt rename to forge-gui/res/cardsfolder/h/heaped_harvest.txt diff --git a/forge-gui/res/cardsfolder/upcoming/heartfire_hero.txt b/forge-gui/res/cardsfolder/h/heartfire_hero.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/heartfire_hero.txt rename to forge-gui/res/cardsfolder/h/heartfire_hero.txt diff --git a/forge-gui/res/cardsfolder/h/heartflame_duelist_heartflame_slash.txt b/forge-gui/res/cardsfolder/h/heartflame_duelist_heartflame_slash.txt index 8079a8e0261..74626ce020d 100644 --- a/forge-gui/res/cardsfolder/h/heartflame_duelist_heartflame_slash.txt +++ b/forge-gui/res/cardsfolder/h/heartflame_duelist_heartflame_slash.txt @@ -10,7 +10,7 @@ Oracle:Instant and sorcery spells you control have lifelink. ALTERNATE -Name:Lagoon Breach +Name:Heartflame Slash ManaCost:2 R Types:Instant Adventure A:SP$ DealDamage | ValidTgts$ Any | NumDmg$ 3 | SpellDescription$ CARDNAME deals 3 damage to any target. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/upcoming/hearthborn_battler.txt b/forge-gui/res/cardsfolder/h/hearthborn_battler.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hearthborn_battler.txt rename to forge-gui/res/cardsfolder/h/hearthborn_battler.txt diff --git a/forge-gui/res/cardsfolder/upcoming/heirloom_epic.txt b/forge-gui/res/cardsfolder/h/heirloom_epic.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/heirloom_epic.txt rename to forge-gui/res/cardsfolder/h/heirloom_epic.txt diff --git a/forge-gui/res/cardsfolder/upcoming/helga_skittish_seer.txt b/forge-gui/res/cardsfolder/h/helga_skittish_seer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/helga_skittish_seer.txt rename to forge-gui/res/cardsfolder/h/helga_skittish_seer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hemlock_vial.txt b/forge-gui/res/cardsfolder/h/hemlock_vial.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hemlock_vial.txt rename to forge-gui/res/cardsfolder/h/hemlock_vial.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_footblade.txt b/forge-gui/res/cardsfolder/h/hidden_footblade.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hidden_footblade.txt rename to forge-gui/res/cardsfolder/h/hidden_footblade.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_grotto.txt b/forge-gui/res/cardsfolder/h/hidden_grotto.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hidden_grotto.txt rename to forge-gui/res/cardsfolder/h/hidden_grotto.txt diff --git a/forge-gui/res/cardsfolder/upcoming/high_stride.txt b/forge-gui/res/cardsfolder/h/high_stride.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/high_stride.txt rename to forge-gui/res/cardsfolder/h/high_stride.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hired_claw.txt b/forge-gui/res/cardsfolder/h/hired_claw.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hired_claw.txt rename to forge-gui/res/cardsfolder/h/hired_claw.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hivespine_wolverine.txt b/forge-gui/res/cardsfolder/h/hivespine_wolverine.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hivespine_wolverine.txt rename to forge-gui/res/cardsfolder/h/hivespine_wolverine.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hoarders_overflow.txt b/forge-gui/res/cardsfolder/h/hoarders_overflow.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hoarders_overflow.txt rename to forge-gui/res/cardsfolder/h/hoarders_overflow.txt diff --git a/forge-gui/res/cardsfolder/h/hollow_trees.txt b/forge-gui/res/cardsfolder/h/hollow_trees.txt index fe7d9bf5ad9..3cbfc9ad988 100644 --- a/forge-gui/res/cardsfolder/h/hollow_trees.txt +++ b/forge-gui/res/cardsfolder/h/hollow_trees.txt @@ -4,7 +4,7 @@ Types:Land R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True K:You may choose not to untap CARDNAME during your untap step. -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Card.Self+tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. SVar:TrigStore:DB$ PutCounter | Defined$ Self | CounterType$ STORAGE | CounterNum$ 1 A:AB$ Mana | Cost$ T SubCounter | Produced$ G | Amount$ X | AILogic$ ManaRitualBattery | SpellDescription$ Add {G} for each storage counter removed this way. SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/upcoming/honored_dreyleader.txt b/forge-gui/res/cardsfolder/h/honored_dreyleader.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/honored_dreyleader.txt rename to forge-gui/res/cardsfolder/h/honored_dreyleader.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hookblade.txt b/forge-gui/res/cardsfolder/h/hookblade.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hookblade.txt rename to forge-gui/res/cardsfolder/h/hookblade.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hookblade_veteran.txt b/forge-gui/res/cardsfolder/h/hookblade_veteran.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hookblade_veteran.txt rename to forge-gui/res/cardsfolder/h/hookblade_veteran.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hop_to_it.txt b/forge-gui/res/cardsfolder/h/hop_to_it.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hop_to_it.txt rename to forge-gui/res/cardsfolder/h/hop_to_it.txt diff --git a/forge-gui/res/cardsfolder/h/hotheaded_giant.txt b/forge-gui/res/cardsfolder/h/hotheaded_giant.txt index 6f28e45c17c..be81044374c 100644 --- a/forge-gui/res/cardsfolder/h/hotheaded_giant.txt +++ b/forge-gui/res/cardsfolder/h/hotheaded_giant.txt @@ -4,5 +4,5 @@ Types:Creature Giant Warrior PT:4/4 K:Haste K:etbCounter:M1M1:2:CheckSVar$ OtherRedCast | SVarCompare$ EQ0:CARDNAME enters with two -1/-1 counters on it unless you've cast another red spell this turn. -SVar:OtherRedCast:Count$ThisTurnCast_Card.Red+Other+YouCtrl +SVar:OtherRedCast:Count$ThisTurnCast_Card.Red+!CastSaSource+YouCtrl Oracle:Haste\nHotheaded Giant enters with two -1/-1 counters on it unless you've cast another red spell this turn. diff --git a/forge-gui/res/cardsfolder/h/howling_mine.txt b/forge-gui/res/cardsfolder/h/howling_mine.txt index 54f58262b58..93ae9a0582b 100644 --- a/forge-gui/res/cardsfolder/h/howling_mine.txt +++ b/forge-gui/res/cardsfolder/h/howling_mine.txt @@ -1,6 +1,6 @@ Name:Howling Mine ManaCost:2 Types:Artifact -T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player | TriggerZones$ Battlefield | IsPresent$ Card.Self+untapped | Execute$ TrigDraw | TriggerDescription$ At the beginning of each player's draw step, if CARDNAME is untapped, that player draws an additional card. -SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ TriggeredPlayer | ConditionDefined$ Self | ConditionPresent$ Card.untapped +T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player | TriggerZones$ Battlefield | PresentDefined$ Self | IsPresent$ Card.untapped | Execute$ TrigDraw | TriggerDescription$ At the beginning of each player's draw step, if CARDNAME is untapped, that player draws an additional card. +SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ TriggeredPlayer Oracle:At the beginning of each player's draw step, if Howling Mine is untapped, that player draws an additional card. diff --git a/forge-gui/res/cardsfolder/upcoming/hugs_grisly_guardian.txt b/forge-gui/res/cardsfolder/h/hugs_grisly_guardian.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hugs_grisly_guardian.txt rename to forge-gui/res/cardsfolder/h/hugs_grisly_guardian.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hunters_bow.txt b/forge-gui/res/cardsfolder/h/hunters_bow.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hunters_bow.txt rename to forge-gui/res/cardsfolder/h/hunters_bow.txt diff --git a/forge-gui/res/cardsfolder/upcoming/hunters_talent.txt b/forge-gui/res/cardsfolder/h/hunters_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/hunters_talent.txt rename to forge-gui/res/cardsfolder/h/hunters_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/huskburster_swarm.txt b/forge-gui/res/cardsfolder/h/huskburster_swarm.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/huskburster_swarm.txt rename to forge-gui/res/cardsfolder/h/huskburster_swarm.txt diff --git a/forge-gui/res/cardsfolder/h/hustle_bustle.txt b/forge-gui/res/cardsfolder/h/hustle_bustle.txt index 59521b979d2..50d9dab351c 100644 --- a/forge-gui/res/cardsfolder/h/hustle_bustle.txt +++ b/forge-gui/res/cardsfolder/h/hustle_bustle.txt @@ -13,5 +13,5 @@ Name:Bustle ManaCost:4 RG RG Types:Sorcery A:SP$ PumpAll | ValidCards$ Creature.YouCtrl | NumAtt$ +2 | NumDef$ +2 | KW$ Trample | SubAbility$ DBTurnFaceUp | SpellDescription$ Creatures you control get +2/+2 and gain trample until end of turn. -SVar:DBTurnFaceUp:DB$ SetState | Optional$ True | Choices$ Creature.faceDown+YouCtrl | ChoiceTitle$ Select target facedown creature you control | Mode$ TurnFaceUp | SpellDescription$ You may turn a face-down creature you control face up. +SVar:DBTurnFaceUp:DB$ SetState | Optional$ True | Choices$ Creature.faceDown+YouCtrl | ChoiceTitle$ Select a face-down creature you control | Mode$ TurnFaceUp | SpellDescription$ You may turn a face-down creature you control face up. Oracle:Creatures you control get +2/+2 and gain trample until end of turn. You may turn a face-down creature you control face up. diff --git a/forge-gui/res/cardsfolder/i/i_bask_in_your_silent_awe.txt b/forge-gui/res/cardsfolder/i/i_bask_in_your_silent_awe.txt index 51194d9e842..c6221077223 100644 --- a/forge-gui/res/cardsfolder/i/i_bask_in_your_silent_awe.txt +++ b/forge-gui/res/cardsfolder/i/i_bask_in_your_silent_awe.txt @@ -7,6 +7,6 @@ T:Mode$ SpellCast | ValidActivatingPlayer$ Player.Opponent | Execute$ DBCount | T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ DBReset | TriggerZones$ Command | Static$ True SVar:DBCount:DB$ StoreSVar | SVar$ X | Type$ CountSVar | Expression$ X/Plus.1 SVar:DBReset:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 0 -SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Abandon:DB$ Abandon SVar:X:Number$0 Oracle:(An ongoing scheme remains face up until it's abandoned.)\nEach opponent can't cast more than one spell each turn.\nAt the beginning of your upkeep, if no opponent cast a spell since your last turn ended, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/i/i_know_all_i_see_all.txt b/forge-gui/res/cardsfolder/i/i_know_all_i_see_all.txt index be9c54c760b..71b38d28d39 100644 --- a/forge-gui/res/cardsfolder/i/i_know_all_i_see_all.txt +++ b/forge-gui/res/cardsfolder/i/i_know_all_i_see_all.txt @@ -3,6 +3,6 @@ ManaCost:no cost Types:Ongoing Scheme S:Mode$ Continuous | EffectZone$ Command | Affected$ Permanent.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each other player's untap step. | Description$ Untap all permanents you control during each other player's untap step. T:Mode$ Phase | Phase$ End of Turn | Execute$ Abandon | TriggerZones$ Command | CheckSVar$ X | SVarCompare$ GE3 | TriggerDescription$ At the beginning of each end step, if three or more cards were put into your graveyard this turn from anywhere, abandon this scheme. -SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Abandon:DB$ Abandon SVar:X:Count$ThisTurnEntered_Graveyard_Card.YouOwn Oracle:(An ongoing scheme remains face up until it's abandoned.)\nUntap all permanents you control during each opponent's untap step.\nAt the beginning of each end step, if three or more cards were put into your graveyard this turn from anywhere, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/i/icatian_store.txt b/forge-gui/res/cardsfolder/i/icatian_store.txt index c2ddc11bc81..92d4459cb70 100644 --- a/forge-gui/res/cardsfolder/i/icatian_store.txt +++ b/forge-gui/res/cardsfolder/i/icatian_store.txt @@ -4,7 +4,7 @@ Types:Land R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True K:You may choose not to untap CARDNAME during your untap step. -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Card.Self+tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. SVar:TrigStore:DB$ PutCounter | Defined$ Self | CounterType$ STORAGE | CounterNum$ 1 A:AB$ Mana | Cost$ T SubCounter | Produced$ W | Amount$ X | AILogic$ ManaRitualBattery | SpellDescription$ Add {W} for each storage counter removed this way. SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/i/imprison_this_insolent_wretch.txt b/forge-gui/res/cardsfolder/i/imprison_this_insolent_wretch.txt index 3e088d677a6..fe192799b1d 100644 --- a/forge-gui/res/cardsfolder/i/imprison_this_insolent_wretch.txt +++ b/forge-gui/res/cardsfolder/i/imprison_this_insolent_wretch.txt @@ -6,5 +6,5 @@ SVar:ChooseTheWretch:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent S:Mode$ Continuous | EffectZone$ Command | Affected$ Permanent.ChosenCtrl | AffectedZone$ Battlefield | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Permanents the chosen player controls don't untap during their untap step. T:Mode$ Attacks | ValidCard$ Card | Attacked$ Player.Chosen | Execute$ Abandon | TriggerZones$ Command | TriggerDescription$ When the chosen player is attacked or becomes the target of a spell or ability, abandon this scheme. T:Mode$ BecomesTarget | ValidTarget$ Player.Chosen | TriggerZones$ Command | Execute$ Abandon | Secondary$ True | TriggerDescription$ When the chosen player is attacked or becomes the target of a spell or ability, abandon this scheme. -SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Abandon:DB$ Abandon Oracle:(An ongoing scheme remains face up until it's abandoned.)\nWhen you set this scheme in motion, choose an opponent.\nPermanents the chosen player controls don't untap during their untap step.\nWhen the chosen player is attacked or becomes the target of a spell or ability, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/i/indris_the_hydrostatic_surge.txt b/forge-gui/res/cardsfolder/i/indris_the_hydrostatic_surge.txt new file mode 100644 index 00000000000..12119469c06 --- /dev/null +++ b/forge-gui/res/cardsfolder/i/indris_the_hydrostatic_surge.txt @@ -0,0 +1,11 @@ +Name:Indris, the Hydrostatic Surge +ManaCost:4 U R +Types:Legendary Creature Otter Incarnation +PT:5/5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigConjure | TriggerDescription$ When CARDNAME enters, conjure a card named Lightning Bolt into your library. It perpetually gains storm. Then shuffle. +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Name$ Lightning Bolt | Zone$ Library | RememberMade$ True | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Remembered | PumpZone$ Library | KW$ Storm | Duration$ Perpetual | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery spell, draw a card. +SVar:TrigDraw:DB$ Draw +Oracle:When Indris, the Hydrostatic Surge enters, conjure a card named Lightning Bolt into your library. It perpetually gains storm. Then shuffle.\nWhenever you cast an instant or sorcery spell, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/innkeepers_talent.txt b/forge-gui/res/cardsfolder/i/innkeepers_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/innkeepers_talent.txt rename to forge-gui/res/cardsfolder/i/innkeepers_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/insatiable_frugivore.txt b/forge-gui/res/cardsfolder/i/insatiable_frugivore.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/insatiable_frugivore.txt rename to forge-gui/res/cardsfolder/i/insatiable_frugivore.txt diff --git a/forge-gui/res/cardsfolder/upcoming/into_the_flood_maw.txt b/forge-gui/res/cardsfolder/i/into_the_flood_maw.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/into_the_flood_maw.txt rename to forge-gui/res/cardsfolder/i/into_the_flood_maw.txt diff --git a/forge-gui/res/cardsfolder/upcoming/intrepid_rabbit.txt b/forge-gui/res/cardsfolder/i/intrepid_rabbit.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/intrepid_rabbit.txt rename to forge-gui/res/cardsfolder/i/intrepid_rabbit.txt diff --git a/forge-gui/res/cardsfolder/i/invoke_prejudice.txt b/forge-gui/res/cardsfolder/i/invoke_prejudice.txt index aa4d0319b39..0061700ff46 100644 --- a/forge-gui/res/cardsfolder/i/invoke_prejudice.txt +++ b/forge-gui/res/cardsfolder/i/invoke_prejudice.txt @@ -1,7 +1,7 @@ Name:Invoke Prejudice ManaCost:U U U U Types:Enchantment -T:Mode$ SpellCast | ValidCard$ Creature.OppCtrl+notSharesColorWith Creature.YouCtrl | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a creature spell that doesn't share a color with a creature you control, counter that spell unless that player pays {X}, where X is its mana value. +T:Mode$ SpellCast | ValidCard$ Creature.OppCtrl+!SharesColorWith Valid Creature.YouCtrl | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a creature spell that doesn't share a color with a creature you control, counter that spell unless that player pays {X}, where X is its mana value. SVar:TrigCounter:DB$ Counter | Defined$ TriggeredSpellAbility | UnlessCost$ X | UnlessPayer$ TriggeredActivator SVar:X:TriggeredCard$CardManaCost Oracle:Whenever an opponent casts a creature spell that doesn't share a color with a creature you control, counter that spell unless that player pays {X}, where X is its mana value. diff --git a/forge-gui/res/cardsfolder/upcoming/iridescent_vinelasher.txt b/forge-gui/res/cardsfolder/i/iridescent_vinelasher.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/iridescent_vinelasher.txt rename to forge-gui/res/cardsfolder/i/iridescent_vinelasher.txt diff --git a/forge-gui/res/cardsfolder/upcoming/jackdaw.txt b/forge-gui/res/cardsfolder/j/jackdaw.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/jackdaw.txt rename to forge-gui/res/cardsfolder/j/jackdaw.txt diff --git a/forge-gui/res/cardsfolder/upcoming/jackdaw_savior.txt b/forge-gui/res/cardsfolder/j/jackdaw_savior.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/jackdaw_savior.txt rename to forge-gui/res/cardsfolder/j/jackdaw_savior.txt diff --git a/forge-gui/res/cardsfolder/upcoming/jacked_rabbit.txt b/forge-gui/res/cardsfolder/j/jacked_rabbit.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/jacked_rabbit.txt rename to forge-gui/res/cardsfolder/j/jacked_rabbit.txt diff --git a/forge-gui/res/cardsfolder/upcoming/jacob_frye.txt b/forge-gui/res/cardsfolder/j/jacob_frye.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/jacob_frye.txt rename to forge-gui/res/cardsfolder/j/jacob_frye.txt diff --git a/forge-gui/res/cardsfolder/j/jaded_response.txt b/forge-gui/res/cardsfolder/j/jaded_response.txt index c1c117bee6e..b1201decd9e 100644 --- a/forge-gui/res/cardsfolder/j/jaded_response.txt +++ b/forge-gui/res/cardsfolder/j/jaded_response.txt @@ -1,5 +1,5 @@ Name:Jaded Response ManaCost:1 U Types:Instant -A:SP$ Counter | TargetType$ Spell | ValidTgts$ Card | AITgts$ Card.SharesColorWith Valid Creature.YouCtrl | ConditionDefined$ Targeted | ConditionPresent$ Spell.SharesColorWith Creature.YouCtrl | SpellDescription$ Counter target spell if it shares a color with a creature you control. +A:SP$ Counter | TargetType$ Spell | ValidTgts$ Card | AITgts$ Card.SharesColorWith Valid Creature.YouCtrl | ConditionDefined$ Targeted | ConditionPresent$ Spell.SharesColorWith Valid Creature.YouCtrl | SpellDescription$ Counter target spell if it shares a color with a creature you control. Oracle:Counter target spell if it shares a color with a creature you control. diff --git a/forge-gui/res/cardsfolder/upcoming/jolly_gerbils.txt b/forge-gui/res/cardsfolder/j/jolly_gerbils.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/jolly_gerbils.txt rename to forge-gui/res/cardsfolder/j/jolly_gerbils.txt diff --git a/forge-gui/res/cardsfolder/upcoming/junkblade_bruiser.txt b/forge-gui/res/cardsfolder/j/junkblade_bruiser.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/junkblade_bruiser.txt rename to forge-gui/res/cardsfolder/j/junkblade_bruiser.txt diff --git a/forge-gui/res/cardsfolder/k/kalamax_the_stormsire.txt b/forge-gui/res/cardsfolder/k/kalamax_the_stormsire.txt index 11a2a504d66..1ffd5f94a78 100644 --- a/forge-gui/res/cardsfolder/k/kalamax_the_stormsire.txt +++ b/forge-gui/res/cardsfolder/k/kalamax_the_stormsire.txt @@ -2,7 +2,7 @@ Name:Kalamax, the Stormsire ManaCost:1 G U R Types:Legendary Creature Elemental Dinosaur PT:4/4 -T:Mode$ SpellCast | ValidCard$ Instant | ValidActivatingPlayer$ You | ActivatorThisTurnCast$ EQ1 | IsPresent$ Card.Self+tapped | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast your first instant spell each turn, if CARDNAME is tapped, copy that spell. You may choose new targets for the copy. +T:Mode$ SpellCast | ValidCard$ Instant | ValidActivatingPlayer$ You | ActivatorThisTurnCast$ EQ1 | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast your first instant spell each turn, if CARDNAME is tapped, copy that spell. You may choose new targets for the copy. SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | AILogic$ Always | MayChooseTarget$ True SVar:BuffedBy:Instant T:Mode$ SpellCopy | ValidCard$ Instant | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you copy an instant spell, put a +1/+1 counter on NICKNAME. diff --git a/forge-gui/res/cardsfolder/k/karlovs_crossbow.txt b/forge-gui/res/cardsfolder/k/karlovs_crossbow.txt new file mode 100644 index 00000000000..1dccd605cd5 --- /dev/null +++ b/forge-gui/res/cardsfolder/k/karlovs_crossbow.txt @@ -0,0 +1,10 @@ +Name:Karlov's Crossbow +ManaCost:5 +Types:Artifact Equipment +T:Mode$ Attacks | ValidCard$ Card.EquippedBy | Execute$ TrigSac | TriggerDescription$ Whenever equipped creature attacks, sacrifice CARDNAME and destroy target creature an opponent controls. +SVar:TrigSac:DB$ Sacrifice | SubAbility$ DBDestroy +SVar:DBDestroy:DB$ Destroy | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls. +K:Equip:1 +A:AB$ Effect | Cost$ 0 Reveal<1/CARDNAME> | Forecast$ True | Name$ Emblem — Karlov's Crossbow | StaticAbilities$ ReduceCost | Duration$ Permanent | AILogic$ Always | SpellDescription$ For the remainder of the game, spells you cast named Karlov's Crossbow cost {1} less to cast. (Activate only during your upkeep and only once each turn.) +SVar:ReduceCost:Mode$ ReduceCost | ValidCard$ Card.namedKarlov's Crossbow | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Spells you cast named Karlov's Crossbow cost {1} less to cast. +Oracle:Whenever equipped creature attacks, sacrifice Karlov's Crossbow and destroy target creature an opponent controls.\nEquip {1}\nForecast — {0}, Reveal Karlov's Crossbow from your hand: For the remainder of the game, spells you cast named Karlov's Crossbow cost {1} less to cast. (Activate only during your upkeep and only once each turn.) diff --git a/forge-gui/res/cardsfolder/upcoming/kassandra_eagle_bearer.txt b/forge-gui/res/cardsfolder/k/kassandra_eagle_bearer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/kassandra_eagle_bearer.txt rename to forge-gui/res/cardsfolder/k/kassandra_eagle_bearer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/kastral_the_windcrested.txt b/forge-gui/res/cardsfolder/k/kastral_the_windcrested.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/kastral_the_windcrested.txt rename to forge-gui/res/cardsfolder/k/kastral_the_windcrested.txt diff --git a/forge-gui/res/cardsfolder/upcoming/keen_eyed_curator.txt b/forge-gui/res/cardsfolder/k/keen_eyed_curator.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/keen_eyed_curator.txt rename to forge-gui/res/cardsfolder/k/keen_eyed_curator.txt diff --git a/forge-gui/res/cardsfolder/upcoming/keen_eyed_raven.txt b/forge-gui/res/cardsfolder/k/keen_eyed_raven.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/keen_eyed_raven.txt rename to forge-gui/res/cardsfolder/k/keen_eyed_raven.txt diff --git a/forge-gui/res/cardsfolder/k/keeper_of_tresserhorn.txt b/forge-gui/res/cardsfolder/k/keeper_of_tresserhorn.txt index 952f234abdb..038b58d75ef 100644 --- a/forge-gui/res/cardsfolder/k/keeper_of_tresserhorn.txt +++ b/forge-gui/res/cardsfolder/k/keeper_of_tresserhorn.txt @@ -2,7 +2,8 @@ Name:Keeper of Tresserhorn ManaCost:5 B Types:Creature Avatar PT:6/6 -T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, it assigns no combat damage this turn and defending player loses 2 life. -SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | SubAbility$ DBLose +T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ DBNoCombatDamage | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, it assigns no combat damage this turn and defending player loses 2 life. +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT | SubAbility$ DBLose +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:DBLose:DB$ LoseLife | Defined$ TriggeredDefendingPlayer | LifeAmount$ 2 Oracle:Whenever Keeper of Tresserhorn attacks and isn't blocked, it assigns no combat damage this turn and defending player loses 2 life. diff --git a/forge-gui/res/cardsfolder/upcoming/kindlespark_duo.txt b/forge-gui/res/cardsfolder/k/kindlespark_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/kindlespark_duo.txt rename to forge-gui/res/cardsfolder/k/kindlespark_duo.txt diff --git a/forge-gui/res/cardsfolder/k/kirtars_wrath.txt b/forge-gui/res/cardsfolder/k/kirtars_wrath.txt index 5555d53a142..f0869a3c597 100644 --- a/forge-gui/res/cardsfolder/k/kirtars_wrath.txt +++ b/forge-gui/res/cardsfolder/k/kirtars_wrath.txt @@ -1,7 +1,10 @@ Name:Kirtar's Wrath ManaCost:4 W W Types:Sorcery -A:SP$ DestroyAll | ValidCards$ Creature | NoRegen$ True | SubAbility$ ThreshToken | SpellDescription$ Destroy all creatures. They can't be regenerated. Threshold — If seven or more cards are in your graveyard, instead destroy all creatures, then create two 1/1 white Spirit creature tokens with flying. Creatures destroyed this way can't be regenerated. -SVar:ThreshToken:DB$ Token | Condition$ Threshold | TokenAmount$ 2 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You +A:SP$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE7 | TrueSubAbility$ ThreshDestruction | FalseSubAbility$ Destruction | SpellDescription$ Destroy all creatures. They can't be regenerated. Threshold — If seven or more cards are in your graveyard, instead destroy all creatures, then create two 1/1 white Spirit creature tokens with flying. Creatures destroyed this way can't be regenerated. +SVar:Destruction:DB$ DestroyAll | ValidCards$ Creature | NoRegen$ True +SVar:ThreshDestruction:DB$ DestroyAll | ValidCards$ Creature | NoRegen$ True | SubAbility$ ThreshToken +SVar:ThreshToken:DB$ Token | TokenAmount$ 2 | TokenScript$ w_1_1_spirit_flying | TokenOwner$ You +SVar:X:Count$ValidGraveyard Card.YouOwn DeckHas:Ability$Token Oracle:Destroy all creatures. They can't be regenerated.\nThreshold — If seven or more cards are in your graveyard, instead destroy all creatures, then create two 1/1 white Spirit creature tokens with flying. Creatures destroyed this way can't be regenerated. diff --git a/forge-gui/res/cardsfolder/upcoming/kitnap.txt b/forge-gui/res/cardsfolder/k/kitnap.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/kitnap.txt rename to forge-gui/res/cardsfolder/k/kitnap.txt diff --git a/forge-gui/res/cardsfolder/upcoming/kitsa_otterball_elite.txt b/forge-gui/res/cardsfolder/k/kitsa_otterball_elite.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/kitsa_otterball_elite.txt rename to forge-gui/res/cardsfolder/k/kitsa_otterball_elite.txt diff --git a/forge-gui/res/cardsfolder/upcoming/knightfisher.txt b/forge-gui/res/cardsfolder/k/knightfisher.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/knightfisher.txt rename to forge-gui/res/cardsfolder/k/knightfisher.txt diff --git a/forge-gui/res/cardsfolder/k/kukemssa_pirates.txt b/forge-gui/res/cardsfolder/k/kukemssa_pirates.txt index 64436970566..cf5e10b5c88 100644 --- a/forge-gui/res/cardsfolder/k/kukemssa_pirates.txt +++ b/forge-gui/res/cardsfolder/k/kukemssa_pirates.txt @@ -4,5 +4,6 @@ Types:Creature Human Pirate PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ TrigGainControl | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may gain control of target artifact defending player controls. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigGainControl:DB$ GainControl | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact defending player controls | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. Oracle:Whenever Kukemssa Pirates attacks and isn't blocked, you may gain control of target artifact defending player controls. If you do, Kukemssa Pirates assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/labyrinth_adversary.txt b/forge-gui/res/cardsfolder/l/labyrinth_adversary.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/labyrinth_adversary.txt rename to forge-gui/res/cardsfolder/l/labyrinth_adversary.txt diff --git a/forge-gui/res/cardsfolder/l/laccolith_grunt.txt b/forge-gui/res/cardsfolder/l/laccolith_grunt.txt index bc9e368fa65..f5327025c0d 100644 --- a/forge-gui/res/cardsfolder/l/laccolith_grunt.txt +++ b/forge-gui/res/cardsfolder/l/laccolith_grunt.txt @@ -4,6 +4,7 @@ Types:Creature Beast PT:2/2 T:Mode$ AttackerBlocked | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME becomes blocked, you may have it deal damage equal to its power to target creature. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:X:Count$CardPower Oracle:Whenever Laccolith Grunt becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Grunt assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/l/laccolith_rig.txt b/forge-gui/res/cardsfolder/l/laccolith_rig.txt index b46aebf61b4..17b7f6ac3d3 100644 --- a/forge-gui/res/cardsfolder/l/laccolith_rig.txt +++ b/forge-gui/res/cardsfolder/l/laccolith_rig.txt @@ -4,7 +4,8 @@ Types:Enchantment Aura K:Enchant creature A:SP$ Attach | Cost$ R | ValidTgts$ Creature | AITgts$ Card.powerGE1 | AILogic$ Pump T:Mode$ AttackerBlocked | ValidCard$ Card.AttachedBy | TriggerZones$ Battlefield | Execute$ LaccolithDmg | OptionalDecider$ You | TriggerDescription$ Whenever enchanted creature becomes blocked, you may have it deal damage equal to its power to target creature. If you do, the first creature assigns no combat damage this turn. -SVar:LaccolithDmg:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to deal damage to | NumDmg$ RigX | SubAbility$ NoCombatDamage | DamageSource$ TriggeredAttacker -SVar:NoCombatDamage:DB$ Pump | Defined$ TriggeredAttackerLKICopy | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:LaccolithDmg:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to deal damage to | NumDmg$ RigX | SubAbility$ DBNoCombatDamage | DamageSource$ TriggeredAttacker +SVar:DBNoCombatDamage:DB$ Effect | RememberObjects$ TriggeredAttackerLKICopy | StaticAbilities$ SNoCombatDamage | ForgetOnMoved$ Battlefield +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.IsRemembered | Description$ Remembered creature assigns no combat damage this turn. SVar:RigX:TriggeredAttacker$CardPower Oracle:Enchant creature\nWhenever enchanted creature becomes blocked, you may have it deal damage equal to its power to target creature. If you do, the first creature assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/l/laccolith_titan.txt b/forge-gui/res/cardsfolder/l/laccolith_titan.txt index e4e9d0d683e..56ac65de042 100644 --- a/forge-gui/res/cardsfolder/l/laccolith_titan.txt +++ b/forge-gui/res/cardsfolder/l/laccolith_titan.txt @@ -4,6 +4,7 @@ Types:Creature Beast PT:6/6 T:Mode$ AttackerBlocked | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME becomes blocked, you may have it deal damage equal to its power to target creature. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:X:Count$CardPower Oracle:Whenever Laccolith Titan becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Titan assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/l/laccolith_warrior.txt b/forge-gui/res/cardsfolder/l/laccolith_warrior.txt index 4ab6d596776..825b4595fd6 100644 --- a/forge-gui/res/cardsfolder/l/laccolith_warrior.txt +++ b/forge-gui/res/cardsfolder/l/laccolith_warrior.txt @@ -4,6 +4,7 @@ Types:Creature Beast Warrior PT:3/3 T:Mode$ AttackerBlocked | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME becomes blocked, you may have it deal damage equal to its power to target creature. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:X:Count$CardPower Oracle:Whenever Laccolith Warrior becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Warrior assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/l/laccolith_whelp.txt b/forge-gui/res/cardsfolder/l/laccolith_whelp.txt index 5c2419650ec..431c8ddf84b 100644 --- a/forge-gui/res/cardsfolder/l/laccolith_whelp.txt +++ b/forge-gui/res/cardsfolder/l/laccolith_whelp.txt @@ -4,6 +4,7 @@ Types:Creature Beast PT:1/1 T:Mode$ AttackerBlocked | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME becomes blocked, you may have it deal damage equal to its power to target creature. If you do, CARDNAME assigns no combat damage this turn. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SubAbility$ DBNoCombatDamage -SVar:DBNoCombatDamage:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:X:Count$CardPower Oracle:Whenever Laccolith Whelp becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Whelp assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/layla_hassan.txt b/forge-gui/res/cardsfolder/l/layla_hassan.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/layla_hassan.txt rename to forge-gui/res/cardsfolder/l/layla_hassan.txt diff --git a/forge-gui/res/cardsfolder/l/leaf_leap_guide.txt b/forge-gui/res/cardsfolder/l/leaf_leap_guide.txt new file mode 100644 index 00000000000..874660a154d --- /dev/null +++ b/forge-gui/res/cardsfolder/l/leaf_leap_guide.txt @@ -0,0 +1,9 @@ +Name:Leaf-Leap Guide +ManaCost:G U +Types:Creature Frog Scout +PT:1/1 +K:Vigilance +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever another creature you control enters, CARDNAME and that creature perpetually get +1/+1. +SVar:TrigPump:DB$ Pump | Defined$ Self & TriggeredCardLKICopy | NumAtt$ 1 | NumDef$ 1 | Duration$ Perpetual +A:AB$ ChangeZone | Cost$ 1 T | ValidTgts$ Creature.YouCtrl+Other | TgtPrompt$ Select another target creature you control | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return another target creature you control to its owner's hand. +Oracle:Vigilance\nWhenever another creature you control enters, Leaf-Leap Guide and that creature perpetually get +1/+1.\n{1}, {T}: Return another target creature you control to its owner's hand. diff --git a/forge-gui/res/cardsfolder/l/legolas_counter_of_kills.txt b/forge-gui/res/cardsfolder/l/legolas_counter_of_kills.txt index 3f7052b7362..d4494c29e9f 100644 --- a/forge-gui/res/cardsfolder/l/legolas_counter_of_kills.txt +++ b/forge-gui/res/cardsfolder/l/legolas_counter_of_kills.txt @@ -3,7 +3,7 @@ ManaCost:2 G U Types:Legendary Creature Elf Archer PT:2/3 K:Reach -T:Mode$ Scry | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | OptionalDecider$ You | IsPresent$ Card.Self+tapped | ResolvedLimit$ 1 | TriggerDescription$ Whenever you scry, if CARDNAME is tapped, you may untap it. Do this only once each turn. +T:Mode$ Scry | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | OptionalDecider$ You | PresentDefined$ Self | IsPresent$ Card.tapped | ResolvedLimit$ 1 | TriggerDescription$ Whenever you scry, if CARDNAME is tapped, you may untap it. Do this only once each turn. SVar:TrigUntap:DB$ Untap | Defined$ Self T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.OppCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever a creature an opponent controls dies, put a +1/+1 counter on NICKNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 diff --git a/forge-gui/res/cardsfolder/l/leisure_bicycle.txt b/forge-gui/res/cardsfolder/l/leisure_bicycle.txt new file mode 100644 index 00000000000..16bf2a2d304 --- /dev/null +++ b/forge-gui/res/cardsfolder/l/leisure_bicycle.txt @@ -0,0 +1,11 @@ +Name:Leisure Bicycle +ManaCost:2 +Types:Artifact Vehicle +PT:3/1 +K:Crew:1 +K:Cycling:2 +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigExplore | TriggerDescription$ Whenever CARDNAME attacks, target creature that crewed it this turn explores. +SVar:TrigExplore:DB$ Explore | ValidTgts$ Creature.CrewedThisTurn | TgtPrompt$ Select target creature that crewed it this turn +DeckHas:Ability$Counters|Discard +SVar:HasAttackEffect:TRUE +Oracle:Whenever Leisure Bicycle attacks, target creature that crewed it this turn explores.\nCrew 1\nCycling {2} diff --git a/forge-gui/res/cardsfolder/l/lich.txt b/forge-gui/res/cardsfolder/l/lich.txt index 1096555d6e8..121e1c98a8b 100644 --- a/forge-gui/res/cardsfolder/l/lich.txt +++ b/forge-gui/res/cardsfolder/l/lich.txt @@ -4,7 +4,7 @@ Types:Enchantment R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LoseLife | ReplacementResult$ Updated | Description$ As CARDNAME enters, you lose life equal to your life total. SVar:LoseLife:DB$ LoseLife | LifeAmount$ LifeTotal SVar:LifeTotal:Count$YourLifeTotal -S:Mode$ Continuous | Affected$ You | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ You don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | Description$ You don't lose the game for having 0 or less life. R:Event$ GainLife | ActiveZones$ Battlefield | ValidPlayer$ You | AILogic$ LichDraw | ReplaceWith$ Draw | Description$ If you would gain life, draw that many cards instead. SVar:Draw:DB$ Draw | Defined$ You | NumCards$ X SVar:X:ReplaceCount$LifeGained diff --git a/forge-gui/res/cardsfolder/l/lichs_mastery.txt b/forge-gui/res/cardsfolder/l/lichs_mastery.txt index 2fd0cc9ae83..9b47eb06d5a 100644 --- a/forge-gui/res/cardsfolder/l/lichs_mastery.txt +++ b/forge-gui/res/cardsfolder/l/lichs_mastery.txt @@ -2,7 +2,7 @@ Name:Lich's Mastery ManaCost:3 B B B Types:Legendary Enchantment K:Hexproof -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game. T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you gain life, draw that many cards. SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X SVar:X:TriggerCount$LifeAmount diff --git a/forge-gui/res/cardsfolder/l/lichs_tomb.txt b/forge-gui/res/cardsfolder/l/lichs_tomb.txt index a17e3cbbcfe..eb38861b643 100644 --- a/forge-gui/res/cardsfolder/l/lichs_tomb.txt +++ b/forge-gui/res/cardsfolder/l/lichs_tomb.txt @@ -1,7 +1,7 @@ Name:Lich's Tomb ManaCost:4 Types:Artifact -S:Mode$ Continuous | Affected$ You | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ You don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | Description$ You don't lose the game for having 0 or less life. T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ Whenever you lose life, sacrifice a permanent for each 1 life you lost. (Damage causes loss of life.) SVar:TrigSac:DB$ Sacrifice | Amount$ X | SacValid$ Permanent SVar:X:TriggerCount$LifeAmount diff --git a/forge-gui/res/cardsfolder/upcoming/lifecreed_duo.txt b/forge-gui/res/cardsfolder/l/lifecreed_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lifecreed_duo.txt rename to forge-gui/res/cardsfolder/l/lifecreed_duo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lightshell_duo.txt b/forge-gui/res/cardsfolder/l/lightshell_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lightshell_duo.txt rename to forge-gui/res/cardsfolder/l/lightshell_duo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lilypad_village.txt b/forge-gui/res/cardsfolder/l/lilypad_village.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lilypad_village.txt rename to forge-gui/res/cardsfolder/l/lilypad_village.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lilysplash_mentor.txt b/forge-gui/res/cardsfolder/l/lilysplash_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lilysplash_mentor.txt rename to forge-gui/res/cardsfolder/l/lilysplash_mentor.txt diff --git a/forge-gui/res/cardsfolder/l/lim_duls_paladin.txt b/forge-gui/res/cardsfolder/l/lim_duls_paladin.txt index 4f7d19e423a..48852bfa1e7 100644 --- a/forge-gui/res/cardsfolder/l/lim_duls_paladin.txt +++ b/forge-gui/res/cardsfolder/l/lim_duls_paladin.txt @@ -10,8 +10,9 @@ SVar:DBDraw:DB$ Draw | NumCards$ 1 | ConditionCheckSVar$ X | ConditionSVarCompar SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True T:Mode$ AttackerBlocked | ValidCard$ Card.Self | ValidBlocker$ Creature | TriggerZones$ Battlefield | Execute$ TrigBlockedPump | TriggerDescription$ Whenever CARDNAME becomes blocked, CARDNAME get +6/+3 until end of turn. SVar:TrigBlockedPump:DB$ Pump | Defined$ Self | NumAtt$ 6 | NumDef$ 3 -T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ TrigUnBlockedPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, it assigns no combat damage this turn and defending player loses 4 life. -SVar:TrigUnBlockedPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | SubAbility$ DBLoseLife +T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ DBNoCombatDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, it assigns no combat damage this turn and defending player loses 4 life. +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT | SubAbility$ DBLoseLife +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:DBLoseLife:DB$ LoseLife | Defined$ TriggeredDefendingPlayer | LifeAmount$ 4 SVar:X:Remembered$Amount AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/l/lock_and_load.txt b/forge-gui/res/cardsfolder/l/lock_and_load.txt index 26d64ea4368..d2bd77f17a3 100644 --- a/forge-gui/res/cardsfolder/l/lock_and_load.txt +++ b/forge-gui/res/cardsfolder/l/lock_and_load.txt @@ -4,5 +4,5 @@ Types:Sorcery K:Plot:3 U A:SP$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBDrawX | StackDescription$ SpellDescription | SpellDescription$ Draw a card, then draw a card for each other instant and sorcery spell you've cast this turn. SVar:DBDrawX:DB$ Draw | Defined$ You | NumCards$ X | StackDescription$ None -SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl/Minus.1 +SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl+!CastSaSource Oracle:Draw a card, then draw a card for each other instant and sorcery spell you've cast this turn.\nPlot {3}{U} (You may pay {3}{U} and exile this card from your hand. Cast it as a sorcery on a later turn without paying its mana cost. Plot only as a sorcery.) diff --git a/forge-gui/res/cardsfolder/upcoming/long_river_lurker.txt b/forge-gui/res/cardsfolder/l/long_river_lurker.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/long_river_lurker.txt rename to forge-gui/res/cardsfolder/l/long_river_lurker.txt diff --git a/forge-gui/res/cardsfolder/upcoming/long_rivers_pull.txt b/forge-gui/res/cardsfolder/l/long_rivers_pull.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/long_rivers_pull.txt rename to forge-gui/res/cardsfolder/l/long_rivers_pull.txt diff --git a/forge-gui/res/cardsfolder/upcoming/longstalk_brawl.txt b/forge-gui/res/cardsfolder/l/longstalk_brawl.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/longstalk_brawl.txt rename to forge-gui/res/cardsfolder/l/longstalk_brawl.txt diff --git a/forge-gui/res/cardsfolder/upcoming/loyal_inventor.txt b/forge-gui/res/cardsfolder/l/loyal_inventor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/loyal_inventor.txt rename to forge-gui/res/cardsfolder/l/loyal_inventor.txt diff --git a/forge-gui/res/cardsfolder/l/lullmages_domination.txt b/forge-gui/res/cardsfolder/l/lullmages_domination.txt index d35dea6f689..947cc15e32a 100644 --- a/forge-gui/res/cardsfolder/l/lullmages_domination.txt +++ b/forge-gui/res/cardsfolder/l/lullmages_domination.txt @@ -1,7 +1,7 @@ Name:Lullmage's Domination ManaCost:X U U U Types:Sorcery -S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ XGrave | Relative$ True | EffectZone$ All | Description$ This spell costs {3} less to cast if it targets a creature whose player has eight or more cards in their graveyard. +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ XGrave | Relative$ True | EffectZone$ All | Description$ This spell costs {3} less to cast if it targets a creature whose controller has eight or more cards in their graveyard. SVar:XGrave:Count$Compare CheckTgt GE8.3.0 SVar:CheckTgt:TargetedController$CardsInGraveyard A:SP$ GainControl | ValidTgts$ Creature.cmcEQX | TgtPrompt$ Select target creature | SpellDescription$ Gain control of target creature with mana value X. diff --git a/forge-gui/res/cardsfolder/upcoming/lunar_convocation.txt b/forge-gui/res/cardsfolder/l/lunar_convocation.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lunar_convocation.txt rename to forge-gui/res/cardsfolder/l/lunar_convocation.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lupinflower_village.txt b/forge-gui/res/cardsfolder/l/lupinflower_village.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lupinflower_village.txt rename to forge-gui/res/cardsfolder/l/lupinflower_village.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lydia_frye.txt b/forge-gui/res/cardsfolder/l/lydia_frye.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/lydia_frye.txt rename to forge-gui/res/cardsfolder/l/lydia_frye.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mabels_mettle.txt b/forge-gui/res/cardsfolder/m/mabels_mettle.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mabels_mettle.txt rename to forge-gui/res/cardsfolder/m/mabels_mettle.txt diff --git a/forge-gui/res/cardsfolder/upcoming/maha_its_feathers_night.txt b/forge-gui/res/cardsfolder/m/maha_its_feathers_night.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/maha_its_feathers_night.txt rename to forge-gui/res/cardsfolder/m/maha_its_feathers_night.txt diff --git a/forge-gui/res/cardsfolder/m/mana_vault.txt b/forge-gui/res/cardsfolder/m/mana_vault.txt index ec1069549a0..4109787142c 100644 --- a/forge-gui/res/cardsfolder/m/mana_vault.txt +++ b/forge-gui/res/cardsfolder/m/mana_vault.txt @@ -4,9 +4,9 @@ Types:Artifact A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 3 | SpellDescription$ Add {C}{C}{C}. K:CARDNAME doesn't untap during your untap step. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ At the beginning of your upkeep, you may pay {4}. If you do, untap CARDNAME. -T:Mode$ Phase | Phase$ Draw | ValidPlayer$ You | IsPresent$ Card.Self+tapped | Execute$ TrigDamage | TriggerDescription$ At the beginning of your draw step, if CARDNAME is tapped, it deals 1 damage to you. +T:Mode$ Phase | Phase$ Draw | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigDamage | TriggerDescription$ At the beginning of your draw step, if CARDNAME is tapped, it deals 1 damage to you. SVar:TrigUntap:AB$ Untap | Cost$ 4 | Defined$ Self -SVar:TrigDamage:DB$ DealDamage | Defined$ You | NumDmg$ 1 | ConditionDefined$ Self | ConditionPresent$ Card.tapped +SVar:TrigDamage:DB$ DealDamage | Defined$ You | NumDmg$ 1 SVar:UntapMe:True AI:RemoveDeck:Random Oracle:Mana Vault doesn't untap during your untap step.\nAt the beginning of your upkeep, you may pay {4}. If you do, untap Mana Vault.\nAt the beginning of your draw step, if Mana Vault is tapped, it deals 1 damage to you.\n{T}: Add {C}{C}{C}. diff --git a/forge-gui/res/cardsfolder/upcoming/manifold_mouse.txt b/forge-gui/res/cardsfolder/m/manifold_mouse.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/manifold_mouse.txt rename to forge-gui/res/cardsfolder/m/manifold_mouse.txt diff --git a/forge-gui/res/cardsfolder/m/marshland_hordemaster.txt b/forge-gui/res/cardsfolder/m/marshland_hordemaster.txt new file mode 100644 index 00000000000..df09107ff1e --- /dev/null +++ b/forge-gui/res/cardsfolder/m/marshland_hordemaster.txt @@ -0,0 +1,10 @@ +Name:Marshland Hordemaster +ManaCost:1 B R +Types:Creature Lizard Warlock +PT:2/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self,Lizard.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigBattleCry | TriggerDescription$ Whenever CARDNAME or another Lizard you control enters, CARDNAME perpetually gains battle cry. +SVar:TrigBattleCry:DB$ Pump | Defined$ Self | KW$ Battle cry | Duration$ Perpetual +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self,Lizard.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever CARDNAME or another Lizard you control dies, target opponent loses 1 life and you gain 1 life. +SVar:TrigLoseLife:DB$ LoseLife | ValidTgts$ Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 +Oracle:Whenever Marshland Hordemaster or another Lizard you control enters, Marshland Hordemaster perpetually gains battle cry.\nWhenever Marshland Hordemaster or another Lizard you control dies, target opponent loses 1 life and you gain 1 life. diff --git a/forge-gui/res/cardsfolder/upcoming/mary_read_and_anne_bonny.txt b/forge-gui/res/cardsfolder/m/mary_read_and_anne_bonny.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mary_read_and_anne_bonny.txt rename to forge-gui/res/cardsfolder/m/mary_read_and_anne_bonny.txt diff --git a/forge-gui/res/cardsfolder/m/master_of_cruelties.txt b/forge-gui/res/cardsfolder/m/master_of_cruelties.txt index 2287da73400..9a96febde13 100644 --- a/forge-gui/res/cardsfolder/m/master_of_cruelties.txt +++ b/forge-gui/res/cardsfolder/m/master_of_cruelties.txt @@ -6,7 +6,8 @@ K:First Strike K:Deathtouch K:CARDNAME can only attack alone. T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | ValidDefender$ Player | Execute$ TrigDamage | TriggerDescription$ Whenever CARDNAME attacks a player and isn't blocked, that player's life total becomes 1. CARDNAME assigns no combat damage this combat. -SVar:TrigDamage:DB$ SetLife | Defined$ TriggeredDefender | LifeAmount$ 1 | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | Duration$ UntilEndOfCombat +SVar:TrigDamage:DB$ SetLife | Defined$ TriggeredDefender | LifeAmount$ 1 | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEndOfCombat +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:MustBeBlocked:True Oracle:First strike, deathtouch\nMaster of Cruelties can only attack alone.\nWhenever Master of Cruelties attacks a player and isn't blocked, that player's life total becomes 1. Master of Cruelties assigns no combat damage this combat. diff --git a/forge-gui/res/cardsfolder/upcoming/merciless_harlequin.txt b/forge-gui/res/cardsfolder/m/merciless_harlequin.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/merciless_harlequin.txt rename to forge-gui/res/cardsfolder/m/merciless_harlequin.txt diff --git a/forge-gui/res/cardsfolder/upcoming/might_of_the_meek.txt b/forge-gui/res/cardsfolder/m/might_of_the_meek.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/might_of_the_meek.txt rename to forge-gui/res/cardsfolder/m/might_of_the_meek.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mind_drill_assailant.txt b/forge-gui/res/cardsfolder/m/mind_drill_assailant.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mind_drill_assailant.txt rename to forge-gui/res/cardsfolder/m/mind_drill_assailant.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mind_spiral.txt b/forge-gui/res/cardsfolder/m/mind_spiral.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mind_spiral.txt rename to forge-gui/res/cardsfolder/m/mind_spiral.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mindwhisker.txt b/forge-gui/res/cardsfolder/m/mindwhisker.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mindwhisker.txt rename to forge-gui/res/cardsfolder/m/mindwhisker.txt diff --git a/forge-gui/res/cardsfolder/m/mine_mine_mine.txt b/forge-gui/res/cardsfolder/m/mine_mine_mine.txt index 4aa3cf07674..0da4d59a201 100644 --- a/forge-gui/res/cardsfolder/m/mine_mine_mine.txt +++ b/forge-gui/res/cardsfolder/m/mine_mine_mine.txt @@ -3,8 +3,8 @@ ManaCost:4 G G Types:Enchantment T:Mode$ ChangesZone | ValidCard$ Card.Self | Destination$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters, each player puts their library into their hand. SVar:TrigChangeZone:DB$ ChangeZoneAll | ChangeType$ Card | Origin$ Library | Destination$ Hand -S:Mode$ Continuous | Affected$ Player | SetMaxHandSize$ Unlimited | Description$ Players don't lose the game for drawing from an empty library. -S:Mode$ Continuous | Affected$ Player | Secondary$ True | AddKeyword$ You don't lose the game for drawing from an empty library. | Description$ Players don't lose the game for drawing from an empty library. +S:Mode$ Continuous | Affected$ Player | SetMaxHandSize$ Unlimited | Description$ Players have no maximum hand size and don't lose the game for drawing from an empty library. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ Player | ValidLoseReason$ Milled | Layer$ CantHappen | Secondary$ True | Description$ Players don't lose the game for drawing from an empty library. S:Mode$ CantBeCast | ValidCard$ Card | Caster$ Player | NumLimitEachTurn$ 1 | Description$ Each player can't cast more than one spell each turn. T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Execute$ TrigShuffleBack | TriggerDescription$ When CARDNAME leaves the battlefield, each player shuffles their hand and graveyard into their library. SVar:TrigShuffleBack:DB$ ChangeZoneAll | ChangeType$ Card | Origin$ Hand,Graveyard | Destination$ Library | Shuffle$ True | Random$ True diff --git a/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt b/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt index 666c786fda7..171eb5edf79 100644 --- a/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt +++ b/forge-gui/res/cardsfolder/m/mishra_claimed_by_gix_mishra_lost_to_phyrexia.txt @@ -23,7 +23,8 @@ PT:9/9 Colors:black,red T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Whenever CARDNAME enters or attacks, ABILITY T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters or attacks, ABILITY -SVar:TrigCharm:DB$ Charm | Choices$ DBDamage,DBDestroy,DBPump,DBCurse,DBToken | CharmNum$ 3 +SVar:TrigCharm:DB$ Charm | Choices$ DBDiscard,DBDamage,DBDestroy,DBPump,DBCurse,DBToken | CharmNum$ 3 +SVar:DBDiscard:DB$ Discard | ValidTgts$ Opponent | NumCards$ 2 | Mode$ TgtChoose | SpellDescription$ Target opponent discards two cards. SVar:DBDamage:DB$ DealDamage | NumDmg$ 3 | ValidTgts$ Any | SpellDescription$ NICKNAME deals 3 damage to any target. SVar:DBDestroy:DB$ Destroy | TargetMax$ 1 | ValidTgts$ Artifact,Planeswalker | TgtPrompt$ Select target artifact or planeswalker | SpellDescription$ Destroy target artifact or planeswalker SVar:DBPump:DB$ PumpAll | ValidCards$ Card.Creature+YouCtrl | KW$ Menace & Trample | SpellDescription$ Creatures you control gain menace and trample until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/mistbreath_elder.txt b/forge-gui/res/cardsfolder/m/mistbreath_elder.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mistbreath_elder.txt rename to forge-gui/res/cardsfolder/m/mistbreath_elder.txt diff --git a/forge-gui/res/cardsfolder/upcoming/misthioss_fury.txt b/forge-gui/res/cardsfolder/m/misthioss_fury.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/misthioss_fury.txt rename to forge-gui/res/cardsfolder/m/misthioss_fury.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mjolnir_storm_hammer.txt b/forge-gui/res/cardsfolder/m/mjolnir_storm_hammer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mjolnir_storm_hammer.txt rename to forge-gui/res/cardsfolder/m/mjolnir_storm_hammer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mockingbird.txt b/forge-gui/res/cardsfolder/m/mockingbird.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mockingbird.txt rename to forge-gui/res/cardsfolder/m/mockingbird.txt diff --git a/forge-gui/res/cardsfolder/upcoming/monastery_raid.txt b/forge-gui/res/cardsfolder/m/monastery_raid.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/monastery_raid.txt rename to forge-gui/res/cardsfolder/m/monastery_raid.txt diff --git a/forge-gui/res/cardsfolder/upcoming/moonrise_cleric.txt b/forge-gui/res/cardsfolder/m/moonrise_cleric.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/moonrise_cleric.txt rename to forge-gui/res/cardsfolder/m/moonrise_cleric.txt diff --git a/forge-gui/res/cardsfolder/upcoming/moonstone_eulogist.txt b/forge-gui/res/cardsfolder/m/moonstone_eulogist.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/moonstone_eulogist.txt rename to forge-gui/res/cardsfolder/m/moonstone_eulogist.txt diff --git a/forge-gui/res/cardsfolder/upcoming/moonstone_harbinger.txt b/forge-gui/res/cardsfolder/m/moonstone_harbinger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/moonstone_harbinger.txt rename to forge-gui/res/cardsfolder/m/moonstone_harbinger.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mouse_trapper.txt b/forge-gui/res/cardsfolder/m/mouse_trapper.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mouse_trapper.txt rename to forge-gui/res/cardsfolder/m/mouse_trapper.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mr_foxglove.txt b/forge-gui/res/cardsfolder/m/mr_foxglove.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mr_foxglove.txt rename to forge-gui/res/cardsfolder/m/mr_foxglove.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ms_bumbleflower.txt b/forge-gui/res/cardsfolder/m/ms_bumbleflower.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ms_bumbleflower.txt rename to forge-gui/res/cardsfolder/m/ms_bumbleflower.txt diff --git a/forge-gui/res/cardsfolder/upcoming/mudflat_village.txt b/forge-gui/res/cardsfolder/m/mudflat_village.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/mudflat_village.txt rename to forge-gui/res/cardsfolder/m/mudflat_village.txt diff --git a/forge-gui/res/cardsfolder/upcoming/muerra_trash_tactician.txt b/forge-gui/res/cardsfolder/m/muerra_trash_tactician.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/muerra_trash_tactician.txt rename to forge-gui/res/cardsfolder/m/muerra_trash_tactician.txt diff --git a/forge-gui/res/cardsfolder/m/murder_of_crows.txt b/forge-gui/res/cardsfolder/m/murder_of_crows.txt index f59bc0c9994..d6dfed31918 100644 --- a/forge-gui/res/cardsfolder/m/murder_of_crows.txt +++ b/forge-gui/res/cardsfolder/m/murder_of_crows.txt @@ -3,6 +3,6 @@ ManaCost:3 U U Types:Creature Bird PT:4/4 K:Flying -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ TrigLoot | TriggerZones$ Battlefield | TriggerDescription$ Whenever another creature dies, you may draw a card. If you do, discard a card. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Other | Execute$ TrigLoot | TriggerZones$ Battlefield | TriggerDescription$ Whenever another creature dies, you may draw a card. If you do, discard a card. SVar:TrigLoot:AB$ Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1 | Cost$ Draw<1/You> Oracle:Flying\nWhenever another creature dies, you may draw a card. If you do, discard a card. diff --git a/forge-gui/res/cardsfolder/upcoming/murmuration.txt b/forge-gui/res/cardsfolder/m/murmuration.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/murmuration.txt rename to forge-gui/res/cardsfolder/m/murmuration.txt diff --git a/forge-gui/res/cardsfolder/m/my_undead_horde_awakens.txt b/forge-gui/res/cardsfolder/m/my_undead_horde_awakens.txt index 82daa2cbbd0..8ae214f6c6f 100644 --- a/forge-gui/res/cardsfolder/m/my_undead_horde_awakens.txt +++ b/forge-gui/res/cardsfolder/m/my_undead_horde_awakens.txt @@ -4,5 +4,5 @@ Types:Ongoing Scheme T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigNecromancy | OptionalDecider$ You | TriggerDescription$ At the beginning of your end step, you may put target creature card from an opponent's graveyard onto the battlefield under your control. SVar:TrigNecromancy:DB$ ChangeZone | ValidTgts$ Creature.OppCtrl | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | RememberChanged$ True T:Mode$ ChangesZone | ValidCard$ Creature.IsRemembered | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigAbandon | TriggerZones$ Command | TriggerDescription$ When a creature put onto the battlefield with this scheme dies, abandon this scheme. -SVar:TrigAbandon:AB$ Abandon | Cost$ 0 +SVar:TrigAbandon:DB$ Abandon Oracle:(An ongoing scheme remains face up until it's abandoned.)\nAt the beginning of your end step, you may put target creature card from an opponent's graveyard onto the battlefield under your control.\nWhen a creature put onto the battlefield with this scheme dies, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/n/nahiri_heir_of_the_ancients.txt b/forge-gui/res/cardsfolder/n/nahiri_heir_of_the_ancients.txt index 3274995bc88..c72eaeb7fd6 100644 --- a/forge-gui/res/cardsfolder/n/nahiri_heir_of_the_ancients.txt +++ b/forge-gui/res/cardsfolder/n/nahiri_heir_of_the_ancients.txt @@ -2,7 +2,7 @@ Name:Nahiri, Heir of the Ancients ManaCost:2 R W Types:Legendary Planeswalker Nahiri Loyalty:4 -A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenScript$ w_1_1_kor_soldier | RememberTokens$ True | SubAbility$ DBAttach | SpellDescription$ Create a 1/1 white Kor Soldier creature token. You may attach an Equipment you control to it. +A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenScript$ w_1_1_kor_warrior | RememberTokens$ True | SubAbility$ DBAttach | SpellDescription$ Create a 1/1 white Kor Warrior creature token. You may attach an Equipment you control to it. SVar:DBAttach:DB$ Attach | Optional$ True | Choices$ Equipment.YouCtrl | ChoiceTitle$ Choose an Equipment you control | Defined$ Remembered | SubAbility$ DBCleanup | StackDescription$ None SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True A:AB$ Dig | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | DigNum$ 6 | ChangeNum$ 1 | Optional$ True | ForceRevealToController$ True | ChangeValid$ Card.Warrior,Card.Equipment | RestRandomOrder$ True | SpellDescription$ Look at the top six cards of your library. You may reveal a Warrior or Equipment card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. diff --git a/forge-gui/res/cardsfolder/upcoming/nettle_guard.txt b/forge-gui/res/cardsfolder/n/nettle_guard.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/nettle_guard.txt rename to forge-gui/res/cardsfolder/n/nettle_guard.txt diff --git a/forge-gui/res/cardsfolder/upcoming/new_master_of_arms.txt b/forge-gui/res/cardsfolder/n/new_master_of_arms.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/new_master_of_arms.txt rename to forge-gui/res/cardsfolder/n/new_master_of_arms.txt diff --git a/forge-gui/res/cardsfolder/upcoming/nightwhorl_hermit.txt b/forge-gui/res/cardsfolder/n/nightwhorl_hermit.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/nightwhorl_hermit.txt rename to forge-gui/res/cardsfolder/n/nightwhorl_hermit.txt diff --git a/forge-gui/res/cardsfolder/n/nim_abomination.txt b/forge-gui/res/cardsfolder/n/nim_abomination.txt index 365a279efcd..7f5375d3498 100644 --- a/forge-gui/res/cardsfolder/n/nim_abomination.txt +++ b/forge-gui/res/cardsfolder/n/nim_abomination.txt @@ -2,6 +2,6 @@ Name:Nim Abomination ManaCost:2 B Types:Creature Zombie PT:3/4 -T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.Self+untapped | Execute$ TrigLoseLife | TriggerDescription$ At the beginning of your end step, if CARDNAME is untapped, you lose 3 life. -SVar:TrigLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 3 | ConditionDefined$ Self | ConditionPresent$ Card.untapped +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | PresentDefined$ Self | IsPresent$ Card.untapped | Execute$ TrigLoseLife | TriggerDescription$ At the beginning of your end step, if CARDNAME is untapped, you lose 3 life. +SVar:TrigLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 3 Oracle:At the beginning of your end step, if Nim Abomination is untapped, you lose 3 life. diff --git a/forge-gui/res/cardsfolder/upcoming/nocturnal_hunger.txt b/forge-gui/res/cardsfolder/n/nocturnal_hunger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/nocturnal_hunger.txt rename to forge-gui/res/cardsfolder/n/nocturnal_hunger.txt diff --git a/forge-gui/res/cardsfolder/n/nothing_can_stop_me_now.txt b/forge-gui/res/cardsfolder/n/nothing_can_stop_me_now.txt index 19c4cca2f6b..a977863abfc 100644 --- a/forge-gui/res/cardsfolder/n/nothing_can_stop_me_now.txt +++ b/forge-gui/res/cardsfolder/n/nothing_can_stop_me_now.txt @@ -5,6 +5,6 @@ Text:(An ongoing scheme remains face up until it's abandoned.) R:Event$ DamageDone | ActiveZones$ Command | ValidSource$ Card.OppCtrl,Emblem.OppCtrl | ValidTarget$ You | ReplaceWith$ DBReplace | PreventionEffect$ True | Description$ If a source an opponent controls would deal damage to you, prevent 1 of that damage. SVar:DBReplace:DB$ ReplaceDamage | Amount$ 1 T:Mode$ Phase | Phase$ End of Turn | CheckSVar$ X | SVarCompare$ GE5 | TriggerZones$ Command | Execute$ Abandon | TriggerDescription$ At the beginning of each end step, if you've been dealt 5 or more damage this turn, abandon this scheme. -SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Abandon:DB$ Abandon SVar:X:PlayerCountPropertyYou$DamageThisTurn Oracle:(An ongoing scheme remains face up until it's abandoned.)\nIf a source an opponent controls would deal damage to you, prevent 1 of that damage.\nAt the beginning of each end step, if you've been dealt 5 or more damage this turn, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/oakhollow_village.txt b/forge-gui/res/cardsfolder/o/oakhollow_village.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/oakhollow_village.txt rename to forge-gui/res/cardsfolder/o/oakhollow_village.txt diff --git a/forge-gui/res/cardsfolder/upcoming/octomancer.txt b/forge-gui/res/cardsfolder/o/octomancer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/octomancer.txt rename to forge-gui/res/cardsfolder/o/octomancer.txt diff --git a/forge-gui/res/cardsfolder/o/ogre_battlecaster.txt b/forge-gui/res/cardsfolder/o/ogre_battlecaster.txt index 22ebba8e926..78e83e004f5 100644 --- a/forge-gui/res/cardsfolder/o/ogre_battlecaster.txt +++ b/forge-gui/res/cardsfolder/o/ogre_battlecaster.txt @@ -3,12 +3,12 @@ ManaCost:2 R Types:Creature Ogre Shaman PT:3/3 K:First Strike -T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDT | TriggerDescription$ Whenever CARDNAME attacks, you may cast target instant or sorcery card from your graveyard by paying {R}{R} in addition to its other costs. If that spell would be put into a graveyard, exile it instead. When you cast that spell, CARDNAME gets +X/+0 until end of turn, where X is that spell's mana value. -SVar:TrigDT:DB$ DelayedTrigger | ValidTgts$ Instant.YouOwn,Sorcery.YouOwn | TgtZone$ Graveyard | TgtPrompt$ Select target instant or sorcery card | Mode$ SpellCast | ValidCard$ Card.IsTriggerRemembered | Execute$ TrigPump | RememberObjects$ Targeted | SubAbility$ DBPlay | TriggerDescription$ When you cast that spell, CARDNAME gets +X/+0 until end of turn, where X is that spell's mana value. -SVar:DBPlay:DB$ Play | Defined$ Targeted | ValidSA$ Spell | ReplaceGraveyard$ Exile | PlayRaiseCost$ R R | Optional$ True | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearTriggered$ True +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPlay | TriggerDescription$ Whenever CARDNAME attacks, you may cast target instant or sorcery card from your graveyard by paying {R}{R} in addition to its other costs. If that spell would be put into a graveyard, exile it instead. When you cast that spell, CARDNAME gets +X/+0 until end of turn, where X is that spell's mana value. +SVar:TrigPlay:DB$ Play | ValidTgts$ Instant.YouOwn,Sorcery.YouOwn | TgtZone$ Graveyard | TgtPrompt$ Select target instant or sorcery card | ValidSA$ Spell | ReplaceGraveyard$ Exile | PlayRaiseCost$ R R | Optional$ True | RememberPlayed$ True | SubAbility$ TrigDT +SVar:TrigDT:DB$ ImmediateTrigger | Execute$ TrigPump | RememberObjects$ Remembered | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup | TriggerDescription$ When you cast that spell, CARDNAME gets +X/+0 until end of turn, where X is that spell's mana value. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ +X -SVar:X:TriggeredStackInstance$CardManaCostLKI +SVar:X:TriggerRemembered$CardManaCostLKI AI:RemoveDeck:All SVar:HasAttackEffect:TRUE DeckHints:Type$Instant|Sorcery diff --git a/forge-gui/res/cardsfolder/o/omenpath_to_naya.txt b/forge-gui/res/cardsfolder/o/omenpath_to_naya.txt new file mode 100644 index 00000000000..deca5bef699 --- /dev/null +++ b/forge-gui/res/cardsfolder/o/omenpath_to_naya.txt @@ -0,0 +1,6 @@ +Name:Omenpath to Naya +ManaCost:no cost +Types:Land Omenpath +K:Vanishing:4 +A:AB$ Mana | Cost$ T | Produced$ Combo R G W | SpellDescription$ Add {R}, {G}, or {W}. +Oracle:Vanishing 4 (This land enters the battlefield with four time counters on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it.)\n{T}: Add {R}, {G}, or {W}. diff --git a/forge-gui/res/cardsfolder/o/ophidian.txt b/forge-gui/res/cardsfolder/o/ophidian.txt index 21fb41f7f98..3c1fca7ac77 100644 --- a/forge-gui/res/cardsfolder/o/ophidian.txt +++ b/forge-gui/res/cardsfolder/o/ophidian.txt @@ -3,7 +3,8 @@ ManaCost:2 U Types:Creature Snake PT:1/3 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may draw a card. If you do, CARDNAME assigns no combat damage this turn. -SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. AI:RemoveDeck:All Oracle:Whenever Ophidian attacks and isn't blocked, you may draw a card. If you do, Ophidian assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/o/orcish_squatters.txt b/forge-gui/res/cardsfolder/o/orcish_squatters.txt index 5d86a787349..8a28e784a14 100644 --- a/forge-gui/res/cardsfolder/o/orcish_squatters.txt +++ b/forge-gui/res/cardsfolder/o/orcish_squatters.txt @@ -3,6 +3,7 @@ ManaCost:4 R Types:Creature Orc PT:2/3 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may gain control of target land defending player controls for as long as you control CARDNAME. If you do, CARDNAME assigns no combat damage this turn. -SVar:TrigGainControl:DB$ GainControl | ValidTgts$ Land.DefenderCtrl | TgtPrompt$ Select target land defending player controls | LoseControl$ LoseControl,LeavesPlay | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:TrigGainControl:DB$ GainControl | ValidTgts$ Land.DefenderCtrl | TgtPrompt$ Select target land defending player controls | LoseControl$ LoseControl,LeavesPlay | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. Oracle:Whenever Orcish Squatters attacks and isn't blocked, you may gain control of target land defending player controls for as long as you control Orcish Squatters. If you do, Orcish Squatters assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/origin_of_the_hidden_ones.txt b/forge-gui/res/cardsfolder/o/origin_of_the_hidden_ones.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/origin_of_the_hidden_ones.txt rename to forge-gui/res/cardsfolder/o/origin_of_the_hidden_ones.txt diff --git a/forge-gui/res/cardsfolder/upcoming/osteomancer_adept.txt b/forge-gui/res/cardsfolder/o/osteomancer_adept.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/osteomancer_adept.txt rename to forge-gui/res/cardsfolder/o/osteomancer_adept.txt diff --git a/forge-gui/res/cardsfolder/upcoming/otterball_antics.txt b/forge-gui/res/cardsfolder/o/otterball_antics.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/otterball_antics.txt rename to forge-gui/res/cardsfolder/o/otterball_antics.txt diff --git a/forge-gui/res/cardsfolder/upcoming/overclocked_electromancer.txt b/forge-gui/res/cardsfolder/o/overclocked_electromancer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/overclocked_electromancer.txt rename to forge-gui/res/cardsfolder/o/overclocked_electromancer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/overpowering_attack.txt b/forge-gui/res/cardsfolder/o/overpowering_attack.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/overpowering_attack.txt rename to forge-gui/res/cardsfolder/o/overpowering_attack.txt diff --git a/forge-gui/res/cardsfolder/upcoming/overprotect.txt b/forge-gui/res/cardsfolder/o/overprotect.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/overprotect.txt rename to forge-gui/res/cardsfolder/o/overprotect.txt diff --git a/forge-gui/res/cardsfolder/p/pact_weapon.txt b/forge-gui/res/cardsfolder/p/pact_weapon.txt index c909b35b5d8..951a7a46d0c 100644 --- a/forge-gui/res/cardsfolder/p/pact_weapon.txt +++ b/forge-gui/res/cardsfolder/p/pact_weapon.txt @@ -2,7 +2,7 @@ Name:Pact Weapon ManaCost:3 B Types:Artifact Equipment K:Equip:Discard<1/Card> -S:Mode$ Continuous | Affected$ You | IsPresent$ Card.Self+AttachedTo Creature | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ As long as CARDNAME is attached to a creature, you don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | IsPresent$ Card.Self+AttachedTo Creature | Description$ As long as CARDNAME is attached to a creature, you don't lose the game for having 0 or less life. T:Mode$ Attacks | ValidCard$ Creature.EquippedBy | Execute$ TrigDraw | TriggerDescription$ Whenever equipped creature attacks, draw a card and reveal it. The creature gets +X/+X until end of turn and you lose X life, where X is that card's mana value. SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Reveal$ True | RememberDrawn$ True | SubAbility$ DBPump SVar:DBPump:DB$ Pump | Defined$ TriggeredAttackerLKICopy | NumAtt$ +X | NumDef$ +X | SubAbility$ DBLoseLife diff --git a/forge-gui/res/cardsfolder/upcoming/palazzo_archers.txt b/forge-gui/res/cardsfolder/p/palazzo_archers.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/palazzo_archers.txt rename to forge-gui/res/cardsfolder/p/palazzo_archers.txt diff --git a/forge-gui/res/cardsfolder/upcoming/parting_gust.txt b/forge-gui/res/cardsfolder/p/parting_gust.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/parting_gust.txt rename to forge-gui/res/cardsfolder/p/parting_gust.txt diff --git a/forge-gui/res/cardsfolder/upcoming/patchwork_banner.txt b/forge-gui/res/cardsfolder/p/patchwork_banner.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/patchwork_banner.txt rename to forge-gui/res/cardsfolder/p/patchwork_banner.txt diff --git a/forge-gui/res/cardsfolder/upcoming/pawpatch_formation.txt b/forge-gui/res/cardsfolder/p/pawpatch_formation.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pawpatch_formation.txt rename to forge-gui/res/cardsfolder/p/pawpatch_formation.txt diff --git a/forge-gui/res/cardsfolder/upcoming/pawpatch_recruit.txt b/forge-gui/res/cardsfolder/p/pawpatch_recruit.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pawpatch_recruit.txt rename to forge-gui/res/cardsfolder/p/pawpatch_recruit.txt diff --git a/forge-gui/res/cardsfolder/upcoming/pearl_of_wisdom.txt b/forge-gui/res/cardsfolder/p/pearl_of_wisdom.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pearl_of_wisdom.txt rename to forge-gui/res/cardsfolder/p/pearl_of_wisdom.txt diff --git a/forge-gui/res/cardsfolder/upcoming/peerless_recycling.txt b/forge-gui/res/cardsfolder/p/peerless_recycling.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/peerless_recycling.txt rename to forge-gui/res/cardsfolder/p/peerless_recycling.txt diff --git a/forge-gui/res/cardsfolder/upcoming/perch_protection.txt b/forge-gui/res/cardsfolder/p/perch_protection.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/perch_protection.txt rename to forge-gui/res/cardsfolder/p/perch_protection.txt diff --git a/forge-gui/res/cardsfolder/upcoming/persistent_marshstalker.txt b/forge-gui/res/cardsfolder/p/persistent_marshstalker.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/persistent_marshstalker.txt rename to forge-gui/res/cardsfolder/p/persistent_marshstalker.txt diff --git a/forge-gui/res/cardsfolder/upcoming/petty_larceny.txt b/forge-gui/res/cardsfolder/p/petty_larceny.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/petty_larceny.txt rename to forge-gui/res/cardsfolder/p/petty_larceny.txt diff --git a/forge-gui/res/cardsfolder/upcoming/phantom_blade.txt b/forge-gui/res/cardsfolder/p/phantom_blade.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/phantom_blade.txt rename to forge-gui/res/cardsfolder/p/phantom_blade.txt diff --git a/forge-gui/res/cardsfolder/p/phyrexian_unlife.txt b/forge-gui/res/cardsfolder/p/phyrexian_unlife.txt index 1186ad2853d..92f0b1fe856 100644 --- a/forge-gui/res/cardsfolder/p/phyrexian_unlife.txt +++ b/forge-gui/res/cardsfolder/p/phyrexian_unlife.txt @@ -1,7 +1,7 @@ Name:Phyrexian Unlife ManaCost:2 W Types:Enchantment -S:Mode$ Continuous | Affected$ You | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ You don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | Description$ You don't lose the game for having 0 or less life. S:Mode$ Continuous | CheckSVar$ UnlifeCondition | SVarCompare$ LE0 | Affected$ You | AddKeyword$ All damage is dealt to you as though its source had infect. | Description$ As long as you have 0 or less life, all damage is dealt to you as though its source had infect. SVar:UnlifeCondition:Count$YourLifeTotal SVar:NonStackingEffect:True diff --git a/forge-gui/res/cardsfolder/upcoming/pileated_provisioner.txt b/forge-gui/res/cardsfolder/p/pileated_provisioner.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pileated_provisioner.txt rename to forge-gui/res/cardsfolder/p/pileated_provisioner.txt diff --git a/forge-gui/res/cardsfolder/p/platinum_angel.txt b/forge-gui/res/cardsfolder/p/platinum_angel.txt index b8edbd08cb8..16710e65187 100644 --- a/forge-gui/res/cardsfolder/p/platinum_angel.txt +++ b/forge-gui/res/cardsfolder/p/platinum_angel.txt @@ -3,6 +3,6 @@ ManaCost:7 Types:Artifact Creature Angel PT:4/4 K:Flying -S:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Battlefield | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. Oracle:Flying\nYou can't lose the game and your opponents can't win the game. diff --git a/forge-gui/res/cardsfolder/p/platinum_angel_avatar.txt b/forge-gui/res/cardsfolder/p/platinum_angel_avatar.txt index b5b5644d92c..aee376caad9 100644 --- a/forge-gui/res/cardsfolder/p/platinum_angel_avatar.txt +++ b/forge-gui/res/cardsfolder/p/platinum_angel_avatar.txt @@ -2,8 +2,8 @@ Name:Platinum Angel Avatar ManaCost:no cost Types:Vanguard HandLifeModifier:-1/-2 -S:Mode$ Continuous | EffectZone$ Command | Affected$ You | CheckSVar$ AvatarAX | CheckSecondSVar$ AvatarCX | CheckThirdSVar$ AvatarEX | CheckFourthSVar$ AvatarLX | AddKeyword$ You can't lose the game. | Description$ If you control an artifact, a creature, an enchantment, and a land, you can't lose the game and your opponents can't win the game. -S:Mode$ Continuous | EffectZone$ Command | Affected$ Player.Opponent | CheckSVar$ AvatarAX | CheckSecondSVar$ AvatarCX | CheckThirdSVar$ AvatarEX | CheckFourthSVar$ AvatarLX | AddKeyword$ You can't win the game. +R:Event$ GameLoss | ActiveZones$ Command | ValidPlayer$ You | Layer$ CantHappen | CheckSVar$ AvatarAX | CheckSecondSVar$ AvatarCX | CheckThirdSVar$ AvatarEX | CheckFourthSVar$ AvatarLX | Description$ If you control an artifact, a creature, an enchantment, and a land, you can't lose the game and your opponents can't win the game. +R:Event$ GameWin | ActiveZones$ Command | ValidPlayer$ Opponent | Layer$ CantHappen | CheckSVar$ AvatarAX | CheckSecondSVar$ AvatarCX | CheckThirdSVar$ AvatarEX | CheckFourthSVar$ AvatarLX | Secondary$ True | Description$ If you control an artifact, a creature, an enchantment, and a land, you can't lose the game and your opponents can't win the game. SVar:AvatarAX:Count$Valid Artifact.YouCtrl SVar:AvatarCX:Count$Valid Creature.YouCtrl SVar:AvatarEX:Count$Valid Enchantment.YouCtrl diff --git a/forge-gui/res/cardsfolder/upcoming/playful_shove.txt b/forge-gui/res/cardsfolder/p/playful_shove.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/playful_shove.txt rename to forge-gui/res/cardsfolder/p/playful_shove.txt diff --git a/forge-gui/res/cardsfolder/upcoming/plumecreed_escort.txt b/forge-gui/res/cardsfolder/p/plumecreed_escort.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/plumecreed_escort.txt rename to forge-gui/res/cardsfolder/p/plumecreed_escort.txt diff --git a/forge-gui/res/cardsfolder/upcoming/plumecreed_mentor.txt b/forge-gui/res/cardsfolder/p/plumecreed_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/plumecreed_mentor.txt rename to forge-gui/res/cardsfolder/p/plumecreed_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/poison_blade_mentor.txt b/forge-gui/res/cardsfolder/p/poison_blade_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/poison_blade_mentor.txt rename to forge-gui/res/cardsfolder/p/poison_blade_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/polliwallop.txt b/forge-gui/res/cardsfolder/p/polliwallop.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/polliwallop.txt rename to forge-gui/res/cardsfolder/p/polliwallop.txt diff --git a/forge-gui/res/cardsfolder/upcoming/pollywog_prodigy.txt b/forge-gui/res/cardsfolder/p/pollywog_prodigy.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pollywog_prodigy.txt rename to forge-gui/res/cardsfolder/p/pollywog_prodigy.txt diff --git a/forge-gui/res/cardsfolder/upcoming/pond_prophet.txt b/forge-gui/res/cardsfolder/p/pond_prophet.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pond_prophet.txt rename to forge-gui/res/cardsfolder/p/pond_prophet.txt diff --git a/forge-gui/res/cardsfolder/p/pool_resources.txt b/forge-gui/res/cardsfolder/p/pool_resources.txt new file mode 100644 index 00000000000..0a2903f6899 --- /dev/null +++ b/forge-gui/res/cardsfolder/p/pool_resources.txt @@ -0,0 +1,8 @@ +Name:Pool Resources +ManaCost:2 U +Types:Instant +K:Gift +SVar:GiftAbility:DB$ Token | TokenAmount$ 1 | TokenScript$ u_1_1_fish | TokenTapped$ True | TokenOwner$ Promised | LockTokenScript$ True | GiftDescription$ a tapped Fish +A:SP$ Draw | ConditionPresent$ Card.Self+PromisedGift | ConditionCompare$ EQ0 | SubAbility$ DBSeek | NumCards$ 2 | SpellDescription$ +SVar:DBSeek:DB$ Seek | Defined$ You | Num$ 2 | ConditionPresent$ Card.Self+PromisedGift | ConditionCompare$ EQ1 |Type$ Card.nonLand +Oracle:Gift a tapped Fish\nDraw two cards. If the gift was promised, seek two nonland cards instead. diff --git a/forge-gui/res/cardsfolder/upcoming/portent_of_calamity.txt b/forge-gui/res/cardsfolder/p/portent_of_calamity.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/portent_of_calamity.txt rename to forge-gui/res/cardsfolder/p/portent_of_calamity.txt diff --git a/forge-gui/res/cardsfolder/p/primetime_suspect.txt b/forge-gui/res/cardsfolder/p/primetime_suspect.txt new file mode 100644 index 00000000000..a494e2cd47c --- /dev/null +++ b/forge-gui/res/cardsfolder/p/primetime_suspect.txt @@ -0,0 +1,11 @@ +Name:Primetime Suspect +ManaCost:1 G +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | ValidTgts$ Creature | AILogic$ Pump +T:Mode$ Attacks | ValidCard$ Card.AttachedBy | Execute$ TrigChange | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever enchanted creature attacks, you may search your library for a land card, put that card onto the battlefield tapped, then shuffle. If enchanted creature is suspected, you search for two lands instead. +SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land | ChangeNum$ X | ShuffleNonMandatory$ True +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddSVar$ AE +SVar:X:Count$Valid Creature.EnchantedBy+IsSuspected/Plus.1 +SVar:AE:SVar:HasAttackEffect:TRUE +Oracle:Enchant creature\nWhenever enchanted creature attacks, you may search your library for a land card, put that card onto the battlefield tapped, then shuffle. If enchanted creature is suspected, you search for two lands instead. diff --git a/forge-gui/res/cardsfolder/p/prophetic_titan.txt b/forge-gui/res/cardsfolder/p/prophetic_titan.txt index da5f552ab10..d8caa2c4ded 100644 --- a/forge-gui/res/cardsfolder/p/prophetic_titan.txt +++ b/forge-gui/res/cardsfolder/p/prophetic_titan.txt @@ -3,9 +3,9 @@ ManaCost:4 U R Types:Creature Giant Wizard PT:4/4 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ Delirium — When CARDNAME enters, ABILITY -SVar:TrigCharm:DB$ Charm | CharmNum$ Count$Compare Y GE4.2.1 | Choices$ DBDealDamage,DBDig | AdditionalDescription$ . If there are four or more card types among cards in your graveyard, choose both. +SVar:TrigCharm:DB$ Charm | CharmNum$ Y | Choices$ DBDealDamage,DBDig | AdditionalDescription$ . If there are four or more card types among cards in your graveyard, choose both. SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 4 | SpellDescription$ CARDNAME deals 4 damage to any target. SVar:DBDig:DB$ Dig | DigNum$ 4 | RestRandomOrder$ True | NoReveal$ True | SpellDescription$ Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order. -SVar:Y:Count$ValidGraveyard Card.YouOwn$CardTypes +SVar:Y:Count$Delirium.2.1 SVar:PlayMain1:TRUE Oracle:Delirium — When Prophetic Titan enters, choose one. If there are four or more card types among cards in your graveyard, choose both instead.\n• Prophetic Titan deals 4 damage to any target.\n• Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in a random order. diff --git a/forge-gui/res/cardsfolder/upcoming/prosperous_bandit.txt b/forge-gui/res/cardsfolder/p/prosperous_bandit.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/prosperous_bandit.txt rename to forge-gui/res/cardsfolder/p/prosperous_bandit.txt diff --git a/forge-gui/res/cardsfolder/upcoming/psychic_whorl.txt b/forge-gui/res/cardsfolder/p/psychic_whorl.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/psychic_whorl.txt rename to forge-gui/res/cardsfolder/p/psychic_whorl.txt diff --git a/forge-gui/res/cardsfolder/p/put_away.txt b/forge-gui/res/cardsfolder/p/put_away.txt index 0030133c386..ac960c023bc 100644 --- a/forge-gui/res/cardsfolder/p/put_away.txt +++ b/forge-gui/res/cardsfolder/p/put_away.txt @@ -2,5 +2,5 @@ Name:Put Away ManaCost:2 U U Types:Instant A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | SubAbility$ DBChangeZone | SpellDescription$ Counter target spell. You may shuffle up to one target card from your graveyard into your library. -SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouCtrl | TgtPrompt$ Select target card from your graveyard | TargetMin$ 0 | TargetMax$ 1 | Shuffle$ True +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouCtrl | TgtPrompt$ Select target card from your graveyard | TargetMin$ 0 | TargetMax$ 1 | Shuffle$ True | ShuffleNonMandatory$ True Oracle:Counter target spell. You may shuffle up to one target card from your graveyard into your library. diff --git a/forge-gui/res/cardsfolder/p/putrefying_rotboar.txt b/forge-gui/res/cardsfolder/p/putrefying_rotboar.txt new file mode 100644 index 00000000000..bbb39b39105 --- /dev/null +++ b/forge-gui/res/cardsfolder/p/putrefying_rotboar.txt @@ -0,0 +1,10 @@ +Name:Putrefying Rotboar +ManaCost:2 B B +Types:Creature Elemental Boar +PT:4/5 +K:Lifelink +T:Mode$ Attacks | ValidCard$ Boar.YouCtrl | Execute$ TrigAnimateAll | TriggerZones$ Battlefield | TriggerDescription$ Whenever a Boar you control attacks, each nonland card in defending player's hand perpetually gains "When you cast this spell, you lose 1 life." +SVar:TrigAnimateAll:DB$ AnimateAll | Duration$ Perpetual | ValidCards$ Card.nonLand+OwnedBy TriggeredDefendingPlayer | Zone$ Hand | Triggers$ CastSpellLoseLife +SVar:CastSpellLoseLife:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigDrain | TriggerDescription$ When you cast this spell, you lose 1 life. +SVar:TrigDrain:DB$ LoseLife | LifeAmount$ 1 +Oracle:Lifelink\nWhenever a Boar you control attacks, each nonland card in defending player's hand perpetually gains "When you cast this spell, you lose 1 life." diff --git a/forge-gui/res/cardsfolder/p/pygmy_hippo.txt b/forge-gui/res/cardsfolder/p/pygmy_hippo.txt index 5b06c8fae5a..b059c6bc002 100644 --- a/forge-gui/res/cardsfolder/p/pygmy_hippo.txt +++ b/forge-gui/res/cardsfolder/p/pygmy_hippo.txt @@ -4,8 +4,9 @@ Types:Creature Hippo PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ TrigActivateManaAbility | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may have defending player activate a mana ability of each land they control and lose all unspent mana. If you do, CARDNAME assigns no combat damage this turn and at the beginning of your postcombat main phase, you add an amount of {C} equal to the amount of mana that player lost this way. SVar:TrigActivateManaAbility:DB$ ActivateAbility | Defined$ DefendingPlayer | Type$ Land | ManaAbility$ True | SubAbility$ DBEmptyPool -SVar:DBEmptyPool:DB$ DrainMana | Defined$ DefendingPlayer | SubAbility$ DBPump | RememberDrainedMana$ True -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | SubAbility$ DBDelTrig +SVar:DBEmptyPool:DB$ DrainMana | Defined$ DefendingPlayer | SubAbility$ DBNoCombatDamage | RememberDrainedMana$ True +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT | SubAbility$ DBDelTrig +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:DBDelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ Main2 | Execute$ TrigAddMana | TriggerDescription$ At the beginning of your postcombat main phase, you add an amount of {C} equal to the amount of mana the defending player lost this way | SubAbility$ DBCleanup | RememberNumber$ True SVar:TrigAddMana:DB$ Mana | Produced$ C | Amount$ X SVar:X:Count$TriggerRememberAmount diff --git a/forge-gui/res/cardsfolder/upcoming/pyreswipe_hawk.txt b/forge-gui/res/cardsfolder/p/pyreswipe_hawk.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/pyreswipe_hawk.txt rename to forge-gui/res/cardsfolder/p/pyreswipe_hawk.txt diff --git a/forge-gui/res/cardsfolder/upcoming/quaketusk_boar.txt b/forge-gui/res/cardsfolder/q/quaketusk_boar.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/quaketusk_boar.txt rename to forge-gui/res/cardsfolder/q/quaketusk_boar.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rabbit_response.txt b/forge-gui/res/cardsfolder/r/rabbit_response.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rabbit_response.txt rename to forge-gui/res/cardsfolder/r/rabbit_response.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rabid_gnaw.txt b/forge-gui/res/cardsfolder/r/rabid_gnaw.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rabid_gnaw.txt rename to forge-gui/res/cardsfolder/r/rabid_gnaw.txt diff --git a/forge-gui/res/cardsfolder/upcoming/raccoon_rallier.txt b/forge-gui/res/cardsfolder/r/raccoon_rallier.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/raccoon_rallier.txt rename to forge-gui/res/cardsfolder/r/raccoon_rallier.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ral_crackling_wit.txt b/forge-gui/res/cardsfolder/r/ral_crackling_wit.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ral_crackling_wit.txt rename to forge-gui/res/cardsfolder/r/ral_crackling_wit.txt diff --git a/forge-gui/res/cardsfolder/r/rancid_earth.txt b/forge-gui/res/cardsfolder/r/rancid_earth.txt index 715296d8dff..f2b9c7c3468 100644 --- a/forge-gui/res/cardsfolder/r/rancid_earth.txt +++ b/forge-gui/res/cardsfolder/r/rancid_earth.txt @@ -1,7 +1,9 @@ Name:Rancid Earth ManaCost:1 B B Types:Sorcery -A:SP$ Destroy | ValidTgts$ Land | TgtPrompt$ Select target land | SubAbility$ DBRancidDamage | SpellDescription$ Destroy target land. Threshold — If seven or more cards are in your graveyard, instead destroy that land and CARDNAME deals 1 damage to each creature and each player. -SVar:DBRancidDamage:DB$ DamageAll | NumDmg$ RancidX | ValidCards$ Creature | ValidPlayers$ Player -SVar:RancidX:Count$Threshold.1.0 +A:SP$ Branch | ValidTgts$ Land | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE7 | TrueSubAbility$ ThreshDestroy | FalseSubAbility$ Destroy | SpellDescription$ Destroy target land. Threshold — If seven or more cards are in your graveyard, instead destroy that land and CARDNAME deals 1 damage to each creature and each player. +SVar:Destroy:DB$ Destroy | Defined$ Targeted +SVar:ThreshDestroy:DB$ Destroy | Defined$ Targeted | SubAbility$ DBRancidDamage +SVar:DBRancidDamage:DB$ DamageAll | NumDmg$ 1 | ValidCards$ Creature | ValidPlayers$ Player +SVar:X:Count$ValidGraveyard Card.YouOwn Oracle:Destroy target land.\nThreshold — If seven or more cards are in your graveyard, instead destroy that land and Rancid Earth deals 1 damage to each creature and each player. diff --git a/forge-gui/res/cardsfolder/upcoming/rapid_augmenter.txt b/forge-gui/res/cardsfolder/r/rapid_augmenter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rapid_augmenter.txt rename to forge-gui/res/cardsfolder/r/rapid_augmenter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ratonhnhake_ton.txt b/forge-gui/res/cardsfolder/r/ratonhnhake_ton.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ratonhnhake_ton.txt rename to forge-gui/res/cardsfolder/r/ratonhnhake_ton.txt diff --git a/forge-gui/res/cardsfolder/upcoming/raven_clan_war_axe.txt b/forge-gui/res/cardsfolder/r/raven_clan_war_axe.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/raven_clan_war_axe.txt rename to forge-gui/res/cardsfolder/r/raven_clan_war_axe.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ravine_raider.txt b/forge-gui/res/cardsfolder/r/ravine_raider.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ravine_raider.txt rename to forge-gui/res/cardsfolder/r/ravine_raider.txt diff --git a/forge-gui/res/cardsfolder/r/recruit_instructor.txt b/forge-gui/res/cardsfolder/r/recruit_instructor.txt new file mode 100644 index 00000000000..8dcbfd34da3 --- /dev/null +++ b/forge-gui/res/cardsfolder/r/recruit_instructor.txt @@ -0,0 +1,9 @@ +Name:Recruit Instructor +ManaCost:R W +Types:Creature Mouse Warrior +PT:1/1 +T:Mode$ AttackersDeclared | ValidAttackers$ Mouse.YouCtrl | Execute$ TrigDraft | TriggerZones$ Battlefield | TriggerDescription$ Whenever one or more Mice you control attack, draft a card from CARDNAME's spellbook. +SVar:TrigDraft:DB$ Draft | Spellbook$ Angelfire Ignition,Barge In,Become Brutes,Boon of Safety,Cheeky House-Mouse,Crumb and Get It,Defiant Strike,Embercleave,Feather of Flight,Mabel's Mettle,Might of the Meek,Moment of Heroism,Unleash Fury,War Squeak +T:Mode$ BecomesTarget | ValidTarget$ Card.Self | ValidSource$ SpellAbility.YouCtrl | TriggerZones$ Battlefield | FirstTime$ True | Execute$ TrigToken | TriggerDescription$ Valiant — Whenever CARDNAME becomes the target of a spell or ability you control for the first time each turn, create a 1/1 white Mouse creature token. +SVar:TrigToken:DB$ Token | TokenScript$ w_1_1_mouse | TokenAmount$ 1 | TokenOwner$ You +Oracle:Whenever one or more Mice you control attack, draft a card from Recruit Instructor's spellbook.\nValiant — Whenever Recruit Instructor becomes the target of a spell or ability you control for the first time each turn, create a 1/1 white Mouse creature token. diff --git a/forge-gui/res/cardsfolder/upcoming/repel_calamity.txt b/forge-gui/res/cardsfolder/r/repel_calamity.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/repel_calamity.txt rename to forge-gui/res/cardsfolder/r/repel_calamity.txt diff --git a/forge-gui/res/cardsfolder/upcoming/reptilian_recruiter.txt b/forge-gui/res/cardsfolder/r/reptilian_recruiter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/reptilian_recruiter.txt rename to forge-gui/res/cardsfolder/r/reptilian_recruiter.txt diff --git a/forge-gui/res/cardsfolder/r/reservoir_kraken.txt b/forge-gui/res/cardsfolder/r/reservoir_kraken.txt index bfa0053766a..ca70d4871d8 100644 --- a/forge-gui/res/cardsfolder/r/reservoir_kraken.txt +++ b/forge-gui/res/cardsfolder/r/reservoir_kraken.txt @@ -4,7 +4,7 @@ Types:Creature Kraken PT:6/6 K:Trample K:Ward:2 -T:Mode$ Phase | Phase$ BeginCombat | TriggerZones$ Battlefield | Execute$ TrigTap | IsPresent$ Card.Self+untapped | TriggerDescription$ At the beginning of each combat, if CARDNAME is untapped, any opponent may tap an untapped creature they control. If they do, tap CARDNAME and create a 1/1 blue Fish creature token with "This creature can't be blocked." +T:Mode$ Phase | Phase$ BeginCombat | TriggerZones$ Battlefield | Execute$ TrigTap | PresentDefined$ Self | IsPresent$ Card.untapped | TriggerDescription$ At the beginning of each combat, if CARDNAME is untapped, any opponent may tap an untapped creature they control. If they do, tap CARDNAME and create a 1/1 blue Fish creature token with "This creature can't be blocked." SVar:TrigTap:DB$ Tap | Defined$ Self | UnlessCost$ tapXType<1/Creature> | UnlessPayer$ Player.Opponent | UnlessSwitched$ True | UnlessAI$ LifeLE8 | UnlessResolveSubs$ WhenPaid | SubAbility$ DBToken SVar:DBToken:DB$ Token | TokenScript$ u_1_1_fish_unblockable DeckHas:Ability$Token & Type$Fish diff --git a/forge-gui/res/cardsfolder/r/resourceful_collector.txt b/forge-gui/res/cardsfolder/r/resourceful_collector.txt new file mode 100644 index 00000000000..658f5e081a2 --- /dev/null +++ b/forge-gui/res/cardsfolder/r/resourceful_collector.txt @@ -0,0 +1,13 @@ +Name:Resourceful Collector +ManaCost:1 R G +Types:Creature Raccoon Druid +PT:3/3 +K:Haste +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigRandom | TriggerDescription$ At the beginning of your end step, a random non-Food permanent card in your graveyard perpetually becomes a Food artifact in addition to its other types and gains "{2}, Exile this artifact: You gain 3 life." You may play that card for as long as it's in your graveyard. +SVar:TrigRandom:DB$ ChooseCard | Choices$ Permanent.nonFood+YouOwn | ChoiceZone$ Graveyard | AtRandom$ True | Amount$ 1 | SubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Types$ Food,Artifact | Defined$ ChosenCard | Duration$ Perpetual | Abilities$ FoodSac | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | ForgetOnMoved$ Graveyard | RememberObjects$ ChosenCard | Duration$ Permanent | SubAbility$ DBCleanup +SVar:MayPlay:Mode$ Continuous | MayPlay$ True | Affected$ Card.IsRemembered | AffectedZone$ Graveyard | Description$ You may cast that card for as long as it's in your graveyard. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:FoodSac:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME/this creature> | LifeAmount$ 3 | SpellDescription$ You gain 3 life. +Oracle:Haste\nAt the beginning of your end step, a random non-Food permanent card in your graveyard perpetually becomes a Food artifact in addition to its other types and gains "{2}, Exile this artifact: You gain 3 life." You may play that card for as long as it's in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/restart_sequence.txt b/forge-gui/res/cardsfolder/r/restart_sequence.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/restart_sequence.txt rename to forge-gui/res/cardsfolder/r/restart_sequence.txt diff --git a/forge-gui/res/cardsfolder/r/retribution.txt b/forge-gui/res/cardsfolder/r/retribution.txt index 5c88b0db751..0fd9510a962 100644 --- a/forge-gui/res/cardsfolder/r/retribution.txt +++ b/forge-gui/res/cardsfolder/r/retribution.txt @@ -1,7 +1,7 @@ Name:Retribution ManaCost:2 R R Types:Sorcery -A:SP$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select two target creature an opponent controls | TargetMin$ 2 | TargetMax$ 2 | TargetsFromSingleZone$ True | IsCurse$ True | RememberTargets$ True | SubAbility$ DBChoose | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures an opponent controls. That player chooses and sacrifices one of those creatures. Put a -1/-1 counter on the other. +A:SP$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select two target creatures an opponent controls | TargetMin$ 2 | TargetMax$ 2 | TargetsFromSingleZone$ True | IsCurse$ True | RememberTargets$ True | SubAbility$ DBChoose | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures an opponent controls. That player chooses and sacrifices one of those creatures. Put a -1/-1 counter on the other. SVar:DBChoose:DB$ ChooseCard | Defined$ TargetedController | Mandatory$ True | Choices$ Creature.IsRemembered | ChoiceTitle$ Choose one to sacrifice | ForgetChosen$ True | AILogic$ WorstCard | SubAbility$ DBSac | StackDescription$ None SVar:DBSac:DB$ SacrificeAll | Defined$ ChosenCard | SubAbility$ DBPutCounter | StackDescription$ None SVar:DBPutCounter:DB$ PutCounter | Defined$ Remembered | CounterType$ M1M1 | CounterNum$ 1 | StackDescription$ None | SubAbility$ DBCleanup diff --git a/forge-gui/res/cardsfolder/r/reveille_squad.txt b/forge-gui/res/cardsfolder/r/reveille_squad.txt index d7905706290..594b8cc29f1 100644 --- a/forge-gui/res/cardsfolder/r/reveille_squad.txt +++ b/forge-gui/res/cardsfolder/r/reveille_squad.txt @@ -2,6 +2,6 @@ Name:Reveille Squad ManaCost:2 W W Types:Creature Human Rebel PT:3/3 -T:Mode$ AttackersDeclared | AttackedTarget$ You | TriggerZones$ Battlefield | Execute$ TrigUntapAll | IsPresent$ Card.untapped+Self | OptionalDecider$ You | TriggerDescription$ Whenever one or more creatures attack you, if CARDNAME is untapped, you may untap all creatures you control. +T:Mode$ AttackersDeclared | AttackedTarget$ You | TriggerZones$ Battlefield | Execute$ TrigUntapAll | PresentDefined$ Self | IsPresent$ Card.untapped | OptionalDecider$ You | TriggerDescription$ Whenever one or more creatures attack you, if CARDNAME is untapped, you may untap all creatures you control. SVar:TrigUntapAll:DB$ UntapAll | ValidCards$ Creature.YouCtrl Oracle:Whenever one or more creatures attack you, if Reveille Squad is untapped, you may untap all creatures you control. diff --git a/forge-gui/res/cardsfolder/upcoming/rockface_village.txt b/forge-gui/res/cardsfolder/r/rockface_village.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rockface_village.txt rename to forge-gui/res/cardsfolder/r/rockface_village.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rolling_hamsphere.txt b/forge-gui/res/cardsfolder/r/rolling_hamsphere.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rolling_hamsphere.txt rename to forge-gui/res/cardsfolder/r/rolling_hamsphere.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rooftop_bypass.txt b/forge-gui/res/cardsfolder/r/rooftop_bypass.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rooftop_bypass.txt rename to forge-gui/res/cardsfolder/r/rooftop_bypass.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rootcast_apprenticeship.txt b/forge-gui/res/cardsfolder/r/rootcast_apprenticeship.txt similarity index 73% rename from forge-gui/res/cardsfolder/upcoming/rootcast_apprenticeship.txt rename to forge-gui/res/cardsfolder/r/rootcast_apprenticeship.txt index a7dfd3a0ab9..3f86c589681 100644 --- a/forge-gui/res/cardsfolder/upcoming/rootcast_apprenticeship.txt +++ b/forge-gui/res/cardsfolder/r/rootcast_apprenticeship.txt @@ -2,9 +2,9 @@ Name:Rootcast Apprenticeship ManaCost:3 G Types:Sorcery A:SP$ Charm | Choices$ DBPutCounter,DBCopy,DBToken,DBSacrifice | CharmNum$ 3 | CanRepeatModes$ True -SVar:DBPutCounter:DB$ PutCounter | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 3 | SpellDescription$ Put three +1/+1 counters on target creature. +SVar:DBPutCounter:DB$ PutCounter | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Put two +1/+1 counters on target creature. SVar:DBCopy:DB$ CopyPermanent | ValidTgts$ Permanent.token+YouCtrl | TgtPrompt$ Select target token you control | SpellDescription$ Create a token that's a copy of target token you control. SVar:DBToken:DB$ Token | ValidTgts$ Player | TokenAmount$ 1 | TokenScript$ g_1_1_squirrel | StackDescription$ SpellDescription | SpellDescription$ Target player creates a 1/1 green Squirrel creature token. SVar:DBSacrifice:DB$ Sacrifice | ValidTgts$ Opponent | SacValid$ Artifact.nonToken | SpellDescription$ Target opponent sacrifices a nontoken artifact. | SacMessage$ nontoken artifact DeckHas:Ability$Counters|Token -Oracle:Choose three. You may choose the same mode more than once.\n• Put three +1/+1 counters on target creature.\n• Create a token that's a copy of target token you control.\n• Target player creates a 1/1 green Squirrel creature token.\n• Target opponent sacrifices a nontoken artifact. +Oracle:Choose three. You may choose the same mode more than once.\n• Put two +1/+1 counters on target creature.\n• Create a token that's a copy of target token you control.\n• Target player creates a 1/1 green Squirrel creature token.\n• Target opponent sacrifices a nontoken artifact. diff --git a/forge-gui/res/cardsfolder/upcoming/roshan_hidden_magister.txt b/forge-gui/res/cardsfolder/r/roshan_hidden_magister.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/roshan_hidden_magister.txt rename to forge-gui/res/cardsfolder/r/roshan_hidden_magister.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rottenmouth_viper.txt b/forge-gui/res/cardsfolder/r/rottenmouth_viper.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rottenmouth_viper.txt rename to forge-gui/res/cardsfolder/r/rottenmouth_viper.txt diff --git a/forge-gui/res/cardsfolder/upcoming/roughshod_duo.txt b/forge-gui/res/cardsfolder/r/roughshod_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/roughshod_duo.txt rename to forge-gui/res/cardsfolder/r/roughshod_duo.txt diff --git a/forge-gui/res/cardsfolder/r/ruhan_of_the_fomori.txt b/forge-gui/res/cardsfolder/r/ruhan_of_the_fomori.txt index ebad4911bdb..fcf4447c8dd 100644 --- a/forge-gui/res/cardsfolder/r/ruhan_of_the_fomori.txt +++ b/forge-gui/res/cardsfolder/r/ruhan_of_the_fomori.txt @@ -3,7 +3,7 @@ ManaCost:1 U R W Types:Legendary Creature Giant Warrior PT:7/7 T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of combat on your turn, choose an opponent at random. CARDNAME attacks that player this combat if able. -SVar:TrigChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | Random$ True | SubAbility$ DBPump -SVar:DBPump:DB$ Animate | Defined$ Self | staticAbilities$ AttackChosen | Duration$ UntilEndOfCombat -SVar:AttackChosen:Mode$ MustAttack | ValidCreature$ Card.Self | MustAttack$ ChosenPlayer | Secondary$ True +SVar:TrigChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | Random$ True | SubAbility$ DBPEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ Self | ExileOnMoved$ Battlefield | StaticAbilities$ AttackChosen | Duration$ UntilEndOfCombat +SVar:AttackChosen:Mode$ MustAttack | ValidCreature$ Card.IsRemembered | MustAttack$ ChosenPlayer | Description$ EFFECTSOURCE attacks that player this combat if able. Oracle:At the beginning of combat on your turn, choose an opponent at random. Ruhan of the Fomori attacks that player this combat if able. diff --git a/forge-gui/res/cardsfolder/upcoming/rust_shield_rampager.txt b/forge-gui/res/cardsfolder/r/rust_shield_rampager.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/rust_shield_rampager.txt rename to forge-gui/res/cardsfolder/r/rust_shield_rampager.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ruthless_negotiation.txt b/forge-gui/res/cardsfolder/r/ruthless_negotiation.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ruthless_negotiation.txt rename to forge-gui/res/cardsfolder/r/ruthless_negotiation.txt diff --git a/forge-gui/res/cardsfolder/r/rysorian_badger.txt b/forge-gui/res/cardsfolder/r/rysorian_badger.txt index a688a925971..bba21d3c2e6 100644 --- a/forge-gui/res/cardsfolder/r/rysorian_badger.txt +++ b/forge-gui/res/cardsfolder/r/rysorian_badger.txt @@ -4,8 +4,9 @@ Types:Creature Badger PT:2/2 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigExile | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may exile up to two target creature cards from defending player's graveyard. If you do, you gain 1 life for each card exiled this way and CARDNAME assigns no combat damage this turn. SVar:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | TargetMin$ 0 | TargetMax$ 2 | ValidTgts$ Creature.DefenderCtrl | RememberChanged$ True | SubAbility$ DBGainLife -SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage | SubAbility$ DBCleanup +SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT | SubAbility$ DBCleanup +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:X:Remembered$Amount SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True Oracle:Whenever Rysorian Badger attacks and isn't blocked, you may exile up to two target creature cards from defending player's graveyard. If you do, you gain 1 life for each card exiled this way and Rysorian Badger assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/salvation_swan.txt b/forge-gui/res/cardsfolder/s/salvation_swan.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/salvation_swan.txt rename to forge-gui/res/cardsfolder/s/salvation_swan.txt diff --git a/forge-gui/res/cardsfolder/s/sand_silos.txt b/forge-gui/res/cardsfolder/s/sand_silos.txt index f8db58032f4..4dd9223002b 100644 --- a/forge-gui/res/cardsfolder/s/sand_silos.txt +++ b/forge-gui/res/cardsfolder/s/sand_silos.txt @@ -4,7 +4,7 @@ Types:Land R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True K:You may choose not to untap CARDNAME during your untap step. -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Card.Self+tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | Execute$ TrigStore | TriggerDescription$ At the beginning of your upkeep, if CARDNAME is tapped, put a storage counter on it. SVar:TrigStore:DB$ PutCounter | Defined$ Self | CounterType$ STORAGE | CounterNum$ 1 A:AB$ Mana | Cost$ T SubCounter | Produced$ U | Amount$ X | AILogic$ ManaRitualBattery | SpellDescription$ Add {U} for each storage counter removed this way. SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/s/sandcloud_harbinger.txt b/forge-gui/res/cardsfolder/s/sandcloud_harbinger.txt new file mode 100644 index 00000000000..796b8108007 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sandcloud_harbinger.txt @@ -0,0 +1,10 @@ +Name:Sandcloud Harbinger +ManaCost:2 W +Types:Creature Elemental Horse +PT:2/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigConjure | TriggerDescription$ When CARDNAME enters, conjure three cards named Sunscorched Desert into the top ten cards of each player's library at random. +SVar:TrigConjure:DB$ MakeCard | Amount$ 3 | Conjure$ True | Name$ Sunscorched Desert | Defined$ Player | Zone$ Library | LibraryPosition$ Count$Random.0.10 +T:Mode$ LandPlayed | ValidCard$ Desert | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a player plays a Desert, that player draws a card and you gain 3 life. +SVar:TrigDraw:DB$ Draw | Defined$ TriggeredCardController | NumCards$ 1 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | LifeAmount$ 3 +Oracle:When Sandcloud Harbinger enters, conjure three cards named Sunscorched Desert into the top ten cards of each player's library at random.\nWhenever a player plays a Desert, that player draws a card and you gain 3 life. diff --git a/forge-gui/res/cardsfolder/s/sanguine_soothsayer.txt b/forge-gui/res/cardsfolder/s/sanguine_soothsayer.txt new file mode 100644 index 00000000000..024e0031a94 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sanguine_soothsayer.txt @@ -0,0 +1,14 @@ +Name:Sanguine Soothsayer +ManaCost:2 B +Types:Creature Bat Cleric +PT:2/1 +K:Flying +K:Lifelink +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigConjure | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, conjure a card named Sanguine Bond into the top fifteen cards of your library at random. It perpetually gains "You may pay {0} rather than pay this spell's mana cost" and "When this permanent enters, draw a card." +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Name$ Sanguine Bond | Zone$ Library | LibraryPosition$ Count$Random.0.15 | RememberMade$ True | SubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Triggers$ DrawTrig | staticAbilities$ FreeCast | Duration$ Perpetual | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:DrawTrig:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When this creature enters, draw a card. +SVar:FreeCast:Mode$ Continuous | MayPlay$ True | MayPlayAltManaCost$ 0 | MayPlayDontGrantZonePermissions$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Hand | Description$ You may pay {0} rather than pay this spell's mana cost +SVar:TrigDraw:DB$ Draw +Oracle:Flying, lifelink\nWhenever Sanguine Soothsayer attacks, conjure a card named Sanguine Bond into the top fifteen cards of your library at random. It perpetually gains "You may pay {0} rather than pay this spell's mana cost" and "When this permanent enters, draw a card." diff --git a/forge-gui/res/cardsfolder/upcoming/savor.txt b/forge-gui/res/cardsfolder/s/savor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/savor.txt rename to forge-gui/res/cardsfolder/s/savor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sazacaps_brew.txt b/forge-gui/res/cardsfolder/s/sazacaps_brew.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sazacaps_brew.txt rename to forge-gui/res/cardsfolder/s/sazacaps_brew.txt diff --git a/forge-gui/res/cardsfolder/upcoming/scales_of_shale.txt b/forge-gui/res/cardsfolder/s/scales_of_shale.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/scales_of_shale.txt rename to forge-gui/res/cardsfolder/s/scales_of_shale.txt diff --git a/forge-gui/res/cardsfolder/upcoming/scavengers_talent.txt b/forge-gui/res/cardsfolder/s/scavengers_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/scavengers_talent.txt rename to forge-gui/res/cardsfolder/s/scavengers_talent.txt diff --git a/forge-gui/res/cardsfolder/s/scour_the_laboratory.txt b/forge-gui/res/cardsfolder/s/scour_the_laboratory.txt index f976367864e..93617628f13 100644 --- a/forge-gui/res/cardsfolder/s/scour_the_laboratory.txt +++ b/forge-gui/res/cardsfolder/s/scour_the_laboratory.txt @@ -1,8 +1,7 @@ Name:Scour the Laboratory ManaCost:4 U U Types:Instant -S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 2 | EffectZone$ All | CheckSVar$ X | SVarCompare$ GE4 | Description$ Delirium — This spell costs {2} less to cast if there are four or more card types among cards in your graveyard. -SVar:X:Count$ValidGraveyard Card.YouOwn$CardTypes +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 2 | EffectZone$ All | Condition$ Delirium | Description$ Delirium — This spell costs {2} less to cast if there are four or more card types among cards in your graveyard. A:SP$ Draw | NumCards$ 3 | SpellDescription$ Draw three cards. DeckHints:Ability$Graveyard|Discard DeckHas:Ability$Delirium diff --git a/forge-gui/res/cardsfolder/upcoming/scrapshooter.txt b/forge-gui/res/cardsfolder/s/scrapshooter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/scrapshooter.txt rename to forge-gui/res/cardsfolder/s/scrapshooter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/scurry_of_squirrels.txt b/forge-gui/res/cardsfolder/s/scurry_of_squirrels.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/scurry_of_squirrels.txt rename to forge-gui/res/cardsfolder/s/scurry_of_squirrels.txt diff --git a/forge-gui/res/cardsfolder/s/searing_blaze.txt b/forge-gui/res/cardsfolder/s/searing_blaze.txt index d95e885eb71..547481dbb3e 100644 --- a/forge-gui/res/cardsfolder/s/searing_blaze.txt +++ b/forge-gui/res/cardsfolder/s/searing_blaze.txt @@ -1,7 +1,7 @@ Name:Searing Blaze ManaCost:R R Types:Instant -A:SP$ DealDamage | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ SearingX | DamageMap$ True | SubAbility$ SearingDamage | SpellDescription$ CARDNAME deals 1 damage to target player or planeswalker and 1 damage to target creature that player or that planeswalker's controller controls. Landfall — If you had a land enter the battlefield under your control this turn, CARDNAME deals 3 damage to that player or planeswalker and 3 damage to that creature instead. +A:SP$ DealDamage | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ SearingX | DamageMap$ True | SubAbility$ SearingDamage | AILogic$ BurnCreatures | SpellDescription$ CARDNAME deals 1 damage to target player or planeswalker and 1 damage to target creature that player or that planeswalker's controller controls. Landfall — If you had a land enter the battlefield under your control this turn, CARDNAME deals 3 damage to that player or planeswalker and 3 damage to that creature instead. SVar:SearingDamage:DB$ DealDamage | ValidTgts$ Creature.ControlledBy ParentTargetedController,Creature.ControlledBy ParentTarget | TgtPrompt$ Select target creature that player or that planeswalker's controller controls | NumDmg$ SearingX | SubAbility$ DBDamageResolve SVar:DBDamageResolve:DB$ DamageResolve SVar:SearingX:Count$Landfall.3.1 diff --git a/forge-gui/res/cardsfolder/upcoming/season_of_gathering.txt b/forge-gui/res/cardsfolder/s/season_of_gathering.txt similarity index 84% rename from forge-gui/res/cardsfolder/upcoming/season_of_gathering.txt rename to forge-gui/res/cardsfolder/s/season_of_gathering.txt index 642883a640c..4f0375cdacd 100644 --- a/forge-gui/res/cardsfolder/upcoming/season_of_gathering.txt +++ b/forge-gui/res/cardsfolder/s/season_of_gathering.txt @@ -5,9 +5,9 @@ A:SP$ Charm | Choices$ DBPutCounter,DBChoose,DBDraw | CharmNum$ 5 | MinCharmNum$ SVar:DBPutCounter:DB$ PutCounter | Pawprint$ 1 | Choices$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | RememberCards$ True | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on a creature you control. It gains vigilance and trample until end of turn. SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ Vigilance & Trample | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:DBChoose:DB$ GenericChoice | Pawprint$ 2 | Choices$ DBKillEnchantments,DBKillArtifacts | Defined$ You | AILogic$ BestOption | SpellDescription$ Choose artifact or enchantment. Destroy all permanents of the chosen type. -SVar:DBKillEnchantments:DB$ DestroyAll | ValidCards$ Enchantment -SVar:DBKillArtifacts:DB$ DestroyAll | ValidCards$ Artifact +SVar:DBChoose:DB$ GenericChoice | Pawprint$ 2 | Choices$ DBKillArtifacts,DBKillEnchantments | Defined$ You | AILogic$ BestOption | SpellDescription$ Choose artifact or enchantment. Destroy all permanents of the chosen type. +SVar:DBKillArtifacts:DB$ DestroyAll | ValidCards$ Artifact | SpellDescription$ Artifact +SVar:DBKillEnchantments:DB$ DestroyAll | ValidCards$ Enchantment | SpellDescription$ Enchantment SVar:DBDraw:DB$ Draw | Pawprint$ 3 | NumCards$ X | SpellDescription$ Draw cards equal to the greatest power among creatures you control. SVar:X:Count$Valid Creature.YouCtrl$GreatestPower DeckHas:Ability$Counters diff --git a/forge-gui/res/cardsfolder/upcoming/season_of_loss.txt b/forge-gui/res/cardsfolder/s/season_of_loss.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/season_of_loss.txt rename to forge-gui/res/cardsfolder/s/season_of_loss.txt diff --git a/forge-gui/res/cardsfolder/upcoming/season_of_the_bold.txt b/forge-gui/res/cardsfolder/s/season_of_the_bold.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/season_of_the_bold.txt rename to forge-gui/res/cardsfolder/s/season_of_the_bold.txt diff --git a/forge-gui/res/cardsfolder/upcoming/season_of_the_burrow.txt b/forge-gui/res/cardsfolder/s/season_of_the_burrow.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/season_of_the_burrow.txt rename to forge-gui/res/cardsfolder/s/season_of_the_burrow.txt diff --git a/forge-gui/res/cardsfolder/upcoming/season_of_weaving.txt b/forge-gui/res/cardsfolder/s/season_of_weaving.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/season_of_weaving.txt rename to forge-gui/res/cardsfolder/s/season_of_weaving.txt diff --git a/forge-gui/res/cardsfolder/upcoming/seasoned_warrenguard.txt b/forge-gui/res/cardsfolder/s/seasoned_warrenguard.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/seasoned_warrenguard.txt rename to forge-gui/res/cardsfolder/s/seasoned_warrenguard.txt diff --git a/forge-gui/res/cardsfolder/upcoming/seedglaive_mentor.txt b/forge-gui/res/cardsfolder/s/seedglaive_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/seedglaive_mentor.txt rename to forge-gui/res/cardsfolder/s/seedglaive_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/seedpod_squire.txt b/forge-gui/res/cardsfolder/s/seedpod_squire.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/seedpod_squire.txt rename to forge-gui/res/cardsfolder/s/seedpod_squire.txt diff --git a/forge-gui/res/cardsfolder/upcoming/senu_keen_eyed_protector.txt b/forge-gui/res/cardsfolder/s/senu_keen_eyed_protector.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/senu_keen_eyed_protector.txt rename to forge-gui/res/cardsfolder/s/senu_keen_eyed_protector.txt diff --git a/forge-gui/res/cardsfolder/upcoming/settlement_blacksmith.txt b/forge-gui/res/cardsfolder/s/settlement_blacksmith.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/settlement_blacksmith.txt rename to forge-gui/res/cardsfolder/s/settlement_blacksmith.txt diff --git a/forge-gui/res/cardsfolder/upcoming/shao_jun.txt b/forge-gui/res/cardsfolder/s/shao_jun.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/shao_jun.txt rename to forge-gui/res/cardsfolder/s/shao_jun.txt diff --git a/forge-gui/res/cardsfolder/upcoming/shaun_and_rebecca_agents.txt b/forge-gui/res/cardsfolder/s/shaun_and_rebecca_agents.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/shaun_and_rebecca_agents.txt rename to forge-gui/res/cardsfolder/s/shaun_and_rebecca_agents.txt diff --git a/forge-gui/res/cardsfolder/upcoming/shay_cormac.txt b/forge-gui/res/cardsfolder/s/shay_cormac.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/shay_cormac.txt rename to forge-gui/res/cardsfolder/s/shay_cormac.txt diff --git a/forge-gui/res/cardsfolder/s/shellfish_scholar.txt b/forge-gui/res/cardsfolder/s/shellfish_scholar.txt new file mode 100644 index 00000000000..f2ce33cdad3 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/shellfish_scholar.txt @@ -0,0 +1,9 @@ +Name:Shellfish Scholar +ManaCost:2 U +Types:Creature Rat Wizard +PT:3/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self,Rat.Other+YouCtrl | Execute$ TrigConjure | TriggerDescription$ Whenever CARDNAME or another Rat you control enters, conjure a card named Think Twice into your graveyard +SVar:TrigConjure:DB$ MakeCard | Conjure$ True | Name$ Think Twice | Zone$ Graveyard | Amount$ 1 +A:AB$ Effect | Cost$ T | StaticAbilities$ StaticReduce | Activation$ Threshold | PrecostDesc$ Threshold — | SpellDescription$ Spells you cast from your graveyard this turn cost {2} less to cast. Activate only if seven or more cards are in your graveyard. +SVar:StaticReduce:Mode$ ReduceCost | ValidCard$ Card.wasCastFromYourGraveyard | Type$ Spell | Activator$ You | Amount$ 2 | Description$ Spells you cast from your graveyard this turn cost {2} less to cast. +Oracle:Whenever Shellfish Scholar or another Rat you control enters, conjure a card named Think Twice into your graveyard.\nThreshold — {T}: Spells you cast from your graveyard this turn cost {2} less to cast. Activate only if seven or more cards are in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/shoreline_looter.txt b/forge-gui/res/cardsfolder/s/shoreline_looter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/shoreline_looter.txt rename to forge-gui/res/cardsfolder/s/shoreline_looter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/short_bow.txt b/forge-gui/res/cardsfolder/s/short_bow.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/short_bow.txt rename to forge-gui/res/cardsfolder/s/short_bow.txt diff --git a/forge-gui/res/cardsfolder/s/show_of_confidence.txt b/forge-gui/res/cardsfolder/s/show_of_confidence.txt index 74fe2ef6192..3c5e3917fc0 100644 --- a/forge-gui/res/cardsfolder/s/show_of_confidence.txt +++ b/forge-gui/res/cardsfolder/s/show_of_confidence.txt @@ -3,7 +3,7 @@ ManaCost:1 W Types:Instant T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigCopy | TriggerDescription$ When you cast this spell, copy it for each other instant and sorcery spell you've cast this turn. You may choose new targets for the copies. SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ X | MayChooseTarget$ True -SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl/Minus.1 +SVar:X:Count$ThisTurnCast_Instant.YouCtrl+!CastSaSource,Sorcery.YouCtrl A:SP$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature. SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Vigilance DeckHas:Ability$Counters diff --git a/forge-gui/res/cardsfolder/upcoming/shrike_force.txt b/forge-gui/res/cardsfolder/s/shrike_force.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/shrike_force.txt rename to forge-gui/res/cardsfolder/s/shrike_force.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sigurd_jarl_of_ravensthorpe.txt b/forge-gui/res/cardsfolder/s/sigurd_jarl_of_ravensthorpe.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sigurd_jarl_of_ravensthorpe.txt rename to forge-gui/res/cardsfolder/s/sigurd_jarl_of_ravensthorpe.txt diff --git a/forge-gui/res/cardsfolder/s/simic_slaw.txt b/forge-gui/res/cardsfolder/s/simic_slaw.txt new file mode 100644 index 00000000000..230397f37d0 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/simic_slaw.txt @@ -0,0 +1,10 @@ +Name:Simic Slaw +ManaCost:2 +Types:Artifact Food Clue +T:Mode$ ChangesZoneAll | TriggerZones$ Battlefield | ValidCards$ Creature | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigCounter | TriggerDescription$ Whenever one or more creatures die, put a charge counter on CARDNAME. +SVar:TrigCounter:DB$ PutCounter | CounterType$ CHARGE +A:AB$ Draw | Cost$ 2 Sac<1/CARDNAME> | NumCards$ X | SubAbility$ DBLife | SpellDescription$ Draw X cards and gain X life, where X is the number of charge counters on CARDNAME. +SVar:DBLife:DB$ GainLife | LifeAmount$ X +SVar:X:Count$CardCounters.CHARGE +DeckHas:Ability$LifeGain|Sacrifice|Counters +Oracle:Whenever one or more creatures die, put a charge counter on Simic Slaw.\n{2}, Sacrifice Simic Slaw: Draw X cards and gain X life, where X is the number of charge counters on Simic Slaw. diff --git a/forge-gui/res/cardsfolder/upcoming/sinister_monolith.txt b/forge-gui/res/cardsfolder/s/sinister_monolith.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sinister_monolith.txt rename to forge-gui/res/cardsfolder/s/sinister_monolith.txt diff --git a/forge-gui/res/cardsfolder/upcoming/skyskipper_duo.txt b/forge-gui/res/cardsfolder/s/skyskipper_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/skyskipper_duo.txt rename to forge-gui/res/cardsfolder/s/skyskipper_duo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/slumbering_waterways.txt b/forge-gui/res/cardsfolder/s/slumbering_waterways.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/slumbering_waterways.txt rename to forge-gui/res/cardsfolder/s/slumbering_waterways.txt diff --git a/forge-gui/res/cardsfolder/upcoming/smoke_bomb.txt b/forge-gui/res/cardsfolder/s/smoke_bomb.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/smoke_bomb.txt rename to forge-gui/res/cardsfolder/s/smoke_bomb.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sokrates_athenian_teacher.txt b/forge-gui/res/cardsfolder/s/sokrates_athenian_teacher.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sokrates_athenian_teacher.txt rename to forge-gui/res/cardsfolder/s/sokrates_athenian_teacher.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sonar_strike.txt b/forge-gui/res/cardsfolder/s/sonar_strike.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sonar_strike.txt rename to forge-gui/res/cardsfolder/s/sonar_strike.txt diff --git a/forge-gui/res/cardsfolder/s/soul_echo.txt b/forge-gui/res/cardsfolder/s/soul_echo.txt index 1f12ab9ecb8..d8d70b2443a 100644 --- a/forge-gui/res/cardsfolder/s/soul_echo.txt +++ b/forge-gui/res/cardsfolder/s/soul_echo.txt @@ -3,7 +3,7 @@ ManaCost:X W W Types:Enchantment K:etbCounter:ECHO:X SVar:X:Count$xPaid -S:Mode$ Continuous | Affected$ You | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ You don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | Description$ You don't lose the game for having 0 or less life. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME if there are no echo counters on it. Otherwise, target opponent may choose that for each 1 damage that would be dealt to you until your next upkeep, you remove an echo counter from CARDNAME instead. SVar:TrigSac:DB$ Sacrifice | ConditionPresent$ Card.Self+counters_EQ0_ECHO | SubAbility$ TrigChoose SVar:TrigChoose:DB$ GenericChoice | AILogic$ SoulEcho | ConditionPresent$ Card.Self+counters_GT0_ECHO | ValidTgts$ Opponent | Choices$ RemoveCounters,DealDamage diff --git a/forge-gui/res/cardsfolder/s/soul_reap.txt b/forge-gui/res/cardsfolder/s/soul_reap.txt index f588e80c4be..dfbceea5e48 100644 --- a/forge-gui/res/cardsfolder/s/soul_reap.txt +++ b/forge-gui/res/cardsfolder/s/soul_reap.txt @@ -3,5 +3,5 @@ ManaCost:1 B Types:Sorcery A:SP$ Destroy | ValidTgts$ Creature.nonGreen | TgtPrompt$ Select target nongreen creature | SubAbility$ DBLoseLife | SpellDescription$ Destroy target nongreen creature. Its controller loses 3 life if you've cast another black spell this turn. SVar:DBLoseLife:DB$ LoseLife | Defined$ TargetedController | LifeAmount$ 3 | ConditionCheckSVar$ X -SVar:X:Count$ThisTurnCast_Card.Black+Other+YouCtrl +SVar:X:Count$ThisTurnCast_Card.Black+!CastSaSource+YouCtrl Oracle:Destroy target nongreen creature. Its controller loses 3 life if you've cast another black spell this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/spartan_veteran.txt b/forge-gui/res/cardsfolder/s/spartan_veteran.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/spartan_veteran.txt rename to forge-gui/res/cardsfolder/s/spartan_veteran.txt diff --git a/forge-gui/res/cardsfolder/upcoming/spellgyre.txt b/forge-gui/res/cardsfolder/s/spellgyre.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/spellgyre.txt rename to forge-gui/res/cardsfolder/s/spellgyre.txt diff --git a/forge-gui/res/cardsfolder/upcoming/splash_lasher.txt b/forge-gui/res/cardsfolder/s/splash_lasher.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/splash_lasher.txt rename to forge-gui/res/cardsfolder/s/splash_lasher.txt diff --git a/forge-gui/res/cardsfolder/upcoming/splash_portal.txt b/forge-gui/res/cardsfolder/s/splash_portal.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/splash_portal.txt rename to forge-gui/res/cardsfolder/s/splash_portal.txt diff --git a/forge-gui/res/cardsfolder/upcoming/staff_of_eden_vaults_key.txt b/forge-gui/res/cardsfolder/s/staff_of_eden_vaults_key.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/staff_of_eden_vaults_key.txt rename to forge-gui/res/cardsfolder/s/staff_of_eden_vaults_key.txt diff --git a/forge-gui/res/cardsfolder/upcoming/star_charter.txt b/forge-gui/res/cardsfolder/s/star_charter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/star_charter.txt rename to forge-gui/res/cardsfolder/s/star_charter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/starfall_invocation.txt b/forge-gui/res/cardsfolder/s/starfall_invocation.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/starfall_invocation.txt rename to forge-gui/res/cardsfolder/s/starfall_invocation.txt diff --git a/forge-gui/res/cardsfolder/upcoming/starforged_sword.txt b/forge-gui/res/cardsfolder/s/starforged_sword.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/starforged_sword.txt rename to forge-gui/res/cardsfolder/s/starforged_sword.txt diff --git a/forge-gui/res/cardsfolder/upcoming/stargaze.txt b/forge-gui/res/cardsfolder/s/stargaze.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/stargaze.txt rename to forge-gui/res/cardsfolder/s/stargaze.txt diff --git a/forge-gui/res/cardsfolder/upcoming/starlit_soothsayer.txt b/forge-gui/res/cardsfolder/s/starlit_soothsayer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/starlit_soothsayer.txt rename to forge-gui/res/cardsfolder/s/starlit_soothsayer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/starscape_cleric.txt b/forge-gui/res/cardsfolder/s/starscape_cleric.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/starscape_cleric.txt rename to forge-gui/res/cardsfolder/s/starscape_cleric.txt diff --git a/forge-gui/res/cardsfolder/upcoming/starseer_mentor.txt b/forge-gui/res/cardsfolder/s/starseer_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/starseer_mentor.txt rename to forge-gui/res/cardsfolder/s/starseer_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/steampath_charger.txt b/forge-gui/res/cardsfolder/s/steampath_charger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/steampath_charger.txt rename to forge-gui/res/cardsfolder/s/steampath_charger.txt diff --git a/forge-gui/res/cardsfolder/upcoming/steelburr_champion.txt b/forge-gui/res/cardsfolder/s/steelburr_champion.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/steelburr_champion.txt rename to forge-gui/res/cardsfolder/s/steelburr_champion.txt diff --git a/forge-gui/res/cardsfolder/upcoming/stickytongue_sentinel.txt b/forge-gui/res/cardsfolder/s/stickytongue_sentinel.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/stickytongue_sentinel.txt rename to forge-gui/res/cardsfolder/s/stickytongue_sentinel.txt diff --git a/forge-gui/res/cardsfolder/upcoming/stocking_the_pantry.txt b/forge-gui/res/cardsfolder/s/stocking_the_pantry.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/stocking_the_pantry.txt rename to forge-gui/res/cardsfolder/s/stocking_the_pantry.txt diff --git a/forge-gui/res/cardsfolder/s/storm_entity.txt b/forge-gui/res/cardsfolder/s/storm_entity.txt index 3e95711c906..31359519253 100644 --- a/forge-gui/res/cardsfolder/s/storm_entity.txt +++ b/forge-gui/res/cardsfolder/s/storm_entity.txt @@ -4,5 +4,5 @@ Types:Creature Elemental PT:1/1 K:Haste K:etbCounter:P1P1:X:no Condition:CARDNAME enters with a +1/+1 counter on it for each other spell cast this turn. -SVar:X:Count$ThisTurnCast_Card.Other +SVar:X:Count$ThisTurnCast_Card.!CastSaSource Oracle:Haste\nStorm Entity enters with a +1/+1 counter on it for each other spell cast this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/stormcatch_mentor.txt b/forge-gui/res/cardsfolder/s/stormcatch_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/stormcatch_mentor.txt rename to forge-gui/res/cardsfolder/s/stormcatch_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/stormchasers_talent.txt b/forge-gui/res/cardsfolder/s/stormchasers_talent.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/stormchasers_talent.txt rename to forge-gui/res/cardsfolder/s/stormchasers_talent.txt diff --git a/forge-gui/res/cardsfolder/upcoming/stormsplitter.txt b/forge-gui/res/cardsfolder/s/stormsplitter.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/stormsplitter.txt rename to forge-gui/res/cardsfolder/s/stormsplitter.txt diff --git a/forge-gui/res/cardsfolder/s/stromgald_spy.txt b/forge-gui/res/cardsfolder/s/stromgald_spy.txt index 688e8f8f946..1fbeb0ba344 100644 --- a/forge-gui/res/cardsfolder/s/stromgald_spy.txt +++ b/forge-gui/res/cardsfolder/s/stromgald_spy.txt @@ -3,8 +3,9 @@ ManaCost:3 B Types:Creature Human Rogue PT:2/4 T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigExile | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may have defending player play with their hand revealed for as long as CARDNAME remains on the battlefield. If you do, CARDNAME assigns no combat damage this turn. -SVar:TrigExile:DB$ Effect | StaticAbilities$ STRevealHand | RememberObjects$ DefendingPlayer | Duration$ AsLongAsInPlay | SubAbility$ DBPump -SVar:DBPump:DB$ Pump | Defined$ Self | KW$ HIDDEN CARDNAME assigns no combat damage +SVar:TrigExile:DB$ Effect | StaticAbilities$ STRevealHand | RememberObjects$ DefendingPlayer | Duration$ AsLongAsInPlay | SubAbility$ DBNoCombatDamage +SVar:DBNoCombatDamage:DB$ Effect | StaticAbilities$ SNoCombatDamage | Duration$ UntilHostLeavesPlayOrEOT +SVar:SNoCombatDamage:Mode$ AssignNoCombatDamage | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE assigns no combat damage this turn. SVar:STRevealHand:Mode$ Continuous | AffectedZone$ Hand | Affected$ Card.RememberedPlayerOwn | MayLookAt$ Player | Description$ The defending player plays with their hand revealed. AI:RemoveDeck:All Oracle:Whenever Stromgald Spy attacks and isn't blocked, you may have defending player play with their hand revealed for as long as Stromgald Spy remains on the battlefield. If you do, Stromgald Spy assigns no combat damage this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/sugar_coat.txt b/forge-gui/res/cardsfolder/s/sugar_coat.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sugar_coat.txt rename to forge-gui/res/cardsfolder/s/sugar_coat.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sunshower_druid.txt b/forge-gui/res/cardsfolder/s/sunshower_druid.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sunshower_druid.txt rename to forge-gui/res/cardsfolder/s/sunshower_druid.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sunspine_lynx.txt b/forge-gui/res/cardsfolder/s/sunspine_lynx.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sunspine_lynx.txt rename to forge-gui/res/cardsfolder/s/sunspine_lynx.txt diff --git a/forge-gui/res/cardsfolder/upcoming/surtr_fiery_jotun.txt b/forge-gui/res/cardsfolder/s/surtr_fiery_jotun.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/surtr_fiery_jotun.txt rename to forge-gui/res/cardsfolder/s/surtr_fiery_jotun.txt diff --git a/forge-gui/res/cardsfolder/upcoming/swarmyard_massacre.txt b/forge-gui/res/cardsfolder/s/swarmyard_massacre.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/swarmyard_massacre.txt rename to forge-gui/res/cardsfolder/s/swarmyard_massacre.txt diff --git a/forge-gui/res/cardsfolder/upcoming/sword_of_the_squeak.txt b/forge-gui/res/cardsfolder/s/sword_of_the_squeak.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/sword_of_the_squeak.txt rename to forge-gui/res/cardsfolder/s/sword_of_the_squeak.txt diff --git a/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt b/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt index a4ff4a48fd2..152c1273f99 100644 --- a/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt +++ b/forge-gui/res/cardsfolder/t/tahngarth_first_mate.txt @@ -3,7 +3,7 @@ ManaCost:2 R G Types:Legendary Creature Minotaur Warrior PT:5/5 S:Mode$ MinMaxBlocker | ValidCard$ Card.Self | Max$ 1 | Description$ CARDNAME can't be blocked by more than one creature. -T:Mode$ AttackersDeclared | AttackingPlayer$ Player.Opponent | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | IsPresent$ Card.Self+tapped | TriggerDescription$ Whenever an opponent attacks with one or more creatures, if NICKNAME is tapped, you may have that opponent gain control of NICKNAME until end of combat. If you do, choose a player or planeswalker that opponent is attacking. NICKNAME is attacking that player or planeswalker. +T:Mode$ AttackersDeclared | AttackingPlayer$ Player.Opponent | Execute$ TrigGainControl | TriggerZones$ Battlefield | OptionalDecider$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerDescription$ Whenever an opponent attacks with one or more creatures, if NICKNAME is tapped, you may have that opponent gain control of NICKNAME until end of combat. If you do, choose a player or planeswalker that opponent is attacking. NICKNAME is attacking that player or planeswalker. SVar:TrigGainControl:DB$ GainControl | Defined$ Self | NewController$ TriggeredAttackingPlayer | LoseControl$ EndOfCombat | RememberControlled$ True | SubAbility$ DBAttack SVar:DBAttack:DB$ ChangeCombatants | Defined$ Remembered | Attacking$ .Defending & Valid Planeswalker.Defending | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/forge-gui/res/cardsfolder/upcoming/take_out_the_trash.txt b/forge-gui/res/cardsfolder/t/take_out_the_trash.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/take_out_the_trash.txt rename to forge-gui/res/cardsfolder/t/take_out_the_trash.txt diff --git a/forge-gui/res/cardsfolder/t/talaras_battalion.txt b/forge-gui/res/cardsfolder/t/talaras_battalion.txt index d4b552f6372..a232aae23a3 100644 --- a/forge-gui/res/cardsfolder/t/talaras_battalion.txt +++ b/forge-gui/res/cardsfolder/t/talaras_battalion.txt @@ -4,5 +4,5 @@ Types:Creature Elf Warrior PT:4/3 K:Trample S:Mode$ CantBeCast | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ EQ0 | EffectZone$ All | Description$ Cast this spell only if you've cast another green spell this turn. -SVar:X:Count$ThisTurnCast_Card.Green+Other+YouCtrl +SVar:X:Count$ThisTurnCast_Card.Green+YouCtrl Oracle:Cast this spell only if you've cast another green spell this turn.\nTrample diff --git a/forge-gui/res/cardsfolder/upcoming/tangle_tumbler.txt b/forge-gui/res/cardsfolder/t/tangle_tumbler.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tangle_tumbler.txt rename to forge-gui/res/cardsfolder/t/tangle_tumbler.txt diff --git a/forge-gui/res/cardsfolder/t/tasteful_offering.txt b/forge-gui/res/cardsfolder/t/tasteful_offering.txt new file mode 100644 index 00000000000..07fa799f499 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/tasteful_offering.txt @@ -0,0 +1,9 @@ +Name:Tasteful Offering +ManaCost:1 B +Types:Sorcery +A:SP$ Effect | Boon$ True | Duration$ Permanent | Triggers$ SacTrig | SubAbility$ DBToken | StackDescription$ REP You get_{p:You} gets & Create a_{p:You} creates a | SpellDescription$ You get a two-time boon with "Whenever you sacrifice one or more permanents, seek a nonland card." Create a Food token. +SVar:SacTrig:Mode$ SacrificedOnce | ValidCard$ Permanent | ValidPlayer$ You | TriggerZones$ Command | BoonAmount$ 2 | Execute$ TrigSeek | TriggerDescription$ Whenever you sacrifice one or more permanents, seek a nonland card. +SVar:TrigSeek:DB$ Seek | Num$ 1 | Type$ Card.nonLand +SVar:DBToken:DB$ Token | TokenScript$ c_a_food_sac +DeckHas:Ability$LifeGain|Token +Oracle:You get a two-time boon with "Whenever you sacrifice one or more permanents, seek a nonland card." Create a Food token. diff --git a/forge-gui/res/cardsfolder/upcoming/tax_collector.txt b/forge-gui/res/cardsfolder/t/tax_collector.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tax_collector.txt rename to forge-gui/res/cardsfolder/t/tax_collector.txt diff --git a/forge-gui/res/cardsfolder/upcoming/teapot_slinger.txt b/forge-gui/res/cardsfolder/t/teapot_slinger.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/teapot_slinger.txt rename to forge-gui/res/cardsfolder/t/teapot_slinger.txt diff --git a/forge-gui/res/cardsfolder/upcoming/teferi_druid_of_argoth.txt b/forge-gui/res/cardsfolder/t/teferi_druid_of_argoth.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/teferi_druid_of_argoth.txt rename to forge-gui/res/cardsfolder/t/teferi_druid_of_argoth.txt diff --git a/forge-gui/res/cardsfolder/t/teferi_who_slows_the_sunset.txt b/forge-gui/res/cardsfolder/t/teferi_who_slows_the_sunset.txt index ac64e006182..3a55f89f387 100644 --- a/forge-gui/res/cardsfolder/t/teferi_who_slows_the_sunset.txt +++ b/forge-gui/res/cardsfolder/t/teferi_who_slows_the_sunset.txt @@ -9,9 +9,10 @@ SVar:DBUntap:DB$ Untap | Defined$ Targeted.YouCtrl | SubAbility$ DBTap | StackDe SVar:DBTap:DB$ Tap | Defined$ Targeted.YouDontCtrl | SubAbility$ DBGainLife | StackDescription$ Tap the chosen permanents you don't control. SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 A:AB$ Dig | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | DigNum$ 3 | ChangeNum$ 1 | NoReveal$ True | StackDescription$ SpellDescription | SpellDescription$ Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order. -A:AB$ Effect | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Emblem — Teferi, Who Slows the Sunset | Image$ emblem_teferi_who_slows_the_sunset | StaticAbilities$ UntapOppStep,DrawOppStep | Stackable$ False | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "Untap all permanents you control during each opponent's untap step" and "You draw a card during each opponent's draw step." +A:AB$ Effect | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Emblem — Teferi, Who Slows the Sunset | Image$ emblem_teferi_who_slows_the_sunset | Triggers$ DrawOppStep | StaticAbilities$ UntapOppStep | Stackable$ False | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "Untap all permanents you control during each opponent's untap step" and "You draw a card during each opponent's draw step." SVar:UntapOppStep:Mode$ Continuous | EffectZone$ Command | Affected$ Permanent.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each opponent's untap step. | Description$ Untap all permanents you control during each opponent's untap step. -SVar:DrawOppStep:Mode$ Continuous | EffectZone$ Command | Affected$ You | AddKeyword$ You draw a card during each opponent's draw step. | Description$ You draw a card during each opponent's draw step. +SVar:DrawOppStep:Mode$ Phase | Phase$ Draw | ValidPlayer$ Opponent | Execute$ TrigDraw | Static$ True | TriggerDescription$ You draw a card during each opponent's draw step. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 SVar:PlayMain1:TRUE DeckHas:Ability$LifeGain Oracle:[+1]: Choose up to one target artifact, up to one target creature, and up to one target land. Untap the chosen permanents you control. Tap the chosen permanents you don't control. You gain 2 life.\n[-2]: Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.\n[-7]: You get an emblem with "Untap all permanents you control during each opponent's untap step" and "You draw a card during each opponent's draw step." diff --git a/forge-gui/res/cardsfolder/upcoming/tempest_angler.txt b/forge-gui/res/cardsfolder/t/tempest_angler.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tempest_angler.txt rename to forge-gui/res/cardsfolder/t/tempest_angler.txt diff --git a/forge-gui/res/cardsfolder/t/tempest_trapper.txt b/forge-gui/res/cardsfolder/t/tempest_trapper.txt new file mode 100644 index 00000000000..7d8e48aace5 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/tempest_trapper.txt @@ -0,0 +1,11 @@ +Name:Tempest Trapper +ManaCost:3 U +Types:Creature Otter Wizard +PT:2/5 +A:AB$ Mana | Cost$ T | Produced$ Combo Any | Amount$ 2 | RestrictValid$ Spell.Instant,Spell.Sorcery | SpellDescription$ Add two mana in any combination of colors. Spend this mana only to cast instant or sorcery spells. +T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigExile | ActivatorThisTurnCast$ EQ3 | TriggerDescription$ Whenever you cast your third spell each turn, exile a random card from your library. Until end of turn, you may play that card without paying its mana cost. +SVar:TrigExile:DB$ ChangeZone | DefinedPlayer$ You | ChangeType$ Card | ChangeNum$ 1 | Origin$ Library | Destination$ Exile | AtRandom$ True | Hidden$ True | NoLooking$ True | NoShuffle$ True | Mandatory$ True | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ STPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile +SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | MayPlayWithoutManaCost$ True | AffectedZone$ Exile | Description$ You may play remembered card without paying its mana cost. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:{T}: Add two mana in any combination of colors. Spend this mana only to cast instant or sorcery spells.\nWhenever you cast your third spell each turn, exile a random card from your library. Until end of turn, you may play that card without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/upcoming/templar_knight.txt b/forge-gui/res/cardsfolder/t/templar_knight.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/templar_knight.txt rename to forge-gui/res/cardsfolder/t/templar_knight.txt diff --git a/forge-gui/res/cardsfolder/upcoming/tempt_with_bunnies.txt b/forge-gui/res/cardsfolder/t/tempt_with_bunnies.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tempt_with_bunnies.txt rename to forge-gui/res/cardsfolder/t/tempt_with_bunnies.txt diff --git a/forge-gui/res/cardsfolder/upcoming/temur_elevator.txt b/forge-gui/res/cardsfolder/t/temur_elevator.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/temur_elevator.txt rename to forge-gui/res/cardsfolder/t/temur_elevator.txt diff --git a/forge-gui/res/cardsfolder/upcoming/tender_wildguide.txt b/forge-gui/res/cardsfolder/t/tender_wildguide.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tender_wildguide.txt rename to forge-gui/res/cardsfolder/t/tender_wildguide.txt diff --git a/forge-gui/res/cardsfolder/upcoming/the_aesir_escape_valhalla.txt b/forge-gui/res/cardsfolder/t/the_aesir_escape_valhalla.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/the_aesir_escape_valhalla.txt rename to forge-gui/res/cardsfolder/t/the_aesir_escape_valhalla.txt diff --git a/forge-gui/res/cardsfolder/t/the_bear_force_pilot.txt b/forge-gui/res/cardsfolder/t/the_bear_force_pilot.txt new file mode 100644 index 00000000000..30cf93416ab --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_bear_force_pilot.txt @@ -0,0 +1,9 @@ +Name:The Bear Force Pilot +ManaCost:1 G +Types:Legendary Creature Bear Pilot +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a colorless artifact Vehicle token with flying, "This creature gets +1/+1 for each Bear you control," and Crew 2. +SVar:TrigToken:DB$ Token | TokenScript$ bear_force_one +DeckHas:Ability$Token & Type$Artifact|Vehicle +DeckHints:Type$Bear +Oracle:When The Bear Force Pilot enters the battlefield, create a colorless artifact Vehicle token with flying, "This creature gets +1/+1 for each Bear you control," and Crew 2. diff --git a/forge-gui/res/cardsfolder/t/the_book_of_exalted_deeds.txt b/forge-gui/res/cardsfolder/t/the_book_of_exalted_deeds.txt index 4abb6d0b5fa..dfc240ff9bf 100644 --- a/forge-gui/res/cardsfolder/t/the_book_of_exalted_deeds.txt +++ b/forge-gui/res/cardsfolder/t/the_book_of_exalted_deeds.txt @@ -4,9 +4,9 @@ Types:Legendary Artifact T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ LifeGained | SVarCompare$ GE3 | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, if you gained 3 or more life this turn, create a 3/3 white Angel creature token with flying. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_3_3_angel_flying | TokenOwner$ You A:AB$ PutCounter | Cost$ W W W T Exile<1/CARDNAME> | ValidTgts$ Angel | TgtPrompt$ Select target Angel | CounterType$ ENLIGHTENED | CounterNum$ 1 | SorcerySpeed$ True | SubAbility$ DBAnimate | SpellDescription$ Put an enlightened counter on target Angel. It gains "You can't lose the game and your opponents can't win the game." Activate only as a sorcery. -SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Duration$ Permanent | staticAbilities$ DBYouCantLose,DBOppCantWin | StackDescription$ None -SVar:DBYouCantLose:Mode$ Continuous | Affected$ You | AddKeyword$ You can't lose the game. | Description$ You can't lose the game. -SVar:DBOppCantWin:Mode$ Continuous | Affected$ Opponent | AddKeyword$ You can't win the game. | Description$ Opponents can't win the game. +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Duration$ Permanent | Replacements$ DBYouCantLose,DBOppCantWin | StackDescription$ None +SVar:DBYouCantLose:Event$ GameLoss | ValidPlayer$ You | Layer$ CantHappen | Description$ You can't lose the game and your opponents can't win the game. +SVar:DBOppCantWin:Event$ GameWin | ValidPlayer$ Opponent | Layer$ CantHappen | Secondary$ True | Description$ You can't lose the game and your opponents can't win the game. SVar:LifeGained:Count$LifeYouGainedThisTurn DeckHints:Ability$LifeGain DeckHas:Ability$Token diff --git a/forge-gui/res/cardsfolder/upcoming/the_capitoline_triad.txt b/forge-gui/res/cardsfolder/t/the_capitoline_triad.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/the_capitoline_triad.txt rename to forge-gui/res/cardsfolder/t/the_capitoline_triad.txt diff --git a/forge-gui/res/cardsfolder/t/the_crafter.txt b/forge-gui/res/cardsfolder/t/the_crafter.txt new file mode 100644 index 00000000000..0efdce1a4f8 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_crafter.txt @@ -0,0 +1,12 @@ +Name:The Crafter +ManaCost:3 R +Types:Legendary Artifact Creature Human +PT:3/4 +K:Affinity:Artifact +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create two colorless Scrap artifact tokens (They have no abilities.) +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ scrap +A:AB$ Token | Cost$ T Sac<1/Artifact> | TokenScript$ bling | SpellDescription$ Create an equipment token named Bling with "Equipped creature gets +1/+0" and "Equip {1}." +SVar:AIPreference:SacCost$Artifact.nonCreature+nonEquipment+Token+powerLE1+toughnessEQ1 +DeckHas:Ability$Token|Sacrifice & Type$Equipment +DeckHints:Type$Artifact +Oracle:Affinity for artifacts\nWhen The Crafter enters the battlefield, create two colorless Scrap artifact tokens (They have no abilities.)\n{T}, Sacrifice an artifact: Create an equipment token named Bling with "Equipped creature gets +1/+0" and "Equip {1}." diff --git a/forge-gui/res/cardsfolder/t/the_crimson_avenger.txt b/forge-gui/res/cardsfolder/t/the_crimson_avenger.txt new file mode 100644 index 00000000000..f8ec165028d --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_crimson_avenger.txt @@ -0,0 +1,13 @@ +Name:The Crimson Avenger +ManaCost:3 R R +Types:Legendary Creature Human Wizard +PT:3/2 +K:Flash +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ When CARDNAME enters the battlefield, choose target spell an opponent controls. Reveal cards from the top of your library until you reveal a card that shares a mana value with it. Cast that card without paying its mana cost. Then shuffle your library. +SVar:TrigChoose:DB$ Pump | TargetType$ Spell | TgtZone$ Stack | ValidTgts$ Card.OppCtrl | TgtPrompt$ Select target spell an opponent controls | SubAbility$ CrimsonCascade +SVar:CrimsonCascade:DB$ DigUntil | Defined$ You | Amount$ 1 | Valid$ Card.cmcEQX | NoMoveRevealed$ True | RememberFound$ True | SubAbility$ CascadeCast +SVar:CascadeCast:DB$ Play | Defined$ Remembered | WithoutManaCost$ True | ValidSA$ Spell | SubAbility$ YouShuffle +SVar:YouShuffle:DB$ Shuffle | Defined$ You | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Targeted$CardManaCost +Oracle:Flash\nWhen The Crimson Avenger enters the battlefield, choose target spell an opponent controls. Reveal cards from the top of your library until you reveal a card that shares a mana value with it. Cast that card without paying its mana cost. Then shuffle your library. diff --git a/forge-gui/res/cardsfolder/t/the_duke_of_midrange.txt b/forge-gui/res/cardsfolder/t/the_duke_of_midrange.txt new file mode 100644 index 00000000000..f0ec01d6e48 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_duke_of_midrange.txt @@ -0,0 +1,13 @@ +Name:The Duke of Midrange +ManaCost:2 B R G +Types:Legendary Creature Lhurgoyf Wizard +PT:*/1+* +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ When CARDNAME enters the battlefield, choose one of Thoughtseize, Lightning Bolt, or Abrupt Decay. Cast a copy of the chosen card without paying its mana cost. +SVar:TrigChoose:DB$ NameCard | Defined$ You | ChooseFromList$ Thoughtseize,Lightning Bolt,Abrupt Decay | SubAbility$ DBCast +SVar:DBCast:DB$ Play | CopyFromChosenName$ True | WithoutManaCost$ True | StackDescription$ None +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ Y | Description$ CARDNAME's power is equal to the number of card types among all cards in all graveyards, and its toughness is equal to that number plus 1. +SVar:X:Count$ValidGraveyard Card$CardTypes +SVar:Y:SVar$X/Plus.1 +SVar:PlayMain1:TRUE +DeckHints:Ability$Graveyard +Oracle:When The Duke of Midrange enters the battlefield, choose one of Thoughtseize, Lightning Bolt, or Abrupt Decay. Cast a copy of the chosen card without paying its mana cost.\nThe Duke of Midrange's power is equal to the number of card types among all cards in all graveyards, and its toughness is equal to that number plus 1. diff --git a/forge-gui/res/cardsfolder/t/the_great_juggernaut.txt b/forge-gui/res/cardsfolder/t/the_great_juggernaut.txt new file mode 100644 index 00000000000..189e35bf94c --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_great_juggernaut.txt @@ -0,0 +1,13 @@ +Name:The Great Juggernaut +ManaCost:3 R +Types:Legendary Artifact Creature Juggernaut +PT:5/3 +K:UpkeepCost:Discard<1/Card> +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigShuffle | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, shuffle your library then exile the top card of your library. You may play that card without paying its mana cost this turn. +SVar:TrigShuffle:DB$ Shuffle | Defined$ You | SubAbility$ DBExile +SVar:DBExile:DB$ Dig | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ DBPlay | SubAbility$ DBCleanup | ExileOnMoved$ Exile +SVar:DBPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play the exiled card without paying its mana cost. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:HasAttackEffect:TRUE +Oracle:At the beginning of your upkeep, sacrifice The Great Juggernaut unless you discard a card.\nWhenever The Great Juggernaut attacks, shuffle your library then exile the top card of your library. You may play that card without paying its mana cost this turn. diff --git a/forge-gui/res/cardsfolder/t/the_heron_moon.txt b/forge-gui/res/cardsfolder/t/the_heron_moon.txt new file mode 100644 index 00000000000..75af83097ea --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_heron_moon.txt @@ -0,0 +1,13 @@ +Name:The Heron Moon +ManaCost:no cost +Types:Legendary Land +A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. +A:AB$ ChangeZoneAll | Cost$ 1 T | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | ChangeType$ Card.BottomLibrary | Origin$ Library | Destination$ Exile | SpellDescription$ Exile the bottom card of target opponent's library. +T:Mode$ ChangesZoneAll | ValidCards$ Card.OppOwn+nonToken+nonCopiedSpell | Destination$ Exile | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever one or more cards an opponent owns are put into exile, put a release counter on CARDNAME. Then if it has thirteen or more release counters on it, sacrifice it and create a copy of Emrakul, the Promised End. Cast it without paying its mana cost. +SVar:TrigPutCounter:DB$ PutCounter | CounterType$ RELEASE | Defined$ Self | CounterNum$ 1 | SubAbility$ DBSac +SVar:DBSac:DB$ Sacrifice | SacValid$ Self | RememberSacrificed$ True | ConditionPresent$ Card.Self+counters_GE13_RELEASE | SubAbility$ DBNameCard +SVar:DBNameCard:DB$ NameCard | Defined$ You | ChooseFromList$ Emrakul; the Promised End | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCast | StackDescription$ None +SVar:DBCast:DB$ Play | CopyFromChosenName$ True | Mandatory$ True | WithoutManaCost$ True | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup | StackDescription$ None +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearNamedCard$ True +DeckHas:Ability$Mana.Colorless +Oracle:{T}: Add {C}.\n{1}, {T}: Exile the bottom card of target opponent's library.\nWhenever one or more cards an opponent owns are put into exile, put a release counter on The Heron Moon. Then if it has thirteen or more release counters on it, sacrifice it and create a copy of Emrakul, the Promised End. Cast it without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/upcoming/the_infamous_cruelclaw.txt b/forge-gui/res/cardsfolder/t/the_infamous_cruelclaw.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/the_infamous_cruelclaw.txt rename to forge-gui/res/cardsfolder/t/the_infamous_cruelclaw.txt diff --git a/forge-gui/res/cardsfolder/t/the_juzam_master.txt b/forge-gui/res/cardsfolder/t/the_juzam_master.txt new file mode 100644 index 00000000000..0d0f93ddb24 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_juzam_master.txt @@ -0,0 +1,9 @@ +Name:The Juzam Master +ManaCost:2 B B +Types:Legendary Creature Human Wizard +PT:4/5 +S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddPower$ 1 | AddTrigger$ JuzamTrigger | Description$ Creatures you control get +1/+0 and have "At the beginning of your upkeep, this creature deals 1 damage to you." +SVar:JuzamTrigger:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your upkeep, this creature deals 1 damage to you. +SVar:TrigDealDamage:DB$ DealDamage | Defined$ You | NumDmg$ 1 +SVar:PlayMain1:TRUE +Oracle:Creatures you control get +1/+0 and have "At the beginning of your upkeep, this creature deals 1 damage to you." diff --git a/forge-gui/res/cardsfolder/t/the_keeper_of_dark_pacts.txt b/forge-gui/res/cardsfolder/t/the_keeper_of_dark_pacts.txt new file mode 100644 index 00000000000..c2b2fcce59f --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_keeper_of_dark_pacts.txt @@ -0,0 +1,11 @@ +Name:The Keeper of Dark Pacts +ManaCost:4 B +Types:Legendary Creature Human Wizard +PT:4/4 +K:Starting intensity:1 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ At the beginning of your upkeep, you lose 1 life and draw a card. Then, double the amount of life you lose and cards you draw for the rest of the game from this ability. (This is true even if this leaves the battlefield and returns.) +SVar:TrigLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ X | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ X | SubAbility$ DBIntensify +SVar:DBIntensify:DB$ Intensify | Amount$ X +SVar:X:Count$Intensity +Oracle:At the beginning of your upkeep, you lose 1 life and draw a card. Then, double the amount of life you lose and cards you draw for the rest of the game from this ability. (This is true even if this leaves the battlefield and returns.) diff --git a/forge-gui/res/cardsfolder/t/the_keeper_of_the_yellow_hat.txt b/forge-gui/res/cardsfolder/t/the_keeper_of_the_yellow_hat.txt new file mode 100644 index 00000000000..5528ebbb499 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_keeper_of_the_yellow_hat.txt @@ -0,0 +1,9 @@ +Name:The Keeper of the Yellow Hat +ManaCost:W U +Types:Legendary Creature Human Wizard +PT:1/1 +S:Mode$ CantBeCast | ValidCard$ Card.Self | EffectZone$ All | Caster$ Player.Active | CheckSVar$ Count$YourTurns | SVarCompare$ LE7 | Description$ You can't cast CARDNAME during your first seven turns of the game. (Keep track if you're playing with this!) +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a legendary artifact equipment token named Yellow Hat with equip {2} and "Equiped creature gets +4/+4 and gains lifelink." +SVar:TrigToken:DB$ Token | TokenScript$ yellow_hat +DeckHas:Ability$Token & Type$Artifact|Equipment +Oracle:You can't cast Keeper of the Yellow Hat during your first seven turns of the game. (Keep track if you're playing with this!)\nWhen The Keeper of the Yellow Hat enters the battlefield, create a legendary artifact equipment token named Yellow Hat with equip {2} and "Equiped creature gets +4/+4 and gains lifelink." diff --git a/forge-gui/res/cardsfolder/t/the_magic_bandit.txt b/forge-gui/res/cardsfolder/t/the_magic_bandit.txt new file mode 100644 index 00000000000..25b7e4b98f6 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_magic_bandit.txt @@ -0,0 +1,14 @@ +Name:The Magic Bandit +ManaCost:3 B +Types:Legendary Creature Human Rogue +PT:3/2 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDig | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME deals combat damage to an opponent, exile the top card of that player's library. You may cast that card for as long as it remains exiled, and mana of any type can be spent to cast that spell. +SVar:TrigDig:DB$ Dig | DigNum$ 1 | Defined$ TriggeredTarget | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup +SVar:STPlay:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand | AffectedZone$ Exile | Description$ You may cast that card for as long as it remains exiled, and mana of any type can be spent to cast that spell. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +T:Mode$ SpellCast | ValidCard$ Card.YouDontOwn | ValidActivatingPlayer$ You | Execute$ TrigCopySpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell or play a land you don't own, copy it. +SVar:TrigCopySpell:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility +T:Mode$ LandPlayed | ValidCard$ Land.YouCtrl+YouDontOwn | TriggerZones$ Battlefield | Execute$ TrigCopyLand | Secondary$ True | TriggerDescription$ Whenever you cast a spell or play a land you don't own, copy it. +SVar:TrigCopyLand:DB$ CopyPermanent | Defined$ TriggeredCardLKICopy +Oracle:When The Magic Bandit deals combat damage to an opponent, exile the top card of that player's library. You may cast that card for as long as it remains exiled, and mana of any type can be spent to cast that spell.\nWhenever you cast a spell or play a land you don't own, copy it. diff --git a/forge-gui/res/cardsfolder/t/the_marvelous_scientist.txt b/forge-gui/res/cardsfolder/t/the_marvelous_scientist.txt new file mode 100644 index 00000000000..f64fab5abc6 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_marvelous_scientist.txt @@ -0,0 +1,17 @@ +Name:The Marvelous Scientist +ManaCost:1 U R +Types:Legendary Creature Human Wizard +PT:2/2 +K:ETBReplacement:Other:SiegeChoice +SVar:SiegeChoice:DB$ GenericChoice | Choices$ Cosplay,Science | Defined$ You | SetChosenMode$ True | ShowChoice$ ExceptSelf | SpellDescription$ As this creature enters the battlefield, choose cosplay or science. +SVar:Cosplay:DB$ Pump | SpellDescription$ Cosplay +SVar:Science:DB$ Pump | SpellDescription$ Science +S:Mode$ Continuous | Affected$ Card.Self+ChosenModeCosplay | AddTrigger$ CosplayTrigger | Description$ • Cosplay — Whenever you cast a creature or planeswalker spell, this creature's base power and toughness each become equal to that spell's mana value until end of turn. +S:Mode$ Continuous | Affected$ Card.Self+ChosenModeScience | AddTrigger$ ScienceTrigger | Description$ • Science — Whenever you cast an instant or sorcery spell, this creature deals 2 damage to each opponent. +SVar:CosplayTrigger:Mode$ SpellCast | ValidCard$ Creature,Planeswalker | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigAnimate | TriggerDescription$ Whenever you cast a creature or planeswalker spell, this creature's base power and toughness each become equal to that spell's mana value until end of turn. +SVar:TrigAnimate:DB$ Animate | Power$ X | Toughness$ X +SVar:X:TriggeredStackInstance$CardManaCostLKI +SVar:ScienceTrigger:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever you cast an instant or sorcery spell, this creature deals 2 damage to each opponent. +SVar:TrigDamage:DB$ DealDamage | Defined$ Player.Opponent | NumDmg$ 2 +DeckHints:Type$Instant|Sorcery +Oracle:As this creature enters the battlefield, choose cosplay or science.\n• Cosplay — Whenever you cast a creature or planeswalker spell, this creature's base power and toughness each become equal to that spell's mana value until end of turn.\n• Science — Whenever you cast an instant or sorcery spell, this creature deals 2 damage to each opponent. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/t/the_massive_zatcatl.txt b/forge-gui/res/cardsfolder/t/the_massive_zatcatl.txt new file mode 100644 index 00000000000..26042f05f47 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_massive_zatcatl.txt @@ -0,0 +1,8 @@ +Name:The Massive Zatcatl +ManaCost:5 G G +Types:Legendary Creature Elf Cat Wizard +PT:6/6 +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, draw a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 +A:AB$ Mana | Cost$ tapXType<3/Creature> | Produced$ G | Amount$ 3 | SpellDescription$ Add {G}{G}{G}. +Oracle:Whenever you cast a creature spell, draw a card.\nTap three untapped creatures you control: Add {G}{G}{G}. diff --git a/forge-gui/res/cardsfolder/t/the_master_of_cuisine.txt b/forge-gui/res/cardsfolder/t/the_master_of_cuisine.txt new file mode 100644 index 00000000000..a9f66cc0af9 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_master_of_cuisine.txt @@ -0,0 +1,14 @@ +Name:The Master of Cuisine +ManaCost:R G W +Types:Legendary Creature Human Chef +PT:3/3 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever this creature attacks, create a Food token. +SVar:TrigToken:DB$ Token | TokenScript$ c_a_food_sac +T:Mode$ Sacrificed | ValidCard$ Food.YouCtrl | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescription$ Whenever you sacrifice a food, ABILITY +SVar:TrigChoose:DB$ Charm | Choices$ Gelato,Pasta,Pizza | CharmNum$ 1 +SVar:Gelato:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Haste & Trample | SpellDescription$ Gelato — Target creature gains haste and trample until end of turn. +SVar:Pasta:DB$ Scry | ScryNum$ 1 | SpellDescription$ Pasta — Scry 1. +SVar:Pizza:DB$ Tap | ValidTgts$ Creature | SpellDescription$ Pizza — Tap target creature. +DeckHas:Ability$Token & Type$Artifact|Food +DeckHints:Type$Food +Oracle:Whenever this creature attacks, create a Food token.\nWhenever you sacrifice a food, choose one\n• Gelato — Target creature gains haste and trample until end of turn.\n• Pasta — Scry 1.\n• Pizza — Tap target creature. diff --git a/forge-gui/res/cardsfolder/upcoming/the_odd_acorn_gang.txt b/forge-gui/res/cardsfolder/t/the_odd_acorn_gang.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/the_odd_acorn_gang.txt rename to forge-gui/res/cardsfolder/t/the_odd_acorn_gang.txt diff --git a/forge-gui/res/cardsfolder/t/the_rebellious_intelligence.txt b/forge-gui/res/cardsfolder/t/the_rebellious_intelligence.txt new file mode 100644 index 00000000000..27d660d405d --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_rebellious_intelligence.txt @@ -0,0 +1,8 @@ +Name:The Rebellious Intelligence +ManaCost:5 +Types:Legendary Artifact Creature Rebel +PT:5/5 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigWish | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, put a random card from outside the game into your hand. +SVar:TrigWish:DB$ ChangeZone | Origin$ Sideboard | Destination$ Hand | ChangeType$ Card.YouOwn | Hidden$ True | AtRandom$ True +A:AB$ Mana | Cost$ T | Produced$ W U B R G | RestrictValid$ CantPayGenericCosts | SpellDescription$ Add {W}{U}{B}{R}{G}. This mana can't be spent to pay generic mana costs. +Oracle:At the beginning of your upkeep, put a random card from outside the game into your hand. (In Commander sealed, that's everything you didn't play with. In any other commander game, find a way to select a random Magic card.)\n{T}: Add {W}{U}{B}{R}{G}. This mana can't be spent to pay generic mana costs. diff --git a/forge-gui/res/cardsfolder/upcoming/the_revelations_of_ezio.txt b/forge-gui/res/cardsfolder/t/the_revelations_of_ezio.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/the_revelations_of_ezio.txt rename to forge-gui/res/cardsfolder/t/the_revelations_of_ezio.txt diff --git a/forge-gui/res/cardsfolder/t/the_roaring_toeclaws.txt b/forge-gui/res/cardsfolder/t/the_roaring_toeclaws.txt new file mode 100644 index 00000000000..334afd68cad --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_roaring_toeclaws.txt @@ -0,0 +1,9 @@ +Name:The Roaring Toeclaws +ManaCost:3 G G +Types:Legendary Creature Dinosaur +PT:5/5 +T:Mode$ Untaps | ValidCard$ Card.Self,Creature.Other+YouCtrl+powerGE5 | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever CARDNAME or another creature you control with mana value five or greater becomes untapped, put +1/+1 counters on it equal to its power. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCard | CounterType$ P1P1 | CounterNum$ X +SVar:X:TriggeredCard$CardPower +DeckHas:Ability$Counters +Oracle:Whenever The Roaring Toeclaws or another creature you control with mana value five or greater becomes untapped, put +1/+1 counters on it equal to its power. diff --git a/forge-gui/res/cardsfolder/t/the_spike_cactus.txt b/forge-gui/res/cardsfolder/t/the_spike_cactus.txt new file mode 100644 index 00000000000..54fbd83b377 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_spike_cactus.txt @@ -0,0 +1,9 @@ +Name:The Spike Cactus +ManaCost:1 G G +Types:Legendary Creature Spike +PT:0/0 +K:etbCounter:P1P1:X:no Condition:CARDNAME enters the battlefield with +1/+1 counters on it equal to the amount of mana spent to cast it. +A:AB$ PutCounter | Cost$ 2 SubCounter<1/P1P1> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +SVar:X:Count$CastTotalManaSpent +DeckHas:Ability$Counters +Oracle:The Spike Cactus enters the battlefield with +1/+1 counters on it equal to the amount of mana spent to cast it.\n{2}, Remove a +1/+1 counter from The Spike Cactus: Put a +1/+1 counter on target creature. diff --git a/forge-gui/res/cardsfolder/t/the_value_knight.txt b/forge-gui/res/cardsfolder/t/the_value_knight.txt new file mode 100644 index 00000000000..f86486452a8 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_value_knight.txt @@ -0,0 +1,10 @@ +Name:The Value Knight +ManaCost:3 U +Types:Legendary Creature Human Knight +PT:1/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create Syr Acha, a 1/1 legendary red artifact creature Food Knight token with "{2}, {T}, Sacrifice this token: You gain 3 life. Until end of turn, if you would draw a card, draw two cards instead." +SVar:TrigToken:DB$ Token | TokenScript$ syr_acha +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you draw a card, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Token|Counters & Type$Artifact|Food +Oracle:When The Value Knight enters the battlefield, create Syr Acha, a 1/1 legendary red artifact creature Food Knight token with "{2}, {T}, Sacrifice this token: You gain 3 life. Until end of turn, if you would draw a card, draw two cards instead."\nWhenever you draw a card, put a +1/+1 counter on The Value Knight. diff --git a/forge-gui/res/cardsfolder/t/the_very_soil_shall_shake.txt b/forge-gui/res/cardsfolder/t/the_very_soil_shall_shake.txt index 01e56f3e5ca..a8dd5ac31e6 100644 --- a/forge-gui/res/cardsfolder/t/the_very_soil_shall_shake.txt +++ b/forge-gui/res/cardsfolder/t/the_very_soil_shall_shake.txt @@ -3,5 +3,5 @@ ManaCost:no cost Types:Ongoing Scheme S:Mode$ Continuous | Affected$ Creature.YouCtrl | EffectZone$ Command | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Trample | Description$ Creatures you control get +2/+2 and have trample. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl | TriggerZones$ Command | Execute$ Abandon | TriggerDescription$ When a creature you control dies, abandon this scheme. -SVar:Abandon:AB$ Abandon | Cost$ 0 +SVar:Abandon:DB$ Abandon Oracle:(An ongoing scheme remains face up until it's abandoned.)\nCreatures you control get +2/+2 and have trample.\nWhen a creature you control dies, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/thickest_in_the_thicket.txt b/forge-gui/res/cardsfolder/t/thickest_in_the_thicket.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thickest_in_the_thicket.txt rename to forge-gui/res/cardsfolder/t/thickest_in_the_thicket.txt diff --git a/forge-gui/res/cardsfolder/upcoming/thistledown_players.txt b/forge-gui/res/cardsfolder/t/thistledown_players.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thistledown_players.txt rename to forge-gui/res/cardsfolder/t/thistledown_players.txt diff --git a/forge-gui/res/cardsfolder/upcoming/thornplate_intimidator.txt b/forge-gui/res/cardsfolder/t/thornplate_intimidator.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thornplate_intimidator.txt rename to forge-gui/res/cardsfolder/t/thornplate_intimidator.txt diff --git a/forge-gui/res/cardsfolder/upcoming/thornvault_forager.txt b/forge-gui/res/cardsfolder/t/thornvault_forager.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thornvault_forager.txt rename to forge-gui/res/cardsfolder/t/thornvault_forager.txt diff --git a/forge-gui/res/cardsfolder/t/thought_rattle.txt b/forge-gui/res/cardsfolder/t/thought_rattle.txt new file mode 100644 index 00000000000..38746458ea0 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/thought_rattle.txt @@ -0,0 +1,10 @@ +Name:Thought Rattle +ManaCost:U B +Types:Sorcery +A:SP$ Reveal | ValidTgts$ Opponent | RevealAllValid$ Card.nonLand+TargetedPlayerCtrl | RememberRevealed$ True | SubAbility$ DBExile | StackDescription$ REP Target opponent_{p:Targeted} & You choose_{p:You} chooses & Exile_{p:You} exiles & your graveyard_{p:You}'s graveyard & seek_they seek | SpellDescription$ Target opponent reveals each nonland card in their hand. You choose one of those cards. Exile that card. Threshold — If seven or more cards are in your graveyard, seek a Rat card. It perpetually gains "This spell costs 1 less to cast." +SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | DefinedPlayer$ Targeted | Chooser$ You | ChangeType$ Card.nonLand | ChangeTypeDesc$ nonland card | Mandatory$ True | SubAbility$ DBClearRemembered | StackDescription$ None +SVar:DBClearRemembered:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBSeek +SVar:DBSeek:DB$ Seek | Condition$ Threshold | Num$ 1 | Type$ Rat | RememberFound$ True | SubAbility$ DBAnimate | StackDescription$ None +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | staticAbilities$ ReduceCost | Duration$ Perpetual | StackDescription$ None +SVar:ReduceCost:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | Description$ This spell costs {1} less to cast. +Oracle:Target opponent reveals each nonland card in their hand. You choose one of those cards. Exile that card.\nThreshold — If seven or more cards are in your graveyard, seek a Rat card. It perpetually gains "This spell costs 1 less to cast." diff --git a/forge-gui/res/cardsfolder/upcoming/thought_shucker.txt b/forge-gui/res/cardsfolder/t/thought_shucker.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thought_shucker.txt rename to forge-gui/res/cardsfolder/t/thought_shucker.txt diff --git a/forge-gui/res/cardsfolder/upcoming/thought_stalker_warlock.txt b/forge-gui/res/cardsfolder/t/thought_stalker_warlock.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thought_stalker_warlock.txt rename to forge-gui/res/cardsfolder/t/thought_stalker_warlock.txt diff --git a/forge-gui/res/cardsfolder/upcoming/thraben_charm.txt b/forge-gui/res/cardsfolder/t/thraben_charm.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thraben_charm.txt rename to forge-gui/res/cardsfolder/t/thraben_charm.txt diff --git a/forge-gui/res/cardsfolder/t/thrasta_tempests_roar.txt b/forge-gui/res/cardsfolder/t/thrasta_tempests_roar.txt index ded5931924a..be16d89a25e 100644 --- a/forge-gui/res/cardsfolder/t/thrasta_tempests_roar.txt +++ b/forge-gui/res/cardsfolder/t/thrasta_tempests_roar.txt @@ -3,7 +3,7 @@ ManaCost:10 G G Types:Legendary Creature Dinosaur PT:7/7 S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {3} less to cast for each other spell cast this turn. -SVar:X:Count$ThisTurnCast_Card.Other/Times.3 +SVar:X:Count$ThisTurnCast_Card/Times.3 K:Trample K:Haste K:Trample:Planeswalker diff --git a/forge-gui/res/cardsfolder/t/three_tree_battalion.txt b/forge-gui/res/cardsfolder/t/three_tree_battalion.txt new file mode 100644 index 00000000000..09badd56669 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/three_tree_battalion.txt @@ -0,0 +1,8 @@ +Name:Three Tree Battalion +ManaCost:3 W +Types:Instant +A:SP$ Dig | DigNum$ 6 | ChangeNum$ 1 | AILogic$ AtOppEOT | Optional$ True | ChangeValid$ Creature.YouCtrl+cmcLE3 | ChangeValidDesc$ creature card with mana value 3 or less | Reveal$ False | DestinationZone$ Battlefield | DestinationZone2$ Library | LibraryPosition$ -1 | RestRandomOrder$ True | RememberChanged$ True | SubAbility$ DBConjure | StackDescription$ REP Look at_{p:You} looks at & your library_their library & You may_{p:You} may & Put the_{p:You} puts the & your library_their library | SpellDescription$ Look at the top six cards of your library. You may put a creature card with mana value 3 or less from among them onto the battlefield, then conjure a duplicate of that card onto the battlefield. The duplicate perpetually has base power and toughness 1/1. Put the rest on the bottom of your library in a random order. +SVar:DBConjure:DB$ MakeCard | Conjure$ True | DefinedName$ Remembered | ImprintMade$ True | Zone$ Battlefield | SubAbility$ DBAnimate | StackDescription$ None +SVar:DBAnimate:DB$ Animate | Defined$ Imprinted | Power$ 1 | Toughness$ 1 | Duration$ Perpetual | SubAbility$ DBCleanup | StackDescription$ None +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True +Oracle:Look at the top six cards of your library. You may put a creature card with mana value 3 or less from among them onto the battlefield, then conjure a duplicate of that card onto the battlefield. The duplicate perpetually has base power and toughness 1/1. Put the rest on the bottom of your library in a random order. diff --git a/forge-gui/res/cardsfolder/upcoming/three_tree_city.txt b/forge-gui/res/cardsfolder/t/three_tree_city.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/three_tree_city.txt rename to forge-gui/res/cardsfolder/t/three_tree_city.txt diff --git a/forge-gui/res/cardsfolder/upcoming/three_tree_mascot.txt b/forge-gui/res/cardsfolder/t/three_tree_mascot.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/three_tree_mascot.txt rename to forge-gui/res/cardsfolder/t/three_tree_mascot.txt diff --git a/forge-gui/res/cardsfolder/upcoming/three_tree_rootweaver.txt b/forge-gui/res/cardsfolder/t/three_tree_rootweaver.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/three_tree_rootweaver.txt rename to forge-gui/res/cardsfolder/t/three_tree_rootweaver.txt diff --git a/forge-gui/res/cardsfolder/upcoming/three_tree_scribe.txt b/forge-gui/res/cardsfolder/t/three_tree_scribe.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/three_tree_scribe.txt rename to forge-gui/res/cardsfolder/t/three_tree_scribe.txt diff --git a/forge-gui/res/cardsfolder/t/thunder_salvo.txt b/forge-gui/res/cardsfolder/t/thunder_salvo.txt index d0ed83eb97b..17f93f35e1c 100644 --- a/forge-gui/res/cardsfolder/t/thunder_salvo.txt +++ b/forge-gui/res/cardsfolder/t/thunder_salvo.txt @@ -2,5 +2,5 @@ Name:Thunder Salvo ManaCost:1 R Types:Instant A:SP$ DealDamage | ValidTgts$ Creature | NumDmg$ X | SpellDescription$ CARDNAME deals X damage to target creature, where X is 2 plus the number of other spells you've cast this turn. -SVar:X:Count$ThisTurnCast_Card.YouCtrl+Other/Plus.2 +SVar:X:Count$ThisTurnCast_Card.YouCtrl+!CastSaSource/Plus.2 Oracle:Thunder Salvo deals X damage to target creature, where X is 2 plus the number of other spells you've cast this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/thundertrap_trainer.txt b/forge-gui/res/cardsfolder/t/thundertrap_trainer.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/thundertrap_trainer.txt rename to forge-gui/res/cardsfolder/t/thundertrap_trainer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/tidecaller_mentor.txt b/forge-gui/res/cardsfolder/t/tidecaller_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tidecaller_mentor.txt rename to forge-gui/res/cardsfolder/t/tidecaller_mentor.txt diff --git a/forge-gui/res/cardsfolder/t/tin_street_gossip.txt b/forge-gui/res/cardsfolder/t/tin_street_gossip.txt index e6083559dfa..c2469121343 100644 --- a/forge-gui/res/cardsfolder/t/tin_street_gossip.txt +++ b/forge-gui/res/cardsfolder/t/tin_street_gossip.txt @@ -3,7 +3,7 @@ ManaCost:2 R G Types:Creature Lizard Advisor PT:4/4 K:Vigilance -A:AB$ Mana | Cost$ T | Produced$ R G | RestrictValid$ FaceDownOrTurnFaceUp | SpellDescription$ Add {R}{G}. Spend this mana only to cast face-down spells or to turn creatures face up. +A:AB$ Mana | Cost$ T | Produced$ R G | RestrictValid$ Spell.isCastFaceDown,Static.isTurnFaceUp+Creature | SpellDescription$ Add {R}{G}. Spend this mana only to cast face-down spells or to turn creatures face up. AI:RemoveDeck:Random DeckHints:Keyword$Morph|Megamorph Oracle:Vigilance\n{T}: Add {R}{G}. Spend this mana only to cast face-down spells or to turn creatures face up. diff --git a/forge-gui/res/cardsfolder/upcoming/towering_viewpoint.txt b/forge-gui/res/cardsfolder/t/towering_viewpoint.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/towering_viewpoint.txt rename to forge-gui/res/cardsfolder/t/towering_viewpoint.txt diff --git a/forge-gui/res/cardsfolder/upcoming/trailtracker_scout.txt b/forge-gui/res/cardsfolder/t/trailtracker_scout.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/trailtracker_scout.txt rename to forge-gui/res/cardsfolder/t/trailtracker_scout.txt diff --git a/forge-gui/res/cardsfolder/upcoming/tranquilize.txt b/forge-gui/res/cardsfolder/t/tranquilize.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/tranquilize.txt rename to forge-gui/res/cardsfolder/t/tranquilize.txt diff --git a/forge-gui/res/cardsfolder/t/transcendence.txt b/forge-gui/res/cardsfolder/t/transcendence.txt index 223c230ca96..ad2ec4a34d0 100644 --- a/forge-gui/res/cardsfolder/t/transcendence.txt +++ b/forge-gui/res/cardsfolder/t/transcendence.txt @@ -1,7 +1,7 @@ Name:Transcendence ManaCost:3 W W W Types:Enchantment -S:Mode$ Continuous | Affected$ You | AddKeyword$ You don't lose the game for having 0 or less life. | Description$ You don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | Description$ You don't lose the game for having 0 or less life. T:Mode$ Always | LifeTotal$ You | LifeAmount$ GE20 | TriggerZones$ Battlefield | Execute$ TrigLoseGame | TriggerDescription$ When you have 20 or more life, you lose the game. T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigLifeGain | TriggerDescription$ Whenever you lose life, you gain 2 life for each 1 life you lost. (Damage dealt to you causes you to lose life.) SVar:TrigLoseGame:DB$ LosesGame | Defined$ You diff --git a/forge-gui/res/cardsfolder/t/traverse_valley.txt b/forge-gui/res/cardsfolder/t/traverse_valley.txt new file mode 100644 index 00000000000..95cb306843b --- /dev/null +++ b/forge-gui/res/cardsfolder/t/traverse_valley.txt @@ -0,0 +1,8 @@ +Name:Traverse Valley +ManaCost:G +Types:Sorcery +K:Kicker:Forage +A:SP$ Seek | Type$ Land.nonBasic | RememberFound$ True | SubAbility$ DBChangeZone | SpellDescription$ Seek a nonbasic land card. +SVar:DBChangeZone:DB$ ChangeZone | Defined$ Remembered | Tapped$ True | Condition$ Kicked | Origin$ Hand | Destination$ Battlefield | SubAbility$ DBCleanup | SpellDescription$ If this spell was kicked, put that card onto the battlefield tapped. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Kicker — Forage.\nSeek a nonbasic land card. If this spell was kicked, put that card onto the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/treeguard_duo.txt b/forge-gui/res/cardsfolder/t/treeguard_duo.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/treeguard_duo.txt rename to forge-gui/res/cardsfolder/t/treeguard_duo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/treetop_sentries.txt b/forge-gui/res/cardsfolder/t/treetop_sentries.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/treetop_sentries.txt rename to forge-gui/res/cardsfolder/t/treetop_sentries.txt diff --git a/forge-gui/res/cardsfolder/upcoming/twenty_toed_toad.txt b/forge-gui/res/cardsfolder/t/twenty_toed_toad.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/twenty_toed_toad.txt rename to forge-gui/res/cardsfolder/t/twenty_toed_toad.txt diff --git a/forge-gui/res/cardsfolder/u/ulamog_the_defiler.txt b/forge-gui/res/cardsfolder/u/ulamog_the_defiler.txt index 5e9d72df1f3..a02f58e67f3 100644 --- a/forge-gui/res/cardsfolder/u/ulamog_the_defiler.txt +++ b/forge-gui/res/cardsfolder/u/ulamog_the_defiler.txt @@ -3,12 +3,12 @@ ManaCost:10 Types:Legendary Creature Eldrazi PT:7/7 K:Ward:Sac<2/Permanent> -T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When you cast this spell, target opponent exiles half their library, rounded up. -SVar:TrigExile:DB$ Dig | ValidTgts$ Opponent | DestinationZone$ Exile | DigNum$ X | ChangeNum$ All -SVar:X:TargetedPlayer$CardsInLibrary/HalfUp +T:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When you cast this spell, target opponent exiles the top of half their library, rounded up. +SVar:TrigExile:DB$ Dig | ValidTgts$ Opponent | DestinationZone$ Exile | DigNum$ Z | ChangeNum$ All +SVar:Z:TargetedPlayer$CardsInLibrary/HalfUp K:etbCounter:P1P1:Y:no Condition:CARDNAME enters with a number of +1/+1 counters on it equal to the greatest mana value among cards in exile. SVar:Y:Count$ValidExile Card$GreatestCMC -S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Annihilator:N | CalcKeywordN$ N | Description$ NICKNAME has annihilator X, where X is the number of +1/+1 counters on it. -SVar:N:Count$CardCounters.P1P1 +S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Annihilator:X | Description$ NICKNAME has annihilator X, where X is the number of +1/+1 counters on it. +SVar:X:Count$CardCounters.P1P1 DeckHas:Ability$Sacrifice|Counters -Oracle:When you cast this spell, target opponent exiles half their library, rounded up.\nWard–Sacrifice two permanents.\nUlamog, the Defiler enters with a number of +1/+1 counters on it equal to the greatest mana value among cards in exile.\nUlamog has annihilator X, where X is the number of +1/+1 counters on it. +Oracle:When you cast this spell, target opponent exiles the top half of their library, rounded up.\nWard–Sacrifice two permanents.\nUlamog, the Defiler enters with a number of +1/+1 counters on it equal to the greatest mana value among cards in exile.\nUlamog has annihilator X, where X is the number of +1/+1 counters on it. diff --git a/forge-gui/res/cardsfolder/u/ulasht_the_hate_seed.txt b/forge-gui/res/cardsfolder/u/ulasht_the_hate_seed.txt index ae934d6403a..6b07d497096 100644 --- a/forge-gui/res/cardsfolder/u/ulasht_the_hate_seed.txt +++ b/forge-gui/res/cardsfolder/u/ulasht_the_hate_seed.txt @@ -3,7 +3,7 @@ ManaCost:2 R G Types:Legendary Creature Hellion Hydra PT:0/0 K:etbCounter:P1P1:X:no Condition:CARDNAME enters with a +1/+1 counter on it for each other red creature you control and a +1/+1 counter on it for each other green creature you control. -A:AB$ DealDamage | Cost$ 1 SubCounter<1/P1P1> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | SpellDescription$ Ulasht deals 1 damage to target creature. +A:AB$ DealDamage | Cost$ 1 SubCounter<1/P1P1> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 1 | SpellDescription$ NICKNAME deals 1 damage to target creature. A:AB$ Token | Cost$ 1 SubCounter<1/P1P1> | TokenAmount$ 1 | TokenScript$ g_1_1_saproling | TokenOwner$ You | SpellDescription$ Create a 1/1 green Saproling creature token. SVar:X:Count$Valid Creature.YouCtrl+Red+Other/Plus.B SVar:B:Count$Valid Creature.YouCtrl+Green+Other diff --git a/forge-gui/res/cardsfolder/upcoming/under_construction_skyscraper.txt b/forge-gui/res/cardsfolder/u/under_construction_skyscraper.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/under_construction_skyscraper.txt rename to forge-gui/res/cardsfolder/u/under_construction_skyscraper.txt diff --git a/forge-gui/res/cardsfolder/u/unholy_heat.txt b/forge-gui/res/cardsfolder/u/unholy_heat.txt index fea47fa88ce..24e9e514701 100644 --- a/forge-gui/res/cardsfolder/u/unholy_heat.txt +++ b/forge-gui/res/cardsfolder/u/unholy_heat.txt @@ -2,6 +2,5 @@ Name:Unholy Heat ManaCost:R Types:Instant A:SP$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | NumDmg$ X | SpellDescription$ CARDNAME deals 2 damage to target creature or planeswalker. Delirium — CARDNAME deals 6 damage instead if there are four or more card types among cards in your graveyard. -SVar:X:Count$Compare Y GE4.6.2 -SVar:Y:Count$ValidGraveyard Card.YouOwn$CardTypes +SVar:X:Count$Delirium.6.2 Oracle:Unholy Heat deals 2 damage to target creature or planeswalker.\nDelirium — Unholy Heat deals 6 damage instead if there are four or more card types among cards in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/a_premonition_of_your_demise.txt b/forge-gui/res/cardsfolder/upcoming/a_premonition_of_your_demise.txt new file mode 100644 index 00000000000..141d9a98e09 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/a_premonition_of_your_demise.txt @@ -0,0 +1,10 @@ +Name:A Premonition of Your Demise +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigRepeatEach | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, reveal the top two cards of your library and put them into your hand. When you reveal one or more nonland cards this way, this scheme deals damage equal to their total mana value to any target. +SVar:DBDig:DB$ Dig | DigNum$ 2 | Reveal$ True | ChangeNum$ All | ChangeValid$ Card | DestinationZone$ Hand | RememberChanged$ True | SubAbility$ DBImmediateTrigger +SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | Execute$ TrigDamage | SubAbility$ DBCleanup | SpellDescription$ When you reveal one or more nonland cards this way, this scheme deals damage equal to their total mana value to any target. +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ X +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$ValidHand Card.IsRemembered+nonLand$SumCMC +Oracle:When you set this scheme in motion, reveal the top two cards of your library and put them into your hand. When you reveal one or more nonland cards this way, this scheme deals damage equal to their total mana value to any target. diff --git a/forge-gui/res/cardsfolder/upcoming/abandoned_campground.txt b/forge-gui/res/cardsfolder/upcoming/abandoned_campground.txt new file mode 100644 index 00000000000..2664abb2417 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/abandoned_campground.txt @@ -0,0 +1,8 @@ +Name:Abandoned Campground +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo W U | SpellDescription$ Add {W} or {U}. +Oracle:Abandoned Campground enters tapped unless a player has 13 or less life.\n{T}: Add {W} or {U}. diff --git a/forge-gui/res/cardsfolder/upcoming/abhorrent_oculus.txt b/forge-gui/res/cardsfolder/upcoming/abhorrent_oculus.txt new file mode 100644 index 00000000000..474b57d5fb3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/abhorrent_oculus.txt @@ -0,0 +1,9 @@ +Name:Abhorrent Oculus +ManaCost:2 U +Types:Creature Eye +PT:5/5 +A:SP$ PermanentCreature | Cost$ 2 U ExileFromGrave<6/Card> +K:Flying +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDread | TriggerDescription$ At the beginning of each opponent's upkeep, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature, and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True +Oracle:As an additional cost to cast this spell, exile six cards from your graveyard.\nFlying\nAt the beginning of each opponent's upkeep, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature, and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/acrobatic_cheerleader.txt b/forge-gui/res/cardsfolder/upcoming/acrobatic_cheerleader.txt new file mode 100644 index 00000000000..73d20ef617c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/acrobatic_cheerleader.txt @@ -0,0 +1,7 @@ +Name:Acrobatic Cheerleader +ManaCost:1 W +Types:Creature Human Survivor +PT:2/2 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigPutCounter | GameActivationLimit$ 1 | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, put a flying counter on it. This ability triggers only once. +SVar:TrigPutCounter:DB$ PutCounter | CounterType$ Flying | CounterNum$ 1 +Oracle:Survival — At the beginning of your second main phase, if Acrobatic Cheerleader is tapped, put a flying counter on it. This ability triggers only once. diff --git a/forge-gui/res/cardsfolder/upcoming/altanak_the_thrice_called.txt b/forge-gui/res/cardsfolder/upcoming/altanak_the_thrice_called.txt new file mode 100644 index 00000000000..2283a154b8b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/altanak_the_thrice_called.txt @@ -0,0 +1,9 @@ +Name:Altanak, the Thrice-Called +ManaCost:5 G G +Types:Legendary Creature Insect Beast +PT:9/9 +K:Trample +T:Mode$ BecomesTarget | ValidTarget$ Card.Self | ValidSource$ SpellAbility.OppCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME becomes the target of a spell or ability an opponent controls, draw a card. +SVar:TrigDraw:DB$ Draw +A:AB$ ChangeZone | Cost$ 1 G Discard<1/CARDNAME> | ActivationZone$ Hand | Origin$ Graveyard | Destination$ Battlefield| TgtPrompt$ Select target land card in your graveyard | ValidTgts$ Land.YouOwn | Tapped$ True | SpellDescription$ Return target land card from your graveyard to the battlefield tapped. +Oracle:Trample\nWhenever Altanak, the Thrice-Called becomes the target of a spell or ability an opponent controls, draw a card.\n{1}{G}, Discard Altanak, the Thrice-Called: Return target land card from your graveyard to the battlefield tapped. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/aminatou_veil_piercer.txt b/forge-gui/res/cardsfolder/upcoming/aminatou_veil_piercer.txt new file mode 100644 index 00000000000..51c1de9eb4a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/aminatou_veil_piercer.txt @@ -0,0 +1,9 @@ +Name:Aminatou, Veil Piercer +ManaCost:1 W U B +Types:Legendary Creature Human Wizard +PT:2/4 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSurveil | TriggerDescription$ At the beginning of your upkeep, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) +SVar:TrigSurveil:DB$ Surveil | Amount$ 2 +S:Mode$ Continuous | Affected$ Card.Enchantment+YouOwn | AffectedZone$ Hand | AddKeyword$ Miracle:CardManaCost | ReduceCost$ 4 | Description$ Each enchantment card in your hand has miracle. Its miracle cost is equal to its mana cost reduced by {4}. (You may cast a card for its miracle cost when you draw it if it's the first card you drew this turn.) +DeckHints:Ability$Graveyard & Type$Enchantment +Oracle:At the beginning of your upkeep, surveil 2. (Look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.)\nEach enchantment card in your hand has miracle. Its miracle cost is equal to its mana cost reduced by {4}. (You may cast a card for its miracle cost when you draw it if it's the first card you drew this turn.) diff --git a/forge-gui/res/cardsfolder/upcoming/appendage_amalgam.txt b/forge-gui/res/cardsfolder/upcoming/appendage_amalgam.txt new file mode 100644 index 00000000000..ac16e9d0da2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/appendage_amalgam.txt @@ -0,0 +1,10 @@ +Name:Appendage Amalgam +ManaCost:2 B +Types:Enchantment Creature Horror +PT:3/2 +K:Flash +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) +SVar:TrigSurveil:DB$ Surveil | Amount$ 1 +SVar:HasAttackEffect:TRUE +DeckHas:Ability$Surveil|Graveyard +Oracle:Flash\nWhenever Appendage Amalgam attacks, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/arabella_abandoned_doll.txt b/forge-gui/res/cardsfolder/upcoming/arabella_abandoned_doll.txt new file mode 100644 index 00000000000..feb4469b869 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/arabella_abandoned_doll.txt @@ -0,0 +1,9 @@ +Name:Arabella, Abandoned Doll +ManaCost:R W +Types:Legendary Artifact Creature Toy +PT:1/3 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDamageAll | TriggerDescription$ Whenever CARDNAME attacks, it deals X damage to each opponent and you gain X life, where X is the number of creatures you control with power 2 or less. +SVar:TrigDamageAll:DB$ DamageAll | ValidPlayers$ Player.Opponent | NumDmg$ X | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ X +SVar:X:Count$Valid Creature.YouCtrl+powerLE2 +Oracle:Whenever Arabella, Abandoned Doll attacks, it deals X damage to each opponent and you gain X life, where X is the number of creatures you control with power 2 or less. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/attack_in_the_box.txt b/forge-gui/res/cardsfolder/upcoming/attack_in_the_box.txt new file mode 100644 index 00000000000..8d0ebe61102 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/attack_in_the_box.txt @@ -0,0 +1,7 @@ +Name:Attack-in-the-Box +ManaCost:3 +Types:Artifact Creature Toy +PT:2/4 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may have it get +4/+0 until end of turn. If you do, sacrifice it at the beginning of the next end step. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 4 | NumDef$ 1 | AtEOT$ Sacrifice +Oracle:Whenever Attack-in-the-box attacks, you may have it get +4/+0 until end of turn. If you do, sacrifice it at the beginning of the next end step. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/balustrade_wurm.txt b/forge-gui/res/cardsfolder/upcoming/balustrade_wurm.txt new file mode 100644 index 00000000000..8efe28611c0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/balustrade_wurm.txt @@ -0,0 +1,11 @@ +Name:Balustrade Wurm +ManaCost:3 G G +Types:Creature Wurm +PT:5/5 +R:Event$ Counter | ValidCard$ Card.Self | ValidSA$ Spell | Layer$ CantHappen | Description$ This spell can't be countered. +K:Trample +K:Haste +A:AB$ ChangeZone | Cost$ 2 G G | PrecostDesc$ Delirium — | Activation$ Delirium | Origin$ Graveyard | Destination$ Battlefield | WithCountersType$ FINALITY | ActivationZone$ Graveyard | SorcerySpeed$ True | SpellDescription$ Return CARDNAME from your graveyard to the battlefield with a finality counter on it. Activate only if there are four or more card types among cards in your graveyard and only as a sorcery. +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:This spell can't be countered.\nTrample, haste\nDelirium — {2}{G}{G}: Return Balustrade Wurm from your graveyard to the battlefield with a finality counter on it. Activate only if there are four or more card types among cards in your graveyard and only as a sorcery. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/baseball_bat.txt b/forge-gui/res/cardsfolder/upcoming/baseball_bat.txt new file mode 100644 index 00000000000..0295afea282 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/baseball_bat.txt @@ -0,0 +1,10 @@ +Name:Baseball Bat +ManaCost:G W +Types:Artifact Equipment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAttach | TriggerDescription$ When CARDNAME enters, attach it to target creature you control. +SVar:TrigAttach:DB$ Attach | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Equipped creature gets +1/+1. +T:Mode$ Attacks | ValidCard$ Card.AttachedBy | Execute$ TrigTap | TriggerDescription$ Whenever equipped creature attacks, tap up to one target creature. +SVar:TrigTap:DB$ Tap | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature | TgtPrompt$ Select target creature +K:Equip:3 +Oracle:When Baseball Bat enters, attach it to target creature you control.\nEquipped creature gets +1/+1.\nWhenever equipped creature attacks, tap up to one target creature.\nEquip {3} ({3}: Attach to target creature you control. Equip only as a sorcery.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/bashful_beastie.txt b/forge-gui/res/cardsfolder/upcoming/bashful_beastie.txt new file mode 100644 index 00000000000..6eaa13fbcff --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bashful_beastie.txt @@ -0,0 +1,7 @@ +Name:Bashful Beastie +ManaCost:4 G +Types:Creature Beast +PT:5/4 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME dies, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You +Oracle:When Bashful Beastie dies, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/bear_trap.txt b/forge-gui/res/cardsfolder/upcoming/bear_trap.txt new file mode 100644 index 00000000000..8cf1ccb3787 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bear_trap.txt @@ -0,0 +1,7 @@ +Name:Bear Trap +ManaCost:1 +Types:Artifact +K:Flash +A:AB$ DealDamage | Cost$ 3 T Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 3 | SpellDescription$ It deals 3 damage to target creature. +DeckHas:Ability$Sacrifice +Oracle:Flash\n{3}, {T}, Sacrifice Bear Trap: It deals 3 damage to target creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/betrayers_bargain.txt b/forge-gui/res/cardsfolder/upcoming/betrayers_bargain.txt new file mode 100644 index 00000000000..ccbc6ae9ee4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/betrayers_bargain.txt @@ -0,0 +1,6 @@ +Name:Betrayer's Bargain +ManaCost:1 R +Types:Instant +K:AlternateAdditionalCost:Sac<1/Creature;Enchantment/creature or enchantment>:2 +A:SP$ DealDamage | NumDmg$ 5 | ValidTgts$ Creature | TgtPrompt$ Select target creature | ReplaceDyingDefined$ Targeted | SpellDescription$ CARDNAME deals 5 damage to target creature. If that creature would die this turn, exile it instead. +Oracle:As an additional cost to cast this spell, sacrifice a creature or enchantment or pay {2}.\nBetrayer's Bargain deals 5 damage to target creature. If that creature would die this turn, exile it instead. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/blazemire_verge.txt b/forge-gui/res/cardsfolder/upcoming/blazemire_verge.txt new file mode 100644 index 00000000000..6e87033702f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/blazemire_verge.txt @@ -0,0 +1,6 @@ +Name:Blazemire Verge +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}. +A:AB$ Mana | Cost$ T | Produced$ R | IsPresent$ Swamp.YouCtrl,Mountain.YouCtrl | SpellDescription$ Add {R}. Activate only if you control a Swamp or a Mountain. +Oracle:{T}: Add {B}.\n{T}: Add {R}. Activate only if you control a Swamp or a Mountain. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/bleeding_woods.txt b/forge-gui/res/cardsfolder/upcoming/bleeding_woods.txt new file mode 100644 index 00000000000..6ca758582f5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bleeding_woods.txt @@ -0,0 +1,8 @@ +Name:Bleeding Woods +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo R G | SpellDescription$ Add {R} or {G}. +Oracle:Bleeding Woods enters tapped unless a player has 13 or less life.\n{T}: Add {R} or {G}. diff --git a/forge-gui/res/cardsfolder/upcoming/boilerbilges_ripper.txt b/forge-gui/res/cardsfolder/upcoming/boilerbilges_ripper.txt new file mode 100644 index 00000000000..639af3350f5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/boilerbilges_ripper.txt @@ -0,0 +1,8 @@ +Name:Boilerbilges Ripper +ManaCost:4 R +Types:Creature Human Assassin +PT:4/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters, you may sacrifice another creature or enchantment. When you do, CARDNAME deals 2 damage to any target. +SVar:TrigSac:AB$ ImmediateTrigger | Cost$ Sac<1/Creature.Other;Enchantment.Other/another creature or enchantment> | Execute$ TrigDealDamage | TriggerDescription$ When you do, CARDNAME deals 2 damage to any target. +SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 2 +Oracle:When Boilerbilges Ripper enters, you may sacrifice another creature or enchantment. When you do, Boilerbilges Ripper deals 2 damage to any target. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/break_down_the_door.txt b/forge-gui/res/cardsfolder/upcoming/break_down_the_door.txt new file mode 100644 index 00000000000..922b4cad445 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/break_down_the_door.txt @@ -0,0 +1,8 @@ +Name:Break Down the Door +ManaCost:2 G +Types:Instant +A:SP$ Charm | CharmNum$ 1 | Choices$ DBExileArtifact,DBExileEnchantment,DBDread +SVar:DBExileArtifact:DB$ ChangeZone | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target artifact. +SVar:DBExileEnchantment:DB$ ChangeZone | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target enchantment. +SVar:DBDread:DB$ Manifest | Dread$ True | SpellDescription$ Manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +Oracle:Choose one —\n• Exile target artifact.\n• Exile target enchantment.\n• Manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/cathartic_parting.txt b/forge-gui/res/cardsfolder/upcoming/cathartic_parting.txt new file mode 100644 index 00000000000..f7a9413083d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cathartic_parting.txt @@ -0,0 +1,6 @@ +Name:Cathartic Parting +ManaCost:1 G +Types:Sorcery +A:SP$ ChangeZone | Origin$ Battlefield | Destination$ Library | ValidTgts$ Artifact.OppCtrl,Enchantment.OppCtrl | TgtPrompt$ Select target artifact or enchantment an opponent controls | SubAbility$ DBChangeZone | Shuffle$ True | SpellDescription$ The owner of target artifact or enchantment an opponent controls shuffles it into their library. You may shuffle up to four target cards from your graveyard into your library. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Library | ValidTgts$ Card.YouOwn | TgtPrompt$ Select target card from your graveyard | TargetMin$ 0 | TargetMax$ 4 | Shuffle$ True | ShuffleNonMandatory$ True +Oracle:The owner of target artifact or enchantment an opponent controls shuffles it into their library. You may shuffle up to four target cards from your graveyard into your library. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/cautious_survivor.txt b/forge-gui/res/cardsfolder/upcoming/cautious_survivor.txt new file mode 100644 index 00000000000..31125d8b94a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cautious_survivor.txt @@ -0,0 +1,7 @@ +Name:Cautious Survivor +Types:Creature Elf Survivor +ManaCost:3 G +PT:4/4 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, you gain 2 life. +SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 +Oracle:Survival — At the beginning of your second main phase, if Cautious Survivor is tapped, you gain 2 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/chaos_is_my_plaything.txt b/forge-gui/res/cardsfolder/upcoming/chaos_is_my_plaything.txt new file mode 100644 index 00000000000..a8d72c808e1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/chaos_is_my_plaything.txt @@ -0,0 +1,8 @@ +Name:Chaos Is My Plaything +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, for each opponent, exile target permanent that player controls. Then each player reveals cards from the top of their library until they reveal a permanent card, puts it onto the battlefield, and puts the rest on the bottom of their library in a random order. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select up to one target creature each opponent controls | TargetMin$ 0 | TargetMax$ OneEach | TargetsForEachPlayer$ True | SubAbility$ DBDigUntil +SVar:DBDigUntil:DB$ DigUntil | Defined$ Player | Valid$ Permanent | ValidDescription$ permanent | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | RevealRandomOrder$ True | FoundDestination$ Battlefield +SVar:OneEach:PlayerCountOpponents$Amount +Oracle:When you set this scheme in motion, for each opponent, exile target permanent that player controls. Then each player reveals cards from the top of their library until they reveal a permanent card, puts it onto the battlefield, and puts the rest on the bottom of their library in a random order. diff --git a/forge-gui/res/cardsfolder/upcoming/clammy_prowler.txt b/forge-gui/res/cardsfolder/upcoming/clammy_prowler.txt new file mode 100644 index 00000000000..3ef172b128e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/clammy_prowler.txt @@ -0,0 +1,8 @@ +Name:Clammy Prowler +ManaCost:3 U +Types:Enchantment Creature Horror +PT:2/5 +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, another target attacking creature can't be blocked this turn. +SVar:TrigPump:DB$ Effect | ValidTgts$ Creature.Other+attacking | TgtPrompt$ Select another target attacking non-Human creature | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | StaticAbilities$ Unblockable +SVar:Unblockable:Mode$ CantBlockBy | ValidAttacker$ Card.IsRemembered | Description$ This creature can't be blocked this turn. +Oracle:Whenever Clammy Prowler attacks, another target attacking creature can't be blocked this turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/clockwork_percussionist.txt b/forge-gui/res/cardsfolder/upcoming/clockwork_percussionist.txt new file mode 100644 index 00000000000..0c01dbacfe1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/clockwork_percussionist.txt @@ -0,0 +1,11 @@ +Name:Clockwork Percussionist +ManaCost:R +Types:Artifact Creature Monkey Toy +PT:1/1 +K:Haste +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME dies, exile the top card of your library. You may play it until the end of your next turn. +SVar:TrigExile:DB$ Dig | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ STPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn +SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play that card until the end of your next turn. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Haste\nWhen Clockwork Percussionist dies, exile the top card of your library. You may play it until the end of your next turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/commune_with_evil.txt b/forge-gui/res/cardsfolder/upcoming/commune_with_evil.txt new file mode 100644 index 00000000000..01d49a67a14 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/commune_with_evil.txt @@ -0,0 +1,7 @@ +Name:Commune with Evil +ManaCost:2 B +Types:Sorcery +A:SP$ Dig | DigNum$ 4 | ChangeNum$ 1 | DestinationZone2$ Graveyard | StackDescription$ SpellDescription | SubAbility$ DBGainLife | SpellDescription$ Look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. You gain 3 life. +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 3 +DeckHas:Ability$Graveyard +Oracle:Look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. You gain 3 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/conductive_machete.txt b/forge-gui/res/cardsfolder/upcoming/conductive_machete.txt new file mode 100644 index 00000000000..936683553dd --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/conductive_machete.txt @@ -0,0 +1,10 @@ +Name:Conductive Machete +ManaCost:4 +Types:Artifact Equipment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread, then attach CARDNAME to that creature. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You | RememberManifested$ True | SubAbility$ DBAttach +SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 1 | Description$ Equipped creature gets +2/+1. +K:Equip:4 +Oracle:When Conductive Machete enters, manifest dread, then attach Conductive Machete to that creature. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\nEquipped creature gets +2/+1.\nEquip {4} \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/coordinated_clobbering.txt b/forge-gui/res/cardsfolder/upcoming/coordinated_clobbering.txt new file mode 100644 index 00000000000..a45a75b8706 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/coordinated_clobbering.txt @@ -0,0 +1,6 @@ +Name:Coordinated Clobbering +ManaCost:G +Types:Sorcery +A:SP$ Tap | TgtPrompt$ Select target untapped creature you control | ValidTgts$ Creature.untapped+YouCtrl | TargetMin$ 1 | TargetMax$ 2 | SubAbility$ DBEachDamage | SpellDescription$ Tap one or two target untapped creatures you control. They each deal damage equal to their power to target creature an opponent controls. +SVar:DBEachDamage:DB$ EachDamage | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | DefinedDamagers$ ParentTarget | NumDmg$ Count$CardPower +Oracle:Tap one or two target untapped creatures you control. They each deal damage equal to their power to target creature an opponent controls. diff --git a/forge-gui/res/cardsfolder/upcoming/cryptid_inspector.txt b/forge-gui/res/cardsfolder/upcoming/cryptid_inspector.txt new file mode 100644 index 00000000000..00a0484e3bd --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cryptid_inspector.txt @@ -0,0 +1,9 @@ +Name:Cryptid Inspector +ManaCost:2 G +Types:Creature Elf Warrior +PT:2/3 +K:Vigilance +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Permanent.faceDown+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever a face-down permanent you control enters and whenever CARDNAME or another permanent you control is turned face up, put a +1/+1 counter on CARDNAME. +T:Mode$ TurnFaceUp | ValidCard$ Card.Self,Permanent.Other+YouCtrl | Secondary$ True | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever a face-down permanent you control enters and whenever CARDNAME or another permanent you control is turned face up, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 +Oracle:Vigilance\nWhenever a face-down permanent you control enters and whenever Cryptid Inspector or another permanent you control is turned face up, put a +1/+1 counter on Cryptid Inspector. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/cult_healer.txt b/forge-gui/res/cardsfolder/upcoming/cult_healer.txt new file mode 100644 index 00000000000..70d35d3a0be --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cult_healer.txt @@ -0,0 +1,9 @@ +Name:Cult Healer +ManaCost:2 W +Types:Creature Human Doctor +PT:3/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gains lifelink until end of turn. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gains lifelink until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Lifelink +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Cult Healer gains lifelink until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/curator_beastie.txt b/forge-gui/res/cardsfolder/upcoming/curator_beastie.txt new file mode 100644 index 00000000000..75f37ca7466 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/curator_beastie.txt @@ -0,0 +1,12 @@ +Name:Curator Beastie +ManaCost:4 G G +Types:Creature Beast +PT:6/6 +K:Reach +K:ETBReplacement:Other:AddExtraCounter:Mandatory:Battlefield:Creature.Colorless+YouCtrl +SVar:AddExtraCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Colorless creatures you control enter with two additional +1/+1 counters on them. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ Whenever CARDNAME enters or attacks, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +T:Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True | Execute$ TrigDread | TriggerDescription$ Whenever CARDNAME enters or attacks, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True +DeckHas:Ability$Counters +Oracle:Reach\nColorless creatures you control enter with two additional +1/+1 counters on them.\nWhenever Curator Beastie enters or attacks, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/cursed_windbreaker.txt b/forge-gui/res/cardsfolder/upcoming/cursed_windbreaker.txt new file mode 100644 index 00000000000..f28e4926cb8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cursed_windbreaker.txt @@ -0,0 +1,10 @@ +Name:Cursed Windbreaker +ManaCost:2 U +Types:Artifact Equipment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread, then attach CARDNAME to that creature. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You | RememberManifested$ True | SubAbility$ DBAttach +SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddKeyword$ Flying | Description$ Equipped creature has flying. +K:Equip:3 +Oracle:When Cursed Windbreaker enters, manifest dread, then attach Cursed Windbreaker to that creature. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\nEquipped creature has flying.\nEquip {3} \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/cynical_loner.txt b/forge-gui/res/cardsfolder/upcoming/cynical_loner.txt new file mode 100644 index 00000000000..88154cb2994 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cynical_loner.txt @@ -0,0 +1,8 @@ +Name:Cynical Loner +Types:Creature Human Survivor +ManaCost:1 B +PT:3/1 +S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.Glimmer | Description$ CARDNAME can't be blocked by Glimmers. +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigChangeZone | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, you may search your library for a card, put it into your graveyard, then shuffle. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Library | Destination$ Graveyard | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True +Oracle:Cynical Loner can't be blocked by Glimmers.\nSurvival — At the beginning of your second main phase, if Cynical Loner is tapped, you may search your library for a card, put it into your graveyard, then shuffle. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/daggermaw_megalodon.txt b/forge-gui/res/cardsfolder/upcoming/daggermaw_megalodon.txt new file mode 100644 index 00000000000..a8ebc0e6291 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/daggermaw_megalodon.txt @@ -0,0 +1,8 @@ +Name:Daggermaw Megalodon +ManaCost:4 U U +Types:Creature Shark +PT:5/7 +K:Vigilance +K:TypeCycling:Island:2 +DeckHas:Ability$Discard +Oracle:Vigilance\nIslandcycling {2} ({2}, Discard this card: Search your library for an Island card, reveal it, put it into your hand, then shuffle.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/dark_wings_bring_your_downfall.txt b/forge-gui/res/cardsfolder/upcoming/dark_wings_bring_your_downfall.txt new file mode 100644 index 00000000000..0af2e954750 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dark_wings_bring_your_downfall.txt @@ -0,0 +1,9 @@ +Name:Dark Wings Bring Your Downfall +ManaCost:no cost +Types:Ongoing Scheme +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigToken | TriggerZones$ Command | TriggerDescription$ Whenever you attack, create a 5/5 black Demon creature token with flying that's tapped and attacking. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ b_5_5_demon_flying | TokenOwner$ You | TokenTapped$ True | TokenAttacking$ True +T:Mode$ Phase | Phase$ End of Turn | CheckSVar$ X | SVarCompare$ GE2 | TriggerZones$ Command | Execute$ TrigAbandon | TriggerDescription$ At the beginning of each end step, if two or more creatures died under your control this turn, abandon this scheme. +SVar:TrigAbandon:DB$ Abandon +SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature.YouCtrl +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nWhenever you attack, create a 5/5 black Demon creature token with flying that's tapped and attacking.\nAt the beginning of each end step, if two or more creatures died under your control this turn, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/dashing_bloodsucker.txt b/forge-gui/res/cardsfolder/upcoming/dashing_bloodsucker.txt new file mode 100644 index 00000000000..58f513604b1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dashing_bloodsucker.txt @@ -0,0 +1,9 @@ +Name:Dashing Bloodsucker +ManaCost:3 B +Types:Creature Vampire Warrior +PT:2/5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 and gains lifelink until end of turn. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ $ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 and gains lifelink until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 2 | KW$ Lifelink +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Dashing Bloodsucker gets +2/+0 and gains lifelink until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/defiant_survivor.txt b/forge-gui/res/cardsfolder/upcoming/defiant_survivor.txt new file mode 100644 index 00000000000..cbb94052ca4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/defiant_survivor.txt @@ -0,0 +1,7 @@ +Name:Defiant Survivor +Types:Creature Human Survivor +ManaCost:2 G +PT:3/2 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigDread | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True +Oracle:Survival — At the beginning of your second main phase, if Defiant Survivor is tapped, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/demolisher_spawn.txt b/forge-gui/res/cardsfolder/upcoming/demolisher_spawn.txt new file mode 100644 index 00000000000..78d2e7e8a17 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/demolisher_spawn.txt @@ -0,0 +1,12 @@ +Name:Demolisher Spawn +ManaCost:5 G G +Types:Enchantment Creature Horror +PT:7/7 +K:Trample +K:Haste +T:Mode$ Attacks | ValidCard$ Card.Self | Delirium$ True | Execute$ TrigPumpAll | TriggerDescription$ Delirium — Whenever CARDNAME attacks, if there are four or more card types among cards in your graveyard, other attacking creatures get +4/+4 until end of turn. +SVar:TrigPumpAll:DB$ PumpAll | ValidCards$ Creature.attacking+Other | NumAtt$ 4 | NumDef$ 4 +SVar:HasAttackEffect:TRUE +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Trample, haste\nDelirium — Whenever Demolisher Spawn attacks, if there are four or more card types among cards in your graveyard, other attacking creatures get +4/+4 until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/demonic_counsel.txt b/forge-gui/res/cardsfolder/upcoming/demonic_counsel.txt new file mode 100644 index 00000000000..997e95e54d6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/demonic_counsel.txt @@ -0,0 +1,9 @@ +Name:Demonic Counsel +ManaCost:1 B +Types:Sorcery +A:SP$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Demon | ChangeNum$ 1 | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ0 | SubAbility$ DBChangeZone | SpellDescription$ Search your library for a Demon card, reveal it, put it into your hand, then shuffle. Delirium — If there are four or more card types among cards in your graveyard, instead search your library for any card, put it into your hand, then shuffle. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 +SVar:X:Count$Delirium.1.0 +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Search your library for a Demon card, reveal it, put it into your hand, then shuffle.\nDelirium — If there are four or more card types among cards in your graveyard, instead search your library for any card, put it into your hand, then shuffle. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/disturbing_mirth.txt b/forge-gui/res/cardsfolder/upcoming/disturbing_mirth.txt new file mode 100644 index 00000000000..6a0256da67a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/disturbing_mirth.txt @@ -0,0 +1,9 @@ +Name:Disturbing Mirth +ManaCost:B R +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters, you may sacrifice another enchantment or creature. If you do, draw two cards. +SVar:TrigDraw:AB$ Draw | Cost$ Sac<1/Enchantment.Other,Creature.Other/another enchantment or creature> | NumCards$ 2 +T:Mode$ Sacrificed | ValidPlayer$ You | ValidCard$ Card.Self | Execute$ TrigDread | TriggerZones$ Battlefield | TriggerDescription$ When you sacrifice CARDNAME, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You +DeckHas:Ability$Sacrifice +Oracle:When Disturbing Mirth enters, you may sacrifice another enchantment or creature. If you do, draw two cards.\nWhen you sacrifice Disturbing Mirth, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/diversion_specialist.txt b/forge-gui/res/cardsfolder/upcoming/diversion_specialist.txt new file mode 100644 index 00000000000..80efc2acc86 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/diversion_specialist.txt @@ -0,0 +1,10 @@ +Name:Diversion Specialist +ManaCost:3 R +Types:Creature Human Warrior +PT:4/3 +K:Menace +A:AB$ Dig | Cost$ 1 Sac<1/Creature.Other;Enchantment.Other/another creature or enchantment> | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Exile the top card of your library. You may play that card this turn. +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBCleanup | ForgetOnMoved$ Exile +SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play remembered card. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Menace (This creature can't be blocked except by two or more creatures)\n{1}, Sacrifice another creature or enchantment: Exile the top card of your library. You may play that card this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/drag_to_the_roots.txt b/forge-gui/res/cardsfolder/upcoming/drag_to_the_roots.txt new file mode 100644 index 00000000000..45ff149116e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/drag_to_the_roots.txt @@ -0,0 +1,6 @@ +Name:Drag to the Roots +ManaCost:2 B G +Types:Instant +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 2 | EffectZone$ All | Condition$ Delirium | Description$ Delirium — This spell costs {2} less to cast if there are four or more card types among cards in your graveyard. +A:SP$ Destroy | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | SpellDescription$ Destroy target nonland permanent. +Oracle:Delirium — This spell costs {2} less to cast if there are four or more card types among cards in your graveyard.\nDestroy target nonland permanent. diff --git a/forge-gui/res/cardsfolder/upcoming/duskmourns_domination.txt b/forge-gui/res/cardsfolder/upcoming/duskmourns_domination.txt new file mode 100644 index 00000000000..9a1b16d3f9c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/duskmourns_domination.txt @@ -0,0 +1,8 @@ +Name:Duskmourn's Domination +ManaCost:4 U U +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | Cost$ 4 U U | ValidTgts$ Creature | AILogic$ GainControl +S:Mode$ Continuous | Affected$ Card.EnchantedBy | GainControl$ You | Description$ You control enchanted creature. +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ -3 | RemoveAllAbilities$ True | Description$ Enchanted creature gets -3/-0 and loses all abilities. +Oracle:Enchant creature\nYou control enchanted creature.\nEnchanted creature gets -3/-0 and loses all abilities. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/emerge_from_the_cocoon.txt b/forge-gui/res/cardsfolder/upcoming/emerge_from_the_cocoon.txt new file mode 100644 index 00000000000..42d2c71ee9d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/emerge_from_the_cocoon.txt @@ -0,0 +1,7 @@ +Name:Emerge from the Cocoon +ManaCost:4 W +Types:Sorcery +A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouOwn | SubAbility$ DBGainLife | SpellDescription$ Return target creature card from your graveyard to the battlefield. You gain 3 life. +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 3 +DeckHas:Ability$Graveyard +Oracle:Return target creature card from your graveyard to the battlefield. You gain 3 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/enduring_courage.txt b/forge-gui/res/cardsfolder/upcoming/enduring_courage.txt new file mode 100644 index 00000000000..e09ae5cdd20 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/enduring_courage.txt @@ -0,0 +1,10 @@ +Name:Enduring Courage +ManaCost:2 R R +Types:Enchantment Creature Dog Glimmer +PT:3/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever another creature you control enters, it gets +2/+0 and gains haste until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ TriggeredCardLKICopy | NumAtt$ +2 | KW$ Haste +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+Creature | Execute$ DBReturn | TriggerDescription$ When CARDNAME dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) +SVar:DBReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | AnimateSubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Enchantment | RemoveCardTypes$ True | Duration$ Permanent +Oracle:Whenever another creature you control enters, it gets +2/+0 and gains haste until end of turn.\nWhen Enduring Courage dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/enduring_curiosity.txt b/forge-gui/res/cardsfolder/upcoming/enduring_curiosity.txt new file mode 100644 index 00000000000..f1f605991d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/enduring_curiosity.txt @@ -0,0 +1,11 @@ +Name:Enduring Curiosity +ManaCost:2 U U +Types:Enchantment Creature Cat Glimmer +PT:4/3 +K:Flash +T:Mode$ DamageDone | ValidSource$ Creature.YouCtrl | ValidTarget$ Player | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a creature you control deals combat damage to a player, draw a card. +SVar:TrigDraw:DB$ Draw | NumCards$ 1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+Creature | Execute$ DBReturn | TriggerDescription$ When CARDNAME dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) +SVar:DBReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | AnimateSubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Enchantment | RemoveCardTypes$ True | Duration$ Permanent +Oracle:Flash\nWhenever a creature you control deals combat damage to a player, draw a card.\nWhen Enduring Curiosity dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/enduring_innocence.txt b/forge-gui/res/cardsfolder/upcoming/enduring_innocence.txt new file mode 100644 index 00000000000..88040f8bd22 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/enduring_innocence.txt @@ -0,0 +1,12 @@ +Name:Enduring Innocence +ManaCost:1 W W +Types:Enchantment Creature Sheep Glimmer +PT:2/1 +K:Lifelink +T:Mode$ ChangesZoneAll | ValidCards$ Creature.powerLE2+YouCtrl+Other | Destination$ Battlefield | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigDraw | TriggerDescription$ Whenever one or more other creatures you control with power 2 or less enter, draw a card. This ability triggers only once each turn. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+Creature | Execute$ DBReturn | TriggerDescription$ When CARDNAME dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) +SVar:DBReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | AnimateSubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Enchantment | RemoveCardTypes$ True | Duration$ Permanent +SVar:BuffedBy:Creature.powerLE2 +Oracle:Lifelink\nWhenever one or more other creatures you control with power 2 or less enter, draw a card. This ability triggers only once each turn.\nWhen Enduring Innocence dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/enduring_vitality.txt b/forge-gui/res/cardsfolder/upcoming/enduring_vitality.txt new file mode 100644 index 00000000000..5a361149191 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/enduring_vitality.txt @@ -0,0 +1,11 @@ +Name:Enduring Vitality +ManaCost:1 G G +Types:Enchantment Creature Elk Glimmer +PT:3/3 +K:Vigilance +S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddAbility$ AnyMana | Description$ Creatures you control have "{T}: Add one mana of any color." +SVar:AnyMana:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+Creature | Execute$ DBReturn | TriggerDescription$ When CARDNAME dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) +SVar:DBReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | AnimateSubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Enchantment | RemoveCardTypes$ True | Duration$ Permanent +Oracle:Creatures you control have "{T}: Add one mana of any color."\nWhen Enduring Vitality dies, if it was a creature, return it to the battlefield under its owner's control. It's an enchantment. (It's not a creature.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/erratic_apparition.txt b/forge-gui/res/cardsfolder/upcoming/erratic_apparition.txt new file mode 100644 index 00000000000..b8b227ea1e8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/erratic_apparition.txt @@ -0,0 +1,11 @@ +Name:Erratic Apparition +ManaCost:2 U +Types:Creature Spirit +PT:1/3 +K:Flying +K:Vigilance +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +1/+1 until end of turn. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +1/+1 until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature | NumAtt$ 1 | NumDef$ 1 +DeckNeeds:Type$Enchantment +Oracle:Flying, vigilance\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Erratic Apparition gets +1/+1 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/etched_cornfield.txt b/forge-gui/res/cardsfolder/upcoming/etched_cornfield.txt new file mode 100644 index 00000000000..ac666d37bb5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/etched_cornfield.txt @@ -0,0 +1,8 @@ +Name:Etched Cornfield +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo G W | SpellDescription$ Add {G} or {W}. +Oracle:Etched Cornfield enters tapped unless a player has 13 or less life.\n{T}: Add {G} or {W}. diff --git a/forge-gui/res/cardsfolder/upcoming/exorcise.txt b/forge-gui/res/cardsfolder/upcoming/exorcise.txt new file mode 100644 index 00000000000..872a8a7d0a2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/exorcise.txt @@ -0,0 +1,5 @@ +Name:Exorcise +ManaCost:1 W +Types:Sorcery +A:SP$ ChangeZone | ValidTgts$ Artifact,Enchantment,Creature.powerGE4 | TgtPrompt$ Select target artifact, enchantment, or creature with power 4 or greater | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target artifact, enchantment, or creature with power 4 or greater. +Oracle:Exile target artifact, enchantment, or creature with power 4 or greater. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fanatic_of_the_harrowing.txt b/forge-gui/res/cardsfolder/upcoming/fanatic_of_the_harrowing.txt new file mode 100644 index 00000000000..368b30d2f13 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fanatic_of_the_harrowing.txt @@ -0,0 +1,10 @@ +Name:Fanatic of the Harrowing +ManaCost:3 B +Types:Creature Human Cleric +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters, each player discards a card. If you discarded a card this way, draw a card. +SVar:TrigDiscard:DB$ Discard | Defined$ Player | NumCards$ 1 | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ You | ConditionDefined$ Remembered | ConditionPresent$ Card.YouOwn | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:AIPreference:DiscardCost$Card.cmcLE1 +Oracle:When Fanatic of the Harrowing enters, each player discards a card. If you discarded a card this way, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_abduction.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_abduction.txt new file mode 100644 index 00000000000..e27997faeff --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_abduction.txt @@ -0,0 +1,11 @@ +Name:Fear of Abduction +ManaCost:4 W W +Types:Enchantment Creature Nightmare +PT:5/5 +A:SP$ PermanentCreature | Cost$ 4 W W Exile<1/Creature> +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target creature an opponent controls. +SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME leaves the battlefield, put each card exiled with it into its owner's hand. +SVar:TrigReturn:DB$ ChangeZoneAll | ChangeType$ Card.ExiledWithSource | Origin$ Exile | Destination$ Hand +Oracle:As an additional cost to cast this spell, exile a creature you control.\nFlying\nWhen Fear of Abduction enters, exile target creature an opponent controls.\nWhen Fear of Abduction leaves the battlefield, put each card exiled with it into its owner's hand. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_being_hunted.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_being_hunted.txt new file mode 100644 index 00000000000..bfb31376339 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_being_hunted.txt @@ -0,0 +1,7 @@ +Name:Fear of Being Hunted +ManaCost:1 R R +Types:Enchantment Creature Nightmare +PT:4/2 +K:Haste +K:CARDNAME must be blocked if able. +Oracle:Haste\nFear of Being Hunted must be blocked if able. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_burning_alive.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_burning_alive.txt new file mode 100644 index 00000000000..9cf6f0397d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_burning_alive.txt @@ -0,0 +1,10 @@ +Name:Fear of Burning Alive +ManaCost:4 R R +Types:Enchantment Creature Nightmare +PT:4/4 +T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDamageAll | TriggerDescription$ When CARDNAME enters, it deals 4 damage to each opponent. +SVar:TrigDamageAll:DB$ DamageAll | ValidPlayers$ Player.Opponent | NumDmg$ 4 +T:Mode$ DamageDone | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Opponent | CombatDamage$ False | TriggerZones$ Battlefield | Delirium$ True | Execute$ TrigDmg | TriggerDescription$ Delirium — Whenever a source you control deals noncombat damage to an opponent, if there are four or more card types among cards in your graveyard, CARDNAME deals that amount of damage to target creature that player controls. +SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature that player controls | TargetsWithDefinedController$ TriggeredTarget | NumDmg$ X +SVar:X:TriggerCount$DamageAmount +Oracle:When Fear of Burning Alive enters, it deals 4 damage to each opponent.\nDelirium — Whenever a source you control deals noncombat damage to an opponent, if there are four or more card types among cards in your graveyard, Fear of Burning Alive deals that amount of damage to target creature that player controls. diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_exposure.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_exposure.txt new file mode 100644 index 00000000000..2bff7dd6b40 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_exposure.txt @@ -0,0 +1,7 @@ +Name:Fear of Exposure +ManaCost:2 G +Types:Enchantment Creature Nightmare +PT:5/4 +A:SP$ PermanentCreature | Cost$ 2 G tapXType<2/Creature;Land/creatures and/or lands> +K:Trample +Oracle:As an additional cost to cast this spell, tap two untapped creatures and/or lands you control.\nTrample \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_failed_tests.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_failed_tests.txt new file mode 100644 index 00000000000..687a3addacf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_failed_tests.txt @@ -0,0 +1,8 @@ +Name:Fear of Failed Tests +ManaCost:4 U +Types:Enchantment Creature Nightmare +PT:2/7 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDraw | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, draw that many cards. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X +SVar:X:TriggerCount$DamageAmount +Oracle:Whenever Fear of Failed Tests deals combat damage to a player, draw that many cards. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_falling.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_falling.txt new file mode 100644 index 00000000000..74243868e30 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_falling.txt @@ -0,0 +1,10 @@ +Name:Fear of Falling +ManaCost:3 U U +Types:Enchantment Creature Nightmare +PT:4/4 +K:Flying +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, target creature defending player controls gets -2/-0 and loses flying until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target creature defending player controls | NumAtt$ -2 | IsCurse$ True | SubAbility$ DBDebuff +SVar:DBDebuff:DB$ Debuff | Defined$ Targeted | Keywords$ Flying +SVar:HasAttackEffect:TRUE +Oracle:Flying\nWhenever Fear of Falling attacks, target creature defending player controls gets -2/-0 and loses flying until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_immobility.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_immobility.txt new file mode 100644 index 00000000000..a2fd2ca5c7b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_immobility.txt @@ -0,0 +1,9 @@ +Name:Fear of Immobility +ManaCost:4 W +Types:Enchantment Creature Nightmare +PT:4/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigTap | TriggerDescription$ When CARDNAME enters, tap up to one target creature. If an opponent controls that creature, put a stun counter on it. (If a permanent with a stun counter would become untapped, remove one from it instead.) +SVar:TrigTap:DB$ Tap | ValidTgts$ Creature | TgtPrompt$ Select target creature | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBPutCounter +SVar:DBPutCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ Stun | CounterNum$ 1 | ConditionDefined$ Targeted | ConditionPresent$ Creature.OppCtrl +SVar:PlayMain1:TRUE +Oracle:When Fear of Immobility enters, tap up to one target creature. If an opponent controls that creature, put a stun counter on it. (If a permanent with a stun counter would become untapped, remove one from it instead.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_impostors.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_impostors.txt new file mode 100644 index 00000000000..3a00c86c909 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_impostors.txt @@ -0,0 +1,9 @@ +Name:Fear of Impostors +ManaCost:1 U U +Types:Enchantment Creature Nightmare +PT:3/2 +K:Flash +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigCounter | TriggerDescription$ When CARDNAME enters, counter target spell. Its controller manifests dread. (That player looks at the top two cards of their library, then puts one onto the battlefield face down as a 2/2 creature and the other into their graveyard. If it's a creature card, it can be turned face up any time for its mana cost.) +SVar:TrigCounter:DB$ Counter | TargetType$ Spell | ValidTgts$ Card | SubAbility$ DBDread | TgtPrompt$ Select target spell +SVar:DBDread:DB$ Manifest | Dread$ True | Defined$ TargetedController +Oracle:Flash\nWhen Fear of Impostors enters, counter target spell. Its controller manifests dread. (That player looks at the top two cards of their library, then puts one onto the battlefield face down as a 2/2 creature and the other into their graveyard. If it's a creature card, it can be turned face up any time for its mana cost.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_infinity.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_infinity.txt new file mode 100644 index 00000000000..fb96df79c3b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_infinity.txt @@ -0,0 +1,11 @@ +Name:Fear of Infinity +ManaCost:1 U B +Types:Enchantment Creature Nightmare +PT:2/2 +K:Flying +K:Lifelink +K:CARDNAME can't block. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | OptionalDecider$ You | TriggerZones$ Graveyard | Execute$ TrigChange | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return CARDNAME from your graveyard to your hand. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | OptionalDecider$ You | TriggerZones$ Graveyard | Execute$ TrigChange | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return CARDNAME from your graveyard to your hand. +SVar:TrigChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand +Oracle:Flying, lifelink\nFear of Infinity can't block.\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return Fear of Infinity from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_isolation.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_isolation.txt new file mode 100644 index 00000000000..90fb1ed26e4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_isolation.txt @@ -0,0 +1,7 @@ +Name:Fear of Isolation +ManaCost:1 U +Types:Enchantment Creature Nightmare +PT:2/3 +A:SP$ PermanentCreature | Cost$ 1 U Return<1/Permanent> +K:Flying +Oracle:As an additional cost to cast this spell, return a permanent you control to its owner's hand.\nFlying \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_lost_teeth.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_lost_teeth.txt new file mode 100644 index 00000000000..6e0c160aee4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_lost_teeth.txt @@ -0,0 +1,8 @@ +Name:Fear of Lost Teeth +ManaCost:B +Types:Enchantment Creature Nightmare +PT:1/1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDealDamage | TriggerDescription$ When CARDNAME dies, it deals 1 damage to any target and you gain 1 life. +SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 1 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 +Oracle:When Fear of Lost Teeth dies, it deals 1 damage to any target and you gain 1 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_surveilance.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_surveilance.txt new file mode 100644 index 00000000000..3eae59778d0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_surveilance.txt @@ -0,0 +1,10 @@ +Name:Fear of Surveillance +ManaCost:1 W +Types:Enchantment Creature Nightmare +PT:2/2 +K:Vigilance +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) +SVar:TrigSurveil:DB$ Surveil | Amount$ 1 +SVar:HasAttackEffect:TRUE +DeckHas:Ability$Surveil|Graveyard +Oracle:Vigilance\nWhenever Fear of Surveillance attacks, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/fear_of_the_dark.txt b/forge-gui/res/cardsfolder/upcoming/fear_of_the_dark.txt new file mode 100644 index 00000000000..bb21b6f832f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/fear_of_the_dark.txt @@ -0,0 +1,7 @@ +Name:Fear of the Dark +ManaCost:4 B +Types:Enchantment Creature Nightmare +PT:5/5 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | IsPresent$ Creature.Glimmer+DefenderCtrl | PresentCompare$ EQ0 | TriggerDescription$ Whenever CARDNAME attacks, if defending player controls no Glimmer creatures, it gains menace and deathtouch until end of turn. (A creature with menace can't be blocked except by two or more creatures.) +SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Menace & Deathtouch +Oracle:Whenever Fear of the Dark attacks, if defending player controls no Glimmer creatures, it gains menace and deathtouch until end of turn. (A creature with menace can't be blocked except by two or more creatures.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/final_vengeance.txt b/forge-gui/res/cardsfolder/upcoming/final_vengeance.txt new file mode 100644 index 00000000000..ba5443a54d9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/final_vengeance.txt @@ -0,0 +1,5 @@ +Name:Final Vengeance +ManaCost:B +Types:Sorcery +A:SP$ ChangeZone | Cost$ B Sac<1/Creature;Enchantment/creature or enchantment> | ValidTgts$ Creature | TgtPrompt$ Select target creature | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target creature. +Oracle:As an additional cost to cast this spell, sacrifice a creature or enchantment.\nExile target creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/flesh_burrower.txt b/forge-gui/res/cardsfolder/upcoming/flesh_burrower.txt new file mode 100644 index 00000000000..da49023a79a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/flesh_burrower.txt @@ -0,0 +1,8 @@ +Name:Flesh Burrower +ManaCost:1 G +Types:Creature Insect +PT:2/2 +K:Deathtouch +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, another target creature you control gains deathtouch until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl+Other | TgtPrompt$ Select another target creature you control | KW$ Deathtouch +Oracle:Deathtouch\nWhenever Flesh Burrower attacks, another target creature you control gains deathtouch until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/floodfarm_verge.txt b/forge-gui/res/cardsfolder/upcoming/floodfarm_verge.txt new file mode 100644 index 00000000000..7ad6d9533d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/floodfarm_verge.txt @@ -0,0 +1,6 @@ +Name:Floodfarm Verge +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W}. +A:AB$ Mana | Cost$ T | Produced$ U | IsPresent$ Plains.YouCtrl,Island.YouCtrl | SpellDescription$ Add {U}. Activate only if you control a Plains or an Island. +Oracle:{T}: Add {W}.\n{T}: Add {U}. Activate only if you control a Plains or an Island. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/floodpits_drowner.txt b/forge-gui/res/cardsfolder/upcoming/floodpits_drowner.txt new file mode 100644 index 00000000000..6b364e222d7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/floodpits_drowner.txt @@ -0,0 +1,11 @@ +Name:Floodpits Drowner +ManaCost:1 U +Types:Creature Merfolk +PT:2/1 +K:Flash +K:Vigilance +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigTap | TriggerDescription$ When CARDNAME enters, tap target creature an opponent controls and put a stun counter on it. +SVar:TrigTap:DB$ Tap | ValidTgts$ Creature.OppCtrl | SubAbility$ DBCounter +SVar:DBCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ Stun | CounterNum$ 1 +A:AB$ ChangeZone | Cost$ 1 U T | ValidTgts$ Creature.counters_GE1_STUN | TgtPrompt$ Select target creature with a stun counter on it | ThisDefinedAndTgts$ Self | Origin$ Battlefield | Destination$ Library | Shuffle$ True | SpellDescription$ Shuffle CARDNAME and target creature with a stun counter on it into their owners' libraries. +Oracle:Flash\nVigilance\nWhen Floodpits Drowner enters, tap target creature an opponent controls and put a stun counter on it.\n{1}{U}, {T}: Shuffle Floodpits Drowner and target creature with a stun counter on it into their owners' libraries. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/found_footage.txt b/forge-gui/res/cardsfolder/upcoming/found_footage.txt new file mode 100644 index 00000000000..48ff65e9b8b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/found_footage.txt @@ -0,0 +1,7 @@ +Name:Found Footage +ManaCost:1 +Types:Artifact Clue +S:Mode$ Continuous | Affected$ Creature.faceDown+OppCtrl | AffectedZone$ Battlefield | MayLookAt$ You | Description$ You may look at face-down creatures your opponents control any time. +A:AB$ Surveil | Cost$ 2 Sac<1/CARDNAME> | Amount$ 2 | SubAbility$ DBDraw | SpellDescription$ Surveil 2, then draw a card. (To surveil 2, look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) +SVar:DBDraw:DB$ Draw +Oracle:You may look at face-down creatures your opponents control any time.\n{2}, Sacrifice Found Footage: Surveil 2, then draw a card. (To surveil 2, look at the top two cards of your library, then put any number of them into your graveyard and the rest on top of your library in any order.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/friendly_ghost.txt b/forge-gui/res/cardsfolder/upcoming/friendly_ghost.txt new file mode 100644 index 00000000000..af846ae2e34 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/friendly_ghost.txt @@ -0,0 +1,9 @@ +Name:Friendly Ghost +ManaCost:3 W +Types:Creature Spirit +PT:2/4 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When CARDNAME enters, target creature gets +2/+4 until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 2 | NumDef$ 4 +SVar:PlayMain1:TRUE +Oracle:Flying\nWhen Friendly Spirit enters, target creature gets +2/+4 until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt b/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt new file mode 100644 index 00000000000..95cb1eb8a63 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt @@ -0,0 +1,7 @@ +Name:Friendly Teddy +ManaCost:2 +Types:Artifact Creature Bear Toy +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters, each player draws a card. +SVar:TrigDraw:DB$ Draw | Defined$ Player +Oracle:When Friendly Teddy enters, each player draws a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/ghost_vacuum.txt b/forge-gui/res/cardsfolder/upcoming/ghost_vacuum.txt new file mode 100644 index 00000000000..2f613942c95 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ghost_vacuum.txt @@ -0,0 +1,8 @@ +Name:Ghost Vacuum +ManaCost:1 +Types:Artifact +A:AB$ ChangeZone | Cost$ T | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Choose target card in a graveyard | ValidTgts$ Card | SpellDescription$ Exile target card from a graveyard. +A:AB$ ChangeZoneAll | Cost$ 6 T Sac<1/CARDNAME> | ChangeType$ Creature.ExiledWithSource | Origin$ Exile | Destination$ Battlefield | GainControl$ True | SorcerySpeed$ True | WithCountersType$ Flying | AnimateSubAbility$ DBAnimate | SpellDescription$ Put each creature card exiled with CARDNAME onto the battlefield under your control with a flying counter on it. Each of them is a 1/1 Spirit in addition to its other types. Activate only as a sorcery. +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Power$ 1 | Toughness$ 1 | Types$ Spirit | Duration$ Permanent +DeckHas:Ability$Counters +Oracle:{T}: Exile target card from a graveyard.\n{6}, {T}, Sacrifice Ghost Vacuum: Put each creature card exiled with Ghost Vacuum onto the battlefield under your control with a flying counter on it. Each of them is a 1/1 Spirit in addition to its other types. Activate only as a sorcery. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/giggling_skitterspike.txt b/forge-gui/res/cardsfolder/upcoming/giggling_skitterspike.txt new file mode 100644 index 00000000000..abd8dd70f86 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/giggling_skitterspike.txt @@ -0,0 +1,14 @@ +Name:Giggling Skitterspike +ManaCost:4 +Types:Artifact Creature Toy +PT:1/1 +K:Indestructible +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDealDamage | TriggerDescription$ Whenever CARDNAME attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent. +T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ TrigDealDamage | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent. +T:Mode$ BecomesTarget | ValidTarget$ Card.Self | ValidSource$ Spell | TriggerZones$ Battlefield | Execute$ TrigDealDamage | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent. +SVar:TrigDealDamage:DB$ DealDamage | Defined$ Opponent | NumDmg$ X +K:Monstrosity:5:5 +SVar:X:Count$CardPower +SVar:HasAttackEffect:TRUE +SVar:HasBlockEffect:TRUE +Oracle:Indestructible\nWhenever Giggling Skitterspike attacks, blocks, or becomes the target of a spell, it deals damage equal to its power to each opponent.\n{5}: Monstrosity 5. (If this creature isn't monstrous, put five +1/+1 counters on it and it becomes monstrous.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/give_in_to_violence.txt b/forge-gui/res/cardsfolder/upcoming/give_in_to_violence.txt new file mode 100644 index 00000000000..636adf40f6b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/give_in_to_violence.txt @@ -0,0 +1,5 @@ +Name:Give In to Violence +ManaCost:1 B +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | NumDef$ +2 | KW$ Lifelink | SpellDescription$ Target creature gets +2/+2 and gains lifelink until end of turn. +Oracle:Target creature gets +2/+2 and gains lifelink until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/glimmer_seeker.txt b/forge-gui/res/cardsfolder/upcoming/glimmer_seeker.txt new file mode 100644 index 00000000000..1708a315d1e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/glimmer_seeker.txt @@ -0,0 +1,10 @@ +Name:Glimmer Seeker +ManaCost:2 W +Types:Creature Human Survivor +PT:3/3 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigBranch | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, draw a card if you control a Glimmer creature. If you don't control a Glimmer creature, create a 1/1 white Glimmer enchantment creature token. +SVar:TrigBranch:DB$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE1 | TrueSubAbility$ DBDraw | FalseSubAbility$ DBToken +SVar:DBDraw:DB$ Draw +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_e_glimmer | TokenOwner$ You +SVar:X:Count$Valid Creature.Glimmer+YouCtrl +Oracle:Survival — At the beginning of your second main phase, if Glimmer Seeker is tapped, draw a card if you control a Glimmer creature. If you don't control a Glimmer creature, create a 1/1 white Glimmer enchantment creature token. diff --git a/forge-gui/res/cardsfolder/upcoming/glimmerburst.txt b/forge-gui/res/cardsfolder/upcoming/glimmerburst.txt new file mode 100644 index 00000000000..6df76a5b4fe --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/glimmerburst.txt @@ -0,0 +1,6 @@ +Name:Glimmerburst +ManaCost:3 U +Types:Instant +A:SP$ Draw | NumCards$ 2 | SubAbility$ DBToken | SpellDescription$ Draw two cards. Create a 1/1 white Glimmer enchantment creature token. +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_e_glimmer | TokenOwner$ You +Oracle:Draw two cards. Create a 1/1 white Glimmer enchantment creature token. diff --git a/forge-gui/res/cardsfolder/upcoming/glimmerlight.txt b/forge-gui/res/cardsfolder/upcoming/glimmerlight.txt new file mode 100644 index 00000000000..29bc4020069 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/glimmerlight.txt @@ -0,0 +1,8 @@ +Name:Glimmerlight +ManaCost:2 +Types:Artifact Equipment +K:Equip:1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters, create a 1/1 white Glimmer enchantment creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_e_glimmer | TokenOwner$ You +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Equipped creature gets +1/+1. +Oracle:When Glimmerlight enters, create a 1/1 white Glimmer enchantment creature token.\nEquipped creature gets +1/+1.\nEquip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/glitch_interpreter.txt b/forge-gui/res/cardsfolder/upcoming/glitch_interpreter.txt new file mode 100644 index 00000000000..3c37f1b1a4b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/glitch_interpreter.txt @@ -0,0 +1,11 @@ +Name:Glitch Interpreter +ManaCost:2 U +Types:Creature Human Wizard +PT:2/3 +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | IsPresent$ Permanent.faceDown+YouCtrl | PresentCompare$ EQ0 | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters, if you control no face-down permanents, return CARDNAME to its owner's hand and manifest dread. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | SubAbility$ DBDread +SVar:DBDread:DB$ Manifest | Dread$ True +T:Mode$ DamageDoneOnce | CombatDamage$ True | ValidSource$ Creature.Colorless+YouCtrl | TriggerZones$ Battlefield | ValidTarget$ Player | Execute$ TrigDraw | TriggerDescription$ Whenever one or more colorless creatures you control deal combat damage to a player, draw a card. +SVar:TrigDraw:DB$ Draw +SVar:PlayMain1:TRUE +Oracle:When Glitch Interpreter enters, if you control no face-down permanents, return Glitch Interpreter to its owner's hand and manifest dread.\nWhenever one or more colorless creatures you control deal combat damage to a player, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/gloomlake_verge.txt b/forge-gui/res/cardsfolder/upcoming/gloomlake_verge.txt new file mode 100644 index 00000000000..65fc3416813 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/gloomlake_verge.txt @@ -0,0 +1,6 @@ +Name:Gloomlake Verge +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}. +A:AB$ Mana | Cost$ T | Produced$ B | IsPresent$ Island.YouCtrl,Swamp.YouCtrl | SpellDescription$ Add {B}. Activate only if you control an Island or a Swamp. +Oracle:{T}: Add {U}.\n{T}: Add {B}. Activate only if you control an Island or a Swamp. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/grab_the_prize.txt b/forge-gui/res/cardsfolder/upcoming/grab_the_prize.txt new file mode 100644 index 00000000000..db76e4a1188 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/grab_the_prize.txt @@ -0,0 +1,9 @@ +Name:Grab the Prize +ManaCost:1 R +Types:Sorcery +A:SP$ Draw | Cost$ 1 R Discard<1/Card> | CostDesc$ As an additional cost to cast this spell, discard a card. | NumCards$ 2 | SubAbility$ DBDealDamage | SpellDescription$ Draw two cards. If the discarded card wasn't a land card, CARDNAME deals 2 damage to each opponent. +SVar:DBDealDamage:DB$ DamageAll | ValidPlayers$ Player.Opponent | NumDmg$ X +SVar:X:Discarded$Valid Card.nonLand/Times.2 +DeckHas:Ability$Discard +DeckHints:Keyword$Madness & Ability$Delirium +Oracle:As an additional cost to cast this spell, discard a card.\nDraw two cards. If the discarded card wasn't a land card, Grab the Prize deals 2 damage to each opponent. diff --git a/forge-gui/res/cardsfolder/upcoming/grasping_longneck.txt b/forge-gui/res/cardsfolder/upcoming/grasping_longneck.txt new file mode 100644 index 00000000000..4f299a711d8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/grasping_longneck.txt @@ -0,0 +1,8 @@ +Name:Grasping Longneck +ManaCost:2 G +Types:Enchantment Creature Horror +PT:4/2 +K:Reach +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME dies, you gain 2 life. +SVar:TrigSac:DB$ GainLife | Defined$ TriggeredCardController | LifeAmount$ 2 +Oracle:Reach\nWhen Grasping Longneck dies, you gain 2 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/gremlin_tamer.txt b/forge-gui/res/cardsfolder/upcoming/gremlin_tamer.txt new file mode 100644 index 00000000000..0be3f288709 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/gremlin_tamer.txt @@ -0,0 +1,10 @@ +Name:Gremlin Tamer +ManaCost:W U +Types:Creature Human Scout +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigToken | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_1_1_gremlin | TokenOwner$ You +DeckHas:Ability$Token +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/grievous_wound.txt b/forge-gui/res/cardsfolder/upcoming/grievous_wound.txt new file mode 100644 index 00000000000..1f42f46a3d4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/grievous_wound.txt @@ -0,0 +1,10 @@ +Name:Grievous Wound +ManaCost:3 B B +Types:Enchantment Aura +K:Enchant player +A:SP$ Attach | Cost$ 3 B B | ValidTgts$ Player | AILogic$ Curse +S:Mode$ CantGainLife | ValidPlayer$ Player.EnchantedBy | Description$ Enchanted player can't gain life. +T:Mode$ DamageDoneOnce | Execute$ TrigLoseLife | ValidTarget$ Player.EnchantedBy | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is dealt damage, they lose half their life, rounded up. +SVar:TrigLoseLife:DB$ LoseLife | Defined$ TriggeredTarget | LifeAmount$ X +SVar:X:TriggeredTarget$LifeTotal/HalfUp +Oracle:Enchant player\nEnchanted player can't gain life.\nWhenever enchanted player is dealt damage, they lose half their life, rounded up. diff --git a/forge-gui/res/cardsfolder/upcoming/growing_dread.txt b/forge-gui/res/cardsfolder/upcoming/growing_dread.txt new file mode 100644 index 00000000000..70491a847a0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/growing_dread.txt @@ -0,0 +1,9 @@ +Name:Growing Dread +ManaCost:G U +Types:Enchantment +K:Flash +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You +T:Mode$ TurnFaceUp | ValidCard$ Permanent | ValidCause$ SpellAbility.YouCtrl | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you turn a permanent face up, put a +1/+1 counter on it. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCardLKICopy | CounterType$ P1P1 | CounterNum$ 1 +Oracle:Flash\nWhen Growing Dread enters, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\nWhenever you turn a permanent face up, put a +1/+1 counter on it. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/hand_that_feeds.txt b/forge-gui/res/cardsfolder/upcoming/hand_that_feeds.txt new file mode 100644 index 00000000000..fa4a1c99abf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hand_that_feeds.txt @@ -0,0 +1,10 @@ +Name:Hand That Feeds +ManaCost:1 R +Types:Creature Mutant +PT:2/2 +T:Mode$ Attacks | ValidCard$ Card.Self | Delirium$ True | Execute$ TrigPump | NoResolvingCheck$ True | TriggerDescription$ Delirium — Whenever CARDNAME attacks while there are four or more card types among cards in your graveyard, it gets +2/+0 and gains menace until end of turn. (It can't be blocked except by two or more creatures.) +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ +2 | KW$ Menace +SVar:HasAttackEffect:TRUE +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Delirium — Whenever Hand That Feeds attacks while there are four or more card types among cards in your graveyard, it gets +2/+0 and gains menace until end of turn. (It can't be blocked except by two or more creatures.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/hardened_escort.txt b/forge-gui/res/cardsfolder/upcoming/hardened_escort.txt new file mode 100644 index 00000000000..edc1a133a00 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hardened_escort.txt @@ -0,0 +1,8 @@ +Name:Hardened Escort +ManaCost:2 W +Types:Creature Human Soldier +PT:2/4 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, another target creature you control gets +1/+0 and gains indestructible until end of turn. (Damage and effects that say "destroy" don't destroy it.) +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl+Other | TgtPrompt$ Select another target creature you control | KW$ Indestructible | NumAtt$ +1 +SVar:HasAttackEffect:TRUE +Oracle:Trample\nWhenever Hardened Escort attacks, another target creature you control gets +1/+0 and gains indestructible until end of turn. (Damage and effects that say "destroy" don't destroy it.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/haunted_screen.txt b/forge-gui/res/cardsfolder/upcoming/haunted_screen.txt new file mode 100644 index 00000000000..7ed32c81c8c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/haunted_screen.txt @@ -0,0 +1,8 @@ +Name:Haunted Screen +ManaCost:3 +Types:Artifact +A:AB$ Mana | Cost$ T | Produced$ Combo W B | SpellDescription$ Add {W} or {B}. +A:AB$ Mana | Cost$ T PayLife<1> | Produced$ Combo G U R | SpellDescription$ Add {G}, {U}, or {R}. +A:AB$ PutCounter | Cost$ 7 | CounterType$ P1P1 | CounterNum$ 7 | SubAbility$ DBAnimate | GameActivationLimit$ 1 | SpellDescription$ Put seven +1/+1 counters on CARDNAME. It becomes a 0/0 Spirit creature in addition to its other types. Activate only once. +SVar:DBAnimate:DB$ Animate | Defined$ Self | Power$ 0 | Toughness$ 0 | Types$ Creature,Spirit | Duration$ Permanent +Oracle:{T}: Add {W} or {B}.\n{T}, Pay 1 life: Add {G}, {U}, or {R}.\n{7}: Put seven +1/+1 counters on Haunted Screen. It becomes a 0/0 Spirit creature in addition to its other types. Activate only once. diff --git a/forge-gui/res/cardsfolder/upcoming/hauntwoods_shrieker.txt b/forge-gui/res/cardsfolder/upcoming/hauntwoods_shrieker.txt new file mode 100644 index 00000000000..1cd5fb8ed13 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hauntwoods_shrieker.txt @@ -0,0 +1,8 @@ +Name:Hauntwoods Shrieker +ManaCost:1 G G +Types:Creature Beast Mutant +PT:3/3 +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDread | TriggerDescription$ Whenever CARDNAME attacks, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True +A:AB$ SetState | ValidTgts$ Card.faceDown | Cost$ 1 G | Mode$ TurnFaceUp | Optional$ True | RevealFirst$ True | ValidNewFace$ Creature | StackDescription$ SpellDescription | SpellDescription$ Reveal target face-down permanent. If it's a creature card, you may turn it face up. +Oracle:Whenever Hauntwoods Shrieker attacks, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\n{1}{G}: Reveal target face-down permanent. If it's a creature card, you may turn it face up. diff --git a/forge-gui/res/cardsfolder/upcoming/hedge_shredder.txt b/forge-gui/res/cardsfolder/upcoming/hedge_shredder.txt new file mode 100644 index 00000000000..a41d1816568 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hedge_shredder.txt @@ -0,0 +1,10 @@ +Name:Hedge Shredder +ManaCost:2 G G +Types:Artifact Vehicle +PT:5/5 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ Whenever CARDNAME attacks, you may mill two cards. +SVar:TrigMill:DB$ Mill | NumCards$ 2 | Defined$ You | Optional$ True +T:Mode$ ChangesZoneAll | ValidCards$ Land.YouOwn | Origin$ Library | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigChangeZoneAll | TriggerDescription$ Whenever one or more land cards are put into your graveyard from your library, put them onto the battlefield tapped. +SVar:TrigChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Card.TriggeredCards | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True +K:Crew:1 +Oracle:Whenever Hedge Shredder attacks, you may mill two cards.\nWhenever one or more land cards are put into your graveyard from your library, put them onto the battlefield tapped.\nCrew 1 (Tap any number of creatures you control with total power 1 or more: This Vehicle becomes an artifact creature until end of turn.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/horrid_vigor.txt b/forge-gui/res/cardsfolder/upcoming/horrid_vigor.txt new file mode 100644 index 00000000000..8209d006f98 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/horrid_vigor.txt @@ -0,0 +1,6 @@ +Name:Horrid Vigor +ManaCost:1 G +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | KW$ Deathtouch & Indestructible | SpellDescription$ Target creature gains deathtouch and indestructible until end of turn. +DeckHas:Keyword$Deathtouch|Indestructible +Oracle:Target creature gains deathtouch and indestructible until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/house_cartographer.txt b/forge-gui/res/cardsfolder/upcoming/house_cartographer.txt new file mode 100644 index 00000000000..ce7bd7afb26 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/house_cartographer.txt @@ -0,0 +1,7 @@ +Name:House Cartographer +Types:Creature Human Scout Survivor +ManaCost:1 G +PT:2/2 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigDigUntil | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, reveal cards from the top of your library until you reveal a land card. Put that card into your hand and the rest on the bottom of your library in a random order. +SVar:TrigDigUntil:DB$ DigUntil | Valid$ Card.Land | ValidDescription$ land | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | RevealRandomOrder$ True | FoundDestination$ Hand +Oracle:Survival — At the beginning of your second main phase, if House Cartographer is tapped, reveal cards from the top of your library until you reveal a land card. Put that card into your hand and the rest on the bottom of your library in a random order. diff --git a/forge-gui/res/cardsfolder/upcoming/hushwood_verge.txt b/forge-gui/res/cardsfolder/upcoming/hushwood_verge.txt new file mode 100644 index 00000000000..7a52d0726ce --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hushwood_verge.txt @@ -0,0 +1,6 @@ +Name:Hushwood Verge +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. +A:AB$ Mana | Cost$ T | Produced$ W | IsPresent$ Forest.YouCtrl,Plains.YouCtrl | SpellDescription$ Add {W}. Activate only if you control a Forest or a Plains. +Oracle:{T}: Add {G}.\n{T}: Add {W}. Activate only if you control a Forest or a Plains. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/i_am_duskmourn.txt b/forge-gui/res/cardsfolder/upcoming/i_am_duskmourn.txt new file mode 100644 index 00000000000..03928be8e48 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/i_am_duskmourn.txt @@ -0,0 +1,8 @@ +Name:I Am Duskmourn +ManaCost:no cost +Types:Ongoing Scheme +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPlay | TriggerDescription$ At the beginning of your end step, you may cast a spell from your hand without paying its mana cost. If you do, abandon this scheme. +SVar:TrigPlay:DB$ Play | Valid$ Card.YouCtrl | ValidSA$ Spell | ValidZone$ Hand | WithoutManaCost$ True | Optional$ True | RememberPlayed$ True +SVar:Abandon:DB$ Abandon | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nAt the beginning of your end step, you may cast a spell from your hand without paying its mana cost. If you do, abandon this scheme. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/i_am_untouchable.txt b/forge-gui/res/cardsfolder/upcoming/i_am_untouchable.txt new file mode 100644 index 00000000000..6b8943a66e2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/i_am_untouchable.txt @@ -0,0 +1,8 @@ +Name:I Am Untouchable +ManaCost:no cost +Types:Ongoing Scheme +S:Mode$ Continuous | EffectZone$ Command | Affected$ You,Permanent.YouCtrl | AddKeyword$ Hexproof | Description$ You and permanents you control have hexproof. +T:Mode$ DamageDoneOnce | ValidTarget$ You | TriggerZones$ Battlefield | CombatDamage$ True | Execute$ TrigToken | TriggerZones$ Command | TriggerDescription$ When combat damage is dealt to you, create a 4/4 colorless Scarecrow artifact creature token with vigilance, then abandon this scheme. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_4_4_a_scarecrow_vigilance | TokenOwner$ You | SubAbility$ DBAbandon +SVar:DBAbandon:DB$ Abandon +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nYou and permanents you control have hexproof.\nWhen combat damage is dealt to you, create a 4/4 colorless Scarecrow artifact creature token with vigilance, then abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/i_call_for_slaughter.txt b/forge-gui/res/cardsfolder/upcoming/i_call_for_slaughter.txt new file mode 100644 index 00000000000..8b091c2d1d3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/i_call_for_slaughter.txt @@ -0,0 +1,10 @@ +Name:I Call for Slaughter +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigToken | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, create three 1/1 red Devil creature tokens with "When this creature dies, it deals 1 damage to any target." They gain haste until end of turn. If a source you control would deal damage this turn, it deals that much damage plus 1 instead. +SVar:TrigToken:DB$ Token | TokenAmount$ 3 | TokenScript$ r_1_1_devil_burn | PumpKeywords$ Haste | PumpDuration$ EOT | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | ReplacementEffects$ DamageEvent +SVar:DamageEvent:Event$ DamageDone | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ReplaceWith$ DmgPlusOne | Description$ If a source you control would deal damage this turn, it deals that much damage plus 1 instead. +SVar:DmgPlusOne:DB$ ReplaceEffect | VarName$ DamageAmount | VarValue$ X +SVar:X:ReplaceCount$DamageAmount/Plus.1 +Oracle:When you set this scheme in motion, create three 1/1 red Devil creature tokens with "When this creature dies, it deals 1 damage to any target." They gain haste until end of turn. If a source you control would deal damage this turn, it deals that much damage plus 1 instead. diff --git a/forge-gui/res/cardsfolder/upcoming/i_will_savor_your_agony.txt b/forge-gui/res/cardsfolder/upcoming/i_will_savor_your_agony.txt new file mode 100644 index 00000000000..8fe04618117 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/i_will_savor_your_agony.txt @@ -0,0 +1,9 @@ +Name:I Will Savor Your Agony +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, ABILITY +SVar:TrigCharm:DB$ Charm | Choices$ DBDestroy,DBDraw,DBGainLife | CharmNum$ 3 | CanRepeatModes$ True +SVar:DBDestroy:DB$ Destroy | ValidTgts$ Creature | TgtPrompt$ Select target Creature. | SpellDescription$ Destroy target creature. +SVar:DBDraw:DB$ Draw | ValidTgts$ Player | TgtPrompt$ Select target player (to draw a card) | SpellDescription$ Target player draws a card. +SVar:DBGainLife:DB$ GainLife | ValidTgts$ Player | TgtPrompt$ Select target player (to gain 5 life) | LifeAmount$ 5 | SpellDescription$ Target player gains 5 life. +Oracle:When you set this scheme in motion, choose three. You may choose the same mode more than once.\n• Destroy target creature.\n• Target player draws a card.\n• Target player gains 5 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/impossible_inferno.txt b/forge-gui/res/cardsfolder/upcoming/impossible_inferno.txt new file mode 100644 index 00000000000..eda80333898 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/impossible_inferno.txt @@ -0,0 +1,9 @@ +Name:Impossible Inferno +ManaCost:4 R +Types:Instant +A:SP$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 6 | SubAbility$ DBDig | SpellDescription$ CARDNAME deals 6 damage to target creature. Delirium — If there are four or more card types among cards in your graveyard, exile the top card of your library. You may play it until the end of your next turn. +SVar:DBDig:DB$ Dig | Condition$ Delirium | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ STPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn +SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play it until the end of your next turn. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Impossible Inferno deals 6 damage to target creature.\nDelirium — If there are four or more card types among cards in your graveyard, exile the top card of your library. You may play it until the end of your next turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/infernal_phantom.txt b/forge-gui/res/cardsfolder/upcoming/infernal_phantom.txt new file mode 100644 index 00000000000..383a846673b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/infernal_phantom.txt @@ -0,0 +1,12 @@ +Name:Infernal Phantom +ManaCost:3 R +Types:Creature Spirit +PT:2/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 until end of turn. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 2 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDamage | TriggerDescription$ When CARDNAME dies, it deals damage equal to its power to any target. +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ X +SVar:X:TriggeredCard$CardPower +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Infernal Phantom gets +2/+0 until end of turn.\nWhen Infernal Phantom dies, it deals damage equal to its power to any target. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/innocuous_rat.txt b/forge-gui/res/cardsfolder/upcoming/innocuous_rat.txt new file mode 100644 index 00000000000..79b7e1665e9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/innocuous_rat.txt @@ -0,0 +1,7 @@ +Name:Innocuous Rat +ManaCost:1 B +Types:Creature Rat +PT:1/1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME dies, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True +Oracle:When Innocuous Rat dies, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/insidious_fungus.txt b/forge-gui/res/cardsfolder/upcoming/insidious_fungus.txt new file mode 100644 index 00000000000..571fabf656f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/insidious_fungus.txt @@ -0,0 +1,10 @@ +Name:Insidious Fungus +ManaCost:G +Types:Creature Fungus +PT:1/2 +A:AB$ Charm | Cost$ 2 Sac<1/CARDNAME> | Choices$ DBDestroyArtifact,DBDestroyEnchantment,DBDraw +SVar:DBDestroyArtifact:DB$ Destroy | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact. +SVar:DBDestroyEnchantment:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | SpellDescription$ Destroy target enchantment. +SVar:DBDraw:DB$ Draw | SubAbility$ DBChangeZone | SpellDescription$ Draw a card. Then you may put a land card from your hand onto the battlefield tapped. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.YouOwn +Oracle:{2}, Sacrifice Insidious Fungus: Choose one —\n• Destroy target artifact.\n• Destroy target enchantment.\n• Draw a card. Then you may put a land card from your hand onto the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/irreverent_gremlin.txt b/forge-gui/res/cardsfolder/upcoming/irreverent_gremlin.txt new file mode 100644 index 00000000000..cda428d726e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/irreverent_gremlin.txt @@ -0,0 +1,8 @@ +Name:Irreverent Gremlin +ManaCost:1 R +Types:Creature Gremlin +PT:2/2 +K:Menace +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.powerLE2+Other+YouCtrl | ResolvedLimit$ 1 | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever another creature you control with power 2 or less enters, you may discard a card. If you do, draw a card. Do this only once each turn. +SVar:TrigDraw:AB$ Draw | Cost$ Discard<1/Card> +Oracle:Menace (This creature can't be blocked except by two or more creatures.)\nWhenever another creature you control with power 2 or less enters, you may discard a card. If you do, draw a card. Do this only once each turn. diff --git a/forge-gui/res/cardsfolder/upcoming/kaito_bane_of_nightmares.txt b/forge-gui/res/cardsfolder/upcoming/kaito_bane_of_nightmares.txt new file mode 100644 index 00000000000..fda8cc7c780 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/kaito_bane_of_nightmares.txt @@ -0,0 +1,13 @@ +Name:Kaito, Bane of Nightmares +ManaCost:2 U B +Types:Legendary Planeswalker Kaito +Loyalty:4 +K:Ninjutsu:1 U B +S:Mode$ Continuous | Affected$ Permanent.Self+counters_GE1_LOYALTY | Condition$ PlayerTurn | AddType$ Creature & Ninja | RemoveCardTypes$ True | SetPower$ 3 | SetToughness$ 4 | AddKeyword$ Hexproof | Description$ During your turn, as long as NICKNAME has one or more loyalty counters on him, he's a 3/4 Ninja creature and has hexproof. +A:AB$ Effect | Cost$ AddCounter<1/LOYALTY> | Name$ Emblem — Kaito, Bane of Nightmares | Image$ emblem_kaito_bane_of_nightmares | StaticAbilities$ STNinjaBoost | Planeswalker$ True | Duration$ Permanent | SpellDescription$ You get an emblem with "Ninjas you control get +1/+1." +SVar:STNinjaBoost:Mode$ Continuous | EffectZone$ Command | Affected$ Ninja.YouCtrl | AffectedZone$ Battlefield | AddPower$ 1 | AddToughness$ 1 | Description$ Ninjas you control get +1/+1. +A:AB$ Surveil | Cost$ AddCounter<0/LOYALTY> | Amount$ 2 | Planeswalker$ True | SubAbility$ DBDraw | SpellDescription$ Surveil 2. Then draw a card for each opponent who lost life this turn. +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ PlayerCountRegisteredOpponents$HasPropertyLostLifeThisTurn +A:AB$ Tap | Cost$ SubCounter<2/LOYALTY> | ValidTgts$ Creature | TgtPrompt$ Choose target creature to tap. | Planeswalker$ True | SubAbility$ DBPutCounter | SpellDescription$ Tap target creature. Put two stun counters on it. +SVar:DBPutCounter:DB$ PutCounter | Defined$ Targeted | CounterType$ Stun | CounterNum$ 2 +Oracle:Ninjutsu {1}{U}{B} ({1}{U}{B}, Return an unblocked attacker you control to hand: Put this card onto the battlefield from your hand tapped and attacking.)\nDuring your turn, as long as Kaito has one or more loyalty counters on him, he's a 3/4 Ninja creature and has hexproof.\n[+1]: You get an emblem with "Ninjas you control get +1/+1."\n[0]: Surveil 2. Then draw a card for each opponent who lost life this turn.\n[−2]: Tap target creature. Put two stun counters on it. diff --git a/forge-gui/res/cardsfolder/upcoming/kianne_corrupted_memory.txt b/forge-gui/res/cardsfolder/upcoming/kianne_corrupted_memory.txt new file mode 100644 index 00000000000..3c18c3a157e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/kianne_corrupted_memory.txt @@ -0,0 +1,9 @@ +Name:Kianne, Corrupted Memory +ManaCost:2 G U +Types:Legendary Creature Illusion +PT:2/2 +S:Mode$ CastWithFlash | ValidCard$ Card.nonCreature | ValidSA$ Spell | Caster$ You | IsPresent$ Card.Self+powerEven | Description$ As long as NICKNAME's power is even, you may cast noncreature spells as though they had flash. +S:Mode$ CastWithFlash | ValidCard$ Creature | ValidSA$ Spell | Caster$ You | IsPresent$ Card.Self+powerOdd | Description$ As long as NICKNAME's power is odd, you may cast creature spells as though they had flash. +T:Mode$ Drawn | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you draw a card, put a +1/+1 counter on NICKNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +Oracle:As long as Kianne's power is even, you may cast noncreature spells as though they had flash.\nAs long as Kianne's power is odd, you may cast creature spells as though they had flash.\nWhenever you draw a card, put a +1/+1 counter on Kianne. diff --git a/forge-gui/res/cardsfolder/upcoming/killers_mask.txt b/forge-gui/res/cardsfolder/upcoming/killers_mask.txt new file mode 100644 index 00000000000..fa707d3b1b9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/killers_mask.txt @@ -0,0 +1,10 @@ +Name:Killer's Mask +ManaCost:2 B +Types:Artifact Equipment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread, then attach CARDNAME to that creature. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You | RememberManifested$ True | SubAbility$ DBAttach +SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddKeyword$ Menace | Description$ Equipped creature has menace. +K:Equip:2 +Oracle:When Killer's Mask enters, manifest dread, then attach Killer's Mask to that creature. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\nEquipped creature has menace.\nEquip {2} \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/kneel_before_my_legions.txt b/forge-gui/res/cardsfolder/upcoming/kneel_before_my_legions.txt new file mode 100644 index 00000000000..dd38c63cc39 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/kneel_before_my_legions.txt @@ -0,0 +1,8 @@ +Name:Kneel Before My Legions +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, ABILITY +SVar:TrigCharm:DB$ Charm | Choices$ DBToken,DBPumpAll | CharmNum$ 1 +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_4_4_a_scarecrow_vigilance | TokenOwner$ You | SpellDescription$ Create a 4/4 colorless Scarecrow artifact creature token with vigilance. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | NumAtt$ +3 | NumDef$ +3 | KW$ Vigilance & Trample | SpellDescription$ Creatures you control get +3/+3 and gain vigilance and trample until end of turn. +Oracle:When you set this scheme in motion, choose one —\n• Create a 4/4 colorless Scarecrow artifact creature token with vigilance.\n• Creatures you control get +3/+3 and gain vigilance and trample until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/lakeside_shack.txt b/forge-gui/res/cardsfolder/upcoming/lakeside_shack.txt new file mode 100644 index 00000000000..42b9d3746af --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lakeside_shack.txt @@ -0,0 +1,8 @@ +Name:Lakeside Shack +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo G U | SpellDescription$ Add {G} or {U}. +Oracle:Lakeside Shack enters tapped unless a player has 13 or less life.\n{T}: Add {G} or {U}. diff --git a/forge-gui/res/cardsfolder/upcoming/lets_play_a_game.txt b/forge-gui/res/cardsfolder/upcoming/lets_play_a_game.txt new file mode 100644 index 00000000000..8bf86d4d34d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lets_play_a_game.txt @@ -0,0 +1,11 @@ +Name:Let's Play a Game +ManaCost:3 B +Types:Sorcery +A:SP$ Charm | PrecostDesc$ Delirium — | MinCharmNum$ 1 | CharmNum$ Count$Delirium.3.1 | Choices$ DBPumpAll,DBDiscard,DBLoseLife | AdditionalDescription$ . If there are four or more card types among cards in your graveyard, choose one or more instead. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.OppCtrl | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True | SpellDescription$ Creatures your opponents control get -1/-1 until end of turn. +SVar:DBDiscard:DB$ Discard | Defined$ Opponent | Mode$ TgtChoose | NumCards$ 2 | SpellDescription$ Each opponent discards two cards. +SVar:DBLoseLife:DB$ LoseLife | Defined$ Opponent | LifeAmount$ 3 | SubAbility$ DBGainLife | SpellDescription$ Each opponent loses 3 life and you gain 3 life. +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 3 +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Delirium — Choose one. If there are four or more card types among cards in your graveyard, choose one or more instead.\n• Creatures your opponents control get -1/-1 until end of turn.\n• Each opponent discards two cards.\n• Each opponent loses 3 life and you gain 3 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/leyline_of_mutation.txt b/forge-gui/res/cardsfolder/upcoming/leyline_of_mutation.txt new file mode 100644 index 00000000000..b72b1b48c46 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/leyline_of_mutation.txt @@ -0,0 +1,8 @@ +Name:Leyline of Mutation +ManaCost:2 G G +Types:Enchantment +K:MayEffectFromOpeningHand:FromHand +SVar:FromHand:DB$ ChangeZone | Defined$ Self | Origin$ Hand | Destination$ Battlefield | SpellDescription$ If CARDNAME is in your opening hand, you may begin the game with it on the battlefield. +S:Mode$ AlternativeCost | ValidSA$ Spell | ValidPlayer$ You | Cost$ W U B R G | Description$ You may pay {W}{U}{B}{R}{G} rather than pay the mana cost for spells that you cast. +SVar:NonStackingEffect:True +Oracle:If Leyline of Mutation is in your opening hand, you may begin the game with it on the battlefield.\nYou may pay {W}{U}{B}{R}{G} rather than pay the mana cost for spells that you cast. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/leyline_of_resonance.txt b/forge-gui/res/cardsfolder/upcoming/leyline_of_resonance.txt new file mode 100644 index 00000000000..a26537fd0a7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/leyline_of_resonance.txt @@ -0,0 +1,8 @@ +Name:Leyline of Resonance +ManaCost:2 R R +Types:Enchantment +K:MayEffectFromOpeningHand:FromHand +SVar:FromHand:DB$ ChangeZone | Defined$ Self | Origin$ Hand | Destination$ Battlefield | SpellDescription$ If CARDNAME is in your opening hand, you may begin the game with it on the battlefield. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | Execute$ TrigCopy | ValidActivatingPlayer$ You | IsSingleTarget$ True | TriggerZones$ Battlefield | TargetsValid$ Creature.YouCtrl+inZoneBattlefield | TriggerDescription$ Whenever you cast an instant or sorcery spell that targets only a single creature you control, copy that spell. You may choose new targets for the copy. +SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True | Controller$ You +Oracle:If Leyline of Resonance is in your opening hand, you may begin the game with it on the battlefield.\nWhenever you cast an instant or sorcery spell that targets only a single creature you control, copy that spell. You may choose new targets for the copy. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/leyline_of_transformation.txt b/forge-gui/res/cardsfolder/upcoming/leyline_of_transformation.txt new file mode 100644 index 00000000000..ada0790c4e8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/leyline_of_transformation.txt @@ -0,0 +1,9 @@ +Name:Leyline of Transformation +ManaCost:2 U U +Types:Enchantment +K:MayEffectFromOpeningHand:FromHand +SVar:FromHand:DB$ ChangeZone | Defined$ Self | Origin$ Hand | Destination$ Battlefield | SpellDescription$ If CARDNAME is in your opening hand, you may begin the game with it on the battlefield. +K:ETBReplacement:Other:DBChooseCreatureType +SVar:DBChooseCreatureType:DB$ ChooseType | Type$ Creature | AILogic$ MostProminentInComputerDeck | SpellDescription$ As CARDNAME enters, choose a creature type. +S:Mode$ Continuous | Affected$ Creature.YouCtrl | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command,Ante | AddType$ ChosenType | Description$ Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield. +Oracle:If Leyline of Transformation is in your opening hand, you may begin the game with it on the battlefield.\nAs Leyline of Transformation enters, choose a creature type.\nCreatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/lionheart_glimmer.txt b/forge-gui/res/cardsfolder/upcoming/lionheart_glimmer.txt new file mode 100644 index 00000000000..f663bd82215 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lionheart_glimmer.txt @@ -0,0 +1,8 @@ +Name:Lionheart Glimmer +ManaCost:3 W W +Types:Enchantment Creature Cat Glimmer +PT:2/5 +K:Ward:2 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPumpAll | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, creatures you control get +1/+1 until end of turn. +SVar:TrigPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | NumAtt$ 1 | NumDef$ 1 +Oracle:Ward {2} (Whenever this creature becomes the target of a spell or ability an opponent controls, counter it unless that player pays {2}.)\nWhenever you attack, creatures you control get +1/+1 until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt b/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt new file mode 100644 index 00000000000..3fa50f07df2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt @@ -0,0 +1,15 @@ +Name:Marina Vendrell's Grimoire +ManaCost:5 U +Types:Legendary Artifact +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+wasCastByYou | Execute$ TrigDraw1 | TriggerDescription$ When CARDNAME enters, if you cast it, draw five cards. +SVar:TrigDraw1:DB$ Draw | NumCards$ 5 +S:Mode$ Continuous | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size and don't lose the game for having 0 or less life. +R:Event$ GameLoss | ActiveZones$ Battlefield | ValidPlayer$ You | ValidLoseReason$ LifeReachedZero | Layer$ CantHappen | Secondary$ True | Description$ You have no maximum hand size and don't lose the game for having 0 or less life. +T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw2 | TriggerDescription$ Whenever you gain life, draw that many cards. +SVar:TrigDraw2:DB$ Draw | Defined$ You | NumCards$ X +T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ Whenever you lose life, discard that many cards. Then if you have no cards in hand, you lose the game. +SVar:TrigDiscard:DB$ Discard | Defined$ You | NumCards$ X | Mode$ TgtChoose | SubAbility$ DBLosesGame +SVar:DBLosesGame:DB$ LosesGame | Defined$ You | ConditionCheckSVar$ Y | ConditionSVarCompare$ EQ0 +SVar:X:TriggerCount$LifeAmount +SVar:Y:Count$InYourHand +Oracle:When Marine Vendrell's Grimoire enters, if you cast it, draw five cards.\nYou have no maximum hand size and don't lose the game for having 0 or less life.\nWhenever you gain life, draw that many cards.\nWhenever you lose life, discard that many cards. Then if you have no cards in hand, you lose the game. diff --git a/forge-gui/res/cardsfolder/upcoming/marvin_murderous_mimic.txt b/forge-gui/res/cardsfolder/upcoming/marvin_murderous_mimic.txt new file mode 100644 index 00000000000..370ce81eef3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/marvin_murderous_mimic.txt @@ -0,0 +1,6 @@ +Name:Marvin, Murderous Mimic +ManaCost:2 +Types:Legendary Artifact Creature Toy +PT:4/6 +S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Battlefield | GainsAbilitiesOf$ Creature.YouCtrl+!sharesNameWith Self | Description$ CARDNAME has all activated abilities of creatures you control that don't have the same name as this creature. +Oracle:Marvin, Murderous Mimic has all activated abilities of creatures you control that don't have the same name as this creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/meathook_massacre_ii.txt b/forge-gui/res/cardsfolder/upcoming/meathook_massacre_ii.txt new file mode 100644 index 00000000000..cad539fa8b4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/meathook_massacre_ii.txt @@ -0,0 +1,12 @@ +Name:Meathook Massacre II +ManaCost:X X B B B B +Types:Legendary Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters, each player sacrifices X creatures. +SVar:TrigSac:DB$ Sacrifice | Defined$ Player | Amount$ X | SacValid$ Creature +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigReturn1 | TriggerDescription$ Whenever a creature you control dies, you may pay 3 life. If you do, return that card under your control with a finality counter on it. +SVar:TrigReturn1:AB$ ChangeZone | Cost$ PayLife<3> | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | Defined$ TriggeredNewCardLKICopy | WithCountersType$ FINALITY +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.OppCtrl | TriggerZones$ Battlefield | Execute$ TrigReturn2 | TriggerDescription$ Whenever a creature an opponent controls dies, they may pay 3 life. If they don't, return that card under your control with a finality counter on it. +SVar:TrigReturn2:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | Defined$ TriggeredNewCardLKICopy | UnlessCost$ PayLife<3> | UnlessPayer$ TriggeredCardController | WithCountersType$ FINALITY +SVar:X:Count$xPaid +DeckHas:Ability$Sacrifice +Oracle:When Meathook Massacre II enters, each player sacrifices X creatures.\nWhenever a creature you control dies, you may pay 3 life. If you do, return that card under your control with a finality counter on it.\nWhenever a creature an opponent controls dies, they may pay 3 life. If they don't, return that card under your control with a finality counter on it. diff --git a/forge-gui/res/cardsfolder/upcoming/metamorphosis_fanatic.txt b/forge-gui/res/cardsfolder/upcoming/metamorphosis_fanatic.txt new file mode 100644 index 00000000000..1285ae333b5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/metamorphosis_fanatic.txt @@ -0,0 +1,9 @@ +Name:Metamorphosis Fanatic +ManaCost:4 B B +Types:Creature Human Cleric +PT:4/4 +K:Lifelink +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters, return up to one target creature card from your graveyard to the battlefield with a lifelink counter on it. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose up to one target creature card in your graveyard | ValidTgts$ Creature.YouOwn | WithCountersType$ Lifelink +K:Miracle:1 B +Oracle:Lifelink\nWhen Metamorphosis Fanatic enters, return up to one target creature card from your graveyard to the battlefield with a lifelink counter on it.\nMiracle {1}{B} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/miasma_demon.txt b/forge-gui/res/cardsfolder/upcoming/miasma_demon.txt new file mode 100644 index 00000000000..c53f086274e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/miasma_demon.txt @@ -0,0 +1,13 @@ +Name:Miasma Demon +ManaCost:4 B B +Types:Creature Demon +PT:5/4 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters, you may discard any number of cards. When you do, up to that many target creatures each get -2/-2 until end of turn. +SVar:TrigDiscard:DB$ Discard | DiscardValid$ Card | AnyNumber$ True | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ TrigImmediateTrig +SVar:TrigImmediateTrig:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1 | RememberObjects$ Remembered | Execute$ TrigPump | SubAbility$ DBCleanup | TriggerDescription$ When you do, up to that many target creatures each get -2/-2 until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select up to that many target creatures | TargetMin$ 0 | TargetMax$ X | NumAtt$ -2 | NumDef$ -2 | IsCurse$ True +SVar:X:TriggerRemembered$Amount +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Discard|Graveyard +Oracle:Flying\nWhen Miasma Demon enters, you may discard any number of cards. When you do, up to that many target creatures each get -2/-2 until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/midnight_mayhem.txt b/forge-gui/res/cardsfolder/upcoming/midnight_mayhem.txt new file mode 100644 index 00000000000..c38b08cad50 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/midnight_mayhem.txt @@ -0,0 +1,7 @@ +Name:Midnight Mayhem +ManaCost:2 R W +Types:Sorcery +A:SP$ Token | TokenAmount$ 3 | TokenScript$ r_1_1_gremlin | TokenOwner$ You | SubAbility$ DBPumpAll | SpellDescription$ Create three 1/1 red Gremlin creature tokens. Gremlins you control gain menace, lifelink, and haste until end of turn. (A creature with menace can't be blocked except by two or more creatures.) +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Gremlin.YouCtrl | KW$ Menace & Lifelink & Haste +SVar:PlayMain1:TRUE +Oracle:Create three 1/1 red Gremlin creature tokens. Gremlins you control gain menace, lifelink, and haste until end of turn. (A creature with menace can't be blocked except by two or more creatures.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/most_valuable_slayer.txt b/forge-gui/res/cardsfolder/upcoming/most_valuable_slayer.txt new file mode 100644 index 00000000000..0e9ee884151 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/most_valuable_slayer.txt @@ -0,0 +1,7 @@ +Name:Most Valuable Slayer +ManaCost:3 R +Types:Creature Human Warrior +PT:2/4 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, target attacking creature gets +1/+0 and gains first strike until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | NumAtt$ +1 | KW$ First Strike +Oracle:Whenever you attack, target attacking creature gets +1/+0 and gains first strike until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/murky_sewer.txt b/forge-gui/res/cardsfolder/upcoming/murky_sewer.txt new file mode 100644 index 00000000000..92e8c7dad69 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/murky_sewer.txt @@ -0,0 +1,8 @@ +Name:Murky Sewer +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo U B | SpellDescription$ Add {U} or {B}. +Oracle:Murky Sewer enters tapped unless a player has 13 or less life.\n{T}: Add {U} or {B}. diff --git a/forge-gui/res/cardsfolder/upcoming/my_champion_stands_supreme.txt b/forge-gui/res/cardsfolder/upcoming/my_champion_stands_supreme.txt new file mode 100644 index 00000000000..f31fd930b32 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/my_champion_stands_supreme.txt @@ -0,0 +1,9 @@ +Name:My Champion Stands Supreme +ManaCost:no cost +Types:Ongoing Scheme +S:Mode$ Continuous | Affected$ Card.IsCommander+YouOwn | EffectZone$ Command | AddKeyword$ Ward:2 | Description$ Your commander has ward {2). +T:Mode$ Attacks | ValidCard$ Card.IsCommander+YouOwn | TriggerZones$ Command | Execute$ TrigPutCounter | TriggerDescription$ Whenever your commander attacks, put two +1/+1 counters on it. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredAttackerLKICopy | CounterType$ P1P1 | CounterNum$ 2 +T:Mode$ ChangesZone | ValidCard$ Card.IsCommander+YouOwn | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigAbandon | TriggerZones$ Command | TriggerDescription$ When your commander leaves the battlefield, abandon this scheme. +SVar:TrigAbandon:DB$ Abandon +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nYour commander has ward {2).\nWhenever your commander attacks, put two +1/+1 counters on it.\nWhen your commander leaves the battlefield, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/my_followers_ascend.txt b/forge-gui/res/cardsfolder/upcoming/my_followers_ascend.txt new file mode 100644 index 00000000000..451ae1e48a4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/my_followers_ascend.txt @@ -0,0 +1,11 @@ +Name:My Followers Ascend +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigBranch| TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, put five +1/+1 counters on a creature you control and it gains flying and vigilance until end of turn. If you control no creatures, instead create a 4/4 colorless Scarecrow artifact creature token with vigilance. +SVar:TrigBranch:DB$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ EQ0 | TrueSubAbility$ DBToken | FalseSubAbility$ DBPutCounter +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_4_4_a_scarecrow_vigilance | TokenOwner$ You +SVar:DBPutCounter:DB$ PutCounter | Choices$ Creature.YouCtrl | CounterType$ P1P1 | CounterNum$ 5 | RememberChosen$ True | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ Flying & Vigilance | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$Valid Creature.YouCtrl +Oracle:When you set this scheme in motion, put five +1/+1 counters on a creature you control and it gains flying and vigilance until end of turn. If you control no creatures, instead create a 4/4 colorless Scarecrow artifact creature token with vigilance. diff --git a/forge-gui/res/cardsfolder/upcoming/my_tendrils_run_deep.txt b/forge-gui/res/cardsfolder/upcoming/my_tendrils_run_deep.txt new file mode 100644 index 00000000000..6e08a5067c2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/my_tendrils_run_deep.txt @@ -0,0 +1,9 @@ +Name:My Tendrils Run Deep +ManaCost:no cost +Types:Ongoing Scheme +S:Mode$ Continuous | EffectZone$ Command | Affected$ You | AdjustLandPlays$ 1 | Description$ You may play an additional land on each of your turns. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ TrigDraw | TriggerZones$ Command | IsPresent$ Land.YouCtrl | PresentCompare$ GE6 | TriggerDescription$ At the beginning of your end step, if you control six or more lands, draw two cards, then abandon this scheme. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 2 | SubAbility$ DBAbandon +SVar:DBAbandon:DB$ Abandon +SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature.YouCtrl +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nYou may play an additional land on each of your turns.\nAt the beginning of your end step, if you control six or more lands, draw two cards, then abandon this scheme. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/my_wealth_will_bury_you.txt b/forge-gui/res/cardsfolder/upcoming/my_wealth_will_bury_you.txt new file mode 100644 index 00000000000..8874347d3d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/my_wealth_will_bury_you.txt @@ -0,0 +1,8 @@ +Name:My Wealth Will Bury You +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigToken | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, create a number of Treasure tokens equal to the number of artifacts and enchantments your opponents control. If they control fewer than four artifacts and enchantments, create four Treasure tokens instead. (Treasure tokens are artifacts with "{T}, Sacrifice this artifact: Add one mana of any color.") +SVar:TrigToken:DB$ Token | TokenAmount$ Y | TokenScript$ c_a_treasure_sac | TokenOwner$ You +SVar:X:Count$Valid Artifact.OppCtrl,Enchantment.OppCtrl +SVar:Y:Count$Compare X GE4.X.4 +Oracle:When you set this scheme in motion, create a number of Treasure tokens equal to the number of artifacts and enchantments your opponents control. If they control fewer than four artifacts and enchantments, create four Treasure tokens instead. (Treasure tokens are artifacts with "{T}, Sacrifice this artifact: Add one mana of any color.") \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/my_wings_enfold_all.txt b/forge-gui/res/cardsfolder/upcoming/my_wings_enfold_all.txt new file mode 100644 index 00000000000..74b630ec0d1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/my_wings_enfold_all.txt @@ -0,0 +1,10 @@ +Name:My Wings Enfold All +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, ABILITY +SVar:TrigCharm:DB$ Charm | Choices$ DBDraw,DBEffect | CharmNum$ 1 +SVar:DBDraw:DB$ Draw | NumCards$ 2 | SpellDescription$ Draw two cards. +SVar:DBEffect:DB$ Effect | Triggers$ CastTrig | SpellDescription$ Until end of turn, whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy. +SVar:CastTrig:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Execute$ TrigCopySpell | TriggerZones$ Command | TriggerDescription$ Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy. +SVar:TrigCopySpell:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True +Oracle:When you set this scheme in motion, choose one —\n• Draw two cards.\n• Until end of turn, whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/nashi_searcher_in_the_dark.txt b/forge-gui/res/cardsfolder/upcoming/nashi_searcher_in_the_dark.txt new file mode 100644 index 00000000000..3115d5f0ed7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/nashi_searcher_in_the_dark.txt @@ -0,0 +1,14 @@ +Name:Nashi, Searcher in the Dark +ManaCost:U B +Types:Legendary Creature Rat Ninja Wizard +PT:2/2 +K:Menace +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigMill | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you mill that many cards. You may put any number of legendary and/or enchantment cards from among them into your hand. If you put no cards into your hand this way, put a +1/+1 counter on NICKNAME. +SVar:TrigMill:DB$ Mill | NumCards$ X | Defined$ You | RememberMilled$ True | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Hidden$ True | Origin$ Graveyard,Exile | Destination$ Hand | ChangeType$ Card.Legendary+IsRemembered,Enchantment.IsRemembered | ChangeNum$ X | RememberChanged$ True | ForgetOtherRemembered$ True | SelectPrompt$ You may select any number of legendary and/or enchantment cards. | SubAbility$ DBPutCounter +SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:TriggerCount$DamageAmount +DeckHas:Ability$Mill +DeckHints:Type$Legendary|Enchantment +Oracle:Menace\nWhenever Nashi, Searcher in the Dark deals combat damage to a player, you mill that many cards. You may put any number of legendary and/or enchantment cards from among them into your hand. If you put no cards into your hand this way, put a +1/+1 counter on Nashi. diff --git a/forge-gui/res/cardsfolder/upcoming/neglected_manor.txt b/forge-gui/res/cardsfolder/upcoming/neglected_manor.txt new file mode 100644 index 00000000000..ff0c70d1892 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/neglected_manor.txt @@ -0,0 +1,8 @@ +Name:Neglected Manor +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo W B | SpellDescription$ Add {W} or {B}. +Oracle:Neglected Manor enters tapped unless a player has 13 or less life.\n{T}: Add {W} or {B}. diff --git a/forge-gui/res/cardsfolder/upcoming/niko_light_of_hope.txt b/forge-gui/res/cardsfolder/upcoming/niko_light_of_hope.txt new file mode 100644 index 00000000000..7cef3e7298e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/niko_light_of_hope.txt @@ -0,0 +1,12 @@ +Name:Niko, Light of Hope +ManaCost:2 W U +Types:Legendary Creature Human Wizard +PT:3/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters, create two Shard tokens. (They're enchantments with "2, Sacrifice this enchantment: Scry 1, then draw a card.") +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ c_e_shard_draw | TokenOwner$ You +A:AB$ ChangeZone | Cost$ 2 T | ValidTgts$ Creature.nonLegendary+YouCtrl | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select nonlegendary creature you control | SubAbility$ DBClone | RememberLKI$ True | Imprint$ True | SpellDescription$ Exile target nonlegendary creature you control. Shards you control become copies of it until the beginning of the next end step. Return it to the battlefield under its owner's control at the beginning of the next end step. +SVar:DBClone:DB$ Clone | Defined$ Remembered | CloneTarget$ Valid Shard.YouCtrl | Duration$ UntilNextEndStep | SubAbility$ DelTrig +SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigReturn | RememberObjects$ ImprintedLKI | TriggerDescription$ Return exiled permanent to the battlefield. | SubAbility$ DBCleanup +SVar:TrigReturn:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ DelayTriggerRememberedLKI +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True +Oracle:When Niko, Light of Hope enters, create two Shard tokens. (They're enchantments with "2, Sacrifice this enchantment: Scry 1, then draw a card.")\n{2}, {T}: Exile target nonlegendary creature you control. Shards you control become copies of it until the beginning of the next end step. Return it to the battlefield under its owner's control at the beginning of the next end step. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/no_secret_is_hidden_from_me.txt b/forge-gui/res/cardsfolder/upcoming/no_secret_is_hidden_from_me.txt new file mode 100644 index 00000000000..e6fa1df53e4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/no_secret_is_hidden_from_me.txt @@ -0,0 +1,12 @@ +Name:No Secret Is Hidden From Me +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigDigUntil | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, exile cards from the top of your library until you exile a nonland card. You may cast that card without paying its mana cost. Then if you control six or more lands, repeat this process once. +SVar:TrigDigUntil:DB$ DigUntil | Valid$ Card.nonLand | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | SubAbility$ DBPlay1 +SVar:DBPlay1:DB$ Play | Defined$ Remembered | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | SubAbility$ DBChange | SubAbility$ DBCleanup1 +SVar:DBCleanup1:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBDigUntil +SVar:DBDigUntil:DB$ DigUntil | Valid$ Card.nonLand | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GE6 | SubAbility$ DBPlay2 +SVar:DBPlay2:DB$ Play | Defined$ Remembered | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | SubAbility$ DBChange | SubAbility$ DBCleanup2 +SVar:DBCleanup2:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$Valid Land.YouCtrl +Oracle:When you set this scheme in motion, exile cards from the top of your library until you exile a nonland card. You may cast that card without paying its mana cost. Then if you control six or more lands, repeat this process once. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/norin_swift_survivalist.txt b/forge-gui/res/cardsfolder/upcoming/norin_swift_survivalist.txt new file mode 100644 index 00000000000..42230eb9239 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/norin_swift_survivalist.txt @@ -0,0 +1,11 @@ +Name:Norin, Swift Survivalist +ManaCost:R +Types:Legendary Creature Human Coward +PT:2/1 +K:CARDNAME can't block. +T:Mode$ AttackerBlocked | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigExile | OptionalDecider$ You | TriggerDescription$ Whenever a creature you control becomes blocked, you may exile it. You may play that card from exile this turn. +SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ TriggeredAttackerLKICopy | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ STPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile +SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play that card from exile this turn. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Norin, Swift Survivalist can't block.\nWhenever a creature you control becomes blocked, you may exile it. You may play that card from exile this turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/nowhere_to_run.txt b/forge-gui/res/cardsfolder/upcoming/nowhere_to_run.txt new file mode 100644 index 00000000000..47270a8a19f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/nowhere_to_run.txt @@ -0,0 +1,9 @@ +Name:Nowhere to Run +ManaCost:1 B +Types:Enchantment +K:Flash +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When CARDNAME enters, target creature an opponent controls gets -3/-3 until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | NumAtt$ -3 | NumDef$ -3 | IsCurse$ True +S:Mode$ IgnoreHexproof | ValidEntity$ Creature.OppCtrl | Description$ Creatures your opponents control can be the targets of spells and abilities as though they didn't have hexproof. Ward abilities of those creatures don't trigger. +S:Mode$ DisableTriggers | Secondary$ True | ValidTrigger$ Triggered.Ward | ValidCard$ Creature.OppCtrl+inZoneBattlefield | Description$ Creatures your opponents control can be the targets of spells and abilities as though they didn't have hexproof. Ward abilities of those creatures don't trigger. +Oracle:Flash\nWhen Nowhere to Run enters, target creature an opponent controls gets -3/-3 until end of turn.\nCreatures your opponents control can be the targets of spells and abilities as though they didn't have hexproof. Ward abilities of those creatures don't trigger. diff --git a/forge-gui/res/cardsfolder/upcoming/omnivorous_flytrap.txt b/forge-gui/res/cardsfolder/upcoming/omnivorous_flytrap.txt new file mode 100644 index 00000000000..5f8b52432da --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/omnivorous_flytrap.txt @@ -0,0 +1,10 @@ +Name:Omnivorous Flytrap +ManaCost:2 G +Types:Creature Plant +PT:2/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPutCounter | Delirium$ True | TriggerDescription$ Delirium — Whenever CARDNAME enters or attacks, if there are four or more card types among cards in your graveyard, distribute two +1/+1 counters among one or two target creatures. Then if there are six or more card types among cards in your graveyard, double the number of +1/+1 counters on those creatures. +T:Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True | Execute$ TrigPutCounter | Delirium$ True | TriggerDescription$ Delirium — Whenever CARDNAME enters or attacks, if there are four or more card types among cards in your graveyard, distribute two +1/+1 counters among one or two target creatures. Then if there are six or more card types among cards in your graveyard, double the number of +1/+1 counters on those creatures. +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 2 | TargetMin$ 1 | TargetMax$ 2 | DividedAsYouChoose$ 2 | SubAbility$ DBMultiplyCounter +SVar:DBMultiplyCounter:DB$ MultiplyCounter | Defined$ Targeted | CounterType$ P1P1 | ConditionCheckSVar$ X | ConditionSVarCompare$ GE6 +SVar:X:Count$ValidGraveyard Card.YouOwn$CardTypes +Oracle:Delirium — Whenever Omnivorous Flytrap enters or attacks, if there are four or more card types among cards in your graveyard, distribute two +1/+1 counters among one or two target creatures. Then if there are six or more card types among cards in your graveyard, double the number of +1/+1 counters on those creatures. diff --git a/forge-gui/res/cardsfolder/upcoming/only_i_know_what_awaits.txt b/forge-gui/res/cardsfolder/upcoming/only_i_know_what_awaits.txt new file mode 100644 index 00000000000..862e6fb5a7c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/only_i_know_what_awaits.txt @@ -0,0 +1,9 @@ +Name:Only I Know What Awaits +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigRepeatEach | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, for each card type among permanents your opponents control, you may put a permanent card of that type from your hand onto the battlefield. +SVar:DBRepeatEach:DB$ RepeatEach | RepeatTypesFrom$ Permanent.OppCtrl | RepeatSubAbility$ ChooseCard | SubAbility$ DBChangeZoneAll +SVar:ChooseCard:DB$ ChooseCard | Choices$ Card.YouOwn+ChosenType | ChoiceTitle$ You may choose a card of this type to put onto the battlefield | ChoiceTitleAppend$ ChosenType | ChoiceZone$ Hand +SVar:DBChangeZoneAll:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Hand | Destination$ Battlefield | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +Oracle:When you set this scheme in motion, for each card type among permanents your opponents control, you may put a permanent card of that type from your hand onto the battlefield. diff --git a/forge-gui/res/cardsfolder/upcoming/optimistic_scavenger.txt b/forge-gui/res/cardsfolder/upcoming/optimistic_scavenger.txt new file mode 100644 index 00000000000..559180742ee --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/optimistic_scavenger.txt @@ -0,0 +1,10 @@ +Name:Optimistic Scavenger +ManaCost:W +Types:Creature Human Scout +PT:1/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature. +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature. diff --git a/forge-gui/res/cardsfolder/upcoming/orphans_of_the_wheat.txt b/forge-gui/res/cardsfolder/upcoming/orphans_of_the_wheat.txt new file mode 100644 index 00000000000..e0faf39da69 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/orphans_of_the_wheat.txt @@ -0,0 +1,10 @@ +Name:Orphans of the Wheat +ManaCost:1 W +Types:Creature Human +PT:2/1 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigTap | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, you may tap any number of untapped creatures you control. CARDNAME gets +1/+1 until end of turn for each creature tapped this way. +SVar:TrigTap:DB$ Tap | CardChoices$ Creature.YouCtrl+untapped | AnyNumber$ True | ChoiceAmount$ Count$Valid Creature.YouCtrl+untapped | RememberTapped$ True | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | NumAtt$ X | NumDef$ X | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$Amount +Oracle:Whenever Orphans of the Wheat attacks, you may tap any number of untapped creatures you control. Orphans of the Wheat gets +1/+1 until end of turn for each creature tapped this way. diff --git a/forge-gui/res/cardsfolder/upcoming/osseous_sticktwister.txt b/forge-gui/res/cardsfolder/upcoming/osseous_sticktwister.txt new file mode 100644 index 00000000000..d1926af3130 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/osseous_sticktwister.txt @@ -0,0 +1,13 @@ +Name:Osseous Sticktwister +ManaCost:1 B +Types:Artifact Creature Scarecrow +PT:2/2 +K:Lifelink +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Condition$ Delirium | TriggerZones$ Battlefield | Execute$ TrigMaySacorDiscard | TriggerDescription$ Delirium — At the beginning of your end step, if there are four or more card types among cards in your graveyard, each opponent may sacrifice a nonland permanent or discard a card. Then CARDNAME deals damage equal to its power to each opponent who didn't sacrifice a permanent or discard a card this way. +SVar:TrigMaySacorDiscard:DB$ GenericChoice | Choices$ PaySac,PayDiscard | TempRemember$ Chooser | Defined$ Opponent | AILogic$ PayUnlessCost | DamageMap$ True +SVar:PaySac:DB$ DealDamage | NumDmg$ X | Defined$ Remembered | UnlessCost$ Sac<1/Permanent.nonLand> | UnlessPayer$ Remembered | UnlessAI$ LifeLTX | SpellDescription$ CARDNAME deals damage equal to its power to you unless you sacrifice a nonland permanent. +SVar:PayDiscard:DB$ DealDamage | NumDmg$ X | Defined$ Remembered | UnlessCost$ Discard<1/Card> | UnlessPayer$ Remembered | UnlessAI$ LifeLTX | SpellDescription$ CARDNAME deals damage equal to its power to you unless you discard a card. +SVar:X:Count$CardPower +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Lifelink\nDelirium — At the beginning of your end step, if there are four or more card types among cards in your graveyard, each opponent may sacrifice a nonland permanent or discard a card. Then Osseous Sticktwister deals damage equal to its power to each opponent who didn't sacrifice a permanent or discard a card this way. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/overgrown_zealot.txt b/forge-gui/res/cardsfolder/upcoming/overgrown_zealot.txt new file mode 100644 index 00000000000..a4535e6770b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/overgrown_zealot.txt @@ -0,0 +1,7 @@ +Name:Overgrown Zealot +ManaCost:1 G +Types:Creature Elf Druid +PT:1/1 +A:AB$ Mana | Cost$ T | Produced$ Any | SpellDescription$ Add one mana of any color. +A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 2 | RestrictValid$ Static.isTurnFaceUp | SpellDescription$ Add two mana of any one color. Spend this mana only to turn permanents face up. +Oracle:{T}: Add one mana of any color.\n{T}: Add two mana of any one color. Spend this mana only to turn permanents face up. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/overlord_of_the_boilerbilges.txt b/forge-gui/res/cardsfolder/upcoming/overlord_of_the_boilerbilges.txt new file mode 100644 index 00000000000..ac07be5ada8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/overlord_of_the_boilerbilges.txt @@ -0,0 +1,9 @@ +Name:Overlord of the Boilerbilges +ManaCost:4 R R +Types:Enchantment Creature Avatar Horror +PT:5/5 +K:Impending:4:2 R R +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDealDamage | TriggerDescription$ Whenever CARDNAME enters or attacks, it deals 4 damage to any target. +T:Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True | Execute$ TrigDealDamage | TriggerDescription$ Whenever CARDNAME enters or attacks, it deals 4 damage to any target. +SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 4 +Oracle:Impending 4—{2}{R}{R} (If you cast this spell for its impending cost, it enters with four time counters and isn't a creature until the last is removed. At the beginning of your end step, remove a time counter from it.)\nWhenever Overlord of the Boilerbilges enters or attacks, it deals 4 damage to any target. diff --git a/forge-gui/res/cardsfolder/upcoming/overlord_of_the_floodpits.txt b/forge-gui/res/cardsfolder/upcoming/overlord_of_the_floodpits.txt new file mode 100644 index 00000000000..635e595e7f3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/overlord_of_the_floodpits.txt @@ -0,0 +1,11 @@ +Name:Overlord of the Floodpits +ManaCost:3 U U +Types:Enchantment Creature Avatar Horror +PT:5/3 +K:Impending:4:1 U U +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME enters or attacks, draw two cards, then discard a card. +T:Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME enters or attacks, draw two cards, then discard a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 2 | SubAbility$ TrigDiscard +SVar:TrigDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose +Oracle:Impending 4—{1}{U}{U} (If you cast this spell for its impending cost, it enters with four time counters and isn't a creature until the last is removed. At the beginning of your end step, remove a time counter from it.)\nFlying\nWhenever Overlord of the Floodpits enters or attacks, draw two cards, then discard a card. diff --git a/forge-gui/res/cardsfolder/upcoming/overlord_of_the_mistmoors.txt b/forge-gui/res/cardsfolder/upcoming/overlord_of_the_mistmoors.txt new file mode 100644 index 00000000000..73a5033daba --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/overlord_of_the_mistmoors.txt @@ -0,0 +1,9 @@ +Name:Overlord of the Mistmoors +ManaCost:5 W W +Types:Enchantment Creature Avatar Horror +PT:6/6 +K:Impending:4:2 W W +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME enters or attacks, create two 2/1 white Insect creature tokens with flying. +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Secondary$ True | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME enters or attacks, create two 2/1 white Insect creature tokens with flying. +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ w_2_1_insect_flying +Oracle:Impending 4—{2}{W}{W} (If you cast this spell for its impending cost, it enters with four time counters and isn't a creature until the last is removed. At the beginning of your end step, remove a time counter from it.)\nWhenever Overlord of the Mistmoors enters or attacks, create two 2/1 white Insect creature tokens with flying. diff --git a/forge-gui/res/cardsfolder/upcoming/patched_plaything.txt b/forge-gui/res/cardsfolder/upcoming/patched_plaything.txt new file mode 100644 index 00000000000..7e746da39a0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/patched_plaything.txt @@ -0,0 +1,9 @@ +Name:Patched Plaything +ManaCost:2 W +Types:Artifact Creature Toy +PT:4/3 +K:Double Strike +K:etbCounter:M1M1:2:CheckSVar$ FromHand:CARDNAME enters with two -1/-1 counters on it if you cast it from your hand. +SVar:FromHand:Count$wasCastFromYourHandByYou.1.0 +DeckHas:Ability$Counters +Oracle:Double strike\nPatched Plaything enters with two -1/-1 counters on it if you cast it from your hand. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/patchwork_beastie.txt b/forge-gui/res/cardsfolder/upcoming/patchwork_beastie.txt new file mode 100644 index 00000000000..c1026d2142a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/patchwork_beastie.txt @@ -0,0 +1,11 @@ +Name:Patchwork Beastie +ManaCost:G +Types:Artifact Creature Beast +PT:3/3 +S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ CARDNAME can't attack or block. | CheckSVar$ X | Description$ Delirium — CARDNAME can't attack or block unless there are four or more card types among cards in your graveyard. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigMill | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, you may mill a card. (You may put the top card of your library into your graveyard.) +SVar:TrigMill:DB$ Mill | NumCards$ 1 | Defined$ You | Optional$ True +SVar:X:Count$Delirium.0.1 +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Delirium — Patchwork Beastie can't attack or block unless there are four or more card types among cards in your graveyard.\nAt the beginning of your upkeep, you may mill a card. (You may put the top card of your library into your graveyard.) diff --git a/forge-gui/res/cardsfolder/upcoming/peculiar_lighthouse.txt b/forge-gui/res/cardsfolder/upcoming/peculiar_lighthouse.txt new file mode 100644 index 00000000000..433b7648ca9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/peculiar_lighthouse.txt @@ -0,0 +1,8 @@ +Name:Peculiar Lighthouse +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo U R | SpellDescription$ Add {U} or {R}. +Oracle:Peculiar Lighthouse enters tapped unless a player has 13 or less life.\n{T}: Add {U} or {R}. diff --git a/forge-gui/res/cardsfolder/upcoming/peer_past_the_veil.txt b/forge-gui/res/cardsfolder/upcoming/peer_past_the_veil.txt new file mode 100644 index 00000000000..be9b090efc5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/peer_past_the_veil.txt @@ -0,0 +1,7 @@ +Name:Peer Past the Veil +ManaCost:2 R G +Types:Instant +A:SP$ Discard | Mode$ Hand | SubAbility$ DBDraw | SpellDescription$ Discard your hand. Then draw X cards, where X is the number of card types among cards in your graveyard. +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ X +SVar:X:Count$ValidGraveyard Card.YouOwn$CardTypes +Oracle:Discard your hand. Then draw X cards, where X is the number of card types among cards in your graveyard. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/phenomenon_investigators.txt b/forge-gui/res/cardsfolder/upcoming/phenomenon_investigators.txt new file mode 100644 index 00000000000..1d65137dd84 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/phenomenon_investigators.txt @@ -0,0 +1,17 @@ +Name:Phenomenon Investigators +ManaCost:2 U B +Types:Creature Human Detective +PT:3/4 +K:ETBReplacement:Other:BelieveOrDoubt +SVar:BelieveOrDoubt:DB$ GenericChoice | Choices$ Believe,Doubt | Defined$ You | SetChosenMode$ True | ShowChoice$ ExceptSelf | SpellDescription$ As CARDNAME enters, enters, choose Believe or Doubt. +SVar:Believe:DB$ Pump | SpellDescription$ Believe +SVar:Doubt:DB$ Pump | SpellDescription$ Doubt +S:Mode$ Continuous | Affected$ Card.Self+ChosenModeBelieve | AddTrigger$ BelieveTrigger | Description$ • Believe — Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token. +S:Mode$ Continuous | Affected$ Card.Self+ChosenModeDoubt | AddTrigger$ DoubtTrigger | Description$ • Doubt — At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card. +SVar:BelieveTrigger:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl+nonToken | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ b_2_2_e_horror | TokenOwner$ You +SVar:DoubtTrigger:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card. +SVar:TrigReturn:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | Hidden$ True | ChangeType$ Permanent.nonLand+YouOwn | ChoiceOptional$ True | RememberChanged$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:As Phenomenon Investigators enters, choose Believe or Doubt.\n• Believe — Whenever a nontoken creature you control dies, create a 2/2 black Horror enchantment creature token.\n• Doubt — At the beginning of your end step, you may return a nonland permanent you own to your hand. If you do, draw a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/piggy_bank.txt b/forge-gui/res/cardsfolder/upcoming/piggy_bank.txt new file mode 100644 index 00000000000..cb8254ebc64 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/piggy_bank.txt @@ -0,0 +1,8 @@ +Name:Piggy Bank +ManaCost:1 R +Types:Artifact Creature Boar Toy +PT:3/2 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, create a Treasure token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_treasure_sac | TokenOwner$ You +DeckHas:Ability$Token +Oracle:When Piggy Bank dies, create a Treasure token. (It's an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.") \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/piranha_fly.txt b/forge-gui/res/cardsfolder/upcoming/piranha_fly.txt new file mode 100644 index 00000000000..deb3666f4bb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/piranha_fly.txt @@ -0,0 +1,8 @@ +Name:Piranha Fly +ManaCost:1 U +Types:Creature Fish Insect +PT:2/1 +K:Flying +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. +SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True +Oracle:Flying\nPiranha Fly enters tapped. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/popular_egotist.txt b/forge-gui/res/cardsfolder/upcoming/popular_egotist.txt new file mode 100644 index 00000000000..7938233e39c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/popular_egotist.txt @@ -0,0 +1,10 @@ +Name:Popular Egotist +ManaCost:2 B +Types:Creature Human Rogue +PT:3/2 +A:AB$ Pump | Cost$ 1 B Sac<1/Creature.Other;Enchantment.Other/another creature or enchantment> | Defined$ Self | KW$ Indestructible | SubAbility$ DBTap | SpellDescription$ CARDNAME gains indestructible until end of turn. Tap it. (Damage and effects that say "destroy" don't destroy it.) +SVar:DBTap:DB$ Tap | Defined$ Self +T:Mode$ Sacrificed | ValidCard$ Permanent.YouCtrl | Execute$ TrigLoseLife | TriggerZones$ Battlefield | ValidPlayer$ You | TriggerDescription$ Whenever you sacrifice a permanent, target opponent loses 1 life and you gain 1 life. +SVar:TrigLoseLife:DB$ LoseLife | ValidTgts$ Opponent | TgtPrompt$ Choose an opponent to lose life | LifeAmount$ 1 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 +Oracle:{1}{B}, Sacrifice another creature or enchantment: Popular Egotist gains indestructible until end of turn. Tap it. (Damage and effects that say "destroy" don't destroy it.)\nWhenever you sacrifice a permanent, target opponent loses 1 life and you gain 1 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/ragged_playmate.txt b/forge-gui/res/cardsfolder/upcoming/ragged_playmate.txt new file mode 100644 index 00000000000..6f7a573e0e3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ragged_playmate.txt @@ -0,0 +1,7 @@ +Name:Ragged Playmate +ManaCost:1 R +Types:Artifact Creature Toy +PT:2/2 +A:AB$ Effect | Cost$ 1 T | ValidTgts$ Creature.powerLE2 | TgtPrompt$ Select target creature with power 2 or less | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | StaticAbilities$ Unblockable | AILogic$ Pump | StackDescription$ {c:Targeted} can't be blocked this turn. | SpellDescription$ Target creature with power 2 or less can't be blocked this turn. +SVar:Unblockable:Mode$ CantBlockBy | ValidAttacker$ Card.IsRemembered | Description$ This creature can't be blocked this turn. +Oracle:{1}, {T}: Target creature with power 2 or less can't be blocked this turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/raucous_carnival.txt b/forge-gui/res/cardsfolder/upcoming/raucous_carnival.txt new file mode 100644 index 00000000000..786051318ba --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/raucous_carnival.txt @@ -0,0 +1,8 @@ +Name:Raucous Carnival +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo R W | SpellDescription$ Add {R} or {W}. +Oracle:Raucous Carnival enters tapped unless a player has 13 or less life.\n{T}: Add {R} or {W}. diff --git a/forge-gui/res/cardsfolder/upcoming/razorkin_hordecaller.txt b/forge-gui/res/cardsfolder/upcoming/razorkin_hordecaller.txt new file mode 100644 index 00000000000..1e8e7b5e716 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/razorkin_hordecaller.txt @@ -0,0 +1,9 @@ +Name:Razorkin Hordecaller +ManaCost:4 R +Types:Creature Human Clown Berserker +PT:4/4 +K:Haste +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, create a 1/1 red Gremlin creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_1_1_gremlin | TokenOwner$ You +DeckHas:Ability$Token +Oracle:Haste\nWhenever you attack, create a 1/1 red Gremlin creature token. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/razorkin_needlehead.txt b/forge-gui/res/cardsfolder/upcoming/razorkin_needlehead.txt new file mode 100644 index 00000000000..1b993b6f02d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/razorkin_needlehead.txt @@ -0,0 +1,8 @@ +Name:Razorkin Needlehead +ManaCost:R R +Types:Creature Human Assassin +PT:2/2 +S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ First Strike | Condition$ PlayerTurn | Description$ CARDNAME has first strike during your turn. +T:Mode$ Drawn | ValidCard$ Card.OppOwn | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever an opponent draws a card, CARDNAME deals 1 damage to them. +SVar:TrigDamage:DB$ DealDamage | Defined$ TriggeredPlayer | NumDmg$ 1 +Oracle:Razorkin Needlehead has first strike during your turn.\nWhenever an opponent draws a card, Razorkin Needlehead deals 1 damage to them. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/razortrap_gorge.txt b/forge-gui/res/cardsfolder/upcoming/razortrap_gorge.txt new file mode 100644 index 00000000000..9ae51e16718 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/razortrap_gorge.txt @@ -0,0 +1,8 @@ +Name:Razortrap Gorge +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo B R | SpellDescription$ Add {B} or {R}. +Oracle:Razortrap Gorge enters tapped unless a player has 13 or less life.\n{T}: Add {B} or {R}. diff --git a/forge-gui/res/cardsfolder/upcoming/reality_is_mine_to_control.txt b/forge-gui/res/cardsfolder/upcoming/reality_is_mine_to_control.txt new file mode 100644 index 00000000000..da1ad12e46b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/reality_is_mine_to_control.txt @@ -0,0 +1,8 @@ +Name:Reality Is Mine to Control +ManaCost:no cost +Types:Ongoing Scheme +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigAbandon | TriggerZones$ Command | TriggerDescription$ Whenever you cast a spell, you may abandon this scheme. If you do, copy that spell, and you may choose new targets for the copy. +SVar:TrigAbandon:DB$ Abandon | Optional$ True | RememberAbandoned$ True | SubAbility$ DBCopy +SVar:DBCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nWhenever you cast a spell, you may abandon this scheme. If you do, copy that spell, and you may choose new targets for the copy. diff --git a/forge-gui/res/cardsfolder/upcoming/redress_fate.txt b/forge-gui/res/cardsfolder/upcoming/redress_fate.txt new file mode 100644 index 00000000000..7df3c6ccba9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/redress_fate.txt @@ -0,0 +1,8 @@ +Name:Redress Fate +ManaCost:6 W W +Types:Sorcery +A:SP$ ChangeZoneAll | ChangeType$ Artifact.YouOwn,Enchantment.YouOwn | Origin$ Graveyard | Destination$ Battlefield | SpellDescription$ Return all artifact and enchantment cards from your graveyard to the battlefield. +K:Miracle:3 W +DeckNeeds:Type$Artifact|Enchantment +DeckHas:Ability$Graveyard +Oracle:Return all artifact and enchantment cards from your graveyard to the battlefield.\nMiracle {3}{W} (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/reluctant_role_model.txt b/forge-gui/res/cardsfolder/upcoming/reluctant_role_model.txt new file mode 100644 index 00000000000..dee1324f87d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/reluctant_role_model.txt @@ -0,0 +1,9 @@ +Name:Reluctant Role Model +ManaCost:1 W +Types:Creature Human Survivor +PT:2/2 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigPutCounter1 | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, put a flying, lifelink, or +1/+1 counter on it. +SVar:TrigPutCounter1:DB$ PutCounter | CounterType$ Flying,Lifelink,P1P1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+HasCounters,Creature.Other+YouCtrl+HasCounters | TriggerZones$ Battlefield | Execute$ TrigPutCounter2 | TriggerDescription$ Whenever CARDNAME or another creature you control dies, if it had counters on it, put those counters on up to one target creature. +SVar:TrigPutCounter2:DB$ PutCounter | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose target creature | ValidTgts$ Creature | CounterType$ EachFromSource | EachFromSource$ TriggeredCardLKICopy +Oracle:Survival — At the beginning of your second main phase, if Reluctant Role Model is tapped, put a flying, lifelink, or +1/+1 counter on it.\nWhenever Reluctant Role Model or another creature you control dies, if it had counters on it, put those counters on up to one target creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/resurrected_cultist.txt b/forge-gui/res/cardsfolder/upcoming/resurrected_cultist.txt new file mode 100644 index 00000000000..6194e206c49 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/resurrected_cultist.txt @@ -0,0 +1,8 @@ +Name:Resurrected Cultist +ManaCost:2 B +Types:Creature Human Cleric +PT:4/1 +A:AB$ ChangeZone | Cost$ 2 B B | PrecostDesc$ Delirium — | Activation$ Delirium | Origin$ Graveyard | Destination$ Battlefield | WithCountersType$ FINALITY | ActivationZone$ Graveyard | SorcerySpeed$ True | SpellDescription$ Return CARDNAME from your graveyard to the battlefield with a finality counter on it. Activate only if there are four or more card types among cards in your graveyard and only as a sorcery. (If a creature with a finality counter on it would die, exile it instead.) +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Delirium — {2}{B}{B}: Return Resurrected Cultist from your graveyard to the battlefield with a finality counter on it. Activate only if there are four or more card types among cards in your graveyard and only as a sorcery. (If a creature with a finality counter on it would die, exile it instead.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/rite_of_the_moth.txt b/forge-gui/res/cardsfolder/upcoming/rite_of_the_moth.txt new file mode 100644 index 00000000000..50f884a84e8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rite_of_the_moth.txt @@ -0,0 +1,7 @@ +Name:Rite of the Moth +ManaCost:1 W B B +Types:Sorcery +K:Flashback:3 W W B +A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouCtrl | WithCountersType$ FINALITY | SpellDescription$ Return target creature card from your graveyard to the battlefield with a finality counter on it. (If a creature with a finality counter on it would die, exile it instead.) +SVar:DiscardMe:1 +Oracle:Return target creature card from your graveyard to the battlefield with a finality counter on it. (If a creature with a finality counter on it would die, exile it instead.)\nFlashback {3}{W}{W}{B} (You may cast this card from your graveyard for its flashback cost. Then exile it.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/rootwise_survivor.txt b/forge-gui/res/cardsfolder/upcoming/rootwise_survivor.txt new file mode 100644 index 00000000000..3d70c8f1d7b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rootwise_survivor.txt @@ -0,0 +1,10 @@ +Name:Rootwise Survivor +Types:Creature Human Survivor +ManaCost:3 G G +PT:3/4 +K:Haste +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, put three +1/+1 counters on up to one target land you control. That land becomes a 0/0 Elemental creature in addition to its other types. It gains haste until your next turn. +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Land.YouCtrl | TgtPrompt$ Select target land you control | TargetMin$ 0 | TargetMax$ 1 | CounterType$ P1P1 | CounterNum$ 3 | SubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Power$ 0 | Toughness$ 0 | Types$ Creature,Elemental | Duration$ Permanent | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Keywords$ Haste | Defined$ Targeted | Duration$ UntilYourNextTurn +Oracle:Survival — At the beginning of your second main phase, if Rootwise Survivor is tapped, put three +1/+1 counters on up to one target land you control. That land becomes a 0/0 Elemental creature in addition to its other types. It gains haste until your next turn. diff --git a/forge-gui/res/cardsfolder/upcoming/rot_like_the_scum_you_are.txt b/forge-gui/res/cardsfolder/upcoming/rot_like_the_scum_you_are.txt new file mode 100644 index 00000000000..152e5842b77 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rot_like_the_scum_you_are.txt @@ -0,0 +1,9 @@ +Name:Rot Like the Scum You Are +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigToken | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, create a 2/2 green Ooze creature token, then put a number of +1/+1 counters on it equal to the number of lands your opponents control. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_2_2_ooze | RememberTokens$ True | TokenOwner$ You | SubAbility$ DBPutCounter +SVar:DBPutCounter:DB$ PutCounter | Defined$ Remembered | CounterNum$ X | CounterType$ P1P1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$Valid Land.OppCtrl +Oracle:When you set this scheme in motion, create a 2/2 green Ooze creature token, then put a number of +1/+1 counters on it equal to the number of lands your opponents control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/savior_of_the_small.txt b/forge-gui/res/cardsfolder/upcoming/savior_of_the_small.txt new file mode 100644 index 00000000000..bea5f35b5ca --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/savior_of_the_small.txt @@ -0,0 +1,7 @@ +Name:Savior of the Small +Types:Creature Kor Survivor +ManaCost:3 W +PT:3/4 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, return target creature card with mana value 3 or less from your graveyard to your hand. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Creature.YouOwn+cmcLE3 | TgtPrompt$ Select target creature card with mana value 3 or less +Oracle:Survival — At the beginning of your second main phase, if Savior of the Small is tapped, return target creature card with mana value 3 or less from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/saw.txt b/forge-gui/res/cardsfolder/upcoming/saw.txt new file mode 100644 index 00000000000..b1e66c2133b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/saw.txt @@ -0,0 +1,8 @@ +Name:Saw +ManaCost:2 +Types:Artifact Equipment +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | Description$ Equipped creature gets +2/+0. +T:Mode$ Attacks | ValidCard$ Card.EquippedBy | Execute$ TrigDraw | TriggerDescription$ Whenever equipped creature attacks, you may sacrifice a permanent other than that creature or CARDNAME. If you do, draw a card. +SVar:TrigDraw:AB$ Draw | Cost$ Sac<1/Permanent.Other+NotDefinedTriggeredAttacker/permanent other than the triggered attacker or CARDNAME> +K:Equip:2 +Oracle:Equipped creature gets +2/+0.\nWhenever equipped creature attacks, you may sacrifice a permanent other than that creature or Saw. If you do, draw a card.\nEquip {2} ({2}: Attach to target creature you control. Equip only as a sorcery.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/sawblade_skinripper.txt b/forge-gui/res/cardsfolder/upcoming/sawblade_skinripper.txt new file mode 100644 index 00000000000..559af866bc4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sawblade_skinripper.txt @@ -0,0 +1,12 @@ +Name:Sawblade Skinripper +ManaCost:1 B R +Types:Creature Human Assassin +PT:3/2 +K:Menace +A:AB$ PutCounter | Cost$ 2 Sac<1/Creature.Other;Enchantment.Other/another creature or enchantment> | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GT0 | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your end step, if you sacrificed one or more permanents this turn, CARDNAME deals that much damage to any target. +SVar:TrigDealDamage:DB$ DealDamage | NumDmg$ X | ValidTgts$ Any +SVar:X:PlayerCountPropertyYou$SacrificedThisTurn Permanent +DeckHints:Ability$Investigate +DeckHas:Ability$Investigate|Token +Oracle:Menace\n{2}, Sacrifice another creature or enchantment: Put a +1/+1 counter on Sawblade Skinripper.\nAt the beginning of your end step, if you sacrificed one or more permanents this turn, Sawblade Skinripper deals that much damage to any target. diff --git a/forge-gui/res/cardsfolder/upcoming/say_its_name.txt b/forge-gui/res/cardsfolder/upcoming/say_its_name.txt new file mode 100644 index 00000000000..6f6abae2acc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/say_its_name.txt @@ -0,0 +1,9 @@ +Name:Say Its Name +ManaCost:1 G +Types:Sorcery +A:SP$ Mill | NumCards$ 3 | Defined$ You | SubAbility$ DBChangeZone | SpellDescription$ Mill three cards. Then you may return a creature or land card from your graveyard to your hand. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeType$ Creature.YouOwn,Land.YouOwn | ChangeNum$ 1 | Hidden$ True +A:AB$ ChangeZone | Cost$ ExileFromGrave<1/CARDNAME> ExileFromGrave<2/Card.Other+YouOwn+namedSay Its Name> | ActivationZone$ Graveyard | Hidden$ True | Origin$ Library | OriginAlternative$ Graveyard,Hand | Destination$ Battlefield | ChangeType$ Card.YouOwn+namedAltanak; the Thrice-Called | SorcerySpeed$ True | SpellDescription$ Search your graveyard, hand, and/or library for a card named Altanak, the Thrice-Called and put it onto the battlefield. If you search your library this way, shuffle. Activate only as a sorcery. +DeckHas:Ability$Graveyard +DeckHints:Name$Altanak, the Thrice-Called +Oracle:Mill three cards. Then you may return a creature or land card from your graveyard to your hand.\nExile this card and two other cards named Say Its Name from your graveyard: Search your graveyard, hand, and/or library for a card named Altanak, the Thrice-Called and put it onto the battlefield. If you search your library this way, shuffle. Activate only as a sorcery. diff --git a/forge-gui/res/cardsfolder/upcoming/scrabbling_skullcrab.txt b/forge-gui/res/cardsfolder/upcoming/scrabbling_skullcrab.txt new file mode 100644 index 00000000000..c3eb6d6daf0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/scrabbling_skullcrab.txt @@ -0,0 +1,9 @@ +Name:Scrabbling Skullcrab +ManaCost:U +Types:Creature Crab Skeleton +PT:0/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.) +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigMill | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.) +SVar:TrigMill:DB$ Mill | NumCards$ 2 | ValidTgts$ Player | TgtPrompt$ Select target player +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/seized_from_slumber.txt b/forge-gui/res/cardsfolder/upcoming/seized_from_slumber.txt new file mode 100644 index 00000000000..bc5e6954ff3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/seized_from_slumber.txt @@ -0,0 +1,6 @@ +Name:Seized from Slumber +ManaCost:4 W +Types:Instant +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 3 | EffectZone$ All | ValidTarget$ Creature.tapped | Description$ This spell costs {3} less to cast if it targets a tapped creature. +A:SP$ Destroy | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Destroy target creature. +Oracle:This spell costs {3} less to cast if it targets a tapped creature.\nDestroy target creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/shardmages_rescue.txt b/forge-gui/res/cardsfolder/upcoming/shardmages_rescue.txt new file mode 100644 index 00000000000..6a7cc0444fe --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/shardmages_rescue.txt @@ -0,0 +1,9 @@ +Name:Shardmage's Rescue +ManaCost:W +Types:Enchantment Aura +K:Flash +K:Enchant creature you control +A:SP$ Attach | Cost$ W | ValidTgts$ Creature.YouCtrl | AILogic$ Pump +S:Mode$ Continuous | IsPresent$ Card.Self+ThisTurnEntered | Affected$ Creature.EnchantedBy | AddKeyword$ Hexproof | Description$ As long as CARDNAME entered this turn, enchanted creature has hexproof. +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Enchanted creature gets +1/+1. +Oracle:Flash\nEnchant creature you control\nAs long as Shardmage's Rescue entered this turn, enchanted creature has hexproof.\nEnchanted creature gets +1/+1. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/shepherding spirits.txt b/forge-gui/res/cardsfolder/upcoming/shepherding spirits.txt new file mode 100644 index 00000000000..b4fc661465f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/shepherding spirits.txt @@ -0,0 +1,7 @@ +Name:Shepherding Spirits +ManaCost:4 W W +Types:Creature Spirit +PT:4/5 +K:Flying +K:TypeCycling:Plains:2 +Oracle:Flying\nPlainscycling {2} ({2}, Discard this card: Search your library for a Plains card, reveal it, put it into your hand, then shuffle.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/shrewd_storyteller.txt b/forge-gui/res/cardsfolder/upcoming/shrewd_storyteller.txt new file mode 100644 index 00000000000..ac67faca4db --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/shrewd_storyteller.txt @@ -0,0 +1,7 @@ +Name:Shrewd Storyteller +Types:Creature Human Survivor +ManaCost:1 G W +PT:3/3 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, put a +1/+1 counter on target creature. +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 +Oracle:Survival — At the beginning of your second main phase, if Shrewd Storyteller is tapped, put a +1/+1 counter on target creature. diff --git a/forge-gui/res/cardsfolder/upcoming/shriekwood_devourer.txt b/forge-gui/res/cardsfolder/upcoming/shriekwood_devourer.txt new file mode 100644 index 00000000000..b97fb45fb70 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/shriekwood_devourer.txt @@ -0,0 +1,9 @@ +Name:Shriekwood Devourer +ManaCost:5 G G +Types:Creature Treefolk +PT:7/5 +K:Trample +T:Mode$ AttackersDeclared | ValidAttackers$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ Whenever you attack with one or more creatures, untap up to X lands, where X is the greatest power among those creatures. +SVar:TrigUntap:DB$ Untap | UntapUpTo$ True | UntapType$ Land | Amount$ X +SVar:X:TriggerObjectsAttackers$GreatestPower +Oracle:Trample\nWhenever you attack with one or more creatures, untap up to X lands, where X is the greatest power among those creatures. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/silent_hallcreeper.txt b/forge-gui/res/cardsfolder/upcoming/silent_hallcreeper.txt new file mode 100644 index 00000000000..0b68a4fbf76 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/silent_hallcreeper.txt @@ -0,0 +1,11 @@ +Name:Silent Hallcreeper +ManaCost:1 U +Types:Enchantment Creature Horror +PT:1/1 +S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't be blocked. +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigCharm | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, ABILITY +SVar:TrigCharm:DB$ Charm | Choices$ DBPutCounter,DBDraw,DBClone | ChoiceRestriction$ ThisGame | CharmNum$ 1 +SVar:DBPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Put two +1/+1 counters on CARDNAME. +SVar:DBDraw:DB$ Draw | SpellDescription$ Draw a card. +SVar:DBClone:DB$ Clone | ValidTgts$ Creature.Other+YouCtrl | TgtPrompt$ Select another target creature you control to copy | SpellDescription$ CARDNAME becomes a copy of another target creature you control. +Oracle:Silent Hallcreeper can't be blocked.\nWhenever Silent Hallcreeper deals combat damage to a player, choose one that hasn't been chosen -\n• Put two +1/+1 counters on Silent Hallcreeper.\n• Draw a card.\n• Silent Hallcreeper becomes a copy of another target creature you control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/skullsnap_nuisance.txt b/forge-gui/res/cardsfolder/upcoming/skullsnap_nuisance.txt new file mode 100644 index 00000000000..073406f1f51 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/skullsnap_nuisance.txt @@ -0,0 +1,10 @@ +Name:Skullsnap Nuisance +ManaCost:U B +Types:Creature Insect Skeleton +PT:1/4 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.) +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.). +SVar:TrigSurveil:DB$ Surveil | Amount$ 1 +DeckNeeds:Type$Enchantment +Oracle:Flying\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/slavering_branchsnapper.txt b/forge-gui/res/cardsfolder/upcoming/slavering_branchsnapper.txt new file mode 100644 index 00000000000..2a0ce3cc972 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/slavering_branchsnapper.txt @@ -0,0 +1,7 @@ +Name:Slavering Branchsnapper +ManaCost:4 G G +Types:Creature Lizard +PT:7/6 +K:Trample +K:TypeCycling:Forest:2 +Oracle:Trample\nForestcycling {2} ({2}, Discard this card: Search your library for a Forest card, reveal it, put it into your hand, then shuffle.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/soaring_lightbringer.txt b/forge-gui/res/cardsfolder/upcoming/soaring_lightbringer.txt new file mode 100644 index 00000000000..6dcf2075361 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/soaring_lightbringer.txt @@ -0,0 +1,10 @@ +Name:Soaring Lightbringer +ManaCost:4 W +Types:Enchantment Creature Bird Glimmer +PT:4/5 +K:Flying +S:Mode$ Continuous | Affected$ Enchantment.Creature+Other+YouCtrl | AddKeyword$ Flying | Description$ Other enchantment creatures you control have flying. +T:Mode$ AttackersDeclaredOneTarget | ValidAttackers$ Creature.YouCtrl | AttackedTarget$ Player | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack a player, create a 1/1 white Glimmer enchantment creature token that's tapped and attacking that player. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_e_glimmer | TokenOwner$ You | TokenTapped$ True | TokenAttacking$ TriggeredAttackedTarget +SVar:PlayMain1:TRUE +Oracle:Flying\nOther enchantment creatures you control have flying.\nWhenever you attack a player, create a 1/1 white Glimmer enchantment creature token that's tapped and attacking that player. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/spineseeker_centipede.txt b/forge-gui/res/cardsfolder/upcoming/spineseeker_centipede.txt new file mode 100644 index 00000000000..c4d23d96481 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/spineseeker_centipede.txt @@ -0,0 +1,10 @@ +Name:Spineseeker Centipede +ManaCost:2 G +Types:Creature Insect +PT:2/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters, search your library for a basic land card, reveal it, put it into your hand, then shuffle. +SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Land.Basic | ChangeNum$ 1 +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 1 | AddToughness$ 2 | AddKeyword$ Vigilance | Condition$ Delirium | Description$ Delirium — CARDNAME gets +1/+2 and has vigilance as long as there are four or more card types among cards in your graveyard. +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:When Spineseeker Centipede enters, search your library for a basic land card, reveal it, put it into your hand, then shuffle.\nDelirium — Spineseeker Centipede gets +1/+2 and has vigilance as long as there are four or more card types among cards in your graveyard. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/split_up.txt b/forge-gui/res/cardsfolder/upcoming/split_up.txt new file mode 100644 index 00000000000..d7a52f15643 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/split_up.txt @@ -0,0 +1,7 @@ +Name:Split Up +ManaCost:1 W W +Types:Sorcery +A:SP$ Charm | Choices$ DBDestroyAll,DBDestroyAll2 +SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Creature.tapped | SpellDescription$ Destroy all tapped creatures. +SVar:DBDestroyAll2:DB$ DestroyAll | ValidCards$ Creature.untapped | SpellDescription$ Destroy all untapped creatures. +Oracle:Choose one —\n• Destroy all tapped creatures.\n• Destroy all untapped creatures. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/splitskin_doll.txt b/forge-gui/res/cardsfolder/upcoming/splitskin_doll.txt new file mode 100644 index 00000000000..c4aad4dd721 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/splitskin_doll.txt @@ -0,0 +1,8 @@ +Name:Splitskin Doll +ManaCost:1 W +Types:Artifact Creature Toy +PT:2/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters, draw a card. Then discard a card unless you control another creature with power 2 or less. +SVar:TrigDraw:DB$ Draw | SubAbility$ DBDiscard +SVar:DBDiscard:DB$ Discard | NumCards$ 1 | Mode$ TgtChoose | ConditionPresent$ Creature.Other+YouCtrl+powerLE2 | ConditionCompare$ EQ0 +Oracle:When Splitskin Doll enters, draw a card. Then discard a card unless you control another creature with power 2 or less. diff --git a/forge-gui/res/cardsfolder/upcoming/stalked_researcher.txt b/forge-gui/res/cardsfolder/upcoming/stalked_researcher.txt new file mode 100644 index 00000000000..c737d968208 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/stalked_researcher.txt @@ -0,0 +1,11 @@ +Name:Stalked Researcher +ManaCost:1 U +Types:Creature Human Wizard +PT:3/3 +K:Defender +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME can attack this turn as though it didn't have defender. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigEffect | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME can attack this turn as though it didn't have defender. +SVar:TrigEffect:DB$ Effect | StaticAbilities$ CanAttack | ForgetOnMoved$ Battlefield +SVar:CanAttack:Mode$ CanAttackDefender | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE can attack this turn as though it didn't have defender. +DeckNeeds:Type$Enchantment +Oracle:Defender\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Stalker Researcher can attack this turn as though it didn't have defender. diff --git a/forge-gui/res/cardsfolder/upcoming/stay_hidden_stay_silent.txt b/forge-gui/res/cardsfolder/upcoming/stay_hidden_stay_silent.txt new file mode 100644 index 00000000000..7ba8bc712a4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/stay_hidden_stay_silent.txt @@ -0,0 +1,10 @@ +Name:Stay Hidden, Stay Silent +ManaCost:1 U +Types:Enchantment Aura +A:SP$ Attach | Cost$ 1 U | ValidTgts$ Creature | AILogic$ KeepTapped +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigTap | TriggerDescription$ When CARDNAME enters, tap enchanted creature. +SVar:TrigTap:DB$ Tap | Defined$ Enchanted +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ Enchanted creature doesn't untap during its controller's untap step. +A:AB$ ChangeZone | Cost$ 4 U U | Origin$ Battlefield | Destination$ Library | Shuffle$ True | Defined$ Enchanted | SorcerySpeed$ True | SubAbility$ DBDread | SpellDescription$ Shuffle enchanted creature into its owner's library, then manifest dread. Activate only as a sorcery. +SVar:DBDread:DB$ Manifest | Dread$ True | Defined$ You +Oracle:Enchant creature\nWhen Stay Hidden, Stay Silent enters, tap enchanted creature.\nEnchanted creature doesn't untap during its controller's untap step.\n{4}{U}{U}: Shuffle enchanted creature into its owner's library, then manifest dread. Activate only as a sorcery. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/strangled_cemetery.txt b/forge-gui/res/cardsfolder/upcoming/strangled_cemetery.txt new file mode 100644 index 00000000000..06641d6bf22 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/strangled_cemetery.txt @@ -0,0 +1,8 @@ +Name:Strangled Cemetery +ManaCost:no cost +Types:Land +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ LandTapped | ReplacementResult$ Updated | Description$ CARDNAME enters tapped unless a player has 13 or less life. +SVar:LandTapped:DB$ Tap | Defined$ Self | ETB$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GT13 +SVar:X:PlayerCountPlayers$LowestLifeTotal +A:AB$ Mana | Cost$ T | Produced$ Combo B G | SpellDescription$ Add {B} or {G}. +Oracle:Strangled Cemetery enters tapped unless a player has 13 or less life.\n{T}: Add {B} or {G}. diff --git a/forge-gui/res/cardsfolder/upcoming/the_jolly_balloon_man.txt b/forge-gui/res/cardsfolder/upcoming/the_jolly_balloon_man.txt new file mode 100644 index 00000000000..3fbf148f497 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_jolly_balloon_man.txt @@ -0,0 +1,8 @@ +Name:The Jolly Balloon Man +ManaCost:1 R W +Types:Legendary Creature Human Clown +PT:1/4 +K:Haste +A:AB$ CopyPermanent | Cost$ 1 T | ValidTgts$ Creature.Other+YouCtrl | TgtPrompt$ Select another target creature you control | SetPower$ 1 | SetToughness$ 1 | AddTypes$ Creature & Balloon | AddColors$ Red | AddKeywords$ Flying & Haste | SorcerySpeed$ True | AtEOT$ Sacrifice | AILogic$ BeforeCombat | SpellDescription$ Create a token that's a copy of another target creature you control, except it's a 1/1 red Balloon creature in addition to its other colors and types and it has flying and haste. Sacrifice it at the beginning of the next end step. Activate only as a sorcery. +SVar:UntapMe:True +Oracle:Haste\n{1}, {T}: Create a token that's a copy of another target creature you control, except it's a 1/1 red Balloon creature in addition to its other colors and types and it has flying and haste. Sacrifice it at the beginning of the next end step. Activate only as a sorcery. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/the_master_of_keys.txt b/forge-gui/res/cardsfolder/upcoming/the_master_of_keys.txt new file mode 100644 index 00000000000..49bc75d10a9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_master_of_keys.txt @@ -0,0 +1,12 @@ +Name:The Master of Keys +ManaCost:X W U B +Types:Legendary Enchantment Creature Horror +PT:3/3 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPutCounter | TriggerDescription$ When CARDNAME enters, put X +1/+1 counters on it and mill twice X cards. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBMill +SVar:DBMill:DB$ Mill | NumCards$ Y +S:Mode$ Continuous | Affected$ Enchantment.YouOwn | AffectedZone$ Graveyard | AddKeyword$ Escape:CardManaCost ExileFromGrave<3/Card.Other/other> | Description$ Each enchantment card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. (You may cast cards from your graveyard for their escape cost.) +SVar:X:Count$xPaid +SVar:Y:SVar$X/Twice +Oracle:Flying\nWhen The Master of Keys enters, put X +1/+1 counters on it and mill twice X cards.\nEach enchantment card in your graveyard has escape. The escape cost is equal to the card's mana cost plus exile three other cards from your graveyard. (You may cast cards from your graveyard for their escape cost.) diff --git a/forge-gui/res/cardsfolder/upcoming/the_mindskinner.txt b/forge-gui/res/cardsfolder/upcoming/the_mindskinner.txt new file mode 100644 index 00000000000..9af7a86b878 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_mindskinner.txt @@ -0,0 +1,9 @@ +Name:The Mindskinner +ManaCost:U U U +Types:Legendary Enchantment Creature Nightmare +PT:10/1 +S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | Description$ CARDNAME can't be blocked. +R:Event$ DamageDone | ActiveZones$ Battlefield | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Opponent | ReplaceWith$ Mill | PreventionEffect$ True | ExecuteMode$ PerTarget | Description$ If a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards. +SVar:Mill:DB$ Mill | Defined$ Opponent | NumCards$ X +SVar:X:ReplaceCount$DamageAmount +Oracle:The Mindskinner can't be blocked.\nIf a source you control would deal damage to an opponent, prevent that damage and each opponent mills that many cards. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/the_rollercrusher_ride.txt b/forge-gui/res/cardsfolder/upcoming/the_rollercrusher_ride.txt new file mode 100644 index 00000000000..3cf72e820ed --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_rollercrusher_ride.txt @@ -0,0 +1,9 @@ +Name:The Rollercrusher Ride +ManaCost:X 2 R +Types:Legendary Enchantment +R:Event$ DamageDone | Delirium$ True | ActiveZones$ Battlefield | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Permanent,Player | IsCombat$ False | ReplaceWith$ DamageReplace | Description$ Delirium — If a source you control would deal noncombat damage to a permanent or player while there are four or more card types among cards in your graveyard, it deals double that damage instead. +SVar:DamageReplace:DB$ ReplaceEffect | VarName$ DamageAmount | VarValue$ ReplaceCount$DamageAmount/Twice +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ When CARDNAME enters, it deals X damage to each of up to X target creatures. +SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | TargetMin$ 0 | TargetMax$ X | NumDmg$ X +SVar:X:Count$xPaid +Oracle:Delirium — If a source you control would deal noncombat damage to a permanent or player while there are four or more card types among cards in your graveyard, it deals double that damage instead.\nWhen The Rollercrusher Ride enters, it deals X damage to each of up to X target creatures. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/the_swarmweaver.txt b/forge-gui/res/cardsfolder/upcoming/the_swarmweaver.txt new file mode 100644 index 00000000000..894422d0d0a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_swarmweaver.txt @@ -0,0 +1,10 @@ +Name:The Swarmweaver +ManaCost:2 B G +Types:Legendary Artifact Creature Scarecrow +PT:2/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters, create two 1/1 black and green Insect creature tokens with flying. +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ bg_1_1_insect_flying | TokenOwner$ You +S:Mode$ Continuous | Condition$ Delirium | Affected$ Insect.YouCtrl,Spider.YouCtrl | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Deathtouch | Description$ Delirium — As long as there are four or more card types among cards in your graveyard, Insects and Spiders you control get +1/+1 and have deathtouch. +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:When The Swarmweaver enters, create two 1/1 black and green Insect creature tokens with flying.\nDelirium — As long as there are four or more card types among cards in your graveyard, Insects and Spiders you control get +1/+1 and have deathtouch. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/the_tale_of_tamiyo.txt b/forge-gui/res/cardsfolder/upcoming/the_tale_of_tamiyo.txt new file mode 100644 index 00000000000..d12f5317b61 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_tale_of_tamiyo.txt @@ -0,0 +1,15 @@ +Name:The Tale of Tamiyo +ManaCost:2 U +Types:Legendary Enchantment Saga +K:Chapter:4:DBRepeat,DBRepeat,DBRepeat,DBChangeZone +SVar:DBRepeat:DB$ Repeat | RepeatSubAbility$ DBCleanAndGrind | MaxRepeat$ MaxRepeats | RepeatCheckSVar$ MilledSharesType | RepeatSVarCompare$ GE2 | SubAbility$ DBCleanup | SpellDescription$ Mill two cards. If two cards that share a card type were milled this way, draw a card and repeat this process. +SVar:DBCleanAndGrind:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBGrind +SVar:DBGrind:DB$ Mill | NumCards$ 2 | NoReveal$ True | RememberMilled$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | ConditionCheckSVar$ MilledSharesType | ConditionSVarCompare$ GE2 +SVar:MaxRepeats:Count$InYourLibrary +SVar:MilledSharesType:Remembered$Valid Card.sharesCardTypeWithOther Remembered +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | TargetMin$ 0 | TargetMax$ Yard | TgtPrompt$ Select any number of target instant, sorcery, and/or Tamiyo planeswalker cards in your graveyard | ValidTgts$ Instant.YouOwn,Sorcery.YouOwn,Planeswalker.Tamiyo+YouOwn | RememberChanged$ True | SubAbility$ DBPlay | StackDescription$ SpellDescription | SpellDescription$ Exile any number of target instant, sorcery, and/or Tamiyo planeswalker cards from your graveyard. Copy them. You may cast any number of the copies. +SVar:DBPlay:DB$ Play | Valid$ Card.IsRemembered | ValidZone$ Exile | Controller$ You | CopyCard$ True | ValidSA$ Spell | Optional$ True | Amount$ All | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Yard:Count$InYourYard +Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.)\nI, II, III — Mill two cards. If two cards that share a card type were milled this way, draw a card and repeat this process.\nIV — Exile any number of target instant, sorcery, and/or Tamiyo planeswalker cards from your graveyard. Copy them. You may cast any number of the copies. diff --git a/forge-gui/res/cardsfolder/upcoming/they_came_from_the_pipes.txt b/forge-gui/res/cardsfolder/upcoming/they_came_from_the_pipes.txt new file mode 100644 index 00000000000..0fc59a0c3bb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/they_came_from_the_pipes.txt @@ -0,0 +1,8 @@ +Name:They Came from the Pipes +ManaCost:4 U +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Times$ 2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.faceDown+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a face-down creature you control enters, draw a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 +Oracle:When They Came from the Pipes enters, manifest dread twice. (To manifest dread, look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\nWhenever a face-down creature you control enters, draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/thornspire_verge.txt b/forge-gui/res/cardsfolder/upcoming/thornspire_verge.txt new file mode 100644 index 00000000000..82c1f146df5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/thornspire_verge.txt @@ -0,0 +1,6 @@ +Name:Thornspire Verge +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}. +A:AB$ Mana | Cost$ T | Produced$ G | IsPresent$ Mountain.YouCtrl,Forest.YouCtrl | SpellDescription$ Add {G}. Activate only if you control a Mountain or a Forest. +Oracle:{T}: Add {R}.\n{T}: Add {G}. Activate only if you control a Mountain or a Forest. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/threats_around_every_corner.txt b/forge-gui/res/cardsfolder/upcoming/threats_around_every_corner.txt new file mode 100644 index 00000000000..0a0ee865f9c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/threats_around_every_corner.txt @@ -0,0 +1,8 @@ +Name:Threats Around Every Corner +ManaCost:3 G +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread. +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Permanent.faceDown+YouCtrl | Execute$ TrigChange | TriggerZones$ Battlefield | TriggerDescription$ Whenever a face-down permanent you control enters, search your library for a basic land card, put it onto the battlefield tapped, then shuffle. +SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Basic | ChangeNum$ 1 +Oracle:When Threats Around Every Corner enters, manifest dread.\nWhenever a face-down permanent you control enters, search your library for a basic land card, put it onto the battlefield tapped, then shuffle. diff --git a/forge-gui/res/cardsfolder/upcoming/time_bends_to_my_will.txt b/forge-gui/res/cardsfolder/upcoming/time_bends_to_my_will.txt new file mode 100644 index 00000000000..7e0c186982c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/time_bends_to_my_will.txt @@ -0,0 +1,6 @@ +Name:Time Bends to My Will +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigExtraTurn | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, take an extra turn after this one. Skip the untap step of that turn. +SVar:TrigExtraTurn:DB$ AddTurn | NumTurns$ 1 | SkipUntap$ True +Oracle:When you set this scheme in motion, take an extra turn after this one. Skip the untap step of that turn. diff --git a/forge-gui/res/cardsfolder/upcoming/trapped_in_the_screen.txt b/forge-gui/res/cardsfolder/upcoming/trapped_in_the_screen.txt new file mode 100644 index 00000000000..72d8ed346ae --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/trapped_in_the_screen.txt @@ -0,0 +1,8 @@ +Name:Trapped in the Screen +ManaCost:2 W +Types:Enchantment +K:Ward:2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target artifact, creature, or enchantment an opponent controls until CARDNAME leaves the battlefield. +SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Artifact.OppCtrl,Creature.OppCtrl,Enchantment.OppCtrl | TgtPrompt$ Select target artifact, creature, or enchantment an opponent controls | Duration$ UntilHostLeavesPlay +SVar:PlayMain1:TRUE +Oracle:Ward {2} (Whenever this enchantment becomes the target of a spell or ability an opponent controls, counter it unless that player pays {2}.)\nWhen Trapped in the Screen enters, exile target artifact, creature, or enchantment an opponent controls until Trapped in the Screen leaves the battlefield. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/trial_of_agony.txt b/forge-gui/res/cardsfolder/upcoming/trial_of_agony.txt new file mode 100644 index 00000000000..8649457d236 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/trial_of_agony.txt @@ -0,0 +1,9 @@ +Name:Trial of Agony +ManaCost:R +Types:Sorcery +A:SP$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select two target creatures controlled by the same opponent | TargetMin$ 2 | TargetMax$ 2 | TargetsFromSingleZone$ True | IsCurse$ True | RememberTargets$ True | SubAbility$ DBChoose | StackDescription$ SpellDescription | SpellDescription$ Choose two target creatures controlled by the same opponent. That player chooses one of those creatures. CARDNAME deals 5 damage to that creature, and the other can't block this turn. +SVar:DBChoose:DB$ ChooseCard | Defined$ TargetedController | Mandatory$ True | Choices$ Creature.IsRemembered | ChoiceTitle$ Choose one to take 5 damage | ForgetChosen$ True | SubAbility$ DBDealDamage +SVar:DBDealDamage:DB$ DealDamage | Defined$ ChosenCard | SubAbility$ DBCantBlock +SVar:DBCantBlock:DB$ Pump | Defined$ Remembered | KW$ HIDDEN CARDNAME can't block. | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Choose two target creatures controlled by the same opponent. That player chooses one of those creatures. Trial of Agony deals 5 damage to that creature, and the other can't block this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/tunnel_surveyor.txt b/forge-gui/res/cardsfolder/upcoming/tunnel_surveyor.txt new file mode 100644 index 00000000000..a951ee950e1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tunnel_surveyor.txt @@ -0,0 +1,7 @@ +Name:Tunnel Surveyor +ManaCost:2 U +Types:Creature Human Detective +PT:3/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters, create a 1/1 white Glimmer enchantment creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_e_glimmer | TokenOwner$ You +Oracle:When Tunnel Surveyor enters, create a 1/1 white Glimmer enchantment creature token. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/turn_inside_out.txt b/forge-gui/res/cardsfolder/upcoming/turn_inside_out.txt new file mode 100644 index 00000000000..55470ca38d6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/turn_inside_out.txt @@ -0,0 +1,7 @@ +Name:Turn Inside Out +ManaCost:R +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +3 | SubAbility$ DBDelayedTrigger | SpellDescription$ Target creature gets +3/+0 until end of turn. +SVar:DBDelayedTrigger:DB$ DelayedTrigger | Mode$ ChangesZone | RememberObjects$ Targeted | ValidCard$ Card.IsTriggerRemembered | Origin$ Battlefield | Destination$ Graveyard | ThisTurn$ True | Execute$ DBDread | SpellDescription$ When it dies this turn, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:DBDread:DB$ Manifest | Dread$ True | Defined$ You +Oracle:Target creature gets +3/+0 until end of turn. When it dies this turn, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/twist_reality.txt b/forge-gui/res/cardsfolder/upcoming/twist_reality.txt new file mode 100644 index 00000000000..30d0d766faa --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/twist_reality.txt @@ -0,0 +1,7 @@ +Name:Twist Reality +ManaCost:1 U U +Types:Instant +A:SP$ Charm | Choices$ DBCounter,DBDread +SVar:DBCounter:DB$ Counter | TargetType$ Spell | ValidTgts$ Card | TgtPrompt$ Counter target spell | SpellDescription$ Counter target spell. +SVar:DBDread:DB$ Manifest | Dread$ True | Defined$ You | SpellDescription$ Manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +Oracle:Choose one —\n• Counter target spell.\n• Manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/tyvar_the_pummeler.txt b/forge-gui/res/cardsfolder/upcoming/tyvar_the_pummeler.txt new file mode 100644 index 00000000000..88d26760a6a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tyvar_the_pummeler.txt @@ -0,0 +1,9 @@ +Name:Tyvar, the Pummeler +ManaCost:1 G G +Types:Legendary Creature Elf Warrior +PT:3/3 +A:AB$ Pump | Cost$ tapXType<1/Creature.Other> | Defined$ Self | KW$ Indestructible | SubAbility$ DBTap | SpellDescription$ CARDNAME gains indestructible until end of turn. Tap it. +SVar:DBTap:DB$ Tap | Defined$ Self +A:AB$ PumpAll | Cost$ 2 G G G | ValidCards$ Creature.YouCtrl | NumAtt$ +X | NumDef$ +X | SpellDescription$ Creatures you control get +X/+X until end of turn, where X is the greatest power among creatures you control. +SVar:X:Count$Valid Creature.YouCtrl$GreatestPower +Oracle:Tap another untapped creature you control: Tyvar, the Pummeler gains indestructible until end of turn. Tap it.\n{3}{G}{G}: Creatures you control get +X/+X until end of turn, where X is the greatest power among creatures you control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/unable_to_scream.txt b/forge-gui/res/cardsfolder/upcoming/unable_to_scream.txt new file mode 100644 index 00000000000..677addcd255 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/unable_to_scream.txt @@ -0,0 +1,9 @@ +Name:Unable to Scream +ManaCost:U +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | ValidTgts$ Creature | AILogic$ Curse +S:Mode$ Continuous | Affected$ Card.EnchantedBy | SetPower$ 0 | SetToughness$ 2 | RemoveAllAbilities$ True | AddType$ Artifact & Creature & Toy | Description$ Enchanted creature loses all abilities and is a Toy artifact creature with base power and toughness 0/2 in addition to its other types. +R:Event$ TurnFaceUp | ValidCard$ Card.EnchantedBy+faceDown | Layer$ CantHappen | ActiveZones$ Battlefield | Description$ As long as enchanted creature is face down, it can't be turned face up. +DeckHas:Type$Toy +Oracle:Enchant creature\nEnchanted creature loses all abilities and is a Toy artifact creature with base power and toughness 0/2 in addition to its other types.\nAs long as enchanted creature is face down, it can't be turned face up. diff --git a/forge-gui/res/cardsfolder/upcoming/undead_sprinter.txt b/forge-gui/res/cardsfolder/upcoming/undead_sprinter.txt new file mode 100644 index 00000000000..9a44e4d46b5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/undead_sprinter.txt @@ -0,0 +1,16 @@ +Name:Undead Sprinter +ManaCost:B R +Types:Creature Zombie +PT:2/2 +K:Trample +K:Haste +S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Graveyard | AffectedZone$ Graveyard | MayPlay$ True | CheckSVar$ X | Description$ You may cast CARDNAME from your graveyard if a non-Zombie creature died this turn. If you do, CARDNAME enters with a +1/+1 counter on it. +T:Mode$ SpellCast | ValidCard$ Card.Self | ValidSA$ Spell.MayPlaySource | Static$ True | Execute$ DBEffect +SVar:DBEffect:DB$ Effect | ExileOnMoved$ Stack | ReplacementEffects$ ETBCreat | ExileOnMoved$ Stack +SVar:ETBCreat:Event$ Moved | ValidCard$ Card.EffectSource | Destination$ Battlefield | ReplaceWith$ DBPutP1P1 | ReplacementResult$ Updated | Description$ That creature enters with an additional +1/+1 counter on it. +SVar:DBPutP1P1:DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ True | CounterNum$ 1 | SubAbility$ DBExile +SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile +SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature.nonZombie +SVar:SacMe:3 +SVar:DiscardMe:3 +Oracle:Trample, haste\nYou may cast Undead Sprinter from your graveyard if a non-Zombie creature died this turn. If you do, Undead Sprinter enters with a +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/upcoming/under_the_skin.txt b/forge-gui/res/cardsfolder/upcoming/under_the_skin.txt new file mode 100644 index 00000000000..bb7c50a05b7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/under_the_skin.txt @@ -0,0 +1,6 @@ +Name:Under the Skin +ManaCost:2 G +Types:Sorcery +A:SP$ Manifest | Dread$ True | SubAbility$ DBChangeZone | SpellDescription$ Manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) You may return a permanent card from your graveyard to your hand. +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeType$ Permanent.YouOwn | Hidden$ True | Optional$ True +Oracle:Manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.)\nYou may return a permanent card from your graveyard to your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/unsettling_twins.txt b/forge-gui/res/cardsfolder/upcoming/unsettling_twins.txt new file mode 100644 index 00000000000..83c09545234 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/unsettling_twins.txt @@ -0,0 +1,7 @@ +Name:Unsettling Twins +ManaCost:3 W +Types:Creature Human +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDread | TriggerDescription$ When CARDNAME enters, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You +Oracle:When Unsettling Twins enters, manifest dread. (Look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/unstoppable_slasher.txt b/forge-gui/res/cardsfolder/upcoming/unstoppable_slasher.txt new file mode 100644 index 00000000000..d9cff7dcc22 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/unstoppable_slasher.txt @@ -0,0 +1,11 @@ +Name:Unstoppable Slasher +ManaCost:2 B +Types:Creature Zombie Assassin +PT:2/3 +K:Deathtouch +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigLoseLifeOpp | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, that player loses half their life, rounded up. +SVar:TrigLoseLifeOpp:DB$ LoseLife | Defined$ TriggeredTarget | LifeAmount$ X +T:Mode$ ChangesZone | ValidCard$ Card.Self+!HasCounters | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME dies, if it had no counters on it, return it to the battlefield tapped under its owner's control with two stun counters on it. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ TriggeredCard | WithCountersType$ STUN | WithCountersAmount$ 2 +SVar:X:TriggeredTarget$LifeTotal/HalfUp +Oracle:Deathtouch\nWhenever Unstoppable Slasher deals combat damage to a player, they lose half their life, rounded up.\nWhen Unstoppable Slasher dies, if it had no counters on it, return it to the battlefield tapped under its owner's control with two stun counters on it. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/untimely_malfunction.txt b/forge-gui/res/cardsfolder/upcoming/untimely_malfunction.txt new file mode 100644 index 00000000000..935cf2cad3a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/untimely_malfunction.txt @@ -0,0 +1,8 @@ +Name:Untimely Malfunction +ManaCost:1 R +Types:Instant +A:SP$ Charm | Choices$ DBDestroy,DBChangeTargets,DBCantBlock +SVar:DBDestroy:DB$ Destroy | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact. +SVar:DBChangeTargets:DB$ ChangeTargets | TargetType$ SpellAbility.singleTarget | ValidTgts$ Card,Emblem | TgtPrompt$ Select target spell or ability with a single target | SpellDescription$ Change the target of target spell or ability with a single target. +SVar:DBCantBlock:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | TargetMin$ 1 | TargetMax$ 2 | KW$ HIDDEN CARDNAME can't block. | IsCurse$ True | SpellDescription$ One or two target creatures can't block this turn. +Oracle:Choose one —\n• Destroy target artifact.\n• Change the target of target spell or ability with a single target.\n• One or two target creatures can't block this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/unwanted_remake.txt b/forge-gui/res/cardsfolder/upcoming/unwanted_remake.txt new file mode 100644 index 00000000000..7f56c5681bc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/unwanted_remake.txt @@ -0,0 +1,6 @@ +Name:Unwanted Remake +ManaCost:W +Types:Instant +A:SP$ Destroy | ValidTgts$ Creature | SubAbility$ DBDread | SpellDescription$ Destroy target creature. +SVar:DBDread:DB$ Manifest | Dread$ True | DefinedPlayer$ TargetedController | SpellDescription$ Its controller manifests dread. (That player looks at the top two cards of their library, then puts one onto the battlefield face down as a 2/2 creature and the other into their graveyard. If it's a creature card, it can be turned face up any time for its mana cost.) +Oracle:Destroy target creature. Its controller manifests dread. (That player looks at the top two cards of their library, then puts one onto the battlefield face down as a 2/2 creature and the other into their graveyard. If it's a creature card, it can be turned face up any time for its mana cost.) diff --git a/forge-gui/res/cardsfolder/upcoming/unwilling_vessel.txt b/forge-gui/res/cardsfolder/upcoming/unwilling_vessel.txt new file mode 100644 index 00000000000..e68418be225 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/unwilling_vessel.txt @@ -0,0 +1,14 @@ +Name:Unwilling Vessel +ManaCost:2 U +Types:Creature Human Wizard +PT:3/2 +K:Vigilance +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on CARDNAME. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ POSSESSION | CounterNum$ 1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on CARDNAME. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ u_x_x_spirit_flying | TokenPower$ X | TokenToughness$ X | TokenOwner$ You +SVar:X:TriggeredCard$CardCounters.ALL +DeckHas:Ability$Token & Type$Spirit +DeckNeeds:Type$Enchantment +Oracle:Vigilance\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on Unwilling Vessel.\nWhen Unwilling Vessel dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on Unwilling Vessel. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/ursine_monstrosity.txt b/forge-gui/res/cardsfolder/upcoming/ursine_monstrosity.txt new file mode 100644 index 00000000000..235e19e93cf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ursine_monstrosity.txt @@ -0,0 +1,13 @@ +Name:Ursine Monstrosity +ManaCost:2 G +Types:Creature Bear Mutant +PT:3/3 +K:Trample +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigMill | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of combat on your turn, mill a card and choose an opponent at random. CARDNAME attacks that player this combat if able. Until end of turn, CARDNAME gains indestructible and gets +1/+1 for each card type among cards in your graveyard. +SVar:TrigMill:DB$ Mill | Defined$ You | NumCards$ 1 | SubAbility$ DBChoose +SVar:DBChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | Random$ True | SubAbility$ DBPEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ Self | ExileOnMoved$ Battlefield | StaticAbilities$ AttackChosen | Duration$ UntilEndOfCombat | SubAbility$ DBPump +SVar:AttackChosen:Mode$ MustAttack | ValidCreature$ Card.IsRemembered | MustAttack$ ChosenPlayer | Description$ EFFECTSOURCE attacks that player this combat if able. +SVar:DBPump:DB$ Pump | Defined$ Self | NumAtt$ X | NumDef$ X | KW$ Indestructible +SVar:X:Count$ValidGraveyard Card.YouOwn$CardTypes +Oracle:Trample\nAt the beginning of combat on your turn, mill a card and choose an opponent at random. Ursine Monstrosity attacks that player this combat if able. Until end of turn, Ursine Monstrosity gains indestructible and gets +1/+1 for each card type among cards in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoth_harrower_of_souls.txt b/forge-gui/res/cardsfolder/upcoming/valgavoth_harrower_of_souls.txt new file mode 100644 index 00000000000..0904eedbfd6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/valgavoth_harrower_of_souls.txt @@ -0,0 +1,11 @@ +Name:Valgavoth, Harrower of Souls +ManaCost:2 B R +Types:Legendary Creature Elder Demon +PT:4/4 +K:Flying +K:Ward:PayLife<2> +T:Mode$ LifeLost | ValidPlayer$ Opponent.Active | TriggerZones$ Battlefield | FirstTime$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent loses life for the first time during each of their turns, put a +1/+1 counter on CARDNAME and draw a card. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 +DeckHas:Ability$Counters +Oracle:Flying\nWard — Pay 2 life.\nWhenever an opponent loses life for the first time during each of their turns, put a +1/+1 counter on Valgavoth, Harrower of Souls and draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt b/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt new file mode 100644 index 00000000000..8d953f72576 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt @@ -0,0 +1,11 @@ +Name:Valgavoth, Terror Eater +ManaCost:6 B B B +Types:Legendary Creature Elder Demon +PT:9/9 +K:Flying +K:Lifelink +K:Ward:Sac<3/Permanent.nonLand/nonland permanent> +R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Graveyard | ValidCard$ Card.nonToken+YouDontCtrl+OppOwn | ReplaceWith$ Exile | Description$ If a card you didn't control would be put into an opponent's graveyard from anywhere, exile it instead. +SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard +S:Mode$ Continuous | Condition$ PlayerTurn | MayPlay$ True | Affected$ Card.ExiledWithSource | AffectedZone$ Exile | MayPlayAltManaCost$ PayLife | Description$ During your turn, you may play cards exiled with NICKNAME. If you cast a spell this way, pay life equal to its mana value rather than pay its mana cost. +Oracle:Flying, lifelink\nWard—Sacrifice three nonland permanents.\nIf a card you didn't control would be put into an opponent's graveyard from anywhere, exile it instead.\nDuring your turn, you may play cards exiled with Valgavoth. If you cast a spell this way, pay life equal to its mana value rather than pay its mana cost. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoths_faithful.txt b/forge-gui/res/cardsfolder/upcoming/valgavoths_faithful.txt new file mode 100644 index 00000000000..418e79be6c1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/valgavoths_faithful.txt @@ -0,0 +1,6 @@ +Name:Valgavoth's Faithful +ManaCost:B +Types:Creature Human Cleric +PT:1/1 +A:AB$ ChangeZone | Cost$ 3 B Sac<1/CARDNAME> | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouCtrl | SorcerySpeed$ True | SpellDescription$ Return target creature card from your graveyard to the battlefield. Activate only as a sorcery. +Oracle:{3}{B}, Sacrifice Valgavoth's Faithful: Return target creature card from your graveyard to the battlefield. Activate only as a sorcery. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoths_lair.txt b/forge-gui/res/cardsfolder/upcoming/valgavoths_lair.txt new file mode 100644 index 00000000000..567bd15c180 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/valgavoths_lair.txt @@ -0,0 +1,10 @@ +Name:Valgavoth's Lair +ManaCost:no cost +Types:Enchantment Land +K:Hexproof +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped. +SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True +K:ETBReplacement:Other:ChooseColor +SVar:ChooseColor:DB$ ChooseColor | Defined$ You | AILogic$ MostProminentInComputerDeck | SpellDescription$ As CARDNAME enters, choose a color. +A:AB$ Mana | Cost$ T | Produced$ Chosen | SpellDescription$ Add one mana of the chosen color. +Oracle:Hexproof\nValgavoth's Lair enters tapped. As it enters, choose a color.\n{T}: Add one mana of the chosen color. diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt b/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt new file mode 100644 index 00000000000..c7fa1502c0a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt @@ -0,0 +1,8 @@ +Name:Valgavoth's Onslaught +ManaCost:X X G +Types:Instant +A:SP$ Manifest | Dread$ True | Times$ X | RememberManifested$ True | SubAbility$ DBPutCounterAll +SVar:DBPutCounterAll:DB$ PutCounterAll | ValidCards$ Card.IsRemembered | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$xPaid +Oracle:Manifest Dread X times, then put X +1/+1 counters on each of those creatures. (To manifest dread, look at the top two cards of your library, then put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/vanish_from_sight.txt b/forge-gui/res/cardsfolder/upcoming/vanish_from_sight.txt new file mode 100644 index 00000000000..2c1ce8f0a7f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vanish_from_sight.txt @@ -0,0 +1,7 @@ +Name:Vanish from Sight +ManaCost:3 U +Types:Instant +A:SP$ ChangeZone | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | AlternativeDecider$ TargetedOwner | Origin$ Battlefield | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | SubAbility$ DBSurveil | StackDescription$ {p:TargetedOwner} puts {c:Targeted} on the top or bottom of their library. | SpellDescription$ Target nonland permanent's owner puts it on the top or bottom of their library. Surveil 1. (Look at the top card of your library. You may put it into your graveyard.) +SVar:DBSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil|Graveyard +Oracle:Target nonland permanent's owner puts it on the top or bottom of their library. Surveil 1. (Look at the top card of your library. You may put it into your graveyard.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/vengeful_possession.txt b/forge-gui/res/cardsfolder/upcoming/vengeful_possession.txt new file mode 100644 index 00000000000..da96b623023 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vengeful_possession.txt @@ -0,0 +1,7 @@ +Name:Vengeful Possession +ManaCost:2 R +Types:Sorcery +A:SP$ GainControl | ValidTgts$ Creature | TgtPrompt$ Select target creature | LoseControl$ EOT | Untap$ True | AddKWs$ Haste | SubAbility$ DBDraw | SpellDescription$ Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. You may discard a card. If you do, draw a card. +SVar:DBDraw:DB$ Draw | UnlessCost$ Discard<1/Card> | UnlessSwitched$ True | UnlessPayer$ You +SVar:PlayMain1:OPPONENTCREATURES +Oracle:Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. You may discard a card. If you do, draw a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/veteran_survivor.txt b/forge-gui/res/cardsfolder/upcoming/veteran_survivor.txt new file mode 100644 index 00000000000..2909fd376f4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/veteran_survivor.txt @@ -0,0 +1,9 @@ +Name:Veteran Survivor +Types:Creature Human Survivor +ManaCost:W +PT:2/1 +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | PresentDefined$ Self | IsPresent$ Card.tapped | TriggerZones$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Survival — At the beginning of your second main phase, if CARDNAME is tapped, exile up to one target card from a graveyard. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Card | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target card in a graveyard to exile +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 3 | AddToughness$ 3 | AddKeyword$ Hexproof | CheckSVar$ X | SVarCompare$ GE3 | Description$ As long as there are three or more cards exiled with CARDNAME, it gets +3/+3 and has hexproof. (It can't be the target of spells or abilities your opponents control.) +SVar:X:ExiledWith$Amount +Oracle:Survival — At the beginning of your second main phase, if Veteran Survivor is tapped, exile up to one target card from a graveyard.\nAs long as there are three or more cards exiled with Veteran Survivor, it gets +3/+3 and has hexproof. (It can't be the target of spells or abilities your opponents control.) diff --git a/forge-gui/res/cardsfolder/upcoming/vicious_clown.txt b/forge-gui/res/cardsfolder/upcoming/vicious_clown.txt new file mode 100644 index 00000000000..6e70d2d567b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vicious_clown.txt @@ -0,0 +1,8 @@ +Name:Vicious Clown +ManaCost:2 R +Types:Creature Human Clown +PT:2/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.powerLE2+YouCtrl+Other | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever another creature you control with power 2 or less enters, CARDNAME gains flying until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 2 +SVar:BuffedBy:Creature.powerLE2 +Oracle:Whenever another creature you control with power 2 or less enters, Vicious Clown gets +2/+0 until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/victor_valgavoths_seneschal.txt b/forge-gui/res/cardsfolder/upcoming/victor_valgavoths_seneschal.txt new file mode 100644 index 00000000000..34cdc4540ab --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/victor_valgavoths_seneschal.txt @@ -0,0 +1,15 @@ +Name:Victor, Valgavoth's Seneschal +ManaCost:1 W B +Types:Legendary Creature Human Warlock +PT:3/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control. +T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control. +SVar:TrigSurveil:DB$ Surveil | Amount$ 2 | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 | SubAbility$ DBDiscard +SVar:DBDiscard:DB$ Discard | Defined$ Player.Opponent | Mode$ TgtChoose | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ2 | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature | ChangeNum$ 1 | Mandatory$ True | GainControl$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ3 | SelectPrompt$ Select a creature card to return to the battlefield | Hidden$ True | SubAbility$ DBLog +SVar:DBLog:DB$ StoreSVar | SVar$ X | Type$ CountSVar | Expression$ X/Plus.1 +SVar:X:Number$1 +T:Mode$ Phase | Phase$ Cleanup | TriggerZones$ Battlefield | Execute$ DBCleanup | Static$ True +SVar:DBCleanup:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 1 +DeckNeeds:Type$Enchantment +Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control. diff --git a/forge-gui/res/cardsfolder/upcoming/vile_mutilator.txt b/forge-gui/res/cardsfolder/upcoming/vile_mutilator.txt new file mode 100644 index 00000000000..00769d25002 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vile_mutilator.txt @@ -0,0 +1,11 @@ +Name:Vile Mutilator +ManaCost:5 B B +Types:Creature Demon +PT:6/5 +A:SP$ PermanentCreature | Cost$ 5 B B Sac<1/Creature;Enchantment/creature or enchantment> +K:Flying +K:Trample +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSacrifice | TriggerDescription$ When CARDNAME enters, each opponent sacrifices a nontoken enchantment, then sacrifices a nontoken creature. +SVar:TrigSacrifice:DB$ Sacrifice | Defined$ Opponent | SacValid$ Enchantment.nonToken | SacMessage$ nontoken enchantment | SubAbility$ DBSacrifice +SVar:DBSacrifice:DB$ Sacrifice | Defined$ Opponent | SacValid$ Creature.nonToken | SacMessage$ nontoken creature +Oracle:As an additional cost to cast this spell, sacrifice a creature or enchantment.\nFlying, trample\nWhen Vile Mutilator enters, each opponent sacrifices a nontoken enchantment, then sacrifices a nontoken creature. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/violent_urge.txt b/forge-gui/res/cardsfolder/upcoming/violent_urge.txt new file mode 100644 index 00000000000..c9d8efd8cbb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/violent_urge.txt @@ -0,0 +1,6 @@ +Name:Violent Urge +ManaCost:R +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | AILogic$ Pump | NumAtt$ +1 | KW$ First Strike | SubAbility$ DBPump | SpellDescription$ Target creature gets +1/+0 and first strike until end of turn. Delirium — If there are four or more card types in your graveyard, that creature gains double strike until end of turn. +SVar:DBPump:DB$ Pump | Defined$ Targeted | Condition$ Delirium | KW$ Double Strike +Oracle:Target creature gets +1/+0 and first strike until end of turn.\nDelirium — If there are four or more card types in your graveyard, that creature gains double strike until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/wary_watchdog.txt b/forge-gui/res/cardsfolder/upcoming/wary_watchdog.txt new file mode 100644 index 00000000000..354dd65d87d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wary_watchdog.txt @@ -0,0 +1,9 @@ +Name:Wary Watchdog +ManaCost:1 G +Types:Creature Dog +PT:3/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSurveil | TriggerDescription$ When CARDNAME enters or dies, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigSurveil | Secondary$ True | TriggerDescription$ When CARDNAME enters or dies, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) +SVar:TrigSurveil:DB$ Surveil | Amount$ 1 +DeckHas:Ability$Surveil|Graveyard +Oracle:When Wary Watchdog enters or dies, surveil 1. (Look at the top card of your library. You may put that card into your graveyard.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/wickerfolk_thresher.txt b/forge-gui/res/cardsfolder/upcoming/wickerfolk_thresher.txt new file mode 100644 index 00000000000..28f2290ed74 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wickerfolk_thresher.txt @@ -0,0 +1,10 @@ +Name:Wickerfolk Thresher +ManaCost:3 G +Types:Artifact Creature Scarecrow +PT:5/4 +T:Mode$ Attacks | ValidCard$ Card.Self | Delirium$ True | Execute$ TrigDig | TriggerDescription$ Delirium — Whenever CARDNAME attacks, if there are four or more card types among cards in your graveyard, look at the top card of your library. If it's a land card, you may put it onto the battlefield. If you don't put the card onto the battlefield, put it into your hand. +SVar:TrigDig:DB$ Dig | DigNum$ 1 | ChangeNum$ 1 | ChangeValid$ Land | Optional$ True | DestinationZone$ Battlefield | DestinationZone2$ Hand +SVar:HasAttackEffect:TRUE +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Delirium — Whenever Wickerfolk Thresher attacks, if there are four or more card types among cards in your graveyard, look at the top card of your library. If it's a land card, you may put it onto the battlefield. If you don't put the card onto the battlefield, put it into your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/wildfire_wickerfolk.txt b/forge-gui/res/cardsfolder/upcoming/wildfire_wickerfolk.txt new file mode 100644 index 00000000000..6566789f15e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wildfire_wickerfolk.txt @@ -0,0 +1,9 @@ +Name:Wildfire Wickerfolk +ManaCost:R G +Types:Artifact Creature Scarecrow +PT:3/2 +K:Haste +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Trample | Condition$ Delirium | Description$ Delirium — CARDNAME gets +1/+1 and has trample as long as there are four or more card types among cards in your graveyard. +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Haste\nDelirium — Wildfire Wickerfolk gets +1/+1 and has trample as long as there are four or more card types among cards in your graveyard. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/winter_misanthropic_guide.txt b/forge-gui/res/cardsfolder/upcoming/winter_misanthropic_guide.txt new file mode 100644 index 00000000000..b4b58f5fbb3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/winter_misanthropic_guide.txt @@ -0,0 +1,13 @@ +Name:Winter, Misanthropic Guide +ManaCost:1 B R G +Types:Legendary Creature Human Warlock +PT:3/4 +K:Ward:2 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of your upkeep, each player draws two cards. +SVar:TrigDraw:DB$ Draw | Defined$ Player | NumCards$ 2 +S:Mode$ Continuous | Condition$ Delirium | Affected$ Opponent | SetMaxHandSize$ Y | Description$ Delirium — As long as there are four or more card types among cards in your graveyard, each opponent's maximum hand size is equal to seven minus the number of those card types. +SVar:X:Count$ValidGraveyard Card.YouOwn$CardTypes +SVar:Y:Number$7/Minus.X +DeckHints:Ability$Graveyard|Discard +DeckHas:Ability$Delirium +Oracle:Ward {2}\nAt the beginning of your upkeep, each player draws two cards.\nDelirium — As long as there are four or more card types among cards in your graveyard, each opponent's maximum hand size is equal to seven minus the number of those card types. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/withering_torment.txt b/forge-gui/res/cardsfolder/upcoming/withering_torment.txt new file mode 100644 index 00000000000..8595b479873 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/withering_torment.txt @@ -0,0 +1,6 @@ +Name:Withering Torment +ManaCost:2 B +Types:Instant +A:SP$ Destroy | ValidTgts$ Creature,Enchantment | TgtPrompt$ Select target creature or enchantment | SubAbility$ DBLoseLife | SpellDescription$ Destroy target creature or enchantment. You lose 2 life. +SVar:DBLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 2 +Oracle:Destroy target creature or enchantment. You lose 2 life. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/you_are_unworthy_of_mercy.txt b/forge-gui/res/cardsfolder/upcoming/you_are_unworthy_of_mercy.txt new file mode 100644 index 00000000000..ef9c014ba79 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/you_are_unworthy_of_mercy.txt @@ -0,0 +1,8 @@ +Name:You Are Unworthy of Mercy +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigSacEach | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each opponent sacrifices a nonland permanent. If you control six or more lands, each opponent sacrifices three nonland permanents instead. +SVar:TrigSacEach:DB$ Sacrifice | Amount$ X | Defined$ Player.Opponent | SacValid$ Permanent.nonLand | SacMessage$ nonland permanent +SVar:X:Count$Compare Y GE6.3.1 +SVar:Y:Count$Valid Land.YouCtrl +Oracle:When you set this scheme in motion, each opponent sacrifices a nonland permanent. If you control six or more lands, each opponent sacrifices three nonland permanents instead. diff --git a/forge-gui/res/cardsfolder/upcoming/you_cannot_hide_from_me.txt b/forge-gui/res/cardsfolder/upcoming/you_cannot_hide_from_me.txt new file mode 100644 index 00000000000..cf1742e3128 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/you_cannot_hide_from_me.txt @@ -0,0 +1,12 @@ +Name:You Cannot Hide from Me +ManaCost:no cost +Types:Ongoing Scheme +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigPump | TriggerDescription$ At the beginning of combat on your turn, up to one target creature gets +2/+2 and gains vigilance until end of turn. It can't be blocked this turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target creature | NumAtt$ 2 | NumDef$ 2 | KW$ Vigilance | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | ExileOnMoved$ Battlefield | RememberObjects$ ParentTarget | StaticAbilities$ Unblockable +SVar:Unblockable:Mode$ CantBlockBy | ValidAttacker$ Card.IsRemembered | Description$ This creature can't be blocked this turn. +T:Mode$ Phase | Phase$ End Of Turn | ValidPlayer$ Opponent | Execute$ Abandon | TriggerZones$ Command | CheckSVar$ X | SVarCompare$ LTY | TriggerDescription$ At the beginning of each opponent's end step, if that player has less than half their starting life total, abandon this scheme. +SVar:Abandon:DB$ Abandon +SVar:X:PlayerCountDefinedActivePlayer$LifeTotal +SVar:Y:PlayerCountDefinedActivePlayer$StartingLife/HalfDown +Oracle:(An ongoing scheme remains face up until it's abandoned.)\nAt the beginning of combat on your turn, up to one target creature gets +2/+2 and gains vigilance until end of turn. It can't be blocked this turn.\nAt the beginning of each opponent's end step, if that player has less than half their starting life total, abandon this scheme. diff --git a/forge-gui/res/cardsfolder/upcoming/you_exist_only_to_amuse.txt b/forge-gui/res/cardsfolder/upcoming/you_exist_only_to_amuse.txt new file mode 100644 index 00000000000..1a771ccbef8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/you_exist_only_to_amuse.txt @@ -0,0 +1,10 @@ +Name:You Exist Only to Amuse +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, ABILITY +SVar:TrigCharm:DB$ Charm | CharmNum$ Count$Compare X GE6.2.1 | Choices$ DBToken,DBAnimateAll | AdditionalDescription$ If you control six or more lands, choose both instead. +SVar:DBToken:DB$ Token | TokenAmount$ 3 | TokenScript$ r_1_1_devil_burn | SpellDescription$ Create three 1/1 red Devil creature tokens with "When this creature dies, it deals 1 damage to any target." +SVar:DBAnimateAll:DB$ AnimateAll | ValidCards$ Creature.OppCtrl | Power$ 1 | Toughness$ 1 | RemoveAllAbilities$ True | Duration$ UntilYourNextTurn | SpellDescription$ Until your next turn, creatures your opponents control have base power and toughness 1/1 and lose all abilities. +SVar:X:Count$Valid Land.YouCtrl +DeckHas:Ability$Token +Oracle:When you set this scheme in motion, choose one. If you control six or more lands, choose both instead.\n• Create three 1/1 red Devil creature tokens with "When this creature dies, it deals 1 damage to any target."\n• Until your next turn, creatures your opponents control have base power and toughness 1/1 and lose all abilities. diff --git a/forge-gui/res/cardsfolder/upcoming/you_live_only_because_i_will_it.txt b/forge-gui/res/cardsfolder/upcoming/you_live_only_because_i_will_it.txt new file mode 100644 index 00000000000..c709d25a4ee --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/you_live_only_because_i_will_it.txt @@ -0,0 +1,6 @@ +Name:You Live Only Because I Will It +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigRedistribute | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, you may redistribute any number of life totals. +SVar:TrigRedistribute:DB$ SetLife | PlayerChoices$ Player | ChoiceAmount$ Any | ChoicePrompt$ Choose any number of players | Redistribute$ True +Oracle:When you set this scheme in motion, you may redistribute any number of life totals. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/you_will_know_true_suffering.txt b/forge-gui/res/cardsfolder/upcoming/you_will_know_true_suffering.txt new file mode 100644 index 00000000000..e18665876b7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/you_will_know_true_suffering.txt @@ -0,0 +1,7 @@ +Name:You Will Know True Suffering +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigDamageAll | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, it deals damage equal to your commander's mana value to each noncommander creature your opponents control. +SVar:TrigDamageAll:DB$ DamageAll | ValidCards$ Creature.IsNotCommander+OppCtrl | ValidDescription$ each noncommander creature your opponents control. | NumDmg$ X +SVar:X:Count$ValidAll Card.IsCommander+YouOwn$SumCMC +Oracle:When you set this scheme in motion, it deals damage equal to your commander's mana value to each noncommander creature your opponents control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/your_mistake_is_my_triumph.txt b/forge-gui/res/cardsfolder/upcoming/your_mistake_is_my_triumph.txt new file mode 100644 index 00000000000..953a8406668 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/your_mistake_is_my_triumph.txt @@ -0,0 +1,8 @@ +Name:Your Mistake Is My Triumph +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigMill | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each player mills three cards. Then you put a permanent card from among the milled cards onto the battlefield under your control. +SVar:TrigMill:DB$ Mill | NumCards$ 3 | Defined$ Player | RememberMilled$ True | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Hidden$ True | Origin$ Graveyard,Exile | Destination$ Hand | ChangeType$ Permanent.IsRemembered | SelectPrompt$ Select a permanent from among the milled cards | GainControl$ True | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:When you set this scheme in motion, each player mills three cards. Then you put a permanent card from among the milled cards onto the battlefield under your control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/your_nightmares_are_delicious.txt b/forge-gui/res/cardsfolder/upcoming/your_nightmares_are_delicious.txt new file mode 100644 index 00000000000..99247fbd834 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/your_nightmares_are_delicious.txt @@ -0,0 +1,10 @@ +Name:Your Nightmares Are Delicious +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigRepeatEach | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, each opponent who has more than five cards in hand discards cards equal to the difference. Then if fewer than three cards were discarded this way, you draw three cards. +SVar:TrigRepeatEach:DB$ RepeatEach | RepeatPlayers$ Opponent | RepeatSubAbility$ DBDiscard | SubAbility$ DBDraw +SVar:DBDiscard:DB$ Discard | Defined$ Player.IsRemembered | NumCards$ X | Mode$ TgtChoose | RememberDiscarded$ True +SVar:DBDraw:DB$ Draw | NumCards$ 3 | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ LT3 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:PlayerCountRemembered$CardsInHand/Minus.5 +Oracle:When you set this scheme in motion, each opponent who has more than five cards in hand discards cards equal to the difference. Then if fewer than three cards were discarded this way, you draw three cards. diff --git a/forge-gui/res/cardsfolder/upcoming/your_own_face_mocks_you.txt b/forge-gui/res/cardsfolder/upcoming/your_own_face_mocks_you.txt new file mode 100644 index 00000000000..9300f984339 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/your_own_face_mocks_you.txt @@ -0,0 +1,10 @@ +Name:Your Own Face Mocks You +ManaCost:no cost +Types:Scheme +T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ TrigCopyPermanent | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, choose up to two target creatures your opponents control. For each one, create a token that's a copy of it. If you created fewer than two tokens this way, create a number of 4/4 colorless Scarecrow artifact creature tokens with vigilance equal to the difference. +SVar:TrigCopyPermanent:DB$ CopyPermanent | ValidTgts$ Creature.OppCtrl | NumCopies$ 1 | AILogic$ DuplicatePerms | TargetMin$ 0 | TargetMax$ 2 | RememberTokens$ True | SubAbility$ DBToken +SVar:DBToken:DB$ Token | TokenAmount$ Difference | TokenScript$ c_4_4_a_scarecrow_vigilance | TokenOwner$ You | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$Amount +SVar:Difference:Number$2/Minus.X +Oracle:When you set this scheme in motion, choose up to two target creatures your opponents control. For each one, create a token that's a copy of it. If you created fewer than two tokens this way, create a number of 4/4 colorless Scarecrow artifact creature tokens with vigilance equal to the difference. diff --git a/forge-gui/res/cardsfolder/upcoming/zimone_all_questioning.txt b/forge-gui/res/cardsfolder/upcoming/zimone_all_questioning.txt new file mode 100644 index 00000000000..aa8da24d713 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zimone_all_questioning.txt @@ -0,0 +1,12 @@ +Name:Zimone, All-Questioning +ManaCost:1 G U +Types:Legendary Creature Human Wizard +PT:1/1 +T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigToken | CheckSVar$ X | TriggerDescription$ At the beginning of your end step, if a land entered the battlefield under your control this turn and you control a prime number of lands, create Primo, the Indivisible, a legendary 0/0 green and blue Fractal creature token, then put that many +1/+1 counters on it. (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, and 31 are prime numbers.) +SVar:TrigToken:DB$ Token | TokenScript$ primo_the_invisible | RememberTokens$ True | SubAbility$ DBCounters +SVar:DBCounters:DB$ PutCounter | Defined$ Remembered | CounterNum$ Y | CounterType$ P1P1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$IsPrime Y.Z.0 +SVar:Y:Count$Valid Land.YouCtrl+IsNotRemembered +SVar:Z:Count$ThisTurnEntered_Battlefield_Land.YouCtrl +Oracle:At the beginning of your end step, if a land entered the battlefield under your control this turn and you control a prime number of lands, create Primo, the Indivisible, a legendary 0/0 green and blue Fractal creature token, then put that many +1/+1 counters on it. (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, and 31 are prime numbers.) diff --git a/forge-gui/res/cardsfolder/upcoming/zimone_mystery_unraveler.txt b/forge-gui/res/cardsfolder/upcoming/zimone_mystery_unraveler.txt new file mode 100644 index 00000000000..aac64b09068 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zimone_mystery_unraveler.txt @@ -0,0 +1,10 @@ +Name:Zimone, Mystery Unraveler +ManaCost:2 G U +Types:Legendary Creature Human Wizard +PT:3/3 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDread | TriggerDescription$ Landfall — Whenever a land you control enters, manifest dread if this is the first time this ability has resolved this turn. Otherwise, you may turn a permanent you control face up. (To manifest dread, look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) +SVar:TrigDread:DB$ Manifest | Dread$ True | Defined$ You | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 | SubAbility$ DBTurnFaceUp +SVar:DBTurnFaceUp:DB$ SetState | Optional$ True | Choices$ Permanent.faceDown+YouCtrl | ChoiceTitle$ Select a face-down permanent you control | ConditionCheckSVar$ X | ConditionSVarCompare$ GT1 | Mode$ TurnFaceUp +SVar:X:Count$ResolvedThisTurn +SVar:BuffedBy:Land +Oracle:Landfall — Whenever a land you control enters, manifest dread if this is the first time this ability has resolved this turn. Otherwise, you may turn a permanent you control face up. (To manifest dread, look at the top two cards of your library. Put one onto the battlefield face down as a 2/2 creature and the other into your graveyard. Turn it face up any time for its mana cost if it's a creature card.) diff --git a/forge-gui/res/cardsfolder/upcoming/zimones_hypothesis.txt b/forge-gui/res/cardsfolder/upcoming/zimones_hypothesis.txt new file mode 100644 index 00000000000..2e451ac8e49 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zimones_hypothesis.txt @@ -0,0 +1,8 @@ +Name:Zimone's Hypothesis +ManaCost:3 U U +Types:Instant +A:SP$ PutCounter | Choices$ Creature | ChoiceTitle$ Choose a creature | CounterType$ P1P1 | CounterNum$ 1 | Optional$ True | SubAbility$ DBGenericChoice | SpellDescription$ You may put a +1/+1 counter on a creature. Then choose odd or even. Return each creature with power of the chosen quality to its owner's hand. (Zero is even.) +SVar:DBGenericChoice:DB$ GenericChoice | Choices$ Odd,Even +SVar:Odd:DB$ ChangeZoneAll | ChangeType$ Creature.powerOdd | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Odd +SVar:Even:DB$ ChangeZoneAll | ChangeType$ Creature.powerEven | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Even +Oracle:You may put a +1/+1 counter on a creature. Then choose odd or even. Return each creature with power of the chosen quality to its owner's hand. (Zero is even.) diff --git a/forge-gui/res/cardsfolder/upcoming/valley_flamecaller.txt b/forge-gui/res/cardsfolder/v/valley_flamecaller.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/valley_flamecaller.txt rename to forge-gui/res/cardsfolder/v/valley_flamecaller.txt diff --git a/forge-gui/res/cardsfolder/upcoming/valley_floodcaller.txt b/forge-gui/res/cardsfolder/v/valley_floodcaller.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/valley_floodcaller.txt rename to forge-gui/res/cardsfolder/v/valley_floodcaller.txt diff --git a/forge-gui/res/cardsfolder/upcoming/valley_mightcaller.txt b/forge-gui/res/cardsfolder/v/valley_mightcaller.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/valley_mightcaller.txt rename to forge-gui/res/cardsfolder/v/valley_mightcaller.txt diff --git a/forge-gui/res/cardsfolder/upcoming/valley_questcaller.txt b/forge-gui/res/cardsfolder/v/valley_questcaller.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/valley_questcaller.txt rename to forge-gui/res/cardsfolder/v/valley_questcaller.txt diff --git a/forge-gui/res/cardsfolder/upcoming/valley_rally.txt b/forge-gui/res/cardsfolder/v/valley_rally.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/valley_rally.txt rename to forge-gui/res/cardsfolder/v/valley_rally.txt diff --git a/forge-gui/res/cardsfolder/upcoming/valley_rotcaller.txt b/forge-gui/res/cardsfolder/v/valley_rotcaller.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/valley_rotcaller.txt rename to forge-gui/res/cardsfolder/v/valley_rotcaller.txt diff --git a/forge-gui/res/cardsfolder/upcoming/veteran_guardmouse.txt b/forge-gui/res/cardsfolder/v/veteran_guardmouse.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/veteran_guardmouse.txt rename to forge-gui/res/cardsfolder/v/veteran_guardmouse.txt diff --git a/forge-gui/res/cardsfolder/upcoming/viewpoint_synchronization.txt b/forge-gui/res/cardsfolder/v/viewpoint_synchronization.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/viewpoint_synchronization.txt rename to forge-gui/res/cardsfolder/v/viewpoint_synchronization.txt diff --git a/forge-gui/res/cardsfolder/v/vigorous_farming.txt b/forge-gui/res/cardsfolder/v/vigorous_farming.txt new file mode 100644 index 00000000000..1583977c035 --- /dev/null +++ b/forge-gui/res/cardsfolder/v/vigorous_farming.txt @@ -0,0 +1,10 @@ +Name:Vigorous Farming +ManaCost:2 G +Types:Enchantment +R:Event$ Moved | ValidCard$ Land.YouCtrl | Destination$ Battlefield | ReplaceWith$ ETBUntapped | ReplacementResult$ Updated | ActiveZones$ Battlefield | Description$ Lands you control enter the battlefield untapped. +SVar:ETBUntapped:DB$ Untap | ETB$ True | Defined$ ReplacedCard +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigAnimate | TriggerDescription$ At the beginning of your end step, the topmost land card in your library perpetually gains "Whenever this land is tapped for mana, add an additional {G}." +SVar:TrigAnimate:DB$ Animate | Defined$ ValidLibrary Land.TopLibraryLand+YouCtrl | Triggers$ ManaTap | Duration$ Perpetual +SVar:ManaTap:Mode$ TapsForMana | ValidCard$ Card.Self | Execute$ TrigMana | Static$ True | TriggerDescription$ Whenever this land is tapped for mana, add an additional {G}. +SVar:TrigMana:DB$ Mana | Produced$ G | Amount$ 1 | Defined$ TriggeredCardController +Oracle:Lands you control enter the battlefield untapped.\nAt the beginning of your end step, the topmost land card in your library perpetually gains "Whenever this land is tapped for mana, add an additional {G}." diff --git a/forge-gui/res/cardsfolder/upcoming/vinereap_mentor.txt b/forge-gui/res/cardsfolder/v/vinereap_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/vinereap_mentor.txt rename to forge-gui/res/cardsfolder/v/vinereap_mentor.txt diff --git a/forge-gui/res/cardsfolder/v/voodoo_doll.txt b/forge-gui/res/cardsfolder/v/voodoo_doll.txt index 65e7a60b810..f738e66db36 100644 --- a/forge-gui/res/cardsfolder/v/voodoo_doll.txt +++ b/forge-gui/res/cardsfolder/v/voodoo_doll.txt @@ -2,11 +2,11 @@ Name:Voodoo Doll ManaCost:6 Types:Artifact T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, put a pin counter on CARDNAME. -T:Mode$ Phase | Phase$ End of Turn | IsPresent$ Card.Self+untapped | ValidPlayer$ You | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, if CARDNAME is untapped, destroy CARDNAME and it deals damage to you equal to the number of pin counters on it. +T:Mode$ Phase | Phase$ End of Turn | PresentDefined$ Self | IsPresent$ Card.untapped | ValidPlayer$ You | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, if CARDNAME is untapped, destroy CARDNAME and it deals damage to you equal to the number of pin counters on it. A:AB$ DealDamage | Cost$ X X T | ValidTgts$ Any | NumDmg$ X | SpellDescription$ CARDNAME deals damage equal to the number of pin counters on it to any target. X is the number of pin counters on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | CounterType$ PIN | CounterNum$ 1 | Defined$ Self -SVar:TrigDestroy:DB$ Destroy | Defined$ Self | SubAbility$ DBDealDamageYou | ConditionDefined$ Self | ConditionPresent$ Card.untapped -SVar:DBDealDamageYou:DB$ DealDamage | Defined$ You | NumDmg$ X | ConditionDefined$ Self | ConditionPresent$ Card.untapped +SVar:TrigDestroy:DB$ Destroy | Defined$ Self | SubAbility$ DBDealDamageYou +SVar:DBDealDamageYou:DB$ DealDamage | Defined$ You | NumDmg$ X SVar:X:Count$CardCounters.PIN AI:RemoveDeck:All Oracle:At the beginning of your upkeep, put a pin counter on Voodoo Doll.\nAt the beginning of your end step, if Voodoo Doll is untapped, destroy Voodoo Doll and it deals damage to you equal to the number of pin counters on it.\n{X}{X}, {T}: Voodoo Doll deals damage equal to the number of pin counters on it to any target. X is the number of pin counters on Voodoo Doll. diff --git a/forge-gui/res/cardsfolder/upcoming/vren_the_relentless.txt b/forge-gui/res/cardsfolder/v/vren_the_relentless.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/vren_the_relentless.txt rename to forge-gui/res/cardsfolder/v/vren_the_relentless.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wandertale_mentor.txt b/forge-gui/res/cardsfolder/w/wandertale_mentor.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wandertale_mentor.txt rename to forge-gui/res/cardsfolder/w/wandertale_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/war_squeak.txt b/forge-gui/res/cardsfolder/w/war_squeak.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/war_squeak.txt rename to forge-gui/res/cardsfolder/w/war_squeak.txt diff --git a/forge-gui/res/cardsfolder/upcoming/warren_elder.txt b/forge-gui/res/cardsfolder/w/warren_elder.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/warren_elder.txt rename to forge-gui/res/cardsfolder/w/warren_elder.txt diff --git a/forge-gui/res/cardsfolder/upcoming/warren_warleader.txt b/forge-gui/res/cardsfolder/w/warren_warleader.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/warren_warleader.txt rename to forge-gui/res/cardsfolder/w/warren_warleader.txt diff --git a/forge-gui/res/cardsfolder/w/waste_land.txt b/forge-gui/res/cardsfolder/w/waste_land.txt index 70a5ca435c3..d859895702c 100644 --- a/forge-gui/res/cardsfolder/w/waste_land.txt +++ b/forge-gui/res/cardsfolder/w/waste_land.txt @@ -3,6 +3,6 @@ ManaCost:no cost Types:Land A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. A:AB$ Destroy | Cost$ T Sac<1/CARDNAME> | ValidTgts$ Land.nonBasic | TgtPrompt$ Select target land. | SubAbility$ DBToken | AILogic$ GhostQuarter | AITgts$ Land.nonBasic | SpellDescription$ Destroy target nonbasic land. That land's controller creates a Wastes land token. (It has {T}: Add {C}.) -SVar:DBToken:DB$ Token | TokenScript$ c_l_wastes | TokenOwner$ TargetedController +SVar:DBToken:DB$ CopyPermanent | DefinedName$ Wastes | Controller$ TargetedController DeckHas:Ability$Mana.Colorless Oracle:{T}: Add {C}.\n{T}, Sacrifice Waste Land: Destroy target nonbasic land. That land's controller creates a Wastes token. (It's a land with {T}: Add {C}.) diff --git a/forge-gui/res/cardsfolder/upcoming/waterspout_warden.txt b/forge-gui/res/cardsfolder/w/waterspout_warden.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/waterspout_warden.txt rename to forge-gui/res/cardsfolder/w/waterspout_warden.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wax_wane_witness.txt b/forge-gui/res/cardsfolder/w/wax_wane_witness.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wax_wane_witness.txt rename to forge-gui/res/cardsfolder/w/wax_wane_witness.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wear_down.txt b/forge-gui/res/cardsfolder/w/wear_down.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wear_down.txt rename to forge-gui/res/cardsfolder/w/wear_down.txt diff --git a/forge-gui/res/cardsfolder/upcoming/what_must_be_done.txt b/forge-gui/res/cardsfolder/w/what_must_be_done.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/what_must_be_done.txt rename to forge-gui/res/cardsfolder/w/what_must_be_done.txt diff --git a/forge-gui/res/cardsfolder/upcoming/whiskerquill_scribe.txt b/forge-gui/res/cardsfolder/w/whiskerquill_scribe.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/whiskerquill_scribe.txt rename to forge-gui/res/cardsfolder/w/whiskerquill_scribe.txt diff --git a/forge-gui/res/cardsfolder/upcoming/whiskervale_forerunner.txt b/forge-gui/res/cardsfolder/w/whiskervale_forerunner.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/whiskervale_forerunner.txt rename to forge-gui/res/cardsfolder/w/whiskervale_forerunner.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wick_the_whorled_mind.txt b/forge-gui/res/cardsfolder/w/wick_the_whorled_mind.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wick_the_whorled_mind.txt rename to forge-gui/res/cardsfolder/w/wick_the_whorled_mind.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wicks_patrol.txt b/forge-gui/res/cardsfolder/w/wicks_patrol.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wicks_patrol.txt rename to forge-gui/res/cardsfolder/w/wicks_patrol.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wildfire_howl.txt b/forge-gui/res/cardsfolder/w/wildfire_howl.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wildfire_howl.txt rename to forge-gui/res/cardsfolder/w/wildfire_howl.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wildsear_scouring_maw.txt b/forge-gui/res/cardsfolder/w/wildsear_scouring_maw.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wildsear_scouring_maw.txt rename to forge-gui/res/cardsfolder/w/wildsear_scouring_maw.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wisedrafters_will.txt b/forge-gui/res/cardsfolder/w/wisedrafters_will.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wisedrafters_will.txt rename to forge-gui/res/cardsfolder/w/wisedrafters_will.txt diff --git a/forge-gui/res/cardsfolder/upcoming/wishing_well.txt b/forge-gui/res/cardsfolder/w/wishing_well.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wishing_well.txt rename to forge-gui/res/cardsfolder/w/wishing_well.txt diff --git a/forge-gui/res/cardsfolder/w/worldheart_phoenix.txt b/forge-gui/res/cardsfolder/w/worldheart_phoenix.txt index ac6ba4fe971..5e5265ac538 100644 --- a/forge-gui/res/cardsfolder/w/worldheart_phoenix.txt +++ b/forge-gui/res/cardsfolder/w/worldheart_phoenix.txt @@ -3,7 +3,11 @@ ManaCost:3 R Types:Creature Phoenix PT:2/2 K:Flying -S:Mode$ AlternativeCost | ValidSA$ Spell.Self | EffectZone$ Graveyard | Cost$ W U B R G | Description$ You may cast CARDNAME from graveyard by paying {W}{U}{B}{R}{G} rather than paying its mana cost. If you do, it enters with two +1/+1 counters on it. -K:etbCounter:P1P1:2:CheckSVar$AltCostPaid:no desc +S:Mode$ AlternativeCost | ValidSA$ Spell.Self | EffectZone$ Graveyard | Cost$ W U B R G | Description$ You may cast CARDNAME from your graveyard by paying {W}{U}{B}{R}{G} rather than paying its mana cost. If you do, it enters with two +1/+1 counters on it. +T:Mode$ SpellCast | ValidCard$ Card.Self | Static$ True | Execute$ DBEffect | CheckSVar$ AltCostPaid +SVar:DBEffect:DB$ Effect | ExileOnMoved$ Stack | ReplacementEffects$ ETBCreat | ExileOnMoved$ Stack +SVar:ETBCreat:Event$ Moved | ValidCard$ Card.EffectSource | Destination$ Battlefield | ReplaceWith$ DBPutP1P1 | ReplacementResult$ Updated | Description$ That creature enters with two additional +1/+1 counters on it. +SVar:DBPutP1P1:DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ True | CounterNum$ 2 | SubAbility$ DBExile +SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile SVar:AltCostPaid:Count$AltCost.1.0 Oracle:Flying\nYou may cast Worldheart Phoenix from your graveyard by paying {W}{U}{B}{R}{G} rather than paying its mana cost. If you do, it enters with two +1/+1 counters on it. diff --git a/forge-gui/res/cardsfolder/upcoming/wrenn_and_one.txt b/forge-gui/res/cardsfolder/w/wrenn_and_one.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/wrenn_and_one.txt rename to forge-gui/res/cardsfolder/w/wrenn_and_one.txt diff --git a/forge-gui/res/cardsfolder/upcoming/yggdrasil_rebirth_engine.txt b/forge-gui/res/cardsfolder/y/yggdrasil_rebirth_engine.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/yggdrasil_rebirth_engine.txt rename to forge-gui/res/cardsfolder/y/yggdrasil_rebirth_engine.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ygra_eater_of_all.txt b/forge-gui/res/cardsfolder/y/ygra_eater_of_all.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/ygra_eater_of_all.txt rename to forge-gui/res/cardsfolder/y/ygra_eater_of_all.txt diff --git a/forge-gui/res/cardsfolder/y/youre_in_command.txt b/forge-gui/res/cardsfolder/y/youre_in_command.txt new file mode 100644 index 00000000000..a7549b3907a --- /dev/null +++ b/forge-gui/res/cardsfolder/y/youre_in_command.txt @@ -0,0 +1,7 @@ +Name:You're in Command +ManaCost:1 W +Types:Sorcery +A:SP$ AlterAttribute | ValidTgts$ Creature.YouOwn+YouCtrl | IncludeAllComponentCards$ True | Attributes$ Commander | RememberTargets$ True | SubAbility$ DBDemote | SpellDescription$ Choose target creature you own and control. That creature becomes your commander. Any other commanders you have are no longer your commander. (That creature starts with a commander tax of {0}.) +SVar:DBDemote:DB$ AlterAttribute | Defined$ ValidAll Card.YouOwn+IsNotRemembered+IsCommander | Attributes$ Commander | Activate$ False | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Choose target creature you own and control. That creature becomes your commander. Any other commanders you have are no longer your commander. (That creature starts with a commander tax of {0}.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/zinnia_valleys_voice.txt b/forge-gui/res/cardsfolder/z/zinnia_valleys_voice.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/zinnia_valleys_voice.txt rename to forge-gui/res/cardsfolder/z/zinnia_valleys_voice.txt diff --git a/forge-gui/res/cardsfolder/upcoming/zoraline_cosmos_caller.txt b/forge-gui/res/cardsfolder/z/zoraline_cosmos_caller.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/zoraline_cosmos_caller.txt rename to forge-gui/res/cardsfolder/z/zoraline_cosmos_caller.txt diff --git a/forge-gui/res/cardsfolder/z/zoyowa_lava_tongue.txt b/forge-gui/res/cardsfolder/z/zoyowa_lava_tongue.txt index e5cf0bbf0f0..e4b656e5e2e 100644 --- a/forge-gui/res/cardsfolder/z/zoyowa_lava_tongue.txt +++ b/forge-gui/res/cardsfolder/z/zoyowa_lava_tongue.txt @@ -5,7 +5,7 @@ PT:2/2 K:Deathtouch T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You.descended | TriggerZones$ Battlefield | Execute$ TrigMaySacorDiscard | TriggerDescription$ At the beginning of your end step, if you descended this turn, each opponent may discard a card or sacrifice a permanent. CARDNAME deals 3 damage to each opponent who didn't. (You descended if a permanent card was put into your graveyard from anywhere.) SVar:TrigMaySacorDiscard:DB$ GenericChoice | Choices$ PaySac,PayDiscard | TempRemember$ Chooser | Defined$ Opponent | AILogic$ PayUnlessCost | DamageMap$ True -SVar:PaySac:DB$ DealDamage | NumDmg$ 3 | Defined$ Remembered | UnlessCost$ Sac<1/Permanent> | UnlessPayer$ Remembered | UnlessAI$ LifeLE2 | SpellDescription$ CARDNAME deals 3 damage to you unless you sacrifice a permanent a card. +SVar:PaySac:DB$ DealDamage | NumDmg$ 3 | Defined$ Remembered | UnlessCost$ Sac<1/Permanent> | UnlessPayer$ Remembered | UnlessAI$ LifeLE2 | SpellDescription$ CARDNAME deals 3 damage to you unless you sacrifice a permanent. SVar:PayDiscard:DB$ DealDamage | NumDmg$ 3 | Defined$ Remembered | UnlessCost$ Discard<1/Card> | UnlessPayer$ Remembered | UnlessAI$ LifeLE2 | SpellDescription$ CARDNAME deals 3 damage to you unless you discard a card. DeckHas:Ability$Discard|Sacrifice Oracle:Deathtouch\nAt the beginning of your end step, if you descended this turn, each opponent may discard a card or sacrifice a permanent. Zoyowa Lava-Tongue deals 3 damage to each opponent who didn't. (You descended if a permanent card was put into your graveyard from anywhere.) diff --git a/forge-gui/res/editions/Bloomburrow.txt b/forge-gui/res/editions/Bloomburrow.txt index 70f76075832..b789bddfe9a 100644 --- a/forge-gui/res/editions/Bloomburrow.txt +++ b/forge-gui/res/editions/Bloomburrow.txt @@ -33,7 +33,7 @@ Replace=.20F Land:fromSheet("BLB full art")+ Base=Common:fromSheet("BLB cards") # I don't know about these numbers, so i'm just copying them from MH3 Replace=.417F Uncommon:fromSheet("BLB cards") -Replace=.078F MythicRare:fromSheet("BLB cards") +Replace=.078F RareMythic:fromSheet("BLB cards") Replace=.004F fromSheet("BLB borderless") Replace=.042F fromSheet("BLB showcase") diff --git a/forge-gui/res/editions/Duskmourn House of Horror Commander.txt b/forge-gui/res/editions/Duskmourn House of Horror Commander.txt index f57b7ad727d..cc25e6aa2a5 100644 --- a/forge-gui/res/editions/Duskmourn House of Horror Commander.txt +++ b/forge-gui/res/editions/Duskmourn House of Horror Commander.txt @@ -6,5 +6,401 @@ Type=Commander ScryfallCode=DSC [cards] +1 M Aminatou, Veil Piercer @David Palumbo +2 M Kianne, Corrupted Memory @Mila Pesic +3 M The Lord of Pain @Greg Staples +4 M The Master of Keys @Wisnu Tan +5 M Rendmaw, Creaking Nest @Ryan Pancoast +6 M Valgavoth, Harrower of Souls @Chris Cold +7 M Winter, Cynical Opportunist @Andrey Kuzinskiy +8 M Zimone, Mystery Unraveler @Mila Pesic +9 R Redress Fate @Julie Dillon +10 R Secret Arcade @Arthur Yuan +11 R Soaring Lightbringer @Michele Giorgi +12 R Fear of Sleep Paralysis @Joshua Raphael +13 R Glitch Interpreter @Miguel Mercado +14 R They Came from the Pipes @Andreas Zafiratos +15 R Zimone's Hypothesis @Crystal Fae +16 R Ancient Cellarspawn @Alexandre Honoré +17 R Cramped Vents @Arthur Yuan +18 R Deluge of Doom @Nereida +19 R Demonic Covenant @LA Draws +20 R Into the Pit @Greg Staples +21 R Metamorphosis Fanatic @Andreas Zafiratos +22 R Persistent Constrictor @Steve Ellis +23 R Polluted Cistern @Arthur Yuan +24 R Sadistic Shell Game @Karl Kopinski +25 R Suspended Sentence @LA Draws +26 R Barbflare Gremlin @Matt Stewart +27 R Gleeful Arsonist @Nereida +28 R Spiked Corridor @Arthur Yuan +29 R Star Athlete @Andrey Kuzinskiy +30 R Curator Beastie @Nils Hamm +31 R Demolisher Spawn @Nino Is +32 R Disorienting Choice @Mirko Failoni +33 R Experimental Lab @Arthur Yuan +34 R Formless Genesis @Mark Poole +35 R Shriekwood Devourer @David Astruga +36 R Ursine Monstrosity @Carlos Palma Cruchaga +37 R Convert to Slime @LA Draws +38 R Phenomenon Investigators @Viko Menezes +39 R Giggling Skitterspike @Nino Is +40 R Séance Board @Robin Olausson +41 R Redress Fate @Julie Dillon +42 R Soaring Lightbringer @Michele Giorgi +43 R Fear of Sleep Paralysis @Joshua Raphael +44 R Glitch Interpreter @Miguel Mercado +45 R They Came from the Pipes @Andreas Zafiratos +46 R Zimone's Hypothesis @Crystal Fae +47 R Ancient Cellarspawn @Alexandre Honoré +48 R Deluge of Doom @Nereida +49 R Demonic Covenant @LA Draws +50 R Into the Pit @Greg Staples +51 R Metamorphosis Fanatic @Andreas Zafiratos +52 R Persistent Constrictor @Steve Ellis +53 R Sadistic Shell Game @Karl Kopinski +54 R Suspended Sentence @LA Draws +55 R Barbflare Gremlin @Matt Stewart +56 R Gleeful Arsonist @Nereida +57 R Star Athlete @Andrey Kuzinskiy +58 R Curator Beastie @Nils Hamm +59 R Demolisher Spawn @Nino Is +60 R Disorienting Choice @Mirko Failoni +61 R Formless Genesis @Mark Poole +62 R Shriekwood Devourer @David Astruga +63 R Ursine Monstrosity @Carlos Palma Cruchaga +64 R Convert to Slime @LA Draws +65 R Phenomenon Investigators @Viko Menezes +66 R Giggling Skitterspike @Nino Is +67 R Séance Board @Robin Olausson +68 R Mesa Enchantress @Eelis Kyttanen +69 U Moon-Blessed Cleric @Mark Poole +70 R Terminus @Jarel Threat +71 R Aminatou's Augury @Loïc Canavaggia +72 R Cackling Counterpart @Zezhou Chen +73 C Ponder @Ernanda Souza +74 C Portent @Bartek Fedyczak +75 U Telling Time @LA Draws +76 C Blood Pact @Camille Alquier +77 C Blood Seeker @David Astruga +78 C Feed the Swarm @Nino Is +79 C Night's Whisper @Carlos Palma Cruchaga +80 U Beast Within @David Astruga +81 R Citanul Hierophants @Zezhou Chen +82 C Grapple with the Past @Filip Burburan +83 R Moldgraf Monstrosity @Nino Is +84 R Bedevil @Nicholas Gregory +85 R Culling Ritual @Lorenzo Mastroianni +86 U Deathreap Ritual @GodMachine +87 U Diabolic Vision @Mirko Failoni +88 C Growth Spiral @Nicholas Gregory +89 M Mogis, God of Slaughter @Chase Stone +90 U Putrefy @Nicholas Gregory +91 R Utter End @Nicholas Gregory +92 C Arcane Signet @David Astruga +93 U Lightning Greaves @Adrián Rodríguez Pérez +94 U Sol Ring @John Stanko +95 U Suspicious Bookcase @Tyler Walpole +96 C Command Tower @Eddie Schillo +97 C Auramancer @Rebecca Guay +98 U Cast Out @Magali Villeneuve +99 M Entreat the Angels @Todd Lockwood +100 R Monologue Tax @Justine Cruz +101 R Ondu Spiritdancer @Tran Nguyen +102 U Return to Dust @Anato Finnstark +103 R Sigil of the Empty Throne @Cyril Van Der Haegen +104 U Sphere of Safety @Slawomir Maniak +105 R Starfield Mystic @Eric Deschamps +106 U Swords to Plowshares @Jesper Ejsing +107 R Timely Ward @Matt Stewart +108 R Verge Rangers @Livia Prima +109 R Aether Gale @Jack Wang +110 C Arcane Denial @Xi Zhang +111 U Archetype of Imagination @Robbie Trevino +112 R Body of Knowledge @Clint Cearley +113 C Brainstorm @Willian Murai +114 C Counterspell @Zack Stella +115 R Dig Through Time @Ryan Yee +116 M Dream Eater @Daarken +117 R Extravagant Replication @Pauline Voss +118 M Kefnet the Mindful @Chase Stone +119 R Kheru Spellsnatcher @Clint Cearley +120 R Mirrormade @Volkan Baǵa +121 M One with the Multiverse @Liiga Smilshkalne +122 C Otherworldly Gaze @Chris Cold +123 R Primordial Mist @Titus Lunter +124 R Prognostic Sphinx @Steve Prescott +125 U Reality Shift @Howard Lyon +126 U Retreat to Coralhelm @Kieran Yanner +127 R Shark Typhoon @Caio Monteiro +128 M Skaab Ruinator @Chris Rahn +129 C Thirst for Meaning @Brian Valeza +130 M Arvinox, the Mind Flail @Nikola Matkovic +131 U Bastion of Remembrance @Volkan Baǵa +132 U Blood Artist @LA Draws +133 R Braids, Arisen Nightmare @Heonhwa Choe +134 C Carrion Grub @Nicholas Gregory +135 R Cemetery Tampering @Taras Susak +136 R Decree of Pain @Mathias Kollros +137 R Demon of Fate's Design @Fajareka Setiawan +138 R Doomwake Giant @Kev Walker +139 U The Eldest Reborn @Ravenna Tran +140 U Falkenrath Noble @Slawomir Maniak +141 R Fate Unraveler @David Palumbo +142 U Gray Merchant of Asphodel @Scott Murphy +143 U Infernal Grasp @Naomi Baker +144 R Kederekt Parasite @Dan Murayama Scott +145 R Mask of Griselbrand @Jason Felix +146 R Massacre Girl @Chris Rallis +147 M Massacre Wurm @Jason Chan +148 U Morbid Opportunist @Tyler Walpole +149 R Nightmare Shepherd @Tyler Jacobson +150 R Nightshade Harvester @PINDURSKI +151 M Noxious Gearhulk @Lius Lasahido +152 M Ob Nixilis Reignited @Chris Rahn +153 M Professor Onyx @Kieran Yanner +154 C Read the Bones @Lars Grant-West +155 R Reanimate @Johann Bodin +156 C Sign in Blood @Howard Lyon +157 U Stitcher's Supplier @Pete Venters +158 U Syr Konrad, the Grim @Anna Steinbauer +159 R Whip of Erebos @Yeong-Hao Han +160 R Blasphemous Act @Daarken +161 R Brash Taunter @Edgar Sánchez Hidalgo +162 R Chaos Warp @Trevor Claxton +163 M Combustible Gearhulk @Daarken +164 R Enchanter's Bane @Steve Prescott +165 R Harsh Mentor @Shreya Shetty +166 U Light Up the Stage @Dmitry Burmak +167 R Rampaging Ferocidon @Jonathan Kuo +168 R Tectonic Giant @Slawomir Maniak +169 R Arachnogenesis @Johannes Voss +170 M Ashaya, Soul of the Wild @Chase Stone +171 R Augur of Autumn @Billy Christian +172 U Beanstalk Giant @Jason A. Engle +173 U Crawling Sensation @Christopher Moeller +174 C Cultivate @Justyna Dura +175 R Deathcap Cultivator @Karla Ortiz +176 M Deathmist Raptor @Filip Burburan +177 U Explosive Vegetation @John Avon +178 R Ezuri's Predation @Uriah Voth +179 M Giant Adephage @Christine Choi +180 U Gnarlwood Dryad @Raymond Swanland +181 C Greater Tanuki @Ilse Gort +182 U Harmonize @Dan Murayama Scott +183 C Harrow @Rob Alexander +184 M Hornet Queen @Jonathan Kuo +185 M Hydra Omnivore @Svetlin Velinov +186 R Inscription of Abundance @Zoltan Boros +187 M Ishkanah, Grafwidow @Christine Choi +188 C Moldgraf Millipede @Simon Dominic +189 C Mulch @Lucas Graciano +190 M Multani, Yavimaya's Avatar @Ryan Yee +191 U Obsessive Skinner @John Stanko +192 R Overwhelming Stampede @Steven Belledin +193 C Rampant Growth @Steven Belledin +194 C Sakura-Tribe Elder @Anastasia Ovchinnikova +195 R Sandwurm Convergence @Slawomir Maniak +196 R Scavenging Ooze @Austin Hsu +197 R Scute Swarm @Alex Konstad +198 R Shigeki, Jukai Visionary @Anna Podedworna +199 C Skola Grovedancer @Josh Hass +200 R Temur War Shaman @Raymond Swanland +201 R Thunderfoot Baloth @Nicholas Gregory +202 M Titania, Nature's Force @Heonhwa Choe +203 R Trail of Mystery @Raymond Swanland +204 M Whisperwood Elemental @Raymond Swanland +205 U Wilderness Reclamation @Tyler Walpole +206 M Worldspine Wurm @Richard Wright +207 M Wrenn and Seven @Heonhwa Choe +208 C Yavimaya Elder @Matt Cavotta +209 U Yedora, Grave Gardener @Svetlin Velinov +210 M Aesi, Tyrant of Gyre Strait @Viktor Titov +211 R Arixmethes, Slumbering Isle @Dimitar Marinski +212 M Athreos, Shroud-Veiled @Igor Kieryluk +213 U Binding the Old Gods @Victor Adame Minguez +214 R Biomass Mutation @Dan Murayama Scott +215 M Deadbridge Chant @Zoltan Boros +216 C Eureka Moment @Anna Steinbauer +217 R Florian, Voldaren Scion @Justine Cruz +218 R Grim Flayer @Mathias Kollros +219 C Grisly Salvage @Dave Kendall +220 M Grist, the Hunger Tide @Yongjae Choi +221 R Inkshield @Jarel Threat +222 R Kaervek the Merciless @Heonhwa Choe +223 U Kardur, Doomscourge @Chris Rahn +224 R Life Insurance @Brian Valeza +225 U Mayhem Devil @Dmitry Burmak +226 U Nyx Weaver @Jack Wang +227 R Old Stickfingers @Jehan Choo +228 R Oversimplify @Liiga Smilshkalne +229 U Rakdos Charm @Zoltan Boros +230 M Rakdos, Lord of Riots @Yigit Koroglu +231 M Rashmi, Eternities Crafter @Magali Villeneuve +232 M Spirit-Sister's Call @Dominik Mayer +233 R Spiteful Visions @Brandon Kitkouski +234 R Stormfist Crusader @Chris Rallis +235 U Tatyova, Benthic Druid @Mathias Kollros +236 R Theater of Horrors @Daarken +237 R Time Wipe @Svetlin Velinov +238 U Trygon Predator @Carl Critchlow +239 M Vial Smasher the Fierce @Deruchenko Alexander +240 U Azorius Signet @Raoul Vitale +241 R Basilisk Collar @Howard Lyon +242 U Brainstone @Drew Tucker +243 U Burnished Hart @Yeong-Hao Han +244 C Commander's Sphere @Ryan Alexander Lee +245 U Fellwar Stone @John Avon +246 C Golgari Signet @Raoul Vitale +247 U Haywire Mite @Izzy +248 U Mind Stone @Camille Alquier +249 U Orzhov Signet @Martina Pilcerova +250 U Rakdos Signet @Martina Pilcerova +251 R Scroll of Fate @Piotr Dura +252 U Simic Signet @Mike Sass +253 R Solemn Simulacrum @Donato Giancola +254 U Talisman of Indulgence @Mike Dringenberg +255 U Talisman of Resilience @Lindsey Look +256 U Thought Vessel @rk post +257 U Whispersilk Cloak @Daren Bader +258 R Adarkar Wastes @Piotr Dura +259 U Arcane Sanctum @Anthony Francisco +260 C Ash Barrens @Rockey Chen +261 U Azorius Chancery @John Avon +262 U Barren Moor @Heather Hudson +263 R Blackcleave Cliffs @Yeong-Hao Han +264 C Bloodfell Caves @Julian Kok Joon Wen +265 C Bojuka Bog @Howard Lyon +266 R Canyon Slough @Titus Lunter +267 R Castle Vantress @John Avon +268 R Caves of Koilos @Julian Kok Joon Wen +269 C Darkmoss Bridge @Raoul Vitale +270 U Dimir Aqueduct @John Avon +271 R Dragonskull Summit @Alayna Danner +272 R Drownyard Temple @John Avon +273 R Dryad Arbor @Eric Fortune +274 C Evolving Wilds @Steven Belledin +275 R Exotic Orchard @Steven Belledin +276 R Flooded Grove @Dave Kendall +277 R Foreboding Ruins @Adam Paquette +278 C Geothermal Bog @Gabor Szikszai +279 C Golgari Rot Farm @John Avon +280 R Graven Cairns @Anthony S. Waters +281 R Grim Backwoods @Vincent Proce +282 C Halimar Depths @Volkan Baǵa +283 R Hall of Heliod's Generosity @Daniel Ljunggren +284 R Hinterland Harbor @Karl Kopinski +285 C Jungle Hollow @Eytan Zana +286 U Leechridden Swamp @Drew Tucker +287 R Llanowar Wastes @Lucas Graciano +288 R Mosswort Bridge @Jeremy Jarvis +289 U Myriad Landscape @Richard Wright +290 R Necroblossom Snarl @Sam Burley +291 C Obscura Storefront @Muhammad Firdaus +292 U Orzhov Basilica @John Avon +293 R Overflowing Basin @Sarah Finnigan +294 C Quandrix Campus @Piotr Dura +295 U Reliquary Tower @Jesper Ejsing +296 R Shadowblood Ridge @Sam White +297 R Shivan Gorge @John Matson +298 U Simic Growth Chamber @John Avon +299 R Smoldering Marsh @Adam Paquette +300 R Spinerock Knoll @Steve Prescott +301 R Sulfurous Springs @Bruce Brenneise +302 U Tainted Field @Alayna Danner +303 U Tainted Isle @Alan Pollack +304 U Tainted Peak @Tony Szczudlo +305 U Tainted Wood @Rob Alexander +306 C Tangled Islet @Randy Gallegos +307 R Temple of Deceit @Jonas De Ro +308 R Temple of Enlightenment @Piotr Dura +309 R Temple of Malady @Titus Lunter +310 R Temple of Malice @Jonas De Ro +311 R Temple of Mystery @Piotr Dura +312 R Temple of Silence @Adam Paquette +313 U Temple of the False God @Brian Snõddy +314 C Thornwood Falls @Roman Kuteynikov +315 C Thriving Heath @Alayna Danner +316 C Thriving Isle @Jonas De Ro +317 C Thriving Moor @Titus Lunter +318 C Tranquil Thicket @Heather Hudson +319 C Tree of Tales @John Avon +320 R Twilight Mire @Rob Alexander +321 R Underground River @Volkan Baǵa +322 C Vault of Whispers @Rob Alexander +323 R Vineglimmer Snarl @Sam Burley +324 R Viridescent Bog @Piotr Dura +325 R Witch's Clinic @Piotr Dura +326 R Woodland Cemetery @Lars Grant-West +327 R Yavimaya Coast @Jesper Ejsing +328 C Behold the Power of Destruction @Alix Branwyn +329 C Chaos Is My Plaything @Alix Branwyn +330 C Choose Your Champion @Pavel Kolomeyets +331 C Choose Your Demise @Volkan Baǵa +332 C Dark Wings Bring Your Downfall @Miklós Ligeti +333 C Fear My Authority @Steven Belledin +334 C I Am Duskmourn @Liiga Smilshkalne +335 C I Am Never Alone @Marcela Bolívar +336 C I Am Untouchable @Bartek Fedyczak +337 C I Call for Slaughter @Pavel Kolomeyets 338 C I Will Savor Your Agony @Michael Walsh +339 C Kneel Before My Legions @Dave Kendall +340 C Mine Is the Only Truth @Eli Minaya +341 C My Champion Stands Supreme @Justyna Dura +342 C My Crushing Masterstroke @Jana Heidersdorf +343 C My Followers Ascend @Steven Russell Black +344 C My Laughter Echoes @Richard Kane Ferguson +345 C My Tendrils Run Deep @Marcela Bolívar +346 C My Wealth Will Bury You @Valera Lutfullina +347 C My Will Is Irresistible @Samuel Araya +348 C My Wings Enfold All @A. M. Sartor +349 C No Secret Is Hidden from Me @Jeremy Wilson +350 C Only I Know What Awaits @Samuel Araya +351 C Plots That Span Centuries @Septian Fajrianto +352 C Power Without Equal @Eli Minaya +353 C A Premonition of Your Demise @Jessica Fong +354 C Reality Is Mine to Control @Valera Lutfullina +355 C Rot Like the Scum You Are @Isis +356 C Running Is Useless @Dominik Mayer 357 C Time Bends to My Will @Eli Minaya +358 C When Will You Learn? @Jana Heidersdorf +359 C You Are Unworthy of Mercy @WolfSkullJack +360 C You Cannot Hide from Me @Allen Williams +361 C You Exist Only to Amuse @WolfSkullJack +362 C You Live Only Because I Will It @Samuel Araya +363 C You Will Know True Suffering @Pavel Kolomeyets +364 C Your Mistake Is My Triumph @Eli Minaya +365 C Your Nightmares Are Delicious @Lars Grant-West +366 C Your Own Face Mocks You @Dominik Mayer +367 C Your Plans Mean Nothing @Fernando Falcone +368 M Crypt Ghast @Tim Jacobus +369 M Damn @Tim Jacobus +370 M Exhume @Tim Jacobus +371 M Archon of Cruelty @James Bousema +372 M Goryo's Vengeance @Martin Ansin +373 M Living Death @Josh Newton + +[tokens] +b_2_2_bird_flying +b_5_5_demon_flying +bg_1_1_insect +c_4_4_a_scarecrow_vigilance +c_x_x_shapeshifter_changeling_deathtouch +g_1_1_insect +g_1_1_insect +g_1_1_insect_flying_deathtouch +g_1_2_spider_reach +g_2_2_ooze +g_3_3_beast +g_4_4_phyrexian_beast +g_5_3_elemental +g_5_5_wurm +g_5_5_wurm_trample +g_x_x_ooze +g_x_x_treefolk_reach_total_lands +gu_0_0_fractal +r_1_1_devil_burn +u_x_x_shark_flying +w_1_1_human_soldier +w_4_4_angel_flying +wb_2_1_inkling_flying diff --git a/forge-gui/res/editions/Duskmourn House of Horror.txt b/forge-gui/res/editions/Duskmourn House of Horror.txt index b106c64e344..ec6f52e76a6 100644 --- a/forge-gui/res/editions/Duskmourn House of Horror.txt +++ b/forge-gui/res/editions/Duskmourn House of Horror.txt @@ -6,36 +6,451 @@ Type=Expansion ScryfallCode=DSK [cards] +1 C Acrobatic Cheerleader @Julia Metzger +2 C Cult Healer @Diana Franco +3 R Dazzling Theater @Henry Peters +4 M Dollmaker's Shop @Chris Cold +5 C Emerge from the Cocoon @Marta Nael +6 R Enduring Innocence @Liiga Smilshkalne +7 U Ethereal Armor @Tyler Walpole +8 U Exorcise @Dominik Mayer +9 U Fear of Abduction @Fernando Falcone +10 C Fear of Immobility @Martin de Diego Sádaba +11 C Fear of Surveillance @Jana Heidersdorf +12 C Friendly Ghost @Sean Murray +13 R Ghostly Dancers @Josh Newton +14 U Glimmer Seeker @Kev Fang +15 C Grand Entryway @Carlos Palma Cruchaga +16 C Hardened Escort @John Stanko +17 C Jump Scare @John Tedrick 18 R Leyline of Hope @Sergey Glushakov +19 U Lionheart Glimmer @Josu Hernaiz +20 C Living Phone @Domenico Cava +21 U Optimistic Scavenger @Brian Valeza +22 U Orphans of the Wheat @Julie Dillon +23 M Overlord of the Mistmoors @Steven Belledin +24 U Patched Plaything @Domenico Cava +25 C Possessed Goat @Edgar Sánchez Hidalgo +26 R Reluctant Role Model @Chris Rallis +27 U Savior of the Small @Elizabeth Peiró +28 C Seized from Slumber @Miranda Meeks +29 U Shardmage's Rescue @Jarel Threat +30 U Sheltered by Ghosts @Mirko Failoni +31 C Shepherding Spirits @Billy Christian +32 R Split Up @Dominik Mayer +33 U Splitskin Doll @Diana Franco +34 U Surgical Suite @Titus Lunter 35 R Toby, Beastie Befriender @Jehan Choo +36 C Trapped in the Screen @Michael Phillippi +37 R Unidentified Hovership @Jana Heidersdorf +38 C Unsettling Twins @Lauren K. Cannon +39 U Unwanted Remake @Eli Minaya +40 U Veteran Survivor @Kai Carpenter 41 M The Wandering Rescuer @Anna Pavleeva +42 M Abhorrent Oculus @Bryan Sola +43 U Bottomless Pool @Diana Franco +44 R Central Elevator @Cristi Balanescu +45 C Clammy Prowler @John Tedrick +46 C Creeping Peeper @Maxime Minard +47 U Cursed Windbreaker @Nino Vecia +48 C Daggermaw Megalodon @Helge C. Balzer +49 C Don't Make a Sound @Zezhou Chen +50 U Duskmourn's Domination @Eli Minaya +51 R Enduring Curiosity @Julie Dillon +52 C Enter the Enigma @Chris Rallis +53 R Entity Tracker @Cristi Balanescu +54 C Erratic Apparition @Miranda Meeks +55 U Fear of Failed Tests @Jana Heidersdorf +56 U Fear of Falling @Maxime Minard +57 U Fear of Impostors @David Szabo +58 U Fear of Isolation @Irina Nordsol +59 U Floodpits Drowner @John Tedrick +60 U Get Out @Mirko Failoni +61 U Ghostly Keybearer @Marco Gorlei +62 C Glimmerburst @Dan Watson +63 R Leyline of Transformation @Sergey Glushakov +64 R Marina Vendrell's Grimoire @Denys Tsiperko +65 C Meat Locker @Sergey Glushakov +66 R The Mindskinner @Abz J Harding +67 M Mirror Room @Helge C. Balzer +68 M Overlord of the Floodpits @Abz J Harding +69 U Paranormal Analyst @James Ryman +70 C Piranha Fly @Kekai Kotaki +71 U Scrabbling Skullcrab @John Tedrick +72 R Silent Hallcreeper @Joshua Raphael +73 C Stalked Researcher @Marta Nael +74 U Stay Hidden, Stay Silent @Josu Hernaiz +75 R The Tale of Tamiyo @Anna Pavleeva +76 C Tunnel Surveyor @John Stanko +77 C Twist Reality @Allen Williams +78 C Unable to Scream @Fariba Khamseh +79 C Underwater Tunnel @Titus Lunter +80 U Unnerving Grasp @Jeremy Wilson +81 U Unwilling Vessel @Josu Hernaiz +82 C Vanish from Sight @Billy Christian +83 C Appendage Amalgam @Bartek Fedyczak +84 C Balemurk Leech @John Tedrick +85 C Cackling Slasher @Johann Bodin 86 R Come Back Wrong @David Auden Nash +87 U Commune with Evil @Ovidio Cartagena +88 C Cracked Skull @Mirko Failoni +89 U Cynical Loner @Miranda Meeks +90 U Dashing Bloodsucker @Randy Gallegos +91 U Defiled Crypt @Martin de Diego Sádaba +92 R Demonic Counsel @Babs Webb +93 C Derelict Attic @Marc Simonetti 94 R Doomsday Excruciator @Denys Tsiperko 95 R Enduring Tenacity @Isis +96 C Fanatic of the Harrowing @Fajareka Setiawan +97 C Fear of Lost Teeth @Oriana Menendez +98 C Fear of the Dark @Sam Wolfe Connelly +99 C Final Vengeance @David Szabo +100 M Funeral Room @Miklós Ligeti +101 C Give In to Violence @Septian Fajrianto +102 R Grievous Wound @Martina Fačková +103 C Innocuous Rat @Maxime Minard +104 U Killer's Mask @Wero Gallo +105 U Let's Play a Game @Riccardo Federici +106 R Leyline of the Void @Sergey Glushakov +107 U Live or Die @Lorenzo Mastroianni +108 M Meathook Massacre II @Tiffany Turrill +109 U Miasma Demon @Mathias Kollros +110 C Murder @Domenico Cava 111 U Nowhere to Run @Jodie Muir +112 U Osseous Sticktwister @Mathias Kollros +113 M Overlord of the Balemurk @Babs Webb +114 U Popular Egotist @Julia Metzger +115 C Resurrected Cultist @Tyler Walpole +116 C Spectral Snatcher @Domenico Cava +117 U Sporogenic Infection @Warren Mahy +118 R Unholy Annex @Matteo Bassini +119 R Unstoppable Slasher @Maxime Minard +120 M Valgavoth, Terror Eater @Antonio José Manzanedo +121 U Valgavoth's Faithful @Jodie Muir +122 U Vile Mutilator @Néstor Ossandón Leal +123 C Winter's Intervention @Cristi Balanescu +124 U Withering Torment @Inkognit +125 C Bedhead Beastie @David Auden Nash +126 U Betrayer's Bargain @Billy Christian +127 C Boilerbilges Ripper @Kai Carpenter 128 R Chainsaw @J.P. Targete +129 M Charred Foyer @Andrew Mar +130 C Clockwork Percussionist @Eric Wilkerson 131 R Cursed Recording @Kim Sokol +132 U Diversion Specialist @Tuan Duong Chu +133 R Enduring Courage @Yigit Koroglu +134 U Fear of Being Hunted @Maxime Minard +135 U Fear of Burning Alive @J.P. Targete 136 R Fear of Missing Out @John Stanko +137 C Glassworks @Sergey Glushakov +138 C Grab the Prize @Halil Ural +139 C Hand That Feeds @Loïc Canavaggia +140 C Impossible Inferno @Edgar Sánchez Hidalgo +141 U Infernal Phantom @Mike Sass +142 U Irreverent Gremlin @Fajareka Setiawan +143 R Leyline of Resonance @Sergey Glushakov +144 C Most Valuable Slayer @Patrik Hell +145 U Norin, Swift Survivalist @Yigit Koroglu +146 M Overlord of the Boilerbilges @Helge C. Balzer +147 U Painter's Studio @Marc Simonetti +148 U Piggy Bank @Steve Ellis +149 U Pyroclasm @Néstor Ossandón Leal +150 C Ragged Playmate @Kaitlyn McCulley +151 C Rampaging Soulrager @Slawomir Maniak +152 U Razorkin Hordecaller @David Álvarez +153 R Razorkin Needlehead @Riccardo Federici +154 C Ripchain Razorkin @David Szabo +155 M The Rollercrusher Ride @Deruchenko Alexander +156 C Scorching Dragonfire @Marta Nael 157 M Screaming Nemesis @Liiga Smilshkalne +158 C Ticket Booth @Marco Gorlei +159 U Trial of Agony @Mike Sass +160 C Turn Inside Out @Loïc Canavaggia +161 U Untimely Malfunction @Jarel Threat +162 U Vengeful Possession @Dominik Mayer +163 C Vicious Clown @Johann Bodin +164 U Violent Urge @Mirko Failoni +165 R Waltz of Rage @Mathias Kollros +166 U Altanak, the Thrice-Called @Sam Wolfe Connelly +167 C Anthropede @Loïc Canavaggia +168 R Balustrade Wurm @Maxime Minard +169 C Bashful Beastie @Aaron Miller +170 U Break Down the Door @Ralph Horsley +171 U Cathartic Parting @Miranda Meeks +172 C Cautious Survivor @Jodie Muir +173 U Coordinated Clobbering @Fajareka Setiawan +174 C Cryptid Inspector @Kim Sokol +175 U Defiant Survivor @Jessica Fong +176 R Enduring Vitality @Valera Lutfullina +177 U Fear of Exposure @Josu Hernaiz +178 C Flesh Burrower @Maxime Minard +179 C Frantic Strength @Flavio Greco Paglia +180 C Grasping Longneck @Mathias Kollros +181 U Greenhouse @John Di Giovanni +182 M Hauntwoods Shrieker @John Tedrick +183 R Hedge Shredder @Cristi Balanescu +184 C Horrid Vigor @Chris Cold +185 U House Cartographer @Kai Carpenter +186 U Insidious Fungus @Slawomir Maniak +187 R Kona, Rescue Beastie @Brian Valeza +188 R Leyline of Mutation @Sergey Glushakov +189 C Manifest Dread @Andrey Kuzinskiy +190 C Moldering Gym @Helge C. Balzer +191 C Monstrous Emergence @Loïc Canavaggia +192 R Omnivorous Flytrap @Antonio José Manzanedo +193 U Overgrown Zealot @Tyler Walpole 194 M Overlord of the Hauntwoods @Tiffany Turrill +195 U Patchwork Beastie @John Tedrick +196 U Rootwise Survivor @Joseph Weston +197 C Say Its Name @Sam Wolfe Connelly +198 C Slavering Branchsnapper @John Tedrick +199 C Spineseeker Centipede @Dave Kendall +200 U Threats Around Every Corner @Andrea Piparo +201 R Twitching Doll @Warren Mahy +202 M Tyvar, the Pummeler @Olivier Bernard +203 U Under the Skin @Fernando Falcone +204 R Valgavoth's Onslaught @Lie Setiawan +205 M Walk-in Closet @Miklós Ligeti +206 C Wary Watchdog @Olivier Bernard +207 U Wickerfolk Thresher @WolfSkullJack +208 U Arabella, Abandoned Doll @J.P. Targete +209 U Baseball Bat @John Stanko +210 U Beastie Beatdown @Inkognit +211 U Broodspinner @Igor Krstic +212 U Disturbing Mirth @Nino Vecia +213 U Drag to the Roots @Deruchenko Alexander +214 U Fear of Infinity @Fernando Falcone +215 U Gremlin Tamer @Billy Christian +216 U Growing Dread @Maxime Minard +217 U Inquisitive Glimmer @Julie Dillon +218 U Intruding Soulrager @Jeremy Wilson +219 R The Jolly Balloon Man @Campbell White +220 M Kaito, Bane of Nightmares @Joshua Raphael +221 R Marina Vendrell @Magali Villeneuve +222 U Midnight Mayhem @Olivier Bernard +223 R Nashi, Searcher in the Dark @Johan Grenier +224 M Niko, Light of Hope @Aurore Folny +225 U Oblivious Bookworm @Josh Newton +226 R Peer Past the Veil @Tuan Duong Chu +227 R Restricted Office @Antonio José Manzanedo +228 R Rip, Spawn Hunter @Justine Cruz +229 U Rite of the Moth @A. M. Sartor +230 R Roaring Furnace @Miklós Ligeti +231 U Sawblade Skinripper @Zezhou Chen +232 U Shrewd Storyteller @David Palumbo +233 U Shroudstomper @Campbell White +234 U Skullsnap Nuisance @Allen Douglas +235 U Smoky Lounge @Marco Gorlei +236 R The Swarmweaver @Helge C. Balzer +237 R Undead Sprinter @Nino Vecia +238 R Victor, Valgavoth's Seneschal @Jeremy Wilson +239 U Wildfire Wickerfolk @J.Lonnee +240 R Winter, Misanthropic Guide @Jodie Muir +241 R Zimone, All-Questioning @Ekaterina Burmak +242 U Attack-in-the-Box @Domenico Cava +243 C Bear Trap @Michele Giorgi +244 U Conductive Machete @Steven Russell Black +245 R Dissection Tools @Diana Franco +246 C Found Footage @Jarel Threat +247 C Friendly Teddy @Johann Bodin +248 R Ghost Vacuum @David Szabo +249 C Glimmerlight @Wero Gallo +250 U Haunted Screen @Sean Murray +251 U Keys to the House @Artur Treffner +252 C Malevolent Chandelier @Mirko Failoni +253 R Marvin, Murderous Mimic @Mirko Failoni +254 U Saw @Jarel Threat +255 C Abandoned Campground @Cristi Balanescu +256 R Blazemire Verge @Andrew Mar +257 C Bleeding Woods @Henry Peters +258 C Etched Cornfield @Randy Gallegos +259 R Floodfarm Verge @Randy Gallegos +260 R Gloomlake Verge @Marco Gorlei +261 R Hushwood Verge @Kasia 'Kafis' Zielińska +262 C Lakeside Shack @Bartek Fedyczak +263 C Murky Sewer @Martin de Diego Sádaba +264 C Neglected Manor @Carlos Palma Cruchaga +265 C Peculiar Lighthouse @Raymond Bonilla +266 C Raucous Carnival @Josu Solano +267 C Razortrap Gorge @Filip Burburan +268 C Strangled Cemetery @Marco Gorlei +269 C Terramorphic Expanse @Sam Burley +270 R Thornspire Verge @Kasia 'Kafis' Zielińska +271 R Valgavoth's Lair @Martin de Diego Sádaba 272 L Plains @Dan Mumford 273 L Island @Dan Mumford 274 L Swamp @Dan Mumford 275 L Mountain @Dan Mumford 276 L Forest @Dan Mumford +277 L Plains @Marco Gorlei +278 L Plains @Josu Hernaiz +279 L Island @Raymond Bonilla +280 L Island @Leonardo Borazio +281 L Swamp @Martin de Diego Sádaba +282 L Swamp @Néstor Ossandón Leal +283 L Mountain @Ralph Horsley +284 L Mountain @Néstor Ossandón Leal +285 L Forest @Martin de Diego Sádaba +286 L Forest @Josu Hernaiz + +[alternate art] +287 C Grand Entryway @Carlos Palma Cruchaga +288 U Optimistic Scavenger @Brian Valeza +289 R Reluctant Role Model @Chris Rallis +290 R Entity Tracker @Cristi Balanescu +291 U Stay Hidden, Stay Silent @Josu Hernaiz 292 R Come Back Wrong @David Auden Nash +293 M Meathook Massacre II @Tiffany Turrill +294 R Unstoppable Slasher @Maxime Minard +295 C Clockwork Percussionist @Eric Wilkerson 296 R Cursed Recording @Kim Sokol +297 U Norin, Swift Survivalist @Yigit Koroglu +298 M The Rollercrusher Ride @Deruchenko Alexander +299 R Kona, Rescue Beastie @Brian Valeza +300 U Oblivious Bookworm @Josh Newton +301 R The Swarmweaver @Helge C. Balzer + +[showcase] +302 R Ghostly Dancers @Scott Buoncristiano +303 R Reluctant Role Model @Ivan Shavrin +304 R Split Up @Toni Infante +305 R Unidentified Hovership @Calder Moore +306 U Unwanted Remake @Ivan Shavrin +307 R Entity Tracker @Ivan Shavrin +308 R Marina Vendrell's Grimoire @Lenka Šimečková & Scott Okumura 309 R Come Back Wrong @Alexis Ziritt +310 R Demonic Counsel @Bastien Grivet +311 M Meathook Massacre II @SchmandrewART +312 R Unstoppable Slasher @SchmandrewART +313 U Withering Torment @Ivan Shavrin 314 R Chainsaw @Alexis Ziritt -346 R Doomsday Excruciator @Jarel Threat -348 M Screaming Nemesis @Inkognit +315 R Cursed Recording @Alexis Ziritt +316 R Fear of Missing Out @Cacho Rubione +317 M The Rollercrusher Ride @Cacho Rubione +318 R Waltz of Rage @SchmandrewART +319 R Balustrade Wurm @Alexis Ziritt +320 R Hedge Shredder @Neo.G +321 U Insidious Fungus @Bastien Grivet +322 R Omnivorous Flytrap @Chun Lo +323 U Under the Skin @Cacho Rubione +324 R Valgavoth's Onslaught @Cacho Rubione +325 R Peer Past the Veil @Scott Buoncristiano +326 R Ghost Vacuum @Lenka Šimečková & Scott Okumura +327 R Valgavoth's Lair @Ivan Shavrin 351 M The Wandering Rescuer @Vance Kelly +352 M Valgavoth, Terror Eater @Pig Hands +353 M Tyvar, the Pummeler @Richard Luong +354 M Kaito, Bane of Nightmares @Richard Luong +355 M Niko, Light of Hope @Vance Kelly 356 R Toby, Beastie Befriender @Ashley Mackenzie -374 R Enduring Tenacity @Isis -383 M Overlord of the Hauntwoods @Tiffany Turrill +357 R The Mindskinner @Goñi Montes +358 R Kona, Rescue Beastie @Sam Wolfe Connelly +359 R The Jolly Balloon Man @Richard Luong +360 R Marina Vendrell @Jack Hughes +361 R Nashi, Searcher in the Dark @Ashley Mackenzie +362 R Rip, Spawn Hunter @Ashley Mackenzie +363 R The Swarmweaver @Sam Wolfe Connelly +364 R Victor, Valgavoth's Seneschal @Ashley Mackenzie +365 R Winter, Misanthropic Guide @Sam Wolfe Connelly +366 R Zimone, All-Questioning @Sam Wolfe Connelly +367 R Marvin, Murderous Mimic @Sam Wolfe Connelly +386 M Enduring Innocence @Kawasumi +387 M Overlord of the Mistmoors @Takeuchi Moto +388 R Enduring Curiosity @D-suzuki +389 M Overlord of the Floodpits @Sansyu 390 M Enduring Tenacity @TAPIOCA +391 M Overlord of the Balemurk @Mikio Masuda +392 M Enduring Courage @Nuisuke +393 M Overlord of the Boilerbilges @akio +394 M Enduring Vitality @Issei Murakami 395 M Overlord of the Hauntwoods @Aogachou +396 R Enduring Innocence @Kawasumi +397 M Overlord of the Mistmoors @Takeuchi Moto +398 R Enduring Curiosity @D-suzuki +399 M Overlord of the Floodpits @Sansyu 400 M Enduring Tenacity @TAPIOCA +401 M Overlord of the Balemurk @Mikio Masuda +402 M Enduring Courage @Nuisuke +403 M Overlord of the Boilerbilges @akio +404 M Enduring Vitality @Issei Murakami 405 M Overlord of the Hauntwoods @Aogachou 406 M The Wandering Rescuer @Vance Kelly +407 M Valgavoth, Terror Eater @Pig Hands +408 M Tyvar, the Pummeler @Richard Luong +409 M Kaito, Bane of Nightmares @Richard Luong +410 M Niko, Light of Hope @Vance Kelly + +[borderless] +328 M Kaito, Bane of Nightmares @Marta Nael +329 R Blazemire Verge @Allen Douglas +330 R Floodfarm Verge @Sam Burley +331 R Gloomlake Verge @Julian Kok Joon Wen +332 R Hushwood Verge @Henry Peters +333 R Thornspire Verge @Pavel Kolomeyets +334 R Dazzling Theater @Ivan Shavrin +335 M Dollmaker's Shop @Cacho Rubione +336 R Central Elevator @Ivan Shavrin +337 M Mirror Room @Cacho Rubione +338 M Funeral Room @Alexandre Chaudret +339 R Unholy Annex @Alexis Ziritt +340 M Charred Foyer @Oliver Barrett +341 M Walk-in Closet @Bastien Grivet +342 R Restricted Office @Scott Buoncristiano +343 R Roaring Furnace @Toni Infante +344 M Abhorrent Oculus @Igor Krstic +345 R Silent Hallcreeper @Inkognit +346 R Doomsday Excruciator @Jarel Threat +347 R Razorkin Needlehead @Loïc Canavaggia +348 M Screaming Nemesis @Inkognit +349 M Hauntwoods Shrieker @Sidharth Chaturvedi +350 R Undead Sprinter @John Thacker + +[extended art] +368 R Enduring Innocence @Liiga Smilshkalne +369 R Leyline of Hope @Sergey Glushakov +370 M Overlord of the Mistmoors @Steven Belledin +371 R Enduring Curiosity @Julie Dillon +372 R Leyline of Transformation @Sergey Glushakov +373 M Overlord of the Floodpits @Abz J Harding +374 R Enduring Tenacity @Isis +375 R Grievous Wound @Martina Fačková +376 R Leyline of the Void @Sergey Glushakov +377 M Overlord of the Balemurk @Babs Webb +378 R Enduring Courage @Yigit Koroglu +379 R Leyline of Resonance @Sergey Glushakov +380 M Overlord of the Boilerbilges @Helge C. Balzer +381 R Enduring Vitality @Valera Lutfullina +382 R Leyline of Mutation @Sergey Glushakov +383 M Overlord of the Hauntwoods @Tiffany Turrill +384 R Twitching Doll @Warren Mahy +385 R Dissection Tools @Diana Franco + +[promo] +411 U Shardmage's Rescue @Jarel Threat +412 U Valgavoth's Faithful @Jodie Muir +413 U Pyroclasm @Néstor Ossandón Leal +414 U Drag to the Roots @Deruchenko Alexander +415 U Inquisitive Glimmer @Julie Dillon + +[bundle] +416 R Grievous Wound @Fajareka Setiawan + +[buy a box] 417 R Twitching Doll @John Tedrick + +[tokens] +b_2_2_e_horror +b_6_6_demon_flying +bg_1_1_insect_flying +c_a_treasure_sac +c_e_shard_draw +everywhere +g_2_2_spider_reach +primo_the_indivisible +r_1_1_gremlin +u_x_x_spirit_flying +w_1_1_a_toy +w_1_1_e_glimmer +w_2_1_insect_flying +w_3_1_spirit_flying +w_4_4_beast_lonely diff --git a/forge-gui/res/editions/Modern Horizons 3 Commander.txt b/forge-gui/res/editions/Modern Horizons 3 Commander.txt index fa8eeb3502c..7719af642c1 100644 --- a/forge-gui/res/editions/Modern Horizons 3 Commander.txt +++ b/forge-gui/res/editions/Modern Horizons 3 Commander.txt @@ -428,7 +428,6 @@ marit_lage r_1_1_goblin r_5_5_dragon_flying rgw_1_1_sand_warrior -tarmogoyf u_2_1_a_phyrexian_myr u_2_2_shapeshifter_changeling u_x_x_illusion diff --git a/forge-gui/res/editions/Modern Horizons 3.txt b/forge-gui/res/editions/Modern Horizons 3.txt index e38c7302549..a339d3a68f3 100644 --- a/forge-gui/res/editions/Modern Horizons 3.txt +++ b/forge-gui/res/editions/Modern Horizons 3.txt @@ -11,25 +11,24 @@ ChaosDraftThemes=MASTERS_SET ScryfallCode=MH3 [Common] -Base=Common +Base=Common:fromSheet("MH3 cards") [Common-Guest] -Base=Common +Base=Common:fromSheet("MH3 cards") Replace=.015625F fromSheet("MH3 special guests") [Uncommon] -Base=Uncommon +Base=Uncommon:fromSheet("MH3 cards") [RareMythic] -Base=RareMythic -Replace=.021F fromSheet("MH3 retro frame") -# Fetch lands, Concept Eldrazi, Planeswalkers, Frame Break treatments, Profile treatments, and borderless treatments on Rare or Mythic Rare cards will appear 5.1 percent of the time -Replace=.051F fromSheet("MH3 booster fun") +Base=RareMythic:fromSheet("MH3 cards") +Replace=.021F fromSheet("MH3 alternate frame") +Replace=.051F fromSheet("MH3 borderless") [Common-Land] -Base=Common -Replace=.20F Land -Replace=.133F Land+ +Base=Common:fromSheet("MH3 cards") +Replace=.20F Land:fromSheet("MH3 cards") +Replace=.133F Land:fromSheet("MH3 cards")+ Replace=.10F fromSheet("MH3 full art") Replace=.067F fromSheet("MH3 full art")+ @@ -39,14 +38,14 @@ Replace=.213F Rare:fromSheet("MH3 new to modern") Replace=.023F Mythic:fromSheet("MH3 new to modern") Replace=.008F fromSheet("MH3 borderless frame") Replace=.003F fromSheet("MH3 borderless profile") -Replace=.001F fromSheet("MH3 retro") +Replace=.001F fromSheet("MH3 alternate frame") [Wildcard] -Base=Common -Replace=.417F Uncommon -Replace=.078F MythicRare +Base=Common:fromSheet("MH3 cards") +Replace=.417F Uncommon:fromSheet("MH3 cards") +Replace=.078F RareMythic:fromSheet("MH3 cards") Replace=.004F fromSheet("MH3 borderless frame") -Replace=.042F fromSheet("MH3 retro") +Replace=.042F fromSheet("MH3 alternate frame") [cards] 1 U Breaker of Creation @Yohann Schepacz @@ -352,12 +351,6 @@ Replace=.042F fromSheet("MH3 retro") 301 R Deserted Temple @Rob Alexander 302 U Nesting Grounds @Yeong-Hao Han 303 M Phyrexian Tower @Martin de Diego Sádaba -304 L Plains @Nadia Hurianova -305 L Island @Samuele Bandini -306 L Swamp @Yohann Schepacz -307 L Mountain @Chuck Lukacs -308 L Forest @Vance Kovacs -309 U Snow-Covered Wastes @Tomáš Honz 310 L Plains @Volkan Baǵa 311 L Plains @Lius Lasahido 312 L Island @Alayna Danner @@ -369,6 +362,14 @@ Replace=.042F fromSheet("MH3 retro") 318 L Forest @Lars Grant-West 319 L Forest @Brian Valeza +[full art] +304 L Plains @Nadia Hurianova +305 L Island @Samuele Bandini +306 L Swamp @Yohann Schepacz +307 L Mountain @Chuck Lukacs +308 L Forest @Vance Kovacs +309 U Snow-Covered Wastes @Tomáš Honz + [borderless] 320 R Echoes of Eternity @Clint Lockwood 321 R Flare of Fortitude @Kev Fang @@ -400,6 +401,8 @@ Replace=.042F fromSheet("MH3 retro") 347 R Pearl Medallion @Olena Richards 348 R Ruby Medallion @Martina Pilcerova 349 R Sapphire Medallion @Ron Spears + +[borderless frame] 350 R Archway of Innovation @Sam Burley 351 R Arena of Glory @Piotr Dura 352 R Bloodstained Mire @Sean Vo @@ -421,6 +424,8 @@ Replace=.042F fromSheet("MH3 retro") 368 R Laelia, the Blade Reforged @Tyler Walpole 369 M Eladamri, Korvecdal @Tyler Walpole 370 R Six @Ivan Shavrin + +[borderless profile] 371 M Arna Kennerüd, Skycaptain @Grant Griffin 372 M Breya, Etherium Shaper @Jack Hughes 373 R Genku, Future Shaper @Ivan Shavrin @@ -497,6 +502,33 @@ Replace=.042F fromSheet("MH3 retro") 432 R Kudo, King Among Bears @Ekaterina Burmak 433 R Psychic Frog @Pete Venters 434 R Rosheen, Roaring Prophet @Fang Xinyu +497 L Plains @Volkan Baǵa +498 L Plains @Lius Lasahido +499 L Island @Alayna Danner +500 L Island @Raph Lomotan +501 L Swamp @David Álvarez +502 L Swamp @Carlos Palma Cruchaga +503 L Mountain @Carlos Palma Cruchaga +504 L Mountain @Paolo Parente +505 L Forest @Lars Grant-West +506 L Forest @Brian Valeza +507 U Glaring Fleshraker @Raph Lomotan +508 U Wastescape Battlemage @Paolo Parente +509 C Jolted Awake @Steven Russell Black +510 U Bespoke Battlewagon @Zoltan Boros +511 U Roil Cartographer @Miranda Meeks +512 C Accursed Marauder @Paolo Parente +513 U Amped Raptor @Alex Konstad +514 U Unstable Amulet @José Parodi +515 U Izzet Generatorium @Yeong-Hao Han +516 U Scurry of Gremlins @Ben Wootten +517 C Snapping Voidcraw @Camille Alquier +518 U Titans' Vanguard @Richard Kane Ferguson +519 U Solar Transformer @Mike Bierek +520 C Tranquil Landscape @Randy Gallegos +521 C Twisted Landscape @Piotr Dura + +[alternate frame] 435 R Bloodstained Mire @Bruce Brenneise 436 R Flooded Strand @Alexander Forssberg 437 U Nesting Grounds @Yeong-Hao Han @@ -526,31 +558,6 @@ Replace=.042F fromSheet("MH3 retro") 492 R The Necrobloom @Igor Krstic 493 M Phlage, Titan of Fire's Fury @Lucas Graciano 494 R Rosheen, Roaring Prophet @Fang Xinyu -497 L Plains @Volkan Baǵa -498 L Plains @Lius Lasahido -499 L Island @Alayna Danner -500 L Island @Raph Lomotan -501 L Swamp @David Álvarez -502 L Swamp @Carlos Palma Cruchaga -503 L Mountain @Carlos Palma Cruchaga -504 L Mountain @Paolo Parente -505 L Forest @Lars Grant-West -506 L Forest @Brian Valeza -507 U Glaring Fleshraker @Raph Lomotan -508 U Wastescape Battlemage @Paolo Parente -509 C Jolted Awake @Steven Russell Black -510 U Bespoke Battlewagon @Zoltan Boros -511 U Roil Cartographer @Miranda Meeks -512 C Accursed Marauder @Paolo Parente -513 U Amped Raptor @Alex Konstad -514 U Unstable Amulet @José Parodi -515 U Izzet Generatorium @Yeong-Hao Han -516 U Scurry of Gremlins @Ben Wootten -517 C Snapping Voidcraw @Camille Alquier -518 U Titans' Vanguard @Richard Kane Ferguson -519 U Solar Transformer @Mike Bierek -520 C Tranquil Landscape @Randy Gallegos -521 C Twisted Landscape @Piotr Dura [extended art] 447 R Argent Dais @Carlos Palma Cruchaga @@ -659,7 +666,6 @@ c_a_treasure_sac g_0_1_plant g_1_1_insect r_1_1_gremlin -spellgorger_weird u_1_1_a_thopter_flying u_1_2_moonfolk_flying u_2_2_bird_flying diff --git a/forge-gui/res/editions/Resale Promos.txt b/forge-gui/res/editions/Resale Promos.txt index 5c895eb0cf3..d337960b290 100644 --- a/forge-gui/res/editions/Resale Promos.txt +++ b/forge-gui/res/editions/Resale Promos.txt @@ -6,7 +6,10 @@ Type=Promo ScryfallCode=PRES [cards] +1 R Llanowar Elves @Chris Rahn A1 R Jaya Ballard, Task Mage @Matt Cavotta +2 M Lathril, Blade of the Elves @Caroline Gariba +2b M Jace, Memory Adept @D. Alexander Gregory A2 R Brion Stoutarm @Zoltan Boros & Gabor Szikszai A3 R Broodmate Dragon @Vance Kovacs A4 R Retaliator Griffin @Jesper Ejsing @@ -14,18 +17,20 @@ A5 R Terra Stomper @Goran Josic A6 R Terastodon @Lars Grant-West A7 R Knight Exemplar @Jason Chan A8 R Sunblast Angel @Jason Chan +9 M Ajani, Mentor of Heroes @Aaron Miller A9 R Angel of Glory's Rise @James Ryman A10 R Hamletback Goliath @Paolo Parente & Brian Snõddy A11 R Angelic Skirmisher @David Rapoza A12 R Xathrid Necromancer @Maciej Kuciara -1 R Llanowar Elves @Chris Rahn -2 M Lathril, Blade of the Elves @Caroline Gariba 13★ U Loam Lion @Daniel Ljunggren 26 R Felidar Sovereign @Zoltan Boros & Gabor Szikszai +46 R Welcoming Vampire @Lorenzo Mastroianni 47 R Thalia's Lancers @David Palumbo 49 R Curator of Mysteries @Christine Choi 52 R Cyclone Summoner @Andrey Kuzinskiy +69 R Patrician Geist @Marta Nael 100 R Etali, Primal Storm @Raymond Swanland +118 R Headless Rider @E. M. Gist 123 R Beast Whisperer @Matt Stewart 124 R End-Raze Forerunners @Mathias Kollros 125 R Calamity Bearer @Simon Dominic diff --git a/forge-gui/res/editions/Secret Lair Drop Series.txt b/forge-gui/res/editions/Secret Lair Drop Series.txt index b1fce77e115..695320306e7 100644 --- a/forge-gui/res/editions/Secret Lair Drop Series.txt +++ b/forge-gui/res/editions/Secret Lair Drop Series.txt @@ -795,6 +795,12 @@ F798 M Discord, Lord of Disharmony @Narendra Bintara Adi 827 R Norin the Wary @Jarel Threat 827b R Norin the Wary @Jarel Threat 828 R Keen Duelist @Thanh Tuấn +873 R Dark Deal @Tyler Jacobson +874 R Archivist of Oghma @Cory Trego-Erdner +875 M Battle Angels of Tyr @Raymond Swanland +876 R Xorn @Ivan Shavrin +877 R Druid of Purification @Alexander Mokhov +878 R Prosperous Innkeeper @Tyler Jacobson 900 M The Scarab God @Barely Human 901 R Lightning Bolt @Christopher Rush 903 M The Locust God @See Machine diff --git a/forge-gui/res/editions/Special Guests.txt b/forge-gui/res/editions/Special Guests.txt index ba8898f5e45..8f81f17a5d1 100644 --- a/forge-gui/res/editions/Special Guests.txt +++ b/forge-gui/res/editions/Special Guests.txt @@ -66,7 +66,7 @@ ScryfallCode=SPG 52 M Fury @Campbell White 53 M Endurance @Campbell White 54 M Swords to Plowshares @Izzy -55 R Ledger Shredder @Volkan Baǵa +55 M Ledger Shredder @Volkan Baǵa 56 M Rat Colony @Mark Zug 57 M Relentless Rats @Mathias Kollros 58 M Kindred Charge @Milivoj Ćeran @@ -75,4 +75,13 @@ ScryfallCode=SPG 61 M Frogmite @Mike Sass 62 M Sword of Fire and Ice @Volkan Baǵa 63 M Secluded Courtyard @Dan Murayama Scott +64 M Hallowed Haunting @Mila Pesic +65 M Soul Warden @Joshua Cairos +66 M Expropriate @Borja Pindado +67 M Phantasmal Image @Darren Tan +68 M Damnation @Masahiro Ito +69 M Sacrifice @David Palumbo +70 M Maddening Hex @Javier Charro +71 M Unholy Heat @Josh Hass 72 M Collected Company @Borja Pindado +73 M Noxious Revival @Javier Charro diff --git a/forge-gui/res/editions/Unknown Event Amsterdam 2024 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Amsterdam 2024 Playtest Cards.txt new file mode 100644 index 00000000000..7e874c78c45 --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Amsterdam 2024 Playtest Cards.txt @@ -0,0 +1,38 @@ +[metadata] +Code=UEAMS24 +Date=2024-06-28 +Name=Unknown Event Amsterdam 2024 Playtest Cards +Type=Funny + +[cards] +1 U Windmill Slam +2 R The Kami Knight +3 R The Inspector Inspector +4 R The Miniaturizer +5 R The Pleasant Taxer +6 R The Clever Magician +7 R The Magic Bandit +8 R The Juzam Master +9 R The Zassacre Zirl +10 R The Great Juggernaut +11 R The Disciple of Nissa +12 R The Massive Zatcatl +13 R The Ash Lizard +14 R The Egotistical Velociraptor +15 R The Joiner of Cats +16 R The Karst, Enchanted +17 R The Keeper of Kaldra +18 R The Keeper of the Yellow Hat +19 R The Knight of Commentary +20 R The Marvelous Scientist +21 R The Master of Cuisine +22 R The Trivia Mastermind +23 R The Wise Sable +24 U Bag of Stroopwafels +25 U Black Tulip +26 C Leisure Bicycle +27 U Famous Museum +28 R The Magic City, New + +[promo] +29 M The Horizon Seeker diff --git a/forge-gui/res/editions/Unknown Event Chicago 2024 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Chicago 2024 Playtest Cards.txt new file mode 100644 index 00000000000..980b05fcfc8 --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Chicago 2024 Playtest Cards.txt @@ -0,0 +1,65 @@ +[metadata] +Code=UECHI24 +Date=2024-02-23 +Name=Unknown Event Chicago 2024 Playtest Cards +Type=Funny + +[cards] +1 R Guild Pact +2 R The Asker of More Mana +3 R The Curve Keeper +4 U Identify the Culprit +5 C Illuminating Detective +6 R The Keeper of Favorite Cards +7 R The Knight of Weeks +8 U Windy City Elemental +9 R The Crab Queen +10 R Disguise Agent +11 C Educated Detective +12 U Elemental, My Dear +13 R The Fish Brewer +14 C Irrefutable Evidence +15 R The Rhystic Storyteller +16 R The Value Knight +17 U Bloodspatter Vampire +18 C Demon Detective +19 R The Disciple of Vess +20 U Halving Season +21 U Impressive Rat +22 R The Keeper of Dark Pacts +23 C Life at Stake +24 C Aggressive Detective +25 R The Crafter +26 R The Crimson Avenger +27 U Guess Who it Is! +28 R The Knight of Land Drops +29 U Ate-o'-Clock +30 R The Bear Force Pilot +31 C Investi-Gate +32 C Growing Detective +33 U Primetime Suspect +34 R The Roaring Toeclaws +35 R The Spike Cactus +36 M The Beleaguered Boxer +37 R The Dogronmaster +38 R The Duke of Midrange +39 R The Scholar of Seas +40 R The Sprinkler of Stardust +41 R The Water Maro +42 U Deep Dish Pizza +43 U Guilded Lotus +44 U Interrogation Robot +45 C Karlov's Crossbow +46 R The Rebellious Intelligence +47 C Simic Slaw +48 U Trash Panda +49 U That Which Was Compleated +50 U Urza's Hot Dog Stand + +[promo] +51 M The Collector + +[You Make The Card] +1 Trash Panda|UECHI24 +1 That Which Was Compleated|UECHI24 +1 Urza's Hot Dog Stand|UECHI24 \ No newline at end of file diff --git a/forge-gui/res/formats/Archived/Explorer/2024-08-27.txt b/forge-gui/res/formats/Archived/Explorer/2024-08-27.txt new file mode 100644 index 00000000000..04a72b0b1d3 --- /dev/null +++ b/forge-gui/res/formats/Archived/Explorer/2024-08-27.txt @@ -0,0 +1,8 @@ +[format] +Name:Explorer (2024-08-27) +Type:Archived +Subtype:Pioneer +Effective:2024-08-27 +Sets:KTK, XLN, RIX, DOM, M19, GRN, G18, RNA, WAR, M20, ELD, THB, IKO, M21, ZNR, KHM, STX, AFR, MID, VOW, NEO, SNC, EA1, DMU, BRO, EA2, ONE, MOM, MAT, EA3, WOE, LCI, MKM, OTJ, BIG, BLB +Banned:Amalia Benavides Aguirre; Bloodstained Mire; Expressive Iteration; Field of the Dead; Flooded Strand; Geological Appraiser; Karn, the Great Creator; Kethis, the Hidden Hand; Leyline of Abundance; Lurrus of the Dream-Den; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Sorin, Imperious Bloodlord; Teferi, Time Raveler; Tibalt's Trickery; Underworld Breach; Uro, Titan of Nature's Wrath; Veil of Summer; Wilderness Reclamation; Windswept Heath; Winota, Joiner of Forces; Wooded Foothills +Additional:Abandoned Sarcophagus; Abundant Maw; Accursed Horde; Accursed Witch; Adaptive Snapjaw; Adorned Pouncer; Advanced Stitchwing; Aerial Guide; Aerial Responder; Aeronaut Admiral; Aether Chaser; Aether Hub; Aether Inspector; Aether Meltdown; Aether Poisoner; Aether Swooper; Aether Theorist; Aether Tradewinds; Aetherborn Marauder; Aetherflux Reservoir; Aethersphere Harvester; Aetherstorm Roc; Aetherstream Leopard; Aethertorch Renegade; Aetherworks Marvel; Ahn-Crop Champion; Ahn-Crop Crasher; Aim High; Airdrop Aeronauts; Ajani Unyielding; Alchemist's Greeting; Alley Evasion; Alley Strangler; Alms of the Vein; Altar's Reap; Altered Ego; Always Watching; Ammit Eternal; Anafenza, Kin-Tree Spirit; Ancestral Statue; Ancient Crab; Angel of Invention; Angel of Sanctions; Angel of the God-Pharaoh; Angelic Edict; Angelic Purge; Anger of the Gods; Anguished Unmaking; Animation Module; Anointed Procession; Anointer Priest; Apothecary Geist; Appeal // Authority; Appetite for the Unnatural; Approach of the Second Sun; Arborback Stomper; Archangel Avacyn; Archfiend of Ifnir; Arlinn Kord; Armorcraft Judge; As Foretold; Assassin's Strike; Assault Formation; Assembled Alphas; Astral Cornucopia; Asylum Visitor; Atarka's Command; Attune with Aether; Audacious Infiltrator; Auger Spree; Aurelia, the Warleader; Authority of the Consuls; Avacyn's Judgment; Aven Initiate; Aven Mindcensor; Aven of Enduring Hope; Aven Wind Guide; Aviary Mechanic; Baleful Ammit; Ballista Charger; Baral's Expertise; Baral, Chief of Compliance; Barrage of Expendables; Barricade Breaker; Bastion Mastodon; Bathe in Dragonfire; Battering Krasis; Battlefield Scavenger; Bedlam Reveler; Belligerent Sliver; Beneath the Sands; Binding Mummy; Biting Rain; Bitterbow Sharpshooters; Black Cat; Blessed Alliance; Blessed Spirits; Blighted Bat; Blind Obedience; Blood Host; Blood Mist; Bloodbond Vampire; Bloodbriar; Bloodhall Priest; Bloodhunter Bat; Bloodlust Inciter; Bloodmad Vampire; Bloodrage Brawler; Blossoming Defense; Blur of Blades; Blur Sliver; Bogbrew Witch; Bomat Bazaar Barge; Bomat Courier; Bonded Construct; Bone Picker; Bone Saw; Bonescythe Sliver; Bontu the Glorified; Bontu's Last Reckoning; Bontu's Monument; Borderland Marauder; Borderland Minotaur; Boros Elite; Borrowed Grace; Borrowed Hostility; Borrowed Malevolence; Bound by Moonsilver; Brain in a Jar; Brain Maggot; Breaching Hippocamp; Bred for the Hunt; Briarbridge Patrol; Brisela, Voice of Nightmares; Bristling Hydra; Bruna, the Fading Light; Brushstrider; Brute Strength; Bubbling Cauldron; Built to Last; Built to Smash; Burn from Within; Burning-Fist Minotaur; Burning-Tree Emissary; Burnished Hart; By Force; Bygone Bishop; Byway Courier; Call the Bloodline; Canyon Slough; Carrier Thrall; Cartouche of Ambition; Cartouche of Knowledge; Cartouche of Solidarity; Cartouche of Strength; Cartouche of Zeal; Cascading Cataracts; Cast Out; Cataclysmic Gearhulk; Cathar's Companion; Cemetery Recruitment; Censor; Ceremonious Rejection; Certain Death; Champion of Rhonas; Champion of Wits; Chandra's Defeat; Chandra's Revolution; Chandra, Pyromaster; Chandra, Torch of Defiance; Chaos Maw; Charging Badger; Chief of the Foundry; Chittering Host; Choked Estuary; Cinder Elemental; Claim // Fame; Cloudblazer; Cogworker's Puzzleknot; Collateral Damage; Collected Company; Collective Brutality; Collective Defiance; Collective Effort; Combat Celebrant; Combustible Gearhulk; Commencement of Festivities; Commit // Memory; Compelling Argument; Compelling Deterrence; Compulsory Rest; Conduit of Storms; Confirm Suspicions; Confiscation Coup; Confront the Unknown; Consign // Oblivion; Consulate Skygate; Consulate Turret; Contraband Kingpin; Conviction; Coralhelm Guide; Corpse Hauler; Countervailing Winds; Countless Gears Renegade; Courageous Outrider; Crawling Sensation; Creeping Mold; Crested Sunmare; Crocanura; Crocodile of the Crossing; Crow of Dark Tidings; Cruel Reality; Crux of Fate; Crypt of the Eternals; Cryptbreaker; Cryptic Serpent; Cryptolith Fragment; Cryptolith Rite; Cultivator's Caravan; Curator of Mysteries; Curious Homunculus; Cut // Ribbons; Dance with Devils; Daredevil Dragster; Daring Demolition; Daring Sleuth; Dark Intimations; Dark Salvation; Dauntless Aven; Dauntless Cathar; Dauntless Onslaught; Dawn Gryff; Dawnfeather Eagle; Death Wind; Death's Approach; Deathcap Cultivator; Decimator of the Provinces; Declaration in Stone; Decoction Module; Deem Worthy; Defiant Greatmaw; Defiant Salvager; Demolition Stomper; Demon of Dark Schemes; Demonic Pact; Deny Existence; Depala, Pilot Exemplar; Deranged Whelp; Descend upon the Sinful; Desert Cerodon; Desert of the Fervent; Desert of the Glorified; Desert of the Indomitable; Desert of the Mindful; Desert of the True; Desert's Hold; Destined // Lead; Devils' Playground; Devilthorn Fox; Devouring Light; Die Young; Diffusion Sliver; Dinrova Horror; Diregraf Colossus; Disallow; Disposal Mummy; Dispossess; Dissenter's Deliverance; Distended Mindbender; Djeru's Renunciation; Djeru's Resolve; Docent of Perfection; Doom Blade; Doomfall; Douse in Gloom; Dovin Baan; Drag Under; Dragon Fodder; Dragon Hatchling; Dragon Mantle; Dragonloft Idol; Dragonlord's Servant; Dragonmaster Outcast; Drainpipe Vermin; Drake Haven; Drana, Liberator of Malakir; Dread Wanderer; Driven // Despair; Drogskol Shieldmate; Dromoka's Command; Drownyard Behemoth; Drownyard Explorers; Drunau Corpse Trawler; Dukhara Peafowl; Dune Beetle; Dusk // Dawn; Dusk Feaster; Duskwatch Recruiter; Dutiful Attendant; Dwynen's Elite; Dynavolt Tower; Eager Construct; Earthshaker Khenra; Eddytrail Hawk; Edifice of Authority; Elder Deep-Fiend; Eldritch Evolution; Electrostatic Pummeler; Elemental Uprising; Elusive Krasis; Elvish Visionary; Ember-Eye Wolf; Embraal Bruiser; Empyreal Voyager; Emrakul, the Promised End; Engineered Might; Enlarge; Enraged Giant; Epiphany at the Drownyard; Era of Innovation; Erdwal Illuminator; Essence Extraction; Essence Flux; Eternal of Harsh Truths; Eternal Scourge; Eternal Thirst; Ever After; Evolutionary Leap; Exemplar of Strength; Exultant Cultist; Eyeblight Assassin; Fabrication Module; Failure // Comply; Fairgrounds Warden; Faith of the Devoted; Faith Unbroken; Faithbearer Paladin; Falkenrath Gorger; Fan Bearer; Fanatic of Mogis; Farm // Market; Fatal Push; Fateful Showdown; Fen Hauler; Feral Prowler; Fervent Paincaster; Festering Mummy; Festering Newt; Fetid Pools; Fevered Visions; Fiend Binder; Fiery Temper; Filigree Familiar; Final Reward; Firebrand Archer; Fireforger's Puzzleknot; Flame Lash; Flameblade Adept; Flameblade Angel; Flames of the Firebrand; Fleeting Memories; Fleshbag Marauder; Floodwaters; Flurry of Horns; Fog; Fogwalker; Foreboding Ruins; Forge Devil; Forgotten Creation; Forsake the Worldly; Fortified Village; Fortify; Fortuitous Find; Foundry Hornet; Foundry Inspector; Foundry Screecher; Foundry Street Denizen; Fourth Bridge Prowler; Fragmentize; Fraying Sanity; Freejam Regent; Fretwork Colony; Frontline Rebel; Fumigate; Furious Reprisal; Furnace Whelp; Furyblade Vampire; Galvanic Bombardment; Game Trail; Gate to the Afterlife; Gatstaf Arsonists; Gavony Unhallowed; Gearseeker Serpent; Gearshift Ace; Geier Reach Bandit; Geier Reach Sanitarium; Geist of the Archives; Geralf's Masterpiece; Ghoulcaller's Accomplice; Gideon of the Trials; Gideon's Intervention; Gifted Aetherborn; Gilded Cerodon; Gisa and Geralf; Gisa's Bidding; Gisela, the Broken Blade; Glimmer of Genius; Glint; Glint-Nest Crane; Glint-Sleeve Artisan; Glint-Sleeve Siphoner; Glorious End; Glory-Bound Initiate; Glorybringer; Gnarlwood Dryad; Goblin Dark-Dwellers; Goblin Rally; Goblin Shortcutter; God-Pharaoh's Gift; Goldnight Castigator; Gonti, Lord of Luxury; Graf Harvest; Graf Mole; Graf Rats; Grapple with the Past; Greenbelt Rampager; Grim Flayer; Grind // Dust; Grisly Salvage; Grotesque Mutation; Groundskeeper; Gryff's Boon; Guardian of Pilgrims; Gust Walker; Hamlet Captain; Hanweir Battlements; Hanweir Garrison; Hanweir Militia Captain; Hanweir, the Writhing Township; Hapatra, Vizier of Poisons; Harmless Offering; Harnessed Lightning; Harsh Mentor; Harvest Hand; Hashep Oasis; Haunted Dead; Hazardous Conditions; Haze of Pollen; Hazoret the Fervent; Hazoret's Monument; Heart of Kiran; Heaven // Earth; Hedron Archive; Heir of Falkenrath; Hekma Sentinels; Herald of Anguish; Herald of the Fair; Heron's Grace Champion; Hidden Stockpile; Hieroglyphic Illumination; Highspire Artisan; Highspire Infusion; Hinterland Drake; Hinterland Logger; Hive Stirrings; Hollow One; Homing Lightning; Honored Crop-Captain; Hooded Brawler; Hope Against Hope; Hope of Ghirapur; Hope Tender; Hornet Queen; Horror of the Broken Lands; Hour of Devastation; Hour of Promise; Hour of Revelation; Howlpack Resurgence; Howlpack Wolf; Humble the Brute; Hungry Flames; Ice Over; Ifnir Deadlands; Illusionist's Stratagem; Imminent Doom; Impact Tremors; Impeccable Timing; Implement of Combustion; Implement of Examination; Implement of Malice; Imprisoned in the Moon; In Oketra's Name; Incendiary Flow; Incorrigible Youths; Indomitable Creativity; Indulgent Aristocrat; Ingenious Skaab; Initiate's Companion; Insatiable Gorgers; Insolent Neonate; Inspiring Call; Inspiring Statuary; Insult // Injury; Intrepid Provisioner; Invasive Surgery; Inventor's Apprentice; Inventor's Goggles; Inventors' Fair; Invigorated Rampage; Ipnu Rivulet; Ironclad Slayer; Irontread Crusher; Irrigated Farmland; Ishkanah, Grafwidow; Jace's Scrutiny; Jace, Unraveler of Secrets; Just the Wind; Kalastria Nightwatch; Kambal, Consul of Allocation; Kari Zev's Expertise; Kari Zev, Skyship Raider; Kefnet the Mindful; Kefnet's Monument; Key to the City; Khenra Charioteer; Khenra Eternal; Khenra Scrapper; Kindly Stranger; Kolaghan's Command; Kujar Seedsculptor; Laboratory Brute; Labyrinth Guardian; Languish; Lathnu Sailback; Launch Party; Lawless Broker; Lay Claim; Leaf Gilder; Leave // Chance; Leave in the Dust; Leeching Sliver; Lethal Sting; Lifecraft Cavalry; Lifecrafter's Bestiary; Lifecrafter's Gift; Lightning Axe; Lightning Diadem; Lightning Shrieker; Lightwalker; Liliana's Defeat; Liliana's Elite; Liliana's Mastery; Liliana's Reaver; Liliana, Death's Majesty; Liliana, the Last Hope; Live Fast; Lone Rider; Long Road Home; Longtusk Cub; Lord of the Accursed; Lost Legacy; Lunarch Mantle; Lupine Prototype; Mad Prophet; Magma Jet; Magma Spray; Magmaroth; Magmatic Chasm; Majestic Myriarch; Make Mischief; Make Obsolete; Malakir Cullblade; Malakir Familiar; Malfunction; Manaweft Sliver; Manglehorn; Manic Scribe; Marauding Boneslasher; Marionette Master; Markov Crusader; Master Trinketeer; Maulfist Revolutionary; Maulfist Squad; Maverick Thopterist; Maze's End; Merchant's Dockhand; Merciless Javelineer; Merciless Resolve; Mercurial Geists; Metallic Mimic; Metallic Rebuke; Metallurgic Summonings; Metalspinner's Puzzleknot; Metalwork Colossus; Miasmic Mummy; Midnight Oil; Midnight Scavengers; Mind's Dilation; Mindwrack Demon; Minister of Inquiries; Minotaur Skullcleaver; Minotaur Sureshot; Mirage Mirror; Mirrorwing Dragon; Mobile Garrison; Mockery of Nature; Monstrous Onslaught; Moonlight Hunt; Morkrut Necropod; Mournwillow; Mouth // Feed; Mugging; Murderer's Axe; Murmuring Phantasm; Naga Oracle; Naga Vitalist; Nahiri's Wrath; Nahiri, the Harbinger; Narnam Cobra; Narnam Renegade; Nature's Way; Nearheath Chaplain; Nebelgast Herald; Nef-Crop Entangler; Neglected Heirloom; Neheb, the Eternal; Neheb, the Worthy; Nest of Scarabs; Never // Return; New Perspectives; Nicol Bolas, God-Pharaoh; Night Market Aeronaut; Night Market Lookout; Nightmare; Nimble Innovator; Nimble Obstructionist; Nimble-Blade Khenra; Nimbus Swimmer; Nissa, Steward of Elements; Nissa, Vital Force; Noose Constrictor; Noosegraf Mob; Notion Thief; Noxious Gearhulk; Nyx-Fleece Ram; Nyx Weaver; Oashra Cultivator; Oasis Ritualist; Oath of Ajani; Obelisk Spider; Obsessive Skinner; Odric, Lunarch Marshal; Ogre Battledriver; Ogre Slumlord; Ojutai's Command; Ojutai's Summons; Oketra the True; Oketra's Attendant; Oketra's Avenger; Oketra's Monument; Olivia's Bloodsworn; Olivia's Dragoon; Olivia, Mobilized for War; Ominous Sphinx; Ongoing Investigation; Onward // Victory; Open Fire; Ornamental Courage; Ornery Kudu; Ornithopter; Outland Boar; Outnumber; Ovalchase Dragster; Overwhelming Splendor; Oviya Pashiri, Sage Lifecrafter; Pacification Array; Pack Guardian; Pack Rat; Padeem, Consul of Innovation; Panharmonicon; Paradox Engine; Paradoxical Outcome; Path of Bravery; Pathmaker Initiate; Patron of the Valiant; Peacewalker Colossus; Peel from Reality; Peema Aether-Seer; Peema Outrider; Perilous Vault; Permeating Mass; Phyrexian Revoker; Pia Nalaar; Pick the Brain; Pieces of the Puzzle; Pilgrim's Eye; Pitiless Vizier; Planar Bridge; Pore Over the Pages; Port Town; Possibility Storm; Pouncing Cheetah; Prakhata Pillar-Bug; Precise Strike; Predatory Sliver; Prepare // Fight; Prescient Chimera; Pride Sovereign; Primeval Bounty; Prized Amalgam; Propeller Pioneer; Protection of the Hekma; Prowling Serpopard; Pull from Tomorrow; Puncturing Blow; Puncturing Light; Pursue Glory; Putrefy; Pyre Hound; Quarry Hauler; Quicksmith Genius; Quicksmith Rebel; Rageblood Shaman; Rags // Riches; Raise Dead; Ramunap Excavator; Ramunap Ruins; Rashmi, Eternities Crafter; Ratchet Bomb; Rattlechains; Ravenous Bloodseeker; Ravenous Intruder; Razaketh, the Foulblooded; Reaper of Flight Moonsilver; Reason // Believe; Reckless Fireweaver; Reckless Racer; Reckless Scholar; Reduce // Rubble; Refurbish; Refuse // Cooperate; Regal Caracal; Relentless Dead; Renegade Map; Renegade Rallier; Renegade Tactics; Renegade Wheelsmith; Renewed Faith; Reservoir Walker; Resilient Khenra; Restoration Gearsmith; Restoration Specialist; Return to the Ranks; Reverse Engineer; Revoke Privileges; Revolutionary Rebuff; Rhonas the Indomitable; Rhonas's Monument; Rhonas's Stalwart; Riddle of Lightning; Ridgescale Tusker; Riparian Tiger; Rise from the Tides; Rise of the Dark Realms; Rishkar's Expertise; Rishkar, Peema Renegade; River Hoopoe; Rogue Refiner; Ruin Rat; Ruinous Gremlin; Rumbling Baloth; Runeclaw Bear; Runed Servitor; Rush of Adrenaline; Rush of Vitality; Ruthless Disposal; Ruthless Sniper; Sacred Cat; Sage of Ancient Lore; Sage of Shaila's Claim; Saheeli Rai; Salivating Gremlins; Samut, the Tested; Samut, Voice of Dissent; Sand Strangler; Sandsteppe Outcast; Sandwurm Convergence; Sanguine Bond; Sarkhan's Rage; Scarab Feast; Scattered Groves; Scavenger Grounds; Scour the Laboratory; Scourge Wolf; Scrap Trawler; Scrapheap Scrounger; Scrapper Champion; Seasons Past; Second Harvest; Seeker of Insight; Seer of the Last Tomorrow; Seismic Elemental; Seismic Rupture; Select for Inspection; Self-Assembler; Selfless Cathar; Selfless Spirit; Sengir Vampire; Sentinel Sliver; Servant of the Conduit; Servant of the Scale; Servo Exhibition; Servo Schematic; Shadow of the Grave; Shadowstorm Vizier; Shambleshark; Shambling Goblin; Shard of Broken Glass; Shed Weakness; Shefet Dunes; Shefet Monitor; Sheltered Thicket; Shielded Aether Thief; Shimmerscale Drake; Shipwreck Moray; Shiv's Embrace; Shreds of Sanity; Shrewd Negotiation; Shrill Howler; Sidewinder Naga; Siege Dragon; Siege Modification; Sifter Wurm; Sigarda's Aid; Sigarda, Heron's Grace; Sigardian Priest; Sigil of the Empty Throne; Sigil of Valor; Sigiled Starfish; Sign in Blood; Silumgar's Command; Sin Prodder; Sixth Sense; Sky Skiff; Skyship Plunderer; Skyship Stalker; Skysovereign, Consul Flagship; Skywhaler's Shot; Slate Street Ruffian; Slayer's Plate; Slither Blade; Sliver Hive; Sly Requisitioner; Smuggler's Copter; Solemnity; Solitary Camel; Somberwald Stag; Sorin, Grim Nemesis; Soul of the Harvest; Soul Separator; Soul-Scar Mage; Soulblade Djinn; Soulstinger; Spectral Shepherd; Speedway Fanatic; Spell Queller; Spellweaver Eternal; Sphinx's Revelation; Spire of Industry; Spire Patrol; Spireside Infiltrator; Spirit of the Hunt; Splendid Agony; Spontaneous Mutation; Sporemound; Spring // Mind; Springleaf Drum; Sram's Expertise; Sram, Senior Edificer; Stab Wound; Start // Finish; Startled Awake; Steadfast Cathar; Steelform Sliver; Stensia Masquerade; Steward of Solidarity; Stinging Shot; Stitcher's Graft; Stitchwing Skaab; Stormfront Pegasus; Strength of Arms; Striking Sliver; Striped Riverwinder; Stromkirk Condemned; Stromkirk Occultist; Struggle // Survive; Subjugator Angel; Summary Dismissal; Sunscorched Desert; Sunscourge Champion; Sunset Pyramid; Supernatural Stamina; Supply Caravan; Supreme Will; Swan Song; Sweatworks Brawler; Sweep Away; Sweltering Suns; Swift Spinner; Synchronized Strike; Tah-Crop Elite; Tajuru Pathwarden; Take Inventory; Tamiyo's Journal; Tamiyo, Field Researcher; Tandem Tactics; Tattered Haunter; Temmet, Vizier of Naktamun; Terrarion; Tezzeret the Schemer; Tezzeret's Ambition; Tezzeret's Touch; Thalia's Lancers; Thalia's Lieutenant; Thalia, Heretic Cathar; The Gitrog Monster; The Locust God; The Scarab God; The Scorpion God; Thing in the Ice; Thopter Arrest; Thorned Moloch; Those Who Serve; Thoughtseize; Thraben Foulbloods; Thraben Inspector; Thraben Standard Bearer; Thresher Lizard; Thriving Rhino; Thriving Turtle; Throne of the God-Pharaoh; Thunderbreak Regent; Tightening Coils; Toolcraft Exemplar; Topplegeist; Torch Fiend; Torment of Hailfire; Torment of Scarabs; Torrential Gearhulk; Town Gossipmonger; Traverse the Ulvenwald; Treasure Keeper; Tree of Perdition; Trespasser's Curse; Trial of Ambition; Trial of Knowledge; Trial of Solidarity; Trial of Strength; Trial of Zeal; Triskaidekaphobia; Trophy Mage; True-Faith Censer; Typhoid Rats; Ulamog, the Ceaseless Hunger; Ulrich of the Krallenhorde; Ulrich's Kindred; Ulvenwald Captive; Ulvenwald Hydra; Ulvenwald Mysteries; Unbridled Growth; Unburden; Unconventional Tactics; Underhanded Designs; Unesh, Criosphinx Sovereign; Universal Solvent; Unlicensed Disintegration; Unquenchable Thirst; Untethered Express; Vampiric Rites; Vengeful Rebel; Verdurous Gearhulk; Vessel of Nascency; Veteran Cathar; Veteran Motorist; Vile Manifestation; Village Messenger; Virulent Plague; Visionary Augmenter; Vizier of Deferment; Vizier of Many Faces; Vizier of Remedies; Vizier of the Anointed; Vizier of the Menagerie; Vizier of Tumbling Sands; Voldaren Pariah; Voltaic Brawler; Voyage's End; Wailing Ghoul; Wall of Forgotten Pharaohs; Wander in Death; Warfire Javelineer; Wasp of the Bitter End; Waste Not; Wasteland Scorpion; Watchers of the Dead; Watchful Naga; Wayward Servant; Weaponcraft Enthusiast; Weaver of Lightning; Weirded Vampire; Weirding Wood; Weldfast Engineer; Weldfast Monitor; Weldfast Wingsmith; Welding Sparks; Westvale Abbey; Wharf Infiltrator; Whelming Wave; Whir of Invention; Whirler Rogue; Whirler Virtuoso; Whirlermaker; Wight of Precinct Six; Wild Wanderer; Wild-Field Scarecrow; Wildest Dreams; Wind-Kin Raiders; Winding Constrictor; Winds of Rebuke; Winged Shepherd; Wispweaver Angel; Witch's Familiar; Woodborn Behemoth; Woodweaver's Puzzleknot; Workshop Assistant; Wretched Gryff; Yahenni's Expertise; Yahenni, Undying Partisan; Young Pyromancer; Zada, Hedron Grinder; Zealot of the God-Pharaoh; Zendikar's Roil; Abrupt Decay; Back for More; Bedevil; Buried in the Garden; Clear Shot; Crackle with Power; Decisive Denial; Detention Sphere; Electrodominance; Endless Detour; Essence Capture; Fierce Retribution; Fling; Heartless Pillage; Humiliate; Hypothesizzle; Ionize; Leyline Binding; Murder; Outlaws' Merriment; Primal Might; Ride Down; Savage Smash; Siphon Insight; Skewer the Critics; Skullcrack; Tyrant's Scorn; Unlicensed Hearse; Vanishing Verse; Villainous Wealth; Void Rend diff --git a/forge-gui/res/formats/Archived/Legacy/2024-08-26.txt b/forge-gui/res/formats/Archived/Legacy/2024-08-26.txt new file mode 100644 index 00000000000..3890a1d501f --- /dev/null +++ b/forge-gui/res/formats/Archived/Legacy/2024-08-26.txt @@ -0,0 +1,8 @@ +[format] +Name:Legacy (2024-08-26) +Type:Archived +Subtype:Legacy +Effective:2024-08-26 +Sets:LEA, LEB, 2ED, ARN, ATQ, 3ED, LEG, DRC94, DRK, PHPR, FEM, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, POR, WTH, TMP, STH, EXO, PO2, USG, ATH, ULG, 6ED, UDS, S99, PTK, MMQ, BRB, NMS, S00, PCY, BTD, INV, PLS, 7ED, APC, ODY, DKM, TOR, JUD, ONS, LGN, SCG, 8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, MED, LRW, DD1, MOR, SHM, EVE, DRB, ME2, ALA, DD2, CFX, DDC, ARB, M10, TD0, FVE, HOP, ME3, ZEN, DDD, PDS, WWK, DDE, ROE, DPA, ARC, M11, FVR, DDF, SOM, TD1, PD2, ME4, MBS, DDG, NPH, TD2, COM, M12, FVL, DDH, ISD, PD3, DKA, DDI, AVR, PC2, M13, V12, DDJ, RTR, CM1, GTC, DDK, DGM, MMA, M14, V13, DDL, THS, C13, BNG, DDM, JOU, MD1, CNS, VMA, M15, V14, DDN, KTK, C14, DVD, EVG, GVL, JVC, FRF, UGF, DDO, DTK, TPR, MM2, ORI, V15, DDP, BFZ, EXP, C15, PZ1, OGW, DDQ, SOI, W16, EMA, EMN, V16, CN2, DDR, KLD, MPS_KLD, C16, PZ2, PCA, AER, MM3, DDS, AKH, MPS_AKH, W17, CMA, E01, HOU, C17, XLN, DDT, IMA, V17, E02, RIX, A25, DDU, DOM, CM2, BBD, SS1, GS1, M19, C18, GRN, MPS_GRN, GK1, G18, GNT, UMA, RNA, MPS_RNA, GK2, WAR, MPS_WAR, MH1, SS2, M20, C19, ELD, MB1, GN2, THB, IKO, C20, SS3, M21, JMP, 2XM, ZNR, ZNE, ZNC, CMR, CC1, KHM, KHC, TSR, STX, STA, C21, MH2, H1R, AFR, AFC, MID, MIC, Q06, VOW, VOC, DBL, CC2, NEO, NEC, SNC, NCC, CLB, 2X2, DMU, DMC, 40K, UNF, GN3, BRO, BRC, BRR, BOT, J22, SCD, DMR, ONE, ONC, MOM, MOC, MUL, MAT, LTR, LTC, CMM, WOE, WOC, WOT, WHO, LCI, LCC, REX, RVR, MKM, MKC, CLU, PIP, OTJ, OTC, OTP, BIG, MH3, M3C, H2R, ACR, BLB, BLC, MB2 +Banned:"Lifetime" Pass Holder; _____ _____ _____ Trespasser; _____ _____ Rocketship; _____ Balls of Fire; _____ Bird Gets the Worm; _____ Goblin; _____-o-saurus; Adriana's Valor; Advantageous Proclamation; Aerialephant; Ambassador Blorpityblorpboop; Amulet of Quoz; Ancestral Recall; Arcum's Astrolabe; Assemble the Rank and Vile; Baaallerina; Backup Plan; Balance; Bazaar of Baghdad; Bioluminary; Black Lotus; Brago's Favor; Bronze Tablet; Carnival Carnivore; Channel; Chaos Orb; Chicken Troupe; Clandestine Chameleon; Cleanse; Coming Attraction; Command Performance; Complaints Clerk; Contract from Below; Crusade; Darkpact; Deadbeat Attendant; Deathrite Shaman; Dee Kay, Finder of the Lost; Demonic Attorney; Demonic Consultation; Demonic Tutor; Dig Through Time; Discourtesy Clerk; Done for the Day; Double Stroke; Draconian Gate-Bot; Dreadhorde Arcanist; Earthcraft; Echoing Boon; Emissary's Ploy; Expressive Iteration; Falling Star; Fastbond; Fight the _____ Fight; Finishing Move; Flash; Frantic Search; Gitaxian Probe; Glitterflitter; Goblin Recruiter; Grief; Gush; Hermit Druid; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Imperial Seal; Imprison; Incendiary Dissent; Invoke Prejudice; Iterative Analysis; Jeweled Bird; Jihad; Last Voyage of the _____; Library of Alexandria; Line Cutter; Lineprancers; Lurrus of the Dream-Den; Make a _____ Splash; Mana Crypt; Mana Drain; Mana Vault; Memory Jar; Mental Misstep; Mind Twist; Minotaur de Force; Mishra's Workshop; Monitor Monitor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Muzzio's Preparations; Myra the Magnificent; Mystical Tutor; Natural Unity; Necropotence; Oath of Druids; Oko, Thief of Crowns; Park Bleater; Petting Zookeeper; Pin Collection; Power Play; Pradesh Gypsies; Prize Wall; Proficient Pyrodancer; Quick Fixer; Rad Rascal; Ragavan, Nimble Pilferer; Rebirth; Ride Guide; Robo-Piñata; Roxi, Publicist to the Stars; Scampire; Seasoned Buttoneer; Secret Summoning; Secrets of Paradise; Sensei's Divining Top; Sentinel Dispatch; Shahrazad; Skullclamp; Sol Ring; Soul Swindler; Sovereign's Realm; Spinnerette, Arachnobat; Squirrel Squatters; Step Right Up; Stiltstrider; Stone-Throwing Devils; Strip Mine; Summoner's Bond; Survival of the Fittest; Sword-Swallowing Seraph; Tempest Efreet; The Most Dangerous Gamer; Ticketomaton; Time Vault; Time Walk; Timetwister; Timmerian Fiends; Tinker; Tolarian Academy; Treasure Cruise; Tusk and Whiskers; Underworld Breach; Unexpected Potential; Vampiric Tutor; Weight Advantage; Wheel of Fortune; White Plume Adventurer; Wicker Picker; Windfall; Wizards of the _____; Wolf in _____ Clothing; Worldknit; Wrenn and Six; Yawgmoth's Bargain; Yawgmoth's Will; Zirda, the Dawnwaker +Additional:Aisha of Sparks and Smoke; Arden Angel; Arvinox, the Mind Flail; Baldin, Century Herdmaster; Bjorna, Nightfall Alchemist; Blanka, Ferocious Friend; Cecily, Haunted Mage; Chief Jim Hopper; Chun-Li, Countless Kicks; Daryl, Hunter of Walkers; Dhalsim, Pliable Pacifist; Doric, Nature's Warden; Dustin, Gadget Genius; E. Honda, Sumo Champion; Edgin, Larcenous Lutenist; Eleven, the Mage; Elmar, Ulvenwald Informant; Enkira, Hostile Scavenger; Forge, Neverwinter Charlatan; Gisa's Favorite Shovel; Glenn, the Voice of Calm; Gregor, Shrewd Magistrate; Greymond, Avacyn's Stalwart; Guile, Sonic Soldier; Hansk, Slayer Zealot; Hargilde, Kindly Runechanter; Havengul Laboratory; Hawkins National Laboratory; Holga, Relentless Rager; Immard, the Stormcleaver; Ken, Burning Brawler; Lara Croft, Tomb Raider; Lucas, the Sharpshooter; Lucille; Maarika, Brutal Gladiator; Malik, Grim Manipulator; Max, the Daredevil; Michonne, Ruthless Survivor; Mike, the Dungeon Master; Mind Flayer, the Shadow; Negan, the Cold-Blooded; Othelm, Sigardian Outcast; Rick, Steadfast Leader; Rose Noble; Ryu, World Warrior; Simon, Wild Magic Sorcerer; Sophina, Spearsage Deserter; Tadeas, Juniper Ascendant; The Celestial Toymaker; The Fifteenth Doctor; The Fourteenth Doctor; The Howling Abomination; Themberchaud; The Meep; Vikya, Scorching Stalwart; Wernog, Rider's Chaplain; Will the Wise; Xenk, Paladin Unbroken; Zangief, the Red Cyclone; Zethi, Arcane Blademaster diff --git a/forge-gui/res/formats/Archived/Modern/2024-08-26.txt b/forge-gui/res/formats/Archived/Modern/2024-08-26.txt new file mode 100644 index 00000000000..4e8ae3a638c --- /dev/null +++ b/forge-gui/res/formats/Archived/Modern/2024-08-26.txt @@ -0,0 +1,7 @@ +[format] +Name:Modern (2024-08-26) +Type:Archived +Subtype:Modern +Effective:2024-08-26 +Sets:8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, LRW, MOR, SHM, EVE, ALA, CFX, ARB, M10, ZEN, WWK, ROE, DPA, M11, SOM, MBS, NPH, M12, ISD, DKA, AVR, M13, RTR, GTC, DGM, MMA, M14, THS, BNG, JOU, MD1, M15, KTK, FRF, DTK, MM2, ORI, BFZ, OGW, SOI, W16, EMN, KLD, AER, MM3, W17, AKH, HOU, XLN, RIX, DOM, M19, GRN, GK1, G18, RNA, GK2, WAR, MH1, M20, ELD, THB, IKO, M21, ZNR, KHM, STX, MH2, AFR, MID, VOW, DBL, NEO, SNC, DMU, BRO, ONE, MOM, MAT, LTR, WOE, LCI, MKM, OTJ, BIG, MH3, ACR, BLB +Banned:Ancient Den; Arcum's Astrolabe; Birthing Pod; Blazing Shoal; Bridge from Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Faithless Looting; Field of the Dead; Fury; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Grief; Hogaak, Arisen Necropolis; Hypergenesis; Krark-Clan Ironworks; Lurrus of the Dream-Den; Mental Misstep; Mox Opal; Mycosynth Lattice; Mystic Sanctuary; Nadu, Winged Wisdom; Oko, Thief of Crowns; Once Upon a Time; Ponder; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Simian Spirit Guide; Skullclamp; Splinter Twin; Summer Bloom; Tibalt's Trickery; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Up the Beanstalk; Uro, Titan of Nature's Wrath; Vault of Whispers; Violent Outburst; Yorion, Sky Nomad diff --git a/forge-gui/res/formats/Archived/Pioneer/2024-08-26.txt b/forge-gui/res/formats/Archived/Pioneer/2024-08-26.txt new file mode 100644 index 00000000000..49789667306 --- /dev/null +++ b/forge-gui/res/formats/Archived/Pioneer/2024-08-26.txt @@ -0,0 +1,7 @@ +[format] +Name:Pioneer (2024-08-26) +Type:Archived +Subtype:Pioneer +Effective:2024-08-26 +Sets:RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, ORI, BFZ, OGW, SOI, W16, EMN, KLD, AER, W17, AKH, HOU, XLN, RIX, DOM, M19, GRN, G18, RNA, WAR, M20, ELD, THB, IKO, M21, ZNR, KHM, STX, AFR, MID, Q06, VOW, DBL, NEO, SNC, DMU, BRO, ONE, MOM, MAT, WOE, LCI, MKM, OTJ, BIG, BLB +Banned:Amalia Benavides Aguirre; Balustrade Spy; Bloodstained Mire; Expressive Iteration; Felidar Guardian; Field of the Dead; Flooded Strand; Geological Appraiser; Inverter of Truth; Karn, the Great Creator; Kethis, the Hidden Hand; Leyline of Abundance; Lurrus of the Dream-Den; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Sorin, Imperious Bloodlord; Teferi, Time Raveler; Undercity Informer; Underworld Breach; Uro, Titan of Nature's Wrath; Veil of Summer; Walking Ballista; Wilderness Reclamation; Windswept Heath; Winota, Joiner of Forces; Wooded Foothills diff --git a/forge-gui/res/formats/Archived/Vintage/2024-08-26.txt b/forge-gui/res/formats/Archived/Vintage/2024-08-26.txt new file mode 100644 index 00000000000..71295502936 --- /dev/null +++ b/forge-gui/res/formats/Archived/Vintage/2024-08-26.txt @@ -0,0 +1,9 @@ +[format] +Name:Vintage (2024-08-26) +Type:Archived +Subtype:Vintage +Effective:2024-08-26 +Sets:LEA, LEB, 2ED, ARN, ATQ, 3ED, LEG, DRC94, DRK, PHPR, FEM, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, POR, WTH, TMP, STH, EXO, PO2, USG, ATH, ULG, 6ED, UDS, S99, PTK, MMQ, BRB, NMS, S00, PCY, BTD, INV, PLS, 7ED, APC, ODY, DKM, TOR, JUD, ONS, LGN, SCG, 8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, MED, LRW, DD1, MOR, SHM, EVE, DRB, ME2, ALA, DD2, CFX, DDC, ARB, M10, TD0, FVE, HOP, ME3, ZEN, DDD, PDS, WWK, DDE, ROE, DPA, ARC, M11, FVR, DDF, SOM, TD1, PD2, ME4, MBS, DDG, NPH, TD2, COM, M12, FVL, DDH, ISD, PD3, DKA, DDI, AVR, PC2, M13, V12, DDJ, RTR, CM1, GTC, DDK, DGM, MMA, M14, V13, DDL, THS, C13, BNG, DDM, JOU, MD1, CNS, VMA, M15, V14, DDN, KTK, C14, DVD, EVG, GVL, JVC, FRF, UGF, DDO, DTK, TPR, MM2, ORI, V15, DDP, BFZ, EXP, C15, PZ1, OGW, DDQ, SOI, W16, EMA, EMN, V16, CN2, DDR, KLD, MPS_KLD, C16, PZ2, PCA, AER, MM3, DDS, AKH, MPS_AKH, W17, CMA, E01, HOU, C17, XLN, DDT, IMA, V17, E02, RIX, A25, DDU, DOM, CM2, BBD, SS1, GS1, M19, C18, GRN, MPS_GRN, GK1, G18, GNT, UMA, RNA, MPS_RNA, GK2, WAR, MPS_WAR, MH1, SS2, M20, C19, ELD, MB1, GN2, THB, IKO, C20, SS3, M21, JMP, 2XM, ZNR, ZNE, ZNC, CMR, CC1, KHM, KHC, TSR, STX, STA, C21, MH2, H1R, AFR, AFC, MID, MIC, Q06, VOW, VOC, DBL, CC2, NEO, NEC, SNC, NCC, CLB, 2X2, DMU, DMC, 40K, UNF, GN3, BRO, BRC, BRR, BOT, J22, SCD, DMR, ONE, ONC, MOM, MOC, MUL, MAT, LTR, LTC, CMM, WOE, WOC, WOT, WHO, LCI, LCC, REX, RVR, MKM, MKC, CLU, PIP, OTJ, OTC, OTP, BIG, MH3, M3C, H2R, ACR, BLB, BLC, MB2 +Restricted:Ancestral Recall; Balance; Black Lotus; Brainstorm; Chalice of the Void; Channel; Demonic Consultation; Demonic Tutor; Dig Through Time; Flash; Gitaxian Probe; Golgari Grave-Troll; Gush; Imperial Seal; Karn, the Great Creator; Library of Alexandria; Lion's Eye Diamond; Lodestone Golem; Lotus Petal; Mana Crypt; Mana Vault; Memory Jar; Mental Misstep; Merchant Scroll; Mind's Desire; Monastery Mentor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystic Forge; Mystical Tutor; Narset, Parter of Veils; Necropotence; Sol Ring; Strip Mine; Thorn of Amethyst; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Trinisphere; Urza's Saga; Vampiric Tutor; Vexing Bauble; Wheel of Fortune; Windfall; Yawgmoth's Will +Banned:"Lifetime" Pass Holder; _____ _____ _____ Trespasser; _____ _____ Rocketship; _____ Balls of Fire; _____ Bird Gets the Worm; _____ Goblin; _____-o-saurus; Adriana's Valor; Advantageous Proclamation; Aerialephant; Ambassador Blorpityblorpboop; Amulet of Quoz; Assemble the Rank and Vile; Baaallerina; Backup Plan; Bioluminary; Brago's Favor; Bronze Tablet; Carnival Carnivore; Chaos Orb; Chicken Troupe; Clandestine Chameleon; Cleanse; Coming Attraction; Command Performance; Complaints Clerk; Contract from Below; Crusade; Darkpact; Deadbeat Attendant; Dee Kay, Finder of the Lost; Demonic Attorney; Discourtesy Clerk; Done for the Day; Double Stroke; Draconian Gate-Bot; Echoing Boon; Emissary's Ploy; Falling Star; Fight the _____ Fight; Finishing Move; Glitterflitter; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Imprison; Incendiary Dissent; Invoke Prejudice; Iterative Analysis; Jeweled Bird; Jihad; Last Voyage of the _____; Line Cutter; Lineprancers; Make a _____ Splash; Minotaur de Force; Monitor Monitor; Muzzio's Preparations; Myra the Magnificent; Natural Unity; Park Bleater; Petting Zookeeper; Pin Collection; Power Play; Pradesh Gypsies; Prize Wall; Proficient Pyrodancer; Quick Fixer; Rad Rascal; Rebirth; Ride Guide; Robo-Piñata; Roxi, Publicist to the Stars; Scampire; Seasoned Buttoneer; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Shahrazad; Soul Swindler; Sovereign's Realm; Spinnerette, Arachnobat; Squirrel Squatters; Step Right Up; Stiltstrider; Stone-Throwing Devils; Summoner's Bond; Sword-Swallowing Seraph; Tempest Efreet; The Most Dangerous Gamer; Ticketomaton; Timmerian Fiends; Tusk and Whiskers; Unexpected Potential; Weight Advantage; Wicker Picker; Wizards of the _____; Wolf in _____ Clothing; Worldknit +Additional:Aisha of Sparks and Smoke; Arden Angel; Arvinox, the Mind Flail; Baldin, Century Herdmaster; Bjorna, Nightfall Alchemist; Blanka, Ferocious Friend; Cecily, Haunted Mage; Chief Jim Hopper; Chun-Li, Countless Kicks; Daryl, Hunter of Walkers; Dhalsim, Pliable Pacifist; Doric, Nature's Warden; Dustin, Gadget Genius; E. Honda, Sumo Champion; Edgin, Larcenous Lutenist; Eleven, the Mage; Elmar, Ulvenwald Informant; Enkira, Hostile Scavenger; Forge, Neverwinter Charlatan; Gisa's Favorite Shovel; Glenn, the Voice of Calm; Gregor, Shrewd Magistrate; Greymond, Avacyn's Stalwart; Guile, Sonic Soldier; Hansk, Slayer Zealot; Hargilde, Kindly Runechanter; Havengul Laboratory; Hawkins National Laboratory; Holga, Relentless Rager; Immard, the Stormcleaver; Ken, Burning Brawler; Lara Croft, Tomb Raider; Lucas, the Sharpshooter; Lucille; Maarika, Brutal Gladiator; Malik, Grim Manipulator; Max, the Daredevil; Michonne, Ruthless Survivor; Mike, the Dungeon Master; Mind Flayer, the Shadow; Negan, the Cold-Blooded; Othelm, Sigardian Outcast; Rick, Steadfast Leader; Rose Noble; Ryu, World Warrior; Simon, Wild Magic Sorcerer; Sophina, Spearsage Deserter; Tadeas, Juniper Ascendant; The Celestial Toymaker; The Fifteenth Doctor; The Fourteenth Doctor; The Howling Abomination; Themberchaud; The Meep; Vikya, Scorching Stalwart; Wernog, Rider's Chaplain; Will the Wise; Xenk, Paladin Unbroken; Zangief, the Red Cyclone; Zethi, Arcane Blademaster diff --git a/forge-gui/res/formats/Sanctioned/Legacy.txt b/forge-gui/res/formats/Sanctioned/Legacy.txt index 92f539a3939..ee3e855f997 100644 --- a/forge-gui/res/formats/Sanctioned/Legacy.txt +++ b/forge-gui/res/formats/Sanctioned/Legacy.txt @@ -4,4 +4,4 @@ Order:105 Subtype:Legacy Type:Sanctioned Sets:LEA, LEB, 2ED, ARN, ATQ, 3ED, LEG, DRC94, DRK, PHPR, FEM, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, POR, WTH, TMP, STH, EXO, PO2, USG, ATH, ULG, 6ED, UDS, S99, PTK, MMQ, BRB, NMS, S00, PCY, BTD, INV, PLS, 7ED, APC, ODY, DKM, TOR, JUD, ONS, LGN, SCG, 8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, MED, LRW, DD1, MOR, SHM, EVE, DRB, ME2, ALA, DD2, CFX, DDC, ARB, M10, TD0, FVE, HOP, ME3, ZEN, DDD, PDS, WWK, DDE, ROE, DPA, ARC, M11, FVR, DDF, SOM, TD1, PD2, ME4, MBS, DDG, NPH, TD2, COM, M12, FVL, DDH, ISD, PD3, DKA, DDI, AVR, PC2, M13, V12, DDJ, RTR, CM1, GTC, DDK, DGM, MMA, M14, V13, DDL, THS, C13, BNG, DDM, JOU, MD1, CNS, VMA, M15, V14, DDN, KTK, C14, DVD, EVG, GVL, JVC, FRF, UGF, DDO, DTK, TPR, MM2, ORI, V15, DDP, BFZ, EXP, C15, PZ1, OGW, DDQ, SOI, W16, EMA, EMN, V16, CN2, DDR, KLD, MPS_KLD, C16, PZ2, PCA, AER, MM3, DDS, AKH, MPS_AKH, W17, CMA, E01, HOU, C17, XLN, DDT, IMA, V17, E02, RIX, A25, DDU, DOM, CM2, BBD, SS1, GS1, M19, C18, GRN, MPS_GRN, GK1, G18, GNT, UMA, RNA, MPS_RNA, GK2, WAR, MPS_WAR, MH1, SS2, M20, C19, ELD, MB1, GN2, SLD, THB, IKO, C20, SS3, M21, JMP, 2XM, ZNR, ZNE, ZNC, CMR, CC1, KHM, KHC, TSR, STX, STA, C21, MH2, H1R, AFR, AFC, MID, MIC, Q06, VOW, VOC, DBL, CC2, NEO, NEC, SNC, NCC, SLX, CLB, 2X2, DMU, DMC, 40K, UNF, GN3, BRO, BRC, BRR, BOT, J22, SCD, DMR, ONE, ONC, MOM, MOC, MUL, MAT, LTR, LTC, CMM, WOE, WOC, WOT, WHO, LCI, LCC, REX, SPG, RVR, MKM, MKC, CLU, PIP, OTJ, OTC, OTP, BIG, MH3, M3C, H2R, ACR, BLB, BLC, MB2 -Banned:"Lifetime" Pass Holder; _____ _____ _____ Trespasser; _____ _____ Rocketship; _____ Balls of Fire; _____ Bird Gets the Worm; _____ Goblin; _____-o-saurus; Adriana's Valor; Advantageous Proclamation; Aerialephant; Ambassador Blorpityblorpboop; Amulet of Quoz; Ancestral Recall; Arcum's Astrolabe; Assemble the Rank and Vile; Baaallerina; Backup Plan; Balance; Bazaar of Baghdad; Bioluminary; Black Lotus; Brago's Favor; Bronze Tablet; Carnival Carnivore; Channel; Chaos Orb; Chicken Troupe; Clandestine Chameleon; Cleanse; Coming Attraction; Command Performance; Complaints Clerk; Contract from Below; Crusade; Darkpact; Deadbeat Attendant; Deathrite Shaman; Dee Kay, Finder of the Lost; Demonic Attorney; Demonic Consultation; Demonic Tutor; Dig Through Time; Discourtesy Clerk; Done for the Day; Double Stroke; Draconian Gate-Bot; Dreadhorde Arcanist; Earthcraft; Echoing Boon; Emissary's Ploy; Expressive Iteration; Falling Star; Fastbond; Fight the _____ Fight; Finishing Move; Flash; Frantic Search; Gitaxian Probe; Glitterflitter; Goblin Recruiter; Gush; Hermit Druid; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Imperial Seal; Imprison; Incendiary Dissent; Invoke Prejudice; Iterative Analysis; Jeweled Bird; Jihad; Last Voyage of the _____; Library of Alexandria; Line Cutter; Lineprancers; Lurrus of the Dream-Den; Make a _____ Splash; Mana Crypt; Mana Drain; Mana Vault; Memory Jar; Mental Misstep; Mind Twist; Minotaur de Force; Mishra's Workshop; Monitor Monitor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Muzzio's Preparations; Myra the Magnificent; Mystical Tutor; Natural Unity; Necropotence; Oath of Druids; Oko, Thief of Crowns; Park Bleater; Petting Zookeeper; Pin Collection; Power Play; Pradesh Gypsies; Prize Wall; Proficient Pyrodancer; Quick Fixer; Rad Rascal; Ragavan, Nimble Pilferer; Rebirth; Ride Guide; Robo-Piñata; Roxi, Publicist to the Stars; Scampire; Seasoned Buttoneer; Secret Summoning; Secrets of Paradise; Sensei's Divining Top; Sentinel Dispatch; Shahrazad; Skullclamp; Sol Ring; Soul Swindler; Sovereign's Realm; Spinnerette, Arachnobat; Squirrel Squatters; Step Right Up; Stiltstrider; Stone-Throwing Devils; Strip Mine; Summoner's Bond; Survival of the Fittest; Sword-Swallowing Seraph; Tempest Efreet; The Most Dangerous Gamer; Ticketomaton; Time Vault; Time Walk; Timetwister; Timmerian Fiends; Tinker; Tolarian Academy; Treasure Cruise; Tusk and Whiskers; Underworld Breach; Unexpected Potential; Vampiric Tutor; Weight Advantage; Wheel of Fortune; White Plume Adventurer; Wicker Picker; Windfall; Wizards of the _____; Wolf in _____ Clothing; Worldknit; Wrenn and Six; Yawgmoth's Bargain; Yawgmoth's Will; Zirda, the Dawnwaker +Banned:"Lifetime" Pass Holder; _____ _____ _____ Trespasser; _____ _____ Rocketship; _____ Balls of Fire; _____ Bird Gets the Worm; _____ Goblin; _____-o-saurus; Adriana's Valor; Advantageous Proclamation; Aerialephant; Ambassador Blorpityblorpboop; Amulet of Quoz; Ancestral Recall; Arcum's Astrolabe; Assemble the Rank and Vile; Baaallerina; Backup Plan; Balance; Bazaar of Baghdad; Bioluminary; Black Lotus; Brago's Favor; Bronze Tablet; Carnival Carnivore; Channel; Chaos Orb; Chicken Troupe; Clandestine Chameleon; Cleanse; Coming Attraction; Command Performance; Complaints Clerk; Contract from Below; Crusade; Darkpact; Deadbeat Attendant; Deathrite Shaman; Dee Kay, Finder of the Lost; Demonic Attorney; Demonic Consultation; Demonic Tutor; Dig Through Time; Discourtesy Clerk; Done for the Day; Double Stroke; Draconian Gate-Bot; Dreadhorde Arcanist; Earthcraft; Echoing Boon; Emissary's Ploy; Expressive Iteration; Falling Star; Fastbond; Fight the _____ Fight; Finishing Move; Flash; Frantic Search; Gitaxian Probe; Glitterflitter; Goblin Recruiter; Grief; Gush; Hermit Druid; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Imperial Seal; Imprison; Incendiary Dissent; Invoke Prejudice; Iterative Analysis; Jeweled Bird; Jihad; Last Voyage of the _____; Library of Alexandria; Line Cutter; Lineprancers; Lurrus of the Dream-Den; Make a _____ Splash; Mana Crypt; Mana Drain; Mana Vault; Memory Jar; Mental Misstep; Mind Twist; Minotaur de Force; Mishra's Workshop; Monitor Monitor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Muzzio's Preparations; Myra the Magnificent; Mystical Tutor; Natural Unity; Necropotence; Oath of Druids; Oko, Thief of Crowns; Park Bleater; Petting Zookeeper; Pin Collection; Power Play; Pradesh Gypsies; Prize Wall; Proficient Pyrodancer; Quick Fixer; Rad Rascal; Ragavan, Nimble Pilferer; Rebirth; Ride Guide; Robo-Piñata; Roxi, Publicist to the Stars; Scampire; Seasoned Buttoneer; Secret Summoning; Secrets of Paradise; Sensei's Divining Top; Sentinel Dispatch; Shahrazad; Skullclamp; Sol Ring; Soul Swindler; Sovereign's Realm; Spinnerette, Arachnobat; Squirrel Squatters; Step Right Up; Stiltstrider; Stone-Throwing Devils; Strip Mine; Summoner's Bond; Survival of the Fittest; Sword-Swallowing Seraph; Tempest Efreet; The Most Dangerous Gamer; Ticketomaton; Time Vault; Time Walk; Timetwister; Timmerian Fiends; Tinker; Tolarian Academy; Treasure Cruise; Tusk and Whiskers; Underworld Breach; Unexpected Potential; Vampiric Tutor; Weight Advantage; Wheel of Fortune; White Plume Adventurer; Wicker Picker; Windfall; Wizards of the _____; Wolf in _____ Clothing; Worldknit; Wrenn and Six; Yawgmoth's Bargain; Yawgmoth's Will; Zirda, the Dawnwaker diff --git a/forge-gui/res/formats/Sanctioned/Modern.txt b/forge-gui/res/formats/Sanctioned/Modern.txt index e0258f183c8..be4aa19aa26 100644 --- a/forge-gui/res/formats/Sanctioned/Modern.txt +++ b/forge-gui/res/formats/Sanctioned/Modern.txt @@ -4,4 +4,4 @@ Order:103 Subtype:Modern Type:Sanctioned Sets:8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, LRW, MOR, SHM, EVE, ALA, CFX, ARB, M10, ZEN, WWK, ROE, DPA, M11, SOM, MBS, NPH, M12, ISD, DKA, AVR, M13, RTR, GTC, DGM, MMA, M14, THS, BNG, JOU, MD1, M15, KTK, FRF, DTK, MM2, ORI, BFZ, OGW, SOI, W16, EMN, KLD, AER, MM3, W17, AKH, HOU, XLN, RIX, DOM, M19, GRN, GK1, G18, RNA, GK2, WAR, MH1, M20, ELD, THB, IKO, M21, ZNR, KHM, STX, MH2, AFR, MID, VOW, DBL, NEO, SNC, DMU, BRO, ONE, MOM, MAT, LTR, WOE, LCI, MKM, OTJ, BIG, MH3, ACR, BLB -Banned:Ancient Den; Arcum's Astrolabe; Birthing Pod; Blazing Shoal; Bridge from Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Faithless Looting; Field of the Dead; Fury; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Hogaak, Arisen Necropolis; Hypergenesis; Krark-Clan Ironworks; Lurrus of the Dream-Den; Mental Misstep; Mox Opal; Mycosynth Lattice; Mystic Sanctuary; Oko, Thief of Crowns; Once Upon a Time; Ponder; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Simian Spirit Guide; Skullclamp; Splinter Twin; Summer Bloom; Tibalt's Trickery; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Up the Beanstalk; Uro, Titan of Nature's Wrath; Vault of Whispers; Violent Outburst; Yorion, Sky Nomad +Banned:Ancient Den; Arcum's Astrolabe; Birthing Pod; Blazing Shoal; Bridge from Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Faithless Looting; Field of the Dead; Fury; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Grief; Hogaak, Arisen Necropolis; Hypergenesis; Krark-Clan Ironworks; Lurrus of the Dream-Den; Mental Misstep; Mox Opal; Mycosynth Lattice; Mystic Sanctuary; Nadu, Winged Wisdom; Oko, Thief of Crowns; Once Upon a Time; Ponder; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Simian Spirit Guide; Skullclamp; Splinter Twin; Summer Bloom; Tibalt's Trickery; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Up the Beanstalk; Uro, Titan of Nature's Wrath; Vault of Whispers; Violent Outburst; Yorion, Sky Nomad diff --git a/forge-gui/res/formats/Sanctioned/Pioneer.txt b/forge-gui/res/formats/Sanctioned/Pioneer.txt index a8e228f6b9d..a9ce627ed0a 100644 --- a/forge-gui/res/formats/Sanctioned/Pioneer.txt +++ b/forge-gui/res/formats/Sanctioned/Pioneer.txt @@ -4,4 +4,4 @@ Order:102 Subtype:Pioneer Type:Sanctioned Sets:RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, ORI, BFZ, OGW, SOI, W16, EMN, KLD, AER, W17, AKH, HOU, XLN, RIX, DOM, M19, GRN, G18, RNA, WAR, M20, ELD, THB, IKO, M21, ZNR, KHM, STX, AFR, MID, Q06, VOW, DBL, NEO, SNC, DMU, BRO, ONE, MOM, MAT, WOE, LCI, MKM, OTJ, BIG, BLB -Banned:Balustrade Spy; Bloodstained Mire; Expressive Iteration; Felidar Guardian; Field of the Dead; Flooded Strand; Geological Appraiser; Inverter of Truth; Karn, the Great Creator; Kethis, the Hidden Hand; Leyline of Abundance; Lurrus of the Dream-Den; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Teferi, Time Raveler; Undercity Informer; Underworld Breach; Uro, Titan of Nature's Wrath; Veil of Summer; Walking Ballista; Wilderness Reclamation; Windswept Heath; Winota, Joiner of Forces; Wooded Foothills +Banned:Amalia Benavides Aguirre; Balustrade Spy; Bloodstained Mire; Expressive Iteration; Felidar Guardian; Field of the Dead; Flooded Strand; Geological Appraiser; Inverter of Truth; Karn, the Great Creator; Kethis, the Hidden Hand; Leyline of Abundance; Lurrus of the Dream-Den; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Sorin, Imperious Bloodlord; Teferi, Time Raveler; Undercity Informer; Underworld Breach; Uro, Titan of Nature's Wrath; Veil of Summer; Walking Ballista; Wilderness Reclamation; Windswept Heath; Winota, Joiner of Forces; Wooded Foothills diff --git a/forge-gui/res/formats/Sanctioned/Vintage.txt b/forge-gui/res/formats/Sanctioned/Vintage.txt index 9883d9db2b9..a779f785965 100644 --- a/forge-gui/res/formats/Sanctioned/Vintage.txt +++ b/forge-gui/res/formats/Sanctioned/Vintage.txt @@ -4,5 +4,5 @@ Order:104 Subtype:Vintage Type:Sanctioned Sets:LEA, LEB, 2ED, ARN, ATQ, 3ED, LEG, DRC94, DRK, PHPR, FEM, 4ED, ICE, CHR, HML, ALL, MIR, VIS, 5ED, POR, WTH, TMP, STH, EXO, PO2, USG, ATH, ULG, 6ED, UDS, S99, PTK, MMQ, BRB, NMS, S00, PCY, BTD, INV, PLS, 7ED, APC, ODY, DKM, TOR, JUD, ONS, LGN, SCG, 8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, MED, LRW, DD1, MOR, SHM, EVE, DRB, ME2, ALA, DD2, CFX, DDC, ARB, M10, TD0, FVE, HOP, ME3, ZEN, DDD, PDS, WWK, DDE, ROE, DPA, ARC, M11, FVR, DDF, SOM, TD1, PD2, ME4, MBS, DDG, NPH, TD2, COM, M12, FVL, DDH, ISD, PD3, DKA, DDI, AVR, PC2, M13, V12, DDJ, RTR, CM1, GTC, DDK, DGM, MMA, M14, V13, DDL, THS, C13, BNG, DDM, JOU, MD1, CNS, VMA, M15, V14, DDN, KTK, C14, DVD, EVG, GVL, JVC, FRF, UGF, DDO, DTK, TPR, MM2, ORI, V15, DDP, BFZ, EXP, C15, PZ1, OGW, DDQ, SOI, W16, EMA, EMN, V16, CN2, DDR, KLD, MPS_KLD, C16, PZ2, PCA, AER, MM3, DDS, AKH, MPS_AKH, W17, CMA, E01, HOU, C17, XLN, DDT, IMA, V17, E02, RIX, A25, DDU, DOM, CM2, BBD, SS1, GS1, M19, C18, GRN, MPS_GRN, GK1, G18, GNT, UMA, RNA, MPS_RNA, GK2, WAR, MPS_WAR, MH1, SS2, M20, C19, ELD, MB1, GN2, SLD, THB, IKO, C20, SS3, M21, JMP, 2XM, ZNR, ZNE, ZNC, CMR, CC1, KHM, KHC, TSR, STX, STA, C21, MH2, H1R, AFR, AFC, MID, MIC, Q06, VOW, VOC, DBL, CC2, NEO, NEC, SNC, NCC, SLX, CLB, 2X2, DMU, DMC, 40K, UNF, GN3, BRO, BRC, BRR, BOT, J22, SCD, DMR, ONE, ONC, MOM, MOC, MUL, MAT, LTR, LTC, CMM, WOE, WOC, WOT, WHO, LCI, LCC, REX, SPG, RVR, MKM, MKC, CLU, PIP, OTJ, OTC, OTP, BIG, MH3, M3C, H2R, ACR, BLB, BLC, MB2 -Restricted:Ancestral Recall; Balance; Black Lotus; Brainstorm; Chalice of the Void; Channel; Demonic Consultation; Demonic Tutor; Dig Through Time; Flash; Gitaxian Probe; Golgari Grave-Troll; Gush; Imperial Seal; Karn, the Great Creator; Library of Alexandria; Lion's Eye Diamond; Lodestone Golem; Lotus Petal; Mana Crypt; Mana Vault; Memory Jar; Mental Misstep; Merchant Scroll; Mind's Desire; Monastery Mentor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystic Forge; Mystical Tutor; Narset, Parter of Veils; Necropotence; Sol Ring; Strip Mine; Thorn of Amethyst; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Trinisphere; Vampiric Tutor; Wheel of Fortune; Windfall; Yawgmoth's Will +Restricted:Ancestral Recall; Balance; Black Lotus; Brainstorm; Chalice of the Void; Channel; Demonic Consultation; Demonic Tutor; Dig Through Time; Flash; Gitaxian Probe; Golgari Grave-Troll; Gush; Imperial Seal; Karn, the Great Creator; Library of Alexandria; Lion's Eye Diamond; Lodestone Golem; Lotus Petal; Mana Crypt; Mana Vault; Memory Jar; Mental Misstep; Merchant Scroll; Mind's Desire; Monastery Mentor; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystic Forge; Mystical Tutor; Narset, Parter of Veils; Necropotence; Sol Ring; Strip Mine; Thorn of Amethyst; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Trinisphere; Urza's Saga; Vampiric Tutor; Vexing Bauble; Wheel of Fortune; Windfall; Yawgmoth's Will Banned:"Lifetime" Pass Holder; _____ _____ _____ Trespasser; _____ _____ Rocketship; _____ Balls of Fire; _____ Bird Gets the Worm; _____ Goblin; _____-o-saurus; Adriana's Valor; Advantageous Proclamation; Aerialephant; Ambassador Blorpityblorpboop; Amulet of Quoz; Assemble the Rank and Vile; Baaallerina; Backup Plan; Bioluminary; Brago's Favor; Bronze Tablet; Carnival Carnivore; Chaos Orb; Chicken Troupe; Clandestine Chameleon; Cleanse; Coming Attraction; Command Performance; Complaints Clerk; Contract from Below; Crusade; Darkpact; Deadbeat Attendant; Dee Kay, Finder of the Lost; Demonic Attorney; Discourtesy Clerk; Done for the Day; Double Stroke; Draconian Gate-Bot; Echoing Boon; Emissary's Ploy; Falling Star; Fight the _____ Fight; Finishing Move; Glitterflitter; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Imprison; Incendiary Dissent; Invoke Prejudice; Iterative Analysis; Jeweled Bird; Jihad; Last Voyage of the _____; Line Cutter; Lineprancers; Make a _____ Splash; Minotaur de Force; Monitor Monitor; Muzzio's Preparations; Myra the Magnificent; Natural Unity; Park Bleater; Petting Zookeeper; Pin Collection; Power Play; Pradesh Gypsies; Prize Wall; Proficient Pyrodancer; Quick Fixer; Rad Rascal; Rebirth; Ride Guide; Robo-Piñata; Roxi, Publicist to the Stars; Scampire; Seasoned Buttoneer; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Shahrazad; Soul Swindler; Sovereign's Realm; Spinnerette, Arachnobat; Squirrel Squatters; Step Right Up; Stiltstrider; Stone-Throwing Devils; Summoner's Bond; Sword-Swallowing Seraph; Tempest Efreet; The Most Dangerous Gamer; Ticketomaton; Timmerian Fiends; Tusk and Whiskers; Unexpected Potential; Weight Advantage; Wicker Picker; Wizards of the _____; Wolf in _____ Clothing; Worldknit diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index a6011f64349..4d02b28a191 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -3419,4 +3419,19 @@ AdvBossIntro31=Was wird als nächstes passieren? AdvBossIntro32=Nicht blinzeln! AdvBossIntro33=Hier kann man nicht verlieren! AdvBossIntro34=Es gibt kein Zurück! -AdvBossIntro35=Jetzt geht es um alles oder nichts! \ No newline at end of file +AdvBossIntro35=Jetzt geht es um alles oder nichts! +lblYouDied={0}, du bist gestorben!!! +lblSellFor=Verkaufen für +lblUnsellableCount=Unverkäuflich ({0}) +lblAutoSell=AUTOVERKAUF +lblNoSell=NICHT VERKAUFEN +lbltoSell=Zu verkaufen ({0}/{1}) +lbltoInventory=Zum Inventar ({0}/{1}) +lblHideAutoSell=Auto-Verkauf Ausblenden +lblShowAutoSell=Auto-Verkauf Anzeigen +lblHideNoSell=No-Sell Ausblenden +lblShowNoSell=No-Sell Anzeigen +lblShowAll=Alle Anzeigen +lblHideCollection=Sammlung Ausblenden +lblShowCollection=Sammlung Anzeigen +lblCracked=Geknackt! \ No newline at end of file diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index b197f00a078..80863cca86b 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -3152,4 +3152,19 @@ AdvBossIntro31=What will happen next? AdvBossIntro32=Don't blink! AdvBossIntro33=You can't lose here! AdvBossIntro34=There's no turning back! -AdvBossIntro35=It's all or nothing now! \ No newline at end of file +AdvBossIntro35=It's all or nothing now! +lblYouDied={0}, You Died!!! +lblSellFor=Sell for +lblUnsellableCount=Unsellable ({0}) +lblAutoSell=AUTO-SELL +lblNoSell=NO-SELL +lbltoSell=To Sell ({0}/{1}) +lbltoInventory=To Inventory ({0}/{1}) +lblHideAutoSell=Hide Auto-Sell +lblShowAutoSell=Show Auto-Sell +lblHideNoSell=Hide No-Sell +lblShowNoSell=Show No-Sell +lblShowAll=Show All +lblHideCollection=Hide Collection +lblShowCollection=Show Collection +lblCracked=Cracked! \ No newline at end of file diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index ef444654045..36ffbc1b600 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -3433,4 +3433,19 @@ AdvBossIntro31=¿Qué pasará después? AdvBossIntro32=¡No parpadees! AdvBossIntro33=¡No puedes perder aquí! AdvBossIntro34=¡No hay marcha atrás! -AdvBossIntro35=¡Ahora es todo o nada! \ No newline at end of file +AdvBossIntro35=¡Ahora es todo o nada! +lblYouDied={0}, ¡¡¡Moriste!!! +lblSellFor=Vender por +lblUnsellableCount=No vendible ({0}) +lblAutoSell=AUTOVENTA +lblNoSell=NO VENDER +lbltoSell=Para vender ({0}/{1}) +lbltoInventory=Al inventario ({0}/{1}) +lblHideAutoSell=Ocultar Venta Automática +lblShowAutoSell=Mostrar Autoventa +lblHideNoSell=Ocultar No Vender +lblShowNoSell=Mostrar No Vender +lblShowAll=Mostrar Todo +lblHideCollection=Ocultar Colección +lblShowCollection=Mostrar Colección +lblCracked=¡Agrietado! \ No newline at end of file diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index db05b60783e..1941f39fa0e 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -3427,4 +3427,19 @@ AdvBossIntro31=Que va-t-il se passer ensuite? AdvBossIntro32=Ne clignez pas des yeux ! AdvBossIntro33=Vous ne pouvez pas perdre ici ! AdvBossIntro34=Il n'y a pas de retour en arrière! -AdvBossIntro35=C'est tout ou rien maintenant ! \ No newline at end of file +AdvBossIntro35=C'est tout ou rien maintenant ! +lblYouDied={0}, tu es mort !!! +lblSellFor=Vendre pour +lblUnsellableCount=Invendable ({0}) +lblAutoSell=VENTE AUTOMATIQUE +lblNoSell=NON-VENTE +lbltoSell=À vendre ({0}/{1}) +lbltoInventory=Vers l'inventaire ({0}/{1}) +lblHideAutoSell=Masquer La Vente Automatique +lblShowAutoSell=Afficher La Vente Automatique +lblHideNoSell=Masquer Non-Vente +lblShowNoSell=Afficher Non-Vente +lblShowAll=Afficher Tout +lblHideCollection=Masquer la Collection +lblShowCollection=Afficher la Collection +lblCracked=Fissuré! \ No newline at end of file diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index e470184c205..f44607dbc64 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1331,7 +1331,7 @@ lblDiscardUpToNCards=Scarta fino a %d carta/e lblDiscardNCards=Scarta %d carta/e lblSelectNCardsToDiscardUnlessDiscarduType=Seleziona %d carta/e da scartare, a meno che tu non scarti una %s. lblCleanupPhase=Sottofase di cancellazione -lblSelectCardsToDiscardHandDownMaximum=Seleziona %d carte da scartare per portare la tua mano al massimo di %max carte. +lblSelectCardsToDiscardHandDownMaximum=Seleziona %d carte da scartare per portare la tua mano al massimo di %s max carte. lblChooseMinCardToDiscard=Scegli %d carte da scartare lblDiscarded=Scartate lblChooseDamageOrderFor=Scegli l''ordine dei danni per %s @@ -3425,4 +3425,19 @@ AdvBossIntro31=Cosa succederà dopo? AdvBossIntro32=Non sbattere le palpebre! AdvBossIntro33=Non puoi perdere qui! AdvBossIntro34=Non si può tornare indietro! -AdvBossIntro35=Adesso è tutto o niente! \ No newline at end of file +AdvBossIntro35=Adesso è tutto o niente! +lblYouDied={0}, sei morto!!! +lblSellFor=Vendi per +lblUnsellableCount=Invendibile ({0}) +lblAutoSell=AUTOVENDITA +lblNoSell=NON VENDITA +lbltoSell=Da vendere ({0}/{1}) +lbltoInventory=All'inventario ({0}/{1}) +lblHideAutoSell=Nascondi Auto-Vendita +lblShowAutoSell=Mostra Auto-Vendita +lblHideNoSell=Nascondi Non Vendita +lblShowNoSell=Mostra Non Vendita +lblShowAll=Mostra Tutto +lblHideCollection=Nascondi Collezione +lblShowCollection=Mostra Collezione +lblCracked=Incrinato! diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index 1984f718ff1..e08a27e1a8a 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -3421,4 +3421,19 @@ AdvBossIntro31=次は何が起こるのだろう? AdvBossIntro32=瞬きしないでください! AdvBossIntro33=ここで負けるわけにはいかない! AdvBossIntro34=もう後戻りはできない! -AdvBossIntro35=もう、オール・オア・ナッシングだ! \ No newline at end of file +AdvBossIntro35=もう、オール・オア・ナッシングだ! +lblYouDied={0}、死んだ!!! +lblSellFor=で売る +lblUnsellableCount=販売不可 ({0}) +lblAutoSell=自動販売 +lblNoSell=販売禁止 +lbltoSell=販売する ({0}/{1}) +lbltoInventory=インベントリへ ({0}/{1}) +lblHideAutoSell=自動販売を隠す +lblShowAutoSell=自動販売を表示する +lblHideNoSell=ノーセールを隠す +lblShowNoSell=ノーセールを表示 +lblShowAll=すべて表示 +lblHideCollection=コレクションを非表示にする +lblShowCollection=ショーコレクション +lblCracked=ひび割れた! \ No newline at end of file diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index 70002c16952..3ff8bc9b44c 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -3511,4 +3511,19 @@ AdvBossIntro31=O que vai acontecer à seguir? AdvBossIntro32=Não pisque! AdvBossIntro33=Você não pode perder aqui! AdvBossIntro34=Não há como voltar atrás! -AdvBossIntro35=É tudo ou nada agora! \ No newline at end of file +AdvBossIntro35=É tudo ou nada agora! +lblYouDied={0}, você morreu!!! +lblSellFor=Vender por +lblUnsellableCount=Invendável ({0}) +lblAutoSell=VENDA AUTOMÁTICA +lblNoSell=NÃO VENDER +lbltoSell=Para Vender ({0}/{1}) +lbltoInventory=Para o estoque ({0}/{1}) +lblHideAutoSell=Ocultar Venda Automática +lblShowAutoSell=Mostrar Venda Automática +lblHideNoSell=Ocultar Não Vender +lblShowNoSell=Mostrar Não-Venda +lblShowAll=Mostrar Tudo +lblHideCollection=Ocultar Coleção +lblShowCollection=Mostrar Coleção +lblCracked=Rachado! \ No newline at end of file diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 8659c9e213f..b77274cf232 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -3412,4 +3412,19 @@ AdvBossIntro31=接下来会发生什么? AdvBossIntro32=别眨眼! AdvBossIntro33=在这里你不能输! AdvBossIntro34=没有回头路了! -AdvBossIntro35=现在要么全有要么全无! \ No newline at end of file +AdvBossIntro35=现在要么全有要么全无! +lblYouDied={0},你死了!!! +lblSellFor=售价为 +lblUnsellableCount=无法出售({0}) +lblAutoSell=自动销售 +lblNoSell=不卖 +lbltoSell=出售({0}/{1}) +lbltoInventory=至库存 ({0}/{1}) +lblHideAutoSell=隐藏自动销售 +lblShowAutoSell=显示自动销售 +lblHideNoSell=隐藏不卖 +lblShowNoSell=显示不卖 +lblShowAll=显示全部 +lblHideCollection=隐藏收藏 +lblShowCollection=展会系列 +lblCracked=破裂了! \ No newline at end of file diff --git a/forge-gui/res/lists/TypeLists.txt b/forge-gui/res/lists/TypeLists.txt index 70b09466427..ddf7270260b 100644 --- a/forge-gui/res/lists/TypeLists.txt +++ b/forge-gui/res/lists/TypeLists.txt @@ -11,6 +11,7 @@ Gate:Gates Lair Locus Mine +Omenpath Power-Plant Sphere:Spheres Tower @@ -155,7 +156,7 @@ Kangaroo:Kangaroos Kavu:Kavu Killbot:Killbots Kirin:Kirins -Kithkin:Kithkins +Kithkin:Kithkin Knight:Knights Kobold:Kobolds Kor:Kors @@ -183,7 +184,7 @@ Monger:Mongers Mongoose:Mongooses Monk:Monks Monkey:Monkeys -Moonfolk:Moonfolks +Moonfolk:Moonfolk Mount:Mounts Mouse:Mice Mutant:Mutants @@ -292,7 +293,7 @@ Thrull:Thrulls Tiefling:Tieflings Time Lord:Time Lords Toy:Toys -Treefolk:Treefolks +Treefolk:Treefolk Trilobite:Trilobites Triskelavite:Triskelavites Troll:Trolls @@ -327,34 +328,35 @@ Chorus Lesson Trap [EnchantmentTypes] -Aura +Aura:Auras Background Cartouche Case Class -Curse +Curse:Curses Role +Room Rune -Saga -Shrine +Saga:Sagas +Shrine:Shrines Shard [ArtifactTypes] Attraction Blood Bobblehead:Bobbleheads Clue:Clues -Contraption +Contraption:Contraptions Equipment -Food +Food:Foods Fortification Gold Incubator:Incubators Junk Key:Keys Map -Powerstone -Treasure -Vehicle +Powerstone:Powerstones +Treasure:Treasures +Vehicle:Vehicles [WalkerTypes] Ajani Aminatou diff --git a/forge-gui/res/puzzle/PS_BLB3.pzl b/forge-gui/res/puzzle/PS_BLB3.pzl new file mode 100644 index 00000000000..11efe8bdf3e --- /dev/null +++ b/forge-gui/res/puzzle/PS_BLB3.pzl @@ -0,0 +1,18 @@ +[metadata] +Name:Possibility Storm - Bloomburrow #03 +URL:https://i0.wp.com/www.possibilitystorm.com/wp-content/uploads/2024/08/latest-1-scaled.jpg?ssl=1 +Goal:Win +Turns:1 +Difficulty:Rare +Description:Win this turn. Assume any cards you or your opponent could draw are not relevant to the puzzle. Ensure your solution considers all possible opponent decisions. Good luck! +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=5 +p0hand=Bitter Reunion;Season of the Burrow;Harvestrite Host;For the Common Good +p0library=Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt +p0battlefield=Baylen, the Haymaker;Alchemist's Talent;Plains;Copperline Gorge;Copperline Gorge;T:c_a_treasure_sac;T:c_a_treasure_sac;T:c_a_treasure_sac;T:c_a_treasure_sac;T:c_a_treasure_sac +p1life=12 +p1library=Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt +p1battlefield=Vengeful Tracker diff --git a/forge-gui/res/skins/default/adv_bg_castle.jpg b/forge-gui/res/skins/default/adv_bg_castle.jpg index e60b87afcc7..ecb5bb67a5e 100644 Binary files a/forge-gui/res/skins/default/adv_bg_castle.jpg and b/forge-gui/res/skins/default/adv_bg_castle.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_cave.jpg b/forge-gui/res/skins/default/adv_bg_cave.jpg index b2f8124590c..718751fe913 100644 Binary files a/forge-gui/res/skins/default/adv_bg_cave.jpg and b/forge-gui/res/skins/default/adv_bg_cave.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_common.jpg b/forge-gui/res/skins/default/adv_bg_common.jpg index 0ee655208dc..54e971880d9 100644 Binary files a/forge-gui/res/skins/default/adv_bg_common.jpg and b/forge-gui/res/skins/default/adv_bg_common.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_dungeon.jpg b/forge-gui/res/skins/default/adv_bg_dungeon.jpg index 2adfe2e48ad..7f60274aa67 100644 Binary files a/forge-gui/res/skins/default/adv_bg_dungeon.jpg and b/forge-gui/res/skins/default/adv_bg_dungeon.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_forest.jpg b/forge-gui/res/skins/default/adv_bg_forest.jpg index 676136c3505..3aa388716f0 100644 Binary files a/forge-gui/res/skins/default/adv_bg_forest.jpg and b/forge-gui/res/skins/default/adv_bg_forest.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_island.jpg b/forge-gui/res/skins/default/adv_bg_island.jpg index 035a59e0a22..9c988e71a1c 100644 Binary files a/forge-gui/res/skins/default/adv_bg_island.jpg and b/forge-gui/res/skins/default/adv_bg_island.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_mountain.jpg b/forge-gui/res/skins/default/adv_bg_mountain.jpg index 4fab6a88231..64ffbe24de8 100644 Binary files a/forge-gui/res/skins/default/adv_bg_mountain.jpg and b/forge-gui/res/skins/default/adv_bg_mountain.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_plains.jpg b/forge-gui/res/skins/default/adv_bg_plains.jpg index 18ba3b9c5ee..34018b9ebd1 100644 Binary files a/forge-gui/res/skins/default/adv_bg_plains.jpg and b/forge-gui/res/skins/default/adv_bg_plains.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_swamp.jpg b/forge-gui/res/skins/default/adv_bg_swamp.jpg index a25b73e94e2..e4f6f89a03b 100644 Binary files a/forge-gui/res/skins/default/adv_bg_swamp.jpg and b/forge-gui/res/skins/default/adv_bg_swamp.jpg differ diff --git a/forge-gui/res/skins/default/adv_bg_waste.jpg b/forge-gui/res/skins/default/adv_bg_waste.jpg index b1c9fd29db0..57ab798bd4a 100644 Binary files a/forge-gui/res/skins/default/adv_bg_waste.jpg and b/forge-gui/res/skins/default/adv_bg_waste.jpg differ diff --git a/forge-gui/res/tokenscripts/b_2_2_e_horror.txt b/forge-gui/res/tokenscripts/b_2_2_e_horror.txt new file mode 100644 index 00000000000..21f026e4f10 --- /dev/null +++ b/forge-gui/res/tokenscripts/b_2_2_e_horror.txt @@ -0,0 +1,6 @@ +Name:Horror Token +ManaCost:no cost +PT:2/2 +Colors:black +Types:Enchantment Creature Horror +Oracle: \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/bear_force_one.txt b/forge-gui/res/tokenscripts/bear_force_one.txt new file mode 100644 index 00000000000..2d86c224474 --- /dev/null +++ b/forge-gui/res/tokenscripts/bear_force_one.txt @@ -0,0 +1,10 @@ +Name:Vehicle Token +ManaCost:no cost +Types:Artifact Vehicle +PT:0/0 +K:Flying +K:Crew:2 +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | Description$ This creature gets +1/+1 for each Bear you control. +SVar:X:Count$Valid Bear.YouCtrl +SVar:BuffedBy:Bear +Oracle:Flying\nThis creature gets +1/+1 for each Bear you control.\nCrew 2 diff --git a/forge-gui/res/tokenscripts/bg_1_1_insect_flying.txt b/forge-gui/res/tokenscripts/bg_1_1_insect_flying.txt new file mode 100644 index 00000000000..95213da1d13 --- /dev/null +++ b/forge-gui/res/tokenscripts/bg_1_1_insect_flying.txt @@ -0,0 +1,7 @@ +Name:Insect Token +ManaCost:no cost +Types:Creature Insect +Colors:black,green +PT:1/1 +K:Flying +Oracle:Flying \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/bling.txt b/forge-gui/res/tokenscripts/bling.txt new file mode 100644 index 00000000000..b9a3f965039 --- /dev/null +++ b/forge-gui/res/tokenscripts/bling.txt @@ -0,0 +1,6 @@ +Name:Bling +ManaCost:no cost +Types:Artifact Equipment +K:Equip:1 +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | Description$ Equipped creature gets +1/+0. +Oracle:Equipped creature gets +1/+0.\nEquip {1} diff --git a/forge-gui/res/tokenscripts/c_4_4_a_scarecrow_vigilance.txt b/forge-gui/res/tokenscripts/c_4_4_a_scarecrow_vigilance.txt new file mode 100644 index 00000000000..e8f70620ce5 --- /dev/null +++ b/forge-gui/res/tokenscripts/c_4_4_a_scarecrow_vigilance.txt @@ -0,0 +1,6 @@ +Name:Scarecrow Token +ManaCost:no cost +PT:4/4 +Types:Artifact Creature Scarecrow +K:Vigilance +Oracle:Vigilance diff --git a/forge-gui/res/tokenscripts/c_l_forest.txt b/forge-gui/res/tokenscripts/c_l_forest.txt deleted file mode 100644 index deebb5ef659..00000000000 --- a/forge-gui/res/tokenscripts/c_l_forest.txt +++ /dev/null @@ -1,4 +0,0 @@ -Name:Forest Token -ManaCost:no cost -Types:Land Forest -Oracle: diff --git a/forge-gui/res/tokenscripts/c_l_wastes.txt b/forge-gui/res/tokenscripts/c_l_wastes.txt deleted file mode 100644 index e83233f6c4e..00000000000 --- a/forge-gui/res/tokenscripts/c_l_wastes.txt +++ /dev/null @@ -1,5 +0,0 @@ -Name:Wastes Token -ManaCost:no cost -Types:Land -A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. -Oracle:{T}: Add {C}. diff --git a/forge-gui/res/tokenscripts/incubator_dark_confidant.txt b/forge-gui/res/tokenscripts/incubator_dark_confidant.txt index b10cb72c62d..267e52003ea 100644 --- a/forge-gui/res/tokenscripts/incubator_dark_confidant.txt +++ b/forge-gui/res/tokenscripts/incubator_dark_confidant.txt @@ -1,4 +1,5 @@ Name:Incubator Dark Confidant Token +ManaCost:no cost Types:Artifact Incubator A:AB$ SetState | Cost$ 2 | Mode$ Transform | SpellDescription$ Transform this artifact. AlternateMode:DoubleFaced diff --git a/forge-gui/res/tokenscripts/pacifism.txt b/forge-gui/res/tokenscripts/pacifism.txt deleted file mode 100644 index 97956b075d1..00000000000 --- a/forge-gui/res/tokenscripts/pacifism.txt +++ /dev/null @@ -1,7 +0,0 @@ -Name:Pacifism -ManaCost:1 W -Types:Enchantment Aura -K:Enchant creature -A:SP$ Attach | Cost$ 1 W | ValidTgts$ Creature | AILogic$ Curse -S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddHiddenKeyword$ CARDNAME can't attack or block. | Description$ Enchanted creature can't attack or block. -Oracle:Enchant creature\nEnchanted creature can't attack or block. diff --git a/forge-gui/res/tokenscripts/primo_the_invisible.txt b/forge-gui/res/tokenscripts/primo_the_invisible.txt new file mode 100644 index 00000000000..52f4b310f61 --- /dev/null +++ b/forge-gui/res/tokenscripts/primo_the_invisible.txt @@ -0,0 +1,6 @@ +Name:Primo, the Invisible +ManaCost:no cost +Colors:green, blue +Types:Legendary Creature Fractal +PT:0/0 +Oracle: diff --git a/forge-gui/res/tokenscripts/role_cursed.txt b/forge-gui/res/tokenscripts/role_cursed.txt index c44c436b05f..a4f6271f85b 100644 --- a/forge-gui/res/tokenscripts/role_cursed.txt +++ b/forge-gui/res/tokenscripts/role_cursed.txt @@ -3,6 +3,6 @@ ManaCost:no cost Types:Enchantment Aura Role K:Enchant creature A:SP$ Attach | Cost$ 0 | ValidTgts$ Creature | AILogic$ Curse -S:Mode$ Continuous | Affected$ Creature.EnchantedBy | SetPower$ 1 | SetToughness$ 1 | Description$ Enchanted creature is 1/1 +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | SetPower$ 1 | SetToughness$ 1 | Description$ Enchanted creature is 1/1. SVar:SacMe:2 -Oracle:Enchant Creature\nEnchanted creature is 1/1 +Oracle:Enchant Creature\nEnchanted creature is 1/1. diff --git a/forge-gui/res/tokenscripts/syr_acha.txt b/forge-gui/res/tokenscripts/syr_acha.txt new file mode 100644 index 00000000000..8c839938054 --- /dev/null +++ b/forge-gui/res/tokenscripts/syr_acha.txt @@ -0,0 +1,10 @@ +Name:Syr Acha +ManaCost:no cost +Types:Legendary Artifact Creature Food Knight +Colors:red +PT:1/1 +A:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME> | LifeAmount$ 3 | SubAbility$ DBEffect | SpellDescription$ You gain 3 life. +SVar:DBEffect:DB$ Effect | ReplacementEffects$ CardDrawn | StackDescription$ Until end of turn, if {p:You} would draw a card, they draw two cards instead. | SpellDescription$ Until end of turn, if you would draw a card, draw two cards instead. +SVar:CardDrawn:Event$ Draw | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ DrawTwo | Description$ If you would draw a card, draw two cards instead. +SVar:DrawTwo:DB$ Draw | Defined$ You | NumCards$ 2 +Oracle:{2}, {T}, Sacrifice this token: You gain 3 life. Until end of turn, if you would draw a card, draw two cards instead. diff --git a/forge-gui/res/tokenscripts/u_0_0_elemental.txt b/forge-gui/res/tokenscripts/u_0_0_elemental.txt new file mode 100644 index 00000000000..68255e9dd3b --- /dev/null +++ b/forge-gui/res/tokenscripts/u_0_0_elemental.txt @@ -0,0 +1,6 @@ +Name:Elemental Token +ManaCost:no cost +Types:Creature Elemental +Colors:blue +PT:0/0 +Oracle: diff --git a/forge-gui/res/tokenscripts/u_x_x_spirit_flying.txt b/forge-gui/res/tokenscripts/u_x_x_spirit_flying.txt new file mode 100644 index 00000000000..725c7b55f28 --- /dev/null +++ b/forge-gui/res/tokenscripts/u_x_x_spirit_flying.txt @@ -0,0 +1,7 @@ +Name:Spirit Token +ManaCost:no cost +Colors:blue +Types:Creature Spirit +PT:*/* +K:Flying +Oracle:Flying \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/w_1_1_e_glimmer.txt b/forge-gui/res/tokenscripts/w_1_1_e_glimmer.txt new file mode 100644 index 00000000000..cc01c1e26f6 --- /dev/null +++ b/forge-gui/res/tokenscripts/w_1_1_e_glimmer.txt @@ -0,0 +1,6 @@ +Name:Glimmer Token +ManaCost:no cost +PT:1/1 +Colors:white +Types:Enchantment Creature Glimmer +Oracle: \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/w_2_1_insect_flying.txt b/forge-gui/res/tokenscripts/w_2_1_insect_flying.txt new file mode 100644 index 00000000000..0418f295ef8 --- /dev/null +++ b/forge-gui/res/tokenscripts/w_2_1_insect_flying.txt @@ -0,0 +1,7 @@ +Name:Insect Token +ManaCost:no cost +PT:2/1 +Colors:white +Types:Creature Insect +K:Flying +Oracle:Flying \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/yellow_hat.txt b/forge-gui/res/tokenscripts/yellow_hat.txt new file mode 100644 index 00000000000..62b4a1d55ac --- /dev/null +++ b/forge-gui/res/tokenscripts/yellow_hat.txt @@ -0,0 +1,6 @@ +Name:Yellow Hat +ManaCost:no cost +Types:Legendary Artifact Equipment +K:Equip:2 +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 4 | AddToughness$ 4 | AddKeyword$ Lifelink | Description$ Equiped creature gets +4/+4 and gains lifelink. +Oracle:Equiped creature gets +4/+4 and gains lifelink.\nEquip {2} diff --git a/forge-gui/src/main/java/forge/gamemodes/match/AbstractGuiGame.java b/forge-gui/src/main/java/forge/gamemodes/match/AbstractGuiGame.java index 41a2d055d82..ef0cdf05a17 100644 --- a/forge-gui/src/main/java/forge/gamemodes/match/AbstractGuiGame.java +++ b/forge-gui/src/main/java/forge/gamemodes/match/AbstractGuiGame.java @@ -461,17 +461,13 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { @Override public final void awaitNextInput() { - if (awaitNextInputTimer == null) { - String name = "?"; - if (this.currentPlayer != null) - name = this.currentPlayer.getLobbyPlayerName(); - awaitNextInputTimer = new Timer("awaitNextInputTimer Game:" + this.gameView.getId() + " Player:" + name); - } + checkAwaitNextInputTimer(); //delay updating prompt to await next input briefly so buttons don't flicker disabled then enabled awaitNextInputTask = new TimerTask() { @Override public void run() { FThreads.invokeInEdtLater(() -> { + checkAwaitNextInputTimer(); synchronized (awaitNextInputTimer) { if (awaitNextInputTask != null) { updatePromptForAwait(getCurrentPlayer()); @@ -483,6 +479,14 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { }; awaitNextInputTimer.schedule(awaitNextInputTask, 250); } + private void checkAwaitNextInputTimer() { + if (awaitNextInputTimer == null) { + String name = "?"; + if (this.currentPlayer != null) + name = this.currentPlayer.getLobbyPlayerName(); + awaitNextInputTimer = new Timer("awaitNextInputTimer Game:" + this.gameView.getId() + " Player:" + name); + } + } protected final void updatePromptForAwait(final PlayerView playerView) { showPromptMessage(playerView, Localizer.getInstance().getMessage("lblWaitingForOpponent")); diff --git a/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java index 68bb4f7a236..59ebe64a76c 100644 --- a/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/gui/card/CardDetailUtil.java @@ -178,7 +178,7 @@ public class CardDetailUtil { public static String formatCardType(final CardStateView card, final boolean canShow) { boolean isInPlay = card.getCard() != null && ZoneType.Battlefield.equals(card.getCard().getZone()); - String translatedtype = CardTranslation.getTranslatedType(card.getName(), card.getType().toString()); + String translatedtype = CardTranslation.getTranslatedType(card); return canShow ? translatedtype : (card.getState() == CardStateName.FaceDown && isInPlay ? "Creature" : ""); } @@ -319,8 +319,8 @@ public class CardDetailUtil { needTranslation = false; } String text = !card.isSplitCard() ? - card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null) : - card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null ); + card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state) : null) : + card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState(), card.getRightSplitState()) : null ); // Bracket P/T for Level up if (text.contains("LEVEL")) { diff --git a/forge-gui/src/main/java/forge/gui/card/CardScriptParser.java b/forge-gui/src/main/java/forge/gui/card/CardScriptParser.java index 165e7f7577b..76de4179a71 100644 --- a/forge-gui/src/main/java/forge/gui/card/CardScriptParser.java +++ b/forge-gui/src/main/java/forge/gui/card/CardScriptParser.java @@ -439,8 +439,7 @@ public final class CardScriptParser { "sameName", "namedCard", "NamedByRememberedPlayer", "Permanent", "ChosenCard", "nonChosenCard", "White", "Blue", "Black", "Red", "Green", "nonWhite", "nonBlue", "nonBlack", "nonRed", "nonGreen", - "Colorless", "nonColorless", "Multicolor", "nonMulticolor", - "Monocolor", "nonMonocolor", "ChosenColor", "AllChosenColors", + "Colorless", "nonColorless", "Multicolor", "Monocolor", "ChosenColor", "AllChosenColors", "AnyChosenColor", "DoubleFaced", "Flip", "YouCtrl", "YourTeamCtrl", "YouDontCtrl", "OppCtrl", "ChosenCtrl", "DefenderCtrl", "DefenderCtrlForRemembered", "DefendingPlayerCtrl", diff --git a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java index f08f5e21832..81b9d1771da 100644 --- a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java +++ b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java @@ -81,11 +81,12 @@ public class AdvancedSearch { protected Set getItemValues(PaperCard input) { Set names = new HashSet<>(); names.add(input.getRules().getOracleText()); - names.add(CardTranslation.getTranslatedOracle(input.getName())); + names.add(CardTranslation.getTranslatedOracle(input)); CardSplitType cardSplitType = input.getRules().getSplitType(); if (cardSplitType != CardSplitType.None && cardSplitType != CardSplitType.Split) { if (input.getRules().getOtherPart() != null) { names.add(input.getRules().getOtherPart().getOracleText()); + //Doesn't support a combination of functional variant + split card, but none of those exist yet. names.add(CardTranslation.getTranslatedOracle(input.getRules().getOtherPart().getName())); } } diff --git a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java index 024717c3586..173f1a301a7 100644 --- a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java +++ b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java @@ -81,8 +81,8 @@ public enum ColumnDef { * The type column. */ TYPE("lblType", "ttType", 100, false, SortState.ASC, - from -> CardTranslation.getTranslatedType(from.getKey().getName(), toType(from.getKey())), - from -> CardTranslation.getTranslatedType(from.getKey().getName(), toType(from.getKey()))), + from -> CardTranslation.getTranslatedType(from.getKey()), + from -> CardTranslation.getTranslatedType(from.getKey())), /** * The mana cost column. */ @@ -357,10 +357,6 @@ public enum ColumnDef { return this.longName; } - private static String toType(final InventoryItem i) { - return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getType().toString() : i.getItemType(); - } - private static IPaperCard toCard(final InventoryItem i) { return i instanceof IPaperCard ? ((IPaperCard) i) : null; } diff --git a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java index 51ca400a829..b8b339834c3 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java +++ b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java @@ -27,7 +27,6 @@ import forge.card.MagicColor; import forge.game.Game; import forge.game.GameActionUtil; import forge.game.GameObject; -import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.CharmEffect; @@ -211,7 +210,7 @@ public class HumanPlaySpellAbility { if (skipStack) { AbilityUtils.resolve(ability); // Should unfreeze stack (but if it was a RE with a cause better to let it be handled by that) - if (!ability.isReplacementAbility() || ability.getRootAbility().getReplacingObject(AbilityKey.Cause) == null) { + if (!ability.isReplacementAbility()) { game.getStack().unfreezeStack(); } } else { diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index bb039b17b85..0e4488fd443 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -1065,7 +1065,6 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont @Override public CardCollectionView orderMoveToZoneList(final CardCollectionView cards, final ZoneType destinationZone, final SpellAbility source) { - boolean bottomOfLibrary = false; if (source == null || source.getApi() != ApiType.ReorderZone) { if (destinationZone == ZoneType.Graveyard) { switch (FModel.getPreferences().getPref(FPref.UI_ALLOW_ORDER_GRAVEYARD_WHEN_NEEDED)) { @@ -1088,17 +1087,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont } } - if (source != null) { - if (source.hasParam("LibraryPosition")) { - bottomOfLibrary = Integer.parseInt(source.getParam("LibraryPosition")) < 0; - } - } tempShowCards(cards); GameEntityViewMap gameCacheMove = GameEntityView.getMap(cards); List choices = gameCacheMove.getTrackableKeys(); switch (destinationZone) { case Library: + boolean bottomOfLibrary = (source != null && source.hasParam("LibraryPosition") ? + AbilityUtils.calculateAmount(source.getHostCard(), source.getParam("LibraryPosition"), source) : 0) < 0; choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoLibrary"), localizer.getMessage(bottomOfLibrary ? "lblClosestToBottom" : "lblClosestToTop"), choices, null); break; case Battlefield: