From 76c485286fe62f40e2f08a98981299580b1b109d Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Mon, 21 Nov 2022 20:51:21 +0100 Subject: [PATCH 01/24] update --- .../cardsfolder/upcoming/distinguished_conjurer.txt | 11 +++++++++++ .../cardsfolder/upcoming/lita_mechanical_engineer.txt | 11 +++++++++++ forge-gui/res/cardsfolder/upcoming/pirated_copy.txt | 9 +++++++++ .../res/cardsfolder/upcoming/preston_the_vanisher.txt | 10 ++++++++++ forge-gui/res/tokenscripts/zeppelin.txt | 7 +++++++ 5 files changed, 48 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/pirated_copy.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt create mode 100644 forge-gui/res/tokenscripts/zeppelin.txt diff --git a/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt b/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt new file mode 100644 index 00000000000..b1a60821ad1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt @@ -0,0 +1,11 @@ +Name:Distinguished Conjurer +ManaCost:1 W +Types:Creature Human Wizard +PT:1/2 +T:Mode$ ChangesZone | ValidCard$ Creature.Other+YouCtrl | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever another creature enters the battlefield under your control, you gain 1 life. +SVar:TrigGainLife:DB$ GainLife | LifeAmount$ 1 +A:AB$ ChangeZone | Cost$ 4 W T | ValidTgts$ Creature.Other+YouCtrl | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select another target creature you control | RememberTargets$ True | SubAbility$ DBReturn | SpellDescription$ Exile another target creature you control, then return it to the battlefield under its owner's control. +SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ All | Destination$ Battlefield | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$LifeGain +Oracle:Whenever another creature enters the battlefield under your control, you gain 1 life.\n{4}{W}{T}:Exile another target creature you control, then return it to the battlefield under its owner's control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt b/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt new file mode 100644 index 00000000000..344b3b1b272 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt @@ -0,0 +1,11 @@ +Name:Lita, Mechanical Engineer +ManaCost:2 W +Types:Legendary Artifact Creature Artificer +PT:3/3 +K:Vigilance +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ At the beginning of your end step, untap all artifact creatures you control. +SVar:TrigUntap:DB$ UntapAll | ValidCards$ Artifact.Creature+YouCtrl +A:AB$ Token | Cost$ 3 W T | TokenScript$ zeppelin | SpellDescription$ Create a 5/5 colorless Vehicle artifact token named Zeppelin with flying and crew:3. +DeckHas:Type$Vehicle & Ability$Token & Keyword$Flying +DeckHints:Type$Artifact +Oracle:Vigilance\nAt the beginning of your end step, untap all artifact creatures you control.\n{3}{W}{T}: Create a 5/5 colorless Vehicle artifact token named Zeppelin with flying and crew:3. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt b/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt new file mode 100644 index 00000000000..3a7e293c7c5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt @@ -0,0 +1,9 @@ +Name:Pirated Copy +ManaCost:4 U +Types:Creature Shapeshifter Pirate +PT:0/0 +K:ETBReplacement:Copy:DBCopy:Optional +SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | AddTypes$ Pirate | AddTriggers$ DrawTrig | AddSVars$ DrawTrig,TrigDraw | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except it's a Pirate in addition to its other types and it has "Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card." +SVar:DrawTrig:Mode$ DamageDone | ValidSource$ Card.Self,Creature.sameName | TriggerZones$ Battlefield | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card. +SVar:TrigDraw:DB$ Draw +Oracle:You may have Pirated Copy enter the battlefield as a copy of any creature on the battlefield, except it's a Pirate in addition to its other types and it has "Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card." \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt b/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt new file mode 100644 index 00000000000..bfe4975ebf2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt @@ -0,0 +1,10 @@ +Name:Preston, the Vanisher +ManaCost:3 W +Types:Legendary Creature Rabbit Wizard +PT:2/5 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+wasNotCast+YouCtrl | TriggerZones$ Battlefield | PresentZone$ Battlefield | Execute$ TrigCopyPermanent | TriggerDescription$ Whenever another nontoken creature enters the battlefield under your control, if it wasn't cast, create a token that's a copy of that Creature except it's a 0/1 white illusion. +SVar:TrigCopyPermanent:DB$ CopyPermanent | Defined$ TriggeredCard | NumCopies$ 1 | SetColor$ White | SetCreatureTypes$ Illusion | SetPower$ 0 | SetToughness$ 1 +A:AB$ ChangeZone | Cost$ 1 W Sac<5/Creature.Illusion/illusions> | ValidTgts$ Permanent.nonLand | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select target nonland permanent | SpellDescription$ Exile target nonland permanent. +DeckHas:Ability$Token|Sacrifice & Type$Illusion +DeckHints:Type$Illusion & Ability$Graveyard +Oracle:Whenever another nontoken creature enters the battlefield under your control, if it wasn't cast, create a token that's a copy of that Creature except it's a 0/1 white illusion.\n{1}{W},Sacrifice five Illusions:Exile target nonland permanent. \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/zeppelin.txt b/forge-gui/res/tokenscripts/zeppelin.txt new file mode 100644 index 00000000000..4342dce42b9 --- /dev/null +++ b/forge-gui/res/tokenscripts/zeppelin.txt @@ -0,0 +1,7 @@ +Name:Zeppelin +ManaCost:no cost +Types:Artifact Creature +PT:5/5 +K:Flying +K:Crew:2 +Oracle:Flying\nCrew:2 \ No newline at end of file From dfb5ed2b2410bdf13783fb7cd061d8d7273c38f4 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Mon, 21 Nov 2022 21:59:00 +0100 Subject: [PATCH 02/24] update --- .../res/cardsfolder/upcoming/distinguished_conjurer.txt | 3 ++- .../res/cardsfolder/upcoming/lita_mechanical_engineer.txt | 4 ++-- forge-gui/res/cardsfolder/upcoming/pirated_copy.txt | 2 +- forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt | 6 +++--- forge-gui/res/tokenscripts/zeppelin.txt | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt b/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt index b1a60821ad1..4414d080d98 100644 --- a/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt +++ b/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt @@ -8,4 +8,5 @@ A:AB$ ChangeZone | Cost$ 4 W T | ValidTgts$ Creature.Other+YouCtrl | Origin$ Bat SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ All | Destination$ Battlefield | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHas:Ability$LifeGain -Oracle:Whenever another creature enters the battlefield under your control, you gain 1 life.\n{4}{W}{T}:Exile another target creature you control, then return it to the battlefield under its owner's control. \ No newline at end of file +SVar:BuffedBy:Creature +Oracle:Whenever another creature enters the battlefield under your control, you gain 1 life.\n{4}{W}, {T}: Exile another target creature you control, then return it to the battlefield under its owner's control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt b/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt index 344b3b1b272..119038c8f32 100644 --- a/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt +++ b/forge-gui/res/cardsfolder/upcoming/lita_mechanical_engineer.txt @@ -5,7 +5,7 @@ PT:3/3 K:Vigilance T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ At the beginning of your end step, untap all artifact creatures you control. SVar:TrigUntap:DB$ UntapAll | ValidCards$ Artifact.Creature+YouCtrl -A:AB$ Token | Cost$ 3 W T | TokenScript$ zeppelin | SpellDescription$ Create a 5/5 colorless Vehicle artifact token named Zeppelin with flying and crew:3. +A:AB$ Token | Cost$ 3 W T | TokenScript$ zeppelin | SpellDescription$ Create a 5/5 colorless Vehicle artifact token named Zeppelin with flying and crew 3. DeckHas:Type$Vehicle & Ability$Token & Keyword$Flying DeckHints:Type$Artifact -Oracle:Vigilance\nAt the beginning of your end step, untap all artifact creatures you control.\n{3}{W}{T}: Create a 5/5 colorless Vehicle artifact token named Zeppelin with flying and crew:3. \ No newline at end of file +Oracle:Vigilance\nAt the beginning of your end step, untap all artifact creatures you control.\n{3}{W}, {T}: Create a 5/5 colorless Vehicle artifact token named Zeppelin with flying and crew 3. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt b/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt index 3a7e293c7c5..09d0e149464 100644 --- a/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt +++ b/forge-gui/res/cardsfolder/upcoming/pirated_copy.txt @@ -3,7 +3,7 @@ ManaCost:4 U Types:Creature Shapeshifter Pirate PT:0/0 K:ETBReplacement:Copy:DBCopy:Optional -SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | AddTypes$ Pirate | AddTriggers$ DrawTrig | AddSVars$ DrawTrig,TrigDraw | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except it's a Pirate in addition to its other types and it has "Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card." +SVar:DBCopy:DB$ Clone | Choices$ Creature.Other | AddTypes$ Pirate | AddTriggers$ DrawTrig | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature on the battlefield, except it's a Pirate in addition to its other types and it has "Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card." SVar:DrawTrig:Mode$ DamageDone | ValidSource$ Card.Self,Creature.sameName | TriggerZones$ Battlefield | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card. SVar:TrigDraw:DB$ Draw Oracle:You may have Pirated Copy enter the battlefield as a copy of any creature on the battlefield, except it's a Pirate in addition to its other types and it has "Whenever this creature or another creature with the same name deals combat damage to a player, you draw a card." \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt b/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt index bfe4975ebf2..e5c79768152 100644 --- a/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt +++ b/forge-gui/res/cardsfolder/upcoming/preston_the_vanisher.txt @@ -2,9 +2,9 @@ Name:Preston, the Vanisher ManaCost:3 W Types:Legendary Creature Rabbit Wizard PT:2/5 -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+wasNotCast+YouCtrl | TriggerZones$ Battlefield | PresentZone$ Battlefield | Execute$ TrigCopyPermanent | TriggerDescription$ Whenever another nontoken creature enters the battlefield under your control, if it wasn't cast, create a token that's a copy of that Creature except it's a 0/1 white illusion. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken+wasNotCast+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigCopyPermanent | TriggerDescription$ Whenever another nontoken creature enters the battlefield under your control, if it wasn't cast, create a token that's a copy of that creature except it's a 0/1 white Illusion. SVar:TrigCopyPermanent:DB$ CopyPermanent | Defined$ TriggeredCard | NumCopies$ 1 | SetColor$ White | SetCreatureTypes$ Illusion | SetPower$ 0 | SetToughness$ 1 -A:AB$ ChangeZone | Cost$ 1 W Sac<5/Creature.Illusion/illusions> | ValidTgts$ Permanent.nonLand | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select target nonland permanent | SpellDescription$ Exile target nonland permanent. +A:AB$ ChangeZone | Cost$ 1 W Sac<5/Illusion> | ValidTgts$ Permanent.nonLand | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select target nonland permanent | SpellDescription$ Exile target nonland permanent. DeckHas:Ability$Token|Sacrifice & Type$Illusion DeckHints:Type$Illusion & Ability$Graveyard -Oracle:Whenever another nontoken creature enters the battlefield under your control, if it wasn't cast, create a token that's a copy of that Creature except it's a 0/1 white illusion.\n{1}{W},Sacrifice five Illusions:Exile target nonland permanent. \ No newline at end of file +Oracle:Whenever another nontoken creature enters the battlefield under your control, if it wasn't cast, create a token that's a copy of that creature except it's a 0/1 white Illusion.\n{1}{W}, Sacrifice five Illusions: Exile target nonland permanent. \ No newline at end of file diff --git a/forge-gui/res/tokenscripts/zeppelin.txt b/forge-gui/res/tokenscripts/zeppelin.txt index 4342dce42b9..7147687015c 100644 --- a/forge-gui/res/tokenscripts/zeppelin.txt +++ b/forge-gui/res/tokenscripts/zeppelin.txt @@ -3,5 +3,5 @@ ManaCost:no cost Types:Artifact Creature PT:5/5 K:Flying -K:Crew:2 -Oracle:Flying\nCrew:2 \ No newline at end of file +K:Crew:3 +Oracle:Flying\nCrew 3. \ No newline at end of file From 21e7a3be02ef6cc68bd9ace0b19a91998949731d Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Mon, 21 Nov 2022 22:02:41 +0100 Subject: [PATCH 03/24] Update distinguished_conjurer.txt --- forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt b/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt index 4414d080d98..2673d340f03 100644 --- a/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt +++ b/forge-gui/res/cardsfolder/upcoming/distinguished_conjurer.txt @@ -4,9 +4,9 @@ Types:Creature Human Wizard PT:1/2 T:Mode$ ChangesZone | ValidCard$ Creature.Other+YouCtrl | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever another creature enters the battlefield under your control, you gain 1 life. SVar:TrigGainLife:DB$ GainLife | LifeAmount$ 1 -A:AB$ ChangeZone | Cost$ 4 W T | ValidTgts$ Creature.Other+YouCtrl | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select another target creature you control | RememberTargets$ True | SubAbility$ DBReturn | SpellDescription$ Exile another target creature you control, then return it to the battlefield under its owner's control. +A:AB$ ChangeZone | Cost$ 4 W T | ValidTgts$ Creature.Other+YouCtrl | Origin$ Battlefield | Destination$ Exile | TgtPrompt$ Select another target creature you control | RememberChanged$ True | SubAbility$ DBReturn | SpellDescription$ Exile another target creature you control, then return it to the battlefield under its owner's control. SVar:DBReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ All | Destination$ Battlefield | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHas:Ability$LifeGain SVar:BuffedBy:Creature -Oracle:Whenever another creature enters the battlefield under your control, you gain 1 life.\n{4}{W}, {T}: Exile another target creature you control, then return it to the battlefield under its owner's control. \ No newline at end of file +Oracle:Whenever another creature enters the battlefield under your control, you gain 1 life.\n{4}{W}, {T}: Exile another target creature you control, then return it to the battlefield under its owner's control. From 2875988adc420e3cbf099197076d3fb0ceb9c18e Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 22 Nov 2022 14:38:55 +0800 Subject: [PATCH 04/24] update ClosingScreen & GameHud - fix ClosingScreen logo after update process - scaledown GameHud text for lifepoints, mana and gold --- forge-gui-mobile/src/forge/Forge.java | 1 + .../src/forge/adventure/stage/GameHUD.java | 10 +++++----- .../src/forge/screens/ClosingScreen.java | 20 ++++++++++++------- .../src/forge/screens/TransitionScreen.java | 6 +++--- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 8ada8dad3c4..eab6414574f 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -73,6 +73,7 @@ public class Forge implements ApplicationListener { public static KeyInputAdapter keyInputAdapter; private static boolean exited; public boolean needsUpdate = false; + public static boolean advStartup = false; public static boolean safeToClose = true; public static boolean magnify = false; public static boolean magnifyToggle = true; diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java index d6c930b7877..03b29869492 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java +++ b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java @@ -111,12 +111,12 @@ public class GameHUD extends Stage { lifePoints = ui.findActor("lifePoints"); mana = ui.findActor("mana"); money = ui.findActor("money"); - mana.setText("0/0"); - lifePoints.setText("20/20"); - AdventurePlayer.current().onLifeChange(() -> lifePoints.setText(AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife())); - AdventurePlayer.current().onManaChange(() -> mana.setText(AdventurePlayer.current().getMana() + "/" + AdventurePlayer.current().getMaxMana())); + mana.setText("{Scale=80%}0/0"); + lifePoints.setText("{Scale=80%}20/20"); + AdventurePlayer.current().onLifeChange(() -> lifePoints.setText("{Scale=80%}"+AdventurePlayer.current().getLife() + "/" + AdventurePlayer.current().getMaxLife())); + AdventurePlayer.current().onManaChange(() -> mana.setText("{Scale=80%}"+AdventurePlayer.current().getMana() + "/" + AdventurePlayer.current().getMaxMana())); - WorldSave.getCurrentSave().getPlayer().onGoldChange(() -> money.setText(String.valueOf(AdventurePlayer.current().getGold()))); + WorldSave.getCurrentSave().getPlayer().onGoldChange(() -> money.setText("{Scale=80%}"+String.valueOf(AdventurePlayer.current().getGold()))); addActor(ui); addActor(miniMapPlayer); console = new Console(); diff --git a/forge-gui-mobile/src/forge/screens/ClosingScreen.java b/forge-gui-mobile/src/forge/screens/ClosingScreen.java index 229adc5463b..8f70d2a3350 100644 --- a/forge-gui-mobile/src/forge/screens/ClosingScreen.java +++ b/forge-gui-mobile/src/forge/screens/ClosingScreen.java @@ -1,6 +1,8 @@ package forge.screens; +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; import forge.Forge; import forge.Graphics; import forge.animation.ForgeAnimation; @@ -16,6 +18,9 @@ public class ClosingScreen extends FContainer { private StaticAnimation staticAnimation; private boolean restart = false; private boolean drawStatic = false; + private FileHandle adv_logo = getSkinFile("adv_logo.png"); + private FileHandle existingLogo = adv_logo.exists() ? adv_logo : getDefaultSkinFile("adv_logo.png"); + private Texture logo = existingLogo.exists() && Forge.advStartup ? new Texture(existingLogo) : FSkin.getLogo(); public ClosingScreen(boolean restart0) { bgAnimation = new BGAnimation(); @@ -48,13 +53,14 @@ public class ClosingScreen extends FContainer { } g.fillRect(Color.BLACK, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); g.setAlphaComposite(1-percentage); - g.drawImage(Forge.isMobileAdventureMode ? FSkinTexture.ADV_BG_TEXTURE : FSkinTexture.BG_TEXTURE, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); + g.drawImage(Forge.isMobileAdventureMode || Forge.advStartup ? FSkinTexture.ADV_BG_TEXTURE : FSkinTexture.BG_TEXTURE, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); g.setAlphaComposite(oldAlpha); float xmod = Forge.getScreenHeight() > 2000 ? 1.5f : 1f; - if (FSkin.getLogo() != null) { - g.drawImage(FSkin.getLogo(), Forge.getScreenWidth()/2 - (FSkin.getLogo().getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (FSkin.getLogo().getHeight()*xmod)/2, FSkin.getLogo().getWidth()*xmod, FSkin.getLogo().getHeight()*xmod); + + if (logo != null) { + g.drawImage(logo, Forge.getScreenWidth()/2 - (logo.getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (logo.getHeight()*xmod)/2, logo.getWidth()*xmod, logo.getHeight()*xmod); } else { - g.drawImage(FSkinImage.LOGO,Forge.getScreenWidth()/2 - (FSkinImage.LOGO.getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (FSkinImage.LOGO.getHeight()*xmod)/1.5f, FSkinImage.LOGO.getWidth()*xmod, FSkinImage.LOGO.getHeight()*xmod); + g.drawImage(FSkinImage.LOGO, Forge.getScreenWidth()/2 - (FSkinImage.LOGO.getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (FSkinImage.LOGO.getHeight()*xmod)/1.5f, FSkinImage.LOGO.getWidth()*xmod, FSkinImage.LOGO.getHeight()*xmod); } } @@ -87,12 +93,12 @@ public class ClosingScreen extends FContainer { } g.fillRect(Color.BLACK, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); g.setAlphaComposite(percentage); - g.drawImage(Forge.isMobileAdventureMode ? FSkinTexture.ADV_BG_TEXTURE : FSkinTexture.BG_TEXTURE, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); + g.drawImage(Forge.isMobileAdventureMode || Forge.advStartup ? FSkinTexture.ADV_BG_TEXTURE : FSkinTexture.BG_TEXTURE, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); g.setAlphaComposite(oldAlpha); float xmod = Forge.getScreenHeight() > 2000 ? 1.5f : 1f; xmod *= 21-(20*percentage); - if (FSkin.getLogo() != null) { - g.drawImage(FSkin.getLogo(), Forge.getScreenWidth()/2 - (FSkin.getLogo().getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (FSkin.getLogo().getHeight()*xmod)/2, FSkin.getLogo().getWidth()*xmod, FSkin.getLogo().getHeight()*xmod); + if (logo != null) { + g.drawImage(logo, Forge.getScreenWidth()/2 - (logo.getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (logo.getHeight()*xmod)/2, logo.getWidth()*xmod, logo.getHeight()*xmod); } else { g.drawImage(FSkinImage.LOGO,Forge.getScreenWidth()/2 - (FSkinImage.LOGO.getWidth()*xmod)/2, Forge.getScreenHeight()/2 - (FSkinImage.LOGO.getHeight()*xmod)/1.5f, FSkinImage.LOGO.getWidth()*xmod, FSkinImage.LOGO.getHeight()*xmod); } diff --git a/forge-gui-mobile/src/forge/screens/TransitionScreen.java b/forge-gui-mobile/src/forge/screens/TransitionScreen.java index e8f7af7bed5..72ac3eeaed8 100644 --- a/forge-gui-mobile/src/forge/screens/TransitionScreen.java +++ b/forge-gui-mobile/src/forge/screens/TransitionScreen.java @@ -19,7 +19,7 @@ public class TransitionScreen extends FContainer { Runnable runnable; TextureRegion textureRegion; private String message = ""; - boolean matchTransition, isloading, isIntro, isFadeMusic, advStartup; + boolean matchTransition, isloading, isIntro, isFadeMusic; public TransitionScreen(Runnable proc, TextureRegion screen, boolean enterMatch, boolean loading) { this(proc, screen, enterMatch, loading, false, false); @@ -43,7 +43,7 @@ public class TransitionScreen extends FContainer { isIntro = intro; isFadeMusic = fadeMusic; message = loadingMessage; - advStartup = Forge.selector.equals("Adventure"); + Forge.advStartup = Forge.selector.equals("Adventure"); } public FProgressBar getProgressBar() { @@ -111,7 +111,7 @@ public class TransitionScreen extends FContainer { g.drawWarpImage(textureRegion, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight(), percentage); } else if (isIntro) { if (textureRegion != null) { - if (advStartup) { + if (Forge.advStartup) { g.drawGrayTransitionImage(Forge.getAssets().fallback_skins().get(0), 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight(), false, percentage); g.setAlphaComposite(1-percentage); g.drawImage(textureRegion, 0, 0, Forge.getScreenWidth(), Forge.getScreenHeight()); From d9a0770640abdebb2607b074594d008907c42026 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 22 Nov 2022 14:56:18 +0800 Subject: [PATCH 05/24] update imports --- forge-gui-mobile/src/forge/screens/ClosingScreen.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-gui-mobile/src/forge/screens/ClosingScreen.java b/forge-gui-mobile/src/forge/screens/ClosingScreen.java index 8f70d2a3350..f99f301a4ad 100644 --- a/forge-gui-mobile/src/forge/screens/ClosingScreen.java +++ b/forge-gui-mobile/src/forge/screens/ClosingScreen.java @@ -1,5 +1,6 @@ package forge.screens; - +import static forge.assets.FSkin.getDefaultSkinFile; +import static forge.assets.FSkin.getSkinFile; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; From 46effccfece918bcfcf14b14c58ad7f5f5162557 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 22 Nov 2022 16:24:30 +0800 Subject: [PATCH 06/24] update AdventureDeckEditor Catalog icon --- .../adventure/scene/AdventureDeckEditor.java | 8 ++++---- forge-gui/res/adventure/Shandalar/ui/binder.png | Bin 0 -> 24762 bytes 2 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 forge-gui/res/adventure/Shandalar/ui/binder.png diff --git a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java index 7cbd4e75445..3e7b671ddc7 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java +++ b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java @@ -42,9 +42,9 @@ import java.util.Map; public static FSkinImage MAIN_DECK_ICON = Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST; public static FSkinImage SIDEBOARD_ICON = Forge.hdbuttons ? FSkinImage.HDSIDEBOARD : FSkinImage.FLASHBACK; private static final float HEADER_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f); - private static final FileHandle tomeIcon = Config.instance().getFile("ui/tome.png"); - private static Texture tomeIconTexture = tomeIcon.exists() ? new Texture(tomeIcon) : null; - private static FImage CATALOG_ICON = tomeIcon.exists() ? new FImage() { + private static final FileHandle binderIcon = Config.instance().getFile("ui/binder.png"); + private static Texture binderTexture = binderIcon.exists() ? new Texture(binderIcon) : null; + private static FImage CATALOG_ICON = binderIcon.exists() ? new FImage() { @Override public float getWidth() { return 100f; @@ -55,7 +55,7 @@ import java.util.Map; } @Override public void draw(Graphics g, float x, float y, float w, float h) { - g.drawImage(tomeIconTexture, x, y, w, h); + g.drawImage(binderTexture, x, y, w, h); } } : FSkinImage.QUEST_BOX; private static final FileHandle sellIcon = Config.instance().getFile("ui/sell.png"); diff --git a/forge-gui/res/adventure/Shandalar/ui/binder.png b/forge-gui/res/adventure/Shandalar/ui/binder.png new file mode 100644 index 0000000000000000000000000000000000000000..2a0c82c918847dba35ed4352c6fa2973a89d222b GIT binary patch literal 24762 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 Date: Tue, 22 Nov 2022 10:59:41 +0100 Subject: [PATCH 07/24] update --- .../java/forge/game/card/CounterEnumType.java | 2 ++ .../res/cardsfolder/upcoming/infernal_idol.txt | 8 ++++++++ .../res/cardsfolder/upcoming/ingenious_leonin.txt | 8 ++++++++ .../upcoming/magnanimous_magistrate.txt | 10 ++++++++++ .../upcoming/mild_mannered_librarian.txt | 9 +++++++++ .../res/cardsfolder/upcoming/primeval_herald.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/read_the_soul.txt | 7 +++++++ .../upcoming/runadi_behemoth_caller.txt | 15 +++++++++++++++ .../res/cardsfolder/upcoming/towering_gibbon.txt | 8 ++++++++ 9 files changed, 77 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/infernal_idol.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/primeval_herald.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/read_the_soul.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/towering_gibbon.txt diff --git a/forge-game/src/main/java/forge/game/card/CounterEnumType.java b/forge-game/src/main/java/forge/game/card/CounterEnumType.java index 16d43b010c5..6ab13e1b55f 100644 --- a/forge-game/src/main/java/forge/game/card/CounterEnumType.java +++ b/forge-game/src/main/java/forge/game/card/CounterEnumType.java @@ -294,6 +294,8 @@ public enum CounterEnumType { P2P2("+2/+2", "+2/+2", 96, 226, 23), QUEST("QUEST", 251, 189, 0), + + REPRIEVE("REPR", 240, 120, 50), RITUAL("RITUAL", 155, 17, 30), diff --git a/forge-gui/res/cardsfolder/upcoming/infernal_idol.txt b/forge-gui/res/cardsfolder/upcoming/infernal_idol.txt new file mode 100644 index 00000000000..d9ffb56ba15 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/infernal_idol.txt @@ -0,0 +1,8 @@ +Name:Infernal Idol +ManaCost:3 +Types:Artifact +A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}. +A:AB$ Draw | Cost$ 1 B B T Sac<1/CARDNAME> | NumCards$ 2 | SubAbility$ DBLoseLife | SpellDescription$ You draw two cards and you lose two life. +SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 2 +DeckNeeds:Color$Black +Oracle:{T}: Add {B}.\n{1}{B}{B}, {T}, Sacrifice Infernal Idol: You draw two cards and you lose two life. diff --git a/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt b/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt new file mode 100644 index 00000000000..1be8363b881 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt @@ -0,0 +1,8 @@ +Name:Ingenious Leonin +ManaCost:4 W +Types:Creature Cat Soldier +PT:4/4 +A:AB$ PutCounter | Cost$ 3 W | ValidTgts$ Creature.attacking+Other+YouCtrl | TgtPrompt$ Select another target attacking creature you control | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on another target attacking creature you control. If that creature is a Cat, it gains first strike until end of turn. +SVar:DBPump:DB$ Pump | Defined$ Targeted | ConditionDefined$ Targeted | ConditionPresent$ Cat | KW$ First Strike +DeckHints:Type$Cat +Oracle:{3}{W}: Put a +1/+1 counter on another target attacking creature you control. If that creature is a Cat, it gains first strike until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt b/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt new file mode 100644 index 00000000000..01ac7c7545a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt @@ -0,0 +1,10 @@ +Name:Magnanimous Magistrate +ManaCost:5 W +Types:Creature Human Advisor +PT:3/4 +K:etbCounter:REPR:5:no condition:CARDNAME enters the battlefield with 5 reprieve counters on it. +T:Mode$ ChangesZone | ValidCard$ Creature.Other+nonToken+cmcGE1 | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Whenever another nontoken creature you control dies, if its mana value was 1 or greater, you may remove that many reprieve counters from CARDNAME. If you do, return that card to the battlefield under its owner's control. +SVar:TrigChangeZone:AB$ ChangeZone | Cost$ SubCounter | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield +SVar:X:TriggeredCard$CardManaCost +DeckHas:Ability$Counters +Oracle:Magnanimous Magistrate enters the battlefield with five reprieve counters on it.\nWhenever another nontoken creature you control dies, if its mana value was 1 or greater, you may remove that many reprieve counters from Magnanimous Magistrate. If you do, return that card to the battlefield under its owner's control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt b/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt new file mode 100644 index 00000000000..3a02ec1d4df --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt @@ -0,0 +1,9 @@ +Name:Mild-Mannered Librarian +ManaCost:G +Types:Creature Human +PT:1/1 +A:AB$ Animate | Cost$ 3 G | GameActivationLimit$ 1 | Types$ Werewolf | Duration$ Permanent | SubAbility$ DBCounter | SpellDescription$ CARDNAME becomes a werewolf. Put two +1/+1 counters on it and you draw a card. Activate only once. +SVar:DBCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw +DeckHas:Ability$Counters & Type$Werewolf +Oracle:{3}{G}: Mild-Mannered Librarian becomes a werewolf. Put two +1/+1 counters on it and you draw a card. Activate only once. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/primeval_herald.txt b/forge-gui/res/cardsfolder/upcoming/primeval_herald.txt new file mode 100644 index 00000000000..4826de131d1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/primeval_herald.txt @@ -0,0 +1,10 @@ +Name:Primeval Herald +ManaCost:3 G +Types:Creature Elf Scout +PT:3/1 +K:Trample +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle. +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | OptionalDecider$ You | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle. +SVar:TrigChange:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.Basic | ChangeNum$ 1 | ShuffleNonMandatory$ True +SVar:HasAttackEffect:TRUE +Oracle:Trample\nWhenever Primeval Herald enters the battlefield or attacks, you may search your library for a basic land card, put it onto the battlefield tapped, then shuffle. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt b/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt new file mode 100644 index 00000000000..4edb0b6eba9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt @@ -0,0 +1,7 @@ +Name:Read the Soul +ManaCost:3 U +Types:Instant +A:SP$ Charm | Choices$ Counter,Draw | CharmNum$ 1 +SVar:Counter:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 4 | SpellDescription$ Counter target spell unless its controller pays {4}. +SVar:Draw:DB$ Draw | NumCards$ 2 +Oracle:Choose one —\n• Counter target spell unless its controller pays {4}.\n• Draw two cards. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt b/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt new file mode 100644 index 00000000000..b3e9bca0de0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt @@ -0,0 +1,15 @@ +Name:Runadi, Behemoth Caller +ManaCost:2 G +Types:Legendary Creature Cat Shaman +PT:1/3 +T:Mode$ SpellCast | ValidCard$ Creature.cmcGE5 | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever you cast a creature spell with mana value 5 or greater, that creature enters the battlefield with X additional +1/+1 counters on it, where X is its mana value minus 4. +SVar:TrigEffect:DB$ Effect | RememberObjects$ TriggeredCard | ReplacementEffects$ ETBCreat | ExileOnMoved$ Stack +SVar:ETBCreat:Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Battlefield | ReplaceWith$ DBPutP1P1 | ReplacementResult$ Updated +SVar:DBPutP1P1:DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ True | CounterNum$ X | SubAbility$ DBExile +SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile +S:Mode$ Continuous | Affected$ Creature.YouCtrl+counters_GE3_P1P1 | AddKeyword$ Haste | Description$ Creature you control with three or more +1/+1 counters on them have haste. +A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. +SVar:X:TriggeredCard$CardManaCost/Minus.4 +DeckHas:Ability$Counters +DeckHints:Type$Tyranid|Hydra +Oracle:Whenever you cast a creature spell with mana value 5 or greater, that creature enters the battlefield with X additional +1/+1 counters on it, where X is its mana value minus 4.\nCreature you control with three or more +1/+1 counters on them have haste.\n{T}: Add {G}. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/towering_gibbon.txt b/forge-gui/res/cardsfolder/upcoming/towering_gibbon.txt new file mode 100644 index 00000000000..aabaefc4a8d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/towering_gibbon.txt @@ -0,0 +1,8 @@ +Name:Towering Gibbon +ManaCost:3 G +Types:Creature Ape +PT:*/4 +K:Reach +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | Description$ CARDNAME's power is equal to the highest mana value among creatures you control. +SVar:X:Count$Valid Creature.YouCtrl$GreatestCMC +Oracle:Reach\nTowering Gibbon's power is equal to the greatest mana value among creatures you control. \ No newline at end of file From beb0f1bef5e6b8ede9c7719af625e80f980a0803 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Tue, 22 Nov 2022 11:01:47 +0100 Subject: [PATCH 08/24] Update read_the_soul.txt --- forge-gui/res/cardsfolder/upcoming/read_the_soul.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt b/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt index 4edb0b6eba9..dc774497a8b 100644 --- a/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt +++ b/forge-gui/res/cardsfolder/upcoming/read_the_soul.txt @@ -3,5 +3,5 @@ ManaCost:3 U Types:Instant A:SP$ Charm | Choices$ Counter,Draw | CharmNum$ 1 SVar:Counter:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 4 | SpellDescription$ Counter target spell unless its controller pays {4}. -SVar:Draw:DB$ Draw | NumCards$ 2 -Oracle:Choose one —\n• Counter target spell unless its controller pays {4}.\n• Draw two cards. \ No newline at end of file +SVar:Draw:DB$ Draw | NumCards$ 2 | SpellDescription$ Draw two cards. +Oracle:Choose one —\n• Counter target spell unless its controller pays {4}.\n• Draw two cards. From 7227feeb988f35d56f43417a1553104a04ee1008 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Tue, 22 Nov 2022 11:43:04 +0100 Subject: [PATCH 09/24] Update runadi_behemoth_caller.txt --- forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt b/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt index b3e9bca0de0..c574bf1e780 100644 --- a/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt +++ b/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt @@ -9,7 +9,7 @@ SVar:DBPutP1P1:DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile S:Mode$ Continuous | Affected$ Creature.YouCtrl+counters_GE3_P1P1 | AddKeyword$ Haste | Description$ Creature you control with three or more +1/+1 counters on them have haste. A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. -SVar:X:TriggeredCard$CardManaCost/Minus.4 +SVar:X:Remembered$CardManaCost/Minus.4 DeckHas:Ability$Counters DeckHints:Type$Tyranid|Hydra Oracle:Whenever you cast a creature spell with mana value 5 or greater, that creature enters the battlefield with X additional +1/+1 counters on it, where X is its mana value minus 4.\nCreature you control with three or more +1/+1 counters on them have haste.\n{T}: Add {G}. \ No newline at end of file From a10f8f4cb7b992799279084c1449b5f35970d32c Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Tue, 22 Nov 2022 12:26:29 +0100 Subject: [PATCH 10/24] Cleanup --- forge-game/src/main/java/forge/game/GameAction.java | 3 ++- .../java/forge/game/ability/effects/EffectEffect.java | 3 ++- forge-game/src/main/java/forge/game/card/Card.java | 2 +- .../src/main/java/forge/game/player/PlayerProperty.java | 2 +- .../game/staticability/StaticAbilityNumLoyaltyAct.java | 3 +-- forge-gui/res/cardsfolder/a/academy_loremaster.txt | 8 ++++---- forge-gui/res/cardsfolder/b/bartered_cow.txt | 4 ++-- forge-gui/res/cardsfolder/g/gate_to_the_aether.txt | 4 ++-- forge-gui/res/cardsfolder/o/obzedat_ghost_council.txt | 7 +++---- forge-gui/res/cardsfolder/w/wild_evocation.txt | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index f2e6b62f67f..1eb2845064a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -2430,7 +2430,7 @@ public class GameAction { } if (c.isPlaneswalker()) { int lethalPW = c.getCurrentLoyalty(); - // 120.10 + // CR 120.10 lethal = c.isCreature() ? Math.min(lethal, lethalPW) : lethalPW; } lethalDamage.put(c, lethal); @@ -2442,6 +2442,7 @@ public class GameAction { sourceLKI.getDamageHistory().registerDamage(e.getValue(), isCombat, sourceLKI, e.getKey(), lkiCache); } + // CR 702.15e if (sum > 0 && sourceLKI.hasKeyword(Keyword.LIFELINK)) { sourceLKI.getController().gainLife(sum, sourceLKI, cause); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java index 0665b7fbe55..b7607038afa 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java @@ -27,6 +27,7 @@ import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.CardTranslation; import forge.util.TextUtil; import forge.util.collect.FCollection; @@ -113,7 +114,7 @@ public class EffectEffect extends SpellAbilityEffect { String name = sa.getParam("Name"); if (name == null) { - name = hostCard.getName() + (sa.hasParam("Boon") ? "'s Boon" : "'s Effect"); + name = CardTranslation.getTranslatedName(hostCard.getName()) + (sa.hasParam("Boon") ? "'s Boon" : "'s Effect"); } // Unique Effects shouldn't be duplicated 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 1c3fdb8f152..1c23be603e8 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -5636,7 +5636,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { @Override public final int addDamageAfterPrevention(final int damageIn, final Card source, final boolean isCombat, GameEntityCounterTable counterTable) { if (damageIn <= 0) { - return 0; // Rule 119.8 + return 0; // 120.8 } // 120.1a Damage can’t be dealt to an object that’s neither a creature nor a planeswalker. diff --git a/forge-game/src/main/java/forge/game/player/PlayerProperty.java b/forge-game/src/main/java/forge/game/player/PlayerProperty.java index 3bcda5ac413..a93167461f2 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerProperty.java +++ b/forge-game/src/main/java/forge/game/player/PlayerProperty.java @@ -160,7 +160,7 @@ public class PlayerProperty { return false; } } else if (property.equals("Defending")) { - if (!game.getCombat().getAttackersAndDefenders().values().contains(player)) { + if (game.getCombat() == null || !game.getCombat().getAttackersAndDefenders().values().contains(player)) { return false; } } else if (property.equals("LostLifeThisTurn")) { diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java index 43bd2d29646..adca5c1e5c2 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityNumLoyaltyAct.java @@ -29,7 +29,6 @@ public class StaticAbilityNumLoyaltyAct { } public static boolean applyLimitIncrease(final StaticAbility stAb, final Card card) { - if (!stAb.matchesValidParam("ValidCard", card)) { return false; } @@ -58,7 +57,7 @@ public class StaticAbilityNumLoyaltyAct { } } int more = AbilityUtils.calculateAmount(card, stAb.getParam("Additional"), stAb); - addl = addl + more; + addl += more; } } } diff --git a/forge-gui/res/cardsfolder/a/academy_loremaster.txt b/forge-gui/res/cardsfolder/a/academy_loremaster.txt index 81b9e42eb11..18ba66a4651 100644 --- a/forge-gui/res/cardsfolder/a/academy_loremaster.txt +++ b/forge-gui/res/cardsfolder/a/academy_loremaster.txt @@ -2,9 +2,9 @@ Name:Academy Loremaster ManaCost:U U Types:Creature Human Wizard PT:2/3 -T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player | TriggerZones$ Battlefield | OptionalDecider$ TriggeredPlayer | Execute$ TrigDraw | TriggerDescription$ At the beginning of each player's draw step, that player may draw an additional card. If they do, spells they cast this turn cost {2} more to cast +T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player | TriggerZones$ Battlefield | OptionalDecider$ TriggeredPlayer | Execute$ TrigDraw | TriggerDescription$ At the beginning of each player's draw step, that player may draw an additional card. If they do, spells they cast this turn cost {2} more to cast. SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ TriggeredPlayer | RememberDrawn$ True | SubAbility$ DBEffect -SVar:DBEffect:DB$ Effect | ConditionDefined$ Remembered | ConditionPresent$ Card | Duration$ EndOfTurn | StaticAbilities$ RaiseCost | SubAbility$ DBCleanup | SpellDescription$ Spells they cast this turn cost {2} more to cast -SVar:RaiseCost:Mode$ RaiseCost | ValidCard$ Card.ActivePlayerCtrl | Type$ Spell | Amount$ 2 | Description$ Spells they cast this turn cost {2} more to cast +SVar:DBEffect:DB$ Effect | ConditionDefined$ Remembered | ConditionPresent$ Card | Duration$ EndOfTurn | StaticAbilities$ RaiseCost | SubAbility$ DBCleanup +SVar:RaiseCost:Mode$ RaiseCost | ValidCard$ Card.ActivePlayerCtrl | Type$ Spell | Amount$ 2 | Description$ Spells they cast this turn cost {2} more to cast. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -Oracle:At the beginning of each player's draw step, that player may draw an additional card. If they do, spells they cast this turn cost {2} more to cast +Oracle:At the beginning of each player's draw step, that player may draw an additional card. If they do, spells they cast this turn cost {2} more to cast. diff --git a/forge-gui/res/cardsfolder/b/bartered_cow.txt b/forge-gui/res/cardsfolder/b/bartered_cow.txt index 306ee01e996..c81014c01ad 100644 --- a/forge-gui/res/cardsfolder/b/bartered_cow.txt +++ b/forge-gui/res/cardsfolder/b/bartered_cow.txt @@ -2,8 +2,8 @@ Name:Bartered Cow ManaCost:3 W Types:Creature Ox PT:3/3 -T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | TriggerController$ TriggeredCardController | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies or blocks you discard it, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") -T:Mode$ Discarded | ValidCard$ Card.Self | Execute$ TrigToken | Secondary$ True | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies or blocks you discard it, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | TriggerController$ TriggeredCardController | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies or when you discard it, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") +T:Mode$ Discarded | ValidCard$ Card.Self | Execute$ TrigToken | Secondary$ True | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies or when you discard it, create a Food token. (It's an artifact with "{2}, {T}, Sacrifice this artifact: You gain 3 life.") SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_food_sac | TokenOwner$ You SVar:SacMe:1 SVar:DiscardMe:3 diff --git a/forge-gui/res/cardsfolder/g/gate_to_the_aether.txt b/forge-gui/res/cardsfolder/g/gate_to_the_aether.txt index 41e10748a6a..2ca8189afc6 100644 --- a/forge-gui/res/cardsfolder/g/gate_to_the_aether.txt +++ b/forge-gui/res/cardsfolder/g/gate_to_the_aether.txt @@ -1,7 +1,7 @@ Name:Gate to the Aether ManaCost:6 Types:Artifact -T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player | Execute$ TrigAetherDig | TriggerController$ TriggeredPlayer | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of each player's upkeep, that player reveals the top card of their library. If it's an artifact, creature, enchantment, or land card, the player may put it onto the battlefield. -SVar:TrigAetherDig:DB$ Dig | Defined$ TriggeredPlayer | DigNum$ 1 | Reveal$ True | DestinationZone$ Battlefield | DestinationZone2$ Library | LibraryPosition2$ 0 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Artifact,Creature,Enchantment,Land +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player | Execute$ TrigAetherDig | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of each player's upkeep, that player reveals the top card of their library. If it's an artifact, creature, enchantment, or land card, the player may put it onto the battlefield. +SVar:TrigAetherDig:DB$ Dig | Defined$ TriggeredPlayer | Choser$ TriggeredPlayer | DigNum$ 1 | Reveal$ True | DestinationZone$ Battlefield | DestinationZone2$ Library | LibraryPosition2$ 0 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Artifact,Creature,Enchantment,Land AI:RemoveDeck:Random Oracle:At the beginning of each player's upkeep, that player reveals the top card of their library. If it's an artifact, creature, enchantment, or land card, the player may put it onto the battlefield. diff --git a/forge-gui/res/cardsfolder/o/obzedat_ghost_council.txt b/forge-gui/res/cardsfolder/o/obzedat_ghost_council.txt index 8f1da8421b5..c1262308ae2 100644 --- a/forge-gui/res/cardsfolder/o/obzedat_ghost_council.txt +++ b/forge-gui/res/cardsfolder/o/obzedat_ghost_council.txt @@ -6,9 +6,8 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigDrain:DB$ LoseLife | ValidTgts$ Opponent | LifeAmount$ 2 | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigExile | OptionalDecider$ You | TriggerDescription$ At the beginning of your end step you may exile NICKNAME. If you do, return it to the battlefield under it's owner's control at the beginning of your next upkeep. It gains haste. -SVar:TrigExile:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBDelaytrig -SVar:DBDelaytrig:DB$ Effect | Name$ Obzedat Effect | Triggers$ TrigEOT | RememberObjects$ Self | Duration$ Permanent -SVar:TrigEOT:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ ObzedatReturn | OneOff$ True | TriggerDescription$ Return CARDNAME to the battlefield under it's owner's control. It gains haste. -SVar:ObzedatReturn:DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield | SubAbility$ ObzedatPump +SVar:TrigExile:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | SubAbility$ DelTrig +SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ ObzedatReturn | ConditionDefined$ Remembered | ConditionPresent$ Card | RememberObjects$ Remembered | TriggerDescription$ Return CARDNAME to the battlefield under its owner's control at the beginning of the next end step. +SVar:ObzedatReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Exile,Command | Destination$ Battlefield | SubAbility$ ObzedatPump SVar:ObzedatPump:DB$ Pump | Defined$ Remembered | KW$ Haste | Duration$ Permanent Oracle:When Obzedat, Ghost Council enters the battlefield, target opponent loses 2 life and you gain 2 life.\nAt the beginning of your end step, you may exile Obzedat. If you do, return it to the battlefield under its owner's control at the beginning of your next upkeep. It gains haste. diff --git a/forge-gui/res/cardsfolder/w/wild_evocation.txt b/forge-gui/res/cardsfolder/w/wild_evocation.txt index 1d00e3d27d6..d29161a75d3 100644 --- a/forge-gui/res/cardsfolder/w/wild_evocation.txt +++ b/forge-gui/res/cardsfolder/w/wild_evocation.txt @@ -4,7 +4,7 @@ Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player | Execute$ TrigEvoke | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of each player's upkeep, that player reveals a card at random from their hand. If it's a land card, the player puts it onto the battlefield. Otherwise, the player casts it without paying its mana cost if able. SVar:TrigEvoke:DB$ Reveal | Random$ True | RememberRevealed$ True | Defined$ TriggeredPlayer | SubAbility$ DBEvokeLand SVar:DBEvokeLand:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Defined$ ValidHand Land.IsRemembered | ForgetChanged$ True | SubAbility$ DBEvokePlay -SVar:DBEvokePlay:DB$ Play | ValidZone$ Hand | Controller$ TriggeredPlayer | Defined$ Remembered | WithoutManaCost$ True | SubAbility$ DBCleanup +SVar:DBEvokePlay:DB$ Play | ValidZone$ Hand | Controller$ TriggeredPlayer | Defined$ Remembered | ValidSA$ Spell | WithoutManaCost$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True AI:RemoveDeck:Random Oracle:At the beginning of each player's upkeep, that player reveals a card at random from their hand. If it's a land card, the player puts it onto the battlefield. Otherwise, the player casts it without paying its mana cost if able. From d45a962faa71e66e2c79c55cd714e1b6ea71fe34 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Tue, 22 Nov 2022 13:37:48 +0100 Subject: [PATCH 11/24] Cleanup SpellDescription from some Triggers that don't need it --- forge-gui/res/cardsfolder/a/awakening.txt | 2 +- forge-gui/res/cardsfolder/b/barbed_shocker.txt | 4 ++-- forge-gui/res/cardsfolder/b/benthicore.txt | 2 +- forge-gui/res/cardsfolder/b/borborygmos_enraged.txt | 2 +- forge-gui/res/cardsfolder/c/crafty_cutpurse.txt | 2 +- forge-gui/res/cardsfolder/d/dragonborn_champion.txt | 2 +- forge-gui/res/cardsfolder/e/euroakus.txt | 2 +- forge-gui/res/cardsfolder/g/genesis_chamber.txt | 2 +- forge-gui/res/cardsfolder/i/irregular_cohort.txt | 2 +- forge-gui/res/cardsfolder/j/jolrael_mwonvuli_recluse.txt | 2 +- forge-gui/res/cardsfolder/j/josu_vess_lich_knight.txt | 2 +- forge-gui/res/cardsfolder/m/militant_angel.txt | 2 +- forge-gui/res/cardsfolder/p/pure_reflection.txt | 2 +- forge-gui/res/cardsfolder/r/regna_the_redeemer.txt | 2 +- forge-gui/res/cardsfolder/t/thelonite_hermit.txt | 2 +- forge-gui/res/cardsfolder/w/watchful_giant.txt | 2 +- .../java/forge/gamemodes/match/input/InputSelectManyBase.java | 4 ++-- .../src/main/java/forge/player/PlayerControllerHuman.java | 4 ++-- 18 files changed, 21 insertions(+), 21 deletions(-) diff --git a/forge-gui/res/cardsfolder/a/awakening.txt b/forge-gui/res/cardsfolder/a/awakening.txt index f72b293b02a..6949b70094d 100644 --- a/forge-gui/res/cardsfolder/a/awakening.txt +++ b/forge-gui/res/cardsfolder/a/awakening.txt @@ -2,7 +2,7 @@ Name:Awakening ManaCost:2 G G Types:Enchantment T:Mode$ Phase | Phase$ Upkeep | TriggerZones$ Battlefield | Execute$ TrigUntapAll | TriggerDescription$ At the beginning of each upkeep, untap all creatures and lands. -SVar:TrigUntapAll:DB$ UntapAll | ValidCards$ Creature,Land | SpellDescription$ untap all creatures and lands. +SVar:TrigUntapAll:DB$ UntapAll | ValidCards$ Creature,Land SVar:UntapsEachTurn:Creature,Land AI:RemoveDeck:Random Oracle:At the beginning of each upkeep, untap all creatures and lands. diff --git a/forge-gui/res/cardsfolder/b/barbed_shocker.txt b/forge-gui/res/cardsfolder/b/barbed_shocker.txt index bc5adff1780..5e8fb13273b 100644 --- a/forge-gui/res/cardsfolder/b/barbed_shocker.txt +++ b/forge-gui/res/cardsfolder/b/barbed_shocker.txt @@ -5,8 +5,8 @@ PT:2/2 K:Trample K:Haste T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | TriggerZones$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ Whenever CARDNAME deals damage to a player, that player discards all the cards in their hand, then draws that many cards. -SVar:TrigDiscard:DB$ Discard | Defined$ TriggeredTarget | Mode$ Hand | RememberDiscarded$ True | SubAbility$ DBDraw | SpellDescription$ Discard hand -SVar:DBDraw:DB$ Draw | NumCards$ X | Defined$ TriggeredTarget | SubAbility$ DBCleanup | SpellDescription$ Draw that many cards +SVar:TrigDiscard:DB$ Discard | Defined$ TriggeredTarget | Mode$ Hand | RememberDiscarded$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ X | Defined$ TriggeredTarget | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Remembered$Amount Oracle:Trample, haste\nWhenever Barbed Shocker deals damage to a player, that player discards all the cards in their hand, then draws that many cards. diff --git a/forge-gui/res/cardsfolder/b/benthicore.txt b/forge-gui/res/cardsfolder/b/benthicore.txt index 1f1c8db3028..c2ed26357cc 100644 --- a/forge-gui/res/cardsfolder/b/benthicore.txt +++ b/forge-gui/res/cardsfolder/b/benthicore.txt @@ -3,7 +3,7 @@ ManaCost:6 U Types:Creature Elemental PT:5/5 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create two 1/1 blue Merfolk Wizard creature tokens. -SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ u_1_1_merfolk_wizard | TokenOwner$ You | SpellDescription$ Create two 1/1 blue Merfolk Wizard creature tokens. +SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ u_1_1_merfolk_wizard | TokenOwner$ You A:AB$ Untap | Cost$ tapXType<2/Merfolk> | SubAbility$ GainShroud | SpellDescription$ Untap CARDNAME. SVar:GainShroud:DB$ Pump | Defined$ Self | KW$ Shroud | SpellDescription$ CARDNAME gains shroud until end of turn. Oracle:When Benthicore enters the battlefield, create two 1/1 blue Merfolk Wizard creature tokens.\nTap two untapped Merfolk you control: Untap Benthicore. It gains shroud until end of turn. (It can't be the target of spells or abilities.) diff --git a/forge-gui/res/cardsfolder/b/borborygmos_enraged.txt b/forge-gui/res/cardsfolder/b/borborygmos_enraged.txt index 5e9275c28e5..cabfd133ee1 100644 --- a/forge-gui/res/cardsfolder/b/borborygmos_enraged.txt +++ b/forge-gui/res/cardsfolder/b/borborygmos_enraged.txt @@ -4,6 +4,6 @@ Types:Legendary Creature Cyclops PT:7/6 K:Trample T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDig | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, reveal the top three cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard. -SVar:TrigDig:DB$ Dig | DigNum$ 3 | Defined$ You | Reveal$ True | ChangeNum$ All | ChangeValid$ Land | DestinationZone2$ Graveyard | SpellDescription$ Reveal the top three cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard. +SVar:TrigDig:DB$ Dig | DigNum$ 3 | Defined$ You | Reveal$ True | ChangeNum$ All | ChangeValid$ Land | DestinationZone2$ Graveyard A:AB$ DealDamage | Cost$ Discard<1/Land> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 3 | SpellDescription$ CARDNAME deals 3 damage to any target. Oracle:Trample\nWhenever Borborygmos Enraged deals combat damage to a player, reveal the top three cards of your library. Put all land cards revealed this way into your hand and the rest into your graveyard.\nDiscard a land card: Borborygmos Enraged deals 3 damage to any target. diff --git a/forge-gui/res/cardsfolder/c/crafty_cutpurse.txt b/forge-gui/res/cardsfolder/c/crafty_cutpurse.txt index fab73f2e1e7..7bafc1cafef 100644 --- a/forge-gui/res/cardsfolder/c/crafty_cutpurse.txt +++ b/forge-gui/res/cardsfolder/c/crafty_cutpurse.txt @@ -4,7 +4,7 @@ Types:Creature Human Pirate PT:2/2 K:Flash T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEffect | TriggerDescription$ When CARDNAME enters the battlefield, each token that would be created under an opponent's control this turn is created under your control instead. -SVar:TrigEffect:DB$ Effect | Name$ Crafty Cutpurse Effect | ReplacementEffects$ OppCreatEnters | SpellDescription$ Each token that would be created under an opponent's control this turn is created under your control instead. +SVar:TrigEffect:DB$ Effect | Name$ Crafty Cutpurse Effect | ReplacementEffects$ OppCreatEnters SVar:OppCreatEnters:Event$ CreateToken | ActiveZones$ Command | ValidToken$ Card.OppCtrl | ReplaceWith$ ETBYourCtrl | Layer$ Control | Description$ Each token that would be created under an opponent's control this turn is created under your control instead. SVar:ETBYourCtrl:DB$ ReplaceToken | Type$ ReplaceController | ValidCard$ Card.OppCtrl | NewController$ You Oracle:Flash\nWhen Crafty Cutpurse enters the battlefield, each token that would be created under an opponent's control this turn is created under your control instead. diff --git a/forge-gui/res/cardsfolder/d/dragonborn_champion.txt b/forge-gui/res/cardsfolder/d/dragonborn_champion.txt index d9ab5d07aa1..9d58306dffd 100644 --- a/forge-gui/res/cardsfolder/d/dragonborn_champion.txt +++ b/forge-gui/res/cardsfolder/d/dragonborn_champion.txt @@ -4,5 +4,5 @@ Types:Creature Dragon Warrior PT:5/3 K:Trample T:Mode$ DamageDone | ValidSource$ Card.YouCtrl,Emblem.YouCtrl | ValidTarget$ Player | TriggerZones$ Battlefield | DamageAmount$ GE5 | Execute$ TrigDraw | TriggerDescription$ Whenever a source you control deals 5 or more damage to a player, draw a card. -SVar:TrigDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card. +SVar:TrigDraw:DB$ Draw | NumCards$ 1 Oracle:Trample\nWhenever a source you control deals 5 or more damage to a player, draw a card. diff --git a/forge-gui/res/cardsfolder/e/euroakus.txt b/forge-gui/res/cardsfolder/e/euroakus.txt index cc4bf947253..7cf889a96f9 100644 --- a/forge-gui/res/cardsfolder/e/euroakus.txt +++ b/forge-gui/res/cardsfolder/e/euroakus.txt @@ -3,7 +3,7 @@ ManaCost:4 G G Types:Legendary Creature Treefolk Wizard PT:6/6 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a number of 1/1 blue Human Wizard creature tokens equal to the number of differently named lands you control. -SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenScript$ u_1_1_human_wizard | SpellDescription$ Create a number of 1/1 blue Human Wizard creature tokens equal to the number of differently named lands you control. +SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenScript$ u_1_1_human_wizard SVar:X:Count$DifferentCardNames_Land.YouCtrl+inZoneBattlefield A:AB$ Draw | Cost$ 4 G U | NumCards$ Y | SubAbility$ PumpAll | SpellDescription$ Draw a card for each Wizard you control. They each get +1/+1 until end of turn for each card in your hand. SVar:Y:Count$Valid Wizard.YouCtrl diff --git a/forge-gui/res/cardsfolder/g/genesis_chamber.txt b/forge-gui/res/cardsfolder/g/genesis_chamber.txt index 91ff9e9bfa0..ee1c96f536e 100644 --- a/forge-gui/res/cardsfolder/g/genesis_chamber.txt +++ b/forge-gui/res/cardsfolder/g/genesis_chamber.txt @@ -2,7 +2,7 @@ Name:Genesis Chamber ManaCost:2 Types:Artifact T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonToken | TriggerZones$ Battlefield | Execute$ TrigToken | IsPresent$ Card.Self+untapped | TriggerDescription$ Whenever a nontoken creature enters the battlefield, if CARDNAME is untapped, that creature's controller creates a 1/1 colorless Myr artifact creature token. -SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ TriggeredCardController | TokenScript$ c_1_1_a_myr | SpellDescription$ Create a 1/1 Myr artifact creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ TriggeredCardController | TokenScript$ c_1_1_a_myr AI:RemoveDeck:Random DeckHas:Ability$Token Oracle:Whenever a nontoken creature enters the battlefield, if Genesis Chamber is untapped, that creature's controller creates a 1/1 colorless Myr artifact creature token. diff --git a/forge-gui/res/cardsfolder/i/irregular_cohort.txt b/forge-gui/res/cardsfolder/i/irregular_cohort.txt index a3a211266f9..6e999cb2d97 100644 --- a/forge-gui/res/cardsfolder/i/irregular_cohort.txt +++ b/forge-gui/res/cardsfolder/i/irregular_cohort.txt @@ -4,6 +4,6 @@ Types:Creature Shapeshifter PT:2/2 K:Changeling T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a colorless Shapeshifter creature token with changeling. -SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_2_2_shapeshifter_changeling | TokenOwner$ You | SpellDescription$ Create a 2/2 colorless Shapeshifter creature token with changeling. (It has every creature type.) +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_2_2_shapeshifter_changeling | TokenOwner$ You DeckHas:Ability$Token Oracle:Changeling (This card is every creature type.)\nWhen Irregular Cohort enters the battlefield, create a 2/2 colorless Shapeshifter creature token with changeling. diff --git a/forge-gui/res/cardsfolder/j/jolrael_mwonvuli_recluse.txt b/forge-gui/res/cardsfolder/j/jolrael_mwonvuli_recluse.txt index 6984b82d5dd..3d617ce3faa 100644 --- a/forge-gui/res/cardsfolder/j/jolrael_mwonvuli_recluse.txt +++ b/forge-gui/res/cardsfolder/j/jolrael_mwonvuli_recluse.txt @@ -3,7 +3,7 @@ ManaCost:1 G Types:Legendary Creature Human Druid PT:1/2 T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you draw your second card each turn, create a 2/2 green Cat creature token. -SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ You | TokenScript$ g_2_2_cat | SpellDescription$ Create a 2/2 green Cat creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ You | TokenScript$ g_2_2_cat DeckHas:Ability$Token A:AB$ AnimateAll | Cost$ 4 G G | ValidCards$ Creature.YouCtrl | Power$ X | Toughness$ X | SpellDescription$ Until end of turn, creatures you control have base power and toughness X/X, where X is the number of cards in your hand. SVar:X:Count$InYourHand diff --git a/forge-gui/res/cardsfolder/j/josu_vess_lich_knight.txt b/forge-gui/res/cardsfolder/j/josu_vess_lich_knight.txt index 234b0820e55..55a55261d77 100644 --- a/forge-gui/res/cardsfolder/j/josu_vess_lich_knight.txt +++ b/forge-gui/res/cardsfolder/j/josu_vess_lich_knight.txt @@ -5,6 +5,6 @@ PT:4/5 K:Kicker:5 B K:Menace T:Mode$ ChangesZone | ValidCard$ Card.Self+kicked | Origin$ Any | Destination$ Battlefield | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, create eight 2/2 black Zombie Knight creature tokens with menace. -SVar:TrigToken:DB$ Token | TokenAmount$ 8 | TokenScript$ b_2_2_zombie_knight_menace | TokenOwner$ You | SpellDescription$ When CARDNAME enters the battlefield, if it was kicked, create eight 2/2 black Zombie Knight creature tokens with menace. +SVar:TrigToken:DB$ Token | TokenAmount$ 8 | TokenScript$ b_2_2_zombie_knight_menace | TokenOwner$ You DeckHas:Ability$Token Oracle:Kicker {5}{B} (You may pay an additional {5}{B} as you cast this spell.)\nMenace\nWhen Josu Vess, Lich Knight enters the battlefield, if it was kicked, create eight 2/2 black Zombie Knight creature tokens with menace. diff --git a/forge-gui/res/cardsfolder/m/militant_angel.txt b/forge-gui/res/cardsfolder/m/militant_angel.txt index 2e468461510..1a47c0b7b7d 100644 --- a/forge-gui/res/cardsfolder/m/militant_angel.txt +++ b/forge-gui/res/cardsfolder/m/militant_angel.txt @@ -5,6 +5,6 @@ PT:3/4 K:Flying K:Lifelink T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn. -SVar:TrigToken:DB$ Token | TokenOwner$ You | TokenAmount$ X | TokenScript$ w_2_2_knight_vigilance | SpellDescription$ Create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn. +SVar:TrigToken:DB$ Token | TokenOwner$ You | TokenAmount$ X | TokenScript$ w_2_2_knight_vigilance SVar:X:TriggeredCardController$OpponentsAttackedThisTurn Oracle:Flying, lifelink\nWhen Militant Angel enters the battlefield, create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn. diff --git a/forge-gui/res/cardsfolder/p/pure_reflection.txt b/forge-gui/res/cardsfolder/p/pure_reflection.txt index 4abf93cfa22..57f067c4be2 100644 --- a/forge-gui/res/cardsfolder/p/pure_reflection.txt +++ b/forge-gui/res/cardsfolder/p/pure_reflection.txt @@ -2,7 +2,7 @@ Name:Pure Reflection ManaCost:2 W Types:Enchantment T:Mode$ SpellCast | ValidCard$ Creature | Execute$ TrigDestroy | ValidActivatingPlayer$ Player | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a creature spell, destroy all Reflections. Then that player creates an X/X white Reflection creature token, where X is the mana value of that spell. -SVar:TrigDestroy:DB$ DestroyAll | ValidCards$ Reflection | SubAbility$ DBToken | SpellDescription$ Destroy all Reflections +SVar:TrigDestroy:DB$ DestroyAll | ValidCards$ Reflection | SubAbility$ DBToken SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenPower$ X | TokenToughness$ X | TokenScript$ w_x_x_reflection | TokenOwner$ TriggeredActivator SVar:X:TriggeredStackInstance$CardManaCostLKI Oracle:Whenever a player casts a creature spell, destroy all Reflections. Then that player creates an X/X white Reflection creature token, where X is the mana value of that spell. diff --git a/forge-gui/res/cardsfolder/r/regna_the_redeemer.txt b/forge-gui/res/cardsfolder/r/regna_the_redeemer.txt index 5ec291771c9..8ebab24bfa5 100644 --- a/forge-gui/res/cardsfolder/r/regna_the_redeemer.txt +++ b/forge-gui/res/cardsfolder/r/regna_the_redeemer.txt @@ -5,7 +5,7 @@ PT:4/4 K:Partner:Krav, the Unredeemed:Krav K:Flying T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | CheckSVar$ YouTeamLifeGained | SVarCompare$ GE1 | Execute$ TrigWarrior | TriggerDescription$ At the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens. -SVar:TrigWarrior:DB$ Token | TokenAmount$ 2 | TokenScript$ w_1_1_warrior | TokenOwner$ You | SpellDescription$ Create two 1/1 white Warrior creature tokens. +SVar:TrigWarrior:DB$ Token | TokenAmount$ 2 | TokenScript$ w_1_1_warrior | TokenOwner$ You SVar:YouTeamLifeGained:Count$LifeYourTeamGainedThisTurn DeckHints:Name$Krav, the Unredeemed Oracle:Partner with Krav, the Unredeemed (When this creature enters the battlefield, target player may put Krav into their hand from their library, then shuffle.)\nFlying\nAt the beginning of each end step, if your team gained life this turn, create two 1/1 white Warrior creature tokens. diff --git a/forge-gui/res/cardsfolder/t/thelonite_hermit.txt b/forge-gui/res/cardsfolder/t/thelonite_hermit.txt index c5bb2d29cea..1f9a3769a44 100644 --- a/forge-gui/res/cardsfolder/t/thelonite_hermit.txt +++ b/forge-gui/res/cardsfolder/t/thelonite_hermit.txt @@ -5,7 +5,7 @@ PT:1/1 K:Morph:3 G G S:Mode$ Continuous | Affected$ Creature.Saproling | AddPower$ 1 | AddToughness$ 1 | IsPresent$ Card.Self+faceUp | Description$ All Saprolings get +1/+1. T:Mode$ TurnFaceUp | ValidCard$ Card.Self | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME is turned face up, create four 1/1 green Saproling creature tokens. -SVar:TrigToken:DB$ Token | TokenAmount$ 4 | TokenScript$ g_1_1_saproling | TokenOwner$ You | SpellDescription$ Create four 1/1 green Saproling creature tokens. +SVar:TrigToken:DB$ Token | TokenAmount$ 4 | TokenScript$ g_1_1_saproling | TokenOwner$ You SVar:PlayMain1:TRUE DeckHints:Type$Fungus DeckHas:Ability$Token diff --git a/forge-gui/res/cardsfolder/w/watchful_giant.txt b/forge-gui/res/cardsfolder/w/watchful_giant.txt index 8df72a9e184..adf0987e2d5 100644 --- a/forge-gui/res/cardsfolder/w/watchful_giant.txt +++ b/forge-gui/res/cardsfolder/w/watchful_giant.txt @@ -3,7 +3,7 @@ ManaCost:5 W Types:Creature Giant Soldier PT:3/6 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a 1/1 white Human creature token. -SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenOwner$ You | SpellDescription$ Create a 1/1 white Human creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human | TokenOwner$ You DeckHints:Type$Human DeckHas:Ability$Token Oracle:When Watchful Giant enters the battlefield, create a 1/1 white Human creature token. diff --git a/forge-gui/src/main/java/forge/gamemodes/match/input/InputSelectManyBase.java b/forge-gui/src/main/java/forge/gamemodes/match/input/InputSelectManyBase.java index ec6d1095826..0c1dacdedc3 100644 --- a/forge-gui/src/main/java/forge/gamemodes/match/input/InputSelectManyBase.java +++ b/forge-gui/src/main/java/forge/gamemodes/match/input/InputSelectManyBase.java @@ -64,8 +64,8 @@ public abstract class InputSelectManyBase extends InputSyn @Override public final void showMessage() { - if ( FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DETAILED_SPELLDESC_IN_PROMPT) && - (card!=null) ) { + if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DETAILED_SPELLDESC_IN_PROMPT) && + card != null) { final StringBuilder sb = new StringBuilder(); sb.append(card.toString()); if ( (sa != null) && (!sa.toString().isEmpty()) ) { // some spell abilities have no useful string value diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 654394c5efb..b96ff13ad81 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -743,13 +743,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont switch (sa.getParam("ShowCardInPrompt")) { case "FirstRemembered": o = sa.getHostCard().getFirstRemembered(); - if (o != null && o instanceof Card) { + if (o instanceof Card) { show = (Card)o; } break; case "LastRemembered": o = sa.getHostCard().getFirstRemembered(); - if (o != null && o instanceof Card) { + if (o instanceof Card) { show = (Card)o; } break; From c16a4700a9bfb76d248793bc610f8faeb462d51e Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Tue, 22 Nov 2022 22:23:50 +0800 Subject: [PATCH 12/24] fix itemfilter --- forge-gui-mobile/src/forge/itemmanager/CardManager.java | 3 +-- .../src/forge/itemmanager/filters/FormatFilter.java | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui-mobile/src/forge/itemmanager/CardManager.java b/forge-gui-mobile/src/forge/itemmanager/CardManager.java index 937721f763d..501a5a6a257 100644 --- a/forge-gui-mobile/src/forge/itemmanager/CardManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/CardManager.java @@ -49,8 +49,7 @@ public class CardManager extends ItemManager { public static void addDefaultFilters(final ItemManager itemManager) { itemManager.addFilter(new CardColorFilter(itemManager)); - if (!Forge.isMobileAdventureMode) - itemManager.addFilter(new CardFormatFilter(itemManager)); + itemManager.addFilter(new CardFormatFilter(itemManager)); itemManager.addFilter(new CardTypeFilter(itemManager)); } diff --git a/forge-gui-mobile/src/forge/itemmanager/filters/FormatFilter.java b/forge-gui-mobile/src/forge/itemmanager/filters/FormatFilter.java index 0db437ac335..79d18810b91 100644 --- a/forge-gui-mobile/src/forge/itemmanager/filters/FormatFilter.java +++ b/forge-gui-mobile/src/forge/itemmanager/filters/FormatFilter.java @@ -47,6 +47,7 @@ public abstract class FormatFilter extends ItemFilter Date: Tue, 22 Nov 2022 22:29:54 +0800 Subject: [PATCH 13/24] unused import --- forge-gui-mobile/src/forge/itemmanager/CardManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/forge-gui-mobile/src/forge/itemmanager/CardManager.java b/forge-gui-mobile/src/forge/itemmanager/CardManager.java index 501a5a6a257..6f194a42afc 100644 --- a/forge-gui-mobile/src/forge/itemmanager/CardManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/CardManager.java @@ -2,7 +2,6 @@ package forge.itemmanager; import java.util.Map.Entry; -import forge.Forge; import forge.Graphics; import forge.assets.FSkinColor; import forge.assets.FSkinFont; From ddc7a807867418ba3da3a065f6ee1d339612fca1 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Tue, 22 Nov 2022 16:51:28 +0100 Subject: [PATCH 14/24] update --- .../res/cardsfolder/upcoming/ingenious_leonin.txt | 2 +- .../upcoming/magnanimous_magistrate.txt | 2 +- .../upcoming/mild_mannered_librarian.txt | 4 ++-- .../cardsfolder/upcoming/rodolf_duskbringer.txt | 15 +++++++++++++++ .../upcoming/runadi_behemoth_caller.txt | 7 +++---- .../upcoming/zask_skittering_swarmlord.txt | 12 ++++++++++++ 6 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt diff --git a/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt b/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt index 1be8363b881..df390b571c9 100644 --- a/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt +++ b/forge-gui/res/cardsfolder/upcoming/ingenious_leonin.txt @@ -3,6 +3,6 @@ ManaCost:4 W Types:Creature Cat Soldier PT:4/4 A:AB$ PutCounter | Cost$ 3 W | ValidTgts$ Creature.attacking+Other+YouCtrl | TgtPrompt$ Select another target attacking creature you control | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on another target attacking creature you control. If that creature is a Cat, it gains first strike until end of turn. -SVar:DBPump:DB$ Pump | Defined$ Targeted | ConditionDefined$ Targeted | ConditionPresent$ Cat | KW$ First Strike +SVar:DBPump:DB$ Pump | Defined$ Targeted | ConditionDefined$ Targeted | ConditionPresent$ Cat | KW$ First Strike | StackDesc$ If that creature is a Cat, it gains first strike until end of turn DeckHints:Type$Cat Oracle:{3}{W}: Put a +1/+1 counter on another target attacking creature you control. If that creature is a Cat, it gains first strike until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt b/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt index 01ac7c7545a..19796a6f506 100644 --- a/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt +++ b/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt @@ -2,7 +2,7 @@ Name:Magnanimous Magistrate ManaCost:5 W Types:Creature Human Advisor PT:3/4 -K:etbCounter:REPR:5:no condition:CARDNAME enters the battlefield with 5 reprieve counters on it. +K:etbCounter:REPR:5:CARDNAME enters the battlefield with 5 reprieve counters on it. T:Mode$ ChangesZone | ValidCard$ Creature.Other+nonToken+cmcGE1 | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Whenever another nontoken creature you control dies, if its mana value was 1 or greater, you may remove that many reprieve counters from CARDNAME. If you do, return that card to the battlefield under its owner's control. SVar:TrigChangeZone:AB$ ChangeZone | Cost$ SubCounter | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield SVar:X:TriggeredCard$CardManaCost diff --git a/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt b/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt index 3a02ec1d4df..6b13b16205d 100644 --- a/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt +++ b/forge-gui/res/cardsfolder/upcoming/mild_mannered_librarian.txt @@ -2,8 +2,8 @@ Name:Mild-Mannered Librarian ManaCost:G Types:Creature Human PT:1/1 -A:AB$ Animate | Cost$ 3 G | GameActivationLimit$ 1 | Types$ Werewolf | Duration$ Permanent | SubAbility$ DBCounter | SpellDescription$ CARDNAME becomes a werewolf. Put two +1/+1 counters on it and you draw a card. Activate only once. +A:AB$ Animate | Cost$ 3 G | GameActivationLimit$ 1 | Types$ Werewolf | RemoveCreatureTypes$ True | Duration$ Permanent | SubAbility$ DBCounter | SpellDescription$ CARDNAME becomes a Werewolf. Put two +1/+1 counters on it and you draw a card. Activate only once. SVar:DBCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2 | SubAbility$ DBDraw SVar:DBDraw:DB$ Draw DeckHas:Ability$Counters & Type$Werewolf -Oracle:{3}{G}: Mild-Mannered Librarian becomes a werewolf. Put two +1/+1 counters on it and you draw a card. Activate only once. \ No newline at end of file +Oracle:{3}{G}: Mild-Mannered Librarian becomes a Werewolf. Put two +1/+1 counters on it and you draw a card. Activate only once. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt b/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt new file mode 100644 index 00000000000..5bf2d5a6ed5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt @@ -0,0 +1,15 @@ +Name:Rodolf Duskbringer +ManaCost:5 B +Types:Legendary Creature Vampire Angel +PT:4/4 +K:Flying +K:Deathtouch +K:Lifelink +T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you gain life, CARDNAME gains indestructible until end of turn. +SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Indestructible +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | Execute$ TrigChangeZone | TriggerDescription$ At the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. +SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 1 WB | ValidTgts$ Creature.cmcLEX+YouOwn | TgtPrompt$ Select target creature card with mana value X or less | Origin$ Graveyard | Destination$ Battlefield +SVar:X:Count$LifeYouGainedThisTurn +DeckHas:Ability$Graveyard|LifeGain & Keyword$indestructible +DeckHints:Ability$Graveyard|LifeGain|Mill +Oracle:Flying, deathtouch, lifelink\nWhenever you gain life, Rodolf Duskbringer gains indestructible until end of turn.\nAt the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt b/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt index c574bf1e780..1b1d0b93602 100644 --- a/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt +++ b/forge-gui/res/cardsfolder/upcoming/runadi_behemoth_caller.txt @@ -5,11 +5,10 @@ PT:1/3 T:Mode$ SpellCast | ValidCard$ Creature.cmcGE5 | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever you cast a creature spell with mana value 5 or greater, that creature enters the battlefield with X additional +1/+1 counters on it, where X is its mana value minus 4. SVar:TrigEffect:DB$ Effect | RememberObjects$ TriggeredCard | ReplacementEffects$ ETBCreat | ExileOnMoved$ Stack SVar:ETBCreat:Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Battlefield | ReplaceWith$ DBPutP1P1 | ReplacementResult$ Updated -SVar:DBPutP1P1:DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ True | CounterNum$ X | SubAbility$ DBExile -SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile -S:Mode$ Continuous | Affected$ Creature.YouCtrl+counters_GE3_P1P1 | AddKeyword$ Haste | Description$ Creature you control with three or more +1/+1 counters on them have haste. +SVar:DBPutP1P1:DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ True | CounterNum$ X +S:Mode$ Continuous | Affected$ Creature.YouCtrl+counters_GE3_P1P1 | AddKeyword$ Haste | Description$ Creatures you control with three or more +1/+1 counters on them have haste. A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. SVar:X:Remembered$CardManaCost/Minus.4 DeckHas:Ability$Counters DeckHints:Type$Tyranid|Hydra -Oracle:Whenever you cast a creature spell with mana value 5 or greater, that creature enters the battlefield with X additional +1/+1 counters on it, where X is its mana value minus 4.\nCreature you control with three or more +1/+1 counters on them have haste.\n{T}: Add {G}. \ No newline at end of file +Oracle:Whenever you cast a creature spell with mana value 5 or greater, that creature enters the battlefield with X additional +1/+1 counters on it, where X is its mana value minus 4.\nCreatures you control with three or more +1/+1 counters on them have haste.\n{T}: Add {G}. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt b/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt new file mode 100644 index 00000000000..ba70ad7c65e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt @@ -0,0 +1,12 @@ +Name:Zask, Skittering Swarmlord +ManaCost:3 G G +Types:Legendary Creature Insect +PT:5/5 +S:Mode$ Continuous | Affected$ Land.YouOwn,Insect.YouOwn | MayPlay$ True | AffectedZone$ Graveyard | Description$ You may play lands and cast Insect spells from your graveyard. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Insect.YouCtrl | Execute$ TrigChange | TriggerDescription$ Whenever another Insect you control dies, put it on the bottom of its owner's library, then mill two cards. (Put the top two cards of your library into your graveyard.) +SVar:TrigChange:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Library | LibraryPosition$ -1 | SubAbility$ DBMill +SVar:DBMill:DB$ Mill | NumCards$ 2 +A:AB$ Pump | Cost$ 1 BG | ValidTgts$ Insect | NumAtt$ 1 | KW$ Deathtouch | SpellDescription$ Target Insect gets +1/+0 and gains deathtouch until end of turn. +DeckHas:Ability$Mill|Graveyard & Keyword$Deathtouch +DeckNeeds:Type$Insect +Oracle:You may play lands and cast Insect spells from your graveyard.\nWhenever another Insect you control dies, put it on the bottom of its owner's library, then mill two cards. (Put the top two cards of your library into your graveyard.)\n{1}{B/G}: Target Insect gets +1/+0 and gains deathtouch until end of turn. From 858db55ca36d0f39a2a89ef93c17193acfd55651 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Tue, 22 Nov 2022 17:24:27 +0100 Subject: [PATCH 15/24] update --- .../res/cardsfolder/upcoming/magnanimous_magistrate.txt | 2 +- forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt b/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt index 19796a6f506..668e78f8b88 100644 --- a/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt +++ b/forge-gui/res/cardsfolder/upcoming/magnanimous_magistrate.txt @@ -2,7 +2,7 @@ Name:Magnanimous Magistrate ManaCost:5 W Types:Creature Human Advisor PT:3/4 -K:etbCounter:REPR:5:CARDNAME enters the battlefield with 5 reprieve counters on it. +K:etbCounter:REPR:5 T:Mode$ ChangesZone | ValidCard$ Creature.Other+nonToken+cmcGE1 | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Whenever another nontoken creature you control dies, if its mana value was 1 or greater, you may remove that many reprieve counters from CARDNAME. If you do, return that card to the battlefield under its owner's control. SVar:TrigChangeZone:AB$ ChangeZone | Cost$ SubCounter | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield SVar:X:TriggeredCard$CardManaCost diff --git a/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt b/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt index 5bf2d5a6ed5..a389dcb34fb 100644 --- a/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt +++ b/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt @@ -7,8 +7,9 @@ K:Deathtouch K:Lifelink T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you gain life, CARDNAME gains indestructible until end of turn. SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Indestructible -T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | Execute$ TrigChangeZone | TriggerDescription$ At the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. -SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 1 WB | ValidTgts$ Creature.cmcLEX+YouOwn | TgtPrompt$ Select target creature card with mana value X or less | Origin$ Graveyard | Destination$ Battlefield +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | Execute$ TrigImmediateTrig | TriggerDescription$ At the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. +SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ 1 WB | Execute$ TrigChangeZone | TriggerDescription$ When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. +SVar:TrigChangeZone:AB$ ChangeZone | ValidTgts$ Creature.cmcLEX+YouOwn | TgtPrompt$ Select target creature card with mana value X or less | Origin$ Graveyard | Destination$ Battlefield SVar:X:Count$LifeYouGainedThisTurn DeckHas:Ability$Graveyard|LifeGain & Keyword$indestructible DeckHints:Ability$Graveyard|LifeGain|Mill From 5d9bba959dd580f50d9b90aed43947bb0327a2c4 Mon Sep 17 00:00:00 2001 From: Northmoc <103371817+Northmoc@users.noreply.github.com> Date: Tue, 22 Nov 2022 11:27:43 -0500 Subject: [PATCH 16/24] J22: 21 Nov (#1949) * conductor_of_cacophony.txt * deathbringer_thoctar.txt tidy * rumbling_slum_avatar.txt tidy * dutiful_replicator.txt * hold_for_questioning.txt --- forge-gui/res/cardsfolder/d/deathbringer_thoctar.txt | 3 ++- forge-gui/res/cardsfolder/r/rumbling_slum_avatar.txt | 2 +- .../cardsfolder/upcoming/conductor_of_cacophony.txt | 9 +++++++++ .../res/cardsfolder/upcoming/dutiful_replicator.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/hold_for_questioning.txt | 11 +++++++++++ 5 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/conductor_of_cacophony.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/dutiful_replicator.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hold_for_questioning.txt diff --git a/forge-gui/res/cardsfolder/d/deathbringer_thoctar.txt b/forge-gui/res/cardsfolder/d/deathbringer_thoctar.txt index 2d172243e28..4c05365dd52 100644 --- a/forge-gui/res/cardsfolder/d/deathbringer_thoctar.txt +++ b/forge-gui/res/cardsfolder/d/deathbringer_thoctar.txt @@ -4,5 +4,6 @@ Types:Creature Zombie Beast PT:3/3 T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Other | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever another creature dies, you may put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 -A:AB$ DealDamage | Cost$ SubCounter<1/P1P1> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to any target. +A:AB$ DealDamage | Cost$ SubCounter<1/P1P1> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1 | SpellDescription$ It deals 1 damage to any target. +DeckHas:Ability$Counters Oracle:Whenever another creature dies, you may put a +1/+1 counter on Deathbringer Thoctar.\nRemove a +1/+1 counter from Deathbringer Thoctar: It deals 1 damage to any target. diff --git a/forge-gui/res/cardsfolder/r/rumbling_slum_avatar.txt b/forge-gui/res/cardsfolder/r/rumbling_slum_avatar.txt index ca188bca282..b078e27d04c 100644 --- a/forge-gui/res/cardsfolder/r/rumbling_slum_avatar.txt +++ b/forge-gui/res/cardsfolder/r/rumbling_slum_avatar.txt @@ -3,5 +3,5 @@ ManaCost:no cost Types:Vanguard HandLifeModifier:+1/+1 T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigDmgOpp | TriggerDescription$ At the beginning of your upkeep, CARDNAME deals 1 damage to each opponent. -SVar:TrigDmgOpp:DB$ DealDamage | Defined$ Player.Opponent | NumDmg$ 1 +SVar:TrigDmgOpp:DB$ DealDamage | Defined$ Opponent | NumDmg$ 1 Oracle:Hand +1, life +1\nAt the beginning of your upkeep, Rumbling Slum Avatar deals 1 damage to each opponent. diff --git a/forge-gui/res/cardsfolder/upcoming/conductor_of_cacophony.txt b/forge-gui/res/cardsfolder/upcoming/conductor_of_cacophony.txt new file mode 100644 index 00000000000..0eeb4044ecf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/conductor_of_cacophony.txt @@ -0,0 +1,9 @@ +Name:Conductor of Cacophony +ManaCost:3 B +Types:Creature Demon +PT:2/1 +K:etbCounter:P1P1:2 +A:AB$ DamageAll | Cost$ B SubCounter<1/P1P1> | ValidCards$ Creature.Other | ValidPlayers$ Player | NumDmg$ 1 | ValidDescription$ each other creature and each player. | SpellDescription$ It deals 1 damage to each other creature and each player. +DeckHas:Ability$Counters +DeckHints:Ability$Counters +Oracle:Conductor of Cacophony enters the battlefield with two +1/+1 counters on it.\n{B}, Remove a +1/+1 counter from Conductor of Cacophony: It deals 1 damage to each other creature and each player. diff --git a/forge-gui/res/cardsfolder/upcoming/dutiful_replicator.txt b/forge-gui/res/cardsfolder/upcoming/dutiful_replicator.txt new file mode 100644 index 00000000000..75ace52e6e9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dutiful_replicator.txt @@ -0,0 +1,10 @@ +Name:Dutiful Replicator +ManaCost:3 +Types:Artifact Creature Assembly-Worker +PT:3/2 +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigImmediate | TriggerDescription$ When CARDNAME enters the battlefield, you may pay {1}. When you do, create a token that's a copy of target token you control not named Dutiful Replicator. +SVar:TrigImmediate:AB$ ImmediateTrigger | Cost$ 1 | Execute$ TrigClone | TriggerDescription$ When you do, create a token that's a copy of target token you control not named Dutiful Replicator. +SVar:TrigClone:DB$ CopyPermanent | ValidTgts$ Permanent.token+YouCtrl+notnamedDutiful Replicator | TgtPrompt$ Select target token you control not named Dutiful Replicator +DeckHas:Ability$Token +DeckNeeds:Ability$Token +Oracle:When Dutiful Replicator enters the battlefield, you may pay {1}. When you do, create a token that's a copy of target token you control not named Dutiful Replicator. diff --git a/forge-gui/res/cardsfolder/upcoming/hold_for_questioning.txt b/forge-gui/res/cardsfolder/upcoming/hold_for_questioning.txt new file mode 100644 index 00000000000..60a3dda9672 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hold_for_questioning.txt @@ -0,0 +1,11 @@ +Name:Hold for Questioning +ManaCost:3 U +Types:Enchantment Aura +K:Enchant creature or planeswalker +A:SP$ Attach | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | AILogic$ Curse +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigTap | TriggerDescription$ When CARDNAME enters the battlefield, tap enchanted permanent and investigate. (Create a Clue token. It's an artifact with "{2}, Sacrifice this artifact: Draw a card.") +SVar:TrigTap:DB$ Tap | Defined$ Enchanted | SubAbility$ DBInvestigate +SVar:DBInvestigate:DB$ Investigate +S:Mode$ Continuous | Affected$ Permanent.EnchantedBy | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. & CARDNAME's activated abilities can't be activated. | Description$ Enchanted permanent doesn't untap during its controller's untap step and its activated abilities can't be activated. +DeckHas:Ability$Investigate|Token|Sacrifice & Type$Artifact|Clue +Oracle:Enchant creature or planeswalker\nWhen Hold for Questioning enters the battlefield, tap enchanted permanent and investigate. (Create a Clue token. It's an artifact with "{2}, Sacrifice this artifact: Draw a card.")\nEnchanted permanent doesn't untap during its controller's untap step and its activated abilities can't be activated. From 99004c3227681b2185a4642d92b2ac7be4b94a04 Mon Sep 17 00:00:00 2001 From: JohnWilliams77 <103562494+JohnWilliams77@users.noreply.github.com> Date: Tue, 22 Nov 2022 16:41:03 +0000 Subject: [PATCH 17/24] Update Secret Lair 30th Anniversary Countdown Kit.txt (#1948) --- .../res/editions/Secret Lair 30th Anniversary Countdown Kit.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-gui/res/editions/Secret Lair 30th Anniversary Countdown Kit.txt b/forge-gui/res/editions/Secret Lair 30th Anniversary Countdown Kit.txt index 958717bd4a0..7bd4987caf6 100644 --- a/forge-gui/res/editions/Secret Lair 30th Anniversary Countdown Kit.txt +++ b/forge-gui/res/editions/Secret Lair 30th Anniversary Countdown Kit.txt @@ -36,3 +36,4 @@ ScryfallCode=SLC 2020 R Shark Typhoon @Edgar Sánchez Hidalgo 2021 R Elite Spellbinder @Alexis Ziritt 2022 M Nashi, Moon Sage's Scion @Death Burger +2023 M Lotus Field @ZIUK From 8626b30ac13e3d8f18b0ac8ad368dfd3fa1d7367 Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Tue, 22 Nov 2022 18:21:24 +0000 Subject: [PATCH 18/24] J22 edition update --- forge-gui/res/editions/Jumpstart 2022.txt | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/forge-gui/res/editions/Jumpstart 2022.txt b/forge-gui/res/editions/Jumpstart 2022.txt index 0c57f069fa6..1f7ac883cd5 100644 --- a/forge-gui/res/editions/Jumpstart 2022.txt +++ b/forge-gui/res/editions/Jumpstart 2022.txt @@ -6,8 +6,75 @@ Type=Draft ScryfallCode=J22 [cards] +4 U Distinguished Conjurer @Nils Hamm +5 U Ingenious Leonin @Eric Deschamps +6 M Lita, Mechanical Engineer @Bartek Fedyczak +7 U Magnanimous Magistrate @Marie Magny +8 R Preston, the Vanisher @Christina Kraus +11 U Hold for Questioning @Samuel Perin 12 M Isu the Abominable @Victor Adame Minguez +15 C Merfolk Pupil @Caroline Gariba +16 M Pirated Copy @Daarken +19 M Ashcoat of the Shadow Swarm @Christina Kraus +20 U Conductor of Cacophony @Jason A. Engle +21 C Creeping Bloodsucker @Antonio José Manzanedo +23 U Disciple of Perdition @Alix Branwyn +25 R Rodolf Duskbringer @Billy Christian +28 R Termination Facilitator @Justine Cruz 29 R Ardoz, Cobbler of War @Kev Walker +40 M Kibo, Uktabi Prince @Zoltan Boros +41 U Mild-Mannered Librarian @Justyna Gil +42 U Primeval Herald @Tatiana Kirgetova +44 R Runadi, Behemoth Caller @Billy Christian +45 C Spectral Hunt-Caller @Uriah Voth +46 U Towering Gibbon @Chris Seaman +48 C Dutiful Replicator @Alexander Forssberg +49 C Infernal Idol @Drew Tucker +50 U Instruments of War @Drew Tucker +51 U Planar Atlas @Alexander Forssberg +52 U Arrest @Katana Canata +53 R Balan, Wandering Knight @Mai Okuma +56 C Flicker of Fate +57 U King of the Pride @Inuchiyo Meimaru +62 U Mirror Image @Yukie Tajima +64 U Spectral Sailor @Fuzichoco +65 C Spellstutter Sprite +66 U Whirler Rogue @I☆LA +67 C Diabolic Edict @Tetsu Kurosawa +68 U Feast on the Fallen +70 U Oathsworn Vampire @Border +71 R Ogre Slumlord 79 M Kiki-Jiki, Mirror Breaker @Ishikawa Kenta +85 U Arlinn, Voice of the Pack @Hisashi Momose +88 C Elvish Rejuvenator @Shiramine +92 U Thrashing Brontodon @Kemonomichi 94 U Coldsteel Heart @I☆LA +95 U Magnifying Glass @Yukihiro Maruo +96 R Peacewalker Colossus @Hisashi Momose +97 M Karn Liberated @Dai-XT +117 U Blood Artist @Julie Dillon +118 U Feast of Blood @Irina Nordsol +119 U Festering Evil @Samuel Araya +126 C Renegade Demon @Alexandre Honoré +133 U Uktabi Orangutan @Milivoj Ćeran +134 R Wicked Wolf @Steve Ellis +141 M Ajani, Strength of the Pride @Chris Rallis +142 U Ajani's Pridemate @Svetlin Velinov +184 R Felidar Retreat @Ralph Horsley +208 R Leonin Warleader @Jakub Kasper +232 R Regal Caracal @Filip Burburan +259 R Trove Warden @Lars Grant-West +323 U Nezumi Bone-Reader @Leonardo Santanna +384 C Burglar Rat @Tyler Walpole +387 C Chittering Rats @Yeong-Hao Han +392 U Crypt Rats @Matt Cavotta +397 R Demon of Catastrophes @Sidharth Chaturvedi +403 R Dread Presence @Anthony Palumbo +412 C Eviscerate @Min Yum +431 R Kothophed, Soul Hoarder @Jakub Kasper +463 R Seizan, Perverter of Truth @Kev Walker +465 C Sinuous Vermin @Jason Kang +468 C Typhoid Rats @Kev Walker +481 U Ulcerate @Johann Bodin +806 R Walking Ballista @Daniel Ljunggren 835 M Kibo, Uktabi Prince @Filipe Pagliuso From 85398f12738be8c4cf3c5cdb1d23bcb6436370b7 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Tue, 22 Nov 2022 19:31:38 +0100 Subject: [PATCH 19/24] Fix Debt of Loyalty triggering non-static --- .../forge/game/ability/AbilityFactory.java | 3 +- .../game/ability/effects/CharmEffect.java | 4 ++ .../ability/effects/DamageDealEffect.java | 5 +- .../effects/DamagePreventEffectBase.java | 3 +- .../ability/effects/DelayedTriggerEffect.java | 1 + .../forge/game/ability/effects/FogEffect.java | 3 +- .../ability/effects/RegenerateBaseEffect.java | 25 ++++---- .../game/ability/effects/SkipPhaseEffect.java | 3 +- .../game/ability/effects/SkipTurnEffect.java | 3 +- .../src/main/java/forge/game/card/Card.java | 62 +++++++------------ .../main/java/forge/game/zone/MagicStack.java | 2 +- .../game/zone/PlayerZoneBattlefield.java | 5 +- .../res/cardsfolder/d/debt_of_loyalty.txt | 2 +- .../res/cardsfolder/d/deserters_quarters.txt | 2 +- .../res/cardsfolder/o/old_man_of_the_sea.txt | 2 +- .../res/cardsfolder/p/prophetic_titan.txt | 2 +- 16 files changed, 55 insertions(+), 72 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index e0e59f1bc6d..710979e36a3 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -302,8 +302,7 @@ public final class AbilityFactory { } if (spellAbility instanceof SpellApiBased && hostCard.isPermanent()) { - String desc = mapParams.containsKey("SpellDescription") ? mapParams.get("SpellDescription") - : spellAbility.getHostCard().getName(); + String desc = mapParams.getOrDefault("SpellDescription", spellAbility.getHostCard().getName()); spellAbility.setDescription(desc); } else if (mapParams.containsKey("SpellDescription")) { spellAbility.rebuiltDescription(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java index 1f5902bc90a..f6955394958 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java @@ -65,6 +65,10 @@ public class CharmEffect extends SpellAbilityEffect { // using getCardForUi game is not set, so can't guess max charm num = Integer.MAX_VALUE; } else { + // fallback needed while ability building + if (sa.getActivatingPlayer() == null) { + sa.setActivatingPlayer(source.getController()); + } num = Math.min(AbilityUtils.calculateAmount(source, sa.getParamOrDefault("CharmNum", "1"), sa), list.size()); } final int min = sa.hasParam("MinCharmNum") ? AbilityUtils.calculateAmount(source, sa.getParam("MinCharmNum"), sa) : num; diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 0ea92400ad2..9f970957841 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -320,12 +320,9 @@ public class DamageDealEffect extends DamageBaseEffect { } else { if (sa.hasParam("ExcessDamage") && (!sa.hasParam("ExcessDamageCondition") || sourceLKI.isValid(sa.getParam("ExcessDamageCondition").split(","), activationPlayer, hostCard, sa))) { - damageMap.put(sourceLKI, c, dmgToTarget); - List list = Lists.newArrayList(); - list.addAll(AbilityUtils.getDefinedCards(hostCard, sa.getParam("ExcessDamage"), sa)); - list.addAll(AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("ExcessDamage"), sa)); + List list = AbilityUtils.getDefinedEntities(hostCard, sa.getParam("ExcessDamage"), sa); if (!list.isEmpty()) { damageMap.put(sourceLKI, list.get(0), excess); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffectBase.java b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffectBase.java index cdecd9ce083..039ab8088aa 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffectBase.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamagePreventEffectBase.java @@ -17,6 +17,7 @@ import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.CardTranslation; import forge.util.TextUtil; public abstract class DamagePreventEffectBase extends SpellAbilityEffect { @@ -24,7 +25,7 @@ public abstract class DamagePreventEffectBase extends SpellAbilityEffect { final Card hostCard = sa.getHostCard(); final Game game = hostCard.getGame(); final Player player = hostCard.getController(); - final String name = hostCard.getName() + "'s Effect"; + final String name = CardTranslation.getTranslatedName(hostCard.getName()) + "'s Effect"; final String image = hostCard.getImageKey(); StringBuilder sb = new StringBuilder("Event$ DamageDone | ActiveZones$ Command | ValidTarget$ "); sb.append((o instanceof Card ? "Card.IsRemembered" : "Player.IsRemembered")); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java index 316885c6234..0770d40935c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DelayedTriggerEffect.java @@ -38,6 +38,7 @@ public class DelayedTriggerEffect extends SpellAbilityEffect { final Card host = sa.getHostCard(); final Game game = host.getGame(); Map mapParams = Maps.newHashMap(sa.getMapParams()); + mapParams.remove("Cost"); if (mapParams.containsKey("SpellDescription")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/FogEffect.java b/forge-game/src/main/java/forge/game/ability/effects/FogEffect.java index 335e8eeb3b7..9f848b2f8d7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/FogEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/FogEffect.java @@ -10,6 +10,7 @@ import forge.game.replacement.ReplacementHandler; import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.CardTranslation; public class FogEffect extends SpellAbilityEffect { @@ -22,7 +23,7 @@ public class FogEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card hostCard = sa.getHostCard(); final Game game = hostCard.getGame(); - final String name = hostCard.getName() + "'s Effect"; + final String name = CardTranslation.getTranslatedName(hostCard.getName()) + "'s Effect"; final String image = hostCard.getImageKey(); StringBuilder sb = new StringBuilder("Event$ DamageDone | ActiveZones$ Command | IsCombat$ True"); sb.append(" | Prevent$ True | Description$ Prevent all combat damage this turn."); diff --git a/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java index 2ed822bb1d4..68f3e7142ac 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RegenerateBaseEffect.java @@ -15,6 +15,7 @@ import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.CardTranslation; public abstract class RegenerateBaseEffect extends SpellAbilityEffect { @@ -24,44 +25,44 @@ public abstract class RegenerateBaseEffect extends SpellAbilityEffect { // create Effect for Regeneration final Card eff = createEffect( - sa, sa.getActivatingPlayer(), hostCard.getName() + "'s Regeneration", hostCard.getImageKey()); - + sa, sa.getActivatingPlayer(), CardTranslation.getTranslatedName(hostCard.getName()) + "'s Regeneration", hostCard.getImageKey()); + eff.addRemembered(list); addForgetOnMovedTrigger(eff, "Battlefield"); - + // build ReplacementEffect String repeffstr = "Event$ Destroy | ActiveZones$ Command | ValidCard$ Card.IsRemembered | Regeneration$ True" + " | Description$ Regeneration (if creature would be destroyed, regenerate it instead)"; - + String effect = "DB$ Regeneration | Defined$ ReplacedCard"; String exileEff = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile" + " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0"; ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true); - + SpellAbility saReg = AbilityFactory.getAbility(effect, eff); - AbilitySub saExile = (AbilitySub)AbilityFactory.getAbility(exileEff, eff); + AbilitySub saExile = (AbilitySub)AbilityFactory.getAbility(exileEff, eff); saReg.setSubAbility(saExile); re.setOverridingAbility(saReg); eff.addReplacementEffect(re); - + // add extra Remembered if (sa.hasParam("RememberObjects")) { eff.addRemembered(AbilityUtils.getDefinedObjects(hostCard, sa.getParam("RememberObjects"), sa)); } - + if (sa.hasParam("RegenerationTrigger")) { final String str = sa.getSVar(sa.getParam("RegenerationTrigger")); - + SpellAbility trigSA = AbilityFactory.getAbility(str, eff); - + final String trigStr = "Mode$ Regenerated | ValidCause$ Effect.Self | TriggerZones$ Command " + " | TriggerDescription$ " + trigSA.getDescription(); final Trigger trigger = TriggerHandler.parseTrigger(trigStr, eff, true); trigger.setOverridingAbility(trigSA); eff.addTrigger(trigger); } - + // Copy text changes if (sa.isIntrinsic()) { eff.copyChangedTextFrom(hostCard); @@ -75,7 +76,7 @@ public abstract class RegenerateBaseEffect extends SpellAbilityEffect { game.getAction().moveTo(ZoneType.Command, eff, sa, AbilityKey.newMap()); eff.updateStateForView(); game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); - + final GameCommand untilEOT = new GameCommand() { private static final long serialVersionUID = 259368227093961103L; diff --git a/forge-game/src/main/java/forge/game/ability/effects/SkipPhaseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SkipPhaseEffect.java index 4c4ddc1f9fd..2e25b4f5373 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SkipPhaseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SkipPhaseEffect.java @@ -15,6 +15,7 @@ import forge.game.replacement.ReplacementLayer; import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.CardTranslation; public class SkipPhaseEffect extends SpellAbilityEffect { @@ -58,7 +59,7 @@ public class SkipPhaseEffect extends SpellAbilityEffect { final String duration, final String phase, final String step) { final Card hostCard = sa.getHostCard(); final Game game = hostCard.getGame(); - final String name = hostCard.getName() + "'s Effect"; + final String name = CardTranslation.getTranslatedName(hostCard.getName()) + "'s Effect"; final String image = hostCard.getImageKey(); final boolean isNextThisTurn = duration != null && duration.equals("NextThisTurn"); diff --git a/forge-game/src/main/java/forge/game/ability/effects/SkipTurnEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SkipTurnEffect.java index 0d81ed142ca..ec956b5e12f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SkipTurnEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SkipTurnEffect.java @@ -16,6 +16,7 @@ import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; +import forge.util.CardTranslation; import forge.util.Lang; public class SkipTurnEffect extends SpellAbilityEffect { @@ -38,7 +39,7 @@ public class SkipTurnEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card hostCard = sa.getHostCard(); final Game game = hostCard.getGame(); - final String name = hostCard.getName() + "'s Effect"; + final String name = CardTranslation.getTranslatedName(hostCard.getName()) + "'s Effect"; final String image = hostCard.getImageKey(); final int numTurns = AbilityUtils.calculateAmount(hostCard, sa.getParam("NumTurns"), sa); String repeffstr = "Event$ BeginTurn | ActiveZones$ Command | ValidPlayer$ You " + 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 1c23be603e8..9c85906bd83 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -299,7 +299,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private Map goad = Maps.newTreeMap(); private final List leavePlayCommandList = Lists.newArrayList(); - private final List etbCommandList = Lists.newArrayList(); private final List untapCommandList = Lists.newArrayList(); private final List changeControllerCommandList = Lists.newArrayList(); private final List unattachCommandList = Lists.newArrayList(); @@ -3265,20 +3264,24 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return canCounter; } - public final void addComesIntoPlayCommand(final GameCommand c) { - etbCommandList.add(c); - } - - public final void runComesIntoPlayCommands() { - for (final GameCommand c : etbCommandList) { - c.run(); - } - etbCommandList.clear(); - } - public final void addLeavesPlayCommand(final GameCommand c) { leavePlayCommandList.add(c); } + public final void addUntapCommand(final GameCommand c) { + untapCommandList.add(c); + } + public final void addUnattachCommand(final GameCommand c) { + unattachCommandList.add(c); + } + public final void addFaceupCommand(final GameCommand c) { + faceupCommandList.add(c); + } + public final void addFacedownCommand(final GameCommand c) { + facedownCommandList.add(c); + } + public final void addChangeControllerCommand(final GameCommand c) { + changeControllerCommandList.add(c); + } public final void runLeavesPlayCommands() { for (final GameCommand c : leavePlayCommandList) { @@ -3286,22 +3289,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } leavePlayCommandList.clear(); } - - public final void addUntapCommand(final GameCommand c) { - untapCommandList.add(c); - } - - public final void addUnattachCommand(final GameCommand c) { - unattachCommandList.add(c); - } - - public final void addFaceupCommand(final GameCommand c) { - faceupCommandList.add(c); - } - - public final void addFacedownCommand(final GameCommand c) { - facedownCommandList.add(c); - } public final void runUntapCommands() { for (final GameCommand c : untapCommandList) { c.run(); @@ -3314,25 +3301,18 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } unattachCommandList.clear(); } - public final void runFaceupCommands() { for (final GameCommand c : faceupCommandList) { c.run(); } faceupCommandList.clear(); } - public final void runFacedownCommands() { for (final GameCommand c : facedownCommandList) { c.run(); } facedownCommandList.clear(); } - - public final void addChangeControllerCommand(final GameCommand c) { - changeControllerCommandList.add(c); - } - public final void runChangeControllerCommands() { for (final GameCommand c : changeControllerCommandList) { c.run(); @@ -3346,16 +3326,16 @@ public class Card extends GameEntity implements Comparable, IHasSVars { view.updateSickness(this); } - public final boolean isFirstTurnControlled() { - return sickness; - } - public final boolean hasSickness() { return sickness && !hasKeyword(Keyword.HASTE); } public final boolean isSick() { - return sickness && isCreature() && !hasKeyword(Keyword.HASTE); + return hasSickness() && isCreature(); + } + + public final boolean isFirstTurnControlled() { + return sickness; } public boolean hasBecomeTargetThisTurn() { @@ -5070,7 +5050,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { getGame().getTriggerHandler().runTrigger(TriggerType.PhaseOut, runParams, false); // when it doesn't exist the game will no longer see it as tapped runUntapCommands(); - // TODO need to run UntilHostLeavesPlay commands but only when worded "for as long as" + // TODO CR 702.26f need to run LeavesPlay + changeController commands but only when worded "for as long as" } setPhasedOut(!phasedOut); diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index e4bf85331e9..479e7439b03 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -305,7 +305,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable Date: Tue, 22 Nov 2022 20:11:57 +0100 Subject: [PATCH 20/24] Update zask_skittering_swarmlord.txt --- .../res/cardsfolder/upcoming/zask_skittering_swarmlord.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt b/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt index ba70ad7c65e..2baf77fcc63 100644 --- a/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt +++ b/forge-gui/res/cardsfolder/upcoming/zask_skittering_swarmlord.txt @@ -2,8 +2,8 @@ Name:Zask, Skittering Swarmlord ManaCost:3 G G Types:Legendary Creature Insect PT:5/5 -S:Mode$ Continuous | Affected$ Land.YouOwn,Insect.YouOwn | MayPlay$ True | AffectedZone$ Graveyard | Description$ You may play lands and cast Insect spells from your graveyard. -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Insect.YouCtrl | Execute$ TrigChange | TriggerDescription$ Whenever another Insect you control dies, put it on the bottom of its owner's library, then mill two cards. (Put the top two cards of your library into your graveyard.) +S:Mode$ Continuous | Affected$ Land.YouOwn,Insect.YouOwn | MayPlay$ True | AffectedZone$ Graveyard | Description$ You may play lands and cast Insect spells from your graveyard.o +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Insect.YouCtrl+Other | Execute$ TrigChange | TriggerDescription$ Whenever another Insect you control dies, put it on the bottom of its owner's library, then mill two cards. (Put the top two cards of your library into your graveyard.) SVar:TrigChange:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Library | LibraryPosition$ -1 | SubAbility$ DBMill SVar:DBMill:DB$ Mill | NumCards$ 2 A:AB$ Pump | Cost$ 1 BG | ValidTgts$ Insect | NumAtt$ 1 | KW$ Deathtouch | SpellDescription$ Target Insect gets +1/+0 and gains deathtouch until end of turn. From 966a951a5e15396e484c6f517ed22f7b23facf47 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 23 Nov 2022 06:43:55 +0800 Subject: [PATCH 21/24] update SaveLoadScene - save player location name --- .../src/forge/adventure/scene/DuelScene.java | 20 ------------- .../src/forge/adventure/scene/GameScene.java | 27 ++++++++++++++++- .../forge/adventure/scene/SaveLoadScene.java | 30 ++++++++++++++++--- .../src/forge/screens/match/MatchScreen.java | 4 +-- .../res/adventure/Shandalar/ui/save_load.json | 4 +-- .../Shandalar/ui/save_load_portrait.json | 4 +-- 6 files changed, 58 insertions(+), 31 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java index df955d63e40..beb9aeef972 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/DuelScene.java @@ -8,16 +8,13 @@ import forge.Graphics; import forge.LobbyPlayer; import forge.adventure.character.EnemySprite; import forge.adventure.character.PlayerSprite; -import forge.adventure.data.BiomeData; import forge.adventure.data.EffectData; import forge.adventure.data.EnemyData; import forge.adventure.data.ItemData; import forge.adventure.player.AdventurePlayer; import forge.adventure.stage.IAfterMatch; -import forge.adventure.stage.MapStage; import forge.adventure.util.Config; import forge.adventure.util.Current; -import forge.adventure.world.World; import forge.assets.FBufferedImage; import forge.assets.FSkin; import forge.deck.Deck; @@ -343,23 +340,6 @@ public class DuelScene extends ForgeScene { this.AIExtras.clear(); this.playerExtras.clear(); } - public String getCurrentLocation() { - String location = ""; - if(MapStage.getInstance().isInMap()) - location = TileMapScene.instance().rootPoint.getData().type; - else { - World world= Current.world(); - int currentBiome = World.highestBiome(world.getBiome((int) player.getX() / world.getTileSize(), (int) player.getY() / world.getTileSize())); - List biomeData = Current.world().getData().GetBiomes(); - try { - BiomeData data = biomeData.get(currentBiome); - location = data.name; - } catch (Exception e) { - e.printStackTrace(); - } - } - return location; - } private String selectAI(String ai) { //Decide opponent AI. String AI = ""; //Use user settings if it's null. diff --git a/forge-gui-mobile/src/forge/adventure/scene/GameScene.java b/forge-gui-mobile/src/forge/adventure/scene/GameScene.java index 595bf49453c..1698182a286 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/GameScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/GameScene.java @@ -3,8 +3,15 @@ package forge.adventure.scene; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import forge.Forge; +import forge.adventure.character.PlayerSprite; +import forge.adventure.data.BiomeData; import forge.adventure.stage.MapStage; import forge.adventure.stage.WorldStage; +import forge.adventure.util.Current; +import forge.adventure.world.World; +import forge.util.TextUtil; + +import java.util.List; /** * Game scene main over world scene @@ -51,6 +58,24 @@ public class GameScene extends HudScene { super.enter(); WorldStage.getInstance().handlePointsOfInterestCollision(); } - + public String getAdventurePlayerLocation(boolean forHeader) { + String location = ""; + if(MapStage.getInstance().isInMap()) { + location = forHeader? TileMapScene.instance().rootPoint.getData().name : TileMapScene.instance().rootPoint.getData().type; + } else { + World world= Current.world(); + PlayerSprite player = WorldStage.getInstance().getPlayerSprite(); + int currentBiome = World.highestBiome(world.getBiome((int) player.getX() / world.getTileSize(), (int) player.getY() / world.getTileSize())); + List biomeData = Current.world().getData().GetBiomes(); + try { + BiomeData data = biomeData.get(currentBiome); + location = forHeader? TextUtil.capitalize(data.name)+" Map" : data.name; + } catch (Exception e) { + e.printStackTrace(); + location = ""; + } + } + return location; + } } diff --git a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java index aa0b94103c1..d5aee9b6aa5 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java @@ -21,6 +21,7 @@ import forge.adventure.util.Current; import forge.adventure.world.WorldSave; import forge.adventure.world.WorldSaveHeader; import forge.screens.TransitionScreen; +import forge.util.TextUtil; import java.io.File; import java.io.FileInputStream; @@ -42,7 +43,7 @@ public class SaveLoadScene extends UIScene { TextraLabel header; int currentSlot = 0, lastSelectedSlot = 0; Image previewImage; - TextraLabel previewDate; + TextraLabel previewDate, playerLocation; Image previewBorder; TextraButton saveLoadButton, back; Selectable quickSave; @@ -50,6 +51,7 @@ public class SaveLoadScene extends UIScene { Actor lastHighlightedSave; SelectBox difficulty; ScrollPane scrollPane; + char ASCII_179 = '│'; private SaveLoadScene() { super(Forge.isLandscapeMode() ? "ui/save_load.json" : "ui/save_load_portrait.json"); @@ -68,9 +70,13 @@ public class SaveLoadScene extends UIScene { //DifficultyData difficulty1 = Config.instance().getConfigData().difficulties[difficulty.getSelectedIndex()]; return null; }); - previewImage = ui.findActor("preview"); previewDate = ui.findActor("saveDate"); + playerLocation = Controls.newTextraLabel(""); + playerLocation.setText(""); + playerLocation.setX(previewImage.getX()); + playerLocation.setY(previewImage.getY()+5); + ui.addActor(playerLocation); header = Controls.newTextraLabel(Forge.getLocalizer().getMessage("lblSave")); header.setAlignment(Align.center); layout.add(header).pad(2).colspan(4).align(Align.center).expandX(); @@ -172,6 +178,16 @@ public class SaveLoadScene extends UIScene { previewDate.setText(DateFormat.getDateInstance().format(header.saveDate) + "\n" + DateFormat.getTimeInstance(DateFormat.SHORT).format(header.saveDate)); else previewDate.setText(""); + if (header.name.contains(Character.toString(ASCII_179))) { + String[] split = TextUtil.split(header.name, ASCII_179); + try { + playerLocation.setText(split[1]); + } catch (Exception e) { + playerLocation.setText(""); + } + } else { + playerLocation.setText(""); + } } } else { if (previewImage != null) @@ -239,7 +255,7 @@ public class SaveLoadScene extends UIScene { public void save() { - if (WorldSave.getCurrentSave().save(textInput.getText(), currentSlot)) { + if (WorldSave.getCurrentSave().save(textInput.getText()+ASCII_179+GameScene.instance().getAdventurePlayerLocation(true), currentSlot)) { updateFiles(); //ensure the dialog is hidden before switching @@ -275,7 +291,13 @@ public class SaveLoadScene extends UIScene { int slot = WorldSave.filenameToSlot(name.getName()); WorldSaveHeader header = (WorldSaveHeader) oos.readObject(); - buttons.get(slot).actor.setText(header.name); + if (header.name.contains(Character.toString(ASCII_179))) { + String[] split = TextUtil.split(header.name, ASCII_179); + buttons.get(slot).actor.setText(split[0]); + //playerLocation.setText(split[1]); + } else { + buttons.get(slot).actor.setText(header.name); + } previews.put(slot, header); } diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 92926f26f63..60c343330f1 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -4,7 +4,7 @@ import java.util.*; import java.util.Map.Entry; import com.badlogic.gdx.math.Vector2; -import forge.adventure.scene.DuelScene; +import forge.adventure.scene.GameScene; import forge.animation.ForgeAnimation; import forge.assets.FImage; import forge.card.CardImageRenderer; @@ -807,7 +807,7 @@ public class MatchScreen extends FScreen { FSkinTexture getBG() { if (Forge.isMobileAdventureMode) { //System.out.println("Adventure Location: "+DuelScene.instance().getCurrentLocation()); - switch(DuelScene.instance().getCurrentLocation()) { + switch(GameScene.instance().getAdventurePlayerLocation(false)) { case "green": return FSkinTexture.ADV_BG_FOREST; case "black": diff --git a/forge-gui/res/adventure/Shandalar/ui/save_load.json b/forge-gui/res/adventure/Shandalar/ui/save_load.json index dba74b8deeb..60d4dde5483 100644 --- a/forge-gui/res/adventure/Shandalar/ui/save_load.json +++ b/forge-gui/res/adventure/Shandalar/ui/save_load.json @@ -36,8 +36,8 @@ { "type": "Label", "name": "saveDate", - "x": 390, - "y": 125, + "x": 370, + "y": 28, "width": 86, "height": 32 }, diff --git a/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json b/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json index fc88558c579..397b785aef4 100644 --- a/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json +++ b/forge-gui/res/adventure/Shandalar/ui/save_load_portrait.json @@ -36,8 +36,8 @@ { "type": "Label", "name": "saveDate", - "x": 70, - "y": 40, + "x": 170, + "y": 8, "width": 96, "height": 16 }, From 0ff5b94923001cf7615669723d4f7a562a757abb Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 23 Nov 2022 07:15:18 +0800 Subject: [PATCH 22/24] update previewdate --- forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java | 2 +- forge-gui/res/adventure/Shandalar/ui/save_load.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java index d5aee9b6aa5..fa9436b5993 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java +++ b/forge-gui-mobile/src/forge/adventure/scene/SaveLoadScene.java @@ -175,7 +175,7 @@ public class SaveLoadScene extends UIScene { previewImage.setVisible(true); previewDate.setVisible(true); if (header.saveDate != null) - previewDate.setText(DateFormat.getDateInstance().format(header.saveDate) + "\n" + DateFormat.getTimeInstance(DateFormat.SHORT).format(header.saveDate)); + previewDate.setText("{Scale=98%}"+DateFormat.getDateInstance().format(header.saveDate) + " " + DateFormat.getTimeInstance(DateFormat.SHORT).format(header.saveDate)); else previewDate.setText(""); if (header.name.contains(Character.toString(ASCII_179))) { diff --git a/forge-gui/res/adventure/Shandalar/ui/save_load.json b/forge-gui/res/adventure/Shandalar/ui/save_load.json index 60d4dde5483..6f77b073af9 100644 --- a/forge-gui/res/adventure/Shandalar/ui/save_load.json +++ b/forge-gui/res/adventure/Shandalar/ui/save_load.json @@ -37,7 +37,7 @@ "type": "Label", "name": "saveDate", "x": 370, - "y": 28, + "y": 24, "width": 86, "height": 32 }, From a4277a6c5ba043005ddc9e8fe45e797f2189e53c Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 23 Nov 2022 10:49:28 +0800 Subject: [PATCH 23/24] update AdventureDeckEditor tab icons --- .../adventure/scene/AdventureDeckEditor.java | 34 ++++++++++++++++-- .../res/adventure/Shandalar/ui/maindeck.png | Bin 0 -> 19894 bytes .../res/adventure/Shandalar/ui/sideboard.png | Bin 0 -> 21631 bytes 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/adventure/Shandalar/ui/maindeck.png create mode 100644 forge-gui/res/adventure/Shandalar/ui/sideboard.png diff --git a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java index 3e7b671ddc7..65f6a04c58c 100644 --- a/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java +++ b/forge-gui-mobile/src/forge/adventure/scene/AdventureDeckEditor.java @@ -39,8 +39,38 @@ import java.util.HashMap; import java.util.Map; public class AdventureDeckEditor extends TabPageScreen { - public static FSkinImage MAIN_DECK_ICON = Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST; - public static FSkinImage SIDEBOARD_ICON = Forge.hdbuttons ? FSkinImage.HDSIDEBOARD : FSkinImage.FLASHBACK; + private static final FileHandle deckIcon = Config.instance().getFile("ui/maindeck.png"); + private static Texture deckTexture = deckIcon.exists() ? new Texture(deckIcon) : null; + private static FImage MAIN_DECK_ICON = deckIcon.exists() ? new FImage() { + @Override + public float getWidth() { + return 100f; + } + @Override + public float getHeight() { + return 100f; + } + @Override + public void draw(Graphics g, float x, float y, float w, float h) { + g.drawImage(deckTexture, x, y, w, h); + } + } : Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST; + private static final FileHandle sideIcon = Config.instance().getFile("ui/sideboard.png"); + private static Texture sideTexture = sideIcon.exists() ? new Texture(sideIcon) : null; + private static FImage SIDEBOARD_ICON = sideIcon.exists() ? new FImage() { + @Override + public float getWidth() { + return 100f; + } + @Override + public float getHeight() { + return 100f; + } + @Override + public void draw(Graphics g, float x, float y, float w, float h) { + g.drawImage(sideTexture, x, y, w, h); + } + } : Forge.hdbuttons ? FSkinImage.HDSIDEBOARD : FSkinImage.FLASHBACK; private static final float HEADER_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f); private static final FileHandle binderIcon = Config.instance().getFile("ui/binder.png"); private static Texture binderTexture = binderIcon.exists() ? new Texture(binderIcon) : null; diff --git a/forge-gui/res/adventure/Shandalar/ui/maindeck.png b/forge-gui/res/adventure/Shandalar/ui/maindeck.png new file mode 100644 index 0000000000000000000000000000000000000000..0c0316d584f59307ea0a41c78f7cb09808435030 GIT binary patch literal 19894 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 literal 0 HcmV?d00001 From da50f1f1f6ea4294238f280a324977b3e4b62b0c Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 23 Nov 2022 13:14:58 +0800 Subject: [PATCH 24/24] Update rodolf_duskbringer.txt fix crash --- forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt b/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt index a389dcb34fb..524e5634fc2 100644 --- a/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt +++ b/forge-gui/res/cardsfolder/upcoming/rodolf_duskbringer.txt @@ -9,8 +9,8 @@ T:Mode$ LifeGained | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ Tri SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Indestructible T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | Execute$ TrigImmediateTrig | TriggerDescription$ At the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ 1 WB | Execute$ TrigChangeZone | TriggerDescription$ When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. -SVar:TrigChangeZone:AB$ ChangeZone | ValidTgts$ Creature.cmcLEX+YouOwn | TgtPrompt$ Select target creature card with mana value X or less | Origin$ Graveyard | Destination$ Battlefield +SVar:TrigChangeZone:DB$ ChangeZone | ValidTgts$ Creature.cmcLEX+YouOwn | TgtPrompt$ Select target creature card with mana value X or less | Origin$ Graveyard | Destination$ Battlefield SVar:X:Count$LifeYouGainedThisTurn DeckHas:Ability$Graveyard|LifeGain & Keyword$indestructible DeckHints:Ability$Graveyard|LifeGain|Mill -Oracle:Flying, deathtouch, lifelink\nWhenever you gain life, Rodolf Duskbringer gains indestructible until end of turn.\nAt the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn. \ No newline at end of file +Oracle:Flying, deathtouch, lifelink\nWhenever you gain life, Rodolf Duskbringer gains indestructible until end of turn.\nAt the beginning of your end step, you may pay {1}{W/B}. When you do, return target creature with mana value X or less from your graveyard to the battlefield, where X is the amount of life you gained this turn.