From 8efb880e2b54f58e7ed5c562eb423977d12f6347 Mon Sep 17 00:00:00 2001 From: Thanatos Date: Sun, 2 Jun 2024 10:52:18 +0200 Subject: [PATCH 1/3] Add async popup windows --- .../files/custom/guilib.lua | 142 +++++++++++++++--- .../files/custom/queue.lua | 39 +++++ .../files/custom/scenario.lua | 57 ++++++- .../templates/randomizer_item_template.lua | 2 +- src/open_samus_returns_rando/lua_editor.py | 6 + 5 files changed, 223 insertions(+), 23 deletions(-) create mode 100644 src/open_samus_returns_rando/files/custom/queue.lua diff --git a/src/open_samus_returns_rando/files/custom/guilib.lua b/src/open_samus_returns_rando/files/custom/guilib.lua index 58a80e9..c52a142 100644 --- a/src/open_samus_returns_rando/files/custom/guilib.lua +++ b/src/open_samus_returns_rando/files/custom/guilib.lua @@ -1,6 +1,12 @@ GUILib = GUILib or {} +function GUILib.InitCustomUI() + GUILib.AddDNACounter() + GUILib.AddMessageBox() +end + + function GUILib.AddDNACounter() local randoUI = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.LowerComposition.LowerInfoComposition.DNAMechIconRando") if randoUI ~= nil then @@ -16,45 +22,27 @@ function GUILib.AddDNACounter() ScaleX = "1.00000", ScaleY = "1.00000", Angle = "0.00000", - FlipX = false, - FlipY = false, - Enabled = true, Visible = true, SkinItemType = "", Autosize = false, - SpriteSheetItem = "IconL_MetroidDNAData", - BlendMode = "AlphaBlend", - USelMode = "Scale", - VSelMode = "Scale" + SpriteSheetItem = "IconL_MetroidDNAData" }))) lowerInfo:AddChild((GUI.CreateDisplayObjectEx("DNAMechCounterRando", "CText", { X = "0.24688", Y = "0.02500", SizeX = "0.12499", SizeY = "0.05833", - ScaleX = "1.00000", - ScaleY = "1.00000", - Angle = "0.00000", - FlipX = false, - FlipY = false, ColorR = "0.68000", ColorG = "0.83000", ColorB = "0.93000", ColorA = "1.00000", Enabled = true, Visible = true, - SkinItemType = "", Text = "10 / 10", Font = "digital_hefty", TextAlignment = "Left", Autosize = true, - Outline = true, - EmbeddedSpritesSuffix = "", - BlinkColorR = "1.00000", - BlinkColorG = "1.00000", - BlinkColorB = "1.00000", - BlinkAlpha = "1.00000", - Blink = "-1.00000" + Outline = true }))) local dnaCounterVanilla = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.LowerComposition.LowerInfoComposition.DNAMechCounter") local dnaIconVanilla = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.LowerComposition.LowerInfoComposition.DNAMechIcon") @@ -86,4 +74,118 @@ function GUILib.UpdateTotalDNAColor() ColorB = "0.93000", }) end +end + +function GUILib.AddMessageBox() + local randoUI = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.USSEF.Outer") + if randoUI ~= nil then + return + end + local ussef = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.USSEF") + local outer = GUI.CreateDisplayObjectEx("Outer", "CDisplayObjectContainer", { + StageID = "Up", + X = "0.0", + Y = "0.822", + ScaleX="2.16", + ScaleY="2.0", + Visible = false + }) + local topL = GUI.CreateDisplayObjectEx("TopL", "CSprite", { + X = "0.0", + Y = "0.0", + Visible = true, + SpriteSheetItem = "TutorialWindowTop" + }) + local topR = GUI.CreateDisplayObjectEx("TopR", "CSprite", { + X = "0.0", + Y = "0.0", + FlipX = true, + Visible = true, + SpriteSheetItem = "TutorialWindowTop" + }) + local midL = GUI.CreateDisplayObjectEx("MidL", "CSprite", { + X = "0.0", + Y = "0.023", + Visible = true, + SpriteSheetItem = "TutorialWindowMid" + }) + local midR = GUI.CreateDisplayObjectEx("MidR", "CSprite", { + X = "0.0", + Y = "0.023", + FlipX = true, + Visible = true, + SpriteSheetItem = "TutorialWindowMid" + }) + local bottomL = GUI.CreateDisplayObjectEx("BotL", "CSprite", { + X = "0.0", + Y = "0.080", + Visible = true, + SpriteSheetItem = "TutorialWindowBot" + }) + local bottomR = GUI.CreateDisplayObjectEx("BotR", "CSprite", { + X = "0.0", + Y = "0.080", + FlipX = true, + Visible = true, + SpriteSheetItem = "TutorialWindowBot" + }) + local firstLine = GUI.CreateDisplayObjectEx("firstLine", "CText", { + X = "-0.6", + Y = "0.03", + Font = "digital_medium", + TextAlignment = "Centered", + Text="Bla bla bla bla", + Visible = true, + }) + local secondLine = GUI.CreateDisplayObjectEx("secondLine", "CText", { + X = "-0.6", + Y = "0.105", + Font = "digital_medium", + TextAlignment = "Centered", + Text="Bla bla bla bla 2", + Visible = true + }) + ussef:AddChild(outer) + outer:AddChild(topL) + outer:AddChild(topR) + outer:AddChild(midL) + outer:AddChild(midR) + outer:AddChild(bottomL) + outer:AddChild(bottomR) + outer:AddChild(firstLine) + outer:AddChild(secondLine) + + GUILib.outer = outer + GUILib.firstLine = firstLine + GUILib.secondLine = secondLine +end + +function GUILib.split(source, delimiters) + local elements = {} + local pattern = '([^'..delimiters..']+)' + for word in source:gmatch(pattern) do + elements[#elements + 1] = word + end + return elements +end + +function GUILib.ShowMessage(text) + local splitted = GUILib.split(text, "\n") + if #splitted == 2 then + GUI.SetTextText(GUILib.firstLine, splitted[1]) + GUI.SetTextText(GUILib.secondLine, splitted[2]) + else + GUI.SetTextText(GUILib.firstLine, text) + GUI.SetTextText(GUILib.secondLine, "") + end + + GUI.SetProperties(GUILib.outer, { + Visible = true + }) +end + +function GUILib.HideMessage() + GUI.SetProperties(GUILib.outer, { + Visible = false + }) end \ No newline at end of file diff --git a/src/open_samus_returns_rando/files/custom/queue.lua b/src/open_samus_returns_rando/files/custom/queue.lua new file mode 100644 index 0000000..7741bc4 --- /dev/null +++ b/src/open_samus_returns_rando/files/custom/queue.lua @@ -0,0 +1,39 @@ +Game.ImportLibrary("system/scripts/class.lua", false) + +---@class Queue +---@field push fun(self: Queue, item: any) +---@field peek fun(self: Queue): any +---@field pop fun(self: Queue): any +---@field empty fun(self: Queue): boolean + +---@type fun(): Queue +Queue = class.New( +---comment +---@param inst Queue +function(inst) + inst.data = {} + + inst.first = 0 + inst.last = -1 + + inst.push = function(self, item) + self.last = self.last + 1 + self.data[self.last] = item + end + + inst.peek = function (self) + if self:empty() then error("Trying to retrieve from an empty queue") end + return self.data[self.first] + end + + inst.pop = function(self) + local value = self:peek() + self.data[self.first] = nil + self.first = self.first + 1 + return value + end + + inst.empty = function(self) + return self.first > self.last + end +end) diff --git a/src/open_samus_returns_rando/files/custom/scenario.lua b/src/open_samus_returns_rando/files/custom/scenario.lua index 6780b20..736e16e 100644 --- a/src/open_samus_returns_rando/files/custom/scenario.lua +++ b/src/open_samus_returns_rando/files/custom/scenario.lua @@ -1,5 +1,6 @@ Game.ImportLibrary("system/scripts/scenario_original.lua") Game.ImportLibrary("system/scripts/guilib.lua", false) +Game.ImportLibrary("system/scripts/queue.lua", false) Game.ImportLibrary("system/scripts/cosmetics.lua", false) Game.DoFile("system/scripts/room_names.lua") @@ -51,7 +52,7 @@ end function Scenario.InitGUI() Cosmetics.UpdateGUI() - GUILib.AddDNACounter() + GUILib.InitCustomUI() GUILib.UpdateTotalDNAColor() Scenario.UpdateDNACounter() @@ -90,6 +91,15 @@ function Scenario.InitScenario(_ARG_0_, _ARG_1_, _ARG_2_, _ARG_3_) Scenario.UpdateProgressiveItemModels() + if Scenario.hideSFID ~= nil then + Game.DelSFByID(Scenario.hideSFID) + -- hide old popup + Scenario.HideAsyncPopup() + end + if Scenario.showNextSFID ~= nil then + Game.DelSFByID(Scenario.showNextSFID) + end + -- Only required for ils test code -- if Scenario.CurrentScenarioID == "s000_surface" then -- local next_number = (NextScenario % 17) + 1 @@ -149,4 +159,47 @@ function Scenario.RandoOnElevatorUse(from_actor, _ARG_1_, _ARG_2_) local destination = ElevatorDestinations[Scenario.CurrentScenarioID][from_actor.sName] Game.AddGUISF(0.5, GUI.ElevatorStartUseActionStep2InterArea, "") Elevator.Use("c10_samus", destination.scenario, destination.actor, _ARG_2_) -end \ No newline at end of file +end + +Scenario.QueuedPopups = Scenario.QueuedPopups or Queue() + +function Scenario.ShowIfNotActive() + + if Scenario.hideSFID == nil and Scenario.showNextSFID == nil then + Scenario.ShowNextAsyncPopup() + end +end + +function Scenario.QueueAsyncPopup(text, time) + Scenario.QueuedPopups:push({Text = text, Time = time or 5.0}) + Scenario.ShowIfNotActive() +end + +function Scenario.ShowNextAsyncPopup() + if Scenario.QueuedPopups:empty() then + Scenario.showNextSFID = nil + return + end + local popup = Scenario.QueuedPopups:peek() + Scenario.ShowAsyncPopup(popup.Text, popup.Time) +end + +function Scenario.ShowAsyncPopup(text, time) + GUILib.ShowMessage(text) + Scenario.hideSFID = Game.AddGUISF(time, "Scenario.HideAsyncPopup", "") + Scenario.showNextSFID = nil +end + +function Scenario.HideAsyncPopup() + if not Scenario.QueuedPopups:empty() then + Scenario.QueuedPopups:pop() + end + GUILib.HideMessage() + Scenario.showNextSFID = Game.AddGUISF(0.5, "Scenario.ShowNextAsyncPopup", "") + Scenario.hideSFID = nil +end + +function Scenario.ShowMessage(text) + GUILib.ShowMessage(text) + Game.AddSF(5.0, "GUILib.HideMessage", "") +end diff --git a/src/open_samus_returns_rando/files/templates/randomizer_item_template.lua b/src/open_samus_returns_rando/files/templates/randomizer_item_template.lua index b098802..9d183f0 100644 --- a/src/open_samus_returns_rando/files/templates/randomizer_item_template.lua +++ b/src/open_samus_returns_rando/files/templates/randomizer_item_template.lua @@ -6,7 +6,7 @@ function T__name__T.OnPickedUp() local resources = TEMPLATE("resources") -- (priority, sound file, unknown, unknown, times to replay sound, fade-out time, fade-in time, unknown) Game.PlayMusicStream(1, TEMPLATE("sound"), -1, -1, 0, 0, 0, 0) - GUI.LaunchMessage(TEMPLATE("caption"), "RandomizerPowerup.Dummy", "") + Scenario.QueueAsyncPopup(TEMPLATE("caption")) TEMPLATE("parent").OnPickedUp(resources) hud.UpdatePlayerInfo(true) end diff --git a/src/open_samus_returns_rando/lua_editor.py b/src/open_samus_returns_rando/lua_editor.py index 36e3624..aa491a4 100644 --- a/src/open_samus_returns_rando/lua_editor.py +++ b/src/open_samus_returns_rando/lua_editor.py @@ -292,6 +292,12 @@ def save_modifications(self, editor: PatcherEditor, configuration: dict) -> None [] ) + editor.add_new_asset( + "system/scripts/queue.lc", + Lua(Container(lua_text=files_path().joinpath("custom", "queue.lua").read_text()), editor.target_game), + [] + ) + cosmetics_script = cosmetic_patches.lua_cosmetics(configuration["cosmetic_patches"]) editor.add_new_asset( "system/scripts/cosmetics.lc", From b8f263deac4d5ea64e3de96e7aa6eb51e0f0f262 Mon Sep 17 00:00:00 2001 From: Thanatos Date: Wed, 5 Jun 2024 21:15:20 +0200 Subject: [PATCH 2/3] Update Async Popup --- .../files/custom/guilib.lua | 53 +++++++++++-------- .../files/custom/scenario.lua | 8 +-- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/open_samus_returns_rando/files/custom/guilib.lua b/src/open_samus_returns_rando/files/custom/guilib.lua index c52a142..851afb4 100644 --- a/src/open_samus_returns_rando/files/custom/guilib.lua +++ b/src/open_samus_returns_rando/files/custom/guilib.lua @@ -79,15 +79,13 @@ end function GUILib.AddMessageBox() local randoUI = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.USSEF.Outer") if randoUI ~= nil then - return + GUI.DestroyDisplayObject(randoUI) end local ussef = GUI.GetDisplayObject("IngameMenuRoot.IngameMenuComposition.USSEF") local outer = GUI.CreateDisplayObjectEx("Outer", "CDisplayObjectContainer", { StageID = "Up", - X = "0.0", - Y = "0.822", - ScaleX="2.16", - ScaleY="2.0", + X = "0.038", + Y = "0.829", Visible = false }) local topL = GUI.CreateDisplayObjectEx("TopL", "CSprite", { @@ -97,59 +95,72 @@ function GUILib.AddMessageBox() SpriteSheetItem = "TutorialWindowTop" }) local topR = GUI.CreateDisplayObjectEx("TopR", "CSprite", { - X = "0.0", + X = "0.462", Y = "0.0", FlipX = true, Visible = true, SpriteSheetItem = "TutorialWindowTop" }) - local midL = GUI.CreateDisplayObjectEx("MidL", "CSprite", { + local hiMidL = GUI.CreateDisplayObjectEx("hiMidL", "CSprite", { X = "0.0", - Y = "0.023", + Y = "0.024", + Visible = true, + SpriteSheetItem = "TutorialWindowMid" + }) + local hiMidR = GUI.CreateDisplayObjectEx("hiMidR", "CSprite", { + X = "0.462", + Y = "0.024", + FlipX = true, Visible = true, SpriteSheetItem = "TutorialWindowMid" }) - local midR = GUI.CreateDisplayObjectEx("MidR", "CSprite", { + local loMidL = GUI.CreateDisplayObjectEx("loMidL", "CSprite", { X = "0.0", - Y = "0.023", + Y = "0.083", + Visible = true, + SpriteSheetItem = "TutorialWindowMid" + }) + local loMidR = GUI.CreateDisplayObjectEx("loMidR", "CSprite", { + X = "0.462", + Y = "0.083", FlipX = true, Visible = true, SpriteSheetItem = "TutorialWindowMid" }) local bottomL = GUI.CreateDisplayObjectEx("BotL", "CSprite", { X = "0.0", - Y = "0.080", + Y = "0.141", Visible = true, SpriteSheetItem = "TutorialWindowBot" }) local bottomR = GUI.CreateDisplayObjectEx("BotR", "CSprite", { - X = "0.0", - Y = "0.080", + X = "0.462", + Y = "0.142", FlipX = true, Visible = true, SpriteSheetItem = "TutorialWindowBot" }) local firstLine = GUI.CreateDisplayObjectEx("firstLine", "CText", { - X = "-0.6", - Y = "0.03", + X = "-0.038", + Y = "0.015", Font = "digital_medium", TextAlignment = "Centered", - Text="Bla bla bla bla", Visible = true, }) local secondLine = GUI.CreateDisplayObjectEx("secondLine", "CText", { - X = "-0.6", - Y = "0.105", + X = "-0.038", + Y = "0.080", Font = "digital_medium", TextAlignment = "Centered", - Text="Bla bla bla bla 2", Visible = true }) ussef:AddChild(outer) outer:AddChild(topL) outer:AddChild(topR) - outer:AddChild(midL) - outer:AddChild(midR) + outer:AddChild(hiMidL) + outer:AddChild(hiMidR) + outer:AddChild(loMidL) + outer:AddChild(loMidR) outer:AddChild(bottomL) outer:AddChild(bottomR) outer:AddChild(firstLine) diff --git a/src/open_samus_returns_rando/files/custom/scenario.lua b/src/open_samus_returns_rando/files/custom/scenario.lua index 736e16e..6c0e0e1 100644 --- a/src/open_samus_returns_rando/files/custom/scenario.lua +++ b/src/open_samus_returns_rando/files/custom/scenario.lua @@ -90,15 +90,15 @@ function Scenario.InitScenario(_ARG_0_, _ARG_1_, _ARG_2_, _ARG_3_) end Scenario.UpdateProgressiveItemModels() - + + if Scenario.showNextSFID ~= nil then + Game.DelSFByID(Scenario.showNextSFID) + end if Scenario.hideSFID ~= nil then Game.DelSFByID(Scenario.hideSFID) -- hide old popup Scenario.HideAsyncPopup() end - if Scenario.showNextSFID ~= nil then - Game.DelSFByID(Scenario.showNextSFID) - end -- Only required for ils test code -- if Scenario.CurrentScenarioID == "s000_surface" then From 94c049e42ff51f852c542e743f8a66a864d8faa8 Mon Sep 17 00:00:00 2001 From: Thanatos Date: Wed, 5 Jun 2024 22:46:55 +0200 Subject: [PATCH 3/3] Variable y coordinate for first line --- src/open_samus_returns_rando/files/custom/guilib.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/open_samus_returns_rando/files/custom/guilib.lua b/src/open_samus_returns_rando/files/custom/guilib.lua index 851afb4..eda29a5 100644 --- a/src/open_samus_returns_rando/files/custom/guilib.lua +++ b/src/open_samus_returns_rando/files/custom/guilib.lua @@ -142,7 +142,6 @@ function GUILib.AddMessageBox() }) local firstLine = GUI.CreateDisplayObjectEx("firstLine", "CText", { X = "-0.038", - Y = "0.015", Font = "digital_medium", TextAlignment = "Centered", Visible = true, @@ -183,9 +182,15 @@ end function GUILib.ShowMessage(text) local splitted = GUILib.split(text, "\n") if #splitted == 2 then + GUI.SetProperties(GUILib.firstLine, { + Y = "0.015", + }) GUI.SetTextText(GUILib.firstLine, splitted[1]) GUI.SetTextText(GUILib.secondLine, splitted[2]) else + GUI.SetProperties(GUILib.firstLine, { + Y = "0.045", + }) GUI.SetTextText(GUILib.firstLine, text) GUI.SetTextText(GUILib.secondLine, "") end