From fa7e9024fe0f08479b707922e53f38245c84f709 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Sun, 7 May 2023 23:44:07 +0200 Subject: [PATCH 1/4] Fix rollback sometimes reverting to LKI version of card --- forge-game/src/main/java/forge/game/GameActionUtil.java | 3 +++ forge-gui/res/cardsfolder/a/aethersquall_ancient.txt | 2 +- forge-gui/res/cardsfolder/f/first_responder.txt | 2 +- forge-gui/res/cardsfolder/k/kethek_crucible_goliath.txt | 2 +- forge-gui/res/cardsfolder/l/loyal_unicorn.txt | 4 ++-- forge-gui/res/cardsfolder/z/ziatora_the_incinerator.txt | 2 +- forge-gui/src/main/java/forge/player/HumanPlay.java | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index fb6e0936897..a4c34e45a21 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -868,6 +868,9 @@ public final class GameActionUtil { final Game game = ability.getActivatingPlayer().getGame(); if (fromZone != null) { // and not a copy + // might have been an alternative lki host + oldCard = ability.getCardState().getCard(); + oldCard.setCastSA(null); oldCard.setCastFrom(null); // add back to where it came from, hopefully old state diff --git a/forge-gui/res/cardsfolder/a/aethersquall_ancient.txt b/forge-gui/res/cardsfolder/a/aethersquall_ancient.txt index 98c9bf47925..c371acb5ad6 100644 --- a/forge-gui/res/cardsfolder/a/aethersquall_ancient.txt +++ b/forge-gui/res/cardsfolder/a/aethersquall_ancient.txt @@ -5,5 +5,5 @@ PT:6/6 K:Flying T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigEnergy | TriggerDescription$ At the beginning of your upkeep, you get {E}{E}{E} (three energy counters). SVar:TrigEnergy:DB$ PutCounter | Defined$ You | CounterType$ ENERGY | CounterNum$ 3 -A:AB$ ChangeZoneAll | Cost$ PayEnergy<8> | ChangeType$ Creature.Other | SorcerySpeed$ True | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return all other creatures to their owners' hands. Activate only as a sorcery. +A:AB$ ChangeZoneAll | Cost$ PayEnergy<8> | ChangeType$ Creature.StrictlyOther | SorcerySpeed$ True | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return all other creatures to their owners' hands. Activate only as a sorcery. Oracle:Flying\nAt the beginning of your upkeep, you get {E}{E}{E} (three energy counters).\nPay {E}{E}{E}{E}{E}{E}{E}{E}: Return all other creatures to their owners' hands. Activate only as a sorcery. diff --git a/forge-gui/res/cardsfolder/f/first_responder.txt b/forge-gui/res/cardsfolder/f/first_responder.txt index 429d91bcb09..a1ec6f9bb04 100644 --- a/forge-gui/res/cardsfolder/f/first_responder.txt +++ b/forge-gui/res/cardsfolder/f/first_responder.txt @@ -4,7 +4,7 @@ Types:Creature Ogre Citizen PT:3/3 K:Vigilance T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ At the beginning of your end step, you may return another creature you control to its owner's hand, then put a number of +1/+1 counters equal to that creature's power on CARDNAME. -SVar:TrigReturn:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | Hidden$ True | ChangeType$ Creature.Other+YouCtrl | RememberLKI$ True | SubAbility$ DBPutCounter +SVar:TrigReturn:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | Hidden$ True | ChangeType$ Creature.StrictlyOther+YouCtrl | RememberLKI$ True | SubAbility$ DBPutCounter SVar:DBPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:RememberedLKI$CardPower diff --git a/forge-gui/res/cardsfolder/k/kethek_crucible_goliath.txt b/forge-gui/res/cardsfolder/k/kethek_crucible_goliath.txt index 8c53ddc3667..e96b24a31ac 100644 --- a/forge-gui/res/cardsfolder/k/kethek_crucible_goliath.txt +++ b/forge-gui/res/cardsfolder/k/kethek_crucible_goliath.txt @@ -3,7 +3,7 @@ ManaCost:2 R B Types:Legendary Creature Phyrexian Beast PT:4/4 T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, you may sacrifice another creature. If you do, reveal cards from the top of your library until you reveal a nonlegendary creature card with lesser mana value, put it onto the battlefield, then put the rest on the bottom of your library in a random order. -SVar:TrigSac:AB$ DigUntil | Cost$ Sac<1/Creature.Other/another creature> | Defined$ You | Valid$ Card.Creature+nonLegendary+cmcLTX | FoundDestination$ Battlefield | RevealedDestination$ Library | RevealRandomOrder$ True +SVar:TrigSac:AB$ DigUntil | Cost$ Sac<1/Creature.StrictlyOther/another creature> | Defined$ You | Valid$ Card.Creature+nonLegendary+cmcLTX | FoundDestination$ Battlefield | RevealedDestination$ Library | RevealRandomOrder$ True SVar:X:Sacrificed$CardManaCost DeckHas:Ability$Sacrifice Oracle:At the beginning of your end step, you may sacrifice another creature. If you do, reveal cards from the top of your library until you reveal a nonlegendary creature card with lesser mana value, put it onto the battlefield, then put the rest on the bottom of your library in a random order. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/l/loyal_unicorn.txt b/forge-gui/res/cardsfolder/l/loyal_unicorn.txt index 0bf25b00f38..1afb9b0dd34 100644 --- a/forge-gui/res/cardsfolder/l/loyal_unicorn.txt +++ b/forge-gui/res/cardsfolder/l/loyal_unicorn.txt @@ -4,9 +4,9 @@ Types:Creature Unicorn PT:3/4 K:Vigilance T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | IsPresent$ Card.IsCommander+YouOwn+YouCtrl | TriggerZones$ Battlefield | Execute$ PreventEffect | TriggerDescription$ Lieutenant — At the beginning of combat on your turn, if you control your commander, prevent all combat damage that would be dealt to creatures you control this turn. -SVar:PreventEffect:DB$ Effect | ReplacementEffects$ RPrevent | ValidTgts$ You | Description$ Prevent all combat damage that would be dealt to creatures you control this turn. +SVar:PreventEffect:DB$ Effect | ReplacementEffects$ RPrevent | ValidTgts$ You | SubAbility$ DBPumpAll SVar:RPrevent:Event$ DamageDone | Prevent$ True | IsCombat$ True | ActiveZones$ Command | ValidTarget$ Creature.YouCtrl | Description$ Prevent all combat damage that would be dealt to creatures you control this turn. -S:Mode$ Continuous | Affected$ Creature.Other+YouCtrl | AddKeyword$ Vigilance | Description$ Other creatures you control gain vigilance until end of turn. +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.StrictlyOther+YouCtrl | KW$ Vigilance SVar:BuffedBy:Card.IsCommander AI:RemoveDeck:Random Oracle:Vigilance\nLieutenant — At the beginning of combat on your turn, if you control your commander, prevent all combat damage that would be dealt to creatures you control this turn. Other creatures you control gain vigilance until end of turn. diff --git a/forge-gui/res/cardsfolder/z/ziatora_the_incinerator.txt b/forge-gui/res/cardsfolder/z/ziatora_the_incinerator.txt index 316e7391566..e82b396369a 100644 --- a/forge-gui/res/cardsfolder/z/ziatora_the_incinerator.txt +++ b/forge-gui/res/cardsfolder/z/ziatora_the_incinerator.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Demon Dragon PT:6/6 K:Flying T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ DBTrigger | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your end step, you may sacrifice another creature. When you do, CARDNAME deals damage equal to that creature's power to any target and you create three Treasure tokens. -SVar:DBTrigger:AB$ ImmediateTrigger | Cost$ Sac<1/Creature.Other/another creature> | Execute$ DBDealDmg | AILogic$ SacForDamage | RememberObjects$ Sacrificed | TriggerDescription$ When you do, CARDNAME deals damage equal to that creature's power to any target and you create three Treasure tokens. +SVar:DBTrigger:AB$ ImmediateTrigger | Cost$ Sac<1/Creature.StrictlyOther/another creature> | Execute$ DBDealDmg | AILogic$ SacForDamage | RememberObjects$ Sacrificed | TriggerDescription$ When you do, CARDNAME deals damage equal to that creature's power to any target and you create three Treasure tokens. SVar:DBDealDmg:DB$ DealDamage | ValidTgts$ Any | TgtPrompt$ Select any target to deal the damage to | NumDmg$ XPower | SubAbility$ DBToken SVar:DBToken:DB$ Token | TokenAmount$ 3 | TokenScript$ c_a_treasure_sac SVar:XPower:TriggerRemembered$CardPower diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index c2f5b5cd4d8..60507599129 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -109,7 +109,7 @@ public class HumanPlay { final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa); if (!req.playAbility(true, false, false)) { - Card rollback = p.getGame().getCardState(sa.getHostCard()); + Card rollback = p.getGame().getCardState(source); if (castFaceDown) { rollback.setFaceDown(false); } else if (flippedToCast) { From 0303a0e6fdc1b293f2312f0f63cc72098453f439 Mon Sep 17 00:00:00 2001 From: TRT <> Date: Mon, 8 May 2023 10:00:19 +0200 Subject: [PATCH 2/4] Better fix for Mutagen Connoisseur --- .../src/main/java/forge/game/ability/effects/PlayEffect.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 a5ac4422a57..7ec1c6447a0 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 @@ -296,7 +296,6 @@ public class PlayEffect extends SpellAbilityEffect { continue; } state = CardStateName.Transformed; - tgtCard.incrementTransformedTimestamp(); } // TODO if cost isn't replaced should include alternative ones @@ -420,6 +419,10 @@ public class PlayEffect extends SpellAbilityEffect { tgtSA.setAlternativeCost(AlternativeCost.Madness); } + if (sa.hasParam("CastTransformed")) { + tgtSA.putParam("CastTransformed", "True"); + } + if (tgtSA.usesTargeting() && !optional) { tgtSA.getTargetRestrictions().setMandatory(true); } From 936833321bae137355723db7b1c7f8199d144bca Mon Sep 17 00:00:00 2001 From: TRT <> Date: Mon, 8 May 2023 10:18:10 +0200 Subject: [PATCH 3/4] Clean up --- forge-game/src/main/java/forge/game/card/CardView.java | 2 +- forge-game/src/main/java/forge/game/player/Player.java | 4 ++-- forge-gui-mobile/src/forge/card/CardImageRenderer.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 7c41d0fa702..0b6c6f0a3f6 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -1452,7 +1452,7 @@ public class CardView extends GameEntityView { public boolean hasLandwalk() { return get(TrackableProperty.HasLandwalk); } - public boolean hasHasAftermath() { + public boolean hasAftermath() { return get(TrackableProperty.HasAftermath); } 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 7ac585ef49e..4720c7b4072 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -3183,7 +3183,7 @@ public class Player extends GameEntity implements Comparable { { final String drawTrig = "Mode$ Phase | Phase$ End of Turn | TriggerZones$ Command | " + "ValidPlayer$ You | TriggerDescription$ At the beginning of your end step, draw a card."; - final String drawEff = "AB$ Draw | Cost$ 0 | Defined$ You"; + final String drawEff = "DB$ Draw | Defined$ You"; final Trigger drawTrigger = TriggerHandler.parseTrigger(drawTrig, monarchEffect, true); @@ -3194,7 +3194,7 @@ public class Player extends GameEntity implements Comparable { { final String damageTrig = "Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ You | CombatDamage$ True | TriggerZones$ Command |" + " TriggerDescription$ Whenever a creature deals combat damage to you, its controller becomes the monarch."; - final String damageEff = "AB$ BecomeMonarch | Cost$ 0 | Defined$ TriggeredSourceController"; + final String damageEff = "DB$ BecomeMonarch | Defined$ TriggeredSourceController"; final Trigger damageTrigger = TriggerHandler.parseTrigger(damageTrig, monarchEffect, true); diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index 72a89af6a9e..9593ecd50ae 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -416,7 +416,7 @@ public class CardImageRenderer { if (alt == null) alt = card.getAlternateState().getCard(); CardView cv = altState && isFaceDown ? alt : card; - boolean isAftermath = altState ? cv.getAlternateState().hasHasAftermath() : cv.getRightSplitState().hasHasAftermath(); + boolean isAftermath = altState ? cv.getAlternateState().hasAftermath() : cv.getRightSplitState().hasAftermath(); if (!isAftermath) { CardEdition ed = FModel.getMagicDb().getEditions().get(cv.getCurrentState().getSetCode()); boolean isOldFrame = ed != null && !ed.isModern(); From 6c3ba986678215b0549955c6bc17af4e89ac145f Mon Sep 17 00:00:00 2001 From: TRT <> Date: Mon, 8 May 2023 11:16:12 +0200 Subject: [PATCH 4/4] Fix casting disturbed from other zones --- .../java/forge/game/spellability/SpellAbilityRestriction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java index 6c23fad580a..0a99921ce57 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java @@ -369,7 +369,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { } // Explicit Aftermath check there - if (sa.isAftermath() && !c.isInZone(ZoneType.Graveyard)) { + if ((sa.isAftermath() || sa.isDisturb()) && !c.isInZone(ZoneType.Graveyard)) { return false; }