From 72181895e68638ab70a3a277119e68ac7950fee8 Mon Sep 17 00:00:00 2001 From: Eradev Date: Sat, 27 Jun 2026 06:57:36 -0400 Subject: [PATCH] Change mana restriction CantCast to be more generic --- .../game/spellability/AbilityManaPart.java | 36 ++++++++++++------- .../cardsfolder/a/archaeomancers_spade.txt | 2 +- .../res/cardsfolder/b/battery_bearer.txt | 2 +- .../res/cardsfolder/h/hydraulic_helper.txt | 2 +- ...genious_scientist_jetfire_air_guardian.txt | 2 +- .../cardsfolder/k/karn_legacy_reforged.txt | 2 +- .../cardsfolder/k/karolina_dean_runaway.txt | 2 +- .../res/cardsfolder/p/phyrexian_adapter.txt | 2 +- .../t/the_mightstone_and_weakstone.txt | 2 +- .../v/vhal_candelkeep_researcher.txt | 2 +- forge-gui/res/tokenscripts/c_a_powerstone.txt | 2 +- forge-gui/res/tokenscripts/c_a_vibranium.txt | 2 +- 12 files changed, 35 insertions(+), 23 deletions(-) diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index f95354e34ce1..d06f6a5e6f67 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -419,23 +419,35 @@ public boolean meetsManaRestrictions(final SpellAbility sa, String restrictions) return true; } - // "can't" zone restriction – shouldn't be mixed with other restrictions - if (restriction.startsWith("CantCastSpellFrom")) { + + if (restriction.startsWith("CantCast ")) { if (!sa.isSpell()) { return true; } - final ZoneType badZone = ZoneType.smartValueOf(restriction.substring(17)); - final Card host = sa.getHostCard(); - final Zone castFrom = host.getCastFrom(); - //ComputerUtilMana looks at this to see if AI can cast things, so need a fallback zone - final ZoneType zone = castFrom == null ? host.getZone().getZoneType() : castFrom.getZoneType(); - if (!badZone.equals(zone)) { - return true; + + final String subRestriction = restriction.substring(9); + + // "can't" zone restriction + if (subRestriction.startsWith("From")) { + final ZoneType badZone = ZoneType.smartValueOf(subRestriction.substring(4)); + final Card host = sa.getHostCard(); + final Zone castFrom = host.getCastFrom(); + //ComputerUtilMana looks at this to see if AI can cast things, so need a fallback zone + final ZoneType zone = castFrom == null ? host.getZone().getZoneType() : castFrom.getZoneType(); + if (!badZone.equals(zone)) { + return true; + } + + continue; + } + + // If the spell matches the restriction filter (e.g. "Spell.!Artifact"), + // then it is explicitly forbidden from using this mana. + if (sa.isValid(subRestriction, this.getSourceCard().getController(), this.getSourceCard(), null)) { + return false; } - } - if (restriction.equals("CantCastNonArtifactSpells")) { - return !sa.isSpell() || sa.getHostCard().isArtifact(); + continue; } // TODO refactor to differ between ForCost and ForEffect diff --git a/forge-gui/res/cardsfolder/a/archaeomancers_spade.txt b/forge-gui/res/cardsfolder/a/archaeomancers_spade.txt index 2ae18d63eda4..4c4ce8ab76e5 100644 --- a/forge-gui/res/cardsfolder/a/archaeomancers_spade.txt +++ b/forge-gui/res/cardsfolder/a/archaeomancers_spade.txt @@ -5,5 +5,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigSeekTwo:DB$ Seek | RememberFound$ True | Num$ 2 | Type$ Card.withFlashback | SubAbility$ DBEntomb SVar:DBEntomb:DB$ ChangeZone | Origin$ Hand | Destination$ Graveyard | Defined$ Remembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -A:AB$ Mana | Cost$ T | Produced$ R W | RestrictValid$ CantCastSpellFromHand | SpellDescription$ Add {R}{W}. This mana can't be spent to cast spells from your hand. +A:AB$ Mana | Cost$ T | Produced$ R W | RestrictValid$ CantCast FromHand | SpellDescription$ Add {R}{W}. This mana can't be spent to cast spells from your hand. Oracle:When this artifact enters, seek two cards with flashback and put them into your graveyard.\n{T}: Add {R}{W}. This mana can't be spent to cast spells from your hand. diff --git a/forge-gui/res/cardsfolder/b/battery_bearer.txt b/forge-gui/res/cardsfolder/b/battery_bearer.txt index 3718029200af..aed9fe9c47e0 100644 --- a/forge-gui/res/cardsfolder/b/battery_bearer.txt +++ b/forge-gui/res/cardsfolder/b/battery_bearer.txt @@ -3,7 +3,7 @@ ManaCost:2 G U Types:Creature Human Artificer PT:3/4 S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddAbility$ AnyMana | Description$ Creatures you control have "{T}: Add {C}. This mana can't be spent to cast a nonartifact spell." -SVar:AnyMana:AB$ Mana | Cost$ T | Produced$ C | Amount$ 1 | RestrictValid$ CantCastNonArtifactSpells | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. +SVar:AnyMana:AB$ Mana | Cost$ T | Produced$ C | Amount$ 1 | RestrictValid$ CantCast Spell.!Artifact | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. T:Mode$ SpellCast | ValidCard$ Artifact.cmcGE6 | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ DBDraw | TriggerDescription$ Whenever you cast an artifact spell with mana value 6 or greater, draw a card. SVar:DBDraw:DB$ Draw DeckNeeds:Type$Artifact diff --git a/forge-gui/res/cardsfolder/h/hydraulic_helper.txt b/forge-gui/res/cardsfolder/h/hydraulic_helper.txt index 4dfd27d74b76..6e5e65aa3609 100644 --- a/forge-gui/res/cardsfolder/h/hydraulic_helper.txt +++ b/forge-gui/res/cardsfolder/h/hydraulic_helper.txt @@ -3,5 +3,5 @@ ManaCost:1 U Types:Artifact Creature Robot PT:2/3 K:Defender -A:AB$ Mana | Cost$ T | Produced$ U | RestrictValid$ CantCastNonArtifactSpells | SpellDescription$ Add {U}. This mana can't be spent to cast a nonartifact spell. +A:AB$ Mana | Cost$ T | Produced$ U | RestrictValid$ CantCast Spell.!Artifact | SpellDescription$ Add {U}. This mana can't be spent to cast a nonartifact spell. Oracle:Defender\n{T}: Add {U}. This mana can't be spent to cast a nonartifact spell. diff --git a/forge-gui/res/cardsfolder/j/jetfire_ingenious_scientist_jetfire_air_guardian.txt b/forge-gui/res/cardsfolder/j/jetfire_ingenious_scientist_jetfire_air_guardian.txt index 4b81d62084e1..caf16129b4c2 100644 --- a/forge-gui/res/cardsfolder/j/jetfire_ingenious_scientist_jetfire_air_guardian.txt +++ b/forge-gui/res/cardsfolder/j/jetfire_ingenious_scientist_jetfire_air_guardian.txt @@ -4,7 +4,7 @@ Types:Legendary Artifact Creature Robot PT:3/4 K:More Than Meets the Eye:3 U K:Flying -A:AB$ Mana | Cost$ RemoveAnyCounter | XMin$ 1 | ValidTgts$ Player | Produced$ C | Amount$ X | AmountDesc$ for each counter removed | RestrictValid$ CantCastNonArtifactSpells | SubAbility$ DBConvert | SpellDescription$ Target player adds that much {C}. This mana can't be spent to cast nonartifact spells. +A:AB$ Mana | Cost$ RemoveAnyCounter | XMin$ 1 | ValidTgts$ Player | Produced$ C | Amount$ X | AmountDesc$ for each counter removed | RestrictValid$ CantCast Spell.!Artifact | SubAbility$ DBConvert | SpellDescription$ Target player adds that much {C}. This mana can't be spent to cast nonartifact spells. SVar:DBConvert:DB$ SetState | Mode$ Transform | StackDescription$ SpellDescription | SpellDescription$ Convert NICKNAME. SVar:X:Count$xPaid AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/k/karn_legacy_reforged.txt b/forge-gui/res/cardsfolder/k/karn_legacy_reforged.txt index cb54c7ce7c0d..f1c1b84a5748 100644 --- a/forge-gui/res/cardsfolder/k/karn_legacy_reforged.txt +++ b/forge-gui/res/cardsfolder/k/karn_legacy_reforged.txt @@ -4,7 +4,7 @@ Types:Legendary Artifact Creature Golem PT:*/* S:Mode$ Continuous | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the greatest mana value among artifacts you control. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ ArtifactMana | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, add {C} for each artifact you control. This mana can't be spent to cast nonartifact spells. Until end of turn, you don't lose this mana as steps and phases end. -SVar:ArtifactMana:DB$ Mana | Produced$ C | Amount$ Y | PersistentMana$ True | RestrictValid$ CantCastNonArtifactSpells +SVar:ArtifactMana:DB$ Mana | Produced$ C | Amount$ Y | PersistentMana$ True | RestrictValid$ CantCast Spell.!Artifact SVar:X:Count$Valid Artifact.YouCtrl$GreatestCardManaCost SVar:Y:Count$Valid Artifact.YouCtrl SVar:BuffedBy:Artifact diff --git a/forge-gui/res/cardsfolder/k/karolina_dean_runaway.txt b/forge-gui/res/cardsfolder/k/karolina_dean_runaway.txt index cd3c6d888b98..acda878ee68c 100644 --- a/forge-gui/res/cardsfolder/k/karolina_dean_runaway.txt +++ b/forge-gui/res/cardsfolder/k/karolina_dean_runaway.txt @@ -4,5 +4,5 @@ Types:Legendary Creature Alien Hero PT:3/3 K:Flying T:Mode$ Phase | Phase$ Main1 | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigMana | TriggerDescription$ At the beginning of your first main phase, add {W}{U}{B}{R}{G}. You can't spend this mana to cast spells from your hand. -SVar:TrigMana:DB$ Mana | Produced$ W U B R G | RestrictValid$ CantCastSpellFromHand +SVar:TrigMana:DB$ Mana | Produced$ W U B R G | RestrictValid$ CantCast FromHand Oracle:Flying\nAt the beginning of your first main phase, add {W}{U}{B}{R}{G}. You can't spend this mana to cast spells from your hand. diff --git a/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt b/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt index 81af600549ba..bb35ed853e1c 100644 --- a/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt +++ b/forge-gui/res/cardsfolder/p/phyrexian_adapter.txt @@ -8,7 +8,7 @@ SVar:FoodSac:AB$ GainLife | Cost$ 2 T Sac<1/CARDNAME/this artifact> | LifeAmount 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. +SVar:PowerstoneTap:AB$ Mana | Cost$ T | Produced$ C | RestrictValid$ CantCast Spell.!Artifact | 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/t/the_mightstone_and_weakstone.txt b/forge-gui/res/cardsfolder/t/the_mightstone_and_weakstone.txt index ac24cccc55a3..85601cccd46b 100644 --- a/forge-gui/res/cardsfolder/t/the_mightstone_and_weakstone.txt +++ b/forge-gui/res/cardsfolder/t/the_mightstone_and_weakstone.txt @@ -5,7 +5,7 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigCharm:DB$ Charm | Choices$ DBDraw,DBPump SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 2 | SpellDescription$ Draw two cards. SVar:DBPump:DB$ Pump | IsCurse$ True | ValidTgts$ Creature | NumAtt$ -5 | NumDef$ -5 | SpellDescription$ Target creature gets -5/-5 until end of turn. -A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 2 | RestrictValid$ CantCastNonArtifactSpells | SpellDescription$ Add {C}{C}. This mana can't be spent to cast nonartifact spells. +A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 2 | RestrictValid$ CantCast Spell.!Artifact | SpellDescription$ Add {C}{C}. This mana can't be spent to cast nonartifact spells. DeckHints:Name$Urza, Lord Protector MeldPair:Urza, Lord Protector AlternateMode:Meld diff --git a/forge-gui/res/cardsfolder/v/vhal_candelkeep_researcher.txt b/forge-gui/res/cardsfolder/v/vhal_candelkeep_researcher.txt index cf44ac5a66db..c70d5733a310 100644 --- a/forge-gui/res/cardsfolder/v/vhal_candelkeep_researcher.txt +++ b/forge-gui/res/cardsfolder/v/vhal_candelkeep_researcher.txt @@ -3,7 +3,7 @@ ManaCost:3 U Types:Legendary Creature Human Wizard PT:2/3 K:Vigilance -A:AB$ Mana | Cost$ T | Produced$ C | Amount$ X | RestrictValid$ CantCastSpellFromHand | SpellDescription$ Add an amount of {C} equal to CARDNAME's toughness. This mana can't be spent to cast spells from your hand. +A:AB$ Mana | Cost$ T | Produced$ C | Amount$ X | RestrictValid$ CantCast FromHand | SpellDescription$ Add an amount of {C} equal to CARDNAME's toughness. This mana can't be spent to cast spells from your hand. SVar:X:Count$CardToughness K:Choose a Background AI:RemoveDeck:Random diff --git a/forge-gui/res/tokenscripts/c_a_powerstone.txt b/forge-gui/res/tokenscripts/c_a_powerstone.txt index 69df785598e1..1b212341612b 100644 --- a/forge-gui/res/tokenscripts/c_a_powerstone.txt +++ b/forge-gui/res/tokenscripts/c_a_powerstone.txt @@ -2,5 +2,5 @@ Name:Powerstone Token ManaCost:no cost Colors:colorless Types:Artifact Powerstone -A:AB$ Mana | Cost$ T | Produced$ C | RestrictValid$ CantCastNonArtifactSpells | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. +A:AB$ Mana | Cost$ T | Produced$ C | RestrictValid$ CantCast Spell.!Artifact | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. Oracle:{T}: Add {C}. This mana can't be spent to cast a nonartifact spell. diff --git a/forge-gui/res/tokenscripts/c_a_vibranium.txt b/forge-gui/res/tokenscripts/c_a_vibranium.txt index 2bc52f4f79fc..06c2bfa010e3 100644 --- a/forge-gui/res/tokenscripts/c_a_vibranium.txt +++ b/forge-gui/res/tokenscripts/c_a_vibranium.txt @@ -3,5 +3,5 @@ ManaCost:no cost Colors:colorless Types:Artifact Vibranium K:Indestructible -A:AB$ Mana | Cost$ T | Produced$ C | RestrictValid$ CantCastNonArtifactSpells | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. +A:AB$ Mana | Cost$ T | Produced$ C | RestrictValid$ CantCast Spell.!Artifact | SpellDescription$ Add {C}. This mana can't be spent to cast a nonartifact spell. Oracle:Indestructible\n{T}: Add {C}. This mana can't be spent to cast a nonartifact spell.