feat: added game over screen, fixed bar filling on ddr, applied tamagochi logic to game
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
59
inc/window/window.gameover.lua
Normal file
59
inc/window/window.gameover.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
--- @section GameOverWindow
|
||||
local GAME_OVER_ART = [[
|
||||
_###_ __#__ #___# #####
|
||||
#____ _#_#_ ##_## #____
|
||||
#_### ##### #_#_# ####_
|
||||
#___# #___# #___# #____
|
||||
_###_ #___# #___# #####
|
||||
|
||||
_###_ #___# ##### ####_
|
||||
#___# #___# #____ #___#
|
||||
#___# _#_#_ ####_ ####_
|
||||
#___# __#__ #____ #_#__
|
||||
_###_ __#__ ##### #__##
|
||||
]]
|
||||
|
||||
local REASON_MESSAGES = {
|
||||
ism = "Your impostor syndrome consumed you.",
|
||||
bm = "You burned out like a cheap candle.",
|
||||
days = "100 days passed. The cycle never broke.",
|
||||
}
|
||||
|
||||
--- Shows the game over screen.
|
||||
--- @within GameOverWindow
|
||||
--- @param reason string One of "ism", "bm", "days".
|
||||
function GameOverWindow.show(reason)
|
||||
GameOverWindow.reason = reason
|
||||
Context.game_in_progress = false
|
||||
Glitch.show()
|
||||
Window.set_current("game_over")
|
||||
end
|
||||
|
||||
--- Draws the game over screen.
|
||||
--- @within GameOverWindow
|
||||
function GameOverWindow.draw()
|
||||
cls(Config.colors.black)
|
||||
|
||||
local cx = Config.screen.width / 2
|
||||
local bounds = AsciiArt.draw(GAME_OVER_ART, {
|
||||
char_w = 4,
|
||||
char_h = 6,
|
||||
line_gap = 1,
|
||||
word_gap = 10,
|
||||
color = Config.colors.red,
|
||||
})
|
||||
|
||||
local msg = REASON_MESSAGES[GameOverWindow.reason] or ""
|
||||
Print.text_center(msg, cx, bounds.bottom + 8, Config.colors.white)
|
||||
Print.text_center("Press Z to restart", cx, Config.screen.height - 10, Config.colors.light_grey)
|
||||
end
|
||||
|
||||
--- Updates the game over screen logic.
|
||||
--- @within GameOverWindow
|
||||
function GameOverWindow.update()
|
||||
if Input.select() then
|
||||
Context.reset()
|
||||
MenuWindow.refresh_menu_items()
|
||||
Window.set_current("menu")
|
||||
end
|
||||
end
|
||||
@@ -130,6 +130,7 @@ function MinigameDDRWindow.on_arrow_hit_special(arrow, game_context)
|
||||
Audio.sfx_arrowhit(arrow.note)
|
||||
game_context.special_mode_counter = game_context.special_mode_counter + 1
|
||||
else
|
||||
game_context.total_misses = game_context.total_misses + 1
|
||||
if game_context.special_mode_condition then Audio.sfx_bloop() end
|
||||
game_context.special_mode_condition = false
|
||||
end
|
||||
@@ -141,10 +142,12 @@ function MinigameDDRWindow.on_arrow_hit_special(arrow, game_context)
|
||||
game_context.bar_fill = game_context.bar_fill - game_context.fill_per_hit
|
||||
end
|
||||
else
|
||||
game_context.total_misses = game_context.total_misses + 1
|
||||
if game_context.special_mode_condition then Audio.sfx_bloop() end
|
||||
game_context.special_mode_condition = false
|
||||
end
|
||||
elseif special_mode == "only_nothing" then
|
||||
game_context.total_misses = game_context.total_misses + 1
|
||||
if game_context.special_mode_condition then Audio.sfx_bloop() end
|
||||
game_context.special_mode_condition = false
|
||||
end
|
||||
@@ -173,6 +176,9 @@ function MinigameDDRWindow.on_end(game_context)
|
||||
end
|
||||
|
||||
game_context.special_mode_condition = game_context.special_mode_condition and was_ok
|
||||
if game_context.special_mode_condition and sm ~= "normal" then
|
||||
game_context.bar_fill = game_context.max_fill
|
||||
end
|
||||
end
|
||||
|
||||
--- Initializes DDR minigame state.
|
||||
@@ -336,7 +342,8 @@ function MinigameDDRWindow.update()
|
||||
mg.win_timer = mg.win_timer - 1
|
||||
if mg.win_timer == 0 then
|
||||
Audio.music_stop()
|
||||
Meter.on_minigame_complete()
|
||||
Meter.apply_ddr_reward(mg.total_misses)
|
||||
if not Context.game_in_progress then return end
|
||||
if mg.on_win then
|
||||
mg.on_win(mg)
|
||||
else
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
--- @section MinigameButtonMashWindow
|
||||
|
||||
---@class MinigameButtonMashState
|
||||
---@field bar_fill number
|
||||
---@field target_points number
|
||||
---@field fill_per_press number
|
||||
---@field base_degradation number
|
||||
---@field degradation_multiplier number
|
||||
---@field button_pressed_timer number
|
||||
---@field button_press_duration number
|
||||
---@field instruction_text string
|
||||
---@field show_progress_text boolean
|
||||
---@field return_window string?
|
||||
---@field bar_x number
|
||||
---@field bar_y number
|
||||
---@field bar_width number
|
||||
---@field bar_height number
|
||||
---@field button_x number
|
||||
---@field button_y number
|
||||
---@field button_size number
|
||||
---@field focus_center_x number?
|
||||
---@field focus_center_y number?
|
||||
---@field focus_initial_radius number
|
||||
---@field win_timer number
|
||||
---@field on_win (fun())?
|
||||
---@field meter_on_complete (fun(elapsed_sec: number))?
|
||||
---@field start_ms number?
|
||||
---@field elapsed_sec number?
|
||||
|
||||
--- Gets initial button mash minigame configuration.
|
||||
--- @within MinigameButtonMashWindow
|
||||
--- @return result table The default button mash minigame configuration.
|
||||
---@return MinigameButtonMashState
|
||||
function MinigameButtonMashWindow.init_context()
|
||||
return {
|
||||
bar_fill = 0,
|
||||
@@ -24,7 +53,11 @@ function MinigameButtonMashWindow.init_context()
|
||||
focus_center_y = nil,
|
||||
focus_initial_radius = 0,
|
||||
win_timer = 0,
|
||||
on_win = nil
|
||||
on_win = nil,
|
||||
--- If set, called with elapsed_sec instead of Meter.on_minigame_complete()
|
||||
meter_on_complete = nil,
|
||||
start_ms = nil,
|
||||
elapsed_sec = nil,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -51,8 +84,10 @@ end
|
||||
function MinigameButtonMashWindow.start(return_window, params)
|
||||
Audio.music_stop()
|
||||
MinigameButtonMashWindow.init(params)
|
||||
---@type MinigameButtonMashState
|
||||
local mg = Context.minigame_button_mash
|
||||
mg.return_window = return_window or "game"
|
||||
mg.start_ms = time()
|
||||
if mg.focus_center_x then
|
||||
Focus.start_driven(mg.focus_center_x, mg.focus_center_y, {
|
||||
initial_radius = mg.focus_initial_radius
|
||||
@@ -64,12 +99,18 @@ end
|
||||
--- Updates button mash minigame logic.
|
||||
--- @within MinigameButtonMashWindow
|
||||
function MinigameButtonMashWindow.update()
|
||||
---@type MinigameButtonMashState
|
||||
local mg = Context.minigame_button_mash
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
mg.win_timer = mg.win_timer - 1
|
||||
if mg.win_timer == 0 then
|
||||
Meter.on_minigame_complete()
|
||||
if mg.meter_on_complete then
|
||||
mg.meter_on_complete(mg.elapsed_sec or 0)
|
||||
else
|
||||
Meter.on_minigame_complete(false)
|
||||
end
|
||||
if not Context.game_in_progress then return end
|
||||
if mg.focus_center_x then Focus.stop() end
|
||||
Context.home_norman_visible = true
|
||||
Context.have_done_work_today = false
|
||||
@@ -97,6 +138,7 @@ function MinigameButtonMashWindow.update()
|
||||
end
|
||||
if mg.bar_fill >= mg.target_points then
|
||||
Audio.sfx_select()
|
||||
mg.elapsed_sec = (time() - mg.start_ms) / 1000
|
||||
mg.win_timer = Config.timing.minigame_win_duration
|
||||
return
|
||||
end
|
||||
@@ -116,6 +158,7 @@ end
|
||||
--- Draws button mash minigame.
|
||||
--- @within MinigameButtonMashWindow
|
||||
function MinigameButtonMashWindow.draw()
|
||||
---@type MinigameButtonMashState
|
||||
local mg = Context.minigame_button_mash
|
||||
if mg.return_window == "game" then
|
||||
GameWindow.draw_with_underlay(function()
|
||||
|
||||
@@ -73,7 +73,8 @@ function MinigameRhythmWindow.update()
|
||||
if mg.win_timer > 0 then
|
||||
mg.win_timer = mg.win_timer - 1
|
||||
if mg.win_timer == 0 then
|
||||
Meter.on_minigame_complete()
|
||||
Meter.on_minigame_complete(false)
|
||||
if not Context.game_in_progress then return end
|
||||
if mg.focus_center_x then Focus.stop() end
|
||||
if mg.on_win then
|
||||
mg.on_win()
|
||||
|
||||
@@ -31,6 +31,9 @@ Window.register("minigame_rhythm", MinigameRhythmWindow)
|
||||
MinigameDDRWindow = {}
|
||||
Window.register("minigame_ddr", MinigameDDRWindow)
|
||||
|
||||
GameOverWindow = {}
|
||||
Window.register("game_over", GameOverWindow)
|
||||
|
||||
EndWindow = {}
|
||||
Window.register("end", EndWindow)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user