From 624616e805eec7849e409b23a36a1a85e4b7f41e Mon Sep 17 00:00:00 2001 From: neomoth <69372252+neomoth@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:31:35 -0400 Subject: [PATCH] version 1.0 release --- NeoQOLPack/Mod.cs | 13 +- NeoQOLPack/Mods/ButtonSellPatcher.cs | 115 +++++++++ NeoQOLPack/Mods/InventoryItemPatcher.cs | 241 +++++++++++++++++- NeoQOLPack/Mods/ItemSelectPatcher.cs | 19 +- NeoQOLPack/Mods/PlayerHudPatcher.cs | 13 +- NeoQOLPack/Mods/ShopButtonPatcher.cs | 2 + NeoQOLPack/Mods/ShopCategoryPatcher.cs | 34 +++ NeoQOLPack/Mods/ShopPatcher.cs | 51 ++++ mods/NeoQOLPack/Assets/Textures/Lock.svg | 1 + .../Assets/Textures/Lock.svg.import | 35 +++ mods/NeoQOLPack/Scenes/HUD/InventoryLock.tscn | 29 +++ .../Scenes/HUD/Shop/button_sell_all.gd | 52 ++++ .../Scenes/HUD/Shop/button_sell_all.tscn | 39 +++ mods/NeoQOLPack/main.gd | 16 ++ mods/NeoQOLPack/test.gd | 3 + 15 files changed, 648 insertions(+), 15 deletions(-) create mode 100644 NeoQOLPack/Mods/ButtonSellPatcher.cs create mode 100644 NeoQOLPack/Mods/ShopCategoryPatcher.cs create mode 100644 mods/NeoQOLPack/Assets/Textures/Lock.svg create mode 100644 mods/NeoQOLPack/Assets/Textures/Lock.svg.import create mode 100644 mods/NeoQOLPack/Scenes/HUD/InventoryLock.tscn create mode 100644 mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.gd create mode 100644 mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.tscn create mode 100644 mods/NeoQOLPack/test.gd diff --git a/NeoQOLPack/Mod.cs b/NeoQOLPack/Mod.cs index aa684d7..026b54d 100644 --- a/NeoQOLPack/Mod.cs +++ b/NeoQOLPack/Mod.cs @@ -15,7 +15,7 @@ public class Mod : IMod public Config Config; public ILogger Logger; - private static readonly string versionTag = "Beta5"; + private static readonly string versionTag = "v1.0"; private static readonly string repo = "neomoth/NeoQOLPack"; private bool injectUpdateNotice = false; @@ -37,6 +37,8 @@ public Mod(IModInterface modInterface) { modInterface.RegisterScriptMod(new MenuPatcher(this, versionTag)); modInterface.RegisterScriptMod(new OptionsMenuPatcher()); modInterface.RegisterScriptMod(new EscMenuPatcher()); + modInterface.RegisterScriptMod(new ButtonSellPatcher()); + modInterface.RegisterScriptMod(new ShopCategoryPatcher()); if (injectUpdateNotice) ; } @@ -56,6 +58,15 @@ private async Task GetVersion() injectUpdateNotice = newVer > currVer; } + else + { + Version latest = new Version(latestVersion.StartsWith('v') ? latestVersion[1..] : latestVersion); + Version current = new Version(versionTag.StartsWith('v') ? versionTag[1..] : versionTag); + + int comparison = latest.CompareTo(current); + + injectUpdateNotice = comparison > 0; + } } catch (Exception e) { diff --git a/NeoQOLPack/Mods/ButtonSellPatcher.cs b/NeoQOLPack/Mods/ButtonSellPatcher.cs new file mode 100644 index 0000000..95e7865 --- /dev/null +++ b/NeoQOLPack/Mods/ButtonSellPatcher.cs @@ -0,0 +1,115 @@ +using GDWeave.Godot; +using GDWeave.Modding; +using GDWeave.Godot.Variants; + +namespace NeoQOLPack.Mods; + +public class ButtonSellPatcher : IScriptMod +{ + public bool ShouldRun(string path) => path == "res://Scenes/HUD/Shop/ShopButtons/button_sell.gdc"; + + public IEnumerable Modify(string path, IEnumerable tokens) + { + // when not waiting for this the error goes away but then i get another error saying "item" isn't valid in this scope at the same line number????? + MultiTokenWaiter setupItemWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken { Name: "_setup" }, + t => t is IdentifierToken { Name: "slot_desc" }, + t => t.Type is TokenType.Newline + ], allowPartialMatch: true); + + // i thought maybe i wasn't getting the right spot? no fucking clue + MultiTokenWaiter customUpdateWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken { Name: "_custom_update" }, + t => t is IdentifierToken { Name: "linked_ref" }, + t => t is IdentifierToken { Name: "has" }, + t => t.Type is TokenType.OpAssign, + t => t is ConstantToken { Value: BoolVariant { Value: true } }, + t => t.Type is TokenType.Newline + ], allowPartialMatch: true); + + MultiTokenWaiter customPurchaseWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken { Name: "_custom_purchase" }, + t => t is IdentifierToken { Name: "linked_ref" }, + t => t.Type is TokenType.Newline + ], allowPartialMatch: true); + + foreach (Token token in tokens) + { + if (setupItemWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.PrVar); + yield return new IdentifierToken("item"); + yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("PlayerData"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("_find_item_code"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new IdentifierToken("linked_ref"); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("item"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 2); + yield return new IdentifierToken("locked"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(true)); + yield return new Token(TokenType.Newline, 2); + yield return new IdentifierToken("slot_desc"); + yield return new Token(TokenType.OpAssignAdd); + yield return new ConstantToken(new StringVariant("\n[color=red]This item is locked and cannot be sold.[/color]")); + + yield return new Token(TokenType.Newline); + } + else if (customUpdateWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.Newline, 3); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("item"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 4); + yield return new IdentifierToken("locked"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(true)); + + yield return new Token(TokenType.Newline, 1); + } + else if (customPurchaseWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.PrVar); + yield return new IdentifierToken("item"); + yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("PlayerData"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("_find_item_code"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new IdentifierToken("linked_ref"); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("item"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("locked"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 2); + yield return new Token(TokenType.CfReturn); + + yield return new Token(TokenType.Newline, 1); + } + else yield return token; + } + } +} \ No newline at end of file diff --git a/NeoQOLPack/Mods/InventoryItemPatcher.cs b/NeoQOLPack/Mods/InventoryItemPatcher.cs index 90864a7..eb5144b 100644 --- a/NeoQOLPack/Mods/InventoryItemPatcher.cs +++ b/NeoQOLPack/Mods/InventoryItemPatcher.cs @@ -10,24 +10,38 @@ public class InventoryItemPatcher(Mod mod) : IScriptMod public IEnumerable Modify(string path, IEnumerable tokens) { - MultiTokenWaiter varWaiter = new([ + MultiTokenWaiter extendsWaiter = new MultiTokenWaiter([ t => t.Type is TokenType.PrExtends, t => t.Type is TokenType.Newline, ], allowPartialMatch: true); - //hotkey_panel.visible = hotkey.size() > 0 - MultiTokenWaiter updateWaiter = new([ + + MultiTokenWaiter readyWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken { Name: "_ready" }, + t => t.Type is TokenType.Newline + ], allowPartialMatch: true); + + MultiTokenWaiter updateWaiter = new MultiTokenWaiter([ t => t.Type is TokenType.PrFunction, t => t is IdentifierToken { Name: "_update" }, t => t is IdentifierToken { Name: "hotkey_panel" }, t => t is IdentifierToken { Name: "visible" }, t => t.Type is TokenType.Newline, ], allowPartialMatch: true); - // this is unfinished ^^^ + + MultiTokenWaiter setupWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken { Name: "_setup_item" }, + t => t is IdentifierToken { Name: "ref" } + ], allowPartialMatch: true); + + MultiTokenWaiter setupBodyWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken { Name: "_setup_item" }, + t => t.Type is TokenType.Newline + ], allowPartialMatch: true); + foreach (Token token in tokens) { - if (varWaiter.Check(token)) + if (extendsWaiter.Check(token)) { - // mod.Logger.Information("#################### FOUND VAR SPOT ######################"); // C yield return token; yield return new Token(TokenType.PrVar); @@ -48,10 +62,127 @@ public IEnumerable Modify(string path, IEnumerable tokens) yield return new ConstantToken(new StringVariant("root")); yield return new Token(TokenType.ParenthesisClose); yield return new Token(TokenType.Newline); + yield return new Token(TokenType.PrOnready); + yield return new Token(TokenType.PrVar); + yield return new IdentifierToken("locked_panel"); + yield return new Token(TokenType.OpAssign); + yield return new Token(TokenType.Dollar); + yield return new ConstantToken(new StringVariant("/root/NeoQOLPack")); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("_attach_lock"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new Token(TokenType.Self); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline); + yield return new Token(TokenType.PrVar); + yield return new IdentifierToken("is_on_hotbar"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(false)); + yield return new Token(TokenType.Newline); + + yield return new Token(TokenType.PrFunction); + yield return new IdentifierToken("_on_item_gui_input"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new IdentifierToken("event"); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("is_on_hotbar"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.CfReturn); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.PrVar); + yield return new IdentifierToken("idata"); + yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("PlayerData"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("_find_item_code"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new IdentifierToken("saved_ref"); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfIf); + yield return new Token(TokenType.OpNot); + yield return new IdentifierToken("Globals"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("item_data"); + yield return new Token(TokenType.BracketOpen); + yield return new IdentifierToken("idata"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("id")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("file")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("can_be_sold"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.CfReturn); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("event"); + yield return new Token(TokenType.PrIs); + yield return new IdentifierToken("InputEventMouseButton"); + yield return new Token(TokenType.OpAnd); + yield return new IdentifierToken("event"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("pressed"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 2); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("event"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("button_index"); + yield return new Token(TokenType.OpEqual); + yield return new IdentifierToken("BUTTON_RIGHT"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 3); + yield return new IdentifierToken("idata"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.OpAssign); + yield return new Token(TokenType.OpNot); + yield return new IdentifierToken("idata"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.Newline, 3); + yield return new IdentifierToken("GlobalAudio"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("_play_sound"); + // yield return new IdentifierToken("emit_signal"); + yield return new Token(TokenType.ParenthesisOpen); + // yield return new ConstantToken(new StringVariant("_play_sfx")); + // yield return new Token(TokenType.Comma); + yield return new ConstantToken(new StringVariant("tb_close")); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline, 3); + yield return new IdentifierToken("_update"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline); + } + else if (readyWaiter.Check(token)) + { + yield return token; + + // yield return new IdentifierToken("owner"); + // yield return new Token(TokenType.Period); + yield return new IdentifierToken("connect"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new ConstantToken(new StringVariant("gui_input")); + yield return new Token(TokenType.Comma); + yield return new Token(TokenType.Self); + yield return new Token(TokenType.Comma); + yield return new ConstantToken(new StringVariant("_on_item_gui_input")); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline, 1); } else if (updateWaiter.Check(token)) { - // mod.Logger.Information("#################### FOUND UPDATE FUNC ######################"); // C yield return token; yield return new Token(TokenType.Newline, 1); @@ -66,6 +197,102 @@ public IEnumerable Modify(string path, IEnumerable tokens) yield return new Token(TokenType.Comma); yield return new IdentifierToken("stack_size"); yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfIf); + yield return new Token(TokenType.OpNot); + yield return new IdentifierToken("is_on_hotbar"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 2); + yield return new IdentifierToken("locked_panel"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("visible"); + yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("idata"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.Newline, 2); + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("data"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("can_be_sold"); + yield return new Token(TokenType.Colon); + yield return new Token(TokenType.Newline, 3); + yield return new Token(TokenType.CfIf); + yield return new Token(TokenType.OpNot); + yield return new IdentifierToken("idata"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + yield return new Token(TokenType.Colon); + yield return new IdentifierToken("desc"); + yield return new Token(TokenType.OpAssignAdd); + yield return new ConstantToken(new StringVariant("\n[color=#b48141](Right click to prevent item from being sold)[/color]")); + yield return new Token(TokenType.Newline, 3); + yield return new Token(TokenType.CfElse); + yield return new Token(TokenType.Colon); + yield return new IdentifierToken("desc"); + yield return new Token(TokenType.OpAssignAdd); + yield return new ConstantToken(new StringVariant("\n[color=#b48141](Right click to allow item to be sold)[/color]")); + yield return new Token(TokenType.Newline, 1); + yield return new Token(TokenType.CfElse); + yield return new Token(TokenType.Colon); + yield return new IdentifierToken("locked_panel"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("visible"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(false)); + yield return new Token(TokenType.Newline, 1); + + //$root / tooltip_node.body = desc + sizetext + worthtext + yield return new Token(TokenType.Dollar); + yield return new ConstantToken(new StringVariant("root/tooltip_node")); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("body"); + yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("desc"); + yield return new Token(TokenType.OpAdd); + yield return new IdentifierToken("sizetext"); + yield return new Token(TokenType.OpAdd); + yield return new IdentifierToken("worthtext"); + yield return new Token(TokenType.Newline, 1); + + //Tooltip._update($root/tooltip_node.header, $root/tooltip_node.body, null) + yield return new IdentifierToken("Tooltip"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("_update"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new Token(TokenType.Dollar); + yield return new ConstantToken(new StringVariant("root/tooltip_node")); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("header"); + yield return new Token(TokenType.Comma); + yield return new Token(TokenType.Dollar); + yield return new ConstantToken(new StringVariant("root/tooltip_node")); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("body"); + yield return new Token(TokenType.Comma); + yield return new ConstantToken(new NilVariant()); + yield return new Token(TokenType.ParenthesisClose); + } + else if (setupWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.Comma); + yield return new IdentifierToken("hotbar"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(false)); + } + else if (setupBodyWaiter.Check(token)) + { + yield return token; + + yield return new IdentifierToken("is_on_hotbar"); + yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("hotbar"); + + yield return new Token(TokenType.Newline, 1); } else { diff --git a/NeoQOLPack/Mods/ItemSelectPatcher.cs b/NeoQOLPack/Mods/ItemSelectPatcher.cs index 7b18195..873a16a 100644 --- a/NeoQOLPack/Mods/ItemSelectPatcher.cs +++ b/NeoQOLPack/Mods/ItemSelectPatcher.cs @@ -10,6 +10,9 @@ public class ItemSelectPatcher(Mod mod) : IScriptMod public IEnumerable Modify(string path, IEnumerable tokens) { + MultiTokenWaiter unselectableWaiter = new MultiTokenWaiter([ + t => t is IdentifierToken {Name: "unselectable"} + ], allowPartialMatch: true); MultiTokenWaiter addWaiter = new ([ t => t is IdentifierToken {Name: "_ready"}, t => t.Type == TokenType.PrVar, @@ -21,12 +24,6 @@ public IEnumerable Modify(string path, IEnumerable tokens) { if (addWaiter.Check(token)) { - for (var i = 0; i < 20; i++) - { - mod.Logger.Information("PENIS"); - } - - // mod.Logger.Information("#################### FOUND ADD FUNC ######################"); yield return token; yield return new IdentifierToken("i"); @@ -36,6 +33,16 @@ public IEnumerable Modify(string path, IEnumerable tokens) yield return new ConstantToken(new BoolVariant(true)); yield return new Token(TokenType.Newline, 2); } + else if (unselectableWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.OpOr); + yield return new IdentifierToken("item"); + yield return new Token(TokenType.BracketOpen); + yield return new ConstantToken(new StringVariant("locked")); + yield return new Token(TokenType.BracketClose); + } else yield return token; } } diff --git a/NeoQOLPack/Mods/PlayerHudPatcher.cs b/NeoQOLPack/Mods/PlayerHudPatcher.cs index 495f2db..fc86dfb 100644 --- a/NeoQOLPack/Mods/PlayerHudPatcher.cs +++ b/NeoQOLPack/Mods/PlayerHudPatcher.cs @@ -16,12 +16,16 @@ public IEnumerable Modify(string path, IEnumerable tokens) t=>t.Type is TokenType.Colon, t => t.Type is TokenType.Newline ], allowPartialMatch: false); + + MultiTokenWaiter setupItemWaiter = new MultiTokenWaiter([ + t=>t is IdentifierToken {Name: "_setup_item"}, + t=>t.Type is TokenType.BracketClose + ], allowPartialMatch: true); foreach (Token token in tokens) { if (chatWaiter.Check(token)) { - mod.Logger.Debug("HIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"); yield return token; yield return new Token(TokenType.Newline, 4); yield return new ConstantToken(new StringVariant("/iamweest")); @@ -52,6 +56,13 @@ public IEnumerable Modify(string path, IEnumerable tokens) yield return new Token(TokenType.ParenthesisClose); yield return new Token(TokenType.Newline, 4); } + else if (setupItemWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.Comma); + yield return new ConstantToken(new BoolVariant(true)); + } else yield return token; } } diff --git a/NeoQOLPack/Mods/ShopButtonPatcher.cs b/NeoQOLPack/Mods/ShopButtonPatcher.cs index de3ce0a..9023063 100644 --- a/NeoQOLPack/Mods/ShopButtonPatcher.cs +++ b/NeoQOLPack/Mods/ShopButtonPatcher.cs @@ -33,6 +33,8 @@ public IEnumerable Modify(string path, IEnumerable tokens) yield return new Token(TokenType.Period); yield return new IdentifierToken("text"); yield return new Token(TokenType.OpAssign); + yield return new IdentifierToken("prefix"); + yield return new Token(TokenType.OpAdd); yield return new IdentifierToken("get_node"); yield return new Token(TokenType.ParenthesisOpen); yield return new ConstantToken(new StringVariant("/root/NeoQOLPack")); diff --git a/NeoQOLPack/Mods/ShopCategoryPatcher.cs b/NeoQOLPack/Mods/ShopCategoryPatcher.cs new file mode 100644 index 0000000..4fc339c --- /dev/null +++ b/NeoQOLPack/Mods/ShopCategoryPatcher.cs @@ -0,0 +1,34 @@ +using GDWeave.Godot; +using GDWeave.Godot.Variants; +using GDWeave.Modding; + +namespace NeoQOLPack.Mods; + +public class ShopCategoryPatcher : IScriptMod +{ + public bool ShouldRun(string path) => path == "res://Scenes/HUD/Shop/ShopSetups/shop_category.gdc"; + + public IEnumerable Modify(string path, IEnumerable tokens) + { + MultiTokenWaiter extendsWaiter = new MultiTokenWaiter([ + t => t.Type is TokenType.PrExtends, + t => t.Type is TokenType.Newline + ], allowPartialMatch: true); + + foreach (Token token in tokens) + { + if (extendsWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.PrVar); + yield return new IdentifierToken("show_sellall"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(false)); + + yield return new Token(TokenType.Newline); + } + else yield return token; + } + } +} \ No newline at end of file diff --git a/NeoQOLPack/Mods/ShopPatcher.cs b/NeoQOLPack/Mods/ShopPatcher.cs index 509abcd..a6d8c9d 100644 --- a/NeoQOLPack/Mods/ShopPatcher.cs +++ b/NeoQOLPack/Mods/ShopPatcher.cs @@ -16,6 +16,17 @@ public IEnumerable Modify(string path, IEnumerable tokens) t => t.Type is TokenType.Newline ], allowPartialMatch: true); + MultiTokenWaiter collapseWaiter = new MultiTokenWaiter([ + t=>t.Type is TokenType.CfIf, + t=>t.Type is TokenType.OpNot, + t=>t is IdentifierToken {Name:"node"}, + t=>t.Type is TokenType.Period, + t=>t is IdentifierToken {Name:"collapse"}, + t=>t.Type is TokenType.Colon, + t=>t is IdentifierToken {Name:"add_child"}, + t=>t.Type is TokenType.Newline, + ], allowPartialMatch: true); + //if(node.name=="titles"): get_node("/root/Main")._append_shop_buttons(grid,self) foreach (Token token in tokens) { @@ -46,6 +57,46 @@ public IEnumerable Modify(string path, IEnumerable tokens) yield return new Token(TokenType.Newline, 2); } + else if (collapseWaiter.Check(token)) + { + yield return token; + + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("node"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("name"); + yield return new Token(TokenType.OpEqual); + yield return new ConstantToken(new StringVariant("sell")); + yield return new Token(TokenType.Colon); + yield return new IdentifierToken("node"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("show_sellall"); + yield return new Token(TokenType.OpAssign); + yield return new ConstantToken(new BoolVariant(true)); + yield return new Token(TokenType.Newline, 2); + + yield return new Token(TokenType.CfIf); + yield return new IdentifierToken("node"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("show_sellall"); + yield return new Token(TokenType.Colon); + yield return new IdentifierToken("lbl"); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("add_child"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new Token(TokenType.PrPreload); + yield return new Token(TokenType.ParenthesisOpen); + yield return new ConstantToken( + new StringVariant("res://mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.tscn")); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.Period); + yield return new IdentifierToken("instance"); + yield return new Token(TokenType.ParenthesisOpen); + yield return new Token(TokenType.ParenthesisClose); + yield return new Token(TokenType.ParenthesisClose); + + yield return new Token(TokenType.Newline, 2); + } else yield return token; } } diff --git a/mods/NeoQOLPack/Assets/Textures/Lock.svg b/mods/NeoQOLPack/Assets/Textures/Lock.svg new file mode 100644 index 0000000..2d17af3 --- /dev/null +++ b/mods/NeoQOLPack/Assets/Textures/Lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mods/NeoQOLPack/Assets/Textures/Lock.svg.import b/mods/NeoQOLPack/Assets/Textures/Lock.svg.import new file mode 100644 index 0000000..39edf71 --- /dev/null +++ b/mods/NeoQOLPack/Assets/Textures/Lock.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Lock.svg-aa6c3f612319f0385e8dac9dfc3e2b95.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://mods/NeoQOLPack/Assets/Textures/Lock.svg" +dest_files=[ "res://.import/Lock.svg-aa6c3f612319f0385e8dac9dfc3e2b95.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=1 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/mods/NeoQOLPack/Scenes/HUD/InventoryLock.tscn b/mods/NeoQOLPack/Scenes/HUD/InventoryLock.tscn new file mode 100644 index 0000000..c5d58c3 --- /dev/null +++ b/mods/NeoQOLPack/Scenes/HUD/InventoryLock.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://Assets/Themes/panel_green.tres" type="StyleBox" id=1] +[ext_resource path="res://mods/NeoQOLPack/Assets/Textures/Lock.svg" type="Texture" id=2] + +[node name="Panel2" type="Panel"] +modulate = Color( 0.831373, 0.494118, 0.494118, 0.439216 ) +anchor_right = 0.046 +anchor_bottom = 0.083 +margin_left = 6.0 +margin_top = 6.0 +margin_right = -4.32001 +margin_bottom = -5.64001 +mouse_filter = 2 +custom_styles/panel = ExtResource( 1 ) +__meta__ = { +"_edit_group_": true +} + +[node name="TextureRect2" type="TextureRect" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 17.0 +margin_top = 17.0 +margin_right = -17.0 +margin_bottom = -17.0 +mouse_filter = 2 +texture = ExtResource( 2 ) +expand = true diff --git a/mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.gd b/mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.gd new file mode 100644 index 0000000..e3d4e06 --- /dev/null +++ b/mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.gd @@ -0,0 +1,52 @@ +extends Button + +var total_price = 0 +var tooltip: TooltipNode + +func _ready(): + tooltip = $TooltipNode + _refresh_price() + + + +func _refresh_price(): + var current_price = 0 + for item in PlayerData.inventory: + var file = Globals.item_data[item["id"]]["file"] + if file.unselectable or not file.can_be_sold or item["locked"]: continue + current_price+=PlayerData._get_item_worth(item["ref"]) + total_price = current_price + if total_price < 1: + tooltip.body = "You have no sellable items." + disabled = true + else: + tooltip.body = "This will sell every sellable item you have for about [color=green]$"+str(total_price)+"[/color]." + disabled = false + Tooltip._update(tooltip.header,tooltip.body,null) + + +func _on_Button2_mouse_entered(): + _refresh_price() + + +func _on_Button2_pressed(): + var items = [] + PlayerData.emit_signal("_play_sfx", "cash" + str(randi() % 2 + 1)) + for item in PlayerData.inventory: + var file = Globals.item_data[item["id"]]["file"] + if file.unselectable or not file.can_be_sold or item["locked"]: continue + items.push_back(item) + for key in PlayerData.hotbar.keys(): + if PlayerData.hotbar[key] == item["ref"]: PlayerData.hotbar[key] = 0 + + for item in items: + var ref = item["ref"] + PlayerData.money+=PlayerData._get_item_worth(item["ref"]) + PlayerData.inventory.erase(item) + PlayerData.emit_signal("_item_sold", ref) + PlayerData.emit_signal("_item_removal", ref) + + PlayerData.emit_signal("_shop_update") + PlayerData.emit_signal("_inventory_refresh") + PlayerData.emit_signal("_hotbar_refresh") + _refresh_price() diff --git a/mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.tscn b/mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.tscn new file mode 100644 index 0000000..3161d9e --- /dev/null +++ b/mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.tscn @@ -0,0 +1,39 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://Scenes/Singletons/Tooltips/tooltip_node.gd" type="Script" id=1] +[ext_resource path="res://Assets/Themes/main.tres" type="Theme" id=2] +[ext_resource path="res://mods/NeoQOLPack/Scenes/HUD/Shop/button_sell_all.gd" type="Script" id=3] + +[node name="Button2" type="Button"] +margin_left = 741.0 +margin_top = 13.0 +margin_right = 842.0 +margin_bottom = 51.0 +theme = ExtResource( 2 ) +align = 0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_group_": true +} + +[node name="TooltipNode" type="Control" parent="."] +margin_left = -2.0 +margin_right = 103.0 +margin_bottom = 38.0 +script = ExtResource( 1 ) +header = "Sell All Items" +body = "This will sell every sellable item you have for about [color=green]$x[/color]." + +[node name="Label" type="RichTextLabel" parent="."] +margin_left = 7.0 +margin_top = 2.0 +margin_right = 92.0 +margin_bottom = 36.0 +mouse_filter = 2 +bbcode_enabled = true +bbcode_text = "[center][color=white]sell all[/color][/center]" +text = "sell all" +scroll_active = false + +[connection signal="mouse_entered" from="." to="." method="_on_Button2_mouse_entered"] +[connection signal="pressed" from="." to="." method="_on_Button2_pressed"] diff --git a/mods/NeoQOLPack/main.gd b/mods/NeoQOLPack/main.gd index 3cde09d..400b0ae 100644 --- a/mods/NeoQOLPack/main.gd +++ b/mods/NeoQOLPack/main.gd @@ -7,6 +7,7 @@ extends Node func _ready(): print("loaded") _load_mod_resources() + var a = preload("res://mods/NeoQOLPack/test.gd") func _append_version(parent,version = "unknown"): print("attaching label...") @@ -55,6 +56,21 @@ static func _attach_stack_size(parent): #print(parent) return stack_size_label +static func _attach_lock(parent): + var lock_icon: Panel = preload("res://mods/NeoQOLPack/Scenes/HUD/InventoryLock.tscn").instance() + parent.add_child(lock_icon) + lock_icon.margin_left = 6 + lock_icon.margin_top = 6 + lock_icon.margin_right = -6 + lock_icon.margin_bottom = -6 + lock_icon.rect_position = Vector2(6,6) + lock_icon.rect_size = Vector2(78,78) + lock_icon.anchor_left = 0 + lock_icon.anchor_top = 0 + lock_icon.anchor_right = 0.046 + lock_icon.anchor_bottom = 0.083 + return lock_icon + static func _append_entry(entry): print("######################## APPENDING ENTRY ########################") #"locked": locked, "stack_size": 0, "stacked": false diff --git a/mods/NeoQOLPack/test.gd b/mods/NeoQOLPack/test.gd new file mode 100644 index 0000000..725d8a6 --- /dev/null +++ b/mods/NeoQOLPack/test.gd @@ -0,0 +1,3 @@ +extends Node +var a = null +