diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 2ad89291285..e2bf5ae96e7 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -64,7 +64,6 @@ import forge.util.Aggregates; import forge.util.ComparatorUtil; import forge.util.Expressions; import forge.util.MyRandom; -import forge.util.collect.FCollectionView; import io.sentry.Breadcrumb; import io.sentry.Sentry; @@ -437,11 +436,11 @@ public class AiController { } landList = CardLists.filter(landList, c -> { - CardCollectionView battlefield = player.getCardsIn(ZoneType.Battlefield); if (canPlaySpellBasic(c, null) != AiPlayDecision.WillPlay) { return false; } String name = c.getName(); + CardCollectionView battlefield = player.getCardsIn(ZoneType.Battlefield); if (c.getType().isLegendary() && !name.equals("Flagstones of Trokair")) { if (Iterables.any(battlefield, CardPredicates.nameEquals(name))) { return false; @@ -461,15 +460,11 @@ public class AiController { } // don't play the land if it has cycling and enough lands are available - final FCollectionView spellAbilities = c.getSpellAbilities(); - for (final SpellAbility sa : spellAbilities) { - if (sa.isCycling()) { - return false; - } + if (c.hasKeyword(Keyword.CYCLING)) { + return false; } } - - return player.canPlayLand(c); + return Iterables.any(c.getAllPossibleAbilities(player, true), SpellAbility::isLandAbility); }); return landList; } @@ -1376,30 +1371,12 @@ public class AiController { Card land = chooseBestLandToPlay(landsWannaPlay); if ((!player.canLoseLife() || player.cantLoseForZeroOrLessLife() || ComputerUtil.getDamageFromETB(player, land) < player.getLife()) && (!game.getPhaseHandler().is(PhaseType.MAIN1) || !isSafeToHoldLandDropForMain2(land))) { - final List abilities = Lists.newArrayList(); + final List abilities = land.getAllPossibleAbilities(player, true); + // skip non Land Abilities + abilities.removeIf(sa -> !sa.isLandAbility()); - // TODO extend this logic to evaluate MDFC with both sides land - // this can only happen if its a MDFC land - if (!land.isLand()) { - land.setState(CardStateName.Modal, true); - land.setBackSide(true); - } - - LandAbility la = new LandAbility(land, player, null); - la.setCardState(land.getCurrentState()); - if (la.canPlay()) { - abilities.add(la); - } - - // add mayPlay option - for (CardPlayOption o : land.mayPlay(player)) { - la = new LandAbility(land, player, o); - la.setCardState(land.getCurrentState()); - if (la.canPlay()) { - abilities.add(la); - } - } if (!abilities.isEmpty()) { + // TODO extend this logic to evaluate MDFC with both sides land return abilities; } } @@ -1570,7 +1547,7 @@ public class AiController { Iterables.removeIf(saList, spellAbility -> { //don't include removedAI cards if somehow the AI can play the ability or gain control of unsupported card // TODO allow when experimental profile? - return spellAbility instanceof LandAbility || (spellAbility.getHostCard() != null && ComputerUtilCard.isCardRemAIDeck(spellAbility.getHostCard())); + return spellAbility.isLandAbility() || (spellAbility.getHostCard() != null && ComputerUtilCard.isCardRemAIDeck(spellAbility.getHostCard())); }); //update LivingEndPlayer useLivingEnd = Iterables.any(player.getZone(ZoneType.Library), CardPredicates.nameEquals("Living End")); diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java b/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java index 1add3ce299d..b08e4e3bd3e 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java @@ -14,7 +14,6 @@ import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; import forge.game.card.CardLists; -import forge.game.card.CardPredicates.Presets; import forge.game.cost.CostPart; import forge.game.cost.CostPayEnergy; import forge.game.cost.CostPutCounter; @@ -32,20 +31,14 @@ public class ComputerUtilAbility { if (!game.getStack().isEmpty() || !game.getPhaseHandler().getPhase().isMain()) { return null; } - final CardCollection hand = new CardCollection(player.getCardsIn(ZoneType.Hand)); - hand.addAll(player.getCardsIn(ZoneType.Exile)); - CardCollection landList = CardLists.filter(hand, Presets.LANDS); + CardCollection landList = new CardCollection(player.getCardsIn(ZoneType.Hand)); //filter out cards that can't be played landList = CardLists.filter(landList, c -> { - if (!c.getSVar("NeedsToPlay").isEmpty()) { - final String needsToPlay = c.getSVar("NeedsToPlay"); - CardCollection list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), needsToPlay, c.getController(), c, null); - if (list.isEmpty()) { - return false; - } + if (!c.hasPlayableLandFace()) { + return false; } - return player.canPlayLand(c); + return player.canPlayLand(c, false, c.getFirstSpellAbility()); }); final CardCollection landsNotInHand = new CardCollection(player.getCardsIn(ZoneType.Graveyard)); @@ -54,7 +47,7 @@ public class ComputerUtilAbility { landsNotInHand.add(player.getCardsIn(ZoneType.Library).get(0)); } for (final Card crd : landsNotInHand) { - if (!(crd.isLand() || (crd.isFaceDown() && crd.getState(CardStateName.Original).getType().isLand()))) { + if (!(crd.hasPlayableLandFace() || (crd.isFaceDown() && crd.getState(CardStateName.Original).getType().isLand()))) { continue; } if (!crd.mayPlay(player).isEmpty()) { diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 2c15791a6d6..b1a282a20b8 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -810,7 +810,7 @@ public class PlayerControllerAi extends PlayerController { @Override public boolean playChosenSpellAbility(SpellAbility sa) { - if (sa instanceof LandAbility) { + if (sa.isLandAbility()) { if (sa.canPlay()) { sa.resolve(); } 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 36a61d50e25..7353a927c82 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -95,8 +95,8 @@ public class DamageDealAi extends DamageAiBase { final String damage = sa.getParam("NumDmg"); int dmg = AbilityUtils.calculateAmount(source, damage, sa); - if (damage.equals("X") || sourceName.equals("Crater's Claws")) { - if (sa.getSVar(damage).equals("Count$xPaid") || sourceName.equals("Crater's Claws")) { + if (damage.equals("X") || source.getSVar("X").equals("Count$xPaid") || sourceName.equals("Crater's Claws")) { + if (sa.getSVar("X").equals("Count$xPaid") || sa.getSVar(damage).equals("Count$xPaid") || sourceName.equals("Crater's Claws")) { dmg = ComputerUtilCost.getMaxXValue(sa, ai, sa.isTrigger()); // Try not to waste spells like Blaze or Fireball on early targets, try to do more damage with them if possible @@ -723,6 +723,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/DiscoverAi.java b/forge-ai/src/main/java/forge/ai/ability/DiscoverAi.java index 9541d8266d5..c0ac69a99b7 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DiscoverAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DiscoverAi.java @@ -8,7 +8,7 @@ import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; -import forge.game.spellability.LandAbility; + import forge.game.spellability.Spell; import forge.game.spellability.SpellAbility; @@ -45,7 +45,7 @@ public class DiscoverAi extends SpellAbilityAi { public boolean confirmAction(Player ai, SpellAbility sa, PlayerActionConfirmMode mode, String message, Map params) { Card c = (Card)params.get("Card"); for (SpellAbility s : AbilityUtils.getBasicSpellsFromPlayEffect(c, ai)) { - if (s instanceof LandAbility) { + if (s.isLandAbility()) { // return false or we get a ClassCastException later if the AI encounters MDFC with land backside return false; } diff --git a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java index 5736c4f8486..5e7e9c482ff 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java @@ -154,7 +154,7 @@ public class PlayAi extends SpellAbilityAi { if (!sa.matchesValidParam("ValidSA", s)) { continue; } - if (s instanceof LandAbility) { + if (s.isLandAbility()) { // might want to run some checks here but it's rare anyway return true; } diff --git a/forge-ai/src/main/java/forge/ai/ability/ScryAi.java b/forge-ai/src/main/java/forge/ai/ability/ScryAi.java index ee98d496455..0c14cd7c3e0 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ScryAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ScryAi.java @@ -26,11 +26,29 @@ public class ScryAi extends SpellAbilityAi { */ @Override protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { - if (sa.usesTargeting()) { // It doesn't appear that Scry ever targets + if (sa.usesTargeting()) { // ability is targeted sa.resetTargets(); - sa.getTargets().add(ai); + if (sa.canTarget(ai)) { + sa.getTargets().add(ai); + } else { + for (Player p : ai.getAllies()) { + if (sa.canTarget(p)) { + sa.getTargets().add(p); + break; + } + } + if (mandatory && !sa.isTargetNumberValid()) { + for (Player p : ai.getOpponents()) { + if (sa.canTarget(p)) { + sa.getTargets().add(p); + break; + } + } + } + } + return mandatory || sa.isTargetNumberValid(); } return true; @@ -132,6 +150,21 @@ public class ScryAi extends SpellAbilityAi { randomReturn = true; } + if (sa.usesTargeting()) { + sa.resetTargets(); + if (sa.canTarget(ai)) { + sa.getTargets().add(ai); + } else { + for (Player p : ai.getAllies()) { + if (sa.canTarget(p)) { + sa.getTargets().add(p); + break; + } + } + } + randomReturn = sa.isTargetNumberValid(); + } + return randomReturn; } diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java b/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java index e78415429a9..c6b354ef553 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameSimulator.java @@ -1,6 +1,6 @@ package forge.ai.simulation; -import forge.game.spellability.LandAbility; + import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -158,9 +158,9 @@ public class GameSimulator { } public Score simulateSpellAbility(SpellAbility origSa, GameStateEvaluator eval, boolean resolve) { SpellAbility sa; - if (origSa instanceof LandAbility) { + if (origSa.isLandAbility()) { Card hostCard = (Card) copier.find(origSa.getHostCard()); - if (!aiPlayer.playLand(hostCard, false)) { + if (!aiPlayer.playLand(hostCard, false, origSa)) { System.err.println("Simulation: Couldn't play land! " + origSa); } sa = origSa; diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameStateEvaluator.java b/forge-ai/src/main/java/forge/ai/simulation/GameStateEvaluator.java index de05636ddc8..eeab7621bb0 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameStateEvaluator.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameStateEvaluator.java @@ -260,7 +260,10 @@ public class GameStateEvaluator { // The value should be more than the value of having a card in hand, so if a land has an // activated ability but not a mana ability, it will still be played. for (SpellAbility m: c.getNonManaAbilities()) { - if (!m.getPayCosts().hasTapCost()) { + if (m.isLandAbility()) { + // Land Ability has no extra Score + continue; + } if (!m.getPayCosts().hasTapCost()) { // probably a manland, rate it higher than a rainbow land value += 25; } else if (m.getPayCosts().hasSpecificCostType(CostSacrifice.class)) { diff --git a/forge-ai/src/main/java/forge/ai/simulation/SpellAbilityPicker.java b/forge-ai/src/main/java/forge/ai/simulation/SpellAbilityPicker.java index 28dfb46d184..483449ace0a 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/SpellAbilityPicker.java +++ b/forge-ai/src/main/java/forge/ai/simulation/SpellAbilityPicker.java @@ -24,7 +24,7 @@ import forge.game.card.CardPredicates; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.AbilitySub; -import forge.game.spellability.LandAbility; + import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityCondition; import forge.game.zone.ZoneType; @@ -136,7 +136,7 @@ public class SpellAbilityPicker { private static boolean isSorcerySpeed(SpellAbility sa, Player player) { // TODO: Can we use the actual rules engine for this instead of trying to do the logic ourselves? - if (sa instanceof LandAbility) { + if (sa.isLandAbility()) { return true; } if (sa.isSpell()) { @@ -327,16 +327,16 @@ public class SpellAbilityPicker { } private AiPlayDecision canPlayAndPayForSim(final SpellAbility sa) { - if (!sa.isLegalAfterStack()) { - return AiPlayDecision.CantPlaySa; - } if (!sa.checkRestrictions(sa.getHostCard(), player)) { return AiPlayDecision.CantPlaySa; } - if (sa instanceof LandAbility) { + if (sa.isLandAbility()) { return AiPlayDecision.WillPlay; } + if (!sa.isLegalAfterStack()) { + return AiPlayDecision.CantPlaySa; + } if (!sa.canPlay()) { return AiPlayDecision.CantPlaySa; } diff --git a/forge-core/src/main/java/forge/card/CardRarity.java b/forge-core/src/main/java/forge/card/CardRarity.java index cad70efa046..c6663162bf3 100644 --- a/forge-core/src/main/java/forge/card/CardRarity.java +++ b/forge-core/src/main/java/forge/card/CardRarity.java @@ -24,7 +24,7 @@ public enum CardRarity { Rare("R", "Rare"), MythicRare("M", "Mythic Rare"), Special("S", "Special"), // Timeshifted - None("N", "None"), // Tokens + Token("T", "Token"), // Tokens Unknown("?", "Unknown"); // In development public static final CardRarity[] FILTER_OPTIONS = new CardRarity[] { diff --git a/forge-core/src/main/java/forge/item/PaperToken.java b/forge-core/src/main/java/forge/item/PaperToken.java index 91b900591f8..c13b0435880 100644 --- a/forge-core/src/main/java/forge/item/PaperToken.java +++ b/forge-core/src/main/java/forge/item/PaperToken.java @@ -169,7 +169,7 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard { @Override public CardRarity getRarity() { - return CardRarity.None; + return CardRarity.Token; } @Override diff --git a/forge-game/src/main/java/forge/game/CardTraitBase.java b/forge-game/src/main/java/forge/game/CardTraitBase.java index 96aaabeaee9..c01f1c7c0d9 100644 --- a/forge-game/src/main/java/forge/game/CardTraitBase.java +++ b/forge-game/src/main/java/forge/game/CardTraitBase.java @@ -64,7 +64,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, * Keys that should not changed */ private static final ImmutableList noChangeKeys = ImmutableList.builder() - .add("TokenScript", "TokenImage", "NewName", "ChooseFromList") + .add("TokenScript", "TokenImage", "NewName" , "DefinedName", "ChooseFromList") .add("AddAbility").build(); /** @@ -170,7 +170,7 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, * * @return a boolean. */ - public final boolean isSecondary() { + public boolean isSecondary() { return getParamOrDefault("Secondary", "False").equals("True"); } diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index 3e873a52146..d6b1b222305 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -91,10 +91,10 @@ public final class GameActionUtil { return alternatives; } - if (sa.isSpell()) { + if (sa.isSpell() || sa.isLandAbility()) { boolean lkicheck = false; - Card newHost = ((Spell)sa).getAlternateHost(source); + Card newHost = sa.getAlternateHost(source); if (newHost != null) { source = newHost; lkicheck = true; diff --git a/forge-game/src/main/java/forge/game/GameLogFormatter.java b/forge-game/src/main/java/forge/game/GameLogFormatter.java index faf9fe64314..9027a6d3bbb 100644 --- a/forge-game/src/main/java/forge/game/GameLogFormatter.java +++ b/forge-game/src/main/java/forge/game/GameLogFormatter.java @@ -2,7 +2,6 @@ package forge.game; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map.Entry; import com.google.common.collect.Iterables; @@ -93,11 +92,7 @@ public class GameLogFormatter extends IGameEventVisitor.Base { if (event.sa.getTargetRestrictions() != null) { StringBuilder sb = new StringBuilder(); - List targets = event.sa.getAllTargetChoices(); - // Include the TargetChoices from the stack instance, since the real target choices - // are on that object at this point (see SpellAbilityStackInstance constructor). - targets.add(event.si.getTargetChoices()); - for (TargetChoices ch : targets) { + for (TargetChoices ch : event.sa.getAllTargetChoices()) { if (null != ch) { sb.append(ch); } 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 c5ff9a72f14..036fff0cd28 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -2953,7 +2953,8 @@ public class AbilityUtils { } for (SpellAbility s : list) { - if (s instanceof LandAbility) { + if (s.isLandAbility()) { + s.setActivatingPlayer(controller); // CR 305.3 if (controller.getGame().getPhaseHandler().isPlayerTurn(controller) && controller.canPlayLand(tgtCard, true, s)) { sas.add(s); @@ -2981,9 +2982,7 @@ public class AbilityUtils { private static void collectSpellsForPlayEffect(final List result, final CardState state, final Player controller, final boolean withAltCost) { if (state.getType().isLand()) { - LandAbility la = new LandAbility(state.getCard(), controller, null); - la.setCardState(state); - result.add(la); + result.add(state.getFirstSpellAbility()); } final Iterable spells = state.getSpellAbilities(); for (SpellAbility sa : spells) { 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 23376bfa6b4..2e3aff67e86 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 @@ -13,7 +13,9 @@ import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import forge.ImageKeys; import forge.StaticData; +import forge.card.CardRarity; import forge.card.CardRulesPredicates; import forge.card.CardStateName; import forge.game.Game; @@ -46,53 +48,59 @@ public class CopyPermanentEffect extends TokenEffectBase { final StringBuilder sb = new StringBuilder(); final Player activator = sa.getActivatingPlayer(); - final List tgtCards = getTargetCards(sa); - boolean justOne = tgtCards.size() == 1; - boolean addKWs = sa.hasParam("AddKeywords"); final int numCopies = sa.hasParam("NumCopies") ? AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumCopies"), sa) : 1; - sb.append(activator).append(" creates ").append(Lang.nounWithNumeralExceptOne(numCopies, "token")); - sb.append(numCopies == 1 ? " that's a copy" : " that are copies").append(" of "); - sb.append(Lang.joinHomogenous(tgtCards)); - - if (addKWs) { - final List keywords = Lists.newArrayList(); - keywords.addAll(Arrays.asList(sa.getParam("AddKeywords").split(" & "))); - if (sa.getDescription().contains("except")) { - sb.append(", except ").append(justOne ? "it has " : "they have "); - } else { - sb.append(". ").append(justOne ? "It gains " : "They gain "); - } - sb.append(Lang.joinHomogenous(keywords).toLowerCase()); - } - - if (sa.hasParam("AddTriggers")) { - final String oDesc = sa.getDescription(); - final String trigStg = oDesc.contains("\"") ? - oDesc.substring(oDesc.indexOf("\""),oDesc.lastIndexOf("\"") + 1) : - "[trigger text parsing error]"; - if (addKWs) { - sb.append(" and ").append(trigStg); - } else { - sb.append(". ").append(justOne ? "It gains " : "They gain ").append(trigStg); - } + sb.append(activator).append(" creates "); + if (sa.hasParam("DefinedName")) { + sb.append(Lang.nounWithNumeralExceptOne(numCopies, sa.getParam("DefinedName") + " token")); } else { - sb.append("."); - } + final List tgtCards = getTargetCards(sa); + boolean justOne = tgtCards.size() == 1; + boolean addKWs = sa.hasParam("AddKeywords"); - if (sa.hasParam("AtEOT")) { - String atEOT = sa.getParam("AtEOT"); - String verb = "Sacrifice "; - if (atEOT.startsWith("Exile")) { - verb = "Exile "; + sb.append(Lang.nounWithNumeralExceptOne(numCopies, "token")); + sb.append(numCopies == 1 ? " that's a copy" : " that are copies").append(" of "); + sb.append(Lang.joinHomogenous(tgtCards)); + + if (addKWs) { + final List keywords = Lists.newArrayList(); + keywords.addAll(Arrays.asList(sa.getParam("AddKeywords").split(" & "))); + if (sa.getDescription().contains("except")) { + sb.append(", except ").append(justOne ? "it has " : "they have "); + } else { + sb.append(". ").append(justOne ? "It gains " : "They gain "); + } + sb.append(Lang.joinHomogenous(keywords).toLowerCase()); } - sb.append(" ").append(verb).append(justOne ? "it " : "them ").append("at "); - String when = "the beginning of the next end step."; - if (atEOT.endsWith("Combat")) { - when = "end of combat."; + + if (sa.hasParam("AddTriggers")) { + final String oDesc = sa.getDescription(); + final String trigStg = oDesc.contains("\"") ? + oDesc.substring(oDesc.indexOf("\""),oDesc.lastIndexOf("\"") + 1) : + "[trigger text parsing error]"; + if (addKWs) { + sb.append(" and ").append(trigStg); + } else { + sb.append(". ").append(justOne ? "It gains " : "They gain ").append(trigStg); + } + } else { + sb.append("."); + } + + if (sa.hasParam("AtEOT")) { + String atEOT = sa.getParam("AtEOT"); + String verb = "Sacrifice "; + if (atEOT.startsWith("Exile")) { + verb = "Exile "; + } + sb.append(" ").append(verb).append(justOne ? "it " : "them ").append("at "); + String when = "the beginning of the next end step."; + if (atEOT.endsWith("Combat")) { + when = "end of combat."; + } + sb.append(when); } - sb.append(when); } return sb.toString(); @@ -180,20 +188,21 @@ public class CopyPermanentEffect extends TokenEffectBase { tgtCards = choice; System.err.println("Copying random permanent(s): " + tgtCards.toString()); - } else if (sa.hasParam("DefinedName")) { - String name = sa.getParam("DefinedName"); - if (name.equals("NamedCard")) { - if (!host.getNamedCard().isEmpty()) { - name = host.getNamedCard(); - } + } + } else if (sa.hasParam("DefinedName")) { + List cards = Lists.newArrayList(StaticData.instance().getCommonCards().getUniqueCards()); + String name = sa.getParam("DefinedName"); + if (name.equals("NamedCard")) { + if (!host.getNamedCard().isEmpty()) { + name = host.getNamedCard(); } + } - Predicate cpp = Predicates.compose(CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard::getRules); - cards = Lists.newArrayList(Iterables.filter(cards, cpp)); + Predicate cpp = Predicates.compose(CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard::getRules); + cards = Lists.newArrayList(Iterables.filter(cards, cpp)); - if (!cards.isEmpty()) { - tgtCards.add(Card.fromPaperCard(cards.get(0), controller)); - } + if (!cards.isEmpty()) { + tgtCards.add(Card.fromPaperCard(cards.get(0), controller)); } } else if (sa.hasParam("Choices")) { Player chooser = activator; @@ -272,31 +281,42 @@ public class CopyPermanentEffect extends TokenEffectBase { } public static Card getProtoType(final SpellAbility sa, final Card original, final Player newOwner) { - final Card host = sa.getHostCard(); - int id = newOwner == null ? 0 : newOwner.getGame().nextCardId(); - // need to create a physical card first, i need the original card faces - final Card copy = CardFactory.getCard(original.getPaperCard(), newOwner, id, host.getGame()); + final Card copy; + if (sa.hasParam("DefinedName")) { + copy = original; + String name = TextUtil.fastReplace(TextUtil.fastReplace(original.getName(), ",", ""), " ", "_").toLowerCase(); + String set = sa.getOriginalHost().getSetCode(); + copy.getCurrentState().setRarity(CardRarity.Token); + copy.getCurrentState().setSetCode(set); + copy.getCurrentState().setImageKey(ImageKeys.getTokenKey(name + "_" + set.toLowerCase())); + } else { + final Card host = sa.getHostCard(); - copy.setTokenSpawningAbility(sa); - if (original.isTransformable()) { - // 707.8a If an effect creates a token that is a copy of a transforming permanent or a transforming double-faced card not on the battlefield, - // the resulting token is a transforming token that has both a front face and a back face. - // The characteristics of each face are determined by the copiable values of the same face of the permanent it is a copy of, as modified by any other copy effects that apply to that permanent. - // If the token is a copy of a transforming permanent with its back face up, the token enters the battlefield with its back face up. - // This rule does not apply to tokens that are created with their own set of characteristics and enter the battlefield as a copy of a transforming permanent due to a replacement effect. - copy.setBackSide(original.isBackSide()); - if (original.isTransformed()) { - copy.incrementTransformedTimestamp(); + int id = newOwner == null ? 0 : newOwner.getGame().nextCardId(); + // need to create a physical card first, i need the original card faces + copy = CardFactory.getCard(original.getPaperCard(), newOwner, id, host.getGame()); + if (original.isTransformable()) { + // 707.8a If an effect creates a token that is a copy of a transforming permanent or a transforming double-faced card not on the battlefield, + // the resulting token is a transforming token that has both a front face and a back face. + // The characteristics of each face are determined by the copiable values of the same face of the permanent it is a copy of, as modified by any other copy effects that apply to that permanent. + // If the token is a copy of a transforming permanent with its back face up, the token enters the battlefield with its back face up. + // This rule does not apply to tokens that are created with their own set of characteristics and enter the battlefield as a copy of a transforming permanent due to a replacement effect. + copy.setBackSide(original.isBackSide()); + if (original.isTransformed()) { + copy.incrementTransformedTimestamp(); + } + } + + copy.setStates(CardFactory.getCloneStates(original, copy, sa)); + // force update the now set State + if (original.isTransformable()) { + copy.setState(original.isTransformed() ? CardStateName.Transformed : CardStateName.Original, true, true); + } else { + copy.setState(copy.getCurrentStateName(), true, true); } } - copy.setStates(CardFactory.getCloneStates(original, copy, sa)); - // force update the now set State - if (original.isTransformable()) { - copy.setState(original.isTransformed() ? CardStateName.Transformed : CardStateName.Original, true, true); - } else { - copy.setState(copy.getCurrentStateName(), true, true); - } + copy.setTokenSpawningAbility(sa); copy.setGamePieceType(GamePieceType.TOKEN); return copy; diff --git a/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java index 0d9333ce947..31f38e3dd13 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java @@ -1,7 +1,5 @@ package forge.game.ability.effects; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; import forge.game.Game; import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; @@ -15,7 +13,7 @@ import forge.game.cost.CostPart; import forge.game.cost.CostReveal; import forge.game.player.Player; import forge.game.player.PlayerCollection; -import forge.game.spellability.LandAbility; + import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.game.zone.PlayerZone; @@ -94,7 +92,7 @@ public class DiscoverEffect extends SpellAbilityEffect { List sas = AbilityUtils.getBasicSpellsFromPlayEffect(found, p); // filter out land abilities due to MDFC or similar - Iterables.removeIf(sas, Predicates.instanceOf(LandAbility.class)); + sas.removeIf(sp -> sp.isLandAbility()); // the spell must also have a mana value equal to or less than the discover number sas.removeIf(sp -> sp.getPayCosts().getTotalMana().getCMC() > num); diff --git a/forge-game/src/main/java/forge/game/ability/effects/InternalRadiationEffect.java b/forge-game/src/main/java/forge/game/ability/effects/InternalRadiationEffect.java index acd621049aa..4d20ed979c3 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/InternalRadiationEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/InternalRadiationEffect.java @@ -35,7 +35,7 @@ public class InternalRadiationEffect extends SpellAbilityEffect { final CardCollectionView milled = game.getAction().mill(new PlayerCollection(p), numRad, ZoneType.Graveyard, sa, moveParams); table.triggerChangesZoneAll(game, sa); int n = CardLists.count(milled, Predicates.not(CardPredicates.Presets.LANDS)); - + if (StaticAbilityGainLifeRadiation.gainLifeRadiation(p)) { p.gainLife(n, sa.getHostCard(), sa); } else { @@ -49,7 +49,7 @@ public class InternalRadiationEffect extends SpellAbilityEffect { game.getTriggerHandler().runTrigger(TriggerType.LifeLostAll, runParams, false); } } - + // and remove n rad counter p.removeRadCounters(n); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java index 4ceb5ea64ad..70f41014817 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java @@ -39,7 +39,7 @@ import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementHandler; import forge.game.replacement.ReplacementLayer; import forge.game.spellability.AlternativeCost; -import forge.game.spellability.LandAbility; + import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityPredicates; import forge.game.zone.Zone; @@ -343,7 +343,7 @@ public class PlayEffect extends SpellAbilityEffect { final Zone originZone = tgtCard.getZone(); // lands will be played - if (tgtSA instanceof LandAbility) { + if (tgtSA.isLandAbility()) { tgtSA.resolve(); amount--; if (remember) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/PlayLandVariantEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PlayLandVariantEffect.java index 8e68bf65b3d..6361442621f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PlayLandVariantEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PlayLandVariantEffect.java @@ -57,7 +57,7 @@ public class PlayLandVariantEffect extends SpellAbilityEffect { PaperCard ran = Aggregates.random(cards); random = CardFactory.getCard(ran, activator, game); cards.remove(ran); - } while (!activator.canPlayLand(random, false)); + } while (!activator.canPlayLand(random, false, random.getFirstSpellAbility())); source.addCloneState(CardFactory.getCloneStates(random, source, sa), game.getNextTimestamp()); source.updateStateForView(); 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 6e73894e478..ddbf16e1a2f 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -5524,6 +5524,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return isInstant() || isSorcery() || (isAura() && !isInZone(ZoneType.Battlefield)); } + public final boolean hasPlayableLandFace() { return isLand() || (isModal() && getState(CardStateName.Modal).getType().isLand()); } + public final boolean isLand() { return getType().isLand(); } public final boolean isBasicLand() { return getType().isBasicLand(); } public final boolean isSnow() { return getType().isSnow(); } @@ -7430,7 +7432,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { for (SpellAbility sa : getState(CardStateName.Modal).getSpellAbilities()) { //add alternative costs as additional spell abilities // only add Spells there - if (sa.isSpell()) { + if (sa.isSpell() || sa.isLandAbility()) { abilities.add(sa); abilities.addAll(GameActionUtil.getAlternativeCosts(sa, player, false)); } @@ -7466,106 +7468,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } abilities.removeAll(toRemove); - // Land Abilities below, move them to CardFactory after MayPlayRefactor - if (getLastKnownZone().is(ZoneType.Battlefield)) { - return abilities; - } - if (getState(CardStateName.Original).getType().isLand()) { - LandAbility la = new LandAbility(this, player, null); - la.setCardState(oState); - if (la.canPlay()) { - abilities.add(la); - } - - Card source = this; - boolean lkicheck = false; - - // if Card is Facedown, need to check if MayPlay still applies - if (isFaceDown()) { - lkicheck = true; - source = CardCopyService.getLKICopy(source); - source.forceTurnFaceUp(); - } - - if (lkicheck) { - // double freeze tracker, so it doesn't update view - game.getTracker().freeze(); - CardCollection preList = new CardCollection(source); - game.getAction().checkStaticAbilities(false, Sets.newHashSet(source), preList); - } - - // extra for MayPlay - for (CardPlayOption o : source.mayPlay(player)) { - la = new LandAbility(this, player, o); - la.setCardState(oState); - if (la.canPlay()) { - abilities.add(la); - } - } - - // reset static abilities - if (lkicheck) { - game.getAction().checkStaticAbilities(false); - // clear delayed changes, this check should not have updated the view - game.getTracker().clearDelayed(); - // need to unfreeze tracker - game.getTracker().unfreeze(); - } - } - - if (isModal() && hasState(CardStateName.Modal)) { - CardState modal = getState(CardStateName.Modal); - if (modal.getType().isLand()) { - LandAbility la = new LandAbility(this, player, null); - la.setCardState(modal); - - Card source = CardCopyService.getLKICopy(this); - boolean lkicheck = true; - - // if Card is Facedown, need to check if MayPlay still applies - if (isFaceDown()) { - source.forceTurnFaceUp(); - } - - // the modal state is not copied with lki, need to copy it extra - if (!source.hasState(CardStateName.Modal)) { - source.addAlternateState(CardStateName.Modal, false); - source.getState(CardStateName.Modal).copyFrom(this.getState(CardStateName.Modal), true); - } - - source.setSplitStateToPlayAbility(la); - - if (la.canPlay(source)) { - abilities.add(la); - } - - if (lkicheck) { - // double freeze tracker, so it doesn't update view - game.getTracker().freeze(); - CardCollection preList = new CardCollection(source); - game.getAction().checkStaticAbilities(false, Sets.newHashSet(source), preList); - } - - // extra for MayPlay - for (CardPlayOption o : source.mayPlay(player)) { - la = new LandAbility(this, player, o); - la.setCardState(modal); - if (la.canPlay(source)) { - abilities.add(la); - } - } - - // reset static abilities - if (lkicheck) { - game.getAction().checkStaticAbilities(false); - // clear delayed changes, this check should not have updated the view - game.getTracker().clearDelayed(); - // need to unfreeze tracker - game.getTracker().unfreeze(); - } - } - } - return abilities; } 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 81885497755..dbf3ab681e5 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -413,17 +413,16 @@ public class CardFactory { // SpellPermanent only for Original State if (c.getCurrentStateName() == CardStateName.Original || c.getCurrentStateName() == CardStateName.Modal || c.getCurrentStateName().toString().startsWith("Specialize")) { - // this is the "default" spell for permanents like creatures and artifacts - if (c.isPermanent() && !c.isAura() && !c.isLand()) { + if (c.isLand()) { + SpellAbility sa = new LandAbility(c); + sa.setCardState(c.getCurrentState()); + c.addSpellAbility(sa); + } else if (c.isPermanent() && !c.isAura()) { + // this is the "default" spell for permanents like creatures and artifacts SpellAbility sa = new SpellPermanent(c); - - // Currently only for Modal, might react different when state is always set - //if (c.getCurrentStateName() == CardStateName.Modal) { - sa.setCardState(c.getCurrentState()); - //} + sa.setCardState(c.getCurrentState()); c.addSpellAbility(sa); } - // TODO add LandAbility there when refactor MayPlay } CardFactoryUtil.addAbilityFactoryAbilities(c, face.getAbilities()); diff --git a/forge-game/src/main/java/forge/game/card/CardPredicates.java b/forge-game/src/main/java/forge/game/card/CardPredicates.java index 5a75387682f..5e2289da035 100644 --- a/forge-game/src/main/java/forge/game/card/CardPredicates.java +++ b/forge-game/src/main/java/forge/game/card/CardPredicates.java @@ -22,7 +22,6 @@ import java.util.Comparator; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import forge.card.CardStateName; import forge.game.CardTraitBase; import forge.game.GameEntity; import forge.game.combat.CombatUtil; @@ -379,7 +378,7 @@ public final class CardPredicates { /** * a Predicate to get all lands. */ - public static final Predicate LANDS = c -> c.isLand() || (!c.isInZone(ZoneType.Battlefield) && c.isModal() && c.getState(CardStateName.Modal).getType().isLand()); + public static final Predicate LANDS = c -> c.isLand(); /** * a Predicate to get all mana-producing lands. */ 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 1cf780a538a..dd00c35e796 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -32,7 +32,7 @@ import forge.game.event.*; import forge.game.player.Player; import forge.game.replacement.ReplacementResult; import forge.game.replacement.ReplacementType; -import forge.game.spellability.LandAbility; + import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; @@ -1064,7 +1064,7 @@ public class PhaseHandler implements java.io.Serializable { final Zone currentZone = saHost.getZone(); // Need to check if Zone did change - if (currentZone != null && originZone != null && !currentZone.equals(originZone) && (sa.isSpell() || sa instanceof LandAbility)) { + if (currentZone != null && originZone != null && !currentZone.equals(originZone) && (sa.isSpell() || sa.isLandAbility())) { // currently there can be only one Spell put on the Stack at once, or Land Abilities be played final CardZoneTable triggerList = new CardZoneTable(game.getLastStateBattlefield(), game.getLastStateGraveyard()); triggerList.put(originZone.getZoneType(), currentZone.getZoneType(), saHost); 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 35f655d96f8..f51e1eab79c 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -43,7 +43,7 @@ import forge.game.replacement.ReplacementHandler; import forge.game.replacement.ReplacementResult; import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilitySub; -import forge.game.spellability.LandAbility; + import forge.game.spellability.SpellAbility; import forge.game.staticability.*; import forge.game.trigger.Trigger; @@ -1691,9 +1691,9 @@ public class Player extends GameEntity implements Comparable { game.fireEvent(new GameEventShuffle(this)); } - public final boolean playLand(final Card land, final boolean ignoreZoneAndTiming) { + public final boolean playLand(final Card land, final boolean ignoreZoneAndTiming, SpellAbility cause) { // Dakkon Blackblade Avatar will use a similar effect - if (canPlayLand(land, ignoreZoneAndTiming)) { + if (canPlayLand(land, ignoreZoneAndTiming, cause)) { playLandNoCheck(land, null); return true; } @@ -1706,7 +1706,7 @@ public class Player extends GameEntity implements Comparable { land.setController(this, 0); if (land.isFaceDown()) { land.turnFaceUp(null); - if (cause instanceof LandAbility) { + if (cause.isLandAbility()) { land.changeToState(cause.getCardStateName()); } } @@ -1730,12 +1730,6 @@ public class Player extends GameEntity implements Comparable { return c; } - public final boolean canPlayLand(final Card land) { - return canPlayLand(land, false); - } - public final boolean canPlayLand(final Card land, final boolean ignoreZoneAndTiming) { - return canPlayLand(land, ignoreZoneAndTiming, null); - } public final boolean canPlayLand(final Card land, final boolean ignoreZoneAndTiming, SpellAbility landSa) { if (!ignoreZoneAndTiming) { // CR 305.3 diff --git a/forge-game/src/main/java/forge/game/spellability/LandAbility.java b/forge-game/src/main/java/forge/game/spellability/LandAbility.java index f8901a57d76..588c06cc809 100644 --- a/forge-game/src/main/java/forge/game/spellability/LandAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/LandAbility.java @@ -21,24 +21,20 @@ import forge.card.CardStateName; import forge.card.mana.ManaCost; import forge.game.card.Card; import forge.game.card.CardCopyService; -import forge.game.card.CardPlayOption; -import forge.game.cost.Cost; import forge.game.player.Player; import forge.game.staticability.StaticAbility; +import forge.game.zone.ZoneType; import forge.util.CardTranslation; import forge.util.Localizer; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -public class LandAbility extends Ability { +public class LandAbility extends AbilityStatic { - public LandAbility(Card sourceCard, Player p, CardPlayOption mayPlay) { - super(sourceCard, new Cost(ManaCost.NO_COST, false)); - setActivatingPlayer(p); - setMayPlay(mayPlay); - } public LandAbility(Card sourceCard) { - this(sourceCard, sourceCard.getController(), null); + super(sourceCard, ManaCost.NO_COST); + + getRestrictions().setZone(ZoneType.Hand); } public boolean canPlay(Card newHost) { @@ -46,11 +42,21 @@ public class LandAbility extends Ability { return p.canPlayLand(newHost, false, this); } + @Override + public boolean isLandAbility() { return true; } + + @Override + public boolean isSecondary() { + return true; + } + @Override public boolean canPlay() { Card land = this.getHostCard(); final Player p = this.getActivatingPlayer(); - + if (p == null || land.isInZone(ZoneType.Battlefield)) { + return false; + } if (this.getCardState() != null && land.getCurrentStateName() != this.getCardStateName()) { if (!land.isLKI()) { land = CardCopyService.getLKICopy(land); @@ -113,4 +119,41 @@ public class LandAbility extends Ability { return sb.toString(); } + @Override + public Card getAlternateHost(Card source) { + boolean lkicheck = false; + + // need to be done before so it works with Vivien and Zoetic Cavern + if (source.isFaceDown() && source.isInZone(ZoneType.Exile)) { + if (!source.isLKI()) { + source = CardCopyService.getLKICopy(source); + } + + source.forceTurnFaceUp(); + lkicheck = true; + } + + if (getCardState() != null && source.getCurrentStateName() != getCardStateName()) { + if (!source.isLKI()) { + source = CardCopyService.getLKICopy(source); + } + CardStateName stateName = getCardState().getStateName(); + if (!source.hasState(stateName)) { + source.addAlternateState(stateName, false); + source.getState(stateName).copyFrom(getHostCard().getState(stateName), true); + } + + source.setState(stateName, false); + if (getHostCard().isDoubleFaced()) { + source.setBackSide(getHostCard().getRules().getSplitType().getChangedStateName().equals(stateName)); + } + + // need to reset CMC + source.setLKICMC(-1); + source.setLKICMC(source.getCMC()); + lkicheck = true; + } + + return lkicheck ? source : null; + } } \ No newline at end of file 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 32ff21ec841..c3cfcce3e9d 100644 --- a/forge-game/src/main/java/forge/game/spellability/Spell.java +++ b/forge-game/src/main/java/forge/game/spellability/Spell.java @@ -153,6 +153,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable this.castFaceDown = faceDown; } + @Override public Card getAlternateHost(Card source) { boolean lkicheck = false; diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 2429b3c0992..aa6bfafb962 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -527,6 +527,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit public boolean isSpell() { return false; } public boolean isAbility() { return true; } public boolean isActivatedAbility() { return false; } + public boolean isLandAbility() { return false; } public boolean isTurnFaceUp() { return isMorphUp() || isDisguiseUp() || isManifestUp() || isCloakUp(); @@ -2185,7 +2186,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } } else if (incR[0].contains("LandAbility")) { - if (!(root instanceof LandAbility)) { + if (!(root.isLandAbility())) { return testFailed; } } @@ -2544,7 +2545,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit if (getRestrictions().isInstantSpeed()) { return true; } - if ((isSpell() || this instanceof LandAbility) && (isCastFromPlayEffect() || host.isInstant() || host.hasKeyword(Keyword.FLASH))) { + if ((isSpell() || this.isLandAbility()) && (isCastFromPlayEffect() || host.isInstant() || host.hasKeyword(Keyword.FLASH))) { return true; } @@ -2589,6 +2590,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return true; } + public Card getAlternateHost(Card source) { + return null; + } + public boolean hasOptionalKeywordAmount(KeywordInterface kw) { return this.optionalKeywordAmount.contains(kw.getKeyword(), Pair.of(kw.getIdx(), kw.getStaticId())); } diff --git a/forge-gui-android/src/forge/app/Main.java b/forge-gui-android/src/forge/app/Main.java index ba243981c01..de4e9f9a10d 100644 --- a/forge-gui-android/src/forge/app/Main.java +++ b/forge-gui-android/src/forge/app/Main.java @@ -51,6 +51,7 @@ import com.badlogic.gdx.Version; import com.badlogic.gdx.backends.android.AndroidApplication; import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; import com.badlogic.gdx.backends.android.AndroidAudio; +import com.badlogic.gdx.backends.android.AsynchronousAndroidAudio; import com.getkeepsafe.relinker.ReLinker; import de.cketti.fileprovider.PublicFileProvider; import forge.Forge; @@ -122,7 +123,8 @@ public class Main extends AndroidApplication { @Override public AndroidAudio createAudio(Context context, AndroidApplicationConfiguration config) { - return super.createAudio(context, config); + return new AsynchronousAndroidAudio(context, config); + //return super.createAudio(context, config); } @Override diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/SpellAbilityPickerSimulationTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/SpellAbilityPickerSimulationTest.java index 367987c4f7d..df3a5b2d282 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/SpellAbilityPickerSimulationTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/SpellAbilityPickerSimulationTest.java @@ -1,6 +1,6 @@ package forge.ai.simulation; -import forge.game.spellability.LandAbility; + import java.util.ArrayList; import java.util.List; @@ -84,7 +84,7 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest { SpellAbilityPicker picker = new SpellAbilityPicker(game, p); SpellAbility sa = picker.chooseSpellAbilityToPlay(null); - AssertJUnit.assertTrue(sa instanceof LandAbility); + AssertJUnit.assertTrue(sa.isLandAbility()); AssertJUnit.assertEquals(mountain, sa.getHostCard()); Plan plan = picker.getPlan(); diff --git a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java index aa1c2f1f4ad..a4652e3ca8f 100644 --- a/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java +++ b/forge-gui-mobile/src/forge/adventure/character/EnemySprite.java @@ -324,7 +324,8 @@ public class EnemySprite extends CharacterSprite implements Steerable { if (_freeze){ //Mob has defeated player in battle, hold still until player has a chance to move away. //Without this moving enemies can immediately restart battle. - if (spriteToPlayer.len() < unfreezeRange) { + float distance = spriteToPlayer.len(); + if (distance < unfreezeRange) { timer += delta; return Vector2.Zero; } @@ -635,7 +636,8 @@ public class EnemySprite extends CharacterSprite implements Steerable { } - - + public boolean isFrozen() { + return _freeze; + } } diff --git a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java index 079a2fdfa43..6a564fd554c 100644 --- a/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java +++ b/forge-gui-mobile/src/forge/adventure/player/AdventurePlayer.java @@ -2,15 +2,19 @@ package forge.adventure.player; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Null; +import com.github.tommyettinger.textra.TextraLabel; import com.google.common.collect.Lists; import forge.Forge; import forge.adventure.data.*; import forge.adventure.pointofintrest.PointOfInterestChanges; import forge.adventure.scene.AdventureDeckEditor; import forge.adventure.scene.DeckEditScene; +import forge.adventure.stage.GameStage; import forge.adventure.stage.MapStage; +import forge.adventure.stage.WorldStage; import forge.adventure.util.*; import forge.adventure.world.WorldSave; import forge.card.ColorSet; @@ -223,6 +227,10 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return name; } + public Boolean isFemale() { + return isFemale; + } + public float getWorldPosX() { return worldPosX; } @@ -594,6 +602,24 @@ public class AdventurePlayer implements Serializable, SaveFileContent { return HeroListData.getRaces().get(Current.player().heroRace); } + public GameStage getCurrentGameStage() { + if (MapStage.getInstance().isInMap()) + return MapStage.getInstance(); + return WorldStage.getInstance(); + } + public void addStatusMessage(String iconName, String message, Integer itemCount, float x, float y) { + String symbol = itemCount == null || itemCount < 0 ? "" : " +"; + String icon = iconName == null ? "" : "[+" + iconName + "]"; + String count = itemCount == null ? "" : String.valueOf(itemCount); + TextraLabel actor = Controls.newTextraLabel("[%95]" + icon + "[WHITE]" + symbol + count + " " + message); + actor.setPosition(x, y); + 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); newCards.add(card); @@ -752,8 +778,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) { diff --git a/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java b/forge-gui-mobile/src/forge/adventure/scene/InventoryScene.java index 2f4ecc78bf6..442081fa5c1 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 diff --git a/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java b/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java index a0dd409be82..b00ab82d761 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/NewGameScene.java @@ -3,12 +3,12 @@ package forge.adventure.scene; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; import com.badlogic.gdx.scenes.scene2d.ui.TextField; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Array; -import com.github.tommyettinger.textra.TextraButton; import com.github.tommyettinger.textra.TextraLabel; import forge.Forge; import forge.adventure.data.DialogData; @@ -48,20 +48,20 @@ public class NewGameScene extends MenuScene { private final TextraLabel starterEditionLabel; private final Array custom; private final TextraLabel colorLabel; - private final TextraButton difficultyHelp; + private final ImageButton difficultyHelp; private DialogData difficultySummary; - private final TextraButton modeHelp; + private final ImageButton modeHelp; private DialogData modeSummary; + private final Random rand = new Random(); private final Array modes = new Array<>(); private NewGameScene() { super(Forge.isLandscapeMode() ? "ui/new_game.json" : "ui/new_game_portrait.json"); - gender = ui.findActor("gender"); selectedName = ui.findActor("nameField"); - selectedName.setText(NameGenerator.getRandomName(gender.getCurrentIndex() > 0 ? "Female" : "Male", "Any", "")); + generateName(); avatarImage = ui.findActor("avatarPreview"); mode = ui.findActor("mode"); modeHelp = ui.findActor("modeHelp"); @@ -127,13 +127,12 @@ public class NewGameScene extends MenuScene { modeNames[i] = modes.get(i).getName(); mode.setTextList(modeNames); - gender.setTextList(new String[]{Forge.getLocalizer().getMessage("lblMale"), Forge.getLocalizer().getMessage("lblFemale")}); + gender.setTextList(new String[]{Forge.getLocalizer().getMessage("lblMale") + "[%120][CYAN] \u2642", + Forge.getLocalizer().getMessage("lblFemale") + "[%120][MAGENTA] \u2640"}); gender.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - //gender should be either Male or Female - String val = gender.getCurrentIndex() > 0 ? "Female" : "Male"; - selectedName.setText(NameGenerator.getRandomName(val, "Any", "")); + nameTT = 0.8f; super.clicked(event, x, y); } }); @@ -150,6 +149,13 @@ public class NewGameScene extends MenuScene { } }); race = ui.findActor("race"); + race.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + avatarTT = 0.7f; + super.clicked(event, x, y); + } + }); race.addListener(event -> NewGameScene.this.updateAvatar()); race.setTextList(HeroListData.getRaces()); difficulty = ui.findActor("difficulty"); @@ -161,15 +167,13 @@ public class NewGameScene extends MenuScene { for (DifficultyData diff : Config.instance().getConfigData().difficulties) { if (diff.startingDifficulty) startingDifficulty = i; - diffList.add(Forge.getLocalizer().getInstance().getMessageorUseDefault("lbl" + diff.name, diff.name)); + diffList.add(Forge.getLocalizer().getMessageorUseDefault("lbl" + diff.name, diff.name)); i++; } difficulty.setTextList(diffList); difficulty.setCurrentIndex(startingDifficulty); - Random rand = new Random(); - avatarIndex = rand.nextInt(); - updateAvatar(); + generateAvatar(); gender.setCurrentIndex(rand.nextInt()); colorId.setCurrentIndex(rand.nextInt()); race.setCurrentIndex(rand.nextInt()); @@ -177,8 +181,16 @@ public class NewGameScene extends MenuScene { ui.onButtonPress("start", NewGameScene.this::start); ui.onButtonPress("leftAvatar", NewGameScene.this::leftAvatar); ui.onButtonPress("rightAvatar", NewGameScene.this::rightAvatar); - difficultyHelp.addListener(new ClickListener(){ public void clicked(InputEvent e, float x, float y){ showDifficultyHelp(); }}); - modeHelp.addListener(new ClickListener(){ public void clicked(InputEvent e, float x, float y){ showModeHelp(); }}); + difficultyHelp.addListener(new ClickListener() { + public void clicked(InputEvent e, float x, float y) { + showDifficultyHelp(); + } + }); + modeHelp.addListener(new ClickListener() { + public void clicked(InputEvent e, float x, float y) { + showModeHelp(); + } + }); } private static NewGameScene object; @@ -189,6 +201,37 @@ public class NewGameScene extends MenuScene { return object; } + float avatarT = 1f, avatarTT = 1f; + float nameT = 1f, nameTT = 1f; + + @Override + public void act(float delta) { + super.act(delta); + if (avatarT > avatarTT) { + avatarTT += (delta / 0.5f); + generateAvatar(); + } else { + avatarTT = avatarT; + } + if (nameT > nameTT) { + nameTT += (delta / 0.5f); + generateName(); + } else { + nameTT = nameT; + } + } + + private void generateAvatar() { + avatarIndex = rand.nextInt(); + updateAvatar(); + } + + private void generateName() { + //gender should be either Male or Female + String val = gender.getCurrentIndex() > 0 ? "Female" : "Male"; + selectedName.setText(NameGenerator.getRandomName(val, "Any", "")); + } + boolean started = false; public boolean start() { @@ -196,7 +239,7 @@ public class NewGameScene extends MenuScene { return true; started = true; if (selectedName.getText().isEmpty()) { - selectedName.setText(NameGenerator.getRandomName("Any", "Any", "")); + generateName(); } Runnable runnable = () -> { started = false; @@ -295,11 +338,11 @@ public class NewGameScene extends MenuScene { dismiss.name = "OK"; DialogData matchImpacts = new DialogData(); - matchImpacts.text = String.format("Difficulty: %s\nStarting Life: %d\nEnemy Health: %d%%\nGold loss on defeat: %d%%\nLife loss on defeat: %d%%", selectedDifficulty.name, selectedDifficulty.startingLife, (int)(selectedDifficulty.enemyLifeFactor * 100) , (int)(selectedDifficulty.goldLoss*100), (int)(selectedDifficulty.lifeLoss*100)); + matchImpacts.text = String.format("Difficulty: %s\nStarting Life: %d\nEnemy Health: %d%%\nGold loss on defeat: %d%%\nLife loss on defeat: %d%%", selectedDifficulty.name, selectedDifficulty.startingLife, (int) (selectedDifficulty.enemyLifeFactor * 100), (int) (selectedDifficulty.goldLoss * 100), (int) (selectedDifficulty.lifeLoss * 100)); matchImpacts.name = "Duels"; DialogData economyImpacts = new DialogData(); - economyImpacts.text = String.format("Difficulty: %s\nStarting Gold: %d\nStarting Mana Shards: %d\nCard Sale Price: %d%%\nMana Shard Sale Price: %d%%\nRandom loot rate: %d%%", selectedDifficulty.name, selectedDifficulty.staringMoney, selectedDifficulty.startingShards, (int)(selectedDifficulty.sellFactor*100), (int)(selectedDifficulty.shardSellRatio*100), (int)(selectedDifficulty.rewardMaxFactor*100)); + economyImpacts.text = String.format("Difficulty: %s\nStarting Gold: %d\nStarting Mana Shards: %d\nCard Sale Price: %d%%\nMana Shard Sale Price: %d%%\nRandom loot rate: %d%%", selectedDifficulty.name, selectedDifficulty.staringMoney, selectedDifficulty.startingShards, (int) (selectedDifficulty.sellFactor * 100), (int) (selectedDifficulty.shardSellRatio * 100), (int) (selectedDifficulty.rewardMaxFactor * 100)); economyImpacts.name = "Economy"; difficultySummary.options = new DialogData[3]; diff --git a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java index c95d826a21a..1f010a15269 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/PlayerStatisticScene.java @@ -12,6 +12,7 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Scaling; import com.github.tommyettinger.textra.TextraButton; import com.github.tommyettinger.textra.TextraLabel; +import com.github.tommyettinger.textra.TypingLabel; import forge.Forge; import forge.adventure.character.EnemySprite; import forge.adventure.data.EnemyData; @@ -44,7 +45,8 @@ public class PlayerStatisticScene extends UIScene { TextraLabel wins, totalWins, eventWins, eventMatchWins; TextraLabel loss, totalLoss, eventLosses, eventMatchLosses; TextraLabel winloss, lossWinRatio, eventLossWinRatio, eventMatchLossWinRatio; - TextraLabel playerName, headerAchievements, headerAvatar, headerName, headerWinLoss; + TextraLabel headerAchievements, headerAvatar, headerName, headerWinLoss; + TypingLabel playerName; TextraButton back, toggleAward; private final Table scrollContainer, achievementContainer; TextraLabel blessingScroll; @@ -196,7 +198,9 @@ public class PlayerStatisticScene extends UIScene { scrollContainer.clear(); if (playerName != null) { - playerName.setText(GamePlayerUtil.getGuiPlayer().getName()); + String gender = Current.player().isFemale() ? "{GRADIENT=MAGENTA;MAUVE;1;1}\u2640{ENDGRADIENT}[BLACK] " : "{GRADIENT=CYAN;BLUE;1;1}\u2642{ENDGRADIENT}[BLACK] "; + playerName.setText(gender + GamePlayerUtil.getGuiPlayer().getName()); + playerName.skipToTheEnd(); } if (avatar != null) { avatar.setDrawable(new TextureRegionDrawable(Current.player().avatar())); diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java index 091106d08c7..0b4200c2ada 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; @@ -47,11 +68,11 @@ public class GameHUD extends Stage { static public GameHUD instance; private final GameStage gameStage; private final Image avatar, miniMapPlayer; - private final TextraLabel lifePoints; - private final TextraLabel money; - private final TextraLabel shards; + private final TypingLabel lifePoints; + private final TypingLabel money; + private final TypingLabel shards; private final TextraLabel keys; - private TextraLabel notificationText = Controls.newTextraLabel(""); + private final TextraLabel notificationText = Controls.newTextraLabel(""); private final Image miniMap, gamehud, mapborder, avatarborder, blank; private final InputEvent eventTouchDown, eventTouchUp; private final TextraButton deckActor, openMapActor, menuActor, logbookActor, inventoryActor, exitToWorldMapActor, bookmarkActor; @@ -60,7 +81,7 @@ public class GameHUD extends Stage { private final Console console; float TOUCHPAD_SCALE = 70f, referenceX; float opacity = 1f; - private boolean debugMap, updatelife; + 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()); @@ -129,32 +154,50 @@ public class GameHUD extends Stage { ui.onButtonPress("exittoworldmap", this::exitToWorldMap); ui.onButtonPress("bookmark", this::bookmark); lifePoints = ui.findActor("lifePoints"); + lifePoints.skipToTheEnd(); shards = ui.findActor("shards"); + shards.skipToTheEnd(); money = ui.findActor("money"); - shards.setText("[%95][+Shards] 0"); - money.setText("[%95][+Gold] "); - lifePoints.setText("[%95][+Life] 20/20"); + money.skipToTheEnd(); + shards.setText("[%95][+Shards]"); + money.setText("[%95][+Gold]"); + lifePoints.setText("[%95][+Life]"); keys = Controls.newTextraLabel(""); scrollPane = new ScrollPane(keys); scrollPane.setPosition(2, 2); scrollPane.setStyle(Controls.getSkin().get("translucent", ScrollPane.ScrollPaneStyle.class)); addActor(scrollPane); - AdventurePlayer.current().onLifeChange(() -> lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife())); - AdventurePlayer.current().onShardsChange(() -> shards.setText("[%95][+Shards] " + AdventurePlayer.current().getShards())); + AdventurePlayer.current().onLifeChange(() -> { + String effect = "{EMERGE}"; + String effectEnd = "{ENDEMERGE}"; + String heartbeat = ""; + //colored lifepoints + if (Current.player().getLife() >= Current.player().getMaxLife()) { + //color green if max life + lifepointsTextColor = "[GREEN]"; + } else if (Current.player().getLife() <= 5) { + //color red if critical + effect = ""; + effectEnd = ""; + heartbeat = "{HEARTBEAT=0.5;0.5}"; + lifepointsTextColor = "{ENDHEARTBEAT}[RED]"; + } else { + lifepointsTextColor = "[WHITE]"; + } + 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() + "{ENDEMERGE}")); + AdventurePlayer.current().onGoldChange(() -> money.restart("[%95][+Gold]{EMERGE} " + AdventurePlayer.current().getGold() + "{ENDEMERGE}")); AdventurePlayer.current().onEquipmentChanged(this::updateAbility); - - WorldSave.getCurrentSave().getPlayer().onGoldChange(() -> money.setText("[%95][+Gold] " + AdventurePlayer.current().getGold())); addActor(ui); addActor(miniMapPlayer); console = new Console(); 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(); @@ -166,11 +209,36 @@ 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() { @@ -268,7 +336,6 @@ public class GameHUD extends Stage { @Override public void draw() { - updatelife = false; int yPos = (int) gameStage.player.getY(); int xPos = (int) gameStage.player.getX(); act(Gdx.graphics.getDeltaTime()); //act the Hud @@ -278,32 +345,10 @@ 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 - //colored lifepoints - if (Current.player().getLife() >= Current.player().getMaxLife()) { - //color green if max life - if (!lifepointsTextColor.equals("[GREEN]")) { - lifepointsTextColor = "[GREEN]"; - updatelife = true; - } - } else if (Current.player().getLife() <= 5) { - //color red if critical - if (!lifepointsTextColor.equals("[RED]")) { - lifepointsTextColor = "[RED]"; - updatelife = true; - } - } else { - if (!lifepointsTextColor.isEmpty()) { - lifepointsTextColor = ""; - updatelife = true; - } - } - if (updatelife) { - updatelife = false; - lifePoints.setText("[%95][+Life]" + lifepointsTextColor + " " + AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife()); - } + if (!MapStage.getInstance().isInMap()) updateMusic(); else @@ -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() { @@ -663,11 +709,6 @@ public class GameHUD extends Stage { 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,38 +719,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); - setVisibility(lifePoints, visible); - setVisibility(shards, visible); - setVisibility(money, visible); - setVisibility(blank, visible); - setDisabled(exitToWorldMapActor, !MapStage.getInstance().isInMap(), "[%120][+ExitToWorldMap]", "---"); - setDisabled(bookmarkActor, !MapStage.getInstance().isInMap(), "[%120][+Bookmark]", "---"); - setAlpha(avatarborder, visible); - setAlpha(avatar, visible); - setAlpha(deckActor, visible); - setAlpha(menuActor, visible); - setAlpha(logbookActor, visible); - setAlpha(inventoryActor, visible); - setAlpha(exitToWorldMapActor, visible); - setAlpha(bookmarkActor, visible); + transluscent = !visible; + setAlpha(mapGroup, visible); + setAlpha(hudGroup, visible); + setAlpha(menuGroup, visible); + setAlpha(avatarGroup, visible); + + setDisabled(exitToWorldMapActor, !MapStage.getInstance().isInMap(), "[%120][+ExitToWorldMap]", "\uFF0F"); + setDisabled(bookmarkActor, !MapStage.getInstance().isInMap(), "[%120][+Bookmark]", "\uFF0F"); + 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()) { @@ -810,8 +883,8 @@ public class GameHUD extends Stage { public boolean act(float v) { if (exitDungeon) { MapStage.getInstance().exitDungeon(); - setDisabled(exitToWorldMapActor, true, "[%120][+ExitToWorldMap]", "---"); - setDisabled(bookmarkActor, true, "[%120][+Bookmark]", "---"); + setDisabled(exitToWorldMapActor, true, "[%120][+ExitToWorldMap]", "\uFF0F"); + setDisabled(bookmarkActor, true, "[%120][+Bookmark]", "\uFF0F"); } return true; } @@ -861,9 +934,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() { @@ -927,13 +1012,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(); @@ -948,22 +1033,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/MapStage.java b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java index 4d2d6ff2be1..42928ee39f8 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/MapStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/MapStage.java @@ -27,6 +27,7 @@ import com.github.tommyettinger.textra.TypingLabel; import forge.Forge; import forge.adventure.character.*; import forge.adventure.data.*; +import forge.adventure.player.AdventurePlayer; import forge.adventure.pointofintrest.PointOfInterestChanges; import forge.adventure.scene.*; import forge.adventure.util.*; @@ -959,10 +960,11 @@ public class MapStage extends GameStage { } else { Vector2 destination = mob.getTargetVector(player, verticesNearPlayer, delta); - if (destination.epsilonEquals(mob.pos()) && !mob.aggro) { + if (mob.isFrozen() || (destination.epsilonEquals(mob.pos()) && !mob.aggro)) { mob.setAnimation(CharacterSprite.AnimationTypes.Idle); continue; } + if (destination.equals(mob.targetVector) && mob.getNavPath() != null) navPath = mob.getNavPath(); @@ -1025,20 +1027,42 @@ public class MapStage extends GameStage { Gdx.input.vibrate(50); if (Controllers.getCurrent() != null && Controllers.getCurrent().canVibrate()) Controllers.getCurrent().startVibration(100, 1); - startPause(0.1f, () -> { //Switch to item pickup scene. - RewardSprite RS = (RewardSprite) actor; - RewardScene.instance().loadRewards(RS.getRewards(), RewardScene.Type.Loot, null); - RS.remove(); - actors.removeValue(RS, true); - changes.deleteObject(RS.getId()); - Forge.switchScene(RewardScene.instance()); - }); + RewardSprite RS = (RewardSprite) actor; + Array rewards = RS.getRewards(); + + if (rewards.size == 1) { + Reward reward = rewards.get(0); + switch (reward.getType()) { + case Life: + case Shards: + case Gold: + String message = Forge.getLocalizer().getMessageorUseDefault("lbl" + reward.getType().name(), reward.getType().name()); + AdventurePlayer.current().addStatusMessage(reward.getType().name(), message, reward.getCount(), actor.getX(), actor.getY() + player.getHeight()); + AdventurePlayer.current().addReward(reward); + break; + default: + showRewardScene(rewards); + break; + } + } else { + showRewardScene(rewards); + } + RS.remove(); + actors.removeValue(RS, true); + changes.deleteObject(RS.getId()); break; } } } } + private void showRewardScene(Array rewards) { + startPause(0.1f, () -> { + RewardScene.instance().loadRewards(rewards, RewardScene.Type.Loot, null); + Forge.switchScene(RewardScene.instance()); + }); + } + boolean started = false; public void beginDuel(EnemySprite mob) { if (mob == null) return; 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/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/util/BlurUtils.java b/forge-gui-mobile/src/forge/util/BlurUtils.java index 087995c1b07..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, height, 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/config.json b/forge-gui/res/adventure/common/config.json index c2e7ae5027d..d389636df14 100644 --- a/forge-gui/res/adventure/common/config.json +++ b/forge-gui/res/adventure/common/config.json @@ -66,7 +66,14 @@ "UNH", "PPC1", "UND", - "PUST" + "PUST", + "UEPHI23", + "UEMIN23", + "UELAS23", + "UEIND23", + "UEBAR23", + "MB2", + "UNF" ], "difficulties": [ { 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..c273c933bd3 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 @@ -6,7 +6,8 @@ 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. 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/skin/ui_skin.json b/forge-gui/res/adventure/common/skin/ui_skin.json index 823c89333bb..4a2bb85a668 100644 --- a/forge-gui/res/adventure/common/skin/ui_skin.json +++ b/forge-gui/res/adventure/common/skin/ui_skin.json @@ -458,6 +458,11 @@ "down": "right_down", "focused": "right_f" }, + "roundhint": { + "up": "unpressedround", + "down": "pressedround", + "focused": "unpressedround" + }, "item_frame": { "imageCheckedOver": "item_frame_selected_hover", "up": "item_frame", diff --git a/forge-gui/res/adventure/common/skin/ui_skin.png b/forge-gui/res/adventure/common/skin/ui_skin.png index f11f48b346b..67ddef59216 100644 Binary files a/forge-gui/res/adventure/common/skin/ui_skin.png and b/forge-gui/res/adventure/common/skin/ui_skin.png differ diff --git a/forge-gui/res/adventure/common/ui/hud.json b/forge-gui/res/adventure/common/ui/hud.json index b1521c98667..8650ab30893 100644 --- a/forge-gui/res/adventure/common/ui/hud.json +++ b/forge-gui/res/adventure/common/ui/hud.json @@ -56,7 +56,7 @@ "y": 10 }, { - "type": "Label", + "type": "TypingLabel", "name": "lifePoints", "font": "default", "width": 64, @@ -65,7 +65,7 @@ "y": 56 }, { - "type": "Label", + "type": "TypingLabel", "name": "shards", "font": "default", "width": 64, @@ -74,7 +74,7 @@ "y": 70 }, { - "type": "Label", + "type": "TypingLabel", "name": "money", "font": "default", "width": 64, diff --git a/forge-gui/res/adventure/common/ui/hud_landscape.json b/forge-gui/res/adventure/common/ui/hud_landscape.json index ece911e40b7..3bf3db4726d 100644 --- a/forge-gui/res/adventure/common/ui/hud_landscape.json +++ b/forge-gui/res/adventure/common/ui/hud_landscape.json @@ -56,7 +56,7 @@ "y": 10 }, { - "type": "Label", + "type": "TypingLabel", "name": "lifePoints", "font": "default", "width": 64, @@ -65,7 +65,7 @@ "y": 56 }, { - "type": "Label", + "type": "TypingLabel", "name": "shards", "font": "default", "width": 64, @@ -74,7 +74,7 @@ "y": 70 }, { - "type": "Label", + "type": "TypingLabel", "name": "money", "font": "default", "width": 64, diff --git a/forge-gui/res/adventure/common/ui/hud_portrait.json b/forge-gui/res/adventure/common/ui/hud_portrait.json index d345e47c81a..c3363b314b3 100644 --- a/forge-gui/res/adventure/common/ui/hud_portrait.json +++ b/forge-gui/res/adventure/common/ui/hud_portrait.json @@ -56,7 +56,7 @@ "y": 10 }, { - "type": "Label", + "type": "TypingLabel", "name": "lifePoints", "width": 48, "height": 3, @@ -64,7 +64,7 @@ "y": 62 }, { - "type": "Label", + "type": "TypingLabel", "name": "shards", "font": "default", "width": 48, @@ -73,7 +73,7 @@ "y": 76 }, { - "type": "Label", + "type": "TypingLabel", "name": "money", "font": "default", "width": 48, diff --git a/forge-gui/res/adventure/common/ui/new_game.json b/forge-gui/res/adventure/common/ui/new_game.json index b5449cf0f3a..8fabf16c6f5 100644 --- a/forge-gui/res/adventure/common/ui/new_game.json +++ b/forge-gui/res/adventure/common/ui/new_game.json @@ -65,14 +65,14 @@ "yOffset": 8 }, { - "type": "TextButton", + "type": "ImageButton", "name": "difficultyHelp", - "text": "[GOLD]?", + "style": "roundhint", "selectable": true, - "width": 16, - "height": 16, + "width": 12, + "height": 15, "x": 145, - "yOffset": -16 + "yOffset": -17 }, { "type": "Label", @@ -93,14 +93,14 @@ "yOffset": 8 }, { - "type": "TextButton", + "type": "ImageButton", "name": "modeHelp", - "text": "[GOLD]?", + "style": "roundhint", "selectable": true, - "width": 16, - "height": 16, + "width": 12, + "height": 15, "x": 145, - "yOffset": -16 + "yOffset": -17 }, { "type": "Label", diff --git a/forge-gui/res/adventure/common/ui/new_game_portrait.json b/forge-gui/res/adventure/common/ui/new_game_portrait.json index b6bf4453c41..a04cfe2b010 100644 --- a/forge-gui/res/adventure/common/ui/new_game_portrait.json +++ b/forge-gui/res/adventure/common/ui/new_game_portrait.json @@ -35,7 +35,7 @@ "width": 128, "height": 24, "x": 16, - "y": 140 + "y": 148 }, { "type": "Label", @@ -65,14 +65,14 @@ "yOffset": 8 }, { - "type": "TextButton", + "type": "ImageButton", "name": "difficultyHelp", - "text": "[GOLD]?", + "style": "roundhint", "selectable": true, - "width": 24, - "height": 24, - "x": 72, - "yOffset": -24 + "width": 12, + "height": 15, + "x": 80, + "yOffset": -17 }, { "type": "Label", @@ -93,14 +93,14 @@ "yOffset": 8 }, { - "type": "TextButton", + "type": "ImageButton", "name": "modeHelp", - "text": "[GOLD]?", + "style": "roundhint", "selectable": true, - "width": 24, - "height": 24, - "x": 72, - "yOffset": -24 + "width": 12, + "height": 15, + "x": 80, + "yOffset": -17 }, { "type": "Label", diff --git a/forge-gui/res/adventure/common/ui/statistic.json b/forge-gui/res/adventure/common/ui/statistic.json index 1feba1b9185..b8e84cecf1d 100644 --- a/forge-gui/res/adventure/common/ui/statistic.json +++ b/forge-gui/res/adventure/common/ui/statistic.json @@ -37,7 +37,7 @@ { "type": "Image", "name": "avatar", - "x": 321, + "x": 384, "y": 28, "width": 64, "height": 64 @@ -46,7 +46,7 @@ "type": "Image", "name": "colorFrame", "image": "ui/colorC.png", - "x": 305, + "x": 368, "y": 45, "width": 64, "height": 64 @@ -137,9 +137,9 @@ "y": 224 }, { - "type": "Label", + "type": "TypingLabel", "name": "playerName", - "x": 394, + "x": 310, "y": 20, "width": 80, "height": 24, @@ -150,7 +150,7 @@ "name": "lifePoints", "width": 64, "height": 16, - "x": 394, + "x": 310, "y": 40 }, { @@ -158,7 +158,7 @@ "name": "money", "width": 64, "height": 16, - "x": 394, + "x": 310, "y": 80 }, { @@ -166,7 +166,7 @@ "name": "shards", "width": 64, "height": 16, - "x": 394, + "x": 310, "y": 60 }, { diff --git a/forge-gui/res/adventure/common/ui/statistic_portrait.json b/forge-gui/res/adventure/common/ui/statistic_portrait.json index 3f8b45b6187..2e7f09f5b85 100644 --- a/forge-gui/res/adventure/common/ui/statistic_portrait.json +++ b/forge-gui/res/adventure/common/ui/statistic_portrait.json @@ -136,7 +136,7 @@ "y": 440 }, { - "type": "Label", + "type": "TypingLabel", "name": "playerName", "x": 98, "y": 4, diff --git a/forge-gui/res/cardsfolder/a/anax_and_cymede_and_kynaios_and_tiro.txt b/forge-gui/res/cardsfolder/a/anax_and_cymede_and_kynaios_and_tiro.txt new file mode 100644 index 00000000000..34d261e7d11 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/anax_and_cymede_and_kynaios_and_tiro.txt @@ -0,0 +1,12 @@ +Name:Anax and Cymede and Kynaios and Tiro +ManaCost:1 W U R G +Types:Legendary Creature Human Soldier +PT:3/8 +K:First Strike +K:Vigilance +T:Mode$ SpellCast | ValidActivatingPlayer$ You | TargetsValid$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Heroic — Whenever you cast a spell that targets CARDNAME, draw a card. Each player may put a land card from their hand onto the battlefield, then each opponent who didn't draws a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ EachPlayLand +SVar:EachPlayLand:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Land | DefinedPlayer$ Player | ChangeNum$ 1 | RememberChanged$ True | SubAbility$ DrawAbstainers +SVar:DrawAbstainers:DB$ Draw | Defined$ OppNonRememberedOwner | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:First strike, vigilance\nHeroic — Whenever you cast a spell that targets Anax and Cymede and Kynaios and Tiro, draw a card. Each player may put a land card from their hand onto the battlefield, then each opponent who didn't draws a card. diff --git a/forge-gui/res/cardsfolder/a/artifact_unknown_shores.txt b/forge-gui/res/cardsfolder/a/artifact_unknown_shores.txt new file mode 100644 index 00000000000..0cc0c8693cb --- /dev/null +++ b/forge-gui/res/cardsfolder/a/artifact_unknown_shores.txt @@ -0,0 +1,8 @@ +Name:Artifact Unknown Shores +ManaCost:no cost +Types:Artifact Land +A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. +A:AB$ Mana | Cost$ 1 T | Produced$ Any | SpellDescription$ Add one mana of any color. +AI:RemoveDeck:Random +DeckHas:Ability$Mana.Colorless +Oracle:{T}: Add {C}.\n{1}, {T}: Add one mana of any color. diff --git a/forge-gui/res/cardsfolder/a/avacyn_and_griselbrand.txt b/forge-gui/res/cardsfolder/a/avacyn_and_griselbrand.txt new file mode 100644 index 00000000000..829d5609634 --- /dev/null +++ b/forge-gui/res/cardsfolder/a/avacyn_and_griselbrand.txt @@ -0,0 +1,11 @@ +Name:Avacyn and Griselbrand +ManaCost:4 W W B B +Types:Legendary Creature Angel Demon +PT:8/8 +K:Flying +K:Vigilance +K:Lifelink +A:AB$ PumpAll | Cost$ PayLife<8> | ValidCards$ Creature.YouCtrl | KW$ Indestructible | SubAbility$ DBDraw | SpellDescription$ Each creature you control gains indestructible until end of turn. Then, draw a card for each creature you control. +SVar:DBDraw:DB$ Draw | NumCards$ X +SVar:X:Count$TypeYouCtrl.Creature +Oracle:Flying, vigilance, lifelink\nPay 8 life: Each creature you control gains indestructible until end of turn. Then, draw a card for each creature you control. diff --git a/forge-gui/res/cardsfolder/b/believe_in_the_cleave.txt b/forge-gui/res/cardsfolder/b/believe_in_the_cleave.txt new file mode 100644 index 00000000000..c8eeb1c6a11 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/believe_in_the_cleave.txt @@ -0,0 +1,7 @@ +Name:Believe in the Cleave +ManaCost:3 R +Types:Instant +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ CARDNAME costs {1} less to cast for each attacking creature you control. +SVar:X:Count$Valid Creature.attacking+YouCtrl +A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 1 | NumDef$ 1 | KW$ Double Strike | SpellDescription$ Target creature gets +1/+1 and gains double strike until end of turn. | StackDescription$ SpellDescription +Oracle:Believe in the Cleave costs {1} less to cast for each attacking creature you control.\nTarget creature gets +1/+1 and gains double strike until end of turn. diff --git a/forge-gui/res/cardsfolder/b/bram_baguette_brawler.txt b/forge-gui/res/cardsfolder/b/bram_baguette_brawler.txt new file mode 100644 index 00000000000..459fbf389e2 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/bram_baguette_brawler.txt @@ -0,0 +1,11 @@ +Name:Bram, Baguette Brawler +ManaCost:1 W +Types:Legendary Creature Human Peasant +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_food_sac | TokenOwner$ You +S:Mode$ Continuous | Affected$ Food.nonCreature+YouCtrl | AddType$ Equipment | AddStaticAbility$ FoodEquip | AddKeyword$ Equip:1 | Description$ Each noncreature Food you control is an Equipment with equip {1} and "Equipped creature gets +1/+1." +SVar:FoodEquip:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Equipped creature gets +1/+1. +DeckHas:Ability$Token|Sacrifice & Type$Food|Artifact|Equipment +DeckHints:Type$Food +Oracle:When Bram, Baguette Brawler enters the battlefield, create a Food token.\nEach noncreature Food you control is an Equipment with equip {1} and "Equipped creature gets +1/+1." diff --git a/forge-gui/res/cardsfolder/b/bringer_of_green_zeniths_twilight.txt b/forge-gui/res/cardsfolder/b/bringer_of_green_zeniths_twilight.txt new file mode 100644 index 00000000000..b78c29c0a19 --- /dev/null +++ b/forge-gui/res/cardsfolder/b/bringer_of_green_zeniths_twilight.txt @@ -0,0 +1,14 @@ +Name:Bringer of Green Zenith's Twilight +ManaCost:X G G +Types:Creature Phyrexian Bringer +PT:2/2 +S:Mode$ AlternativeCost | ValidSA$ Spell.Self | EffectZone$ All | Cost$ W U B R G | Description$ You may pay {W}{U}{B}{R}{G} rather than pay this spell's mana cost. If you do, X is 5. +K:etbCounter:P1P1:Y:no condition:CARDNAME enters the battlefield with X +1/+1 counters on it. If X was 5 or greater, it enters with twice that many counters instead. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME dies, shuffle it into its owner's library. +SVar:TrigChange:DB$ ChangeZone | Destination$ Library | Shuffle$ True | Defined$ TriggeredNewCardLKICopy +SVar:X:Count$xPaid +SVar:AltCostPaid:Count$AltCost.5.X +SVar:Y:Count$Compare AltCostPaid LT5.AltCostPaid.Z +SVar:Z:SVar$AltCostPaid/Twice +DeckHas:Ability$Counters +Oracle:You may pay {W}{U}{B}{R}{G} rather than pay this spell's mana cost. If you do, X is 5.\nBringer of Green Zenith's Twilight enters the battlefield with X +1/+1 counters on it. If X was 5 or greater, it enters with twice that many counters instead.\nWhen Bringer of Green Zenith's Twilight dies, shuffle it into its owner's library. diff --git a/forge-gui/res/cardsfolder/c/cat_oven.txt b/forge-gui/res/cardsfolder/c/cat_oven.txt new file mode 100644 index 00000000000..d90e3777c76 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/cat_oven.txt @@ -0,0 +1,12 @@ +Name:Cat Oven +ManaCost:1 +Types:Artifact +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigFood | TriggerDescription$ When CARDNAME enters the battlefield, create a Food token. +SVar:TrigFood:DB$ Token | TokenScript$ c_a_food_sac | TokenAmount$ 1 +A:AB$ Token | Cost$ T Sac<1/Food> | TokenScript$ b_1_1_cat | TokenAmount$ 1 | SubAbility$ DBDrain | SpellDescription$ Create a 1/1 black Cat creature token. Each opponent loses 1 life and you gain 1 life. +SVar:DBDrain:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 +SVar:AIPreference:SacCost$Food.token +DeckHas:Ability$Token|Sacrifice|LifeGain & Type$Food|Artifact|Cat +DeckHints:Type$Food +Oracle:When Cat Oven enters the battlefield, create a Food token.\n{T}, Sacrifice a Food: Create a 1/1 black Cat creature token. Each opponent loses 1 life and you gain 1 life. diff --git a/forge-gui/res/cardsfolder/c/chatterstorm_and_awaken_the_woods.txt b/forge-gui/res/cardsfolder/c/chatterstorm_and_awaken_the_woods.txt new file mode 100644 index 00000000000..ff6528fdc87 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/chatterstorm_and_awaken_the_woods.txt @@ -0,0 +1,7 @@ +Name:Chatterstorm and Awaken the Woods +ManaCost:1 G +Types:Sorcery +K:Storm +A:SP$ Token | TokenAmount$ 1 | TokenScript$ g_1_1_forest_dryad_squirrel | TokenOwner$ You | SpellDescription$ Create a 1/1 green Forest Dryad Squirrel land creature token. +DeckHas:Ability$Token +Oracle:Create a 1/1 green Forest Dryad Squirrel land creature token. (It's affected by summoning sickness.)\nStorm (When you cast this spell, copy it for each spell cast before it this turn.) diff --git a/forge-gui/res/cardsfolder/c/cinnamon_seasoned_steed.txt b/forge-gui/res/cardsfolder/c/cinnamon_seasoned_steed.txt new file mode 100644 index 00000000000..69ae8f5a495 --- /dev/null +++ b/forge-gui/res/cardsfolder/c/cinnamon_seasoned_steed.txt @@ -0,0 +1,14 @@ +Name:Cinnamon, Seasoned Steed +ManaCost:1 +Types:Legendary Artifact Creature Food Horse +PT:1/1 +S:Mode$ Continuous | Affected$ Creature.Food+Other+YouCtrl | AddKeyword$ Horsemanship | Description$ Other Food creatures you control have horsemanship. (They can't be blocked except by creatures with horsemanship.) +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerDescription$ At the beginning of your combat step, you may put a +1/+1 counter on target non-creature Food you control. If you do, it becomes a 0/0 Knight creature in addition to its other types. +SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Food.nonCreature+YouCtrl | TgtPrompt$ Select target noncreature Food you control | CounterType$ P1P1 | CounterNum$ 1 | RememberCards$ True | SubAbility$ DBAnimate +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Power$ 0 | Toughness$ 0 | Types$ Creature,Knight | Duration$ Permanent | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME> | LifeAmount$ 3 | SpellDescription$ You gain 3 life. +SVar:PlayMain1:TRUE +DeckHas:Ability$LifeGain|Counters & Type$Knight +DeckHints:Type$Food +Oracle:Other Food creatures you control have horsemanship. (They can't be blocked except by creatures with horsemanship.)\nAt the beginning of your combat step, you may put a +1/+1 counter on target non-creature Food you control. If you do, it becomes a 0/0 Knight creature in addition to its other types.\n{2}, {T}, Sacrifice Cinnamon, Seasoned Steed: You gain 3 life. diff --git a/forge-gui/res/cardsfolder/c/colossal_dreadmaw_and_storm_crow.txt b/forge-gui/res/cardsfolder/c/colossal_dreadmaw_and_storm_crow.txt new file mode 100644 index 00000000000..c979c78910e --- /dev/null +++ b/forge-gui/res/cardsfolder/c/colossal_dreadmaw_and_storm_crow.txt @@ -0,0 +1,7 @@ +Name:Colossal Dreadmaw and Storm Crow +ManaCost:5 U G +Types:Legendary Creature Dinosaur Bird +PT:7/8 +K:Flying +K:Trample +Oracle:Flying, trample diff --git a/forge-gui/res/cardsfolder/d/delve_too_deep.txt b/forge-gui/res/cardsfolder/d/delve_too_deep.txt new file mode 100644 index 00000000000..1545f121692 --- /dev/null +++ b/forge-gui/res/cardsfolder/d/delve_too_deep.txt @@ -0,0 +1,9 @@ +Name:Delve too Deep +ManaCost:X B +Types:Sorcery +K:Delve +A:SP$ Pump | ValidTgts$ Creature | NumAtt$ -X | NumDef$ -X | IsCurse$ True | SubAbility$ DBToken | SpellDescription$ Target creature gets -X/-X until end of turn. If X was 7 or greater, create a 7/7 black and red Demon creature token. +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ br_7_7_demon | TokenOwner$ You | ConditionCheckSVar$ X | ConditionSVarCompare$ GE7 +SVar:X:Count$xPaid +DeckHas:Ability$Token & Type$Demon +Oracle:Delve\nTarget creature gets -X/-X until end of turn. If X was 7 or greater, create a 7/7 black and red Demon creature token. diff --git a/forge-gui/res/cardsfolder/d/disa_the_restless.txt b/forge-gui/res/cardsfolder/d/disa_the_restless.txt index 32d89bc2f32..e6bf5818472 100644 --- a/forge-gui/res/cardsfolder/d/disa_the_restless.txt +++ b/forge-gui/res/cardsfolder/d/disa_the_restless.txt @@ -5,7 +5,7 @@ PT:5/6 T:Mode$ ChangesZone | ValidCard$ Permanent.Lhurgoyf+YouOwn | Origin$ Library,Hand,Exile,Command,Stack | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Whenever a Lhurgoyf permanent card is put into your graveyard from anywhere other than the battlefield, put it onto the battlefield. SVar:TrigChangeZone:DB$ ChangeZone | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Battlefield T:Mode$ DamageDoneOnce | ValidSource$ Creature.YouCtrl | TriggerZones$ Battlefield | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigToken | TriggerDescription$ Whenever one or more creatures you control deal combat damage to a player, create a Tarmogoyf token. (It's a {1}{G} Lhurgoyf creature with "Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.") -SVar:TrigToken:DB$ Token | TokenScript$ tarmogoyf +SVar:TrigToken:DB$ CopyPermanent | DefinedName$ Tarmogoyf DeckNeeds:Type$Lhurgoyf DeckHas:Ability$Token & Type$Lhurgoyf DeckHints:Ability$Mill diff --git a/forge-gui/res/cardsfolder/e/eldest_dragon_highlander.txt b/forge-gui/res/cardsfolder/e/eldest_dragon_highlander.txt new file mode 100644 index 00000000000..499d218bd5a --- /dev/null +++ b/forge-gui/res/cardsfolder/e/eldest_dragon_highlander.txt @@ -0,0 +1,10 @@ +Name:Eldest Dragon Highlander +ManaCost:W W U U B B R R G G +Types:Legendary Creature Elder Dragon +PT:7/7 +K:Flying +K:Trample +K:Rampage:2 +A:AB$ PumpAll | Cost$ W U B R G | ValidCards$ Dragon.Elder+YouCtrl | NumAtt$ 7 | NumDef$ 7 | SpellDescription$ Elder Dragons you control get +7/+7 until end of turn. +K:UpkeepCost:W U B R G +Oracle:Flying, trample, rampage 2\n{W}{U}{B}{R}{G}: Elder Dragons you control get +7/+7 until end of turn.\nAt the beginning of your upkeep, sacrifice Eldest Dragon Highlander unless you pay {W}{U}{B}{R}{G}. diff --git a/forge-gui/res/cardsfolder/e/ensoul_ring.txt b/forge-gui/res/cardsfolder/e/ensoul_ring.txt new file mode 100644 index 00000000000..762e1340bbc --- /dev/null +++ b/forge-gui/res/cardsfolder/e/ensoul_ring.txt @@ -0,0 +1,9 @@ +Name:Ensoul Ring +ManaCost:1 U +Types:Enchantment Aura +K:Enchant nonland permanent +A:SP$ Attach | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | AILogic$ Curse +S:Mode$ Continuous | Affected$ Permanent.EnchantedBy | SetColor$ Colorless | AddType$ Artifact | RemoveCardTypes$ True | RemoveArtifactTypes$ True | AddAbility$ SolMana | SetName$ Sol Ring | RemoveAllAbilities$ True | Description$ Enchanted permanent is a Sol Ring. (It's no longer anything else.) +SVar:SolMana:AB$ Mana | Cost$ T | Produced$ C | Amount$ 2 | SpellDescription$ Add {C}{C}. +SVar:NonStackingAttachEffect:True +Oracle:Enchant nonland permanent.\nEnchanted permanent is a Sol Ring. (It's no longer anything else.) diff --git a/forge-gui/res/cardsfolder/f/force_of_rowan.txt b/forge-gui/res/cardsfolder/f/force_of_rowan.txt new file mode 100644 index 00000000000..bb13d415dcd --- /dev/null +++ b/forge-gui/res/cardsfolder/f/force_of_rowan.txt @@ -0,0 +1,7 @@ +Name:Force of Rowan +ManaCost:3 R R +Types:Instant +S:Mode$ AlternativeCost | ValidSA$ Spell.Self | EffectZone$ All | Cost$ PayLife<1> ExileFromHand<1/Card.Red+Other> | Description$ You may pay 1 life and exile a red card from your hand rather than pay this spell's mana cost. +A:SP$ CopySpellAbility | ValidTgts$ Instant,Sorcery | TargetType$ Spell | MayChooseTarget$ True | SpellDescription$ Copy target instant or sorcery spell. You may choose new targets for the copy. +DeckHints:Type$Instant|Sorcery +Oracle:You may pay 1 life and exile a red card from your hand rather than pay this spell's mana cost.\nCopy target instant or sorcery spell. You may choose new targets for the copy. diff --git a/forge-gui/res/cardsfolder/f/forestfolk.txt b/forge-gui/res/cardsfolder/f/forestfolk.txt new file mode 100644 index 00000000000..8b6286097c4 --- /dev/null +++ b/forge-gui/res/cardsfolder/f/forestfolk.txt @@ -0,0 +1,10 @@ +Name:Forestfolk +ManaCost:2 G U +Types:Creature Elf Wizard +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle. +SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Basic | ChangeNum$ 1 | ShuffleNonMandatory$ True +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME leaves the battlefield, draw a card. +SVar:TrigDraw:DB$ Draw | Defined$ TriggeredCardController | NumCards$ 1 +SVar:SacMe:1 +Oracle:When Forestfolk enters the battlefield, you may search your library for a basic land card, put that card onto the battlefield tapped, then shuffle.\nWhen Forestfolk leaves the battlefield, draw a card. diff --git a/forge-gui/res/cardsfolder/g/garruks_lost_wolf_hey_has_anyone_seen_garruk.txt b/forge-gui/res/cardsfolder/g/garruks_lost_wolf_hey_has_anyone_seen_garruk.txt new file mode 100644 index 00000000000..d2e9957ced7 --- /dev/null +++ b/forge-gui/res/cardsfolder/g/garruks_lost_wolf_hey_has_anyone_seen_garruk.txt @@ -0,0 +1,19 @@ +Name:Garruk's Lost Wolf +ManaCost:3 G +Types:Creature Wolf +PT:2/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a Huntsman Role token attached to another target creature you control. (Enchanted creature gets +1/+1 and has "{T}: Add {G}") +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ role_huntsman | TokenOwner$ You | AttachedTo$ Targeted | ValidTgts$ Creature.YouCtrl+Other | TgtPrompt$ Select another target creature you control +DeckHas:Ability$Mill|Graveyard|Token & Type$Aura|Enchantment|Role +AlternateMode:Adventure +Oracle:When Garruk's Lost Wolf enters the battlefield, create a Huntsman Role token attached to another target creature you control. (Enchanted creature gets +1/+1 and has "{T}: Add {G}") + +ALTERNATE + +Name:Hey, Has Anyone Seen Garruk? +ManaCost:1 G +Types:Sorcery Adventure +A:SP$ Mill | NumCards$ 4 | RememberMilled$ True | SubAbility$ DBChangeZone | SpellDescription$ Mill the top four cards of your library. Return a creature or planeswalker card milled this way to your hand. +SVar:DBChangeZone:DB$ ChangeZone | Hidden$ True | Origin$ Graveyard,Exile | Mandatory$ True | Destination$ Hand | ChangeType$ Card.IsRemembered+Creature,Card.IsRemembered+Planeswalker | SelectPrompt$ Return a creature or planeswalker card milled this way to your hand | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Mill the top four cards of your library. Return a creature or planeswalker card milled this way to your hand. diff --git a/forge-gui/res/cardsfolder/g/gingerbehemoth.txt b/forge-gui/res/cardsfolder/g/gingerbehemoth.txt new file mode 100644 index 00000000000..3ba1da1f695 --- /dev/null +++ b/forge-gui/res/cardsfolder/g/gingerbehemoth.txt @@ -0,0 +1,12 @@ +Name:Gingerbehemoth +ManaCost:6 +Types:Artifact Creature Food Golem +PT:6/6 +K:Vigilance +K:Trample +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Secondary$ True | Description$ CARDNAME costs {2} less to cast for each Food you've sacrificed this turn. +SVar:X:PlayerCountPropertyYou$SacrificedThisTurn Food/Times.2 +A:AB$ GainLife | Cost$ 4 T Sac<1/CARDNAME> | LifeAmount$ 6 | SpellDescription$ You gain 6 life. +DeckHas:Ability$LifeGain +DeckHints:Type$Food +Oracle:Gingerbehemoth costs {2} less to cast for each Food you've sacrificed this turn.\nVigilance, trample\n{4}, {T}, Sacrifice Gingerbehemoth: You gain 6 life. diff --git a/forge-gui/res/cardsfolder/g/glorious_dragon_kin.txt b/forge-gui/res/cardsfolder/g/glorious_dragon_kin.txt new file mode 100644 index 00000000000..a8fee7e2fdb --- /dev/null +++ b/forge-gui/res/cardsfolder/g/glorious_dragon_kin.txt @@ -0,0 +1,9 @@ +Name:Glorious Dragon-Kin +ManaCost:7 +Types:Artifact Creature Dragon +PT:6/6 +K:Flying +K:ETBReplacement:Other:ChooseColor +SVar:ChooseColor:DB$ ChooseColor | Defined$ You | SpellDescription$ As CARDNAME enters the battlefield, choose a color. | AILogic$ MostProminentInHumanDeck +S:Mode$ Continuous | Affected$ Creature.Artifact+YouCtrl,Dragon.YouCtrl | AddKeyword$ Protection:Card.ChosenColor:chosenColor | Description$ Artifact creatures and Dragons you control have protection from the chosen color. +Oracle:Flying\nAs Glorious Dragon-Kin enters the battlefield, choose a color.\nArtifact creatures and Dragons you control have protection from the chosen color. diff --git a/forge-gui/res/cardsfolder/h/honk.txt b/forge-gui/res/cardsfolder/h/honk.txt new file mode 100644 index 00000000000..7065108c383 --- /dev/null +++ b/forge-gui/res/cardsfolder/h/honk.txt @@ -0,0 +1,10 @@ +Name:HONK! +ManaCost:G +Types:Instant +A:SP$ Charm | Choices$ TheGooseIsLoose,TheGooseLaidAnEgg +SVar:TheGooseIsLoose:DB$ Destroy | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SubAbility$ DBGiveFood | SpellDescription$ The Goose is Loose — Destroy target artifact or enchantment. Its controller creates a Food token. +SVar:DBGiveFood:DB$ Token | TokenScript$ c_a_food_sac | TokenOwner$ TargetedController | TokenAmount$ 1 +SVar:TheGooseLaidAnEgg:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBGetFood | SpellDescription$ The Goose Laid an Egg — Put a +1/+1 counter on target creature. You create a Food token. +SVar:DBGetFood:DB$ Token | TokenScript$ c_a_food_sac | TokenAmount$ 1 +DeckHas:Ability$Token|Counters|LifeGain & Type$Food|Artifact +Oracle:Choose one —\n• The Goose is Loose — Destroy target artifact or enchantment. Its controller creates a Food token.\n• The Goose Laid an Egg — Put a +1/+1 counter on target creature. You create a Food token. diff --git a/forge-gui/res/cardsfolder/h/hound_of_urabrask.txt b/forge-gui/res/cardsfolder/h/hound_of_urabrask.txt new file mode 100644 index 00000000000..6614c7682dd --- /dev/null +++ b/forge-gui/res/cardsfolder/h/hound_of_urabrask.txt @@ -0,0 +1,11 @@ +Name:Hound of Urabrask +ManaCost:3 R R +Types:Creature Phyrexian +PT:3/3 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+counters_EQ0_OIL | TriggerZones$ Battlefield | Execute$ DBReturn | TriggerDescription$ Oildying (When this creature dies, if it had no oil counters on it, return it to the battlefield under its owner's control with an oil counter on it.) +SVar:DBReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | WithCountersType$ OIL +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | Description$ CARDNAME gets +1/+1 for each oil counter on it. +S:Mode$ Continuous | Affected$ Card.Self+counters_GE1_OIL | AddKeyword$ Double Strike | Description$ As long as CARDNAME has an oil counter on it, it has double strike. +SVar:X:Count$CardCounters.OIL +DeckHas:Ability$Counters +Oracle:Oildying (When this creature dies, if it had no oil counters on it, return it to the battlefield under its owner's control with an oil counter on it.)\nHound of Urabrask gets +1/+1 for each oil counter on it.\nAs long as Hound of Urabrask has an oil counter on it, it has double strike. diff --git a/forge-gui/res/cardsfolder/i/ignite_the_future.txt b/forge-gui/res/cardsfolder/i/ignite_the_future.txt index 742fe2f0e6e..fd2bd99348a 100644 --- a/forge-gui/res/cardsfolder/i/ignite_the_future.txt +++ b/forge-gui/res/cardsfolder/i/ignite_the_future.txt @@ -2,7 +2,7 @@ Name:Ignite the Future ManaCost:3 R Types:Sorcery A:SP$ Dig | Defined$ You | DigNum$ 3 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Exile the top three cards of your library. Until the end of your next turn, you may play those cards. If this spell was cast from a graveyard, you may play cards this way without paying their mana costs. -SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn | ConditionDefined$ Self | ConditionPresent$ Card.wasCastFromGraveyard | ConditionCompare$ EQ0 | SubAbility$ DBEffect2 +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn | SubAbility$ DBEffect2 SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play remembered card. SVar:DBEffect2:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play2 | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn | ConditionDefined$ Self | ConditionPresent$ Card.wasCastFromGraveyard | ConditionCompare$ EQ1 | SubAbility$ DBCleanup SVar:Play2:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play remembered card without paying their mana costs. diff --git a/forge-gui/res/cardsfolder/i/incisor_steed.txt b/forge-gui/res/cardsfolder/i/incisor_steed.txt new file mode 100644 index 00000000000..6c0248619af --- /dev/null +++ b/forge-gui/res/cardsfolder/i/incisor_steed.txt @@ -0,0 +1,10 @@ +Name:Incisor Steed +ManaCost:1 W +Types:Artifact Creature Phyrexian Horse +PT:1/4 +K:Vigilance +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 3 | CheckSVar$ X | SVarCompare$ GE3 | Condition$ Metalcraft | Description$ Corrupted Metalcraft — As long as you control three or more artifacts and an opponent has three or more poison counters, CARDNAME gets +3/+0. +SVar:X:PlayerCountOpponents$HighestCounters.Poison +SVar:BuffedBy:Artifact +DeckHints:Keyword$Toxic|Infect & Type$Artifact +Oracle:Vigilance\nCorrupted Metalcraft — As long as you control three or more artifacts and an opponent has three or more poison counters, Incisor Steed gets +3/+0. diff --git a/forge-gui/res/cardsfolder/i/incubob.txt b/forge-gui/res/cardsfolder/i/incubob.txt new file mode 100644 index 00000000000..72674a4c7fa --- /dev/null +++ b/forge-gui/res/cardsfolder/i/incubob.txt @@ -0,0 +1,7 @@ +Name:Incubob +ManaCost:1 B +Types:Sorcery +K:Flashback:3 B PayLife<3> +A:SP$ Token | TokenScript$ incubator_dark_confidant | WithCountersType$ P1P1 | WithCountersAmount$ 1 | SpellDescription$ Incubate Dark Confidant 1. (Create an Incubator Dark Confidant token with a +1/+1 counter on it and "{2}: Transform this artifact." It transforms into Dark Confidant, except it's also a Phyrexian.) +DeckHas:Ability$Token|Counters & Type$Incubator|Artifact|Phyrexian|Human|Wizard +Oracle:Incubate Dark Confidant 1. (Create an Incubator Dark Confidant token with a +1/+1 counter on it and "{2}: Transform this artifact." It transforms into Dark Confidant, except it's also a Phyrexian.)\nFlashback—{3}{B}, Pay 3 life. diff --git a/forge-gui/res/cardsfolder/i/innistrad_charm.txt b/forge-gui/res/cardsfolder/i/innistrad_charm.txt new file mode 100644 index 00000000000..95cfda485b4 --- /dev/null +++ b/forge-gui/res/cardsfolder/i/innistrad_charm.txt @@ -0,0 +1,11 @@ +Name:Innistrad Charm +ManaCost:1 B +Types:Sorcery +A:SP$ Charm | Choices$ CemeteryRecruitment,Duress,HumanFrailty | Defined$ You +SVar:CemeteryRecruitment:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouCtrl | SubAbility$ DBDraw | RememberChanged$ True | SpellDescription$ Return target creature card from your graveyard to your hand. If it's a Zombie card, draw a card. +SVar:DBDraw:DB$ Draw | NumCards$ 1 | ConditionDefined$ Remembered | ConditionPresent$ Card.Zombie | ConditionCompare$ GE1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Duress:DB$ Discard | ValidTgts$ Opponent | Mode$ RevealYouChoose | DiscardValid$ Card.nonCreature+nonLand | NumCards$ 1 | SpellDescription$ Target opponent reveals their hand. You choose a noncreature, nonland card from it. That player discards that card. +SVar:HumanFrailty:DB$ Destroy | ValidTgts$ Creature.Human | TgtPrompt$ Choose target Human creature. | SpellDescription$ Destroy target Human creature. +DeckHints:Type$Zombie +Oracle:Choose one —\n• Cemetery Recruitment (Return a creature card from graveyard to hand, draw a card if it's a Zombie.)\n• Duress (Look at their hand, make them discard a noncreature, nonland.)\n• Human Frailty (Destroy target Human.) diff --git a/forge-gui/res/cardsfolder/i/isamaru_and_yoshimaru.txt b/forge-gui/res/cardsfolder/i/isamaru_and_yoshimaru.txt new file mode 100644 index 00000000000..f0496cee645 --- /dev/null +++ b/forge-gui/res/cardsfolder/i/isamaru_and_yoshimaru.txt @@ -0,0 +1,9 @@ +Name:Isamaru and Yoshimaru +ManaCost:W +Types:Legendary Creature Dog +PT:2/2 +T:Mode$ ChangesZone | ValidCard$ Creature.Legendary+Other+YouCtrl,Creature.cmcEQ1+Other+YouCtrl | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ Whenever another legendary creature or creature with mana value one enters the battlefield under your control, put a +1/+1 counter on CARDNAME. +SVar:TrigCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 +SVar:BuffedBy:Creature.Legendary,Creature.cmcEQ1 +DeckHas:Ability$Counters +Oracle:Whenever another legendary creature or creature with mana value one enters the battlefield under your control, put a +1/+1 counter on Isamaru and Yoshimaru. diff --git a/forge-gui/res/cardsfolder/j/jeska_and_kamahl.txt b/forge-gui/res/cardsfolder/j/jeska_and_kamahl.txt new file mode 100644 index 00000000000..62eafd48800 --- /dev/null +++ b/forge-gui/res/cardsfolder/j/jeska_and_kamahl.txt @@ -0,0 +1,8 @@ +Name:Jeska and Kamahl +ManaCost:3 R +Types:Legendary Creature Human Barbarian Warrior +PT:4/1 +K:First Strike +K:Haste +A:AB$ DealDamage | Cost$ T | ValidTgts$ Opponent,Planeswalker,Battle | TgtPrompt$ Select target opponent, battle, or planeswalker | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to target opponent, battle, or planeswalker. +Oracle:Haste, first strike\n{T}: Jeska and Kamahl deals 2 damage to target opponent, battle, or planeswalker. diff --git a/forge-gui/res/cardsfolder/j/joven_and_chandler.txt b/forge-gui/res/cardsfolder/j/joven_and_chandler.txt new file mode 100644 index 00000000000..6203ed0d458 --- /dev/null +++ b/forge-gui/res/cardsfolder/j/joven_and_chandler.txt @@ -0,0 +1,12 @@ +Name:Joven and Chandler +ManaCost:3 R R +Types:Legendary Creature Human Rogue +PT:3/3 +K:Backup:2:BackupAbilities +SVar:BackupAbilities:DB$ Animate | Keywords$ Haste | Triggers$ DamageTrig +SVar:DamageTrig:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | Execute$ TrigDestroy | CombatDamage$ True | TriggerDescription$ Whenever this creature deals combat damage to an opponent, destroy target artifact that player controls. +K:Haste +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | Execute$ TrigDestroy | CombatDamage$ True | TriggerDescription$ Whenever this creature deals combat damage to an opponent, destroy target artifact that player controls. +SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact damaged player controls +DeckHas:Ability$Counters +Oracle:Backup 2 (When this creature enters the battlefield, put two +1/+1 counters on target creature. If that's another creature, it gains the following abilities until end of turn.)\nHaste\nWhenever this creature deals combat damage to an opponent, destroy target artifact that player controls. diff --git a/forge-gui/res/cardsfolder/k/kamigawa_charm.txt b/forge-gui/res/cardsfolder/k/kamigawa_charm.txt new file mode 100644 index 00000000000..b26dba91fd9 --- /dev/null +++ b/forge-gui/res/cardsfolder/k/kamigawa_charm.txt @@ -0,0 +1,14 @@ +Name:Kamigawa Charm +ManaCost:1 G G +Types:Sorcery +A:SP$ Charm | Choices$ DosansOldestChant,KodamasReach,TimeOfNeed | Defined$ You +SVar:DosansOldestChant:DB$ GainLife | LifeAmount$ 6 | SubAbility$ DBDraw | SpellDescription$ You gain 6 life. Draw a card. +SVar:DBDraw:DB$ Draw | NumCards$ 1 +SVar:KodamasReach:DB$ ChangeZone | Origin$ Library | Destination$ Library | ChangeType$ Land.Basic | ChangeNum$ 2 | RememberChanged$ True | Reveal$ True | Shuffle$ False | StackDescription$ SpellDescription | SubAbility$ DBChangeZone1 | SpellDescription$ Search your library for up to two basic land cards, reveal those cards, put one onto the battlefield tapped and the other into your hand, then shuffle. +SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.IsRemembered | ChangeNum$ 1 | Mandatory$ True | NoLooking$ True | SelectPrompt$ Select a card for the battlefield | Tapped$ True | Shuffle$ False | SubAbility$ DBChangeZone2 | StackDescription$ None +SVar:DBChangeZone2:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Land.IsRemembered | Mandatory$ True | NoLooking$ True | SelectPrompt$ Select a card for your hand | StackDescription$ None | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TimeOfNeed:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Creature.Legendary | ChangeNum$ 1 | SpellDescription$ Search your library for a legendary creature card, reveal it, put it into your hand, then shuffle. +DeckHas:Ability$LifeGain +DeckHints:Type$Legendary +Oracle:Choose one —\n• Dosan's Oldest Chant (Gain 6 life, draw a card.)\n• Kodama's Reach (Search for two basic lands, put one onto the battlefield tapped and one to hand.)\n• Time of Need (Search for a legend.) diff --git a/forge-gui/res/cardsfolder/k/kevin_questing_dragon.txt b/forge-gui/res/cardsfolder/k/kevin_questing_dragon.txt new file mode 100644 index 00000000000..3e0c3f16c6e --- /dev/null +++ b/forge-gui/res/cardsfolder/k/kevin_questing_dragon.txt @@ -0,0 +1,17 @@ +Name:Kevin, Questing Dragon +ManaCost:4 R R R R +Types:Legendary Creature Dragon +PT:8/8 +K:Devour:2 +K:Flying +K:Landwalk:Mountain +K:Rampage:2 +K:Bushido:2 +K:Trample:Planeswalker +R:Event$ Counter | ValidCard$ Card.Self | ValidSA$ Spell | Layer$ CantHappen | Description$ This spell can't be countered. +S:Mode$ CantPreventDamage | Description$ Damage can't be prevented. +S:Mode$ CantGainLife | ValidPlayer$ Player | Description$ Players can't gain life. +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigControl | TriggerZones$ Battlefield | TriggerDescription$ Whenever NICKNAME deals combat damage to a player, gain control of target land that player controls. Untap it. +SVar:TrigControl:DB$ GainControl | ValidTgts$ Land.ControlledBy TriggeredTarget | TgtPrompt$ Select target land damaged player controls | SubAbility$ DBUntap +SVar:DBUntap:DB$ Untap | Defined$ Targeted | SpellDescription$ Untap it. +Oracle:Kevin can't be countered, devour 2\nFlying, mountainwalk, rampage 2, bushido 2, trample over planeswalkers\nDamage can't be prevented.\nPlayers can't gain life.\nWhenever Kevin deals combat damage to a player, gain control of target land that player controls. Untap it. diff --git a/forge-gui/res/cardsfolder/k/knowing_half_the_battle.txt b/forge-gui/res/cardsfolder/k/knowing_half_the_battle.txt new file mode 100644 index 00000000000..91cf1902b37 --- /dev/null +++ b/forge-gui/res/cardsfolder/k/knowing_half_the_battle.txt @@ -0,0 +1,15 @@ +Name:Knowing +ManaCost:3 U U +Types:Sorcery +A:SP$ Draw | NumCards$ 3 | SpellDescription$ Draw three cards. +AlternateMode:Split +Oracle:Draw three cards. + +ALTERNATE + +Name:Half the Battle +ManaCost:2 R +Types:Sorcery +DeckHints:Type$Battle +A:SP$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Battle | ChangeNum$ 1 | SpellDescription$ Search your library for a Battle card, reveal it, put it into your hand, then shuffle. +Oracle:Search your library for a Battle card, reveal it, put it into your hand, then shuffle. diff --git a/forge-gui/res/cardsfolder/k/koma_and_toski_compleated.txt b/forge-gui/res/cardsfolder/k/koma_and_toski_compleated.txt new file mode 100644 index 00000000000..f8d2937ce62 --- /dev/null +++ b/forge-gui/res/cardsfolder/k/koma_and_toski_compleated.txt @@ -0,0 +1,14 @@ +Name:Koma and Toski, Compleated +ManaCost:6 U G +Types:Legendary Creature Phyrexian Serpent Squirrel +PT:7/7 +R:Event$ Counter | ValidCard$ Card.Self | ValidSA$ Spell | Layer$ CantHappen | Description$ This spell can't be countered. +T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of each upkeep, create a 1/1 Phyrexian Serpent Squirrel artifact creature token named Toski's Coil with "Whenever this creature deals combat damage to a player, draw a card." +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ toskis_coil | TokenOwner$ You +A:AB$ Charm | Cost$ Sac<1/Serpent.Other;Squirrel.Other/another Serpent or Squirrel> | Choices$ DBEffect,DBPump +SVar:DBEffect:DB$ Effect | ValidTgts$ Creature | RememberObjects$ Targeted | ExileOnMoved$ Battlefield | StaticAbilities$ MustAttack | SubAbility$ DBConstrict | SpellDescription$ Target creature attacks this turn if able. Its activated abilities can't be activated this turn. +SVar:MustAttack:Mode$ MustAttack | ValidCreature$ Card.IsRemembered | Description$ This creature attacks this turn if able. +SVar:DBConstrict:DB$ Pump | Defined$ ParentTarget | KW$ HIDDEN CARDNAME's activated abilities can't be activated. | StackDescription$ None +SVar:DBPump:DB$ Pump | Defined$ Self | KW$ Indestructible | SpellDescription$ CARDNAME gains indestructible until end of turn. +DeckHas:Ability$Token|Sacrifice & Type$Artifact +Oracle:This spell can't be countered.\nAt the beginning of each upkeep, create a 1/1 Phyrexian Serpent Squirrel artifact creature token named Toski's Coil with "Whenever this creature deals combat damage to a player, draw a card."\nSacrifice another Serpent or Squirrel: Choose one —\n• Target creature attacks this turn if able. Its activated abilities can't be activated this turn.\n• Koma and Toski, Compleated gains indestructible until end of turn. diff --git a/forge-gui/res/cardsfolder/l/leech_medic.txt b/forge-gui/res/cardsfolder/l/leech_medic.txt new file mode 100644 index 00000000000..51dc11b0c0d --- /dev/null +++ b/forge-gui/res/cardsfolder/l/leech_medic.txt @@ -0,0 +1,7 @@ +Name:Leech Medic +ManaCost:3 W +Types:Creature Leech Cleric +PT:3/4 +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigConjure | TriggerDescription$ When CARDNAME enters the battlefield, create a Leeches token card and put it into your hand. +SVar:TrigConjure:DB$ MakeCard | Name$ Leeches | TokenCard$ True | Zone$ Hand +Oracle:When Leech Medic enters the battlefield, create a Leeches token card and put it into your hand. diff --git a/forge-gui/res/cardsfolder/l/life_cloud.txt b/forge-gui/res/cardsfolder/l/life_cloud.txt new file mode 100644 index 00000000000..6610ea329f3 --- /dev/null +++ b/forge-gui/res/cardsfolder/l/life_cloud.txt @@ -0,0 +1,11 @@ +Name:Life Cloud +ManaCost:X W W W +Types:Sorcery +A:SP$ GainLife | Defined$ Player | LifeAmount$ X | SubAbility$ DBDraw | SpellDescription$ Each player gains X life, draws X cards, returns X creatures from their graveyard to the battlefield, then returns X lands from their graveyard to the battlefield. +SVar:DBDraw:DB$ Draw | NumCards$ X | Defined$ Player | SubAbility$ DBRepeatCreature +SVar:DBRepeatCreature:DB$ RepeatEach | RepeatSubAbility$ DBReturnCreature | RepeatPlayers$ Player | SubAbility$ DBRepeatLand +SVar:DBReturnCreature:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.RememberedPlayerCtrl | DefinedPlayer$ Player.IsRemembered | Chooser$ Player.IsRemembered | ChangeNum$ X | Hidden$ True | Mandatory$ True +SVar:DBRepeatLand:DB$ RepeatEach | RepeatSubAbility$ DBReturnLand | RepeatPlayers$ Player +SVar:DBReturnLand:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Land.RememberedPlayerCtrl | DefinedPlayer$ Player.IsRemembered | Chooser$ Player.IsRemembered | ChangeNum$ X | Hidden$ True | Mandatory$ True +SVar:X:Count$xPaid +Oracle:Each player gains X life, draws X cards, returns X creatures from their graveyard to the battlefield, then returns X lands from their graveyard to the battlefield. diff --git a/forge-gui/res/cardsfolder/l/locus_cobra.txt b/forge-gui/res/cardsfolder/l/locus_cobra.txt new file mode 100644 index 00000000000..4b202e55de0 --- /dev/null +++ b/forge-gui/res/cardsfolder/l/locus_cobra.txt @@ -0,0 +1,11 @@ +Name:Locus Cobra +ManaCost:1 G +Types:Creature Phyrexian Snake +PT:1/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigMana | TriggerDescription$ Landfall — Whenever a land enters the battlefield under your control, add one mana of any color. If it was a Locus or Sphere land, put a +1/+1 counter on CARDNAME. +SVar:TrigMana:DB$ Mana | Produced$ Any | SubAbility$ DBPutCounter +SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | ConditionDefined$ TriggeredCard | ConditionPresent$ Locus,Sphere +SVar:BuffedBy:Locus,Sphere +DeckHas:Ability$Counters +DeckHints:Type$Locus|Sphere +Oracle:Landfall — Whenever a land enters the battlefield under your control, add one mana of any color. If it was a Locus or Sphere land, put a +1/+1 counter on Locus Cobra. diff --git a/forge-gui/res/cardsfolder/l/luxior_and_shadowspear.txt b/forge-gui/res/cardsfolder/l/luxior_and_shadowspear.txt new file mode 100644 index 00000000000..9e6e4d5071f --- /dev/null +++ b/forge-gui/res/cardsfolder/l/luxior_and_shadowspear.txt @@ -0,0 +1,10 @@ +Name:Luxior and Shadowspear +ManaCost:2 +Types:Legendary Artifact Equipment +K:Equip:3:Planeswalker.YouCtrl:planeswalker +K:Equip:3 +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ X | AddToughness$ X | AddKeyword$ Trample & Lifelink | Description$ Equipped creature gets +1/+1 for each counter on it, and has trample and lifelink. +SVar:X:Equipped$CardCounters.ALL +S:Mode$ Continuous | Affected$ Permanent.EquippedBy | RemoveType$ Planeswalker | AddType$ Creature | Description$ Equipped permanent isn't a planeswalker and is a creature in addition it its other types. (Loyalty abilities can still be activated.) +A:AB$ AnimateAll | Cost$ 1 | ValidCards$ Permanent.OppCtrl | RemoveKeywords$ Hexproof & Indestructible | SpellDescription$ Permanents your opponents control lose hexproof and indestructible until end of turn. | StackDescription$ SpellDescription +Oracle:Equipped creature gets +1/+1 for each counter on it, and has trample and lifelink.\n{1}: Permanents your opponents control lose hexproof and indestructible until end of turn.\nEquipped permanent isn't a planeswalker and is a creature in addition it its other types. (Loyalty abilities can still be activated.)\Equip creature or planeswalker {3} diff --git a/forge-gui/res/cardsfolder/m/manakin_and_millikin.txt b/forge-gui/res/cardsfolder/m/manakin_and_millikin.txt new file mode 100644 index 00000000000..3f483ebfc41 --- /dev/null +++ b/forge-gui/res/cardsfolder/m/manakin_and_millikin.txt @@ -0,0 +1,8 @@ +Name:Manakin and Millikin +ManaCost:3 +Types:Artifact Creature Construct +PT:1/2 +A:AB$ Mana | Cost$ T Mill<1> | Produced$ C | Amount$ 2 | SpellDescription$ Add {C}{C}. +DeckHas:Ability$Mill +DeckHints:Ability$Graveyard +Oracle:{T}, Mill a card: Add {C}{C}. diff --git a/forge-gui/res/cardsfolder/m/more_of_that_strange_oil.txt b/forge-gui/res/cardsfolder/m/more_of_that_strange_oil.txt new file mode 100644 index 00000000000..9f2c6b50856 --- /dev/null +++ b/forge-gui/res/cardsfolder/m/more_of_that_strange_oil.txt @@ -0,0 +1,10 @@ +Name:More of That Strange Oil... +ManaCost:2 U +Types:Instant +A:SP$ Charm | Choices$ DBProliferate,DBCounter +SVar:DBProliferate:DB$ Proliferate | SubAbility$ DBDraw | SpellDescription$ It's Probably Nothing — Proliferate. Draw a card. +SVar:DBDraw:DB$ Draw | NumCards$ 1 +SVar:DBCounter:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target creature, artifact, or planeswalker spell | ValidTgts$ Creature,Artifact,Planeswalker | SubAbility$ DBScry | SpellDescription$ That Could Actually Be Dangerous — Counter target creature, artifact, or planeswalker spell. Scry 1. +SVar:DBScry:DB$ Scry | ScryNum$ 1 +DeckHas:Ability$Proliferate +Oracle:Choose one —\n• It's Probably Nothing — Proliferate. Draw a card.\n• That Could Actually Be Dangerous — Counter target creature, artifact, or planeswalker spell. Scry 1. diff --git a/forge-gui/res/cardsfolder/m/mox_poison.txt b/forge-gui/res/cardsfolder/m/mox_poison.txt new file mode 100644 index 00000000000..6747b294fc7 --- /dev/null +++ b/forge-gui/res/cardsfolder/m/mox_poison.txt @@ -0,0 +1,6 @@ +Name:Mox Poison +ManaCost:0 +Types:Artifact +A:AB$ Mana | Cost$ T | Produced$ Any | SubAbility$ DBPain | SpellDescription$ Add one mana of any color. You get two poison counters +SVar:DBPain:DB$ Poison | Defined$ You | Num$ 2 +Oracle:{T}: Add one mana of any color. You get two poison counters diff --git a/forge-gui/res/cardsfolder/m/myojin_of_nights_reach_grim_betrayal.txt b/forge-gui/res/cardsfolder/m/myojin_of_nights_reach_grim_betrayal.txt new file mode 100644 index 00000000000..156c2373efc --- /dev/null +++ b/forge-gui/res/cardsfolder/m/myojin_of_nights_reach_grim_betrayal.txt @@ -0,0 +1,10 @@ +Name:Myojin of Night's Reach Grim Betrayal +ManaCost:5 B B B +Types:Legendary Creature Spirit +PT:10/4 +K:etbCounter:Indestructible:1:CheckSVar$ FromHand:CARDNAME enters the battlefield with an indestructible counter on it if you cast it from your hand. +SVar:FromHand:Count$wasCastFromYourHandByYou.1.0 +A:AB$ Discard | Cost$ SubCounter<1/Indestructible> | Defined$ Player.Opponent | Mode$ Hand | SubAbility$ DBReturn | SpellDescription$ Each opponent discards their hand. Put onto the battlefield under your control all creature cards in all graveyards that were put there from anywhere this turn. +SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ ValidGraveyard Creature.ThisTurnEntered | GainControl$ True +DeckHas:Ability$Graveyard +Oracle:Myojin of Night's Reach Grim Betrayal enters the battlefield with an indestructible counter on it if you cast it from your hand.\nRemove an indestructible counter from Myojin of Night's Reach Grim Betrayal: Each opponent discards their hand. Put onto the battlefield under your control all creature cards in all graveyards that were put there from anywhere this turn. diff --git a/forge-gui/res/cardsfolder/m/mysterious_confluence.txt b/forge-gui/res/cardsfolder/m/mysterious_confluence.txt new file mode 100644 index 00000000000..84dc3c63011 --- /dev/null +++ b/forge-gui/res/cardsfolder/m/mysterious_confluence.txt @@ -0,0 +1,7 @@ +Name:Mysterious Confluence +ManaCost:5 +Types:Instant +A:SP$ NameCard | AtRandom$ True | ChooseFromList$ Righteous Confluence,Mystic Confluence,Wretched Confluence,Fiery Confluence,Verdant Confluence,Brokers Confluence,Cabaretti Confluence,Maestros Confluence,Obscura Confluence,Riveteers Confluence | SubAbility$ DBCast | StackDescription$ SpellDescription | SpellDescription$ Choose a card at random from among Righteous Confluence, Mystic Confluence, Wretched Confluence, Fiery Confluence, Verdant Confluence, Brokers Confluence, Cabaretti Confluence, Maestros Confluence, Obscura Confluence, and Riveteers Confluence. Create a copy of that card. You may cast the copy without paying its mana cost. +SVar:DBCast:DB$ Play | WithoutManaCost$ True | CopyFromChosenName$ True | Optional$ True | SubAbility$ DBCleanup | StackDescription$ None +SVar:DBCleanup:DB$ Cleanup | ClearNamedCard$ True +Oracle:Choose a card at random from among Righteous Confluence, Mystic Confluence, Wretched Confluence, Fiery Confluence, Verdant Confluence, Brokers Confluence, Cabaretti Confluence, Maestros Confluence, Obscura Confluence, and Riveteers Confluence. Create a copy of that card. You may cast the copy without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/n/nahiris_lithoforming.txt b/forge-gui/res/cardsfolder/n/nahiris_lithoforming.txt index d091434a374..c03aff4a5ac 100644 --- a/forge-gui/res/cardsfolder/n/nahiris_lithoforming.txt +++ b/forge-gui/res/cardsfolder/n/nahiris_lithoforming.txt @@ -2,16 +2,15 @@ Name:Nahiri's Lithoforming ManaCost:X R R Types:Sorcery A:SP$ Sacrifice | SacValid$ Land | Amount$ X | RememberSacrificed$ True | SubAbility$ DBDraw | StackDescription$ SpellDescription | SpellDescription$ Sacrifice X lands. For each land sacrificed this way, draw a card. You may play X additional lands this turn. Lands you control enter tapped this turn. -SVar:DBDraw:DB$ Draw | NumCards$ Y | SubAbility$ DBStoreSVar | StackDescription$ None -SVar:DBStoreSVar:DB$ StoreSVar | SVar$ XLands | Type$ CountSVar | Expression$ X | SubAbility$ DBEffect -SVar:DBEffect:DB$ Effect | StaticAbilities$ PlayMoreLand | ReplacementEffects$ LandETB | SubAbility$ DBCleanup -SVar:PlayMoreLand:Mode$ Continuous | Affected$ You | AdjustLandPlays$ XLands | EffectZone$ Command | Description$ You may play X additional lands this turn. +SVar:DBDraw:DB$ Draw | NumCards$ Y | SubAbility$ DBEffect | StackDescription$ None +SVar:DBEffect:DB$ Effect | SetChosenNumber$ X | StaticAbilities$ PlayMoreLand | ReplacementEffects$ LandETB | SubAbility$ DBCleanup +SVar:PlayMoreLand:Mode$ Continuous | Affected$ You | AdjustLandPlays$ Z | EffectZone$ Command | Description$ You may play X additional lands this turn. SVar:LandETB:Event$ Moved | ValidCard$ Land.YouCtrl | Destination$ Battlefield | ReplaceWith$ ETBTapped | ReplacementResult$ Updated | Description$ Lands you control enter tapped this turn. SVar:ETBTapped:DB$ Tap | ETB$ True | Defined$ ReplacedCard SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$xPaid SVar:Y:Count$RememberedSize -SVar:XLands:Number$0 +SVar:Z:Count$ChosenNumber DeckHas:Ability$Sacrifice AI:RemoveDeck:All Oracle:Sacrifice X lands. For each land sacrificed this way, draw a card. You may play X additional lands this turn. Lands you control enter tapped this turn. diff --git a/forge-gui/res/cardsfolder/n/night_out_in_vegas.txt b/forge-gui/res/cardsfolder/n/night_out_in_vegas.txt new file mode 100644 index 00000000000..bcce1fc99b7 --- /dev/null +++ b/forge-gui/res/cardsfolder/n/night_out_in_vegas.txt @@ -0,0 +1,15 @@ +Name:Night Out in Vegas +ManaCost:2 B B +Types:Enchantment +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigCharm | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, ABILITY +SVar:TrigCharm:DB$ Charm | Choices$ Buffet,SeeAShow,PlayGames,GoToSleep | ChoiceRestriction$ ThisGame | CharmNum$ 1 +SVar:Buffet:DB$ Token | TokenScript$ c_a_food_sac | TokenAmount$ 3 | SpellDescription$ Buffet — Create three Food tokens. +SVar:SeeAShow:DB$ Token | TokenScript$ w_2_2_performer | TokenAmount$ 2 | SpellDescription$ See a Show — Create two 2/2 white Performer creature tokens. +SVar:PlayGames:DB$ ChangeZone | Origin$ Library | NoShuffle$ True | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | SubAbility$ DBDiscard | Mandatory$ True | SpellDescription$ Play Games — Search your library for a card, put that card into your hand, discard a card at random, then shuffle. +SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ Random | SubAbility$ DBShuffle +SVar:DBShuffle:DB$ Shuffle | Defined$ You +SVar:GoToSleep:DB$ LoseLife | LifeAmount$ 15 | SubAbility$ DBSacSelf | SpellDescription$ Go to Sleep — You lose 15 life. Sacrifice CARDNAME. +SVar:DBSacSelf:DB$ Sacrifice +DeckHas:Ability$Token|Sacrifice|LifeGain & Type$Food|Artifact|Performer +AI:RemoveDeck:All +Oracle:At the beginning of your upkeep, choose one that hasn't been chosen —\n• Buffet — Create three Food tokens.\n• See a Show — Create two 2/2 white Performer creature tokens.\n• Play Games — Search your library for a card, put that card into your hand, discard a card at random, then shuffle.\n• Go to Sleep — You lose 15 life. Sacrifice Night Out in Vegas. diff --git a/forge-gui/res/cardsfolder/n/nim_mongoose.txt b/forge-gui/res/cardsfolder/n/nim_mongoose.txt new file mode 100644 index 00000000000..65977c77fe6 --- /dev/null +++ b/forge-gui/res/cardsfolder/n/nim_mongoose.txt @@ -0,0 +1,11 @@ +Name:Nim Mongoose +ManaCost:B +Types:Creature Zombie Mongoose +PT:2/1 +K:Shroud +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters the battlefield tapped. +SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True +S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | Condition$ Threshold | Description$ Threshold — CARDNAME gets +1/+0 for each artifact you control as long as seven or more cards are in your graveyard. +SVar:X:Count$Valid Artifact.YouCtrl +SVar:BuffedBy:Artifact +Oracle:Shroud\nNim Mongoose enters the battlefield tapped.\nThreshold — Nim Mongoose gets +1/+0 for each artifact you control as long as seven or more cards are in your graveyard. diff --git a/forge-gui/res/cardsfolder/n/norin_and_feldon.txt b/forge-gui/res/cardsfolder/n/norin_and_feldon.txt new file mode 100644 index 00000000000..29e496e9463 --- /dev/null +++ b/forge-gui/res/cardsfolder/n/norin_and_feldon.txt @@ -0,0 +1,9 @@ +Name:Norin and Feldon +ManaCost:1 R +Types:Legendary Creature Human Warrior Artificer +PT:2/2 +A:AB$ CopyPermanent | Cost$ 2 R T | SorcerySpeed$ True | TgtZone$ Graveyard | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select target creature card in your graveyard | NumCopies$ 1 | AddTypes$ Artifact | PumpKeywords$ Haste | AddSVars$ NorinExile | AddTriggers$ Norin1,Norin2 | SpellDescription$ Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types, gains haste, and has "Whenever a player casts a spell or a creature attacks, exile this token." Activate only as a sorcery. +SVar:Norin1:Mode$ SpellCast | ValidCard$ Card | Execute$ NorinExile | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a spell or a creature attacks, exile this token. +SVar:Norin2:Mode$ Attacks | ValidCard$ Creature | Execute$ NorinExile | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever a player casts a spell or a creature attacks, exile this token. +SVar:NorinExile:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile +Oracle:{2}{R}, {T}: Create a token that's a copy of target creature card in your graveyard, except it's an artifact in addition to its other types, gains haste, and has "Whenever a player casts a spell or a creature attacks, exile this token." Activate only as a sorcery. diff --git a/forge-gui/res/cardsfolder/n/nyssa_of_traken.txt b/forge-gui/res/cardsfolder/n/nyssa_of_traken.txt index 1d56a8be081..ca2392612fa 100644 --- a/forge-gui/res/cardsfolder/n/nyssa_of_traken.txt +++ b/forge-gui/res/cardsfolder/n/nyssa_of_traken.txt @@ -3,8 +3,8 @@ ManaCost:3 U Types:Legendary Creature Human Scientist PT:3/4 S:Mode$ Continuous | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size. -T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigImmediateTrig | OptionalDecider$ You | TriggerDescription$ Sonic Booster — Whenever CARDNAME attacks, sacrifice X artifacts. When you sacrifice one or more artifacts this way, tap up to X target creatures and you draw X cards. -SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ Sac | Execute$ TrigTap | TriggerDescription$ When you sacrifice one or more artifacts this way, tap up to X target creatures and you draw X cards. +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigImmediateTrig | OptionalDecider$ You | TriggerDescription$ Sonic Booster — Whenever CARDNAME attacks, sacrifice any number artifacts. When you sacrifice one or more artifacts this way, tap up to that many target creatures and draw that many cards. +SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ Sac | Execute$ TrigTap | TriggerDescription$ When you sacrifice one or more artifacts this way, tap up to that many target creatures and draw that many cards. SVar:TrigTap:DB$ Tap | TargetMin$ 0 | TargetMax$ X | TgtPrompt$ Select up to X target creatures to tap | ValidTgts$ Creature | SubAbility$ TrigDraw SVar:TrigDraw:DB$ Draw | NumCards$ X SVar:X:Count$xPaid @@ -12,4 +12,4 @@ K:Doctor's companion SVar:HasAttackEffect:TRUE DeckHas:Ability$Sacrifice DeckNeeds:Type$Artifact -Oracle:You have no maximum hand size.\nSonic Booster — Whenever Nyssa of Traken attacks, sacrifice X artifacts. When you sacrifice one or more artifacts this way, tap up to X target creatures and you draw X cards.\nDoctor's companion (You can have two commanders if the other is the Doctor.) +Oracle:You have no maximum hand size.\nSonic Booster — Whenever Nyssa of Traken attacks, sacrifice any number of artifacts. When you sacrifice one or more artifacts this way, tap up to that many target creatures and draw that many cards.\nDoctor's companion (You can have two commanders if the other is the Doctor.) diff --git a/forge-gui/res/cardsfolder/o/original_skullclamp.txt b/forge-gui/res/cardsfolder/o/original_skullclamp.txt new file mode 100644 index 00000000000..85459fb185f --- /dev/null +++ b/forge-gui/res/cardsfolder/o/original_skullclamp.txt @@ -0,0 +1,8 @@ +Name:Original Skullclamp +ManaCost:1 +Types:Artifact Equipment +K:Equip:1 +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Equipped creature gets +1/+1. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.EquippedBy | Execute$ TrigDraw | TriggerDescription$ Whenever equipped creature dies, draw two cards. +SVar:TrigDraw:DB$ Draw | NumCards$ 2 +Oracle:Equipped creature gets +1/+1.\nWhenever equipped creature dies, draw two cards.\nEquip {1} diff --git a/forge-gui/res/cardsfolder/p/peacekeeper_avatar.txt b/forge-gui/res/cardsfolder/p/peacekeeper_avatar.txt index fe610d9520b..de9ddc26d4c 100644 --- a/forge-gui/res/cardsfolder/p/peacekeeper_avatar.txt +++ b/forge-gui/res/cardsfolder/p/peacekeeper_avatar.txt @@ -4,5 +4,5 @@ Types:Vanguard HandLifeModifier:+0/+9 A:AB$ RepeatEach | Cost$ 3 | ActivationZone$ Command | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ ArrestEach | StackDescription$ SpellDescription | SpellDescription$ For each opponent who controls a creature, create a token that's a copy of a card named Arrest and attach it to a creature that player controls chosen at random. SVar:ArrestEach:DB$ ChooseCard | Amount$ 1 | Choices$ Creature.RememberedPlayerCtrl | AtRandom$ True | SubAbility$ DBAttach -SVar:DBAttach:DB$ CopyPermanent | NumCopies$ 1 | ValidSupportedCopy$ Card.namedArrest | DefinedName$ Arrest | AttachAfter$ True | AttachedTo$ ChosenCard | ConditionDefined$ ChosenCard | ConditionPresent$ Creature | ConditionCompare$ GE1 +SVar:DBAttach:DB$ CopyPermanent | NumCopies$ 1 | DefinedName$ Arrest | AttachAfter$ True | AttachedTo$ ChosenCard | ConditionDefined$ ChosenCard | ConditionPresent$ Creature | ConditionCompare$ GE1 Oracle:Hand +0, life +9\n{3}: For each opponent who controls a creature, create a token that's a copy of a card named Arrest and attach it to a creature that player controls chosen at random. diff --git a/forge-gui/res/cardsfolder/p/phila_unsealed.txt b/forge-gui/res/cardsfolder/p/phila_unsealed.txt new file mode 100644 index 00000000000..c43f34ec781 --- /dev/null +++ b/forge-gui/res/cardsfolder/p/phila_unsealed.txt @@ -0,0 +1,7 @@ +Name:Phila, Unsealed +ManaCost:4 +Types:Legendary Artifact Creature Rebel Golem +PT:4/4 +S:Mode$ CantPutCounter | ValidPlayer$ You | CounterType$ POISON | Description$ You can't get poison counters. +A:AB$ ChangeZone | Cost$ W U B R G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target artifact. +Oracle:You can't get poison counters.\n{W}{U}{B}{R}{G}: Exile target artifact. diff --git a/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt b/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt new file mode 100644 index 00000000000..81af600549b --- /dev/null +++ b/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt @@ -0,0 +1,14 @@ +Name:Phyrexian Adapter +ManaCost:1 U +Types:Creature Phyrexian Wizard +PT:1/3 +K:Flying +S:Mode$ Continuous | Affected$ Incubator.token+YouCtrl | AddType$ Food,Blood,Clue,Treasure,Powerstone | AddAbility$ FoodSac & BloodSac & ClueSac & TreasureSac & PowerstoneTap | Description$ All Incubator tokens you control become Food, Blood, Clue, Treasure, and Powerstone in addition to their other types, and have the respective abilities of those tokens. (Once they transform, they're no longer Incubator tokens.) +SVar:FoodSac:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME/this artifact> | LifeAmount$ 3 | SpellDescription$ You gain 3 life. +SVar:BloodSac:AB$ Draw | Cost$ 1 T Discard<1/Card> Sac<1/CARDNAME/this artifact> | NumCards$ 1 | SpellDescription$ Draw a card. +SVar:ClueSac:AB$ Draw | Cost$ 2 Sac<1/CARDNAME/this artifact> | NumCards$ 1 | SpellDescription$ Draw a card. +SVar:TreasureSac:AB$ Mana | Cost$ T Sac<1/CARDNAME/this artifact> | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color. +SVar:PowerstoneTap:AB$ Mana | Cost$ T | Produced$ C | RestrictValid$ CantCastNonArtifactSpells | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. +DeckHas:Ability$Sacrifice & Type$Food|Blood|Clue|Treasure|Powerstone +DeckHints:Type$Incubator +Oracle:Flying\nAll Incubator tokens you control become Food, Blood, Clue, Treasure, and Powerstone in addition to their other types, and have the respective abilities of those tokens. (Once they transform, they're no longer Incubator tokens.) diff --git a/forge-gui/res/cardsfolder/p/phyrexian_broodstar.txt b/forge-gui/res/cardsfolder/p/phyrexian_broodstar.txt new file mode 100644 index 00000000000..0eee15bce1b --- /dev/null +++ b/forge-gui/res/cardsfolder/p/phyrexian_broodstar.txt @@ -0,0 +1,12 @@ +Name:Phyrexian Broodstar +ManaCost:6 U U +Types:Creature Phyrexian Beast +PT:*/* +K:Affinity:Phyrexian +K:Flying +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of Phyrexians you control. +SVar:X:Count$Valid Phyrexian.YouCtrl +SVar:NoZeroToughnessAI:True +SVar:BuffedBy:Phyrexian +DeckNeeds:Type$Phyrexian +Oracle:Affinity for Phyrexians (This spell costs {1} less to cast for each Phyrexian you control.)\nFlying\nPhyrexian Broodstar's power and toughness are each equal to the number of Phyrexians you control. diff --git a/forge-gui/res/cardsfolder/p/phyrexian_chimney_imp.txt b/forge-gui/res/cardsfolder/p/phyrexian_chimney_imp.txt new file mode 100644 index 00000000000..b1041f88872 --- /dev/null +++ b/forge-gui/res/cardsfolder/p/phyrexian_chimney_imp.txt @@ -0,0 +1,8 @@ +Name:Phyrexian Chimney Imp +ManaCost:4 PB +Types:Creature Phyrexian Imp +PT:2/3 +K:Flying +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME dies, target opponent puts two cards from their hand on top of their library in any order. +SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Hand | Destination$ Library | LibraryPosition$ 0 | ValidTgts$ Opponent | Chooser$ Targeted | ChangeType$ Card | ChangeNum$ 2 | Mandatory$ True | Reorder$ True | IsCurse$ True +Oracle:Flying\nWhen Phyrexian Chimney Imp dies, target opponent puts two cards from their hand on top of their library in any order. diff --git a/forge-gui/res/cardsfolder/p/phyrexian_esthetician.txt b/forge-gui/res/cardsfolder/p/phyrexian_esthetician.txt new file mode 100644 index 00000000000..45fc8721a8d --- /dev/null +++ b/forge-gui/res/cardsfolder/p/phyrexian_esthetician.txt @@ -0,0 +1,8 @@ +Name:Phyrexian Esthetician +ManaCost:3 R +Types:Artifact Creature Phyrexian Cleric +PT:4/3 +K:Haste +A:AB$ PutCounter | Cost$ 3 R ExileFromGrave<1/CARDNAME> | ActivationZone$ Graveyard | ValidTgts$ Creature | CounterType$ OIL | CounterNum$ ScavengeX | SorcerySpeed$ True | PrecostDesc$ Oil Scavenge | CostDesc$ {3}{R} | SpellDescription$ ({3}{R}, Exile this card from your graveyard: Put a number of oil counters equal to this card's power on target creature. Oil Scavenge only as a sorcery.) +SVar:ScavengeX:Exiled$CardPower +Oracle:Haste\nOil Scavenge {3}{R} ({3}{R}, Exile this card from your graveyard: Put a number of oil counters equal to this card's power on target creature. Oil Scavenge only as a sorcery.) diff --git a/forge-gui/res/cardsfolder/p/phyrexian_ornithopter.txt b/forge-gui/res/cardsfolder/p/phyrexian_ornithopter.txt new file mode 100644 index 00000000000..2c70b87495a --- /dev/null +++ b/forge-gui/res/cardsfolder/p/phyrexian_ornithopter.txt @@ -0,0 +1,7 @@ +Name:Phyrexian Ornithopter +ManaCost:1 +Types:Artifact Creature Thopter +PT:0/2 +K:Flying +K:Toxic:1 +Oracle:Flying\nToxic 1 (Players dealt combat damage by this creature also get a poison counter.) diff --git a/forge-gui/res/cardsfolder/p/potatoes.txt b/forge-gui/res/cardsfolder/p/potatoes.txt new file mode 100644 index 00000000000..34e816768d3 --- /dev/null +++ b/forge-gui/res/cardsfolder/p/potatoes.txt @@ -0,0 +1,10 @@ +Name:Potatoes +ManaCost:0 +Types:Artifact Food +A:AB$ Charm | Cost$ 2 T Sac<1/CARDNAME> | Choices$ Boil,Mash,Stew +SVar:Boil:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 1 | SpellDescription$ Boil — CARDNAME deals 1 damage to any target. +SVar:Mash:DB$ Token | TokenScript$ c_a_food_sac | TokenAmount$ 2 | SpellDescription$ Mash — Create two Food tokens. +SVar:Stew:DB$ GainLife | LifeAmount$ 3 | SubAbility$ DBDraw | SpellDescription$ Stew — Gain 3 life. Draw a card. +SVar:DBDraw:DB$ Draw | NumCards$ 1 +DeckHas:Ability$Sacrifice +Oracle:{2}, {T}, Sacrifice Potatoes: Choose one —\n• Boil — Potatoes deals 1 damage to any target.\n• Mash — Create two Food tokens.\n• Stew — Gain 3 life. Draw a card. diff --git a/forge-gui/res/cardsfolder/q/questing_cosplayer.txt b/forge-gui/res/cardsfolder/q/questing_cosplayer.txt new file mode 100644 index 00000000000..a1df0385b6d --- /dev/null +++ b/forge-gui/res/cardsfolder/q/questing_cosplayer.txt @@ -0,0 +1,9 @@ +Name:Questing Cosplayer +ManaCost:1 G +Types:Creature Human Bard +PT:1/1 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When Questing Cosplayer enters the battlefield, create a Questing Role token and attach it to target creature. (If you control another Role on it, put that one into the graveyard. Enchanted creature has all the abilities of Questing Beast.) +SVar:TrigToken:DB$ Token | TokenScript$ role_questing | AttachedTo$ Targeted | ValidTgts$ Creature +DeckHas:Type$Aura|Role & Ability$Token +DeckHints:Type$Aura +Oracle:When Questing Cosplayer enters the battlefield, create a Questing Role token and attach it to target creature. (If you control another Role on it, put that one into the graveyard. Enchanted creature has all the abilities of Questing Beast.) diff --git a/forge-gui/res/cardsfolder/r/ral_and_the_implicit_maze.txt b/forge-gui/res/cardsfolder/r/ral_and_the_implicit_maze.txt index 618c46c6a6b..ff178e89f71 100644 --- a/forge-gui/res/cardsfolder/r/ral_and_the_implicit_maze.txt +++ b/forge-gui/res/cardsfolder/r/ral_and_the_implicit_maze.txt @@ -7,7 +7,7 @@ SVar:DBImpulseDraw:AB$ Dig | Cost$ Discard<1/Card> | Defined$ You | DigNum$ 2 | 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 them until the end of your next turn. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ spellgorger_weird | TokenOwner$ You | SpellDescription$ Create a Spellgorger Weird token. (It's a {2}{R} 2/2 Weird creature with "Whenever you cast a noncreature spell, put a +1/+1 counter on Spellgorger Weird.") +SVar:DBToken:DB$ CopyPermanent | DefinedName$ Spellgorger Weird | SpellDescription$ Create a Spellgorger Weird token. (It's a {2}{R} 2/2 Weird creature with "Whenever you cast a noncreature spell, put a +1/+1 counter on Spellgorger Weird.") SVar:BuffedBy:nonCreature DeckHas:Ability$Counters Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — Ral and the Implicit Maze deals 2 damage to each creature and planeswalker your opponents control.\nII — You may discard a card. If you do, exile the top two cards of your library. You may play them until the end of your next turn.\nIII — Create a Spellgorger Weird token. (It's a {2}{R} 2/2 Weird creature with "Whenever you cast a noncreature spell, put a +1/+1 counter on Spellgorger Weird.") diff --git a/forge-gui/res/cardsfolder/r/really_charming_prince.txt b/forge-gui/res/cardsfolder/r/really_charming_prince.txt new file mode 100644 index 00000000000..d28327bb723 --- /dev/null +++ b/forge-gui/res/cardsfolder/r/really_charming_prince.txt @@ -0,0 +1,11 @@ +Name:Really Charming Prince +ManaCost:1 U +Types:Creature Faerie Noble +PT:2/1 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ When CARDNAME enters the battlefield, choose one of the following four cards at random: Piracy Charm, Sapphire Charm, Trickery Charm, and Vision Charm. You may create a copy of the chosen card and cast that copy without paying its mana cost. +SVar:TrigChoose:DB$ NameCard | AtRandom$ True | ChooseFromList$ Piracy Charm,Sapphire Charm,Trickery Charm,Vision Charm | SubAbility$ DBCast | StackDescription$ SpellDescription +SVar:DBCast:DB$ Play | WithoutManaCost$ True | CopyFromChosenName$ True | Optional$ True | SubAbility$ DBCleanup | StackDescription$ None +SVar:DBCleanup:DB$ Cleanup | ClearNamedCard$ True +SVar:PlayMain1:TRUE +Oracle:Flying\nWhen Really Charming Prince enters the battlefield, choose one of the following four cards at random: Piracy Charm, Sapphire Charm, Trickery Charm, and Vision Charm. You may create a copy of the chosen card and cast that copy without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/r/red_priest_of_yawgmoth.txt b/forge-gui/res/cardsfolder/r/red_priest_of_yawgmoth.txt new file mode 100644 index 00000000000..c09aa4a917f --- /dev/null +++ b/forge-gui/res/cardsfolder/r/red_priest_of_yawgmoth.txt @@ -0,0 +1,8 @@ +Name:Red Priest of Yawgmoth +ManaCost:1 R +Types:Artifact Creature Phyrexian Cleric +PT:1/2 +A:AB$ Mana | Cost$ T Sac<1/Artifact> | Produced$ R | Amount$ X | SpellDescription$ Add an amount of {R} equal to the sacrificed artifact's mana value. +SVar:X:Sacrificed$CardManaCost +DeckHas:Ability$Sacrifice +Oracle:{T}, Sacrifice an artifact: Add an amount of {R} equal to the sacrificed artifact's mana value. diff --git a/forge-gui/res/cardsfolder/r/riku_and_riku.txt b/forge-gui/res/cardsfolder/r/riku_and_riku.txt new file mode 100644 index 00000000000..3fedb2b674e --- /dev/null +++ b/forge-gui/res/cardsfolder/r/riku_and_riku.txt @@ -0,0 +1,8 @@ +Name:Riku and Riku +ManaCost:2 RG U +Types:Legendary Creature Human Wizard +PT:2/2 +K:Double Strike +A:AB$ CopySpellAbility | Cost$ U R | GameActivationLimit$ 1 | TgtPrompt$ Select target instant or sorcery spell you control | ValidTgts$ Instant.YouCtrl,Sorcery.YouCtrl | TargetType$ Spell | SpellDescription$ Copy target instant or sorcery spell you control. Activate this ability only once. +A:AB$ CopySpellAbility | Cost$ G U | GameActivationLimit$ 1 | TgtPrompt$ Select target creature spell you control | ValidTgts$ Creature.YouCtrl | TargetType$ Spell | SpellDescription$ Copy target creature spell you control. Activate this ability only once. +Oracle:Double strike\n{U}{R}: Copy target instant or sorcery spell you control. Activate this ability only once.\n{G}{U}: Copy target creature spell you control. Activate this ability only once. (Copies of permanent spells enter the battlefield as tokens.) diff --git a/forge-gui/res/cardsfolder/r/riven_turnbull_and_princess_lucrezia.txt b/forge-gui/res/cardsfolder/r/riven_turnbull_and_princess_lucrezia.txt new file mode 100644 index 00000000000..cc7b653bc23 --- /dev/null +++ b/forge-gui/res/cardsfolder/r/riven_turnbull_and_princess_lucrezia.txt @@ -0,0 +1,6 @@ +Name:Riven Turnbull and Princess Lucrezia +ManaCost:5 U B +Types:Legendary Creature Human Advisor Wizard +PT:10/11 +A:AB$ Mana | Cost$ T | Produced$ U B | SpellDescription$ Add {U}{B}. +Oracle:{T}: Add {U}{B}. diff --git a/forge-gui/res/cardsfolder/s/sagrada_familiar.txt b/forge-gui/res/cardsfolder/s/sagrada_familiar.txt new file mode 100644 index 00000000000..bad8161032c --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sagrada_familiar.txt @@ -0,0 +1,12 @@ +Name:Sagrada Familiar +ManaCost:3 +Types:Artifact Creature Wall +PT:0/5 +K:Reach +K:Defender +S:Mode$ ReduceCost | ValidCard$ Card.IsCommander+YouCtrl | Type$ Spell | Activator$ You | Amount$ 1 | Description$ Commander spells you cast cost {1} less to cast. +T:Mode$ SpellCast | ValidCard$ Card.IsCommander+YouCtrl | ValidActivatingPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a commander spell, create X 1/1 Stained Glass artifact creature tokens that are all colors, where X is the number of colors of that commander. +SVar:TrigToken:DB$ Token | TokenScript$ all_1_1_a_stained_glass | TokenAmount$ X +SVar:X:TriggeredCard$CardNumColors +DeckHas:Ability$Token +Oracle:Reach, defender\nCommander spells you cast cost {1} less to cast.\nWhenever you cast a commander spell, create X 1/1 Stained Glass artifact creature tokens that are all colors, where X is the number of colors of that commander. 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/s/segovian_sword.txt b/forge-gui/res/cardsfolder/s/segovian_sword.txt new file mode 100644 index 00000000000..5dd90e16cd8 --- /dev/null +++ b/forge-gui/res/cardsfolder/s/segovian_sword.txt @@ -0,0 +1,11 @@ +Name:Segovian Sword +ManaCost:3 +Types:Artifact Equipment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ For Segovia! (When this Equipment enters the battlefield, create a -1/-1 blue Squid creature token, then attach this to it. Yes, it's a -1/-1 creature.) +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ u_m1_m1_squid | TokenOwner$ You | RememberTokens$ True | SubAbility$ DBAttach +SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Token & Type$Squid +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Skulk | Description$ Equipped creature gets +2/+2 and has skulk. +K:Equip:3 +Oracle:For Segovia! (When this Equipment enters the battlefield, create a -1/-1 blue Squid creature token, then attach this to it. Yes, it's a -1/-1 creature.)\nEquipped creature gets +2/+2 and has skulk. (It can't be blocked by creatures with greater power.)\nEquip {3} diff --git a/forge-gui/res/cardsfolder/s/soul_of_mirrodin.txt b/forge-gui/res/cardsfolder/s/soul_of_mirrodin.txt new file mode 100644 index 00000000000..3ea0697331d --- /dev/null +++ b/forge-gui/res/cardsfolder/s/soul_of_mirrodin.txt @@ -0,0 +1,8 @@ +Name:Soul of Mirrodin +ManaCost:6 +Types:Artifact Creature Spirit +PT:6/6 +K:Trample +A:AB$ ChangeZone | Cost$ 5 | Origin$ Library | Destination$ Battlefield | ChangeType$ Artifact.cmcLE5 | Tapped$ True | ChangeNum$ 1 | Shuffle$ True | SpellDescription$ Search your library for an artifact card with mana value 5 or less, put it onto the battlefield tapped, then shuffle. +A:AB$ ChangeZone | Cost$ 5 ExileFromGrave<1/CARDNAME> | ActivationZone$ Graveyard | Origin$ Library | Destination$ Battlefield | ChangeType$ Artifact.cmcLE5 | Tapped$ True | ChangeNum$ 1 | Shuffle$ True | SpellDescription$ Search your library for an artifact card with mana value 5 or less, put it onto the battlefield tapped, then shuffle. +Oracle:Trample\n{5}: Search your library for an artifact card with mana value 5 or less, put it onto the battlefield tapped, then shuffle.\n{5}, Exile Soul of Mirrodin from your graveyard: Search your library for an artifact card with mana value 5 or less, put it onto the battlefield tapped, then shuffle. diff --git a/forge-gui/res/cardsfolder/s/sword_of_fire_and_ice_and_war_and_peace.txt b/forge-gui/res/cardsfolder/s/sword_of_fire_and_ice_and_war_and_peace.txt new file mode 100644 index 00000000000..c5276c05fcf --- /dev/null +++ b/forge-gui/res/cardsfolder/s/sword_of_fire_and_ice_and_war_and_peace.txt @@ -0,0 +1,14 @@ +Name:Sword of Fire and Ice and War and Peace +ManaCost:6 +Types:Artifact Equipment +K:Equip:4 +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 4 | AddToughness$ 4 | AddSVar$ SwordOfFireAndIceCE | AddKeyword$ Protection from white & Protection from blue & Protection from red | Description$ Equipped creature gets +4/+4 and has protection from white, blue, and red. +T:Mode$ DamageDone | ValidSource$ Creature.EquippedBy | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDealDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever equipped creature deals combat damage to an opponent, CARDNAME deals 2 damage to any target and you draw a card. Then, it deals damage to defending player equal to the number of cards in their hand and you gain 1 life for each card in your hand. +SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ 2 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBWar +SVar:DBWar:DB$ DealDamage | Defined$ TriggeredTarget | NumDmg$ X | SubAbility$ DBGain +SVar:X:TriggeredTarget$CardsInHand +SVar:DBGain:DB$ GainLife | Defined$ You | LifeAmount$ Y +SVar:Y:Count$CardsInYourHand +SVar:SwordOfFireAndIceCE:SVar:MustBeBlocked:AttackingPlayerConservative +Oracle:Equipped creature gets +4/+4 and has protection from white, blue, and red.\nWhenever equipped creature deals combat damage to an opponent, Sword of Fire and Ice and War and Peace deals 2 damage to any target and you draw a card. Then, it deals damage to defending player equal to the number of cards in their hand and you gain 1 life for each card in your hand.\nEquip {4} diff --git a/forge-gui/res/cardsfolder/t/tarkir_charm.txt b/forge-gui/res/cardsfolder/t/tarkir_charm.txt new file mode 100644 index 00000000000..93d7a1331b7 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/tarkir_charm.txt @@ -0,0 +1,10 @@ +Name:Tarkir Charm +ManaCost:3 R +Types:Sorcery +A:SP$ Charm | Choices$ BatheInDragonfire,HordelingOutburst,SarkhansTriumph | Defined$ You +SVar:BatheInDragonfire:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 4 | SpellDescription$ CARDNAME deals 4 damage to target creature. +SVar:HordelingOutburst:DB$ Token | TokenAmount$ 3 | TokenScript$ r_1_1_goblin | TokenOwner$ You | SpellDescription$ Create three 1/1 red Goblin creature tokens. +SVar:SarkhansTriumph:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Creature.Dragon | ChangeNum$ 1 | SpellDescription$ Search your library for a Dragon creature card, reveal it, put it into your hand, then shuffle. +DeckHas:Ability$Token & Type$Goblin +DeckHints:Type$Dragon +Oracle:Choose one —\n• Bathe in Dragonfire (4 damage to a creature.)\n• Hordeling Outburst (Create three 1/1 Goblin tokens.)\n• Sarkhan's Triumph (Search for a dragon.) diff --git a/forge-gui/res/cardsfolder/t/tarmogoyf_nest.txt b/forge-gui/res/cardsfolder/t/tarmogoyf_nest.txt index 58947bb0f0c..aa6a645b1f6 100644 --- a/forge-gui/res/cardsfolder/t/tarmogoyf_nest.txt +++ b/forge-gui/res/cardsfolder/t/tarmogoyf_nest.txt @@ -4,6 +4,6 @@ Types:Kindred Enchantment Lhurgoyf Aura K:Enchant land A:SP$ Attach | Cost$ 2 G | ValidTgts$ Land | AILogic$ Pump S:Mode$ Continuous | Affected$ Land.AttachedBy | AddAbility$ Token | Description$ Enchanted land has "{T}: Create a Tarmogoyf token. (It's a {1}{G} Lhurgoyf creature with "Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.") -SVar:Token:AB$ Token | Cost$ 1 G T | TokenAmount$ 1 | TokenScript$ tarmogoyf | TokenOwner$ You | SpellDescription$ Create a Tarmogoyf token. (It's a {1}{G} Lhurgoyf creature with "Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.") +SVar:Token:AB$ CopyPermanent | Cost$ 1 G T | DefinedName$ Tarmogoyf | SpellDescription$ Create a Tarmogoyf token. (It's a {1}{G} Lhurgoyf creature with "Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.") DeckHas:Ability$Token & Type$Lhurgoyf Oracle:Enchant land\nEnchanted land has "{1}{G}, {T}: Create a Tarmogoyf token. (It's a {1}{G} Lhurgoyf creature with "Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.") diff --git a/forge-gui/res/cardsfolder/t/the_alright_henge.txt b/forge-gui/res/cardsfolder/t/the_alright_henge.txt new file mode 100644 index 00000000000..f2579d1c9bd --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_alright_henge.txt @@ -0,0 +1,8 @@ +Name:The Alright Henge +ManaCost:3 G +Types:Artifact +A:AB$ Mana | Cost$ T | Produced$ G | Amount$ 2 | SpellDescription$ Add {G}{G}. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever a nontoken creature enters the battlefield under your control, put a +1/+1 counter on it. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCardLKICopy | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters +Oracle:{T}: Add {G}{G}. You gain 2 life.\nWhenever a nontoken creature enters the battlefield under your control, put a +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/t/the_belligerent_and_useless_island.txt b/forge-gui/res/cardsfolder/t/the_belligerent_and_useless_island.txt new file mode 100644 index 00000000000..ad72b4ff530 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_belligerent_and_useless_island.txt @@ -0,0 +1,12 @@ +Name:The Belligerent and Useless Island +ManaCost:no cost +Types:Legendary Artifact Land Vehicle Island +PT:2/2 +R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters the battlefield tapped. +SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player,Battle | Execute$ TrigDraw | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player or battle, draw a card then discard a card. +SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ You | SubAbility$ DBDiscard +SVar:DBDiscard:DB$ Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1 +K:Crew:2 +DeckHas:Ability$Discard +Oracle:The Belligerent and Useless Island enters the battlefield tapped.\nWhenever The Belligerent and Useless Island deals combat damage to a player or battle, draw a card then discard a card.\nCrew 2 diff --git a/forge-gui/res/cardsfolder/t/the_dilu_horse.txt b/forge-gui/res/cardsfolder/t/the_dilu_horse.txt new file mode 100644 index 00000000000..8ac1a85f058 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_dilu_horse.txt @@ -0,0 +1,10 @@ +Name:The Dilu Horse +ManaCost:2 G +Types:Legendary Creature Horse +PT:2/2 +K:Horsemanship +K:Partner +S:Mode$ Continuous | Affected$ Card.YouCtrl+IsCommander | AddKeyword$ Horsemanship | Description$ Commanders you control have horsemanship. +SVar:PlayMain1:TRUE +AI:RemoveDeck:NonCommander +Oracle:Horsemanship (This creature can't be blocked except by creatures with horsemanship.)\nCommanders you control have horsemanship.\nPartner (You can have two commanders if both have partner.) diff --git a/forge-gui/res/cardsfolder/t/the_forgotten_place.txt b/forge-gui/res/cardsfolder/t/the_forgotten_place.txt new file mode 100644 index 00000000000..1c8d32f0105 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/the_forgotten_place.txt @@ -0,0 +1,9 @@ +Name:The Forgotten Place +ManaCost:no cost +Types:Land Locus Sphere +A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. +A:AB$ Draw | Cost$ 2 T Sac<1/CARDNAME> | NumCards$ X | SpellDescription$ Draw a card for each Locus and/or Sphere in your graveyard. +SVar:X:Count$ValidGraveyard Locus.YouOwn,Sphere.YouOwn +DeckHas:Ability$Sacrifice|Mana.Colorless +DeckHints:Type$Locus|Sphere +Oracle:{T}: Add {C}.\n{2}, {T}, Sacrifice The Forgotten Place: Draw a card for each Locus and/or Sphere in your graveyard. diff --git a/forge-gui/res/cardsfolder/t/then_dreadmaws_ate_everyone.txt b/forge-gui/res/cardsfolder/t/then_dreadmaws_ate_everyone.txt new file mode 100644 index 00000000000..00d7fde5d51 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/then_dreadmaws_ate_everyone.txt @@ -0,0 +1,7 @@ +Name:Then, Dreadmaws Ate Everyone +ManaCost:X 4 G G +Types:Sorcery +A:SP$ Token | TokenAmount$ X | TokenScript$ colossal_dreadmaw | TokenOwner$ You | SpellDescription$ Create X 6/6 green Dinosaur creature tokens with trample named Colossal Dreadmaw. +SVar:X:Count$xPaid +DeckHas:Ability$Token & Type$Dinosaur +Oracle:Create X 6/6 green Dinosaur creature tokens with trample named Colossal Dreadmaw. diff --git a/forge-gui/res/cardsfolder/t/theros_charm.txt b/forge-gui/res/cardsfolder/t/theros_charm.txt new file mode 100644 index 00000000000..7b5286c0bea --- /dev/null +++ b/forge-gui/res/cardsfolder/t/theros_charm.txt @@ -0,0 +1,9 @@ +Name:Theros Charm +ManaCost:3 W +Types:Instant +A:SP$ Charm | Choices$ IdyllicTutor,RevokeExistence,Reprisal | Defined$ You +SVar:IdyllicTutor:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Enchantment | ChangeNum$ 1 | SpellDescription$ Search your library for an enchantment card, reveal it, put it into your hand, then shuffle. +SVar:RevokeExistence:DB$ ChangeZone | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | Origin$ Battlefield | Destination$ Exile | SpellDescription$ Exile target artifact or enchantment. +SVar:Reprisal:DB$ Destroy | ValidTgts$ Creature.powerGE4 | TgtPrompt$ Select target creature with power 4 or greater | NoRegen$ True | SpellDescription$ Destroy target creature with power 4 or greater. It can't be regenerated. +DeckHints:Type$Enchantment +Oracle:Choose one —\n• Idyllic Tutor (Search for an enchantment.)\n• Revoke Existence (Exile an artifact or enchantment.)\n• Reprisal (Destroy a creature with power 4 or greater. It can't be regenerated.) diff --git a/forge-gui/res/cardsfolder/t/toe_breaking_helmet.txt b/forge-gui/res/cardsfolder/t/toe_breaking_helmet.txt new file mode 100644 index 00000000000..6ef9d66a801 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/toe_breaking_helmet.txt @@ -0,0 +1,8 @@ +Name:Toe-Breaking Helmet +ManaCost:1 +Types:Artifact Equipment +K:Equip:1 +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 1 | AddToughness$ 1 | Description$ Equipped creature gets +1/+1. +A:AB$ PutCounter | Cost$ 2 T Sac<1/CARDNAME> | ValidTgts$ Creature | IsCurse$ True | CounterType$ M1M1 | CounterNum$ 2 | SorcerySpeed$ True | SpellDescription$ Put two -1/-1 counters on target creature. Activate only as a sorcery. +DeckHas:Ability$Counters +Oracle:Equipped creature gets +1/+1.\n{2}, {T}, Sacrifice Toe-Breaking Helmet: Put two -1/-1 counters on target creature. Activate only as a sorcery.\nEquip {1} diff --git a/forge-gui/res/cardsfolder/t/toothy_and_zndrsplt.txt b/forge-gui/res/cardsfolder/t/toothy_and_zndrsplt.txt new file mode 100644 index 00000000000..86519d42f95 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/toothy_and_zndrsplt.txt @@ -0,0 +1,14 @@ +Name:Toothy and Zndrsplt +ManaCost:3 U +Types:Legendary Creature Homunculus Illusion +PT:2/2 +T:Mode$ FlippedCoin | ValidPlayer$ You | ValidResult$ Win | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you win a coin flip, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigFlip | TriggerDescription$ At the beginning of combat on your turn, flip a coin until you lose a flip. +SVar:TrigFlip:DB$ FlipACoin | FlipUntilYouLose$ True +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME leaves the battlefield, draw a card for each +1/+1 counter on it. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ X +SVar:X:TriggeredCard$CardCounters.P1P1 +SVar:PlayMain1:TRUE +DeckHas:Ability$Counters +Oracle:Whenever you win a coin flip, put a +1/+1 counter on Toothy and Zndrsplt.\nAt the beginning of combat on your turn, flip a coin until you lose a flip.\nWhen Toothy and Zndrsplt leaves the battlefield, draw a card for each +1/+1 counter on it. diff --git a/forge-gui/res/cardsfolder/t/try_my_deck_elemental.txt b/forge-gui/res/cardsfolder/t/try_my_deck_elemental.txt new file mode 100644 index 00000000000..6fe86d12025 --- /dev/null +++ b/forge-gui/res/cardsfolder/t/try_my_deck_elemental.txt @@ -0,0 +1,8 @@ +Name:Try-My-Deck Elemental +ManaCost:3 W +Types:Creature Elemental +PT:4/3 +K:Flying +S:Mode$ Continuous | Affected$ Card.IsCommander+YouCtrl | AffectedZone$ Stack | AddKeyword$ Demonstrate | Description$ Commander spells you cast have demonstrate. (When you cast a commander spell, you may copy it. If you do, choose an opponent to also copy it. The copies become tokens.) +S:Mode$ IgnoreLegendRule | ValidCard$ Card.IsCommander+YouCtrl | Description$ The "legend rule" doesn't apply to commanders you control. +Oracle:Flying\nCommander spells you cast have demonstrate. (When you cast a commander spell, you may copy it. If you do, choose an opponent to also copy it. The copies become tokens.)\nThe "legend rule" doesn't apply to commanders you control. diff --git a/forge-gui/res/cardsfolder/u/ulgrotha_charm.txt b/forge-gui/res/cardsfolder/u/ulgrotha_charm.txt new file mode 100644 index 00000000000..de267cddeab --- /dev/null +++ b/forge-gui/res/cardsfolder/u/ulgrotha_charm.txt @@ -0,0 +1,11 @@ +Name:Ulgrotha Charm +ManaCost:2 U +Types:Instant +A:SP$ Charm | Choices$ MerchantScroll,MemoryLapse,Forget | Defined$ You +SVar:MerchantScroll:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Instant.Blue | ChangeNum$ 1 | SpellDescription$ Search your library for a blue instant card, reveal that card, put it into your hand, then shuffle. +SVar:MemoryLapse:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | Destination$ TopOfLibrary | SpellDescription$ Counter target spell. If that spell is countered this way, put it on top of its owner's library instead of into that player's graveyard. +SVar:Forget:DB$ Discard | ValidTgts$ Player | TgtPrompt$ Select target player | Mode$ TgtChoose | NumCards$ 2 | RememberDiscarded$ True | SubAbility$ DBDraw | SpellDescription$ Target player discards two cards, then draws as many cards as they discarded this way. +SVar:DBDraw:DB$ Draw | Defined$ Targeted | NumCards$ X | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$Amount +Oracle:Choose one —\n• Merchant Scroll (Search for a blue instant.)\n• Memory Lapse (Counter a spell and put it on top of its owner's library.)\n• Forget (Target player discards 2, then draws that many.) diff --git a/forge-gui/res/cardsfolder/upcoming/insatiable_frugivore.txt b/forge-gui/res/cardsfolder/upcoming/insatiable_frugivore.txt index 97dc4c2a5ae..c54902929b6 100644 --- a/forge-gui/res/cardsfolder/upcoming/insatiable_frugivore.txt +++ b/forge-gui/res/cardsfolder/upcoming/insatiable_frugivore.txt @@ -6,8 +6,8 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ You | TokenScript$ c_a_food_sac | SubAbility$ DBStoreSVar SVar:DBStoreSVar:DB$ StoreSVar | SVar$ CheckNotPaid | Type$ Number | Expression$ 1 | SubAbility$ DBRepeat SVar:DBRepeat:DB$ Repeat | RepeatSubAbility$ DBToken | RepeatCheckSVar$ CheckNotPaid | RepeatSVarCompare$ GT0 -SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ You | UnlessCost$ ExileFromGrave<3/Card> | UnlessPayer$ You | UnlessSwitched$ True | UnlessResolveSubs$ WhenNotPaid | SubAbility$ DBStoreSVar | TokenScript$ c_a_food_sac -SVar:DBStoreSVar:DB$ StoreSVar | SVar$ CheckNotPaid | Type$ Number | Expression$ 0 +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ You | UnlessCost$ ExileFromGrave<3/Card> | UnlessPayer$ You | UnlessSwitched$ True | UnlessResolveSubs$ WhenNotPaid | SubAbility$ DBStoreSVarT | TokenScript$ c_a_food_sac +SVar:DBStoreSVarT:DB$ StoreSVar | SVar$ CheckNotPaid | Type$ Number | Expression$ 0 A:AB$ PumpAll | Cost$ 3 B Sac | ValidCards$ Creature.YouCtrl | NumAtt$ +X | KW$ Menace | SpellDescription$ Creatures you control get +X/+0 and gain menace until end of turn. SVar:CheckNotPaid:Number$1 SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/upcoming/new_master_of_arms.txt b/forge-gui/res/cardsfolder/upcoming/new_master_of_arms.txt new file mode 100644 index 00000000000..8b185a9905f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/new_master_of_arms.txt @@ -0,0 +1,8 @@ +Name:New Master of Arms +ManaCost:2 W +Types:Creature Human Soldier +PT:2/2 +K:First Strike +R:Event$ DamageDone | Prevent$ True | IsCombat$ True | ValidSource$ Creature.blocking+tapped | Description$ Prevent all combat damage that would be dealt by blocking creatures that are tapped. +A:AB$ Tap | Cost$ 1 W | ValidTgts$ Creature.blockingSource | TgtPrompt$ Select target creature blocking CARDNAME | SpellDescription$ Tap target creature blocking CARDNAME. +Oracle:First strike\nPrevent all combat damage that would be dealt by blocking creatures that are tapped.\n{1}{W}: Tap target creature blocking New Master of Arms. diff --git a/forge-gui/res/cardsfolder/upcoming/slumbering_waterways.txt b/forge-gui/res/cardsfolder/upcoming/slumbering_waterways.txt new file mode 100644 index 00000000000..3b16468534b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/slumbering_waterways.txt @@ -0,0 +1,10 @@ +Name:Slumbering Waterways +ManaCost:no cost +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 +A:AB$ Mana | Cost$ T | Produced$ Combo G U | SpellDescription$ Add {G} or {U}. +K:Flying +K:Vigilance +K:Trample +Oracle:Slumbering Waterways enters tapped.\n{T}: Add {G} or {U}.\nFlying, vigilance, trample diff --git a/forge-gui/res/cardsfolder/upcoming/teferi_druid_of_argoth.txt b/forge-gui/res/cardsfolder/upcoming/teferi_druid_of_argoth.txt new file mode 100644 index 00000000000..ca27018577b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/teferi_druid_of_argoth.txt @@ -0,0 +1,8 @@ +Name:Teferi, Druid of Argoth +ManaCost:2 G G G +Types:Legendary Creature Human Druid +PT:3/4 +K:Flash +S:Mode$ Continuous | Affected$ Creature.YouOwn+nonToken | AffectedZone$ Hand,Graveyard,Exile,Library,Command,Stack | AddKeyword$ Flash | Description$ Creature cards you own that aren't on the battlefield have flash. +S:Mode$ CantBeCast | ValidCard$ Card | OnlySorcerySpeed$ True | Caster$ Opponent | Description$ Each opponent can cast spells only any time they could cast a sorcery. +Oracle:Flash\nCreature cards you own that aren't on the battlefield have flash.\nEach opponent can cast spells only any time they could cast a sorcery. diff --git a/forge-gui/res/cardsfolder/upcoming/temur_elevator.txt b/forge-gui/res/cardsfolder/upcoming/temur_elevator.txt new file mode 100644 index 00000000000..84e9621b34b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/temur_elevator.txt @@ -0,0 +1,8 @@ +Name:Temur Elevator +ManaCost:no cost +Types:Land +K:Ascend +A:AB$ Mana | Cost$ T | Produced$ Combo G U R | SubAbility$ DBLoseLife | SpellDescription$ Add {G}, {U}, or {R}. If you don’t have the city’s blessing, you lose 1 life. +SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ X | Defined$ You +SVar:X:Count$Blessing.0.1 +Oracle:Ascend (If you control ten or more permanents, you get the city’s blessing for the rest of the game.)\n{T}: Add {G}, {U}, or {R}. If you don’t have the city’s blessing, you lose 1 life. diff --git a/forge-gui/res/cardsfolder/upcoming/under_construction_skyscraper.txt b/forge-gui/res/cardsfolder/upcoming/under_construction_skyscraper.txt new file mode 100644 index 00000000000..bf36753b000 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/under_construction_skyscraper.txt @@ -0,0 +1,13 @@ +Name:Under-Construction Skyscraper +ManaCost:no cost +Types:Land +K:Level up:1 +SVar:maxLevel:8 +A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}. +DeckHas:Ability$Mana.Colorless +S:Mode$ Continuous | Affected$ Card.Self | AddAbility$ ABManaAbzan | IsPresent$ Card.Self+counters_GE1_LEVEL+counters_LE7_LEVEL | Description$ LEVEL 1-7 {T}: Add {W}, {B}, {G}, or {C}. +SVar:ABManaAbzan:AB$ Mana | Cost$ T | Produced$ Combo W B G C | SpellDescription$ Add {W}, {B}, {G}, or {C}. +S:Mode$ Continuous | Affected$ Card.Self | AddAbility$ ABManaScry | IsPresent$ Card.Self+counters_GE8_LEVEL | Description$ LEVEL 8+ {T}: Add {W}, {B}, {G}, or {C}. Scry 1. +SVar:ABManaScry:AB$ Mana | Cost$ T | Produced$ Combo W B G C | Subability$ DBScry | SpellDescription$ Add {W}, {B}, {G}, or {C}. Scry 1. +SVar:DBScry:DB$ Scry | ScryNum$ 1 +Oracle:Level up {1} ({1}: Put a level counter on this. Level up only as a sorcery.)\n{T}: Add {C}.\nLEVEL 1-7\n{T}: Add {W}, {B}, {G}, or {C}.\nLEVEL 8+\n{T}: Add {W}, {B}, {G}, or {C}. Scry 1. diff --git a/forge-gui/res/cardsfolder/upcoming/wisedrafters_will.txt b/forge-gui/res/cardsfolder/upcoming/wisedrafters_will.txt new file mode 100644 index 00000000000..a00ed56f1f8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wisedrafters_will.txt @@ -0,0 +1,9 @@ +Name:Wisedrafter's Will +ManaCost:U +Types:Enchantment +S:Mode$ Continuous | AffectedZone$ Hand | Affected$ Card.OppOwn | MayLookAt$ Player | Description$ Your opponents play with their hands revealed. +A:AB$ Draw | Cost$ U Sac<1/CARDNAME> | SpellDescription$ Draw a card. +A:AB$ Counter | Cost$ U U Sac<1/CARDNAME> | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | SpellDescription$ Counter target spell. +SVar:NonStackingEffect:True +AI:RemoveDeck:All +Oracle:Your opponents play with their hands revealed.\n{U}, Sacrifice Wisedrafter’s Will: Draw a card.\n{U}{U}, Sacrifice Wisedrafter’s Will: Counter target spell. diff --git a/forge-gui/res/cardsfolder/upcoming/wrenn_and_one.txt b/forge-gui/res/cardsfolder/upcoming/wrenn_and_one.txt new file mode 100644 index 00000000000..2f12f433cc9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wrenn_and_one.txt @@ -0,0 +1,13 @@ +Name:Wrenn and One +ManaCost:no cost +Colors:green +Types:Land Planeswalker Wrenn +Loyalty:1 +A:AB$ Animate | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ Self | Abilities$ ABMana | Duration$ UntilYourNextTurn | StackDescription$ SpellDescription | SpellDescription$ CARDNAME gains "{T}: Add {G}" until your next turn. +SVar:ABMana:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. +A:AB$ Token | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | TokenScript$ g_1_1_squirrel | StackDescription$ REP Create_{p:You} creates | SpellDescription$ Create a 1/1 green Squirrel creature token. +A:AB$ Effect | Cost$ SubCounter<4/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Emblem — Wrenn and One | Image$ emblem_wrenn_and_one | Triggers$ TrigCradle | Duration$ Permanent | StackDescription$ REP You get_{p:You} gets | SpellDescription$ You get an emblem with "At the beginning of your precombat main phase, add {G} for each creature you control." +SVar:TrigCradle:Mode$ Phase | Phase$ Main1 | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigMana | TriggerDescription$ At the beginning of your precombat main phase, add {G} for each creature you control. +SVar:TrigMana:DB$ Mana | Produced$ G | Amount$ X | Defined$ You +SVar:X:Count$Valid Creature.YouCtrl +Oracle:[+1]: Wrenn and One gains "{T}: Add {G}" until your next turn.\n[−1]: Create a 1/1 green Squirrel creature token.\n[−4]: You get an emblem with "At the beginning of your precombat main phase, add {G} for each creature you control." diff --git a/forge-gui/res/cardsfolder/w/welcome_to_miniapolis.txt b/forge-gui/res/cardsfolder/w/welcome_to_miniapolis.txt new file mode 100644 index 00000000000..6afb665aa60 --- /dev/null +++ b/forge-gui/res/cardsfolder/w/welcome_to_miniapolis.txt @@ -0,0 +1,6 @@ +Name:Welcome to Mini-apolis +ManaCost:3 U U +Types:Enchantment +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigCopySpell | TriggerDescription$ Whenever an opponent casts a creature spell, create a token that's a copy of it, except it's 1/1. +SVar:TrigCopySpell:DB$ CopySpellAbility | Controller$ You | Defined$ TriggeredSpellAbility | SetPower$ 1 | SetToughness$ 1 +Oracle:Whenever an opponent casts a creature spell, create a token that's a copy of it, except it's 1/1. diff --git a/forge-gui/res/cardsfolder/w/wheel_of_potential.txt b/forge-gui/res/cardsfolder/w/wheel_of_potential.txt index 453284c8ec5..a862ebbc54b 100644 --- a/forge-gui/res/cardsfolder/w/wheel_of_potential.txt +++ b/forge-gui/res/cardsfolder/w/wheel_of_potential.txt @@ -1,18 +1,18 @@ Name:Wheel of Potential ManaCost:2 R Types:Sorcery -A:SP$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 3 | SubAbility$ ChooseX | StackDescription$ REP You get_{p:You} gets & you_ | SpellDescription$ You get {E}{E}{E} (three energy counters), then you may pay X {E}.,,,,,, +A:SP$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 3 | SubAbility$ ChooseX | StackDescription$ REP You get_{p:You} gets & you_ | SpellDescription$ You get {E}{E}{E} (three energy counters), then you may pay any amount of {E}.,,,,,, SVar:ChooseX:DB$ ChooseNumber | Max$ Count$YourCountersEnergy | ListTitle$ amount of energy to pay | SubAbility$ Pay | StackDescription$ None SVar:Pay:DB$ Pump | UnlessCost$ Mandatory PayEnergy | UnlessPayer$ You | UnlessSwitched$ True | SubAbility$ Choose | StackDescription$ None -SVar:Choose:DB$ GenericChoice | TempRemember$ Chooser | ShowChoice$ ExceptSelf | Defined$ Player | Choices$ ExileDraw,No | SubAbility$ DBExile | StackDescription$ SpellDescription | SpellDescription$ Each player may exile their hand and draw X cards. +SVar:Choose:DB$ GenericChoice | TempRemember$ Chooser | ShowChoice$ ExceptSelf | Defined$ Player | Choices$ ExileDraw,No | SubAbility$ Exile | StackDescription$ SpellDescription | SpellDescription$ Each player may exile their hand and draw cards equal to the amount of {E} paid this way. SVar:ExileDraw:DB$ Pump | Defined$ Remembered | NoteCards$ Self | NoteCardsFor$ ExileDraw | SpellDescription$ Exile your hand and draw X cards. SVar:No:DB$ Pump | SpellDescription$ Keep your hand. -SVar:ExileDraw:DB$ ChangeZoneAll | Origin$ Hand | Destination$ Exile | ChangeType$ Card.OwnedBy Player.NotedForExile | RememberChanged$ True | SubAbility$ Draw | StackDescription$ None -SVar:Draw:DB$ Draw | Defined$ Player.NotedForExile | NumCards$ X | SubAbility$ Effect | StackDescription$ None -SVar:Effect:DB$ Effect | ConditionCheckSVar$ X | ConditionSVarCompare$ GE7 | RememberObjects$ Remembered.YouOwn | StaticAbilities$ Play | Duration$ UntilTheEndOfYourNextTurn | ForgetOnMoved$ Exile | SubAbility$ DBCleanup | SpellDescription$ If X is 7 or more, you may play cards you own exiled this way until the end of your next turn. +SVar:Exile:DB$ ChangeZoneAll | Origin$ Hand | Destination$ Exile | Defined$ Player.NotedForExileDraw | RememberChanged$ True | SubAbility$ Draw | StackDescription$ None +SVar:Draw:DB$ Draw | Defined$ Player.NotedForExileDraw | NumCards$ X | SubAbility$ Effect | StackDescription$ None +SVar:Effect:DB$ Effect | ConditionCheckSVar$ X | ConditionSVarCompare$ GE7 | RememberObjects$ Remembered.YouOwn | StaticAbilities$ Play | Duration$ UntilTheEndOfYourNextTurn | ForgetOnMoved$ Exile | SubAbility$ DBCleanup | SpellDescription$ If 7 or more {E} was paid this way, you may play cards you own exiled this way until the end of your next turn. SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.YouOwn+IsRemembered | AffectedZone$ Exile | Description$ You may play cards you own exiled this way until the end of your next turn. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBClearNotes -SVar:DBClearNotes:DB$ Pump | Defined$ Player | ClearNotedCardsFor$ Exile +SVar:DBClearNotes:DB$ Pump | Defined$ Player | ClearNotedCardsFor$ ExileDraw SVar:X:Count$ChosenNumber AI:RemoveDeck:All -Oracle:You get {E}{E}{E} (three energy counters), then you may pay X {E}.\nEach player may exile their hand and draw X cards. If X is 7 or more, you may play cards you own exiled this way until the end of your next turn. +Oracle:You get {E}{E}{E} (three energy counters), then you may pay any amount of {E}.\nEach player may exile their hand and draw cards equal to the amount of {E} paid this way. If 7 or more {E} was paid this way, you may play cards you own exiled this way until the end of your next turn. diff --git a/forge-gui/res/cardsfolder/w/white_rhystic_study.txt b/forge-gui/res/cardsfolder/w/white_rhystic_study.txt new file mode 100644 index 00000000000..bf894c53327 --- /dev/null +++ b/forge-gui/res/cardsfolder/w/white_rhystic_study.txt @@ -0,0 +1,6 @@ +Name:White Rhystic Study +ManaCost:2 W +Types:Enchantment +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a spell, you may draw a card unless that player pays {1}. +SVar:TrigDraw:DB$ Draw | Defined$ You | UnlessCost$ 1 | UnlessPayer$ TriggeredPlayer | NumCards$ 1 | OptionalDecider$ You +Oracle:Whenever an opponent casts a spell, you may draw a card unless that player pays {1}. diff --git a/forge-gui/res/cardsfolder/w/wrath_of_oko.txt b/forge-gui/res/cardsfolder/w/wrath_of_oko.txt new file mode 100644 index 00000000000..c1db8b86998 --- /dev/null +++ b/forge-gui/res/cardsfolder/w/wrath_of_oko.txt @@ -0,0 +1,5 @@ +Name:Wrath of Oko +ManaCost:2 U U +Types:Sorcery +A:SP$ AnimateAll | ValidCards$ Creature | Power$ 3 | Toughness$ 3 | RemoveAllAbilities$ True | Colors$ Green | OverwriteColors$ True | Types$ Creature,Elk | RemoveCreatureTypes$ True | RemoveCardTypes$ True | Duration$ Permanent | SpellDescription$ All creatures loose all abilities and become green Elk creatures with base power and toughness 3/3. (This effect lasts indefinitely. Just like Oko. Unfortunately.) +Oracle:All creatures loose all abilities and become green Elk creatures with base power and toughness 3/3. (This effect lasts indefinitely. Just like Oko. Unfortunately.) diff --git a/forge-gui/res/deckgendecks/Standard.lda.dat b/forge-gui/res/deckgendecks/Standard.lda.dat index 00b6d800294..0e7e024cc75 100644 Binary files a/forge-gui/res/deckgendecks/Standard.lda.dat and b/forge-gui/res/deckgendecks/Standard.lda.dat differ diff --git a/forge-gui/res/deckgendecks/Standard.raw.dat b/forge-gui/res/deckgendecks/Standard.raw.dat index f740b961aac..3192fb60758 100644 Binary files a/forge-gui/res/deckgendecks/Standard.raw.dat and b/forge-gui/res/deckgendecks/Standard.raw.dat differ diff --git a/forge-gui/res/editions/Duskmourn House of Horror.txt b/forge-gui/res/editions/Duskmourn House of Horror.txt index 6f6339126ab..b106c64e344 100644 --- a/forge-gui/res/editions/Duskmourn House of Horror.txt +++ b/forge-gui/res/editions/Duskmourn House of Horror.txt @@ -24,6 +24,7 @@ ScryfallCode=DSK 275 L Mountain @Dan Mumford 276 L Forest @Dan Mumford 292 R Come Back Wrong @David Auden Nash +296 R Cursed Recording @Kim Sokol 309 R Come Back Wrong @Alexis Ziritt 314 R Chainsaw @Alexis Ziritt 346 R Doomsday Excruciator @Jarel Threat diff --git a/forge-gui/res/editions/Secret Lair Drop Series.txt b/forge-gui/res/editions/Secret Lair Drop Series.txt index e6f6fc8c275..b1fce77e115 100644 --- a/forge-gui/res/editions/Secret Lair Drop Series.txt +++ b/forge-gui/res/editions/Secret Lair Drop Series.txt @@ -755,6 +755,7 @@ ScryfallCode=SLD 777 R Reclamation Sage @Christopher Moeller 779 R Sylvan Ranger @Ciruelo 780 R Timberwatch Elf @Dave Dorman +782 R Viridian Shaman @Scott M. Fischer 783 R Wellwisher @Christopher Rush 785 R Wirewood Symbiote @Thomas M. Baxa 786 R Frilled Mystic @Randy Vargas @@ -1599,12 +1600,22 @@ F1540 M Rainbow Dash @John Thacker 1788 R Delay @Jordan Speer 1789 M Blood Money @Ricardo Diseño 1790 R Drown in the Loch @Wojtek Łebski +1791 M Karazikar, the Eye Tyrant @Skinner +1792 R Snuff Out @Ed Repka +1793 R Defile @Cabrol +1794 R Oubliette @Will Sweeney +1795 R Fling @Jon Vermilyea +1796 R Fire Covenant @Dan Mumford 1797 R Astarion, the Decadent @Nereida 1798 R Exquisite Blood @Justyna Dura 1799 R Sanguine Bond @Livia Prima 1800 R Anguished Unmaking @Mila Pesic 1801 R Mortify @Bartek Fedyczak 1802 M Karlach, Fury of Avernus @Mila Pesic +1803 R City on Fire @Fajareka Setiawan +1804 R Stranglehold @Bartek Fedyczak +1805 R Thrill of Possibility @Johannes Voss +1806 R Dolmen Gate @Justyna Dura 8001 M Jace, the Mind Sculptor @Wizard of Barge 9990 R Doom Blade @Cynthia Sheppard 9991 R Massacre @Andrey Kuzinskiy diff --git a/forge-gui/res/editions/Unknown Event Barcelona 2023 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Barcelona 2023 Playtest Cards.txt new file mode 100644 index 00000000000..58c845eddf4 --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Barcelona 2023 Playtest Cards.txt @@ -0,0 +1,71 @@ +[metadata] +Code=UEBAR23 +Date=2023-07-28 +Name=Unknown Event Barcelona 2023 Playtest Cards +Type=Funny + +[cards] +1 R Command From the Shadows +2 R Enolc, Perfect Clone +3 R Mysterious Confluence +4 R Your Favorite Character +5 R Fioran Reformist +6 R Form of the Stax Player +7 U Gather, the Townsfolk +8 C Taught by Serra +9 U Tax Hounds +10 R Theopholos, Order Acolyte +11 R Try-My-Deck Elemental +12 R White Rhystic Study +13 U Clear, the Mind +14 R Dockbreacher +15 U Ensoul Ring +16 R Lorthos, Tentacled Terror +17 C One Does Not +18 U Ring Out +19 C Taught by Narset +20 U Tax Draw +21 R Auntie Flint +22 U Delve too Deep +23 U Ransack, the Lab +24 C Shedding Snake +25 U Soul Drainer +26 C Taught by Vito +27 U Tax Sweeper +28 U Lava, Axe +29 R Math is for Blockers +30 C My Deck is About a Seven +31 R Mzed, Mercenary Leader +32 C Taught by Bruce Tarl +33 U Tax Bolt +34 R Triple Threat +35 R The Colossal Dreadmaw +36 R The Dilu Horse +37 R Maître Tree +38 R Mr. Wiggles, Helpful Butterfly +39 U Rampant, Growth +40 C Taught by Surrak +41 U Tax Keeper +42 R Ano'thr, Equipment Commander +43 R Arvad of the Weatherlight +44 R Awoken Nephilim +45 R Daxiver, Izzet Electromancer +46 R Eldest Dragon Highlander +47 R Groaaaaag, Hungry Monster +48 R Hadran, Naya Sunseeder +49 R Kallist Rhoka +50 R Margle, Cousin of Yargle +51 R Simic, Value Engine +52 R Slobad, Actually Just Fine +53 R Valko Indorian, Researcher +54 C Potatoes +55 U Power Level Analyzer +56 U Sagrada Familiar +57 R Spice Rack +58 C Toe-Breaking Helmet +59 C Your Mana Rock +60 U Mana Conference + +[promo] +61 M Barce, Friend Finder +62 R Lona, Tracker of the Known \ No newline at end of file diff --git a/forge-gui/res/editions/Unknown Event Indiana 2023 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Indiana 2023 Playtest Cards.txt new file mode 100644 index 00000000000..c9449103a5e --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Indiana 2023 Playtest Cards.txt @@ -0,0 +1,70 @@ +[metadata] +Code=UEIND23 +Date=2023-08-03 +Name=Unknown Event Indiana 2023 Playtest Cards +Type=Funny + +[cards] +1 R Command From the Shadows +2 R Enolc, Perfect Clone +3 R Mysterious Confluence +4 R Your Favorite Character +5 R Fioran Reformist +6 R Form of the Stax Player +7 U Gather, the Townsfolk +8 C Taught by Serra +9 U Tax Hounds +10 R Theopholos, Order Acolyte +11 R Try-My-Deck Elemental +12 R White Rhystic Study +13 U Clear, the Mind +14 R Dockbreacher +15 U Ensoul Ring +16 R Lorthos, Tentacled Terror +17 C One Does Not +18 U Ring Out +19 C Taught by Narset +20 U Tax Draw +21 R Auntie Flint +22 U Delve too Deep +23 U Ransack, the Lab +24 C Shedding Snake +25 U Soul Drainer +26 C Taught by Vito +27 U Tax Sweeper +28 U Lava, Axe +29 R Math is for Blockers +30 C My Deck is About a Seven +31 R Mzed, Mercenary Leader +32 C Taught by Bruce Tarl +33 U Tax Bolt +34 R Triple Threat +35 R The Colossal Dreadmaw +36 R The Dilu Horse +37 R Maître Tree +38 R Mr. Wiggles, Helpful Butterfly +39 U Rampant, Growth +40 C Taught by Surrak +41 U Tax Keeper +42 R Ano'thr, Equipment Commander +43 R Arvad of the Weatherlight +44 R Awoken Nephilim +45 R Daxiver, Izzet Electromancer +46 R Eldest Dragon Highlander +47 R Groaaaaag, Hungry Monster +48 R Hadran, Naya Sunseeder +49 R Kallist Rhoka +50 R Margle, Cousin of Yargle +51 R Simic, Value Engine +52 R Slobad, Actually Just Fine +53 R Valko Indorian, Researcher +54 C Potatoes +55 U Power Level Analyzer +56 U Sagrada Familiar +57 R Spice Rack +58 C Toe-Breaking Helmet +59 C Your Mana Rock +60 U Mana Conference + +[promo] +61 M Gen, Confider of Ages \ No newline at end of file diff --git a/forge-gui/res/editions/Unknown Event Las Vegas 2023 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Las Vegas 2023 Playtest Cards.txt new file mode 100644 index 00000000000..a5b932312e5 --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Las Vegas 2023 Playtest Cards.txt @@ -0,0 +1,48 @@ +[metadata] +Code=UELAS23 +Date=2023-09-22 +Name=Unknown Event Las Vegas 2023 Playtest Cards +Type=Funny + +[cards] +1 R The Companion of the Wilds +2 R Banned Eldraine Card +3 U Magic Designer +4 R Playtest Wish +5 R Bram, Baguette Brawler +6 R Ratatwotwo +7 R Stika, Playtestress +8 U Adventurer Beguiler +9 R Really Charming Prince +10 C Wistful Puppeteer +11 R Wrath of Oko +12 R Dan, Shrewd Trader +13 R Night Out in Vegas +14 R Rankle, Master of Pranksters +15 C Syr Konrad's Squire +16 C Believe in the Cleave +17 R Force of Rowan +18 U Must Be Knights +19 U The Alright Henge +20 C Garruk's Lost Wolf +21 R Grek the Ogre +22 R HONK! +23 R Questing Cosplayer +24 R Maeve, Wearer of Many Hats +25 R Princess Snowfall +26 U Cat Oven +27 R Cinnamon, Seasoned Steed +28 U Gingerbehemoth +29 C Command Mine +30 C Command Power Plant +31 R Kevin, Questing Dragon +32 R Takesies // Backsies +33 R Trampled Lotus + +[promo] +34 M You, Magic Playtester + +[You Make The Card] +1 Kevin, Questing Dragon|UELAS23 +1 Takesies // Backsies|UELAS23 +1 Trampled Lotus|UELAS23 \ No newline at end of file diff --git a/forge-gui/res/editions/Unknown Event Minneapolis 2023 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Minneapolis 2023 Playtest Cards.txt new file mode 100644 index 00000000000..db7db1fcaad --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Minneapolis 2023 Playtest Cards.txt @@ -0,0 +1,71 @@ +[metadata] +Code=UEMIN23 +Date=2023-05-05 +Name=Unknown Event Minneapolis 2023 Playtest Cards +Type=Funny + +[cards] +1 U Hero's Uncle +2 U Theros Charm +3 R Isamaru and Yoshimaru +4 R Azorius Traffic Enforcement +5 R Kylem All-Star +6 R Gerrard and Hanna +7 R Agoraphobic Phyrexian +8 C Shadowmoor Draw Spell +9 U Ulgrotha Charm +10 U Xerex Squire +11 U Farseeing Flockmate +12 R Phyrexian Adapter +13 R Toothy and Zndrsplt +14 R Welcome to Mini-apolis +15 C May of the Machine +16 U Incubob +17 U Innistrad Charm +18 R Incubation Triformer +19 R Quest Compleated Best +20 R Invasion Specialist +21 R Myojin of Night's Reach Grim Betrayal +22 C Azra Matchthrower +23 U Tarkir Charm +24 U Jeska and Kamahl +25 U Joven and Chandler +26 U Nevermind +27 R Across the Multiverse +28 R Norin and Feldon +29 C That's No Moonmist +30 C Merfolk Surveyor +31 R Occupation of Llanowar +32 U Kamigawa Charm +33 R Chatterstorm and Awaken the Woods +34 R Phyrexian Cytoshaper +35 R Praetorhoof Behemoth +36 R Emrakul and Chatterfang +37 R Anax and Cymede and Kynaios and Tiro +38 R Shahrazad and Sindbad +39 R Riku and Riku +40 R Halana and Alena and Gisa and Geralf +41 R Autumn Willow and Baron Sengir +42 R Colossal Dreadmaw and Storm Crow +43 R Riven Turnbull and Princess Lucrezia +44 R Avacyn and Griselbrand +45 R Koma and Toski, Compleated +46 R Knowing // Half the Battle +47 C Unicycling Automaton +48 U Segovian Sword +49 R Huge Truck +50 R Jitte and Divining Top +51 R Manakin and Millikin +52 R Luxior and Shadowspear +53 R Bob the Claymore +54 R Phyrexian Incubator +55 R Sword of Fire and Ice and War and Peace +56 R Battle Myrsphere +57 R Guildmark +58 C Unknown Event Shores +59 R The Belligerent and Useless Island +60 C Common Curve Filler + +[promo] +61 M Minnea, Planar Tourist +62 M Polis the Planeshifter \ No newline at end of file diff --git a/forge-gui/res/editions/Unknown Event Philadelphia 2023 Playtest Cards.txt b/forge-gui/res/editions/Unknown Event Philadelphia 2023 Playtest Cards.txt new file mode 100644 index 00000000000..104a523c33f --- /dev/null +++ b/forge-gui/res/editions/Unknown Event Philadelphia 2023 Playtest Cards.txt @@ -0,0 +1,71 @@ +[metadata] +Code=UEPHI23 +Date=2023-02-17 +Name=Unknown Event Philadelphia 2023 Playtest Cards +Type=Funny + +[cards] +1 C Unclaimed Cat +2 C Incisor Steed +3 U Good Knight +4 U Rosewater's Nemesis +5 U Echoing Echo +6 R Leech Medic +7 R Life Cloud +8 R Crux of Mirrodin +9 C Drake with Set's Mechanic +10 C Unclaimed Bird +11 C Point to the Scoreboard +12 C More of That Strange Oil... +13 U Tricky Mage +14 R Memnarchitect +15 R Phyrexian Broodstar +16 R Untap, Upkeep, Draw +17 C Unclaimed Blessing +18 C Long-Term Phyresis Study +19 U Nim Mongoose +20 U Bad Knight +21 U Phyrexian Chimney Imp +22 U Sheoldred's Terror +23 R Old Way Phyrexian +24 R Hidetsugu's Poison Rite +25 C Join the Winning Team +26 C Phyrexian Esthetician +27 C Burn the Phyresis +28 U Unclaimed Battle Axe +29 U Red Priest of Yawgmoth +30 U Furnace Oriflamme +31 R Snapsail Rider +32 R Hound of Urabrask +33 C Naturalize the Phyresis +34 C Unclaimed Tanadon +35 C Take the High Ground +36 U Arcbound Mamba +37 R Bringer of Green Zenith's Twilight +38 R Locus Cobra +39 R Pulse of the Hunter Maze +40 R Then, Dreadmaws Ate Everyone +41 R Forestfolk +42 C Phyrexian Ornithopter +43 C Sojourner's Enforcermite +44 C Melira's Snacks +45 U Compleated Clone Shell +46 U Sawtooth Avenger +47 U Original Skullclamp +48 R Goblin Savant +49 R Glorious Dragon-Kin +50 R Oilskelion +51 R Soul of Mirrodin +52 R Platinum Persecutor +53 R Chancellor of the Mulligan +54 R Mindslaver Toolkit +55 R Mox Poison +56 R Sort of ____ and ____ +57 C The Forgotten Place +58 C Artifact Unknown Shores +59 R Who's That Praetor? +60 R Call Up Emrakul to Help + +[promo] +61 M Phila, Unsealed +62 M Delphia, Undecided \ No newline at end of file diff --git a/forge-gui/res/formats/Archived/Alchemy/2024-08-20.txt b/forge-gui/res/formats/Archived/Alchemy/2024-08-20.txt new file mode 100644 index 00000000000..13689bd708f --- /dev/null +++ b/forge-gui/res/formats/Archived/Alchemy/2024-08-20.txt @@ -0,0 +1,6 @@ +[format] +Name:Alchemy (YBLB) +Type:Archived +Subtype:Arena +Effective:2024-08-20 +Sets:ANA, ANB, WOE, YWOE, LCI, YLCI, MKM, YMKM, OTJ, BIG, YOTJ, BLB, YBLB 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/Historic/2024-08-20.txt b/forge-gui/res/formats/Archived/Historic/2024-08-20.txt new file mode 100644 index 00000000000..f0ea6c1db92 --- /dev/null +++ b/forge-gui/res/formats/Archived/Historic/2024-08-20.txt @@ -0,0 +1,8 @@ +[format] +Name:Historic (YBLB) +Type:Archived +Subtype:Arena +Effective:2024-08-20 +Sets:KTK, XLN, RIX, DOM, M19, ANA, PANA, GRN, G18, RNA, WAR, M20, ELD, HA1, THB, HA2, IKO, HA3, M21, JMP, AJMP, AKR, ANB, ZNR, KLR, KHM, HA4, STX, STA, HA5, AFR, J21, MID, VOW, YMID, NEO, YNEO, SNC, YSNC, HBG, HA6, EA1, DMU, YDMU, BRO, BRR, YBRO, EA2, ONE, YONE, SIR, SIS, MOM, MUL, MAT, LTR, HA7, EA3, WOE, WOT, YWOE, LCI, YLCI, MKM, YMKM, OTJ, OTP, BIG, YOTJ, MH3, BLB, YBLB +Banned:Agent of Treachery; Arid Mesa; Blood Moon; Bloodstained Mire; Brainstorm; Channel; Commandeer; Counterspell; Dark Ritual; Demonic Tutor; Endurance; Field of the Dead; Flare of Cultivation; Flare of Denial; Flare of Duplication; Flare of Fortitude; Flare of Malice; Flooded Strand; Force of Vigor; Fury; Grief; Harbinger of the Seas; Intruder Alarm; Land Tax; Lightning Bolt; Mana Drain; Marsh Flats; Memory Lapse; Mishra's Bauble; Misty Rainforest; Natural Order; Necropotence; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Ragavan, Nimble Pilferer; Reanimate; Scalding Tarn; Show and Tell; Sneak Attack; Solitude; Spreading Seas; Subtlety; Swords to Plowshares; Thassa's Oracle; Tibalt's Trickery; Time Warp; Uro, Titan of Nature's Wrath; Veil of Summer; Verdant Catacombs; Wilderness Reclamation; Windswept Heath; Winter Moon; Wooded Foothills +Additional:Admiral Brass, Unsinkable; Burden of Guilt; Clavileño, First of the Blessed; Crashing Footfalls; Desert; Desertion; Dismember; Duskmantle, House of Shadow; Enlisted Wurm; Evolutionary Leap; Fabricate; Gamble; Ghostly Prison; Gonti, Canny Acquisitor; Goro-Goro and Satoru; Ixidor, Reality Sculptor; Katilda and Lier; Kuldotha Rebirth; Leonin Relic-Warder; Magmaw; Mass Hysteria; Metalspinner's Puzzleknot; Mistveil Plains; Molten Psyche; Monologue Tax; Mystery Key; Mystic Snake; Notion Thief; Nyx Weaver; Olivia, Opulent Outlaw; Pantlaza, Sun-Favored; Persist; Port Razer; Possibility Storm; Prismatic Ending; Prismatic Vista; Putrid Warrior; Shard of Broken Glass; Slimefoot and Squee; Smuggler's Copter; Spell Snare; Stella Lee, Wild Card; Stoneforge Mystic; Timeless Dragon; Treacherous Terrain; Victimize; Xolatoyac, the Smiling Flood; Yuma, Proud Protector 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/Timeless/2024-08-20.txt b/forge-gui/res/formats/Archived/Timeless/2024-08-20.txt new file mode 100644 index 00000000000..d2f26d31059 --- /dev/null +++ b/forge-gui/res/formats/Archived/Timeless/2024-08-20.txt @@ -0,0 +1,8 @@ +[format] +Name:Timeless (YBLB) +Type:Archived +Subtype:Vintage +Effective:2024-08-20 +Sets:KTK, XLN, RIX, DOM, M19, ANA, PANA, GRN, G18, RNA, WAR, M20, ELD, HA1, THB, HA2, IKO, HA3, M21, JMP, AJMP, AKR, ANB, ZNR, KLR, KHM, HA4, STX, STA, HA5, AFR, J21, MID, VOW, YMID, NEO, YNEO, SNC, YSNC, HBG, HA6, EA1, DMU, YDMU, BRO, BRR, YBRO, EA2, ONE, YONE, SIR, SIS, MOM, MUL, MAT, LTR, HA7, EA3, WOE, WOT, YWOE, LCI, YLCI, MKM, YMKM, OTJ, OTP, BIG, YOTJ, MH3, BLB, YBLB +Restricted:Channel; Demonic Tutor; Tibalt's Trickery +Additional:Admiral Brass, Unsinkable; Burden of Guilt; Clavileño, First of the Blessed; Crashing Footfalls; Desert; Desertion; Dismember; Duskmantle, House of Shadow; Endurance; Enlisted Wurm; Evolutionary Leap; Fabricate; Fury; Gamble; Ghostly Prison; Gonti, Canny Acquisitor; Goro-Goro and Satoru; Grief; Ixidor, Reality Sculptor; Katilda and Lier; Kuldotha Rebirth; Leonin Relic-Warder; Magmaw; Mass Hysteria; Metalspinner's Puzzleknot; Mistveil Plains; Molten Psyche; Monologue Tax; Mystery Key; Mystic Snake; Notion Thief; Nyx Weaver; Olivia, Opulent Outlaw; Pantlaza, Sun-Favored; Persist; Port Razer; Possibility Storm; Prismatic Ending; Prismatic Vista; Putrid Warrior; Shard of Broken Glass; Show and Tell; Slimefoot and Squee; Smuggler's Copter; Solitude; Spell Snare; Stella Lee, Wild Card; Stoneforge Mystic; Subtlety; Timeless Dragon; Treacherous Terrain; Victimize; Xolatoyac, the Smiling Flood; Yuma, Proud Protector 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/Historic.txt b/forge-gui/res/formats/Sanctioned/Historic.txt index bc69df5556f..fa3b9bba362 100644 --- a/forge-gui/res/formats/Sanctioned/Historic.txt +++ b/forge-gui/res/formats/Sanctioned/Historic.txt @@ -4,6 +4,6 @@ Type:Digital Subtype:Arena Effective:2019-11-21 Order:142 -Sets:KTK, XLN, RIX, DOM, M19, ANA, PANA, GRN, G18, RNA, WAR, M20, ELD, HA1, THB, HA2, IKO, HA3, M21, JMP, AJMP, AKR, ANB, ZNR, KLR, KHM, HA4, STX, STA, HA5, AFR, J21, MID, VOW, YMID, NEO, YNEO, SNC, YSNC, HBG, HA6, EA1, DMU, YDMU, BRO, BRR, YBRO, EA2, ONE, YONE, SIR, SIS, MOM, MUL, MAT, LTR, HA7, EA3, WOE, WOT, YWOE, LCI, YLCI, MKM, YMKM, OTJ, OTP, BIG, YOTJ, MH3, BLB +Sets:KTK, XLN, RIX, DOM, M19, ANA, PANA, GRN, G18, RNA, WAR, M20, ELD, HA1, THB, HA2, IKO, HA3, M21, JMP, AJMP, AKR, ANB, ZNR, KLR, KHM, HA4, STX, STA, HA5, AFR, J21, MID, VOW, YMID, NEO, YNEO, SNC, YSNC, HBG, HA6, EA1, DMU, YDMU, BRO, BRR, YBRO, EA2, ONE, YONE, SIR, SIS, MOM, MUL, MAT, LTR, HA7, EA3, WOE, WOT, YWOE, LCI, YLCI, MKM, YMKM, OTJ, OTP, BIG, YOTJ, MH3, BLB, YBLB Banned:Agent of Treachery; Arid Mesa; Blood Moon; Bloodstained Mire; Brainstorm; Channel; Commandeer; Counterspell; Dark Ritual; Demonic Tutor; Endurance; Field of the Dead; Flare of Cultivation; Flare of Denial; Flare of Duplication; Flare of Fortitude; Flare of Malice; Flooded Strand; Force of Vigor; Fury; Grief; Harbinger of the Seas; Intruder Alarm; Land Tax; Lightning Bolt; Mana Drain; Marsh Flats; Memory Lapse; Mishra's Bauble; Misty Rainforest; Natural Order; Necropotence; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Ragavan, Nimble Pilferer; Reanimate; Scalding Tarn; Show and Tell; Sneak Attack; Solitude; Spreading Seas; Subtlety; Swords to Plowshares; Thassa's Oracle; Tibalt's Trickery; Time Warp; Uro, Titan of Nature's Wrath; Veil of Summer; Verdant Catacombs; Wilderness Reclamation; Windswept Heath; Winter Moon; Wooded Foothills Additional:Admiral Brass, Unsinkable; Burden of Guilt; Clavileño, First of the Blessed; Crashing Footfalls; Desert; Desertion; Dismember; Duskmantle, House of Shadow; Enlisted Wurm; Evolutionary Leap; Fabricate; Gamble; Ghostly Prison; Gonti, Canny Acquisitor; Goro-Goro and Satoru; Ixidor, Reality Sculptor; Katilda and Lier; Kuldotha Rebirth; Leonin Relic-Warder; Magmaw; Mass Hysteria; Metalspinner's Puzzleknot; Mistveil Plains; Molten Psyche; Monologue Tax; Mystery Key; Mystic Snake; Notion Thief; Nyx Weaver; Olivia, Opulent Outlaw; Pantlaza, Sun-Favored; Persist; Port Razer; Possibility Storm; Prismatic Ending; Prismatic Vista; Putrid Warrior; Shard of Broken Glass; Slimefoot and Squee; Smuggler's Copter; Spell Snare; Stella Lee, Wild Card; Stoneforge Mystic; Timeless Dragon; Treacherous Terrain; Victimize; Xolatoyac, the Smiling Flood; Yuma, Proud Protector 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/tokenscripts/all_1_1_a_stained_glass.txt b/forge-gui/res/tokenscripts/all_1_1_a_stained_glass.txt new file mode 100644 index 00000000000..c421a91e2a0 --- /dev/null +++ b/forge-gui/res/tokenscripts/all_1_1_a_stained_glass.txt @@ -0,0 +1,7 @@ +Name:Stained Glass Token +ManaCost:no cost +Colors:all +Types:Artifact Creature Stained Glass +PT:1/1 +Text:This creature is all colors. +Oracle:This creature is all colors. diff --git a/forge-gui/res/tokenscripts/b_1_1_cat.txt b/forge-gui/res/tokenscripts/b_1_1_cat.txt new file mode 100644 index 00000000000..963c09790d7 --- /dev/null +++ b/forge-gui/res/tokenscripts/b_1_1_cat.txt @@ -0,0 +1,6 @@ +Name:Cat Token +ManaCost:no cost +Types:Creature Cat +Colors:black +PT:1/1 +Oracle: diff --git a/forge-gui/res/tokenscripts/br_7_7_demon.txt b/forge-gui/res/tokenscripts/br_7_7_demon.txt new file mode 100644 index 00000000000..9c1bf6b6fe4 --- /dev/null +++ b/forge-gui/res/tokenscripts/br_7_7_demon.txt @@ -0,0 +1,6 @@ +Name:Demon Token +ManaCost:no cost +Types:Creature Demon +Colors:black,red +PT:7/7 +Oracle: diff --git a/forge-gui/res/tokenscripts/colossal_dreadmaw.txt b/forge-gui/res/tokenscripts/colossal_dreadmaw.txt new file mode 100644 index 00000000000..f3eb7200cca --- /dev/null +++ b/forge-gui/res/tokenscripts/colossal_dreadmaw.txt @@ -0,0 +1,7 @@ +Name:Colossal Dreadmaw +ManaCost:no cost +Types:Creature Dinosaur +Colors:green +PT:6/6 +K:Trample +Oracle:Trample (This creature can deal excess combat damage to the player or planeswalker it's attacking.) diff --git a/forge-gui/res/tokenscripts/incubator_dark_confidant.txt b/forge-gui/res/tokenscripts/incubator_dark_confidant.txt new file mode 100644 index 00000000000..b10cb72c62d --- /dev/null +++ b/forge-gui/res/tokenscripts/incubator_dark_confidant.txt @@ -0,0 +1,18 @@ +Name:Incubator Dark Confidant Token +Types:Artifact Incubator +A:AB$ SetState | Cost$ 2 | Mode$ Transform | SpellDescription$ Transform this artifact. +AlternateMode:DoubleFaced +Oracle:{2}: Transform this artifact. + +ALTERNATE + +Name:Dark Confidant +ManaCost:1 B +Types:Creature Phyrexian Human Wizard +PT:2/1 +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ At the beginning of your upkeep, reveal the top card of your library and put that card into your hand. You lose life equal to its mana value. +SVar:TrigDig:DB$ Dig | DigNum$ 1 | Reveal$ True | ChangeNum$ All | ChangeValid$ Card | DestinationZone$ Hand | RememberChanged$ True | SubAbility$ DBLose +SVar:DBLose:DB$ LoseLife | LifeAmount$ X | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$CardManaCost +Oracle:At the beginning of your upkeep, reveal the top card of your library and put that card into your hand. You lose life equal to its mana value. diff --git a/forge-gui/res/tokenscripts/role_huntsman.txt b/forge-gui/res/tokenscripts/role_huntsman.txt new file mode 100644 index 00000000000..9353393caa0 --- /dev/null +++ b/forge-gui/res/tokenscripts/role_huntsman.txt @@ -0,0 +1,8 @@ +Name:Huntsman +ManaCost:no cost +Types:Enchantment Aura Role +K:Enchant creature +A:SP$ Attach | Cost$ 0 | ValidTgts$ Creature | AILogic$ Pump +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 1 | AddToughness$ 1 | AddAbility$ Mana | Description$ Enchanted creature gets +1/+1 and has "{T}: Add {G}." +SVar:Mana:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. +Oracle:Enchant Creature\nEnchanted creature gets +1/+1 and has "{T}: Add {G}." diff --git a/forge-gui/res/tokenscripts/role_questing.txt b/forge-gui/res/tokenscripts/role_questing.txt new file mode 100644 index 00000000000..00a61e14eb6 --- /dev/null +++ b/forge-gui/res/tokenscripts/role_questing.txt @@ -0,0 +1,12 @@ +Name:Questing +ManaCost:no cost +Types:Enchantment Aura Role +K:Enchant creature +A:SP$ Attach | Cost$ 0 | ValidTgts$ Creature | AILogic$ Pump +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Vigilance & Deathtouch & Haste | AddTrigger$ TrigChomp | AddStaticAbility$ StaticNoBlock & StaticNoFog | Description$ Enchanted creature has vigilance, deathtouch, and haste, and has "This creature can't be blocked by creatures with power 2 or less.", "Combat damage that would be dealt by creatures you control can't be prevented.", and "Whenever this creature deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls." +SVar:StaticNoBlock:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.powerLE2 | Description$ This creature can't be blocked by creatures with power 2 or less. +SVar:StaticNoFog:Mode$ CantPreventDamage | IsCombat$ True | ValidSource$ Creature.YouCtrl | Description$ Combat damage that would be dealt by creatures you control can't be prevented. +SVar:TrigChomp:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ MoreDamage | TriggerDescription$ Whenever this creature deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls. +SVar:MoreDamage:DB$ DealDamage | ValidTgts$ Planeswalker.ControlledBy TriggeredTarget | TgtPrompt$ Select target planeswalker that player controls | NumDmg$ X +SVar:X:TriggerCount$DamageAmount +Oracle:Enchant Creature\nEnchanted creature has vigilance, deathtouch, and haste, and has "This creature can't be blocked by creatures with power 2 or less.", "Combat damage that would be dealt by creatures you control can't be prevented.", and "Whenever this creature deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls." \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/spellgorger_weird.txt b/forge-gui/res/tokenscripts/spellgorger_weird.txt deleted file mode 100644 index d758cb137c3..00000000000 --- a/forge-gui/res/tokenscripts/spellgorger_weird.txt +++ /dev/null @@ -1,7 +0,0 @@ -Name:Spellgorger Weird -ManaCost:2 R -Types:Creature Weird -PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a noncreature spell, put a +1/+1 counter on CARDNAME. -SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 -Oracle:Whenever you cast a noncreature spell, put a +1/+1 counter on Spellgorger Weird. diff --git a/forge-gui/res/tokenscripts/tarmogoyf.txt b/forge-gui/res/tokenscripts/tarmogoyf.txt deleted file mode 100644 index 36625d6adc9..00000000000 --- a/forge-gui/res/tokenscripts/tarmogoyf.txt +++ /dev/null @@ -1,8 +0,0 @@ -Name:Tarmogoyf -ManaCost:1 G -Types:Creature Lhurgoyf -PT:*/1+* -S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ Y | Description$ CARDNAME's power is equal to the number of card types among 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 -Oracle:Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1. diff --git a/forge-gui/res/tokenscripts/toskis_coil.txt b/forge-gui/res/tokenscripts/toskis_coil.txt new file mode 100644 index 00000000000..75f43bcf2bc --- /dev/null +++ b/forge-gui/res/tokenscripts/toskis_coil.txt @@ -0,0 +1,7 @@ +Name:Toski's Coil +ManaCost:no cost +Types:Artifact Creature Phyrexian Serpent Squirrel +PT:1/1 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 +Oracle:Whenever this creature deals combat damage to a player, draw a card. diff --git a/forge-gui/res/tokenscripts/u_m1_m1_squid.txt b/forge-gui/res/tokenscripts/u_m1_m1_squid.txt new file mode 100644 index 00000000000..9c9417adeb8 --- /dev/null +++ b/forge-gui/res/tokenscripts/u_m1_m1_squid.txt @@ -0,0 +1,6 @@ +Name:Squid Token +ManaCost:no cost +Types:Creature Squid +Colors:blue +PT:-1/-1 +Oracle: diff --git a/forge-gui/res/tokenscripts/w_2_2_performer.txt b/forge-gui/res/tokenscripts/w_2_2_performer.txt new file mode 100644 index 00000000000..357a91d14fa --- /dev/null +++ b/forge-gui/res/tokenscripts/w_2_2_performer.txt @@ -0,0 +1,6 @@ +Name:Performer Token +ManaCost:no cost +Types:Creature Performer +Colors:white +PT:2/2 +Oracle: diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java index b55c1213a6b..1a9bae2da9c 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedPlayer.java @@ -414,7 +414,7 @@ public class LimitedPlayer { } public boolean hasCanalDredger() { - return (playerFlags & CanalDredgerLastPick) != CanalDredgerLastPick; + return (playerFlags & CanalDredgerLastPick) == CanalDredgerLastPick; } public void receiveUnopenedPack(DraftPack pack) { diff --git a/forge-gui/src/main/java/forge/gamemodes/match/input/InputPassPriority.java b/forge-gui/src/main/java/forge/gamemodes/match/input/InputPassPriority.java index 13d8fe9f832..c134489837d 100644 --- a/forge-gui/src/main/java/forge/gamemodes/match/input/InputPassPriority.java +++ b/forge-gui/src/main/java/forge/gamemodes/match/input/InputPassPriority.java @@ -25,7 +25,7 @@ import forge.game.card.Card; import forge.game.player.Player; import forge.game.player.PlayerController; import forge.game.player.actions.PassPriorityAction; -import forge.game.spellability.LandAbility; + import forge.game.spellability.SpellAbility; import forge.localinstance.properties.ForgePreferences.FPref; import forge.model.FModel; @@ -169,7 +169,7 @@ public class InputPassPriority extends InputSyncronizedBase { if (sa.isSpell()) { return Localizer.getInstance().getMessage("lblCastSpell"); } - if (sa instanceof LandAbility) { + if (sa.isLandAbility()) { return Localizer.getInstance().getMessage("lblPlayLand"); } return Localizer.getInstance().getMessage("lblActivateAbility"); diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index b8887145913..1d9323108a3 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -33,7 +33,7 @@ import forge.game.mana.ManaRefundService; import forge.game.player.Player; import forge.game.player.PlayerController; import forge.game.player.PlayerView; -import forge.game.spellability.LandAbility; + import forge.game.spellability.OptionalCostValue; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbilityManaConvert; @@ -70,7 +70,7 @@ public class HumanPlay { Card source = sa.getHostCard(); sa.setActivatingPlayer(p); - if (sa instanceof LandAbility) { + if (sa.isLandAbility()) { if (sa.canPlay()) { sa.resolve(); }