Compare commits

..

4 Commits

Author SHA1 Message Date
7697b35336 input remapping + mouse control
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2026-04-02 18:39:36 +02:00
6e1cf1db3e remove situation management 2026-04-02 15:32:20 +02:00
020bfd4134 set version to beta2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-23 07:02:39 +01:00
8e610f14a0 new ddr2 game
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2026-03-22 23:47:12 +01:00
31 changed files with 184 additions and 180 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.claude
.local .local
impostor.lua impostor.lua
impostor.original.lua impostor.original.lua
@@ -5,4 +6,4 @@ prompts
docs docs
minify.lua minify.lua
*.tic *.tic
*.zip *.zip

View File

@@ -10,7 +10,6 @@ globals = {
"Discussion", "Discussion",
"Util", "Util",
"Decision", "Decision",
"Situation",
"Screen", "Screen",
"Sprite", "Sprite",
"UI", "UI",
@@ -66,6 +65,10 @@ globals = {
"map", "map",
"time", "time",
"RLE", "RLE",
"mouse",
"Mouse",
"print",
"musicator_generate_pattern",
} }

View File

@@ -6,6 +6,7 @@ init/init.context.lua
system/system.util.lua system/system.util.lua
system/system.print.lua system/system.print.lua
system/system.input.lua system/system.input.lua
system/system.mouse.lua
system/system.asciiart.lua system/system.asciiart.lua
system/system.rle.lua system/system.rle.lua
logic/logic.meter.lua logic/logic.meter.lua
@@ -38,10 +39,7 @@ sprite/sprite.matrix_architect.lua
sprite/sprite.matrix_neo.lua sprite/sprite.matrix_neo.lua
sprite/sprite.matrix_oraculum.lua sprite/sprite.matrix_oraculum.lua
sprite/sprite.matrix_trinity.lua sprite/sprite.matrix_trinity.lua
situation/situation.manager.lua
situation/situation.drink_coffee.lua
decision/decision.manager.lua decision/decision.manager.lua
decision/decision.have_a_coffee.lua
decision/decision.go_to_home.lua 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

View File

@@ -1,16 +0,0 @@
Decision.register({
id = "have_a_coffee",
label = "Have a Coffee",
handle = function()
local new_situation_id = Situation.apply("drink_coffee", Context.game.current_screen)
local level = Ascension.get_level()
local disc_id = "coworker_disc_0"
-- TODO: Add more discussions for levels above 3
if level >= 1 and level <= 3 then
local suffix = Context.have_done_work_today and ("_asc_" .. level) or ("_" .. level)
disc_id = "coworker_disc" .. suffix
end
Discussion.start(disc_id, "game")
Context.game.current_situation = new_situation_id
end,
})

View File

@@ -134,6 +134,7 @@ end
--- @param decisions table A table of decision items.<br/> --- @param decisions table A table of decision items.<br/>
--- @param selected_decision_index number The current index of the selected decision.<br/> --- @param selected_decision_index number The current index of the selected decision.<br/>
--- @return number selected_decision_index The updated index of the selected decision. --- @return number selected_decision_index The updated index of the selected decision.
--- @return boolean mouse_confirmed True if the user clicked the center to confirm.
function Decision.update(decisions, selected_decision_index) function Decision.update(decisions, selected_decision_index)
if Input.left() then if Input.left() then
Audio.sfx_beep() Audio.sfx_beep()
@@ -142,5 +143,27 @@ function Decision.update(decisions, selected_decision_index)
Audio.sfx_beep() Audio.sfx_beep()
selected_decision_index = Util.safeindex(decisions, selected_decision_index + 1) selected_decision_index = Util.safeindex(decisions, selected_decision_index + 1)
end end
return selected_decision_index
if Mouse.clicked() then
local mx = Mouse.x()
local my = Mouse.y()
local bar_height = 16
local bar_y = Config.screen.height - bar_height
if my >= bar_y then
if mx < 15 then
Audio.sfx_beep()
Mouse.consume()
selected_decision_index = Util.safeindex(decisions, selected_decision_index - 1)
elseif mx > Config.screen.width - 15 then
Audio.sfx_beep()
Mouse.consume()
selected_decision_index = Util.safeindex(decisions, selected_decision_index + 1)
else
Mouse.consume()
return selected_decision_index, true
end
end
end
return selected_decision_index, false
end end

View File

@@ -23,7 +23,7 @@ Context = {}
--- * have_met_sumphore (boolean) Whether the player has talked to the homeless guy.<br/> --- * have_met_sumphore (boolean) Whether the player has talked to the homeless guy.<br/>
--- * have_been_to_office (boolean) Whether the player has been to the office.<br/> --- * have_been_to_office (boolean) Whether the player has been to the office.<br/>
--- * have_done_work_today (boolean) Whether the player has done work today.<br/> --- * have_done_work_today (boolean) Whether the player has done work today.<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<br/>
function Context.initial_data() function Context.initial_data()
return { return {
current_menu_item = 1, current_menu_item = 1,
@@ -48,7 +48,6 @@ function Context.initial_data()
have_met_sumphore = false, have_met_sumphore = false,
game = { game = {
current_screen = "home", current_screen = "home",
current_situation = nil,
}, },
day_count = 1, day_count = 1,
delta_time = 0, delta_time = 0,

View File

@@ -3,12 +3,12 @@ Util = {}
Meter = {} Meter = {}
Minigame = {} Minigame = {}
Decision = {} Decision = {}
Situation = {}
Screen = {} Screen = {}
Map = {} Map = {}
UI = {} UI = {}
Print = {} Print = {}
Input = {} Input = {}
Mouse = {}
Sprite = {} Sprite = {}
Audio = {} Audio = {}
Focus = {} Focus = {}

View File

@@ -4,5 +4,5 @@
-- desc: Life of a programmer -- desc: Life of a programmer
-- site: https://git.teletype.hu/games/impostor -- site: https://git.teletype.hu/games/impostor
-- license: MIT License -- license: MIT License
-- version: 1.0-beta1 -- version: 1.0-beta2
-- script: lua -- script: lua

View File

@@ -8,7 +8,6 @@ local _screens = {}
--- @param screen_data.name string Display name of the screen. --- @param screen_data.name string Display name of the screen.
--- @param screen_data.decisions table Array of decision ID strings available on this screen. --- @param screen_data.decisions table Array of decision ID strings available on this screen.
--- @param screen_data.background string Map ID used as background. --- @param screen_data.background string Map ID used as background.
--- @param[opt] screen_data.situations table Array of situation ID strings. Defaults to {}.
--- @param[opt] screen_data.init function Called when the screen is entered. Defaults to noop. --- @param[opt] screen_data.init function Called when the screen is entered. Defaults to noop.
--- @param[opt] screen_data.update function Called each frame while screen is active. Defaults to noop. --- @param[opt] screen_data.update function Called each frame while screen is active. Defaults to noop.
--- @param[opt] screen_data.draw function Called after the focus overlay to draw screen-specific overlays. Defaults to noop. --- @param[opt] screen_data.draw function Called after the focus overlay to draw screen-specific overlays. Defaults to noop.
@@ -16,9 +15,6 @@ function Screen.register(screen_data)
if _screens[screen_data.id] then if _screens[screen_data.id] then
trace("Warning: Overwriting screen with id: " .. screen_data.id) trace("Warning: Overwriting screen with id: " .. screen_data.id)
end end
if not screen_data.situations then
screen_data.situations = {}
end
if not screen_data.init then if not screen_data.init then
screen_data.init = function() end screen_data.init = function() end
end end
@@ -43,7 +39,6 @@ end
--- * name (string) Display name.<br/> --- * name (string) Display name.<br/>
--- * decisions (table) Array of decision ID strings.<br/> --- * decisions (table) Array of decision ID strings.<br/>
--- * background (string) Map ID used as background.<br/> --- * background (string) Map ID used as background.<br/>
--- * situations (table) Array of situation ID strings.<br/>
--- * init (function) Called when the screen is entered.<br/> --- * init (function) Called when the screen is entered.<br/>
--- * update (function) Called each frame while screen is active. --- * update (function) Called each frame while screen is active.
function Screen.get_by_id(screen_id) function Screen.get_by_id(screen_id)
@@ -58,7 +53,6 @@ end
--- * name (string) Display name of the screen.<br/> --- * name (string) Display name of the screen.<br/>
--- * decisions (table) Array of decision ID strings available on this screen.<br/> --- * decisions (table) Array of decision ID strings available on this screen.<br/>
--- * background (string) Map ID used as background.<br/> --- * background (string) Map ID used as background.<br/>
--- * situations (table) Array of situation ID strings.<br/>
--- * init (function) Called when the screen is entered.<br/> --- * init (function) Called when the screen is entered.<br/>
--- * update (function) Called each frame while screen is active.<br/> --- * update (function) Called each frame while screen is active.<br/>
function Screen.get_all() function Screen.get_all()

View File

@@ -240,9 +240,12 @@ Screen.register({
end end
end end
elseif state == STATE_CHOICE then elseif state == STATE_CHOICE then
selected_choice = UI.update_menu(MysteriousManScreen.choices, selected_choice) local menu_x = (Config.screen.width - 60) / 2
local menu_y = (Config.screen.height - 20) / 2
local confirmed
selected_choice, confirmed = UI.update_menu(MysteriousManScreen.choices, selected_choice, menu_x, menu_y)
if Input.select() then if Input.select() or confirmed then
Audio.sfx_select() Audio.sfx_select()
if selected_choice == 1 then if selected_choice == 1 then
MysteriousManScreen.wake_up() MysteriousManScreen.wake_up()

View File

@@ -6,9 +6,6 @@ Screen.register({
"go_to_walking_to_home", "go_to_walking_to_home",
"have_a_coffee", "have_a_coffee",
}, },
situations = {
"drink_coffee",
},
init = function() init = function()
Audio.music_play_room_work() Audio.music_play_room_work()
end, end,

View File

@@ -16,7 +16,7 @@ Screen.register({
end, end,
update = function() update = function()
if not Context.stat_screen_active then return end if not Context.stat_screen_active then return end
if Input.select() or Input.player_interact() then if Input.select() or Input.select() then
Focus.stop() Focus.stop()
Context.stat_screen_active = false Context.stat_screen_active = false
Meter.show() Meter.show()

View File

@@ -1,6 +0,0 @@
Situation.register({
id = "drink_coffee",
handle = function()
Audio.sfx_select()
end,
})

View File

@@ -1,84 +0,0 @@
--- @section Situation
local _situations = {}
--- Registers a situation definition.
--- @within Situation
--- @param situation table The situation data table.
--- @param situation.id string Unique situation identifier.<br/>
--- @param[opt] situation.screen_id string ID of the screen this situation belongs to.<br/>
--- @param[opt] situation.handle function Called when the situation is applied. Defaults to noop.<br/>
--- @param[opt] situation.update function Called each frame while situation is active. Defaults to noop.<br/>
function Situation.register(situation)
if not situation or not situation.id then
PopupWindow.show({"Error: Invalid situation object registered (missing id)!"})
return
end
if not situation.handle then
situation.handle = function() end
end
if not situation.update then
situation.update = function() end
end
if _situations[situation.id] then
trace("Warning: Overwriting situation with id: " .. situation.id)
end
_situations[situation.id] = situation
end
--- Gets a situation by ID.
--- @within Situation
--- @param id string The situation ID.
--- @return result table The situation table or nil. </br>
--- Fields: </br>
--- * id (string) Unique situation identifier.<br/>
--- * screen_id (string) ID of the screen this situation belongs to.<br/>
--- * handle (function) Called when the situation is applied.<br/>
--- * update (function) Called each frame while situation is active.<br/>
function Situation.get_by_id(id)
return _situations[id]
end
--- Gets all registered situations, optionally filtered by screen ID.
--- @within Situation
--- @param screen_id string Optional. If provided, returns situations associated with this screen ID.
--- @return result table A table containing all registered situation data, indexed by their IDs, or an array filtered by screen_id. </br>
--- Fields: </br>
--- * id (string) Unique situation identifier.<br/>
--- * screen_id (string) ID of the screen this situation belongs to.<br/>
--- * handle (function) Called when the situation is applied.<br/>
--- * update (function) Called each frame while situation is active.<br/>
function Situation.get_all(screen_id)
if screen_id then
local filtered_situations = {}
for _, situation in pairs(_situations) do
if situation.screen_id == screen_id then
table.insert(filtered_situations, situation)
end
end
return filtered_situations
end
return _situations
end
--- Applies a situation, checking screen compatibility and returning the new situation ID if successful.
--- @within Situation
--- @param id string The situation ID to apply.
--- @param current_screen_id string The ID of the currently active screen.
--- @return string|nil The ID of the applied situation if successful, otherwise nil.
function Situation.apply(id, current_screen_id)
local situation = Situation.get_by_id(id)
local screen = Screen.get_by_id(current_screen_id)
if not situation then
trace("Error: No situation found with id: " .. id)
return nil
end
if Util.contains(screen.situations, id) then
situation.handle()
return id
else
trace("Info: Situation " .. id .. " cannot be applied to current screen (id: " .. current_screen_id .. ").")
return nil
end
end

View File

@@ -3,12 +3,9 @@ local INPUT_KEY_UP = 0
local INPUT_KEY_DOWN = 1 local INPUT_KEY_DOWN = 1
local INPUT_KEY_LEFT = 2 local INPUT_KEY_LEFT = 2
local INPUT_KEY_RIGHT = 3 local INPUT_KEY_RIGHT = 3
local INPUT_KEY_A = 4
local INPUT_KEY_B = 5
local INPUT_KEY_Y = 7 local INPUT_KEY_Y = 7
local INPUT_KEY_SPACE = 48 local INPUT_KEY_SPACE = 48
local INPUT_KEY_BACKSPACE = 51 local INPUT_KEY_BACKSPACE = 51
local INPUT_KEY_ENTER = 50
--- Checks if Up is pressed. --- Checks if Up is pressed.
--- @within Input --- @within Input
@@ -22,22 +19,9 @@ function Input.left() return btnp(INPUT_KEY_LEFT) end
--- Checks if Right is pressed. --- Checks if Right is pressed.
--- @within Input --- @within Input
function Input.right() return btnp(INPUT_KEY_RIGHT) end function Input.right() return btnp(INPUT_KEY_RIGHT) end
--- Checks if Space is pressed.
--- @within Input
function Input.space() return keyp(INPUT_KEY_SPACE) end
--- Checks if Select is pressed. --- Checks if Select is pressed.
--- @within Input --- @within Input
function Input.select() return btnp(INPUT_KEY_A) or keyp(INPUT_KEY_SPACE) end function Input.select() return btnp(INPUT_KEY_Y) or keyp(INPUT_KEY_SPACE) or Mouse.clicked() end
--- Checks if Menu Confirm is pressed. --- Checks if Back is pressed.
--- @within Input --- @within Input
function Input.menu_confirm() return btnp(INPUT_KEY_A) or keyp(INPUT_KEY_ENTER) end function Input.back() return keyp(INPUT_KEY_BACKSPACE) end
--- Checks if Player Interact is pressed.
--- @within Input
function Input.player_interact() return btnp(INPUT_KEY_B) or keyp(INPUT_KEY_ENTER) end
--- Checks if Menu Back is pressed.
--- @within Input
function Input.menu_back() return btnp(INPUT_KEY_Y) or keyp(INPUT_KEY_BACKSPACE) end
--- Checks if Toggle Popup is pressed.
--- @within Input
function Input.toggle_popup() return keyp(INPUT_KEY_ENTER) end

View File

@@ -17,6 +17,7 @@ end
--- @within Main --- @within Main
function TIC() function TIC()
init_game() init_game()
Mouse.update()
local now = time() local now = time()
if Context.last_frame_time == 0 then if Context.last_frame_time == 0 then

View File

@@ -0,0 +1,43 @@
--- @section Mouse
local _mx, _my = 0, 0
local _mleft, _mleft_prev = false, false
local _consumed = false
--- Updates mouse state. Call once per frame.
--- @within Mouse
function Mouse.update()
_mleft_prev = _mleft
_consumed = false
local mt = {mouse()}
_mx, _my, _mleft = mt[1], mt[2], mt[3]
end
--- Returns current mouse X position.
--- @within Mouse
function Mouse.x() return _mx end
--- Returns current mouse Y position.
--- @within Mouse
function Mouse.y() return _my end
--- Returns true if the mouse button was just pressed this frame (and not yet consumed).
--- @within Mouse
function Mouse.clicked() return _mleft and not _mleft_prev and not _consumed end
--- Returns true if the mouse button is held down.
--- @within Mouse
function Mouse.held() return _mleft end
--- Marks the current click as consumed so Mouse.clicked() won't fire again this frame.
--- @within Mouse
function Mouse.consume() _consumed = true end
--- Returns true if the mouse is within the given rectangle.
--- @within Mouse
--- @param x number Left edge.
--- @param y number Top edge.
--- @param w number Width.
--- @param h number Height.
function Mouse.in_rect(x, y, w, h)
return _mx >= x and _mx < x + w and _my >= y and _my < y + h
end

View File

@@ -38,8 +38,12 @@ end
--- @within UI --- @within UI
--- @param items table A table of menu items.<br/> --- @param items table A table of menu items.<br/>
--- @param selected_item number The current index of the selected item.<br/> --- @param selected_item number The current index of the selected item.<br/>
--- @param[opt] x number Menu x position (required for mouse support).<br/>
--- @param[opt] y number Menu y position (required for mouse support).<br/>
--- @param[opt] centered boolean Whether the menu is centered horizontally.<br/>
--- @return number selected_item The updated index of the selected item. --- @return number selected_item The updated index of the selected item.
function UI.update_menu(items, selected_item) --- @return boolean mouse_confirmed True if the user clicked on a menu item.
function UI.update_menu(items, selected_item, x, y, centered)
if Input.up() then if Input.up() then
Audio.sfx_beep() Audio.sfx_beep()
selected_item = selected_item - 1 selected_item = selected_item - 1
@@ -53,7 +57,29 @@ function UI.update_menu(items, selected_item)
selected_item = 1 selected_item = 1
end end
end end
return selected_item
if x ~= nil and y ~= nil and Mouse.clicked() then
local mx = Mouse.x()
local my = Mouse.y()
local menu_x = x
if centered then
local max_w = 0
for _, item in ipairs(items) do
local w = print(item.label, 0, -10, 0, false, 1, false)
if w > max_w then max_w = w end
end
menu_x = (Config.screen.width - max_w) / 2
end
for i, _ in ipairs(items) do
local item_y = y + (i - 1) * 10
if my >= item_y and my < item_y + 10 and mx >= menu_x - 8 then
Mouse.consume()
return i, true
end
end
end
return selected_item, false
end end
--- Draws a bordered textbox with scrolling text. --- Draws a bordered textbox with scrolling text.

View File

@@ -107,9 +107,9 @@ function AudioTestWindow.update()
AudioTestWindow.menuitems = AudioTestWindow.generate_menuitems( AudioTestWindow.menuitems = AudioTestWindow.generate_menuitems(
AudioTestWindow.list_func, AudioTestWindow.index_func AudioTestWindow.list_func, AudioTestWindow.index_func
) )
elseif Input.menu_confirm() then elseif Input.select() then
AudioTestWindow.menuitems[AudioTestWindow.index_menu].decision() AudioTestWindow.menuitems[AudioTestWindow.index_menu].decision()
elseif Input.menu_back() then elseif Input.back() then
AudioTestWindow.back() AudioTestWindow.back()
end end
end end

View File

@@ -65,7 +65,7 @@ end
--- Updates configuration window logic. --- Updates configuration window logic.
--- @within ConfigurationWindow --- @within ConfigurationWindow
function ConfigurationWindow.update() function ConfigurationWindow.update()
if Input.menu_back() then if Input.back() then
GameWindow.set_state("menu") GameWindow.set_state("menu")
return return
end end
@@ -94,7 +94,7 @@ function ConfigurationWindow.update()
control.set(new_value) control.set(new_value)
end end
elseif control.type == "action_item" then elseif control.type == "action_item" then
if Input.menu_confirm() then if Input.select() then
control.action() control.action()
end end
end end

View File

@@ -26,7 +26,7 @@ end
--- @within ContinuedWindow --- @within ContinuedWindow
function ContinuedWindow.update() function ContinuedWindow.update()
ContinuedWindow.timer = ContinuedWindow.timer - 1 ContinuedWindow.timer = ContinuedWindow.timer - 1
if ContinuedWindow.timer <= 0 or Input.select() or Input.menu_confirm() then if ContinuedWindow.timer <= 0 or Input.select() or Input.select() then
Window.set_current("menu") Window.set_current("menu")
MenuWindow.refresh_menu_items() MenuWindow.refresh_menu_items()
end end

View File

@@ -52,7 +52,7 @@ function EndWindow.update()
end end
end end
if Input.menu_confirm() then if Input.select() then
Audio.sfx_select() Audio.sfx_select()
if Context._end.selection == 1 then if Context._end.selection == 1 then
Context._end.state = "ending" Context._end.state = "ending"
@@ -69,7 +69,7 @@ function EndWindow.update()
end end
end end
elseif Context._end.state == "ending" then elseif Context._end.state == "ending" then
if Input.menu_confirm() then if Input.select() then
Window.set_current("menu") Window.set_current("menu")
MenuWindow.refresh_menu_items() MenuWindow.refresh_menu_items()
end end

View File

@@ -38,7 +38,7 @@ end
--- @within GameWindow --- @within GameWindow
function GameWindow.update() function GameWindow.update()
Focus.update() Focus.update()
if Input.menu_back() then if Input.back() then
Window.set_current("menu") Window.set_current("menu")
MenuWindow.refresh_menu_items() MenuWindow.refresh_menu_items()
return return
@@ -48,14 +48,6 @@ function GameWindow.update()
if not screen or not screen.update then return end if not screen or not screen.update then return end
screen.update() screen.update()
-- Handle current situation updates
if Context.game.current_situation then
local current_situation_obj = Situation.get_by_id(Context.game.current_situation)
if current_situation_obj and type(current_situation_obj.update) == "function" then
current_situation_obj.update()
end
end
if Context.stat_screen_active then return end if Context.stat_screen_active then return end
-- Fetch and filter decisions locally -- Fetch and filter decisions locally
@@ -68,7 +60,7 @@ function GameWindow.update()
_selected_decision_index = 1 _selected_decision_index = 1
end end
local new_selected_decision_index = Decision.update( local new_selected_decision_index, mouse_confirmed = Decision.update(
_available_decisions, _available_decisions,
_selected_decision_index _selected_decision_index
) )
@@ -77,7 +69,7 @@ function GameWindow.update()
_selected_decision_index = new_selected_decision_index _selected_decision_index = new_selected_decision_index
end end
if Input.select() then if Input.select() or mouse_confirmed then
local selected_decision = _available_decisions[_selected_decision_index] local selected_decision = _available_decisions[_selected_decision_index]
if selected_decision and selected_decision.handle then if selected_decision and selected_decision.handle then
Audio.sfx_select() Audio.sfx_select()

View File

@@ -31,7 +31,7 @@ function BriefIntroWindow.update()
lines = lines + 1 lines = lines + 1
end end
if BriefIntroWindow.y < -lines * 8 or Input.select() or Input.menu_confirm() then if BriefIntroWindow.y < -lines * 8 or Input.select() or Input.select() then
Window.set_current("menu") Window.set_current("menu")
end end
end end

View File

@@ -30,7 +30,7 @@ end
--- @within TitleIntroWindow --- @within TitleIntroWindow
function TitleIntroWindow.update() function TitleIntroWindow.update()
TitleIntroWindow.timer = TitleIntroWindow.timer - 1 TitleIntroWindow.timer = TitleIntroWindow.timer - 1
if TitleIntroWindow.timer <= 0 or Input.select() or Input.menu_confirm() then if TitleIntroWindow.timer <= 0 or Input.select() or Input.select() then
Window.set_current("intro_ttg") Window.set_current("intro_ttg")
end end
end end

View File

@@ -28,12 +28,12 @@ function TTGIntroWindow.update()
end end
-- Count menu_back presses during the intro -- Count menu_back presses during the intro
if Input.menu_back() then if Input.back() then
TTGIntroWindow.space_count = TTGIntroWindow.space_count + 1 TTGIntroWindow.space_count = TTGIntroWindow.space_count + 1
end end
TTGIntroWindow.timer = TTGIntroWindow.timer - 1 TTGIntroWindow.timer = TTGIntroWindow.timer - 1
if TTGIntroWindow.timer <= 0 or Input.menu_confirm() then if TTGIntroWindow.timer <= 0 or Input.select() then
-- Evaluate exactly 3 presses at the end of the intro -- Evaluate exactly 3 presses at the end of the intro
if TTGIntroWindow.space_count == 3 then if TTGIntroWindow.space_count == 3 then
Context.test_mode = true Context.test_mode = true

View File

@@ -1,5 +1,6 @@
--- @section MenuWindow --- @section MenuWindow
local _menu_items = {} local _menu_items = {}
local _click_timer = 0
--- Draws the menu window. --- Draws the menu window.
--- @within MenuWindow --- @within MenuWindow
@@ -22,9 +23,28 @@ end
--- Updates the menu window logic. --- Updates the menu window logic.
--- @within MenuWindow --- @within MenuWindow
function MenuWindow.update() function MenuWindow.update()
Context.current_menu_item = UI.update_menu(_menu_items, Context.current_menu_item) local menu_h = #_menu_items * 10
local y = 10 + (Config.screen.height - 10 - 10 - menu_h) / 2
if Input.menu_confirm() then if _click_timer > 0 then
_click_timer = _click_timer - Context.delta_time
if _click_timer <= 0 then
_click_timer = 0
local selected_item = _menu_items[Context.current_menu_item]
if selected_item and selected_item.decision then
selected_item.decision()
end
end
return
end
local new_item, mouse_confirmed = UI.update_menu(_menu_items, Context.current_menu_item, 0, y, true)
Context.current_menu_item = new_item
if mouse_confirmed then
Audio.sfx_select()
_click_timer = 0.5
elseif Input.select() then
local selected_item = _menu_items[Context.current_menu_item] local selected_item = _menu_items[Context.current_menu_item]
if selected_item and selected_item.decision then if selected_item and selected_item.decision then
Audio.sfx_select() Audio.sfx_select()
@@ -115,4 +135,5 @@ function MenuWindow.refresh_menu_items()
table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit}) table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit})
Context.current_menu_item = 1 Context.current_menu_item = 1
_click_timer = 0
end end

View File

@@ -3,10 +3,10 @@
--- Background drawing for DDR minigame. --- Background drawing for DDR minigame.
--- @witin MinigameDDRWindow --- @witin MinigameDDRWindow
function MinigameDDRWindow.draw_background() function MinigameDDRWindow.draw_background()
local img_values = {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1} local img_values = {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1}
local img_runs = {213,27,213,27,212,28,212,28,211,29,212,28,212,28,212,28,211,29,211,29,126,16,69,29,136,9,66,29,210,30,80,1,129,30,80,1,78,1,51,29,80,1,78,1,51,29,80,2,77,1,51,28,81,2,76,2,51,28,81,2,76,2,50,29,81,2,76,2,51,28,81,2,76,2,50,29,81,2,76,2,50,28,82,2,75,3,50,28,81,4,74,3,50,28,81,4,74,3,51,27,81,4,74,3,50,27,82,4,74,3,50,27,82,4,74,3,51,26,82,4,73,4,50,27,82,4,73,4,51,25,83,4,73,4,50,26,83,4,2,2,69,4,50,26,83,5,1,2,27,7,35,4,50,26,83,9,23,13,28,1,3,4,50,26,83,9,5,2,15,15,27,2,2,4,50,25,84,9,3,5,14,16,26,3,1,4,51,24,84,9,3,6,13,16,26,8,51,24,85,8,3,5,15,14,27,8,50,25,85,8,26,9,29,8,50,25,85,8,63,9,51,23,86,8,63,9,51,23,86,8,63,9,51,23,86,8,12,3,13,5,30,9,51,23,86,8,12,3,12,7,29,8,52,22,87,8,28,5,30,8,53,21,87,8,63,8,52,22,87,8,63,8,52,22,87,8,62,9,52,21,88,8,62,9,52,21,88,8,62,9,52,21,88,8,62,9,52,21,88,8,62,9,51,22,88,8,62,9,51,21,89,8,62,9,52,20,89,8,62,9,52,20,89,8,62,9,52,20,89,8,62,9,52,20,89,8,62,9,52,19,90,9,61,9,53,18,90,9,61,9,53,18,90,9,61,8,53,19,90,9,61,8,53,18,91,9,61,8,53,18,91,9,60,9,52,19,91,10,59,9,52,19,91,10,59,9,51,20,91,16,1,2,48,11,51,19,93,77,51,19,93,77,52,18,93,77,51,19,93,77,51,19,93,77,50,19,94,76,51,19,94,12,1,63,51,19,94,75,52,19,94,4,12,46,2,9,54,19,94,2,33,24,68,19,220,20,220,19,220,20,220,20,220,20,89,6,125,19,88,9,76,4,43,20,87,11,74,6,42,20,86,12,73,8,39,22,86,69,15,10,37,23,85,82,3,11,36,22,85,98,35,22,84,100,33,23,83,102,31,24,82,104,29,25,81,106,27,26,80,108,26,25,80,110,25,25,79,112,24,25,78,113,24,25,77,115,23,25,77,116,22,24,78,2,11,104,20,25,78,1,65,51,20,25,78,1,115,1,21,23,79,1,115,1,21,23,79,1,115,1,20,24,79,1,115,1,20,24,79,1,115,1,20,24,79,1,74,10,6,1,24,1,21,22,80,1,75,9,4,7,20,1,21,22,80,1,75,9,4,7,20,1,20,23,80,1,76,8,4,7,20,1,21,22,80,1,115,1,22,20,81,1,115,1,23,19,197,1,24,18,197,1,25,17,223,17,224,16,226,13,228,12,228,12,229,11,81,4,145,9,80,9,137,3,3,8,73,3,8,122,21,3,3,7,72,3,129,4,19,4,3,6,71,3,131,4,19,4,3,5,71,2,13,8,5,8,99,4,18,5,4,2,71,3,11,10,5,8,100,3,17,7,4,1,71,2,8,30,97,4,16,8,74,3,136,4,14,10,72,3,138,3,14,11,71,3,10,3,9,3,3,3,3,3,4,2,95,4,13,12,69,3,10,4,8,4,3,3,3,3,3,3,7,4,2,4,2,4,2,4,6,4,2,4,2,4,2,4,2,4,5,4,2,4,2,4,2,4,6,3,12,13,69,2,10,5,8,4,2,4,2,4,3,3,7,4,2,4,2,4,2,4,6,4,2,4,2,4,2,4,2,4,5,4,2,4,2,4,2,4,6,4,11,13,68,3,10,5,1,2,5,4,3,3,2,4,3,3,7,4,2,3,3,4,2,4,6,4,2,4,2,4,2,4,2,4,5,4,2,5,1,4,3,3,7,4,10,13,68,2,11,5,1,2,20,1,5,1,7,3,5,1,6,1,2,1,1,1,9,2,3,3,3,3,3,3,2,1,1,2,6,3,4,2,3,3,5,1,7,4,9,13,68,3,10,6,1,2,33,2,1,1,3,1,4,3,2,9,4,3,3,3,3,3,2,5,1,5,6,2,4,3,4,3,2,3,7,4,8,13,67,3,13,4,3,2,19,1,5,1,5,1,4,3,4,2,4,3,3,2,4,3,3,3,3,3,2,5,2,4,6,3,3,3,4,3,3,2,8,4,7,13,67,3,13,4,17,1,11,2,5,1,4,3,4,2,4,2,4,2,4,3,3,3,4,2,3,4,2,4,6,3,4,3,3,3,3,3,7,4,7,13,66,3,14,4,29,1,12,1,4,1,1,1,4,2,4,2,4,2,4,3,4,3,2,4,2,4,6,3,4,2,4,3,3,3,8,4,6,13,66,2,14,5,83,11,21,1,14,4,7,12,65,3,14,5,31,1,1,1,10,2,5,2,5,1,6,1,5,1,5,2,4,11,8,2,4,2,5,1,5,2,8,4,6,11,66,2,14,6,1,2,8,3,4,2,4,3,4,3,3,3,4,3,3,3,3,4,3,3,4,3,4,2,2,11,10,2,4,3,4,2,4,2,8,5,5,11,65,3,14,6,1,2,1,3,4,3,4,2,4,3,4,3,3,3,4,3,3,3,3,4,3,3,3,4,3,16,10,2,4,3,4,2,4,3,8,4,5,11,64,3,15,9,42,1,4,2,4,3,4,3,4,2,5,16,15,1,12,3,9,4,4,11,64,3,10,2,3,8,31,1,18,2,4,2,19,13,11,2,5,1,6,1,15,4,4,11,63,3,9,4,2,7,1,1,11,1,5,2,5,2,5,1,5,2,4,3,4,3,3,3,5,2,4,3,1,12,2,2,11,3,4,2,5,2,2,4,9,4,4,9,64,2,10,4,2,7,1,2,3,1,4,3,4,3,4,3,5,1,4,3,4,3,3,4,3,3,4,3,4,15,3,2,11,3,5,2,4,9,8,5,4,8,63,3,9,5,2,8,4,2,4,3,4,3,3,4,3,3,4,3,4,3,3,4,3,3,4,3,3,17,2,3,10,3,4,3,3,11,8,5,4,7,62,3,10,4,2,10,30,2,4,3,4,3,3,4,3,3,4,3,3,4,1,12,1,4,10,3,4,4,2,4,3,5,7,5,4,7,62,3,10,3,3,9,76,11,1,4,10,2,4,4,6,1,3,5,8,5,1,9,61,3,9,5,3,8,2,2,46,1,5,2,5,2,10,18,10,3,3,5,5,1,3,6,8,14,61,3,9,5,2,9,1,4,8,3,4,3,4,3,4,3,5,2,4,3,4,3,4,3,5,2,2,13,1,5,10,3,3,6,5,2,1,6,8,13,61,3,10,5,2,13,9,3,4,3,4,3,4,3,11,3,4,3,4,3,9,19,11,2,2,7,4,2,2,7,8,12,60,3,11,5,2,13,58,1,11,20,10,12,3,11,8,12,60,3,24,6,71,20,11,1,8,2,9,5,9,11,59,3,40,4,3,5,2,6,1,35,17,9,45,11,59,3,36,61,16,9,46,10,58,3,37,60,17,10,46,8,58,4,114,10,46,8,58,3,116,9,47,7,57,4,172,6,58,3,174,5,57,5,173,6,55,60,73,52,55,4,118,64,53,4,119,64,53,4,120,63,53,4,120,63,53,6,10,3,104,64,53,187,54,186,55,184,59,180,82,7,25,63,2,5,6,5,16,4,9,14,214,2,238,1,239,3,776} local img_runs = {809,40,5,26,178,42,4,7,30,10,127,103,11,1,116,124,116,124,115,18,60,47,115,10,105,10,115,9,108,9,114,9,108,9,114,9,108,9,114,9,33,31,44,9,114,9,34,28,46,9,114,9,108,9,114,9,108,9,114,9,108,9,114,9,108,9,114,9,109,8,114,9,109,8,114,9,109,9,112,10,105,1,3,9,111,11,104,2,3,9,111,11,101,5,3,9,111,11,101,5,3,9,111,9,103,5,3,9,111,9,99,1,2,6,3,9,111,9,99,1,2,8,1,9,111,9,3,1,88,1,3,1,2,11,1,9,111,9,3,1,88,1,3,14,1,9,111,9,3,1,88,1,3,1,2,11,1,9,111,9,3,1,88,1,5,12,1,9,111,9,3,1,88,1,3,14,1,9,111,9,3,1,88,3,1,1,2,11,1,9,111,9,3,1,88,3,1,14,1,9,111,9,3,1,88,3,2,13,2,8,111,9,3,1,88,3,3,12,3,8,110,9,3,1,88,3,3,12,3,9,109,9,3,1,88,3,1,14,3,9,109,9,3,1,90,1,1,7,3,4,3,9,109,9,3,1,90,1,1,5,6,3,3,9,108,10,3,1,44,1,4,1,40,1,1,5,7,2,3,9,108,10,3,1,44,1,4,1,38,3,1,5,7,3,2,9,108,10,3,1,48,1,39,3,1,5,7,2,3,9,108,10,3,1,88,3,1,5,6,3,3,9,108,10,3,1,32,5,4,4,3,2,38,3,1,15,2,9,108,10,3,1,41,5,2,2,2,4,32,3,1,15,2,9,108,10,2,2,41,9,2,5,3,1,3,1,23,3,1,9,1,5,2,9,108,10,2,2,41,12,35,3,1,7,4,4,2,9,108,10,2,2,32,26,30,3,1,5,7,3,2,9,108,10,2,2,36,21,31,9,7,3,2,9,108,10,2,2,35,23,30,10,6,3,2,9,108,10,2,2,35,23,30,11,4,4,2,9,108,10,2,2,34,24,30,19,2,9,108,10,2,2,33,25,30,19,2,9,108,10,2,2,32,28,28,19,2,9,108,10,2,2,32,30,26,19,2,9,108,10,2,2,33,31,24,19,2,9,108,10,2,4,37,17,32,19,2,10,107,10,2,5,85,19,2,10,107,10,2,109,2,10,107,12,1,107,3,10,107,133,107,133,107,133,107,133,107,133,107,133,107,133,118,111,129,6,63,3,28,10,121,13,98,6,142,7,76,6,129,10,13,5,77,15,109,4,31,4,78,4,24,7,75,173,66,176,64,177,62,178,62,178,62,56,31,2,7,2,2,3,2,1,2,1,61,8,62,56,114,8,62,56,114,8,62,56,114,8,62,56,114,8,62,9,8,39,114,9,61,8,9,39,114,9,61,8,9,39,114,9,61,8,9,39,114,9,61,8,9,39,114,9,61,8,9,39,114,9,61,8,9,39,115,8,61,8,8,40,115,8,61,56,115,8,61,13,2,1,1,1,1,16,1,1,2,17,115,8,61,13,2,1,1,1,2,1,1,10,2,1,1,1,2,1,2,7,1,6,115,8,60,14,2,1,1,1,5,9,2,1,1,1,2,1,2,6,2,6,115,8,59,15,2,1,1,1,5,9,2,1,1,1,2,1,2,6,2,6,115,8,59,15,2,1,1,1,6,8,2,1,1,1,2,1,2,14,115,8,59,6,1,11,1,1,7,10,1,1,2,1,2,14,115,8,59,6,1,11,1,1,7,10,1,1,2,1,2,1,1,12,115,9,58,6,1,1,2,10,9,8,1,1,2,1,2,1,1,12,115,9,58,6,1,1,2,8,1,1,9,8,1,1,2,1,2,1,1,11,116,9,58,6,1,1,2,1,2,7,9,8,1,1,2,1,2,1,1,11,116,9,58,6,1,1,2,1,2,7,9,10,2,1,2,1,1,11,116,9,58,57,116,9,58,58,115,9,102,13,116,9,58,48,2,10,1,3,22,84,5,7,58,158,7,5,6,6,75,3,7,2,7,1,7,2,6,1,6,2,6,2,4,4,6,2,6,1,6,2,6,3,6,1,6,5,7,8,7,9,11,1,9,2,50,1,22,1,14,5,3,5,3,4,3,6,3,5,2,16,2,5,3,14,2,6,2,6,5,5,11,4,30,1,50,1,37,6,3,5,3,5,2,6,3,5,3,6,1,7,2,6,2,15,2,6,2,5,6,5,12,1,15,1,106,93,2,8,10,5,2,6,2,5,4,4,100,7,3,13,2,65,3,8,3,5,2,5,4,4,3,5,4,4,100,94,2,5,3,5,4,4,6,5,2,5,105,86,2,13,3,5,4,4,6,5,2,1,1,3,102,4,2,24,2,62,1,1,2,7,3,5,4,5,4,5,2,8,4,2,92,5,2,24,2,61,5,5,7,2,5,6,3,4,3,7,102,88,6,7,12,8,6,1,3,7,103,87,6,7,11,9,6,1,3,7,110,1,9,9,5,1,2,1,3,47,162,1,10,6,27,34,162,1,10,6,27,34,97,3,57,14,2,7,26,66,9,33,5,2,17,223,17,223,18,222,47,193,53,1,3,163,19,1,85,109,14,29,36,151,784}
-- pal = {255,255,255,0,0,0} -- pal = {220,220,220,90,90,90}
-- pal = ffffff000000 -- pal = dcdcdc5a5a5a
RLE.draw(img_values, img_runs) RLE.draw(img_values, img_runs)
end end
@@ -355,6 +355,17 @@ function MinigameDDRWindow.update()
right = Input.right() right = Input.right()
} }
if Mouse.clicked() then
local mx = Mouse.x()
local my = Mouse.y()
for _, target in ipairs(mg.target_arrows) do
if mx >= target.x and mx < target.x + mg.arrow_size and
my >= mg.target_y and my < mg.target_y + mg.arrow_size then
input_map[target.dir] = true
end
end
end
for dir, pressed in pairs(input_map) do for dir, pressed in pairs(input_map) do
if pressed and mg.input_cooldowns[dir] == 0 then if pressed and mg.input_cooldowns[dir] == 0 then
mg.input_cooldowns[dir] = mg.input_cooldown_duration mg.input_cooldowns[dir] = mg.input_cooldown_duration

View File

@@ -83,7 +83,14 @@ function MinigameButtonMashWindow.update()
return return
end end
if Input.select() then local mouse_on_button = false
if Mouse.clicked() then
local dx = Mouse.x() - mg.button_x
local dy = Mouse.y() - mg.button_y
mouse_on_button = (dx * dx + dy * dy) <= (mg.button_size * mg.button_size)
end
if Input.select() or mouse_on_button then
Audio.sfx_drum_high() Audio.sfx_drum_high()
mg.bar_fill = mg.bar_fill + mg.fill_per_press mg.bar_fill = mg.bar_fill + mg.fill_per_press

View File

@@ -95,7 +95,14 @@ function MinigameRhythmWindow.update()
if mg.press_cooldown > 0 then if mg.press_cooldown > 0 then
mg.press_cooldown = mg.press_cooldown - 1 mg.press_cooldown = mg.press_cooldown - 1
end end
if Input.select() and mg.press_cooldown == 0 then local mouse_on_button = false
if Mouse.clicked() then
local dx = Mouse.x() - mg.button_x
local dy = Mouse.y() - mg.button_y
mouse_on_button = (dx * dx + dy * dy) <= (mg.button_size * mg.button_size)
end
if (Input.select() or mouse_on_button) and mg.press_cooldown == 0 then
mg.button_pressed_timer = mg.button_press_duration mg.button_pressed_timer = mg.button_press_duration
mg.press_cooldown = mg.press_cooldown_duration mg.press_cooldown = mg.press_cooldown_duration
local target_left = mg.target_center - (mg.target_width / 2) local target_left = mg.target_center - (mg.target_width / 2)

View File

@@ -28,7 +28,7 @@ end
--- @within PopupWindow --- @within PopupWindow
function PopupWindow.update() function PopupWindow.update()
if Context.popup.show then if Context.popup.show then
if Input.menu_confirm() or Input.menu_back() then if Input.select() or Input.back() then
PopupWindow.hide() PopupWindow.hide()
end end
end end