Compare commits
10 Commits
feature/mi
...
5d78cffc99
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d78cffc99 | |||
| d1e7704d66 | |||
| 71a21f3f86 | |||
| 5383fa3240 | |||
|
|
f3846a283e | ||
|
|
732c8b34c8 | ||
| 53a3f37c8e | |||
|
|
9b49e13a5d | ||
|
|
3f2df7d512 | ||
| 3db1ae1064 |
@@ -5,6 +5,7 @@ globals = {
|
|||||||
"Focus",
|
"Focus",
|
||||||
"Day",
|
"Day",
|
||||||
"Timer",
|
"Timer",
|
||||||
|
"Trigger",
|
||||||
"Util",
|
"Util",
|
||||||
"Decision",
|
"Decision",
|
||||||
"Situation",
|
"Situation",
|
||||||
@@ -29,6 +30,7 @@ globals = {
|
|||||||
"MinigameButtonMashWindow",
|
"MinigameButtonMashWindow",
|
||||||
"MinigameRhythmWindow",
|
"MinigameRhythmWindow",
|
||||||
"MinigameDDRWindow",
|
"MinigameDDRWindow",
|
||||||
|
"MysteriousManWindow",
|
||||||
"mset",
|
"mset",
|
||||||
"mget",
|
"mget",
|
||||||
"btnp",
|
"btnp",
|
||||||
|
|||||||
10
impostor.inc
10
impostor.inc
@@ -9,6 +9,7 @@ logic/logic.meter.lua
|
|||||||
logic/logic.focus.lua
|
logic/logic.focus.lua
|
||||||
logic/logic.day.lua
|
logic/logic.day.lua
|
||||||
logic/logic.timer.lua
|
logic/logic.timer.lua
|
||||||
|
logic/logic.trigger.lua
|
||||||
logic/logic.minigame.lua
|
logic/logic.minigame.lua
|
||||||
system/system.ui.lua
|
system/system.ui.lua
|
||||||
audio/audio.manager.lua
|
audio/audio.manager.lua
|
||||||
@@ -23,10 +24,10 @@ decision/decision.go_to_home.lua
|
|||||||
decision/decision.go_to_toilet.lua
|
decision/decision.go_to_toilet.lua
|
||||||
decision/decision.go_to_walking_to_office.lua
|
decision/decision.go_to_walking_to_office.lua
|
||||||
decision/decision.go_to_office.lua
|
decision/decision.go_to_office.lua
|
||||||
|
decision/decision.go_to_end.lua
|
||||||
decision/decision.go_to_walking_to_home.lua
|
decision/decision.go_to_walking_to_home.lua
|
||||||
decision/decision.play_button_mash.lua
|
decision/decision.go_to_sleep.lua
|
||||||
decision/decision.play_rhythm.lua
|
decision/decision.do_work.lua
|
||||||
decision/decision.play_ddr.lua
|
|
||||||
map/map.manager.lua
|
map/map.manager.lua
|
||||||
map/map.bedroom.lua
|
map/map.bedroom.lua
|
||||||
map/map.street.lua
|
map/map.street.lua
|
||||||
@@ -37,8 +38,10 @@ screen/screen.toilet.lua
|
|||||||
screen/screen.walking_to_office.lua
|
screen/screen.walking_to_office.lua
|
||||||
screen/screen.office.lua
|
screen/screen.office.lua
|
||||||
screen/screen.walking_to_home.lua
|
screen/screen.walking_to_home.lua
|
||||||
|
screen/screen.work.lua
|
||||||
window/window.manager.lua
|
window/window.manager.lua
|
||||||
window/window.register.lua
|
window/window.register.lua
|
||||||
|
window/window.end.lua
|
||||||
window/window.splash.lua
|
window/window.splash.lua
|
||||||
window/window.intro.lua
|
window/window.intro.lua
|
||||||
window/window.menu.lua
|
window/window.menu.lua
|
||||||
@@ -48,6 +51,7 @@ window/window.popup.lua
|
|||||||
window/window.minigame.mash.lua
|
window/window.minigame.mash.lua
|
||||||
window/window.minigame.rhythm.lua
|
window/window.minigame.rhythm.lua
|
||||||
window/window.minigame.ddr.lua
|
window/window.minigame.ddr.lua
|
||||||
|
window/window.mysterious_man.lua
|
||||||
window/window.game.lua
|
window/window.game.lua
|
||||||
system/system.main.lua
|
system/system.main.lua
|
||||||
meta/meta.assets.lua
|
meta/meta.assets.lua
|
||||||
|
|||||||
15
inc/decision/decision.do_work.lua
Normal file
15
inc/decision/decision.do_work.lua
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Decision.register({
|
||||||
|
id = "do_work",
|
||||||
|
label = "Do Work",
|
||||||
|
handle = function()
|
||||||
|
Meter.hide()
|
||||||
|
Util.go_to_screen_by_id("work")
|
||||||
|
MinigameDDRWindow.start("game", nil, {
|
||||||
|
on_win = function()
|
||||||
|
Meter.show()
|
||||||
|
Util.go_to_screen_by_id("office")
|
||||||
|
Window.set_current("game")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
})
|
||||||
7
inc/decision/decision.go_to_end.lua
Normal file
7
inc/decision/decision.go_to_end.lua
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Decision.register({
|
||||||
|
id = "go_to_end",
|
||||||
|
label = "Break the cycle",
|
||||||
|
handle = function()
|
||||||
|
Window.set_current("end")
|
||||||
|
end,
|
||||||
|
})
|
||||||
16
inc/decision/decision.go_to_sleep.lua
Normal file
16
inc/decision/decision.go_to_sleep.lua
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Decision.register({
|
||||||
|
id = "go_to_sleep",
|
||||||
|
label = "Go to Sleep",
|
||||||
|
handle = function()
|
||||||
|
Meter.hide()
|
||||||
|
Day.increase()
|
||||||
|
MinigameRhythmWindow.start("game", {
|
||||||
|
focus_center_x = Config.screen.width / 2,
|
||||||
|
focus_center_y = Config.screen.height / 2,
|
||||||
|
focus_initial_radius = 0,
|
||||||
|
on_win = function()
|
||||||
|
MysteriousManWindow.start()
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
})
|
||||||
@@ -10,11 +10,11 @@ local _decisions = {}
|
|||||||
--- @param[opt] decision.handle function Called when the decision is selected. Defaults to noop.
|
--- @param[opt] decision.handle function Called when the decision is selected. Defaults to noop.
|
||||||
function Decision.register(decision)
|
function Decision.register(decision)
|
||||||
if not decision or not decision.id then
|
if not decision or not decision.id then
|
||||||
PopupWindow.show({"Error: Invalid decision object registered (missing id)!"})
|
trace("Error: Invalid decision object registered (missing id)!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not decision.label then
|
if not decision.label then
|
||||||
PopupWindow.show({"Error: Invalid decision object registered (missing label)!"})
|
trace("Error: Invalid decision object registered (missing label)!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ end
|
|||||||
function Decision.filter_available(decisions_list)
|
function Decision.filter_available(decisions_list)
|
||||||
local available = {}
|
local available = {}
|
||||||
for _, decision in ipairs(decisions_list) do
|
for _, decision in ipairs(decisions_list) do
|
||||||
if decision and decision.condition() then
|
if decision and (not decision.condition or decision.condition()) then
|
||||||
table.insert(available, decision)
|
table.insert(available, decision)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Context = {}
|
|||||||
--- * minigame_button_mash (table) Button mash minigame state (see Minigame.get_default_button_mash).<br/>
|
--- * minigame_button_mash (table) Button mash minigame state (see Minigame.get_default_button_mash).<br/>
|
||||||
--- * minigame_rhythm (table) Rhythm minigame state (see Minigame.get_default_rhythm).<br/>
|
--- * minigame_rhythm (table) Rhythm minigame state (see Minigame.get_default_rhythm).<br/>
|
||||||
--- * meters (table) Meter values (see Meter.get_initial).<br/>
|
--- * meters (table) Meter values (see Meter.get_initial).<br/>
|
||||||
|
--- * triggers (table) Active trigger runtime state, keyed by trigger ID.<br/>
|
||||||
--- * stat_screen_active (boolean) Whether the stat screen overlay is currently shown.<br/>
|
--- * stat_screen_active (boolean) Whether the stat screen overlay is currently shown.<br/>
|
||||||
--- * game (table) Current game progress state. Contains: `current_screen` (string) active screen ID, `current_situation` (string|nil) active situation ID.<br/>
|
--- * game (table) Current game progress state. Contains: `current_screen` (string) active screen ID, `current_situation` (string|nil) active situation ID.<br/>
|
||||||
function Context.initial_data()
|
function Context.initial_data()
|
||||||
@@ -35,11 +36,16 @@ function Context.initial_data()
|
|||||||
minigame_rhythm = {},
|
minigame_rhythm = {},
|
||||||
meters = Meter.get_initial(),
|
meters = Meter.get_initial(),
|
||||||
timer = Timer.get_initial(),
|
timer = Timer.get_initial(),
|
||||||
|
triggers = {},
|
||||||
game = {
|
game = {
|
||||||
current_screen = "home",
|
current_screen = "home",
|
||||||
current_situation = nil,
|
current_situation = nil,
|
||||||
},
|
},
|
||||||
day_count = 1,
|
day_count = 1,
|
||||||
|
_end = {
|
||||||
|
state = "choice",
|
||||||
|
selection = 1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ Audio = {}
|
|||||||
Focus = {}
|
Focus = {}
|
||||||
Day = {}
|
Day = {}
|
||||||
Timer = {}
|
Timer = {}
|
||||||
|
Trigger = {}
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
|
--- @section Day
|
||||||
local _day_increase_handlers = {}
|
local _day_increase_handlers = {}
|
||||||
|
|
||||||
|
--- Increases the day count and triggers registered handlers.
|
||||||
|
--- @within Day
|
||||||
function Day.increase()
|
function Day.increase()
|
||||||
Context.day_count = Context.day_count + 1
|
Context.day_count = Context.day_count + 1
|
||||||
for _, handler in ipairs(_day_increase_handlers) do
|
for _, handler in ipairs(_day_increase_handlers) do
|
||||||
handler()
|
handler()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Registers a handler to be called when the day increases.
|
||||||
|
--- @within Day
|
||||||
|
--- @param handler function The function to call when the day increases.
|
||||||
function Day.register_handler(handler)
|
function Day.register_handler(handler)
|
||||||
table.insert(_day_increase_handlers, handler)
|
table.insert(_day_increase_handlers, handler)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -131,7 +131,9 @@ function Meter.draw()
|
|||||||
local bar_x = 182
|
local bar_x = 182
|
||||||
local label_x = 228
|
local label_x = 228
|
||||||
local line_h = 5
|
local line_h = 5
|
||||||
local start_y = 11
|
local start_y = 1
|
||||||
|
|
||||||
|
|
||||||
local bar_offset = math.floor((line_h - bar_h) / 2)
|
local bar_offset = math.floor((line_h - bar_h) / 2)
|
||||||
|
|
||||||
local meter_list = {
|
local meter_list = {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
--- Draws a unified win message overlay.
|
--- Draws a unified win message overlay.
|
||||||
--- @within Minigame
|
--- @within Minigame
|
||||||
function Minigame.draw_win_overlay()
|
function Minigame.draw_win_overlay()
|
||||||
local text = "WELL DONE!"
|
local text = "SUCCESS"
|
||||||
local tw = #text * 4
|
local tw = #text * 4
|
||||||
local th = 6
|
local th = 6
|
||||||
local padding = 4
|
local padding = 4
|
||||||
|
|||||||
@@ -43,14 +43,14 @@ function Timer.draw()
|
|||||||
if Context.meters.hidden and not Context.stat_screen_active then return end
|
if Context.meters.hidden and not Context.stat_screen_active then return end
|
||||||
|
|
||||||
local cx = 10
|
local cx = 10
|
||||||
local cy = 20
|
local cy = 8
|
||||||
local r_outer = 5
|
local r_outer = 5
|
||||||
local r_inner = 3
|
local r_inner = 3
|
||||||
local progress = Context.timer.progress
|
local progress = Context.timer.progress
|
||||||
|
|
||||||
local fg_color
|
local fg_color
|
||||||
if progress <= 0.25 then
|
if progress <= 0.25 then
|
||||||
fg_color = Config.colors.white
|
fg_color = Config.colors.dark_grey
|
||||||
elseif progress <= 0.5 then
|
elseif progress <= 0.5 then
|
||||||
fg_color = Config.colors.light_blue
|
fg_color = Config.colors.light_blue
|
||||||
elseif progress <= 0.75 then
|
elseif progress <= 0.75 then
|
||||||
@@ -59,7 +59,7 @@ function Timer.draw()
|
|||||||
fg_color = Config.colors.red
|
fg_color = Config.colors.red
|
||||||
end
|
end
|
||||||
|
|
||||||
local bg_color = Config.colors.dark_grey
|
local bg_color = Config.colors.white
|
||||||
local start_angle = -math.pi * 0.5
|
local start_angle = -math.pi * 0.5
|
||||||
local progress_angle = progress * 2 * math.pi
|
local progress_angle = progress * 2 * math.pi
|
||||||
local r_outer_sq = r_outer * r_outer
|
local r_outer_sq = r_outer * r_outer
|
||||||
|
|||||||
135
inc/logic/logic.trigger.lua
Normal file
135
inc/logic/logic.trigger.lua
Normal file
@@ -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
|
||||||
@@ -4,6 +4,8 @@ Screen.register({
|
|||||||
decisions = {
|
decisions = {
|
||||||
"go_to_toilet",
|
"go_to_toilet",
|
||||||
"go_to_walking_to_office",
|
"go_to_walking_to_office",
|
||||||
|
"go_to_sleep",
|
||||||
|
"go_to_end",
|
||||||
},
|
},
|
||||||
background = "bedroom"
|
background = "bedroom"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ Screen.register({
|
|||||||
id = "office",
|
id = "office",
|
||||||
name = "Office",
|
name = "Office",
|
||||||
decisions = {
|
decisions = {
|
||||||
"play_button_mash",
|
"do_work",
|
||||||
"play_rhythm",
|
|
||||||
"play_ddr",
|
|
||||||
"go_to_walking_to_home",
|
"go_to_walking_to_home",
|
||||||
"have_a_coffee",
|
"have_a_coffee",
|
||||||
},
|
},
|
||||||
|
|||||||
6
inc/screen/screen.work.lua
Normal file
6
inc/screen/screen.work.lua
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Screen.register({
|
||||||
|
id = "work",
|
||||||
|
name = "Work",
|
||||||
|
decisions = {},
|
||||||
|
background_color = Config.colors.blue,
|
||||||
|
})
|
||||||
@@ -23,6 +23,7 @@ function TIC()
|
|||||||
end
|
end
|
||||||
Meter.update()
|
Meter.update()
|
||||||
Timer.update()
|
Timer.update()
|
||||||
|
Trigger.update()
|
||||||
if Context.game_in_progress then
|
if Context.game_in_progress then
|
||||||
Meter.draw()
|
Meter.draw()
|
||||||
Timer.draw()
|
Timer.draw()
|
||||||
|
|||||||
75
inc/window/window.end.lua
Normal file
75
inc/window/window.end.lua
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
--- Draws the end screen window.
|
||||||
|
--- @within EndWindow
|
||||||
|
function EndWindow.draw()
|
||||||
|
cls(Config.colors.black)
|
||||||
|
|
||||||
|
if Context._end.state == "choice" then
|
||||||
|
local lines = {
|
||||||
|
"This is not a workplace.",
|
||||||
|
"This is a cycle.",
|
||||||
|
"And if it is a cycle...",
|
||||||
|
"it can be broken."
|
||||||
|
}
|
||||||
|
|
||||||
|
local y = 40
|
||||||
|
for _, line in ipairs(lines) do
|
||||||
|
Print.text_center(line, Config.screen.width / 2, y, Config.colors.white)
|
||||||
|
y = y + 10
|
||||||
|
end
|
||||||
|
|
||||||
|
y = y + 20
|
||||||
|
local yes_color = Context._end.selection == 1 and Config.colors.light_blue or Config.colors.white
|
||||||
|
local no_color = Context._end.selection == 2 and Config.colors.light_blue or Config.colors.white
|
||||||
|
|
||||||
|
local yes_text = (Context._end.selection == 1 and "> YES" or " YES")
|
||||||
|
local no_text = (Context._end.selection == 2 and "> NO" or " NO")
|
||||||
|
|
||||||
|
local centerX = Config.screen.width / 2
|
||||||
|
Print.text(yes_text, centerX - 40, y, yes_color)
|
||||||
|
Print.text(no_text, centerX + 10, y, no_color)
|
||||||
|
elseif Context._end.state == "ending" then
|
||||||
|
Print.text_center("Game over -- good ending.", Config.screen.width / 2, 50, Config.colors.light_blue)
|
||||||
|
Print.text_center("Congratulations!", Config.screen.width / 2, 70, Config.colors.white)
|
||||||
|
Print.text_center("Press Z to return to menu", Config.screen.width / 2, 110, Config.colors.light_grey)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Updates the end screen logic.
|
||||||
|
--- @within EndWindow
|
||||||
|
function EndWindow.update()
|
||||||
|
if Context._end.state == "choice" then
|
||||||
|
if Input.left() or Input.up() then
|
||||||
|
if Context._end.selection == 2 then
|
||||||
|
Audio.sfx_beep()
|
||||||
|
Context._end.selection = 1
|
||||||
|
end
|
||||||
|
elseif Input.right() or Input.down() then
|
||||||
|
if Context._end.selection == 1 then
|
||||||
|
Audio.sfx_beep()
|
||||||
|
Context._end.selection = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if Input.menu_confirm() then
|
||||||
|
Audio.sfx_select()
|
||||||
|
if Context._end.selection == 1 then
|
||||||
|
Context._end.state = "ending"
|
||||||
|
else
|
||||||
|
-- NO: increment day and go home
|
||||||
|
Day.increase()
|
||||||
|
Context.game.current_screen = "home"
|
||||||
|
Window.set_current("game")
|
||||||
|
-- Initialize home screen
|
||||||
|
local home_screen = Screen.get_by_id("home")
|
||||||
|
if home_screen and home_screen.init then
|
||||||
|
home_screen.init()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif Context._end.state == "ending" then
|
||||||
|
if Input.menu_confirm() then
|
||||||
|
Window.set_current("menu")
|
||||||
|
MenuWindow.refresh_menu_items()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -6,12 +6,12 @@ local _selected_decision_index = 1
|
|||||||
--- @within GameWindow
|
--- @within GameWindow
|
||||||
function GameWindow.draw()
|
function GameWindow.draw()
|
||||||
local screen = Screen.get_by_id(Context.game.current_screen)
|
local screen = Screen.get_by_id(Context.game.current_screen)
|
||||||
|
if not screen then return end
|
||||||
if screen.background then
|
if screen.background then
|
||||||
Map.draw(screen.background)
|
Map.draw(screen.background)
|
||||||
elseif screen.background_color then
|
elseif screen.background_color then
|
||||||
rect(0, 0, Config.screen.width, Config.screen.height, screen.background_color)
|
rect(0, 0, Config.screen.width, Config.screen.height, screen.background_color)
|
||||||
end
|
end
|
||||||
UI.draw_top_bar(screen.name)
|
|
||||||
if not Context.stat_screen_active and #_available_decisions > 0 then
|
if not Context.stat_screen_active and #_available_decisions > 0 then
|
||||||
Decision.draw(_available_decisions, _selected_decision_index)
|
Decision.draw(_available_decisions, _selected_decision_index)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ function MinigameDDRWindow.init_context()
|
|||||||
pattern_index = 1,
|
pattern_index = 1,
|
||||||
use_pattern = false,
|
use_pattern = false,
|
||||||
return_window = nil,
|
return_window = nil,
|
||||||
win_timer = 0
|
win_timer = 0,
|
||||||
|
on_win = nil
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -162,9 +163,13 @@ function MinigameDDRWindow.update()
|
|||||||
mg.win_timer = mg.win_timer - 1
|
mg.win_timer = mg.win_timer - 1
|
||||||
if mg.win_timer == 0 then
|
if mg.win_timer == 0 then
|
||||||
Meter.on_minigame_complete()
|
Meter.on_minigame_complete()
|
||||||
|
if mg.on_win then
|
||||||
|
mg.on_win()
|
||||||
|
else
|
||||||
Meter.show()
|
Meter.show()
|
||||||
Window.set_current(mg.return_window)
|
Window.set_current(mg.return_window)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ function MinigameButtonMashWindow.init_context()
|
|||||||
focus_center_x = nil,
|
focus_center_x = nil,
|
||||||
focus_center_y = nil,
|
focus_center_y = nil,
|
||||||
focus_initial_radius = 0,
|
focus_initial_radius = 0,
|
||||||
win_timer = 0
|
win_timer = 0,
|
||||||
|
on_win = nil
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -63,10 +64,14 @@ function MinigameButtonMashWindow.update()
|
|||||||
mg.win_timer = mg.win_timer - 1
|
mg.win_timer = mg.win_timer - 1
|
||||||
if mg.win_timer == 0 then
|
if mg.win_timer == 0 then
|
||||||
Meter.on_minigame_complete()
|
Meter.on_minigame_complete()
|
||||||
Meter.show()
|
|
||||||
if mg.focus_center_x then Focus.stop() end
|
if mg.focus_center_x then Focus.stop() end
|
||||||
|
if mg.on_win then
|
||||||
|
mg.on_win()
|
||||||
|
else
|
||||||
|
Meter.show()
|
||||||
Window.set_current(mg.return_window)
|
Window.set_current(mg.return_window)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ function MinigameRhythmWindow.init_context()
|
|||||||
focus_center_x = nil,
|
focus_center_x = nil,
|
||||||
focus_center_y = nil,
|
focus_center_y = nil,
|
||||||
focus_initial_radius = 0,
|
focus_initial_radius = 0,
|
||||||
win_timer = 0
|
win_timer = 0,
|
||||||
|
on_win = nil
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -72,10 +73,14 @@ function MinigameRhythmWindow.update()
|
|||||||
mg.win_timer = mg.win_timer - 1
|
mg.win_timer = mg.win_timer - 1
|
||||||
if mg.win_timer == 0 then
|
if mg.win_timer == 0 then
|
||||||
Meter.on_minigame_complete()
|
Meter.on_minigame_complete()
|
||||||
Meter.show()
|
|
||||||
if mg.focus_center_x then Focus.stop() end
|
if mg.focus_center_x then Focus.stop() end
|
||||||
|
if mg.on_win then
|
||||||
|
mg.on_win()
|
||||||
|
else
|
||||||
|
Meter.show()
|
||||||
Window.set_current(mg.return_window)
|
Window.set_current(mg.return_window)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
132
inc/window/window.mysterious_man.lua
Normal file
132
inc/window/window.mysterious_man.lua
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
--- @section MysteriousManWindow
|
||||||
|
|
||||||
|
local STATE_TEXT = "text"
|
||||||
|
local STATE_DAY = "day"
|
||||||
|
local STATE_CHOICE = "choice"
|
||||||
|
|
||||||
|
local state = STATE_TEXT
|
||||||
|
local text_y = Config.screen.height
|
||||||
|
local text_speed = 0.4
|
||||||
|
local day_timer = 0
|
||||||
|
local day_display_frames = 120
|
||||||
|
local selected_choice = 1
|
||||||
|
|
||||||
|
local choices = {
|
||||||
|
{
|
||||||
|
label = "Wake Up",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "Stay in Bed",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local text = [[
|
||||||
|
Misterious man appears
|
||||||
|
during your sleep.
|
||||||
|
|
||||||
|
He says nothing.
|
||||||
|
He doesn't need to.
|
||||||
|
|
||||||
|
He says nothing.
|
||||||
|
]]
|
||||||
|
|
||||||
|
--- Sets the scrolling text content.
|
||||||
|
--- @within MysteriousManWindow
|
||||||
|
--- @param new_text string The text to display.
|
||||||
|
function MysteriousManWindow.set_text(new_text)
|
||||||
|
text = new_text
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Starts the mysterious man window.
|
||||||
|
--- @within MysteriousManWindow
|
||||||
|
function MysteriousManWindow.start()
|
||||||
|
state = STATE_TEXT
|
||||||
|
text_y = Config.screen.height
|
||||||
|
day_timer = 0
|
||||||
|
selected_choice = 1
|
||||||
|
Meter.hide()
|
||||||
|
Window.set_current("mysterious_man")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wake_up()
|
||||||
|
Util.go_to_screen_by_id("home")
|
||||||
|
MinigameButtonMashWindow.start("game", {
|
||||||
|
focus_center_x = Config.screen.width / 2,
|
||||||
|
focus_center_y = Config.screen.height / 2,
|
||||||
|
focus_initial_radius = 0,
|
||||||
|
on_win = function()
|
||||||
|
Meter.show()
|
||||||
|
Window.set_current("game")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function stay_in_bed()
|
||||||
|
Day.increase()
|
||||||
|
state = STATE_DAY
|
||||||
|
day_timer = day_display_frames
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Updates the mysterious man window logic.
|
||||||
|
--- @within MysteriousManWindow
|
||||||
|
function MysteriousManWindow.update()
|
||||||
|
if state == STATE_TEXT then
|
||||||
|
text_y = text_y - text_speed
|
||||||
|
|
||||||
|
local lines = 1
|
||||||
|
for _ in string.gmatch(text, "\n") do
|
||||||
|
lines = lines + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if text_y < -lines * 8 then
|
||||||
|
state = STATE_DAY
|
||||||
|
day_timer = day_display_frames
|
||||||
|
end
|
||||||
|
|
||||||
|
if Input.select() then
|
||||||
|
state = STATE_DAY
|
||||||
|
day_timer = day_display_frames
|
||||||
|
end
|
||||||
|
elseif state == STATE_DAY then
|
||||||
|
day_timer = day_timer - 1
|
||||||
|
|
||||||
|
if day_timer <= 0 or Input.select() then
|
||||||
|
state = STATE_CHOICE
|
||||||
|
selected_choice = 1
|
||||||
|
end
|
||||||
|
elseif state == STATE_CHOICE then
|
||||||
|
selected_choice = UI.update_menu(choices, selected_choice)
|
||||||
|
|
||||||
|
if Input.select() then
|
||||||
|
Audio.sfx_select()
|
||||||
|
if selected_choice == 1 then
|
||||||
|
wake_up()
|
||||||
|
else
|
||||||
|
stay_in_bed()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Draws the mysterious man window.
|
||||||
|
--- @within MysteriousManWindow
|
||||||
|
function MysteriousManWindow.draw()
|
||||||
|
rect(0, 0, Config.screen.width, Config.screen.height, Config.colors.black)
|
||||||
|
|
||||||
|
if state == STATE_TEXT then
|
||||||
|
local x = (Config.screen.width - 132) / 2
|
||||||
|
Print.text(text, x, text_y, Config.colors.light_grey)
|
||||||
|
elseif state == STATE_DAY then
|
||||||
|
local day_text = "Day " .. Context.day_count
|
||||||
|
Print.text_center(
|
||||||
|
day_text,
|
||||||
|
Config.screen.width / 2,
|
||||||
|
Config.screen.height / 2 - 3,
|
||||||
|
Config.colors.white
|
||||||
|
)
|
||||||
|
elseif state == STATE_CHOICE then
|
||||||
|
local menu_x = (Config.screen.width - 60) / 2
|
||||||
|
local menu_y = (Config.screen.height - 20) / 2
|
||||||
|
UI.draw_menu(choices, selected_choice, menu_x, menu_y)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -27,3 +27,9 @@ Window.register("minigame_rhythm", MinigameRhythmWindow)
|
|||||||
|
|
||||||
MinigameDDRWindow = {}
|
MinigameDDRWindow = {}
|
||||||
Window.register("minigame_ddr", MinigameDDRWindow)
|
Window.register("minigame_ddr", MinigameDDRWindow)
|
||||||
|
|
||||||
|
MysteriousManWindow = {}
|
||||||
|
Window.register("mysterious_man", MysteriousManWindow)
|
||||||
|
|
||||||
|
EndWindow = {}
|
||||||
|
Window.register("end", EndWindow)
|
||||||
|
|||||||
Reference in New Issue
Block a user