From 21c34b552dd917cfcf09f3047ba248edc86ee25f Mon Sep 17 00:00:00 2001 From: tool4ever Date: Sat, 14 Sep 2024 19:47:40 +0200 Subject: [PATCH] Fix Frankenstein's Monster (#6143) --- .../ability/effects/CountersPutEffect.java | 33 +++++++++++++------ .../game/ability/effects/ReplaceEffect.java | 2 +- .../StaticAbilityPanharmonicon.java | 4 +++ .../cardsfolder/f/frankensteins_monster.txt | 10 ++---- .../upcoming/marina_vendrells_grimoire.txt | 2 +- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java index c3f3d970542..fa13b0a3ced 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java @@ -91,13 +91,12 @@ public class CountersPutEffect extends SpellAbilityEffect { // skip the StringBuilder if no targets are chosen ("up to" scenario) if (sa.usesTargeting()) { final List targetCards = getTargetCards(sa); - if (targetCards.size() == 0) { + if (targetCards.isEmpty()) { return stringBuilder.toString(); } } - final String key = forEach ? "ForEachNum" : "CounterNum"; - final int amount = AbilityUtils.calculateAmount(card, sa.getParamOrDefault(key, "1"), sa); + final int amount = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("CounterNum", "1"), sa); if (sa.hasParam("Bolster")) { stringBuilder.append("bolsters ").append(amount).append("."); @@ -308,7 +307,7 @@ public class CountersPutEffect extends SpellAbilityEffect { for (int i = 0; i < num; i++) { CounterType ct = chooseTypeFromList(sa, options, obj, pc); typesToAdd.add(ct); - options = options.replace(ct.getName(),""); + options = options.replace(ct.getName(), ""); } for (CounterType ct : typesToAdd) { if (obj instanceof Player) { @@ -338,7 +337,7 @@ public class CountersPutEffect extends SpellAbilityEffect { CardCollectionView counterCards = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), type.split("_")[1], activator, card, sa); - List counterTypes = Lists.newArrayList(); + List counterTypes = Lists.newArrayList(); for (Card c : counterCards) { for (final Map.Entry map : c.getCounters().entrySet()) { if (!counterTypes.contains(map.getKey())) { @@ -357,7 +356,23 @@ public class CountersPutEffect extends SpellAbilityEffect { typesToAdd.add(CounterType.getType(type)); } } + int remaining = counterAmount; for (CounterType ct : typesToAdd) { + if (sa.hasParam("SplitAmount")) { + if (typesToAdd.size() - typesToAdd.indexOf(ct) > 1) { + Map params = Maps.newHashMap(); + params.put("Target", obj); + params.put("CounterType", counterType); + counterAmount = pc.chooseNumber(sa, ct.toString() + ": " + + Localizer.getInstance().getMessage("lblHowManyCounters"), 0, remaining, params); + if (counterAmount == 0) { + continue; + } + remaining -= counterAmount; + } else { + counterAmount = remaining; + } + } if (obj instanceof Player) { ((Player) obj).addCounter(ct, counterAmount, placer, table); } @@ -483,11 +498,9 @@ public class CountersPutEffect extends SpellAbilityEffect { } // Adapt need extra logic - if (sa.hasParam("Adapt")) { - if (!(gameCard.getCounters(CounterEnumType.P1P1) == 0 - || StaticAbilityAdapt.anyWithAdapt(sa, gameCard))) { - continue; - } + if (sa.hasParam("Adapt") && + !(gameCard.getCounters(CounterEnumType.P1P1) == 0 || StaticAbilityAdapt.anyWithAdapt(sa, gameCard))) { + continue; } if (sa.isKeyword(Keyword.TRIBUTE)) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java index 82fa064dc41..84c937f9a80 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ReplaceEffect.java @@ -48,7 +48,7 @@ public class ReplaceEffect extends SpellAbilityEffect { for (Player key : AbilityUtils.getDefinedPlayers(card, sa.getParam("VarKey"), sa)) { m.put(key, m.getOrDefault(key, 0) + AbilityUtils.calculateAmount(card, varValue, sa)); } - } else { + } else if (varName != null) { params.put(varName, AbilityUtils.calculateAmount(card, varValue, sa)); } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java index 0d9066955b2..1b4bc16c7f4 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityPanharmonicon.java @@ -62,6 +62,10 @@ public class StaticAbilityPanharmonicon { continue; } // it can't trigger more times than the limit allows + if (t.hasParam("GameActivationLimit") && + t.getActivationsThisGame() + n + 1 >= Integer.parseInt(t.getParam("GameActivationLimit"))) { + break; + } if (t.hasParam("ActivationLimit") && t.getActivationsThisTurn() + n + 1 >= Integer.parseInt(t.getParam("ActivationLimit"))) { break; diff --git a/forge-gui/res/cardsfolder/f/frankensteins_monster.txt b/forge-gui/res/cardsfolder/f/frankensteins_monster.txt index a40e651dfff..3ddbf2387c6 100644 --- a/forge-gui/res/cardsfolder/f/frankensteins_monster.txt +++ b/forge-gui/res/cardsfolder/f/frankensteins_monster.txt @@ -5,13 +5,9 @@ PT:0/1 R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$ ExileCreature | Description$ As CARDNAME enters, exile X creature cards from your graveyard. If you can't, put CARDNAME into its owner's graveyard instead of onto the battlefield. For each creature card exiled this way, CARDNAME enters with a +2/+0, +1/+1, or +0/+2 counter on it. SVar:ExileCreature:DB$ ChooseCard | ETB$ True | Choices$ Creature.YouOwn+NotDefinedReplacedSimultaneousETB | ChoiceZone$ Graveyard | Amount$ X | Mandatory$ True | ConditionCheckSVar$ CheckYard | ConditionSVarCompare$ GEX | SubAbility$ DBExile SVar:DBExile:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Graveyard | Destination$ Exile | RememberChanged$ True | SubAbility$ Movetoyard -SVar:Movetoyard:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Graveyard | Defined$ Self | ConditionCheckSVar$ CheckExiled | ConditionSVarCompare$ LTX | Imprint$ True | ETB$ True | SubAbility$ ChooseCounters -SVar:ChooseCounters:DB$ Repeat | MaxRepeat$ X | ETB$ True | RepeatSubAbility$ DBChooseCounter | ConditionCheckSVar$ CheckExiled | ConditionSVarCompare$ EQX | SubAbility$ MovetoPlay -SVar:DBChooseCounter:DB$ GenericChoice | Choices$ SVarP1P1,SVarP2P0,SVarP0P2 -SVar:SVarP1P1:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 | ETB$ True | SpellDescription$ +1/+1 -SVar:SVarP2P0:DB$ PutCounter | CounterType$ P2P0 | CounterNum$ 1 | ETB$ True | SpellDescription$ +2/+0 -SVar:SVarP0P2:DB$ PutCounter | CounterType$ P0P2 | CounterNum$ 1 | ETB$ True | SpellDescription$ +0/+2 -SVar:MovetoPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ Self | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCleanup +SVar:Movetoyard:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Graveyard | Defined$ Self | ConditionCheckSVar$ CheckExiled | ConditionSVarCompare$ LTX | Imprint$ True | ETB$ True | SubAbility$ DBChooseCounter +SVar:DBChooseCounter:DB$ PutCounter | CounterTypes$ P2P0,P1P1,P0P2 | CounterNum$ X | SplitAmount$ True | ETB$ True | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBUpdate +SVar:DBUpdate:DB$ ReplaceEffect | ConditionDefined$ Imprinted | ConditionPresent$ Card | ConditionCompare$ EQ0 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True SVar:X:Count$xPaid SVar:CheckExiled:Count$ValidExile Card.IsRemembered diff --git a/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt b/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt index 13acd344541..3fa50f07df2 100644 --- a/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt +++ b/forge-gui/res/cardsfolder/upcoming/marina_vendrells_grimoire.txt @@ -9,7 +9,7 @@ T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ Tri SVar:TrigDraw2:DB$ Draw | Defined$ You | NumCards$ X T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ Whenever you lose life, discard that many cards. Then if you have no cards in hand, you lose the game. SVar:TrigDiscard:DB$ Discard | Defined$ You | NumCards$ X | Mode$ TgtChoose | SubAbility$ DBLosesGame -SVar:DBLosesGame:DB$ LosesGame | Defined$ You | CheckSVar$ Y | SVarCompare$ EQ0 +SVar:DBLosesGame:DB$ LosesGame | Defined$ You | ConditionCheckSVar$ Y | ConditionSVarCompare$ EQ0 SVar:X:TriggerCount$LifeAmount SVar:Y:Count$InYourHand Oracle:When Marine Vendrell's Grimoire enters, if you cast it, draw five cards.\nYou have no maximum hand size and don't lose the game for having 0 or less life.\nWhenever you gain life, draw that many cards.\nWhenever you lose life, discard that many cards. Then if you have no cards in hand, you lose the game.