Compare commits

..

1 Commits

Author SHA1 Message Date
7e1dd28808 screen init, update, optional decision condition
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2026-02-21 23:35:00 +01:00
17 changed files with 13 additions and 103 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,4 @@
.local .local
impostor.lua impostor.lua
prompts prompts
docs docs

View File

@@ -204,22 +204,7 @@ install_precommit_hook:
@chmod +x .git/hooks/pre-commit @chmod +x .git/hooks/pre-commit
@echo "Pre-commit hook installed successfully." @echo "Pre-commit hook installed successfully."
docs: build .PHONY: all build export watch import_assets export_assets clean lint ci-version ci-export ci-upload ci-update install_precommit_hook
@echo "==> Checking for ldoc..."
@if ! command -v ldoc &> /dev/null; then \
echo "ldoc not found, attempting to install with luarocks..."; \
if command -v luarocks &> /dev/null; then \
luarocks install ldoc; \
else \
echo "Error: luarocks not found. Please install luarocks and then ldoc manually."; \
exit 1; \
fi; \
fi
@echo "==> Running ldoc..."
@ldoc ${OUTPUT} -d docs
@echo "==> Documentation generated."
.PHONY: all build export watch import_assets export_assets clean lint ci-version ci-export ci-upload ci-update install_precommit_hook docs
#-- <WAVES> #-- <WAVES>
#-- 000:224578acdeeeeddcba95434567653100 #-- 000:224578acdeeeeddcba95434567653100

View File

@@ -4,5 +4,4 @@ Decision.register({
handle = function() handle = function()
Util.go_to_screen_by_id("home") Util.go_to_screen_by_id("home")
end, end,
condition = function() return true end
}) })

View File

@@ -4,5 +4,4 @@ Decision.register({
handle = function() handle = function()
Util.go_to_screen_by_id("office") Util.go_to_screen_by_id("office")
end, end,
condition = function() return true end
}) })

View File

@@ -4,5 +4,4 @@ Decision.register({
handle = function() handle = function()
Util.go_to_screen_by_id("toilet") Util.go_to_screen_by_id("toilet")
end, end,
condition = function() return true end
}) })

View File

@@ -4,5 +4,4 @@ Decision.register({
handle = function() handle = function()
Util.go_to_screen_by_id("walking_to_home") Util.go_to_screen_by_id("walking_to_home")
end, end,
condition = function() return true end
}) })

View File

@@ -4,5 +4,4 @@ Decision.register({
handle = function() handle = function()
Util.go_to_screen_by_id("walking_to_office") Util.go_to_screen_by_id("walking_to_office")
end, end,
condition = function() return true end
}) })

View File

@@ -4,5 +4,4 @@ Decision.register({
handle = function() handle = function()
Situation.apply("drink_coffee") Situation.apply("drink_coffee")
end, end,
condition = function() return true end
}) })

View File

@@ -2,5 +2,4 @@ Decision.register({
id = "play_button_mash", id = "play_button_mash",
label = "Play Button Mash", label = "Play Button Mash",
handle = function() Meters.hide() MinigameButtonMashWindow.start(WINDOW_GAME) end, handle = function() Meters.hide() MinigameButtonMashWindow.start(WINDOW_GAME) end,
condition = function() return true end
}) })

View File

@@ -2,5 +2,4 @@ Decision.register({
id = "play_ddr", id = "play_ddr",
label = "Play DDR (Random)", label = "Play DDR (Random)",
handle = function() Meters.hide() MinigameDDRWindow.start(WINDOW_GAME, nil) end, handle = function() Meters.hide() MinigameDDRWindow.start(WINDOW_GAME, nil) end,
condition = function() return true end
}) })

View File

@@ -2,5 +2,4 @@ Decision.register({
id = "play_rhythm", id = "play_rhythm",
label = "Play Rhythm Game", label = "Play Rhythm Game",
handle = function() Meters.hide() MinigameRhythmWindow.start(WINDOW_GAME) end, handle = function() Meters.hide() MinigameRhythmWindow.start(WINDOW_GAME) end,
condition = function() return true end
}) })

View File

@@ -46,11 +46,7 @@ on than meets the eye.]]
minigame_button_mash = Minigames.get_default_button_mash(), minigame_button_mash = Minigames.get_default_button_mash(),
minigame_rhythm = Minigames.get_default_rhythm(), minigame_rhythm = Minigames.get_default_rhythm(),
meters = Meters.get_initial(), meters = Meters.get_initial(),
--- Table storing currently active sprites to be drawn.
-- Each entry is a table with `id`, `x`, `y`, and other drawing parameters.
sprites = {}, sprites = {},
--- The ID of the currently active situation.
-- Set by `Situation.apply()` and `nil` if no situation is active.
current_situation = nil, current_situation = nil,
} }
end end
@@ -89,6 +85,7 @@ function Context.new_game()
reset_context_to_initial_state() reset_context_to_initial_state()
Context.game_in_progress = true Context.game_in_progress = true
MenuWindow.refresh_menu_items() MenuWindow.refresh_menu_items()
Context.screens[Context.current_screen].init()
end end
function Context.save_game() function Context.save_game()
@@ -109,4 +106,5 @@ function Context.load_game()
Context.game_in_progress = true Context.game_in_progress = true
MenuWindow.refresh_menu_items() MenuWindow.refresh_menu_items()
Context.screens[Context.current_screen].init()
end end

View File

@@ -1,13 +1,5 @@
local _screens = {} local _screens = {}
--- Registers a new screen definition with the Screen manager.
-- Overwrites existing screen if an ID conflict occurs.
-- @param screen_data table A table containing the screen definition.
-- Must include an `id` field (string).
-- Optional fields:
-- - `situations` (table): A table of situation IDs allowed on this screen. Defaults to an empty table.
-- - `init` (function): Function to execute once when the screen becomes active. Defaults to an empty function.
-- - `update` (function): Function to execute each frame while the screen is active. Defaults to an empty function.
function Screen.register(screen_data) 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)
@@ -24,9 +16,6 @@ function Screen.register(screen_data)
_screens[screen_data.id] = screen_data _screens[screen_data.id] = screen_data
end end
--- Retrieves a registered screen by its ID.
-- @param screen_id string The ID of the screen to retrieve.
-- @return table The screen table, or `nil` if not found.
function Screen.get_by_id(screen_id) function Screen.get_by_id(screen_id)
return _screens[screen_id] return _screens[screen_id]
end end

View File

@@ -1,12 +1,5 @@
local _situations = {} local _situations = {}
--- Registers a new situation with the Situation manager.
-- Overwrites existing situation if an ID conflict occurs.
-- @param situation table A table containing the situation definition.
-- Must include an `id` field (string).
-- Optional fields:
-- - `handle` (function): Function to execute when the situation is applied. Defaults to an empty function.
-- - `update` (function): Function to execute each frame while the situation is active. Defaults to an empty function.
function Situation.register(situation) function Situation.register(situation)
if not situation or not situation.id then if not situation or not situation.id then
PopupWindow.show({"Error: Invalid situation object registered (missing id)!"}) PopupWindow.show({"Error: Invalid situation object registered (missing id)!"})
@@ -24,19 +17,10 @@ function Situation.register(situation)
_situations[situation.id] = situation _situations[situation.id] = situation
end end
--- Retrieves a registered situation by its ID.
-- @param id string The ID of the situation to retrieve.
-- @return table The situation table, or `nil` if not found.
function Situation.get(id) function Situation.get(id)
return _situations[id] return _situations[id]
end end
--- Applies a situation, making it the current active situation.
-- The situation's `handle` function is executed.
-- This function first checks if the situation is valid and if it's allowed
-- on the current screen (as defined in `Context.screens[Context.current_screen].situations`).
-- If successful, `Context.current_situation` is updated with the ID of the applied situation.
-- @param id string The ID of the situation to apply.
function Situation.apply(id) function Situation.apply(id)
local situation = Situation.get(id) local situation = Situation.get(id)
if not situation then if not situation then
@@ -53,3 +37,4 @@ function Situation.apply(id)
Context.current_situation = id Context.current_situation = id
situation.handle() situation.handle()
end end

View File

@@ -1,15 +1,5 @@
local _sprites = {} local _sprites = {}
--- Registers a new sprite or complex sprite definition with the Sprite manager.
-- Overwrites existing sprite if an ID conflict occurs.
-- @param sprite_data table A table containing the sprite definition.
-- Must include an `id` field (string) and either an `s` field (number, for simple sprites)
-- or a `sprites` field (table, for complex sprites).
-- For complex sprites, `sprites` is a table of sub-sprite definitions, each with:
-- - `s` (number): Sprite index.
-- - `x_offset` (number): X-offset relative to the parent sprite's position.
-- - `y_offset` (number): Y-offset relative to the parent sprite's position.
-- - Optional `colorkey`, `scale`, `flip_x`, `flip_y`, `rot` for individual sub-sprites.
function Sprite.register(sprite_data) function Sprite.register(sprite_data)
if not sprite_data or not sprite_data.id then if not sprite_data or not sprite_data.id then
trace("Error: Invalid sprite object registered (missing id)!") trace("Error: Invalid sprite object registered (missing id)!")
@@ -21,17 +11,6 @@ function Sprite.register(sprite_data)
_sprites[sprite_data.id] = sprite_data _sprites[sprite_data.id] = sprite_data
end end
--- Schedules a registered sprite to be drawn at a specific position with optional transformations.
-- The sprite's parameters are stored in `Context.sprites` for deferred rendering by `Sprite.draw()`.
-- If the sprite with the given `id` is already scheduled, its parameters will be updated.
-- @param id string The unique identifier of the sprite to show. Must be registered via `Sprite.register`.
-- @param x number The x-coordinate on the screen where the sprite will be drawn.
-- @param y number The y-coordinate on the screen where the sprite will be drawn.
-- @param[opt] colorkey number The color index to be treated as transparent (default: 0).
-- @param[opt] scale number The scaling factor for the sprite (default: 1).
-- @param[opt] flip_x number Set to 1 to flip the sprite horizontally (default: 0).
-- @param[opt] flip_y number Set to 1 to flip the sprite vertically (default: 0).
-- @param[opt] rot number The rotation of the sprite in degrees (default: 0).
function Sprite.show(id, x, y, colorkey, scale, flip_x, flip_y, rot) function Sprite.show(id, x, y, colorkey, scale, flip_x, flip_y, rot)
-- Ensure the sprite exists before attempting to show it -- Ensure the sprite exists before attempting to show it
if not _sprites[id] then if not _sprites[id] then
@@ -51,16 +30,10 @@ function Sprite.show(id, x, y, colorkey, scale, flip_x, flip_y, rot)
} }
end end
--- Hides a currently displayed sprite by removing it from the `Context.sprites` table.
-- The sprite will no longer be drawn in subsequent frames.
-- @param id string The unique identifier of the sprite to hide.
function Sprite.hide(id) function Sprite.hide(id)
Context.sprites[id] = nil Context.sprites[id] = nil
end end
--- Draws all sprites currently scheduled in `Context.sprites`.
-- This function retrieves the registered sprite definitions and applies the stored
-- position and transformation parameters. It handles both simple and complex sprites.
function Sprite.draw() function Sprite.draw()
for id, params in pairs(Context.sprites) do for id, params in pairs(Context.sprites) do
local sprite_data = _sprites[id] local sprite_data = _sprites[id]

View File

@@ -1,17 +1,17 @@
Sprite.register({ Sprite.register({
id = "norman", id = "norman",
sprites = { sprites = {
-- Body (sprite index 0) -- Body
{ s = 0, x_offset = 0, y_offset = 0 }, { s = 0, x_offset = 0, y_offset = 0 },
-- Head (sprite index 1) -- Head
{ s = 1, x_offset = 0, y_offset = -8 }, { s = 1, x_offset = 0, y_offset = -8 },
-- Left Arm (sprite index 2) -- Left Arm
{ s = 2, x_offset = -4, y_offset = 4 }, { s = 2, x_offset = -4, y_offset = 4 },
-- Right Arm (sprite index 3, flipped) -- Right Arm
{ s = 3, x_offset = 4, y_offset = 4, flip_x = 1 }, -- Flipped arm { s = 3, x_offset = 4, y_offset = 4, flip_x = 1 }, -- Flipped arm
-- Left Leg (sprite index 4) -- Left Leg
{ s = 4, x_offset = -2, y_offset = 8 }, { s = 4, x_offset = -2, y_offset = 8 },
-- Right Leg (sprite index 5, flipped) -- Right Leg
{ s = 5, x_offset = 2, y_offset = 8, flip_x = 1 } -- Flipped leg { s = 5, x_offset = 2, y_offset = 8, flip_x = 1 } -- Flipped leg
} }
}) })

View File

@@ -1,6 +1,3 @@
--- Draws the main game window content.
-- This includes the current screen's background, top bar, decisions, and all active sprites.
-- @function GameWindow.draw
function GameWindow.draw() function GameWindow.draw()
local screen = Context.screens[Context.current_screen] local screen = Context.screens[Context.current_screen]
Map.draw(screen.background) Map.draw(screen.background)
@@ -20,10 +17,6 @@ function GameWindow.draw()
Sprite.draw() Sprite.draw()
end end
--- Updates the logic for the main game window.
-- Handles input, navigates between screens, calls the current screen's and situation's update functions,
-- and processes player decisions.
-- @function GameWindow.update
function GameWindow.update() function GameWindow.update()
local previous_screen_index = Context.current_screen local previous_screen_index = Context.current_screen
@@ -86,10 +79,6 @@ function GameWindow.update()
end end
end end
--- Sets the active window state for the game.
-- This function is typically called when transitioning between different game states (e.g., to a minigame).
-- @param new_state number The ID of the new active window (e.g., `WINDOW_MENU`, `WINDOW_GAME`).
-- @function GameWindow.set_state
function GameWindow.set_state(new_state) function GameWindow.set_state(new_state)
Context.active_window = new_state Context.active_window = new_state
end end