diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index b147420577f..a677c2ddf90 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -267,6 +267,15 @@ public class AiCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(c); } + @Override + public PaymentDecision visit(CostRollDice cost) { + Integer c = cost.convertAmount(); + if (c == null) { + c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability); + } + return PaymentDecision.number(c); + } + @Override public PaymentDecision visit(CostGainControl cost) { if (cost.payCostFromSource()) { diff --git a/forge-game/src/main/java/forge/game/PlanarDice.java b/forge-game/src/main/java/forge/game/PlanarDice.java index d8705f3e889..6f46a28f604 100644 --- a/forge-game/src/main/java/forge/game/PlanarDice.java +++ b/forge-game/src/main/java/forge/game/PlanarDice.java @@ -1,5 +1,6 @@ package forge.game; +import java.util.Arrays; import java.util.Map; import com.google.common.collect.ImmutableList; @@ -8,7 +9,7 @@ import forge.game.ability.AbilityKey; import forge.game.player.Player; import forge.game.trigger.TriggerType; -/** +/** * Represents the planar dice for Planechase games. * */ @@ -16,7 +17,7 @@ public enum PlanarDice { Planeswalk, Chaos, Blank; - + public static PlanarDice roll(Player roller, PlanarDice riggedResult) { PlanarDice res = Blank; @@ -27,25 +28,37 @@ public enum PlanarDice { res = Planeswalk; else if (i == 1) res = Chaos; - - + + PlanarDice trigRes = res; - + if(roller.getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.blankIsChaos) && res == Blank) { trigRes = Chaos; } - final Map runParams = AbilityKey.newMap(); + Map runParams = AbilityKey.newMap(); runParams.put(AbilityKey.Player, roller); runParams.put(AbilityKey.Result, trigRes); roller.getGame().getTriggerHandler().runTrigger(TriggerType.PlanarDice, runParams,false); - - + + // Also run normal RolledDie and RolledDieOnce triggers + runParams = AbilityKey.newMap(); + runParams.put(AbilityKey.Player, roller); + runParams.put(AbilityKey.Sides, 6); + runParams.put(AbilityKey.Result, 0); + roller.getGame().getTriggerHandler().runTrigger(TriggerType.RolledDie, runParams, false); + + runParams = AbilityKey.newMap(); + runParams.put(AbilityKey.Player, roller); + runParams.put(AbilityKey.Sides, 6); + runParams.put(AbilityKey.Result, Arrays.asList(0)); + roller.getGame().getTriggerHandler().runTrigger(TriggerType.RolledDieOnce, runParams, false); + return res; } - + /** * Parses a string into an enum member. * @param string to parse 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 8f9a2056a0d..07908174fac 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1796,6 +1796,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public void setCurrentRoom(String room) { currentRoom = room; view.updateCurrentRoom(this); + view.getCurrentState().updateAbilityText(this, getCurrentState()); } public boolean isInLastRoom() { for (final Trigger t : getTriggers()) { @@ -2212,6 +2213,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public String getAbilityText(final CardState state) { + final String grayTag = ""; + final String endTag = ""; final CardTypeView type = state.getType(); final StringBuilder sb = new StringBuilder(); @@ -2298,8 +2301,16 @@ public class Card extends GameEntity implements Comparable, IHasSVars { // Triggered abilities for (final Trigger trig : state.getTriggers()) { if (!trig.isSecondary() && !trig.isClassAbility()) { + boolean disabled = false; + // Disable text of other rooms + if (type.isDungeon() && !trig.getOverridingAbility().getParam("RoomName").equals(getCurrentRoom())) { + disabled = true; + } String trigStr = trig.replaceAbilityText(trig.toString(), state); - sb.append(trigStr.replaceAll("\\\\r\\\\n", "\r\n")).append("\r\n"); + if (disabled) sb.append(grayTag); + sb.append(trigStr.replaceAll("\\\\r\\\\n", "\r\n")); + if (disabled) sb.append(endTag); + sb.append("\r\n"); } } @@ -2397,8 +2408,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { // Currently the maximum levels of all Class cards are all 3 for (int level = 1; level <= 3; ++level) { boolean disabled = level > getClassLevel() && isInZone(ZoneType.Battlefield); - final String grayTag = ""; - final String endTag = ""; for (final Trigger trig : state.getTriggers()) { if (trig.isClassLevelNAbility(level) && !trig.isSecondary()) { if (disabled) sb.append(grayTag); diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index 8aa688e4678..18984d40709 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -530,6 +530,7 @@ public final class CardUtil { // however, due to the changes necessary for SA_Requirements this is much // different than the original public static List getValidCardsToTarget(TargetRestrictions tgt, SpellAbility ability) { + Card activatingCard = ability.getHostCard(); final Game game = ability.getActivatingPlayer().getGame(); final List zone = tgt.getZone(); @@ -539,7 +540,6 @@ public final class CardUtil { if (canTgtStack) { // Since getTargetableCards doesn't have additional checks if one of the Zones is stack // Remove the activating card from targeting itself if its on the Stack - Card activatingCard = ability.getHostCard(); if (activatingCard.isInZone(ZoneType.Stack)) { choices.remove(ability.getHostCard()); } @@ -561,7 +561,7 @@ public final class CardUtil { final List choicesCopy = Lists.newArrayList(choices); for (final Card c : choicesCopy) { - if (c.getCMC() > tgt.getMaxTotalCMC(c, ability) - totalCMCTargeted) { + if (c.getCMC() > tgt.getMaxTotalCMC(activatingCard, ability) - totalCMCTargeted) { choices.remove(c); } } @@ -576,7 +576,7 @@ public final class CardUtil { final List choicesCopy = Lists.newArrayList(choices); for (final Card c : choicesCopy) { - if (c.getNetPower() > tgt.getMaxTotalPower(c, ability) - totalPowerTargeted) { + if (c.getNetPower() > tgt.getMaxTotalPower(activatingCard, ability) - totalPowerTargeted) { choices.remove(c); } } diff --git a/forge-game/src/main/java/forge/game/cost/Cost.java b/forge-game/src/main/java/forge/game/cost/Cost.java index 80a0021c52f..fae4d70df52 100644 --- a/forge-game/src/main/java/forge/game/cost/Cost.java +++ b/forge-game/src/main/java/forge/game/cost/Cost.java @@ -363,6 +363,13 @@ public class Cost implements Serializable { return new CostFlipCoin(splitStr[0]); } + if (parse.startsWith("RollDice<")) { + // RollDice + final String[] splitStr = abCostParse(parse, 4); + final String description = splitStr.length > 3 ? splitStr[3] : null; + return new CostRollDice(splitStr[0], splitStr[1], splitStr[2], description); + } + if (parse.startsWith("Discard<")) { // Discard final String[] splitStr = abCostParse(parse, 3); diff --git a/forge-game/src/main/java/forge/game/cost/CostRollDice.java b/forge-game/src/main/java/forge/game/cost/CostRollDice.java new file mode 100644 index 00000000000..67355994a34 --- /dev/null +++ b/forge-game/src/main/java/forge/game/cost/CostRollDice.java @@ -0,0 +1,68 @@ +package forge.game.cost; + +import forge.game.ability.effects.RollDiceEffect; +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; + +/** + * This is for the "RollDice" Cost + */ +public class CostRollDice extends CostPart { + + /** + * Serializables need a version ID. + */ + private static final long serialVersionUID = 1L; + + private final String resultSVar; + + /** + * Instantiates a new cost RollDice. + * + * @param amount + * the amount + */ + public CostRollDice(final String amount, final String sides, final String resultSVar, final String description) { + super(amount, sides, description); + this.resultSVar = resultSVar; + } + + /* + * (non-Javadoc) + * + * @see + * forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility, + * forge.Card, forge.Player, forge.card.cost.Cost) + */ + @Override + public final boolean canPay(final SpellAbility ability, final Player payer) { + return true; + } + + @Override + public final String toString() { + final StringBuilder sb = new StringBuilder(); + + sb.append("Roll ").append(getAmount()); + + if (this.getTypeDescription() == null) { + sb.append("d").append(getType()); + } else { + sb.append(" ").append(this.getTypeDescription()); + } + + return sb.toString(); + } + + @Override + public boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa) { + int sides = Integer.parseInt(getType()); + int result = RollDiceEffect.rollDiceForPlayer(sa, payer, pd.c, sides); + sa.setSVar(resultSVar, Integer.toString(result)); + return true; + } + + public T accept(ICostVisitor visitor) { + return visitor.visit(this); + } +} diff --git a/forge-game/src/main/java/forge/game/cost/ICostVisitor.java b/forge-game/src/main/java/forge/game/cost/ICostVisitor.java index 1b46b741e7e..89b69c2c2e1 100644 --- a/forge-game/src/main/java/forge/game/cost/ICostVisitor.java +++ b/forge-game/src/main/java/forge/game/cost/ICostVisitor.java @@ -12,6 +12,7 @@ public interface ICostVisitor { T visit(CostExiledMoveToGrave cost); T visit(CostExert cost); T visit(CostFlipCoin cost); + T visit(CostRollDice cost); T visit(CostMill cost); T visit(CostAddMana cost); T visit(CostPayLife cost); @@ -84,6 +85,11 @@ public interface ICostVisitor { return null; } + @Override + public T visit(CostRollDice cost) { + return null; + } + @Override public T visit(CostMill cost) { return null; @@ -173,7 +179,7 @@ public interface ICostVisitor { public T visit(CostUnattach cost) { return null; } - + @Override public T visit(CostTapType cost) { return null; diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerRolledDie.java b/forge-game/src/main/java/forge/game/trigger/TriggerRolledDie.java index e495f62c5bc..1adc634d3a2 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerRolledDie.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerRolledDie.java @@ -44,6 +44,11 @@ public class TriggerRolledDie extends Trigger { } return false; } + if (hasParam("ValidSides")) { + final int validSides = Integer.parseInt(getParam("ValidSides")); + final int sides = (int) runParams.get(AbilityKey.Sides); + if (sides == validSides) return true; + } return true; } diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java index f46bd78e19f..c645d02e467 100644 --- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java +++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java @@ -232,8 +232,8 @@ public class WrappedAbility extends Ability { if (regtrig == null) return ""; final StringBuilder sb = new StringBuilder(regtrig.replaceAbilityText(regtrig.toString(true), this)); List allTargets = sa.getAllTargetChoices(); - if (!allTargets.isEmpty()) { - sb.append(" (Targeting "); + if (!allTargets.isEmpty() && !ApiType.Charm.equals(sa.getApi())) { + sb.append(" (Targeting: "); sb.append(allTargets); sb.append(")"); } diff --git a/forge-game/src/main/java/forge/util/MessageUtil.java b/forge-game/src/main/java/forge/util/MessageUtil.java index 431054e395f..a73c34179e7 100644 --- a/forge-game/src/main/java/forge/util/MessageUtil.java +++ b/forge-game/src/main/java/forge/util/MessageUtil.java @@ -53,6 +53,7 @@ public class MessageUtil { case Protection: return Localizer.getInstance().getMessage("lblPlayerChooseValue", choser, value); case RollDice: + case PutCounter:// For Clay Golem cost text return value; case Vote: String chooser = StringUtils.capitalize(mayBeYou(player, target)); diff --git a/forge-gui-mobile/src/forge/assets/TextRenderer.java b/forge-gui-mobile/src/forge/assets/TextRenderer.java index ce7fdfb3006..84b693e439f 100644 --- a/forge-gui-mobile/src/forge/assets/TextRenderer.java +++ b/forge-gui-mobile/src/forge/assets/TextRenderer.java @@ -291,6 +291,19 @@ public class TextRenderer { case "clr": colorOverride = value != null ? new Color(Integer.parseInt(value)) : null; break; + case "span": + // + if (value != null && value.contains("color:")) { + int startIdx = value.indexOf(':') + 1; + int endIdx = value.indexOf(';'); + String colorName = value.substring(startIdx, endIdx); + if (colorName.equals("gray")) { + colorOverride = Color.GRAY; + } + } else { + colorOverride = null; + } + break; default: validKeyword = false; break; diff --git a/forge-gui/res/blockdata/blocks.txt b/forge-gui/res/blockdata/blocks.txt index cdbf25e1ccc..c70bab58191 100644 --- a/forge-gui/res/blockdata/blocks.txt +++ b/forge-gui/res/blockdata/blocks.txt @@ -97,3 +97,4 @@ Kaldheim, 3/6/KHM, KHM Time Spiral Remastered, 3/6/KHM, TSR Strixhaven: School of Mages, 3/6/STX, STX Modern Horizons 2, 3/6/MH2, MH2 +Adventures in the Forgotten Realms, 3/6/AFR, AFR diff --git a/forge-gui/res/cardsfolder/c/chicken_a_la_king.txt b/forge-gui/res/cardsfolder/c/chicken_a_la_king.txt index 53720fdfc14..0d12c573d40 100644 --- a/forge-gui/res/cardsfolder/c/chicken_a_la_king.txt +++ b/forge-gui/res/cardsfolder/c/chicken_a_la_king.txt @@ -2,7 +2,7 @@ Name:Chicken à la King ManaCost:1 U U Types:Creature Bird Noble PT:2/2 -T:Mode$ RolledDie | TriggerZones$ Battlefield | Execute$ TrigCounters | ValidResult$ 6 | TriggerDescription$ Whenever a 6 is rolled on a six-sided die, put a +1/+1 counter on each Bird. +T:Mode$ RolledDie | TriggerZones$ Battlefield | Execute$ TrigCounters | ValidResult$ 6 | ValidSides$ 6 | TriggerDescription$ Whenever a 6 is rolled on a six-sided die, put a +1/+1 counter on each Bird. SVar:TrigCounters:DB$ PutCounterAll | ValidCards$ Bird | CounterType$ P1P1 | CounterNum$ 1 A:AB$ RollDice | Cost$ tapXType<1/Bird> | AILogic$ AtOppEOT | SpellDescription$ Roll a six-sided die. DeckHas:Ability$Counters diff --git a/forge-gui/res/cardsfolder/s/sutured_ghoul.txt b/forge-gui/res/cardsfolder/s/sutured_ghoul.txt index c3d3926be6b..d59150085f8 100644 --- a/forge-gui/res/cardsfolder/s/sutured_ghoul.txt +++ b/forge-gui/res/cardsfolder/s/sutured_ghoul.txt @@ -3,14 +3,14 @@ ManaCost:4 B B B Types:Creature Zombie PT:*/* K:Trample -K:ETBReplacement:Copy:ChooseCreatures -SVar:ChooseCreatures:DB$ ChooseCard | Defined$ You | Amount$ X | Choices$ Creature.YouOwn | ChoiceTitle$ Exile any number of creature cards from your graveyard. | ChoiceZone$ Graveyard | RememberChosen$ True | SubAbility$ ExileCreatures | SpellDescription$ As CARDNAME enters the battlefield, exile any number of creature cards from your graveyard. CARDNAME's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. -SVar:ExileCreatures:DB$ ChangeZoneAll | ChangeType$ Remembered | Origin$ Graveyard | Destination$ Exile | SubAbility$ AnimateSuture -SVar:AnimateSuture:DB$ Animate | Defined$ Self | Power$ TotalPower | Toughness$ TotalToughness | Duration$ Permanent | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +K:ETBReplacement:Other:ETBPrep +SVar:ETBPrep:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBChoose +SVar:DBChoose:DB$ ChooseCard | Defined$ You | MinAmount$ 0 | Amount$ X | Choices$ Creature.YouOwn+Other | ChoiceTitle$ Exile any number of creature cards from your graveyard | ChoiceZone$ Graveyard | RememberChosen$ True | SubAbility$ ExileCreatures | SpellDescription$ As CARDNAME enters the battlefield, exile any number of creature cards from your graveyard. CARDNAME's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. +SVar:ExileCreatures:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Graveyard | Destination$ Exile | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +S:Mode$ Continuous | EffectZone$ Battlefield | Affected$ Card.Self | SetPower$ TotalPower | SetToughness$ TotalToughness | Description$ CARDNAME's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. SVar:TotalPower:Remembered$CardPower SVar:TotalToughness:Remembered$CardToughness SVar:X:Count$TypeInYourYard.Creature AI:RemoveDeck:Random -SVar:Picture:http://www.wizards.com/global/images/magic/general/sutured_ghoul.jpg Oracle:Trample\nAs Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard.\nSutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness. diff --git a/forge-gui/res/cardsfolder/upcoming/clay_golem.txt b/forge-gui/res/cardsfolder/upcoming/clay_golem.txt new file mode 100644 index 00000000000..d6e35596511 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/clay_golem.txt @@ -0,0 +1,9 @@ +Name:Clay Golem +ManaCost:4 +Types:Artifact Creature Golem +PT:4/4 +A:AB$ PutCounter | Cost$ 6 RollDice<1/8/X> | ConditionPresent$ Card.Self+IsNotMonstrous | Monstrosity$ True | CounterNum$ X | CounterType$ P1P1 | StackDescription$ SpellDescription | SpellDescription$ Monstrosity X, where X is the result. (If this creature isn't monstrous, put X +1/+1 counters on it and it becomes monstrous.) +T:Mode$ BecomeMonstrous | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Berserk — When CARDNAME becomes monstrous, destroy target permanent. +SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Permanent +DeckHas:Ability$Counters +Oracle:{6}, Roll a d8: Monstrosity X, where X is the result. (If this creature isn't monstrous, put X +1/+1 counters on it and it becomes monstrous.)\nBerserk — When Clay Golem becomes monstrous, destroy target permanent. diff --git a/forge-gui/res/cardsfolder/upcoming/dungeon_of_the_mad_mage.txt b/forge-gui/res/cardsfolder/upcoming/dungeon_of_the_mad_mage.txt index 3e23e1d82bb..a12ad7f5047 100644 --- a/forge-gui/res/cardsfolder/upcoming/dungeon_of_the_mad_mage.txt +++ b/forge-gui/res/cardsfolder/upcoming/dungeon_of_the_mad_mage.txt @@ -7,9 +7,8 @@ SVar:DBDungeon:DB$ Scry | ScryNum$ 1 | RoomName$ Dungeon Level | SpellDescriptio SVar:DBBazaar:DB$ Token | TokenScript$ c_a_treasure_sac | TokenOwner$ You | RoomName$ Goblin Bazaar | SpellDescription$ Create a Treasure token. | NextRoom$ DBLost SVar:DBCaverns:DB$ Pump | ValidTgts$ Creature | KW$ HIDDEN CARDNAME can't attack. | Duration$ UntilYourNextTurn | IsCurse$ True | RoomName$ Twisted Caverns | SpellDescription$ Target creature can't attack until your next turn. | NextRoom$ DBLost SVar:DBLost:DB$ Scry | ScryNum$ 2 | RoomName$ Lost Level | SpellDescription$ Scry 2. | NextRoom$ DBRunestone,DBGraveyard -SVar:DBRunestone:DB$ Dig | Defined$ You | DigNum$ 2 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | RoomName$ Runestone Caverns | SpellDescription$ Exile the top two cards of your library. You may play them. | NextRoom$ DBMines -SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | RememberObjects$ RememberedCard | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup -SVar:STPlay:Mode$ Continuous | EffectZone$ Command | AffectedZone$ Exile | Affected$ Card.IsRemembered | MayPlay$ True | Description$ You may play them. +SVar:DBRunestone:DB$ Dig | Defined$ You | DigNum$ 2 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBPlayExiled | RoomName$ Runestone Caverns | SpellDescription$ Exile the top two cards of your library. You may play them. | NextRoom$ DBMines +SVar:DBPlayExiled:DB$ Play | Valid$ Card.IsRemembered | ValidZone$ Exile | Controller$ You | Optional$ True | Amount$ All | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBGraveyard:DB$ Token | TokenScript$ b_1_1_skeleton | TokenOwner$ You | TokenAmount$ 2 | RoomName$ Muiral's Graveyard | SpellDescription$ Create two 1/1 black Skeleton creature tokens. | NextRoom$ DBMines SVar:DBMines:DB$ Scry | ScryNum$ 3 | RoomName$ Deep Mines | SpellDescription$ Scry 3. | NextRoom$ DBLair diff --git a/forge-gui/res/cardsfolder/upcoming/galea_kindler_of_hope.txt b/forge-gui/res/cardsfolder/upcoming/galea_kindler_of_hope.txt new file mode 100644 index 00000000000..e4c5f3d45df --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/galea_kindler_of_hope.txt @@ -0,0 +1,13 @@ +Name:Galea, Kindler of Hope +ManaCost:1 G U W +Types:Legendary Creature Elf Knight +PT:4/4 +K:Vigilance +S:Mode$ Continuous | Affected$ Card.TopLibrary+YouCtrl | AffectedZone$ Library | MayLookAt$ You | Description$ You may look at the top card of your library any time. +S:Mode$ Continuous | Affected$ Aura.TopLibrary+YouCtrl+nonLand,Equipment.TopLibrary+YouCtrl+nonLand | AffectedZone$ Library | MayPlay$ True | Description$ You may cast Aura and Equipment spells from the top of your library. When you cast an Equipment spell this way, it gains "When this Equipment enters the battlefield, attach it to target creature you control." +T:Mode$ SpellCast | ValidCard$ Equipment | ValidSA$ Spell.MayPlaySource | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigAnimate | Secondary$ True | TriggerDescription$ When you cast an Equipment spell this way, it gains "When this Equipment enters the battlefield, attach it to target creature you control." +SVar:TrigAnimate:DB$ Animate | Defined$ TriggeredCard | Triggers$ ETBAttach | Duration$ Permanent +SVar:ETBAttach:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAttach | TriggerDescription$ When this Equipment enters the battlefield, attach it to target creature you control. +SVar:TrigAttach:DB$ Attach | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control +DeckHints:Type$Aura|Equipment +Oracle:Vigilance\nYou may look at the top card of your library any time./nYou may cast Aura and Equipment spells from the top of your library. When you cast an Equipment spell this way, it gains "When this Equipment enters the battlefield, attach it to target creature you control." diff --git a/forge-gui/res/cardsfolder/upcoming/sefris_of_the_hidden_ways.txt b/forge-gui/res/cardsfolder/upcoming/sefris_of_the_hidden_ways.txt new file mode 100644 index 00000000000..030456bf2da --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sefris_of_the_hidden_ways.txt @@ -0,0 +1,11 @@ +Name:Sefris of the Hidden Ways +ManaCost:W U B +Types:Legendary Creature Human Wizard +PT:2/3 +T:Mode$ ChangesZoneAll | ValidCards$ Creature.YouOwn+nonToken | Origin$ Any | Destination$ Graveyard | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigVenture | TriggerDescription$ Whenever one or more creature cards are put into your graveyard from anywhere, venture into the dungeon. This ability triggers only once each turn. (To venture into the dungeon, enter the first room or advance to the next room.) +SVar:TrigVenture:DB$ Venture +T:Mode$ DungeonCompleted | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ DBReturn | TriggerDescription$ Create Undead – Whenever you complete a dungeon, return target creature card from your graveyard to the battlefield. +SVar:DBReturn:DB$ ChangeZone | ValidTgts$ Creature.YouOwn | Origin$ Graveyard | Destination$ Battlefield +DeckHas:Ability$Graveyard +AI:RemoveDeck:Random +Oracle:Whenever one or more creature cards are put into your graveyard from anywhere, venture into the dungeon. This ability triggers only once each turn. (To venture into the dungeon, enter the first room or advance to the next room.)\nCreate Undead - Whenever you complete a dungeon, return target creature card from your graveyard to the battlefield. diff --git a/forge-gui/res/draft/rankings.txt b/forge-gui/res/draft/rankings.txt index 9ce21b6f44c..c419e06d371 100644 --- a/forge-gui/res/draft/rankings.txt +++ b/forge-gui/res/draft/rankings.txt @@ -1,4 +1,266 @@ //Rank|Name|Rarity|Set +#1|Iymrith, Desert Doom|M|AFR +#2|Lolth, Spider Queen|M|AFR +#3|Mordenkainen|M|AFR +#4|Icingdeath, Frost Tyrant|M|AFR +#5|Inferno of the Star Mounts|M|AFR +#6|Varis, Silverymoon Ranger|R|AFR +#7|Ebondeath, Dracolich|M|AFR +#8|Adult Gold Dragon|R|AFR +#9|Drizzt Do'Urden|R|AFR +#10|Westgate Regent|R|AFR +#11|Xanathar, Guild Kingpin|M|AFR +#12|Gelatinous Cube|R|AFR +#13|Orcus, Prince of Undeath|R|AFR +#14|Zariel, Archduke of Avernus|M|AFR +#15|Mind Flayer|R|AFR +#16|Froghemoth|R|AFR +#17|The Book of Exalted Deeds|M|AFR +#18|Grand Master of Flowers|M|AFR +#19|Old Gnawbone|M|AFR +#20|Ranger Class|R|AFR +#21|Nadaar, Selfless Paladin|R|AFR +#22|Skeletal Swarming|R|AFR +#23|Meteor Swarm|R|AFR +#24|Flameskull|M|AFR +#25|Dancing Sword|R|AFR +#26|Werewolf Pack Leader|R|AFR +#27|Vorpal Sword|R|AFR +#28|Ellywick Tumblestrum|M|AFR +#29|Minsc, Beloved Ranger|M|AFR +#30|Paladin Class|R|AFR +#31|Lair of the Hydra|R|AFR +#32|Hobgoblin Bandit Lord|R|AFR +#33|Teleportation Circle|R|AFR +#34|Grazilaxx, Illithid Scholar|R|AFR +#35|Ochre Jelly|R|AFR +#36|Hall of Storm Giants|R|AFR +#37|Den of the Bugbear|R|AFR +#38|Cave of the Frost Dragon|R|AFR +#39|Forsworn Paladin|R|AFR +#40|Monk Class|R|AFR +#41|Yuan-Ti Malison|R|AFR +#42|Triumphant Adventurer|R|AFR +#43|Wight|R|AFR +#44|Hive of the Eye Tyrant|R|AFR +#45|Grim Bounty|C|AFR +#46|Hand of Vecna|R|AFR +#47|Acererak the Archlich|M|AFR +#48|Volo, Guide to Monsters|R|AFR +#49|Demilich|M|AFR +#50|Tiamat|M|AFR +#51|Dragon's Fire|C|AFR +#52|Fighter Class|R|AFR +#53|Gretchen Titchwillow|U|AFR +#54|Zalto, Fire Giant Duke|R|AFR +#55|Dragon Turtle|R|AFR +#56|Sphere of Annihilation|R|AFR +#57|Priest of Ancient Lore|C|AFR +#58|Loyal Warhound|R|AFR +#59|Burning Hands|U|AFR +#60|Sorcerer Class|R|AFR +#61|Ingenious Smith|U|AFR +#62|Wandering Troubadour|U|AFR +#63|Wizard's Spellbook|R|AFR +#64|Targ Nar, Demon-Fang Gnoll|U|AFR +#65|Krydle of Baldur's Gate|U|AFR +#66|Trelasarra, Moon Dancer|U|AFR +#67|Bruenor Battlehammer|U|AFR +#68|Magic Missile|U|AFR +#69|Asmodeus the Archfiend|R|AFR +#70|Ray of Enfeeblement|U|AFR +#71|Cleric Class|U|AFR +#72|Precipitous Drop|C|AFR +#73|Eccentric Apprentice|U|AFR +#74|Bag of Holding|U|AFR +#75|Hama Pashar, Ruin Seeker|U|AFR +#76|Barrowin of Clan Undurr|U|AFR +#77|Farideh, Devil's Chosen|U|AFR +#78|Intrepid Outlander|U|AFR +#79|Power Word Kill|U|AFR +#80|Rust Monster|U|AFR +#81|Spoils of the Hunt|C|AFR +#82|Rogue Class|R|AFR +#83|Instrument of the Bards|R|AFR +#84|Kalain, Reclusive Painter|U|AFR +#85|Minimus Containment|C|AFR +#86|Guardian of Faith|R|AFR +#87|Skullport Merchant|U|AFR +#88|Ray of Frost|U|AFR +#89|Shessra, Death's Whisper|U|AFR +#90|The Blackstaff of Waterdeep|R|AFR +#91|Circle of Dreams Druid|R|AFR +#92|Battle Cry Goblin|U|AFR +#93|Devoted Paladin|C|AFR +#94|The Tarrasque|M|AFR +#95|Prosperous Innkeeper|U|AFR +#96|Aberrant Mind Sorcerer|U|AFR +#97|White Dragon|U|AFR +#98|Divine Smite|U|AFR +#99|Barbarian Class|U|AFR +#100|Warlock Class|U|AFR +#101|Wizard Class|U|AFR +#102|The Deck of Many Things|M|AFR +#103|Death-Priest of Myrkul|U|AFR +#104|Djinni Windseer|C|AFR +#105|Delina, Wild Mage|R|AFR +#106|Hunter's Mark|U|AFR +#107|Displacer Beast|U|AFR +#108|Charmed Sleep|C|AFR +#109|The Book of Vile Darkness|M|AFR +#110|Celestial Unicorn|C|AFR +#111|Tiger-Tribe Hunter|U|AFR +#112|Owlbear|C|AFR +#113|Cloister Gargoyle|U|AFR +#114|Farideh's Fireball|C|AFR +#115|Eye of Vecna|R|AFR +#116|Monk of the Open Hand|C|AFR +#117|Long Rest|R|AFR +#118|Xorn|R|AFR +#119|Bard Class|R|AFR +#120|Split the Party|U|AFR +#121|Goblin Morningstar|U|AFR +#122|Feywild Trickster|U|AFR +#123|Hulking Bugbear|U|AFR +#124|Red Dragon|U|AFR +#125|Grim Wanderer|U|AFR +#126|Chaos Channeler|U|AFR +#127|Drider|U|AFR +#128|Green Dragon|U|AFR +#129|Blue Dragon|U|AFR +#130|Check for Traps|U|AFR +#131|Eyes of the Beholder|C|AFR +#132|True Polymorph|R|AFR +#133|Sudden Insight|U|AFR +#134|Druid Class|U|AFR +#135|Reaper's Talisman|U|AFR +#136|Veteran Dungeoneer|C|AFR +#137|Lightfoot Rogue|U|AFR +#138|Treasure Chest|R|AFR +#139|Swarming Goblins|C|AFR +#140|Air-Cult Elemental|C|AFR +#141|Dungeon Map|U|AFR +#142|Elturgard Ranger|C|AFR +#143|You See a Pair of Goblins|U|AFR +#144|Black Dragon|U|AFR +#145|Purple Worm|U|AFR +#146|You Come to a River|C|AFR +#147|Iron Golem|U|AFR +#148|Steadfast Paladin|C|AFR +#149|Temple of the Dragon Queen|U|AFR +#150|Circle of the Moon Druid|C|AFR +#151|Plate Armor|U|AFR +#152|Wild Shape|U|AFR +#153|Rally Maneuver|U|AFR +#154|Sepulcher Ghoul|C|AFR +#155|Trickster's Talisman|U|AFR +#156|Soulknife Spy|C|AFR +#157|Clattering Skeletons|C|AFR +#158|Planar Ally|C|AFR +#159|Hill Giant Herdgorger|C|AFR +#160|Power of Persuasion|U|AFR +#161|Loathsome Troll|U|AFR +#162|Bulette|C|AFR +#163|Guild Thief|U|AFR +#164|Manticore|C|AFR +#165|Fifty Feet of Rope|U|AFR +#166|Moon-Blessed Cleric|U|AFR +#167|Inspiring Bard|C|AFR +#168|Hobgoblin Captain|C|AFR +#169|Wish|R|AFR +#170|Valor Singer|U|AFR +#171|Portable Hole|C|AFR +#172|Dungeon Crawler|C|AFR +#173|Vampire Spawn|C|AFR +#174|Hoard Robber|C|AFR +#175|Armory Veteran|C|AFR +#176|Boots of Speed|C|AFR +#177|Underdark Basilisk|C|AFR +#178|Arborea Pegasus|C|AFR +#179|Blink Dog|U|AFR +#180|Neverwinter Dryad|C|AFR +#181|Unexpected Windfall|C|AFR +#182|Arcane Investigator|C|AFR +#183|You Meet in a Tavern|U|AFR +#184|Dire Wolf Prowler|C|AFR +#185|Secret Door|C|AFR +#186|Dragon's Disciple|U|AFR +#187|Sylvan Shepherd|C|AFR +#188|Pixie Guide|C|AFR +#189|Scion of Stygia|C|AFR +#190|Contact Other Plane|C|AFR +#191|Jaded Sell-Sword|C|AFR +#192|Hoarding Ogre|C|AFR +#193|Lurking Roper|U|AFR +#194|Rimeshield Frost Giant|C|AFR +#195|Fly|U|AFR +#196|Find the Path|C|AFR +#197|Zombie Ogre|C|AFR +#198|Keen-Eared Sentry|U|AFR +#199|Dwarfhold Champion|C|AFR +#200|Yuan-Ti Fang-Blade|C|AFR +#201|Half-Elf Monk|C|AFR +#202|Clever Conjurer|C|AFR +#203|You Happen On a Glade|C|AFR +#204|Gnoll Hunter|C|AFR +#205|Dungeon Descent|R|AFR +#206|Improvised Weaponry|C|AFR +#207|Spiked Pit Trap|C|AFR +#208|You Hear Something on Watch|C|AFR +#209|Choose Your Weapon|U|AFR +#210|Orb of Dragonkind|R|AFR +#211|You Find the Villains' Lair|C|AFR +#212|Baleful Beholder|C|AFR +#213|Ranger's Hawk|C|AFR +#214|Oswald Fiddlebender|R|AFR +#215|Mimic|C|AFR +#216|Flumph|R|AFR +#217|Tasha's Hideous Laughter|R|AFR +#218|Shortcut Seeker|C|AFR +#219|Evolving Wilds|C|AFR +#220|Deadly Dispute|C|AFR +#221|Thieves' Tools|C|AFR +#222|Ranger's Longbow|C|AFR +#223|Paladin's Shield|C|AFR +#224|Demogorgon's Clutches|U|AFR +#225|Delver's Torch|C|AFR +#226|Hired Hexblade|C|AFR +#227|Herald of Hadar|C|AFR +#228|Bar the Gate|C|AFR +#229|Feign Death|C|AFR +#230|You Find a Cursed Idol|C|AFR +#231|You Come to the Gnoll Camp|C|AFR +#232|You Find Some Prisoners|C|AFR +#233|Earth-Cult Elemental|C|AFR +#234|Kick in the Door|C|AFR +#235|Fates' Reversal|C|AFR +#236|+2 Mace|C|AFR +#237|Plundering Barbarian|C|AFR +#238|Dawnbringer Cleric|C|AFR +#239|Bull's Strength|C|AFR +#240|Dueling Rapier|C|AFR +#241|Minion of the Mighty|R|AFR +#242|Greataxe|C|AFR +#243|Spare Dagger|C|AFR +#244|Potion of Healing|C|AFR +#245|Critical Hit|U|AFR +#246|Brazen Dwarf|C|AFR +#247|Shocking Grasp|C|AFR +#248|You're Ambushed on the Road|C|AFR +#249|Shambling Ghast|C|AFR +#250|Gloom Stalker|C|AFR +#251|Silver Raven|C|AFR +#252|Compelled Duel|C|AFR +#253|Leather Armor|C|AFR +#254|Scaled Herbalist|C|AFR +#255|Goblin Javelineer|C|AFR +#256|You See a Guard Approach|C|AFR +#257|Devour Intellect|C|AFR +#258|Plummet|C|AFR +#259|Price of Loyalty|C|AFR +#260|Treasure Vault|R|AFR +#261|Mordenkainen's Polymorph|C|AFR +//Rank|Name|Rarity|Set #1|Fury|M|MH2 #2|Grist, the Hunger Tide|M|MH2 #3|Kaldra Compleat|M|MH2 @@ -33391,4 +33653,4 @@ #257|Dust to Dust|U|ME4 #258|Gate to Phyrexia|U|ME4 #259|Tablet of Epityr|C|ME4 -#260|Leeches|R|ME4 +#260|Leeches|R|ME4 \ No newline at end of file diff --git a/forge-gui/res/editions/2021 Lunar New Year.txt b/forge-gui/res/editions/2021 Lunar New Year.txt index 2569019bc78..78af5d1ea3c 100644 --- a/forge-gui/res/editions/2021 Lunar New Year.txt +++ b/forge-gui/res/editions/2021 Lunar New Year.txt @@ -6,9 +6,9 @@ Type=Promo ScryfallCode=PL21 [cards] -1 R Sethron, Hurloon General -2 M Moraug, Fury of Akoum -3 M Ox of Agonas +1 M Moraug, Fury of Akoum +1★ R Sethron, Hurloon General +2 M Ox of Agonas [tokens] r_2_3_minotaur diff --git a/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms Commander.txt b/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms Commander.txt index 1a58da53b6b..6eb45fba32e 100644 --- a/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms Commander.txt +++ b/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms Commander.txt @@ -10,7 +10,330 @@ ScryfallCode=AFC 2 M Prosper, Tome-Bound 3 M Sefris of the Hidden Ways 4 M Vrondiss, Rage of Ancients +5 R Fey Steed +6 R Holy Avenger +7 R Immovable Rod +8 R Mantle of the Ancients +9 R Radiant Solar +10 R Revivify +11 R Robe of Stars +12 R Thorough Investigation +13 R Valiant Endeavor +14 R Arcane Endeavor +15 R Diviner's Portent +16 R Minn, Wily Illusionist +17 R Netherese Puzzle-Ward +18 R Phantom Steed +19 R Rod of Absorption +20 R Winged Boots +21 R Bag of Devouring +22 R Danse Macabre +23 R Death Tyrant +24 R Grave Endeavor +25 R Grim Hireling +26 R Hellish Rebuke +27 R Lorcan, Warlock Collector +28 R Wand of Orcus +29 R Berserker's Frenzy +30 R Chaos Dragon +31 R Fiendlash +32 R Maddening Hex +33 R Reckless Endeavor +34 R Share the Spoils +35 R Vengeful Ancestor +36 R Wild-Magic Sorcerer +37 R Bag of Tricks +38 R Belt of Giant Strength +39 R Druid of Purification +40 R Indomitable Might +41 R Neverwinter Hydra +42 R Song of Inspiration +43 R Wild Endeavor +44 R Catti-brie of Mithral Hall +45 R Dragonborn Champion +46 R Extract Brain +47 R Fevered Suspicion +48 R Hurl Through Hell +49 M Karazikar, the Eye Tyrant +50 M Klauth, Unrivaled Ancient +51 R Klauth's Will +52 R Midnight Pathlighter +53 M Nihiloor +54 R Ride the Avalanche +55 M Storvald, Frost Giant Jarl +56 R Wulfgar of Icewind Dale +57 U Bucknard's Everfull Purse +58 U Clay Golem +59 U Component Pouch +60 U Ebony Fly +61 U Sword of Hours +62 U Underdark Rift +63 R Angel of Finality +64 C Angelic Gift +65 M Cataclysmic Gearhulk +66 R Eternal Dragon +67 U Gryff's Boon +68 R Karmic Guide +69 R Puresteel Paladin +70 M Realm-Cloaked Giant // Cast Off +71 C Ronom Unicorn +72 R Sram, Senior Edificer +73 M Sun Titan +74 R Sunblast Angel +75 U Swords to Plowshares +76 U Valorous Stance +77 U Wall of Omens +78 R Winds of Rath +79 C Brainstorm +80 R Champion of Wits +81 R Curator of Mysteries +82 U Curse of Verbosity +83 C Eel Umbra +84 U Forbidden Alchemy +85 R Imprisoned in the Moon +86 U Merfolk Looter +87 U Mulldrifter +88 U Murder of Crows +89 R Phantasmal Image +90 R Prognostic Sphinx +91 U Propaganda +92 U Psychic Impetus +93 U Riverwise Augur +94 U Serum Visions +95 R Chittering Witch +96 R Consuming Vapors +97 R Dead Man's Chest +98 R Doomed Necromancer +99 R Fiend of the Shadows +100 R Gonti, Lord of Luxury +101 R Hex +102 R Marionette Master +103 R Necromantic Selection +104 R Ogre Slumlord +105 U Phthisis +106 R Piper of the Swarm +107 U Plaguecrafter +108 R Pontiff of Blight +109 U Reassembling Skeleton +110 U Shriekmaw +111 U Unburial Rites +112 U Victimize +113 U Anger +114 M Apex of Power +115 M Bogardan Hellkite +116 R Chain Reaction +117 R Chaos Warp +118 R Commune with Lava +119 R Dark-Dweller Oracle +120 R Demanding Dragon +121 R Dire Fleet Daredevil +122 R Disrupt Decorum +123 U Dragonlord's Servant +124 M Dragonmaster Outcast +125 R Dream Pillager +126 R Etali, Primal Storm +127 R Gratuitous Violence +128 R Hoard-Smelter Dragon +129 R Ignite the Future +130 R Izzet Chemister +131 U Light Up the Stage +132 U Loyal Apprentice +133 R Magmaquake +134 R Opportunistic Dragon +135 R Outpost Siege +136 C Rile +137 R Scourge of Valkas +138 U Shiny Impetus +139 R Shivan Hellkite +140 R Skyline Despot +141 R Skyship Stalker +142 R Spit Flame +143 R Taurean Mauler +144 R Tectonic Giant +145 R Terror of Mount Velus +146 U Throes of Chaos +147 R Thunderbreak Regent +148 U Vandalblast +149 R Warstorm Surge +150 C Abundant Growth +151 U Acidic Slime +152 U Beast Within +153 R Chameleon Colossus +154 U Colossal Majesty +155 U Cultivate +156 R Decree of Savagery +157 C Explore +158 C Fertile Ground +159 U Garruk's Uprising +160 R Greater Good +161 R Heroic Intervention +162 U Kenrith's Transformation +163 R Kindred Summons +164 C Nature's Lore +165 U Paradise Druid +166 C Rampant Growth +167 U Rancor +168 R Return of the Wildspeaker +169 C Return to Nature +170 R Rishkar's Expertise +171 R Shamanic Revelation +172 U Utopia Sprawl +173 R Verdant Embrace +174 C Wild Growth +175 M Ashen Rider +176 R Atarka, World Render +177 R Baleful Strix +178 U Bant Charm +179 R Bedevil +180 U Behemoth Sledge +181 U Bituminous Blast +182 U Cloudblazer +183 R Cold-Eyed Selkie +184 U Despark +185 R Fleecemane Lion +186 R Hostage Taker +187 R Knight of Autumn +188 U Necrotic Sliver +189 U Obsessive Stitcher +190 U Rakdos Charm +191 U Savage Ventmaw +192 C Shielding Plax +193 U Terminate +194 R Theater of Horrors +195 R Utter End +196 U Vanish into Memory +197 C Arcane Signet +198 R Argentum Armor +199 R Basilisk Collar +200 U Burnished Hart +201 R Chaos Wand +202 U Colossus Hammer +203 C Commander's Sphere +204 R Dragon's Hoard +205 C Explorer's Scope +206 U Fellwar Stone +207 U Gruul Signet +208 U Heirloom Blade +209 R Masterwork of Ingenuity +210 U Meteor Golem +211 U Mind Stone +212 R Moonsilver Spear +213 C Orazca Relic +214 U Rakdos Signet +215 U Sol Ring +216 R Solemn Simulacrum +217 U Swiftfoot Boots +218 R Sword of the Animist +219 U Talisman of Indulgence +220 U Unstable Obelisk +221 C Viridian Longbow +222 C Wayfarer's Bauble +223 U Arcane Sanctum +224 U Azorius Chancery +225 C Bant Panorama +226 C Bojuka Bog +227 R Canopy Vista +228 R Choked Estuary +229 R Cinder Glade +230 C Command Tower +231 R Crucible of the Spirit Dragon +232 R Darkwater Catacombs +233 U Desert +234 U Dimir Aqueduct +235 C Esper Panorama +236 R Exotic Orchard +237 U Flood Plain +238 R Foreboding Ruins +239 R Fortified Village +240 R Game Trail +241 R Geier Reach Sanitarium +242 U Grasslands +243 U Gruul Turf +244 C Halimar Depths +245 R Haven of the Spirit Dragon +246 R High Market +247 R Lumbering Falls +248 U Mishra's Factory +249 C Mortuary Mire +250 R Mossfire Valley +251 R Mosswort Bridge +252 R Nimbus Maze +253 U Orzhov Basilica +254 C Path of Ancestry +255 R Port Town +256 R Prairie Stream +257 U Rakdos Carnarium +258 U Seaside Citadel +259 R Shadowblood Ridge +260 U Simic Growth Chamber +261 R Skycloud Expanse +262 R Smoldering Marsh +263 R Spinerock Knoll +264 R Sungrass Prairie +265 R Sunken Hollow +266 U Tainted Peak +267 C Terramorphic Expanse +268 C Thriving Grove +269 C Thriving Heath +270 C Thriving Isle +271 C Thriving Moor +272 U Vitu-Ghazi, the City-Tree +273 U Zhalfirin Void +274 R Fey Steed +275 R Holy Avenger +276 R Immovable Rod +277 R Mantle of the Ancients +278 R Radiant Solar +279 R Revivify +280 R Robe of Stars +281 R Thorough Investigation +282 R Valiant Endeavor +283 R Arcane Endeavor +284 R Diviner's Portent +285 R Minn, Wily Illusionist +286 R Netherese Puzzle-Ward +287 R Phantom Steed +288 R Rod of Absorption +289 R Winged Boots +290 R Bag of Devouring +291 R Danse Macabre +292 R Death Tyrant +293 R Grave Endeavor +294 R Grim Hireling +295 R Hellish Rebuke +296 R Lorcan, Warlock Collector +297 R Wand of Orcus +298 R Berserker's Frenzy +299 R Chaos Dragon +300 R Fiendlash +301 R Maddening Hex +302 R Reckless Endeavor +303 R Share the Spoils +304 R Vengeful Ancestor +305 R Wild-Magic Sorcerer +306 R Bag of Tricks +307 R Belt of Giant Strength +308 R Druid of Purification +309 R Indomitable Might +310 R Neverwinter Hydra +311 R Song of Inspiration +312 R Wild Endeavor +313 R Catti-brie of Mithral Hall +314 R Dragonborn Champion +315 R Extract Brain +316 R Fevered Suspicion 317 M Galea, Kindler of Hope +318 R Hurl Through Hell +319 M Karazikar, the Eye Tyrant +320 M Klauth, Unrivaled Ancient +321 C Klauth's Will +322 R Midnight Pathlighter +323 M Nihiloor 324 M Prosper, Tome-Bound +325 R Ride the Avalanche 326 M Sefris of the Hidden Ways +327 M Storvald, Frost Giant Jarl 328 M Vrondiss, Rage of Ancients +329 R Wulfgar of Icewind Dale +330 U Dragonspeaker Shaman +331 U Lightning Greaves diff --git a/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms.txt b/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms.txt index a8c9555bb06..a761652efd6 100644 --- a/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms.txt +++ b/forge-gui/res/editions/Dungeons & Dragons Adventures in the Forgotten Realms.txt @@ -6,6 +6,8 @@ Code2=AFR MciCode=afr Type=Expansion ScryfallCode=AFR +BoosterCovers=5 +Booster=10 Common, 3 Uncommon, 1 RareMythic, 1 BasicLand [cards] 1 C +2 Mace diff --git a/forge-gui/res/editions/The List.txt b/forge-gui/res/editions/The List.txt index 76cc9910b11..c1b240c5fec 100644 --- a/forge-gui/res/editions/The List.txt +++ b/forge-gui/res/editions/The List.txt @@ -459,3 +459,52 @@ ScryfallCode=PLIST 451 R Petrified Field 452 R Urborg, Tomb of Yawgmoth 453 L Mountain +454 U Quest for the Holy Relic +455 C Resurrection +456 S Silence +457 U Twinblade Paladin +458 U Undead Slayer +459 U Air Elemental +460 C Invisibility +461 U Invisible Stalker +462 C Jump +463 R Polymorph +464 U Raven Familiar +465 U Sleep +466 C Sleeping Potion +467 R Tempest Djinn +468 R Trade Routes +469 U Treasure Trove +470 U Assassin's Blade +471 R Captivating Vampire +472 R Demonic Tutor +473 C Dungeon Shade +474 R Nightmare +475 U Noxious Ghoul +476 U Tymaret, Chosen from Death +477 U Will-o'-the-Wisp +478 M Balefire Dragon +479 U Fireball +480 C Orcish Lumberjack +481 R Sneak Attack +482 U Stone Giant +483 R Hermit Druid +484 R Traverse the Outlands +485 R Yisan, the Wanderer Bard +486 M Arcades, the Strategist +487 M Daxos the Returned +488 M Dragonlord Dromoka +489 R Grenzo, Dungeon Warden +490 M Hellkite Overlord +491 R Cloud Key +492 R Coveted Jewel +493 R Doubling Cube +494 C Expedition Map +495 R Gauntlet of Power +496 U Golem's Heart +497 R Haunted Plate Mail +498 U Sorcerer's Wand +499 R Staff of Domination +500 R Transmogrifying Wand +501 R Eiganjo Castle +502 R Gemstone Caverns diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 470ae4aa85f..416513b0180 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -1034,7 +1034,7 @@ lblEnableUnknownCards=Erlaube unbekannte Karten nlEnableUnknownCards=Erlaube unbekannte Karten von unbekannten Sets. (Erfordert Neustart) lblEnableNonLegalCards=Erlaube nicht-legale Karten nlEnableNonLegalCards=Erlaube nicht-legale Karten, wie Un-Sets and PlayTest-Karten. (Erfordert Neustart) -lblEnableCustomCards=Erlaube benutzerdefinierten Karten +lblEnableCustomCards=Erlaube benutzerdefinierte Karten nlEnableCustomCards=Aktivieren Sie die Verwendung von benutzerdefinierten Karten für das Spielen. (Erfordert Neustart) lblDisableCardImages=Kartenbilder abschalten nlDisableCardImages=Wenn aktiviert, zeigt Forge keine Kartenbilder mehr. @@ -1725,6 +1725,7 @@ lblDoYouWantPayNLife=Möchtest du {0} Leben bezahlen? lblDoyouWantTo=Möchtest du lblDoYouWantMillNCardsOrDoAction=Möchtest du {0} Karte(n) von der Bibliothek auf den Friedhof legen? {1} lblDoYouWantFlipNCoinAction=Möchtest du {0} Münze(n) werfen? +lblDoYouWantRollNDiceAction=Do you want to roll {0}{1}? lblDoYouWantRemoveNTargetTypeCounterFromCard=Möchtest du {0} {1}-Marken von {2} entfernen? lblDoYouWantRemoveCountersFromCard=Möchtest du Marken von {0} entfernen? lblDoYouWantExileNCardsFromYourLibrary=Möchtest du {0} Karte(n) von deiner Bibliothek ins Exil schicken? diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 545850e5a64..f66bd7b7cd4 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -1725,6 +1725,7 @@ lblDoYouWantPayNLife=Do you want to pay {0} life? lblDoyouWantTo=Do you want to lblDoYouWantMillNCardsOrDoAction=Do you want to mill {0} card(s)? {1} lblDoYouWantFlipNCoinAction=Do you want to flip {0} coin(s)? +lblDoYouWantRollNDiceAction=Do you want to roll {0}{1}? lblDoYouWantRemoveNTargetTypeCounterFromCard=Do you want to remove {0} {1} counter from {2}? lblDoYouWantRemoveCountersFromCard=Do you want to remove counters from {0}? lblDoYouWantExileNCardsFromYourLibrary=Do you want to exile {0} card(s) from your library? diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 670c71b1f39..fbc8c2ee7bd 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -1724,6 +1724,7 @@ lblDoYouWantPayNLife=¿Quieres pagar {0} de vida? lblDoyouWantTo=¿Quieres lblDoYouWantMillNCardsOrDoAction=¿Quieres moler {0} carta(s)? {1} lblDoYouWantFlipNCoinAction=¿Quieres lanzar {0} moneda(s)? +lblDoYouWantRollNDiceAction=Do you want to roll {0}{1}? lblDoYouWantRemoveNTargetTypeCounterFromCard=¿Quieres quitar el contador {0} {1} de {2}? lblDoYouWantRemoveCountersFromCard=¿Quieres quitar los contadores de {0}? lblDoYouWantExileNCardsFromYourLibrary=¿Quieres exiliar {0} carta(s) de tu biblioteca? diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index 8c488fb82f9..705c55d8a55 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1724,6 +1724,7 @@ lblDoYouWantPayNLife=Vuoi pagare {0} punti vita? lblDoyouWantTo=Vuoi lblDoYouWantMillNCardsOrDoAction=Vuoi macinare {0} carta/e? {1} lblDoYouWantFlipNCoinAction=Vuoi lanciare {0} moneta/e? +lblDoYouWantRollNDiceAction=Do you want to roll {0}{1}? lblDoYouWantRemoveNTargetTypeCounterFromCard=Vuoi rimuovere {0} segnalino {1} da {2}? lblDoYouWantRemoveCountersFromCard=Vuoi rimuovere i segnalini da {0}? lblDoYouWantExileNCardsFromYourLibrary=Vuoi esiliare {0} carta/e dal tuo grimorio? diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index dd183bd0b6b..5792fd342ac 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -1724,7 +1724,8 @@ lblDoYouWantPay=プレイしますか? lblDoYouWantPayNLife={0}点のライフを支払いますか? lblDoyouWantTo=この行動をしてもいい? lblDoYouWantMillNCardsOrDoAction={0}枚のカードを切削しますか? {1} -lblDoYouWantFlipNCoinOrDoAction={0}枚のコイントスをしますか? {1} +lblDoYouWantFlipNCoinAction={0}枚のコイントスをしますか? +lblDoYouWantRollNDiceAction={0}{1}を投げますか? lblDoYouWantRemoveNTargetTypeCounterFromCard={2}から {1}個の {0}カウンターを取り除きますか? lblDoYouWantRemoveCountersFromCard={0}からカウンターを取り除きますか? lblDoYouWantExileNCardsFromYourLibrary=ライブラリーから {0}枚のカードを追放しますか? diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 533f8a7552d..1f0cc199f83 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -1725,6 +1725,7 @@ lblDoYouWantPayNLife=你想要支付{0}点生命吗? lblDoyouWantTo=你想要 lblDoYouWantMillNCardsOrDoAction=你想要磨{0}张牌吗? {1} lblDoYouWantFlipNCoinAction=你想要抛{0}个硬币吗? +lblDoYouWantRollNDiceAction=Do you want to roll {0}{1}? lblDoYouWantRemoveNTargetTypeCounterFromCard=你想要从{2}移除{0}个{1}指示物吗? lblDoYouWantRemoveCountersFromCard=你想要从{0}删除指示物吗? lblDoYouWantExileNCardsFromYourLibrary=你想要从你的牌库放逐{0}张牌吗? diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index 6e3920266d5..63fac618df4 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -482,6 +482,22 @@ public class HumanCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(c); } + @Override + public PaymentDecision visit(final CostRollDice cost) { + final String amount = cost.getAmount(); + Integer c = cost.convertAmount(); + + if (c == null) { + c = AbilityUtils.calculateAmount(source, amount, ability); + } + + if (!player.getController().confirmPayment(cost, Localizer.getInstance().getMessage("lblDoYouWantRollNDiceAction", String.valueOf(c), "d" + cost.getType()), ability)) { + return null; + } + + return PaymentDecision.number(c); + } + @Override public PaymentDecision visit(final CostGainControl cost) { final String amount = cost.getAmount(); diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index f7e120b8e51..a410e3e3006 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -349,6 +349,18 @@ public class HumanPlay { else part.payAsDecided(p, pd, sourceAbility); } + else if (part instanceof CostRollDice) { + if (!part.canPay(sourceAbility, p)) { + return false; + } + + PaymentDecision pd = part.accept(hcd); + + if (pd == null) + return false; + else + part.payAsDecided(p, pd, sourceAbility); + } else if (part instanceof CostDamage) { if (!part.canPay(sourceAbility, p)) { return false;