From 3f2df7d512d46463fb96e2a684102a7fe774d062 Mon Sep 17 00:00:00 2001 From: Zoltan Timar Date: Thu, 5 Mar 2026 20:26:23 +0100 Subject: [PATCH 1/2] feat: trigger logic implementation --- impostor.inc | 1 + inc/init/init.context.lua | 2 + inc/init/init.module.lua | 3 +- inc/logic/logic.trigger.lua | 135 ++++++++++++++++++++++++++++++++++++ inc/system/system.main.lua | 1 + 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 inc/logic/logic.trigger.lua diff --git a/impostor.inc b/impostor.inc index ca29ee2..126d176 100644 --- a/impostor.inc +++ b/impostor.inc @@ -9,6 +9,7 @@ logic/logic.meter.lua logic/logic.focus.lua logic/logic.day.lua logic/logic.timer.lua +logic/logic.trigger.lua logic/logic.minigame.lua system/system.ui.lua audio/audio.manager.lua diff --git a/inc/init/init.context.lua b/inc/init/init.context.lua index dbc0bed..7434246 100644 --- a/inc/init/init.context.lua +++ b/inc/init/init.context.lua @@ -18,6 +18,7 @@ Context = {} --- * minigame_button_mash (table) Button mash minigame state (see Minigame.get_default_button_mash).
--- * minigame_rhythm (table) Rhythm minigame state (see Minigame.get_default_rhythm).
--- * meters (table) Meter values (see Meter.get_initial).
+--- * triggers (table) Active trigger runtime state, keyed by trigger ID.
--- * stat_screen_active (boolean) Whether the stat screen overlay is currently shown.
--- * game (table) Current game progress state. Contains: `current_screen` (string) active screen ID, `current_situation` (string|nil) active situation ID.
function Context.initial_data() @@ -35,6 +36,7 @@ function Context.initial_data() minigame_rhythm = {}, meters = Meter.get_initial(), timer = Timer.get_initial(), + triggers = {}, game = { current_screen = "home", current_situation = nil, diff --git a/inc/init/init.module.lua b/inc/init/init.module.lua index d99472a..a1b9759 100644 --- a/inc/init/init.module.lua +++ b/inc/init/init.module.lua @@ -13,4 +13,5 @@ Sprite = {} Audio = {} Focus = {} Day = {} -Timer = {} \ No newline at end of file +Timer = {} +Trigger = {} \ No newline at end of file diff --git a/inc/logic/logic.trigger.lua b/inc/logic/logic.trigger.lua new file mode 100644 index 0000000..7f15c8a --- /dev/null +++ b/inc/logic/logic.trigger.lua @@ -0,0 +1,135 @@ +--- @section Trigger +local triggers = {} + +--- @within Trigger +--- @param trigger table The trigger data table. +--- @param trigger.id string Unique trigger identifier. +--- @param trigger.duration number Duration in frames before the trigger fires. +--- @param[opt] trigger.on_start function Called when the trigger starts. Defaults to noop. +--- @param[opt] trigger.on_stop function Called when the trigger fires or is manually stopped. Defaults to noop. +--- @param[opt] trigger.repeating boolean If true, trigger restarts after firing. Defaults to false. +function Trigger.register(trigger) + if not trigger or not trigger.id then + trace("Error: Invalid trigger registered (missing id)!") + return + end + if not trigger.duration or trigger.duration <= 0 then + trace("Error: Invalid trigger registered (missing or invalid duration)!") + return + end + + if not trigger.on_start then + trigger.on_start = function() end + end + if not trigger.on_stop then + trigger.on_stop = function() end + end + if trigger.repeating == nil then + trigger.repeating = false + end + if triggers[trigger.id] then + trace("Warning: Overwriting trigger with id: " .. trigger.id) + end + triggers[trigger.id] = trigger +end + +--- @within Trigger +--- @param id string The trigger ID. +--- @return table|nil result The trigger definition or nil. +function Trigger.get_by_id(id) + return triggers[id] +end + +--- @within Trigger +--- @return table result All trigger definitions keyed by ID. +function Trigger.get_all() + return triggers +end + +--- @within Trigger +--- @param id string The trigger ID. +--- @return boolean active True if the trigger is running. +function Trigger.is_active(id) + if not Context or not Context.triggers then return false end + return Context.triggers[id] ~= nil +end + +--- If already active, restarts from 0. +--- @within Trigger +--- @param id string The trigger ID. +function Trigger.start(id) + if not Context or not Context.triggers then return end + local trigger = triggers[id] + if not trigger then + trace("Error: Cannot start unknown trigger: " .. tostring(id)) + return + end + + Context.triggers[id] = { elapsed = 0 } + trigger.on_start() +end + +--- @within Trigger +--- @param id string The trigger ID. +function Trigger.stop(id) + if not Context or not Context.triggers then return end + local trigger = triggers[id] + if not trigger then + trace("Error: Cannot stop unknown trigger: " .. tostring(id)) + return + end + if not Context.triggers[id] then return end + + Context.triggers[id] = nil + trigger.on_stop() +end + +--- Resets elapsed time to 0 without calling handlers. No-op if inactive. +--- @within Trigger +--- @param id string The trigger ID. +function Trigger.reset(id) + if not Context or not Context.triggers then return end + if not triggers[id] then + trace("Error: Cannot reset unknown trigger: " .. tostring(id)) + return + end + if not Context.triggers[id] then return end + + Context.triggers[id].elapsed = 0 +end + +--- Pauses during minigames. +--- @within Trigger +function Trigger.update() + if not Context or not Context.game_in_progress or not Context.triggers then return end + + local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil + if in_minigame then return end + + local fired = {} + for id, state in pairs(Context.triggers) do + local trigger = triggers[id] + if trigger then + state.elapsed = state.elapsed + 1 + if state.elapsed >= trigger.duration then + table.insert(fired, id) + end + else + table.insert(fired, id) + end + end + + for _, id in ipairs(fired) do + local trigger = triggers[id] + if trigger then + trigger.on_stop() + if trigger.repeating then + Context.triggers[id] = { elapsed = 0 } + else + Context.triggers[id] = nil + end + else + Context.triggers[id] = nil + end + end +end diff --git a/inc/system/system.main.lua b/inc/system/system.main.lua index 1204d02..9140532 100644 --- a/inc/system/system.main.lua +++ b/inc/system/system.main.lua @@ -23,6 +23,7 @@ function TIC() end Meter.update() Timer.update() + Trigger.update() if Context.game_in_progress then Meter.draw() Timer.draw() -- 2.49.1 From 9b49e13a5daadbb9c1618d951457d0f25871af05 Mon Sep 17 00:00:00 2001 From: Zoltan Timar Date: Thu, 5 Mar 2026 20:38:16 +0100 Subject: [PATCH 2/2] fix: adding Trigger to luacheckrc --- .luacheckrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.luacheckrc b/.luacheckrc index 8142729..1221c0b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -5,6 +5,7 @@ globals = { "Focus", "Day", "Timer", + "Trigger", "Util", "Decision", "Situation", -- 2.49.1