From 35cd7d0f4eee531892a945f36dd72bbd51a923d3 Mon Sep 17 00:00:00 2001 From: Agetian Date: Wed, 25 Sep 2024 11:02:22 +0300 Subject: [PATCH 1/6] - Add puzzle PS_BLB4, fix GameState support for class level. (#6195) --- forge-ai/src/main/java/forge/ai/GameState.java | 2 +- forge-gui/res/puzzle/PS_BLB4.pzl | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 forge-gui/res/puzzle/PS_BLB4.pzl diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index e663feb77da..4939cdd9282 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -1398,7 +1398,7 @@ public abstract class GameState { c.setTurnInZone(turn); } else if (info.equals("IsToken")) { c.setGamePieceType(GamePieceType.TOKEN); - } else if (info.equals("ClassLevel:")) { + } else if (info.startsWith("ClassLevel:")) { c.setClassLevel(Integer.parseInt(info.substring(info.indexOf(':') + 1))); } } diff --git a/forge-gui/res/puzzle/PS_BLB4.pzl b/forge-gui/res/puzzle/PS_BLB4.pzl new file mode 100644 index 00000000000..6ce0bc5ecad --- /dev/null +++ b/forge-gui/res/puzzle/PS_BLB4.pzl @@ -0,0 +1,16 @@ +[metadata] +Name:Possibility Storm - Bloomburrow #04 +URL:https://i2.wp.com/www.possibilitystorm.com/wp-content/uploads/2024/09/latest-scaled.jpg?ssl=1 +Goal:Win +Turns:1 +Difficulty:Mythic +Description:Win this turn. Ensure your solution satisfies all possible blocking decisions. Good luck! +[state] +turn=1 +activeplayer=p0 +activephase=MAIN1 +p0life=20 +p0hand=Ornery Tumblewagg;Oko, the Ringleader;Season of Gathering;Shivan Devastator;Ferocification +p0battlefield=Innkeeper's Talent|ClassLevel:2;Rampaging Geoderm;Kami of Whispered Hopes|Counters:P1P1=2;Island;Island;Mountain;Mountain;Forest;Forest +p1life=17 +p1battlefield=Fear of Immobility;Shield-Wall Sentinel From fb5d9a0b562eb03d6898b0a9d7c9aeba0d2a4cc5 Mon Sep 17 00:00:00 2001 From: tool4ever Date: Wed, 25 Sep 2024 10:02:36 +0200 Subject: [PATCH 2/6] Update valgavoths_onslaught.txt (#6187) --- forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt b/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt index b40db49938f..96b8e79f6f4 100644 --- a/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt +++ b/forge-gui/res/cardsfolder/upcoming/valgavoths_onslaught.txt @@ -1,6 +1,6 @@ Name:Valgavoth's Onslaught ManaCost:X X G -Types:Instant +Types:Sorcery A:SP$ ManifestDread | Amount$ X | RememberManifested$ True | SubAbility$ DBPutCounter SVar:DBPutCounter:DB$ PutCounter | Defined$ RememberedCard | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True From 68db59f080528e5a9a72e326fbd97ad8f4c36c95 Mon Sep 17 00:00:00 2001 From: Ayora29 Date: Wed, 25 Sep 2024 13:01:18 +0200 Subject: [PATCH 3/6] New dsk card : Monstrous Emergence (#6194) --- forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt | 4 ++-- .../res/cardsfolder/upcoming/monstruous_emergence.txt | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/monstruous_emergence.txt diff --git a/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt b/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt index 95cb1eb8a63..28d409da95f 100644 --- a/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt +++ b/forge-gui/res/cardsfolder/upcoming/friendly_teddy.txt @@ -2,6 +2,6 @@ Name:Friendly Teddy ManaCost:2 Types:Artifact Creature Bear Toy PT:2/2 -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters, each player draws a card. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME dies, each player draws a card. SVar:TrigDraw:DB$ Draw | Defined$ Player -Oracle:When Friendly Teddy enters, each player draws a card. \ No newline at end of file +Oracle:When Friendly Teddy dies, each player draws a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/monstruous_emergence.txt b/forge-gui/res/cardsfolder/upcoming/monstruous_emergence.txt new file mode 100644 index 00000000000..1473bb4189d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/monstruous_emergence.txt @@ -0,0 +1,7 @@ +Name:Monstrous Emergence +ManaCost:1 G +Types:Sorcery +A:SP$ DealDamage | Cost$ 1 G RevealOrChoose<1/Creature> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ X | SpellDescription$ CARDNAME deals damage equal to the power of the creature you chose or the card you revealed to target creature. +SVar:X:Revealed$CardPower +AI:RemoveDeck:All +Oracle:As an additional cost to cast this spell, choose a creature you control or reveal a creature card from your hand.\nMonstrous Emergence deals damage equal to the power of the creature you chose or the card you revealed to target creature. From 786d6834ef17bb91e3e76e36cbfd2bf1ec1dc268 Mon Sep 17 00:00:00 2001 From: Michael Lo Date: Wed, 25 Sep 2024 15:58:28 +0100 Subject: [PATCH 4/6] Fix valiant cards only triggering once per game rather than once per turn (#6196) --- forge-game/src/main/java/forge/game/card/Card.java | 1 + 1 file changed, 1 insertion(+) 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 df4e2fc8cfe..fe5b8489d91 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -7206,6 +7206,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars, ITr setRegeneratedThisTurn(0); resetShieldCount(); setBecameTargetThisTurn(false); + setValiant(false); setFoughtThisTurn(false); turnedFaceUpThisTurn = false; clearMustBlockCards(); From 2ac31bf45cc05d3ac0e9b8bf90432840a7c2634a Mon Sep 17 00:00:00 2001 From: Fulgur14 <54345051+Fulgur14@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:19:53 +0200 Subject: [PATCH 5/6] Rename monstruous_emergence.txt to monstrous_emergence.txt (#6197) --- .../{monstruous_emergence.txt => monstrous_emergence.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename forge-gui/res/cardsfolder/upcoming/{monstruous_emergence.txt => monstrous_emergence.txt} (100%) diff --git a/forge-gui/res/cardsfolder/upcoming/monstruous_emergence.txt b/forge-gui/res/cardsfolder/upcoming/monstrous_emergence.txt similarity index 100% rename from forge-gui/res/cardsfolder/upcoming/monstruous_emergence.txt rename to forge-gui/res/cardsfolder/upcoming/monstrous_emergence.txt From 941a1129e540a424331d3d992326fae0138178d6 Mon Sep 17 00:00:00 2001 From: tool4ever Date: Thu, 26 Sep 2024 07:52:08 +0200 Subject: [PATCH 6/6] Make Myriad optional for each player again (#6191) * Make Myriad optional for each player again * Fix scripts * Fix NPE due to not removing empty shards --------- Co-authored-by: TRT <> Co-authored-by: tool4EvEr --- .../game/ability/effects/CopyPermanentEffect.java | 4 ++++ .../main/java/forge/game/card/CardFactoryUtil.java | 2 +- .../main/java/forge/game/mana/ManaCostBeingPaid.java | 12 ++++++------ forge-gui/res/cardsfolder/d/doomsday.txt | 2 +- forge-gui/res/cardsfolder/s/saw_in_half.txt | 2 +- .../cardsfolder/upcoming/valgavoth_terror_eater.txt | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) 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 7f3ca431d7d..08ac7418f67 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 @@ -258,6 +258,10 @@ public class CopyPermanentEffect extends TokenEffectBase { if (sa.hasParam("ForEach")) { for (Player p : AbilityUtils.getDefinedPlayers(host, sa.getParam("ForEach"), sa)) { + if (sa.hasParam("OptionalForEach") && !activator.getController().confirmAction(sa, null, + Localizer.getInstance().getMessage("lblCopyPermanentConfirm") + " (" + p + ")", null)) { + continue; + } Card proto = getProtoType(sa, c, controller); proto.addRemembered(p); tokenTable.put(controller, proto, numCopies); diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 4d64ee8fb2d..ecb07b2b39b 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1553,7 +1553,7 @@ public class CardFactoryUtil { final String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True" + " | TriggerDescription$ Myriad (" + inst.getReminderText() + ")"; - final String copyStr = "DB$ CopyPermanent | Defined$ Self | TokenTapped$ True | Optional$ True | TokenAttacking$ RememberedPlayer & Valid Planeswalker.ControlledBy Remembered" + final String copyStr = "DB$ CopyPermanent | Defined$ Self | TokenTapped$ True | OptionalForEach$ True | TokenAttacking$ RememberedPlayer & Valid Planeswalker.ControlledBy Remembered" + "| ForEach$ OppNonDefendingPlayer | AtEOT$ ExileCombat | CleanupForEach$ True"; final SpellAbility copySA = AbilityFactory.getAbility(copyStr, card); diff --git a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java index 1b2933d00f0..04788a01ae3 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostBeingPaid.java @@ -307,7 +307,7 @@ public class ManaCostBeingPaid { sc.xCount = sc.totalCount; } // nothing more left in otherSubtract - return; + break; } } } @@ -327,7 +327,7 @@ public class ManaCostBeingPaid { sc.xCount = sc.totalCount; } // nothing more left in otherSubtract - return; + break; } } } @@ -347,7 +347,7 @@ public class ManaCostBeingPaid { sc.xCount = sc.totalCount; } // nothing more left in otherSubtract - return; + break; } } } @@ -367,7 +367,7 @@ public class ManaCostBeingPaid { sc.xCount = sc.totalCount; } // nothing more left in otherSubtract - return; + break; } } } @@ -389,7 +389,7 @@ public class ManaCostBeingPaid { sc.xCount = sc.totalCount; } // nothing more left in otherSubtract - return; + break; } } else if (sc.xCount > 0) { // X part that can only be paid by specific color if (otherSubtract >= sc.xCount) { @@ -403,7 +403,7 @@ public class ManaCostBeingPaid { sc.totalCount -= otherSubtract; sc.xCount -= otherSubtract; // nothing more left in otherSubtract - return; + break; } } } diff --git a/forge-gui/res/cardsfolder/d/doomsday.txt b/forge-gui/res/cardsfolder/d/doomsday.txt index 2554696e343..e0b92280dc4 100644 --- a/forge-gui/res/cardsfolder/d/doomsday.txt +++ b/forge-gui/res/cardsfolder/d/doomsday.txt @@ -1,7 +1,7 @@ Name:Doomsday ManaCost:B B B Types:Sorcery -A:SP$ ChangeZone | Origin$ Graveyard,Library | Destination$ Library | ChangeType$ Card | ChangeNum$ 5 | SubAbility$ DBChangeZone | RememberChanged$ True | Mandatory$ True | SpellDescription$ Search your library and graveyard for five cards and exile the rest. Put the chosen cards on top of your library in any order. You lose half your life, rounded up. +A:SP$ ChangeZone | Origin$ Graveyard,Library | Destination$ Library | ChangeType$ Card | ChangeNum$ 5 | Shuffle$ False | SubAbility$ DBChangeZone | RememberChanged$ True | Mandatory$ True | SpellDescription$ Search your library and graveyard for five cards and exile the rest. Put the chosen cards on top of your library in any order. You lose half your life, rounded up. SVar:DBChangeZone:DB$ ChangeZoneAll | Defined$ You | Origin$ Graveyard,Library | Destination$ Exile | ChangeType$ Card.IsNotRemembered | SubAbility$ DBDig SVar:DBDig:DB$ RearrangeTopOfLibrary | Defined$ You | NumCards$ X | SubAbility$ DBLoseLife SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ Y | SubAbility$ DBCleanup diff --git a/forge-gui/res/cardsfolder/s/saw_in_half.txt b/forge-gui/res/cardsfolder/s/saw_in_half.txt index 9a6f9ba25af..de86038d9a0 100644 --- a/forge-gui/res/cardsfolder/s/saw_in_half.txt +++ b/forge-gui/res/cardsfolder/s/saw_in_half.txt @@ -2,7 +2,7 @@ Name:Saw in Half ManaCost:2 B Types:Instant A:SP$ Destroy | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBCopy | RememberLKI$ True | SpellDescription$ Destroy target creature. -SVar:DBCopy:DB$ CopyPermanent | Defined$ Remembered | NumCopies$ 2 | Controller$ TargetedController | SetPower$ dX | SetToughness$ dY | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ If that creature dies this way, its controller creates two tokens that are copies of that creature, except their base power is half that creature's power and their base toughness is half that creature's toughness. Round up each time. +SVar:DBCopy:DB$ CopyPermanent | Defined$ RememberedLKI | NumCopies$ 2 | Controller$ TargetedController | SetPower$ dX | SetToughness$ dY | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ If that creature dies this way, its controller creates two tokens that are copies of that creature, except their base power is half that creature's power and their base toughness is half that creature's toughness. Round up each time. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Remembered$Amount SVar:dX:RememberedLKI$CardPower/HalfUp diff --git a/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt b/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt index 8d953f72576..6f003372032 100644 --- a/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt +++ b/forge-gui/res/cardsfolder/upcoming/valgavoth_terror_eater.txt @@ -5,7 +5,7 @@ PT:9/9 K:Flying K:Lifelink K:Ward:Sac<3/Permanent.nonLand/nonland permanent> -R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Graveyard | ValidCard$ Card.nonToken+YouDontCtrl+OppOwn | ReplaceWith$ Exile | Description$ If a card you didn't control would be put into an opponent's graveyard from anywhere, exile it instead. +R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Graveyard | ValidLKI$ Card.nonToken+YouDontCtrl+OppOwn | ReplaceWith$ Exile | Description$ If a card you didn't control would be put into an opponent's graveyard from anywhere, exile it instead. SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard S:Mode$ Continuous | Condition$ PlayerTurn | MayPlay$ True | Affected$ Card.ExiledWithSource | AffectedZone$ Exile | MayPlayAltManaCost$ PayLife | Description$ During your turn, you may play cards exiled with NICKNAME. If you cast a spell this way, pay life equal to its mana value rather than pay its mana cost. Oracle:Flying, lifelink\nWard—Sacrifice three nonland permanents.\nIf a card you didn't control would be put into an opponent's graveyard from anywhere, exile it instead.\nDuring your turn, you may play cards exiled with Valgavoth. If you cast a spell this way, pay life equal to its mana value rather than pay its mana cost. \ No newline at end of file