From 09c0d3a5ae1459c007e2e279278674e952688186 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Wed, 22 Feb 2023 11:55:34 +0100 Subject: [PATCH] fix: Add missing game state hooks Co-authored-by: Aussiemon --- .luacheckrc | 2 + scripts/mods/dml/init.lua | 81 ++++++++++++++++++++++++++++++------ scripts/mods/dml/message.lua | 47 +++++++++++++++++++++ 3 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 scripts/mods/dml/message.lua diff --git a/.luacheckrc b/.luacheckrc index f213500..e04e4da 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -8,6 +8,7 @@ ignore = { "12.", -- ignore "Setting a read-only global variable/Setting a read-only field of a global variable." "542", -- disable warnings for empty if branches. These are useful sometime and easy to notice otherwise. "212/self", -- Disable unused self warnings. + "432/self", -- Allow shadowing `self`, often happens when creating hooks in functions } std = "+DT+DML" @@ -28,6 +29,7 @@ stds["DML"] = { "_get_item_hook", "_patch", }}, + message = { fields = { "echo", "notify" }}, "original_require", "require_store", "original_class", diff --git a/scripts/mods/dml/init.lua b/scripts/mods/dml/init.lua index 71f299d..dcfa892 100644 --- a/scripts/mods/dml/init.lua +++ b/scripts/mods/dml/init.lua @@ -2,30 +2,87 @@ -- to initialize the modding environment. local loader = {} -Mods = { - lua = setmetatable({}, { - __index = { debug = debug, io = io, ffi = ffi, os = os }, - }), -} +Mods = {} -dofile("scripts/mods/dml/require") -dofile("scripts/mods/dml/class") -Mods.hook = dofile("scripts/mods/dml/hook") +function loader:init(libs, mod_data, boot_gui) + -- The metatable prevents overwriting these + self._libs = setmetatable({}, { __index = libs }) + Mods.lua = self._libs + + dofile("scripts/mods/dml/message") + dofile("scripts/mods/dml/require") + dofile("scripts/mods/dml/class") + dofile("scripts/mods/dml/hook") -function loader:init(boot_gui, mod_data) local ModLoader = dofile("scripts/mods/dml/mod_loader") - local mod_loader = ModLoader:init(boot_gui, mod_data) + local mod_loader = ModLoader:new(boot_gui, mod_data) self._mod_loader = mod_loader - Mods.hook.set(StateGame, "update", function(func, dt, ...) + -- The mod loader needs to remain active during game play, to + -- enable reloads + Mods.hook.set("DML", "StateGame.update", function(func, dt, ...) mod_loader:update(dt) return func(dt, ...) end) + -- Skip splash view + Mods.hook.set("Base", "StateSplash.on_enter", function(func, self, ...) + local result = func(self, ...) + + self._should_skip = true + self._continue = true + + return result + end) + + -- Trigger state change events + Mods.hook.set("Base", "GameStateMachine._change_state", function(func, self, ...) + local old_state = self._state + local old_state_name = old_state and self:current_state_name() + + if old_state_name then + mod_loader:on_game_state_changed("exit", old_state_name, old_state) + end + + local result = func(self, ...) + + local new_state = self._state + local new_state_name = new_state and self:current_state_name() + + if new_state_name then + mod_loader:on_game_state_changed("enter", new_state_name, new_state) + end + + return result + end) + + -- Trigger ending state change event + Mods.hook.set("Base", "GameStateMachine.destroy", function(func, self, ...) + local old_state = self._state + local old_state_name = old_state and self:current_state_name() + + if old_state_name then + mod_loader:on_game_state_changed("exit", old_state_name) + end + + return func(self, ...) + end) end function loader:update(dt) - self._mod_loader:update(dt) + local mod_loader = self._mod_loader + mod_loader:update(dt) + + local done = mod_loader:all_mods_loaded() + if done then + mod_loader:_remove_gui() + end + + return done +end + +function loader:done() + return self._mod_loader:all_mods_loaded() end return loader diff --git a/scripts/mods/dml/message.lua b/scripts/mods/dml/message.lua new file mode 100644 index 0000000..3ea27fe --- /dev/null +++ b/scripts/mods/dml/message.lua @@ -0,0 +1,47 @@ +local chat_sound = "wwise/events/ui/play_ui_click" + +local notify = function(message) + local event_manager = Managers and Managers.event + + if event_manager then + event_manager:trigger("event_add_notification_message", "default", message, nil, chat_sound) + end + + print(message) +end + +local echo = function(message, sender) + local chat_manager = Managers and Managers.chat + local event_manager = Managers and Managers.event + + if chat_manager and event_manager then + local message_obj = { + message_body = message, + is_current_user = false, + } + + local participant = { + displayname = sender or "SYSTEM", + } + + local message_sent = false + + local channel_handle, channel = next(chat_manager:connected_chat_channels()) + if channel then + event_manager:trigger("chat_manager_message_recieved", channel_handle, participant, message_obj) + message_sent = true + end + + if not message_sent then + notify(message) + return + end + end + + print(message) +end + +Mods.message = { + echo = echo, + notify = notify, +}