Compare commits
16 Commits
e07eeb466b
...
feature/pi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd7b5650d3 | ||
| 0e956ec7a9 | |||
| 0c2999f596 | |||
| e46c48b2ec | |||
| 99ace8a1e8 | |||
| 15bf66f1ca | |||
|
|
41f75da8c3 | ||
| e05018d637 | |||
| 8e104b1ff9 | |||
| e14160114b | |||
|
|
1b64fd2392 | ||
|
|
aaf1479a78 | ||
| c321fbc19a | |||
| dc8a82d583 | |||
| c565213e44 | |||
| 035a2bc37e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
|||||||
.local
|
.local
|
||||||
impostor.lua
|
impostor.lua
|
||||||
|
impostor.original.lua
|
||||||
prompts
|
prompts
|
||||||
docs
|
docs
|
||||||
|
minify.lua
|
||||||
@@ -5,7 +5,32 @@ steps:
|
|||||||
- 'apk add --no-cache make'
|
- 'apk add --no-cache make'
|
||||||
- 'make ci-version'
|
- 'make ci-version'
|
||||||
|
|
||||||
- name: build
|
- name: lint
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- 'apk add --no-cache make lua5.4 lua5.4-dev luarocks gcc musl-dev'
|
||||||
|
- 'ln -sf /usr/bin/lua5.4 /usr/bin/lua'
|
||||||
|
- 'ln -sf /usr/bin/luarocks-5.4 /usr/bin/luarocks'
|
||||||
|
- 'luarocks install luacheck'
|
||||||
|
- 'make ci-lint'
|
||||||
|
|
||||||
|
- name: minify
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- 'apk add --no-cache make lua5.4 curl'
|
||||||
|
- 'ln -sf /usr/bin/lua5.4 /usr/bin/lua'
|
||||||
|
- 'make ci-minify'
|
||||||
|
|
||||||
|
- name: docs
|
||||||
|
image: alpine
|
||||||
|
commands:
|
||||||
|
- 'apk add --no-cache make lua5.4 lua5.4-dev luarocks gcc musl-dev zip'
|
||||||
|
- 'ln -sf /usr/bin/lua5.4 /usr/bin/lua'
|
||||||
|
- 'ln -sf /usr/bin/luarocks-5.4 /usr/bin/luarocks'
|
||||||
|
- 'luarocks install ldoc'
|
||||||
|
- 'make ci-docs'
|
||||||
|
|
||||||
|
- name: export
|
||||||
image: git.teletype.hu/internal/tic80pro:latest
|
image: git.teletype.hu/internal/tic80pro:latest
|
||||||
environment:
|
environment:
|
||||||
XDG_RUNTIME_DIR: /tmp
|
XDG_RUNTIME_DIR: /tmp
|
||||||
@@ -23,7 +48,7 @@ steps:
|
|||||||
from_secret: droparea_ssh_password
|
from_secret: droparea_ssh_password
|
||||||
commands:
|
commands:
|
||||||
- 'apk add --no-cache make openssh-client sshpass'
|
- 'apk add --no-cache make openssh-client sshpass'
|
||||||
- 'make ci-upload'
|
- 'make ci-artifact'
|
||||||
|
|
||||||
- name: update
|
- name: update
|
||||||
image: alpine
|
image: alpine
|
||||||
|
|||||||
113
Makefile
113
Makefile
@@ -6,9 +6,13 @@ PROJECT = impostor
|
|||||||
|
|
||||||
ORDER = $(PROJECT).inc
|
ORDER = $(PROJECT).inc
|
||||||
OUTPUT = $(PROJECT).lua
|
OUTPUT = $(PROJECT).lua
|
||||||
|
OUTPUT_ORIGINAL = $(PROJECT).original.lua
|
||||||
OUTPUT_ZIP = $(PROJECT).html.zip
|
OUTPUT_ZIP = $(PROJECT).html.zip
|
||||||
OUTPUT_TIC = $(PROJECT).tic
|
OUTPUT_TIC = $(PROJECT).tic
|
||||||
|
|
||||||
|
MINIFY = minify.lua
|
||||||
|
MINIFY_URL = https://raw.githubusercontent.com/ztimar31/lua-minify-tic80/refs/heads/master/minify.lua
|
||||||
|
|
||||||
SRC_DIR = inc
|
SRC_DIR = inc
|
||||||
SRC = $(shell sed 's|^|$(SRC_DIR)/|' $(ORDER))
|
SRC = $(shell sed 's|^|$(SRC_DIR)/|' $(ORDER))
|
||||||
|
|
||||||
@@ -30,16 +34,22 @@ UPDATE_SERVER ?= https://games.vps.teletype.hu
|
|||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build: $(OUTPUT)
|
build:
|
||||||
|
|
||||||
$(OUTPUT): $(SRC) $(ORDER)
|
|
||||||
@rm -f $(OUTPUT)
|
@rm -f $(OUTPUT)
|
||||||
@sed 's/\r$$//' $(ORDER) | while read f; do \
|
@sed 's/\r$$//' $(ORDER) | while read f; do \
|
||||||
cat "$(SRC_DIR)/$$f" >> $(OUTPUT); \
|
cat "$(SRC_DIR)/$$f" >> $(OUTPUT); \
|
||||||
echo "" >> $(OUTPUT); \
|
echo "" >> $(OUTPUT); \
|
||||||
done
|
done
|
||||||
|
|
||||||
export: build
|
download-minify:
|
||||||
|
@test -f $(MINIFY) || { echo "==> Downloading $(MINIFY)"; curl -fsSL $(MINIFY_URL) -o $(MINIFY); }
|
||||||
|
|
||||||
|
minify: build download-minify
|
||||||
|
@echo "==> Minifying $(OUTPUT)"
|
||||||
|
@cp $(OUTPUT) $(OUTPUT_ORIGINAL)
|
||||||
|
@lua $(MINIFY) minify $(OUTPUT_ORIGINAL) > $(OUTPUT)
|
||||||
|
|
||||||
|
export: minify
|
||||||
@if [ -z "$(VERSION)" ]; then \
|
@if [ -z "$(VERSION)" ]; then \
|
||||||
echo "ERROR: VERSION not set!"; \
|
echo "ERROR: VERSION not set!"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
@@ -61,7 +71,7 @@ watch:
|
|||||||
$(MAKE) build
|
$(MAKE) build
|
||||||
fswatch -o $(SRC_DIR) $(ORDER) assets | while read; do $(MAKE) build; done
|
fswatch -o $(SRC_DIR) $(ORDER) assets | while read; do $(MAKE) build; done
|
||||||
|
|
||||||
import_assets: $(OUTPUT)
|
import_assets: build
|
||||||
@TIC_CMD="load $(OUTPUT) &"; \
|
@TIC_CMD="load $(OUTPUT) &"; \
|
||||||
for t in $(ASSET_TYPES); do \
|
for t in $(ASSET_TYPES); do \
|
||||||
for f in $(ASSETS_DIR)/$$t/*.png; do \
|
for f in $(ASSETS_DIR)/$$t/*.png; do \
|
||||||
@@ -156,41 +166,9 @@ export_assets:
|
|||||||
@$(call f_export_asset_awk,WAVES,$(OUTPUT),$(ASSETS_LUA))
|
@$(call f_export_asset_awk,WAVES,$(OUTPUT),$(ASSETS_LUA))
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f $(PROJECT)-*.tic $(PROJECT)-*.html.zip $(OUTPUT)
|
@rm -f $(PROJECT)-*.tic $(PROJECT)-*.html.zip $(PROJECT)-*-docs.zip $(PROJECT)-docs.zip $(OUTPUT) $(OUTPUT_ORIGINAL)
|
||||||
@echo "==> Cleaned build artifacts"
|
@echo "==> Cleaned build artifacts"
|
||||||
|
|
||||||
# CI/CD Targets
|
|
||||||
ci-version:
|
|
||||||
@VERSION=$$(sed -n "s/^-- version: //p" inc/meta/meta.header.lua | head -n 1 | tr -d "[:space:]"); \
|
|
||||||
BRANCH=$${CI_COMMIT_BRANCH:-$${WOODPECKER_BRANCH}}; \
|
|
||||||
BRANCH=$$(echo "$$BRANCH" | tr '/' '-'); \
|
|
||||||
if [ "$$BRANCH" != "main" ] && [ "$$BRANCH" != "master" ] && [ -n "$$BRANCH" ]; then \
|
|
||||||
VERSION=dev-$$VERSION-$$BRANCH; \
|
|
||||||
fi; \
|
|
||||||
echo "VERSION is: $$VERSION"; \
|
|
||||||
echo $$VERSION > $(VERSION_FILE)
|
|
||||||
|
|
||||||
ci-export:
|
|
||||||
@VERSION=$$(cat $(VERSION_FILE)); \
|
|
||||||
echo "==> Building and exporting version $$VERSION"; \
|
|
||||||
$(MAKE) export VERSION=$$VERSION
|
|
||||||
|
|
||||||
ci-upload:
|
|
||||||
@VERSION=$$(cat $(VERSION_FILE)); \
|
|
||||||
echo "==> Uploading artifacts for version $$VERSION"; \
|
|
||||||
ls -lh $(PROJECT)-$$VERSION.* $(PROJECT).tic $(PROJECT).html.zip 2>/dev/null || true; \
|
|
||||||
cp $(PROJECT).lua $(PROJECT)-$$VERSION.lua; \
|
|
||||||
FILE_LUA=$(PROJECT)-$$VERSION.lua; \
|
|
||||||
FILE_TIC=$(PROJECT)-$$VERSION.tic; \
|
|
||||||
FILE_HTML_ZIP=$(PROJECT)-$$VERSION.html.zip; \
|
|
||||||
SCP_TARGET="$(DROPAREA_USER)@$(DROPAREA_HOST):$(DROPAREA_TARGET_PATH)/"; \
|
|
||||||
sshpass -p "$(DROPAREA_SSH_PASSWORD)" scp -o StrictHostKeyChecking=no -P $(DROPAREA_PORT) $$FILE_LUA $$FILE_TIC $$FILE_HTML_ZIP $$SCP_TARGET
|
|
||||||
|
|
||||||
ci-update:
|
|
||||||
@VERSION=$$(cat $(VERSION_FILE)); \
|
|
||||||
echo "==> Triggering update for version $$VERSION"; \
|
|
||||||
curl "$(UPDATE_SERVER)/update?secret=$(UPDATE_SECRET)&name=$(PROJECT)&platform=tic80&version=$$VERSION"
|
|
||||||
|
|
||||||
install_precommit_hook:
|
install_precommit_hook:
|
||||||
@echo "Installing Git pre-commit hook (lint check)..."
|
@echo "Installing Git pre-commit hook (lint check)..."
|
||||||
@mkdir -p .git/hooks
|
@mkdir -p .git/hooks
|
||||||
@@ -219,5 +197,62 @@ docs: build
|
|||||||
@ldoc ${OUTPUT} -d docs
|
@ldoc ${OUTPUT} -d docs
|
||||||
@echo "==> Documentation generated."
|
@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
|
# -----------------------------------------
|
||||||
|
# CI/CD Pipeline targets
|
||||||
|
# -----------------------------------------
|
||||||
|
|
||||||
|
ci-version:
|
||||||
|
@VERSION=$$(sed -n "s/^-- version: //p" inc/meta/meta.header.lua | head -n 1 | tr -d "[:space:]"); \
|
||||||
|
BRANCH=$${CI_COMMIT_BRANCH:-$${WOODPECKER_BRANCH}}; \
|
||||||
|
BRANCH=$$(echo "$$BRANCH" | tr '/' '-'); \
|
||||||
|
if [ "$$BRANCH" != "main" ] && [ "$$BRANCH" != "master" ] && [ -n "$$BRANCH" ]; then \
|
||||||
|
VERSION=dev-$$VERSION-$$BRANCH; \
|
||||||
|
fi; \
|
||||||
|
echo "VERSION is: $$VERSION"; \
|
||||||
|
echo $$VERSION > $(VERSION_FILE)
|
||||||
|
|
||||||
|
ci-lint: lint
|
||||||
|
|
||||||
|
ci-minify: minify
|
||||||
|
|
||||||
|
ci-docs:
|
||||||
|
@VERSION=$$(cat $(VERSION_FILE)); \
|
||||||
|
echo "==> Generating docs from $(OUTPUT_ORIGINAL)"; \
|
||||||
|
ldoc $(OUTPUT_ORIGINAL) -d docs; \
|
||||||
|
echo "==> Zipping docs for version $$VERSION"; \
|
||||||
|
(cd docs && zip -r ../$(PROJECT)-$$VERSION-docs.zip .); \
|
||||||
|
cp $(PROJECT)-$$VERSION-docs.zip $(PROJECT)-docs.zip; \
|
||||||
|
echo "==> Docs zip created"
|
||||||
|
|
||||||
|
ci-export:
|
||||||
|
@VERSION=$$(cat $(VERSION_FILE)); \
|
||||||
|
echo "==> Exporting HTML for version $$VERSION"; \
|
||||||
|
tic80 --cli --skip --fs=. \
|
||||||
|
--cmd="load $(OUTPUT) & save $(PROJECT)-$$VERSION & export html $(PROJECT)-$$VERSION.html & exit"; \
|
||||||
|
if [ -f "$(PROJECT)-$$VERSION.tic" ]; then \
|
||||||
|
cp $(PROJECT)-$$VERSION.tic $(PROJECT).tic; \
|
||||||
|
fi; \
|
||||||
|
if [ -f "$(PROJECT)-$$VERSION.html.zip" ]; then \
|
||||||
|
cp $(PROJECT)-$$VERSION.html.zip $(PROJECT).html.zip; \
|
||||||
|
fi; \
|
||||||
|
echo "==> Generated files:"; \
|
||||||
|
ls -lh $(PROJECT)-$$VERSION.* $(PROJECT).tic $(PROJECT).html.zip 2>/dev/null || true
|
||||||
|
|
||||||
|
ci-artifact:
|
||||||
|
@VERSION=$$(cat $(VERSION_FILE)); \
|
||||||
|
echo "==> Uploading artifacts for version $$VERSION"; \
|
||||||
|
cp $(PROJECT).lua $(PROJECT)-$$VERSION.lua; \
|
||||||
|
SCP_TARGET="$(DROPAREA_USER)@$(DROPAREA_HOST):$(DROPAREA_TARGET_PATH)/"; \
|
||||||
|
sshpass -p "$(DROPAREA_SSH_PASSWORD)" scp -o StrictHostKeyChecking=no -P $(DROPAREA_PORT) \
|
||||||
|
$(PROJECT)-$$VERSION.lua \
|
||||||
|
$(PROJECT)-$$VERSION.tic \
|
||||||
|
$(PROJECT)-$$VERSION.html.zip \
|
||||||
|
$(PROJECT)-$$VERSION-docs.zip \
|
||||||
|
$$SCP_TARGET
|
||||||
|
|
||||||
|
ci-update:
|
||||||
|
@VERSION=$$(cat $(VERSION_FILE)); \
|
||||||
|
echo "==> Triggering update for version $$VERSION"; \
|
||||||
|
curl "$(UPDATE_SERVER)/update?secret=$(UPDATE_SECRET)&name=$(PROJECT)&platform=tic80&version=$$VERSION"
|
||||||
|
|
||||||
|
.PHONY: all build download-minify minify export watch import_assets export_assets clean lint install_precommit_hook docs ci-version ci-lint ci-minify ci-docs ci-export ci-artifact ci-update
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets_src/background_street.ase
Normal file
BIN
assets_src/background_street.ase
Normal file
Binary file not shown.
@@ -8,7 +8,7 @@ Context = {}
|
|||||||
|
|
||||||
--- Gets initial data for Context.
|
--- Gets initial data for Context.
|
||||||
--- @within Context
|
--- @within Context
|
||||||
--- @return result table Initial context data. </br>
|
--- @return result table Initial context data or nil. </br>
|
||||||
--- Fields: </br>
|
--- Fields: </br>
|
||||||
--- * current_menu_item (number) Index of the currently selected menu item.<br/>
|
--- * current_menu_item (number) Index of the currently selected menu item.<br/>
|
||||||
--- * splash_timer (number) Remaining frames for the splash screen timer.<br/>
|
--- * splash_timer (number) Remaining frames for the splash screen timer.<br/>
|
||||||
@@ -18,7 +18,8 @@ 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/>
|
||||||
--- * game (table) Current game progress state. Contains: `current_screen` (string) active screen ID, `current_situation` (string|nil) active situation ID.
|
--- * 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/>
|
||||||
function Context.initial_data()
|
function Context.initial_data()
|
||||||
return {
|
return {
|
||||||
current_menu_item = 1,
|
current_menu_item = 1,
|
||||||
@@ -28,6 +29,7 @@ function Context.initial_data()
|
|||||||
content = {}
|
content = {}
|
||||||
},
|
},
|
||||||
game_in_progress = false,
|
game_in_progress = false,
|
||||||
|
stat_screen_active = false,
|
||||||
minigame_ddr = Minigame.get_default_ddr(),
|
minigame_ddr = Minigame.get_default_ddr(),
|
||||||
minigame_button_mash = Minigame.get_default_button_mash(),
|
minigame_button_mash = Minigame.get_default_button_mash(),
|
||||||
minigame_rhythm = Minigame.get_default_rhythm(),
|
minigame_rhythm = Minigame.get_default_rhythm(),
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
--- @section Meter
|
--- @section Meter
|
||||||
local METER_MAX = 1000
|
local METER_MAX = 1000
|
||||||
local METER_DEFAULT = 500
|
local METER_DEFAULT = 500
|
||||||
local METER_DECAY_PER_FRAME = 0.02
|
|
||||||
local METER_GAIN_PER_CHORE = 100
|
local METER_GAIN_PER_CHORE = 100
|
||||||
local COMBO_BASE_BONUS = 0.02
|
local COMBO_BASE_BONUS = 0.02
|
||||||
local COMBO_MAX_BONUS = 0.16
|
local COMBO_MAX_BONUS = 0.16
|
||||||
@@ -90,9 +89,6 @@ function Meter.update()
|
|||||||
local m = Context.meters
|
local m = Context.meters
|
||||||
local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil
|
local in_minigame = string.find(Window.get_current_id(), "^minigame_") ~= nil
|
||||||
if not in_minigame then
|
if not in_minigame then
|
||||||
m.ism = math.max(0, m.ism - METER_DECAY_PER_FRAME)
|
|
||||||
m.wpm = math.max(0, m.wpm - METER_DECAY_PER_FRAME)
|
|
||||||
m.bm = math.max(0, m.bm - METER_DECAY_PER_FRAME)
|
|
||||||
if m.combo > 0 then
|
if m.combo > 0 then
|
||||||
m.combo_timer = m.combo_timer + 1
|
m.combo_timer = m.combo_timer + 1
|
||||||
if m.combo_timer >= COMBO_TIMEOUT_FRAMES then
|
if m.combo_timer >= COMBO_TIMEOUT_FRAMES then
|
||||||
@@ -122,6 +118,13 @@ function Meter.add(key, amount)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the timer decay as a percentage of the max meter value.
|
||||||
|
--- @within Meter
|
||||||
|
--- @return number The decay percentage per revolution (e.g. 2 means -2%).
|
||||||
|
function Meter.get_timer_decay_percentage()
|
||||||
|
return math.floor(meter_timer_decay_per_revolution / METER_MAX * 100)
|
||||||
|
end
|
||||||
|
|
||||||
--- Called on minigame completion.
|
--- Called on minigame completion.
|
||||||
--- @within Meter
|
--- @within Meter
|
||||||
function Meter.on_minigame_complete()
|
function Meter.on_minigame_complete()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ local _screens = {}
|
|||||||
--- @param[opt] screen_data.situations table Array of situation ID strings. Defaults to {}.
|
--- @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.
|
||||||
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,6 +25,9 @@ function Screen.register(screen_data)
|
|||||||
if not screen_data.update then
|
if not screen_data.update then
|
||||||
screen_data.update = function() end
|
screen_data.update = function() end
|
||||||
end
|
end
|
||||||
|
if not screen_data.draw then
|
||||||
|
screen_data.draw = function() end
|
||||||
|
end
|
||||||
_screens[screen_data.id] = screen_data
|
_screens[screen_data.id] = screen_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,74 @@ Screen.register({
|
|||||||
name = "Toilet",
|
name = "Toilet",
|
||||||
decisions = {
|
decisions = {
|
||||||
"go_to_home",
|
"go_to_home",
|
||||||
|
},
|
||||||
|
background = "bedroom",
|
||||||
|
init = function()
|
||||||
|
Context.stat_screen_active = true
|
||||||
|
Meter.hide()
|
||||||
|
local cx = Config.screen.width * 0.75
|
||||||
|
local cy = Config.screen.height * 0.75
|
||||||
|
Focus.start_driven(cx, cy)
|
||||||
|
Focus.set_percentage(0.15)
|
||||||
|
end,
|
||||||
|
update = function()
|
||||||
|
if not Context.stat_screen_active then return end
|
||||||
|
if Input.select() or Input.player_interact() then
|
||||||
|
Focus.stop()
|
||||||
|
Context.stat_screen_active = false
|
||||||
|
Meter.show()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
draw = function()
|
||||||
|
if not Context.stat_screen_active then return end
|
||||||
|
|
||||||
|
local sw = Config.screen.width
|
||||||
|
local cx = sw / 2
|
||||||
|
local bar_w = math.floor(sw * 0.75)
|
||||||
|
local bar_x = math.floor((sw - bar_w) / 2)
|
||||||
|
local bar_h = 4
|
||||||
|
|
||||||
|
-- TODO: Add day counter
|
||||||
|
Print.text_center("day 1", cx, 10, Config.colors.white)
|
||||||
|
|
||||||
|
local narrative = "reflecting on my past and present\n...\nboth eventually flushed."
|
||||||
|
local wrapped = UI.word_wrap(narrative, 38)
|
||||||
|
local text_y = 24
|
||||||
|
for _, line in ipairs(wrapped) do
|
||||||
|
Print.text_center(line, cx, text_y, Config.colors.light_grey)
|
||||||
|
text_y = text_y + 8
|
||||||
|
end
|
||||||
|
|
||||||
|
local m = Context.meters
|
||||||
|
local max_val = Meter.get_max()
|
||||||
|
local decay_pct = Meter.get_timer_decay_percentage()
|
||||||
|
local decay_text = string.format("-%d%%", decay_pct)
|
||||||
|
local combo_mult = Meter.get_combo_multiplier()
|
||||||
|
local combo_pct = math.floor((combo_mult - 1) * 100)
|
||||||
|
local mult_text = string.format("+%d%%", combo_pct)
|
||||||
|
local meter_start_y = text_y + 10
|
||||||
|
|
||||||
|
local meter_list = {
|
||||||
|
{ key = "wpm", label = "Work Productivity Meter" },
|
||||||
|
{ key = "ism", label = "Impostor Syndrome Meter" },
|
||||||
|
{ key = "bm", label = "Burnout Meter" },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i, meter in ipairs(meter_list) do
|
||||||
|
local y = meter_start_y + (i - 1) * 20
|
||||||
|
|
||||||
|
Print.text_center(meter.label, cx, y, Config.colors.white)
|
||||||
|
|
||||||
|
local bar_y = y + 8
|
||||||
|
local fill_w = math.max(0, math.floor((m[meter.key] / max_val) * bar_w))
|
||||||
|
rect(bar_x, bar_y, bar_w, bar_h, Meter.COLOR_BG)
|
||||||
|
if fill_w > 0 then
|
||||||
|
rect(bar_x, bar_y, fill_w, bar_h, Config.colors.blue)
|
||||||
|
end
|
||||||
|
|
||||||
|
local decay_w = print(decay_text, 0, -6, 0, false, 1)
|
||||||
|
Print.text(decay_text, bar_x - decay_w - 4, bar_y, Config.colors.light_blue)
|
||||||
|
Print.text(mult_text, bar_x + bar_w + 4, bar_y, Config.colors.light_blue)
|
||||||
|
end
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -157,11 +157,10 @@ end
|
|||||||
|
|
||||||
--- Draws the clock timer indicator as a circular progress bar in the top-left area.
|
--- Draws the clock timer indicator as a circular progress bar in the top-left area.
|
||||||
--- Color transitions: white (0-50%), yellow (50-75%), red (75-100%).
|
--- Color transitions: white (0-50%), yellow (50-75%), red (75-100%).
|
||||||
--- Only visible when meters are visible.
|
|
||||||
--- @within UI
|
--- @within UI
|
||||||
function UI.draw_timer()
|
function UI.draw_timer()
|
||||||
if not Context or not Context.game_in_progress or not Context.meters then return end
|
if not Context or not Context.game_in_progress or not Context.meters then return end
|
||||||
if Context.meters.hidden then return end
|
if Context.meters.hidden and not Context.stat_screen_active then return end
|
||||||
|
|
||||||
local m = Context.meters
|
local m = Context.meters
|
||||||
local cx = 10
|
local cx = 10
|
||||||
@@ -207,7 +206,7 @@ function UI.draw_timer()
|
|||||||
local hand_angle = start_angle + progress_angle
|
local hand_angle = start_angle + progress_angle
|
||||||
local hand_x = math.floor(cx + math.cos(hand_angle) * (r_inner - 1) + 0.5)
|
local hand_x = math.floor(cx + math.cos(hand_angle) * (r_inner - 1) + 0.5)
|
||||||
local hand_y = math.floor(cy + math.sin(hand_angle) * (r_inner - 1) + 0.5)
|
local hand_y = math.floor(cy + math.sin(hand_angle) * (r_inner - 1) + 0.5)
|
||||||
line(cx, cy, hand_x, hand_y, Config.colors.black)
|
line(cx, cy, hand_x, hand_y, Config.colors.white)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Draws meters.
|
--- Draws meters.
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ function GameWindow.draw()
|
|||||||
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)
|
UI.draw_top_bar(screen.name)
|
||||||
if #_available_decisions > 0 then
|
if not Context.stat_screen_active and #_available_decisions > 0 then
|
||||||
UI.draw_decision_selector(_available_decisions, _selected_decision_index)
|
UI.draw_decision_selector(_available_decisions, _selected_decision_index)
|
||||||
end
|
end
|
||||||
Sprite.draw()
|
Sprite.draw()
|
||||||
Focus.draw()
|
Focus.draw()
|
||||||
|
screen.draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Updates the game window logic.
|
--- Updates the game window logic.
|
||||||
@@ -40,6 +41,8 @@ function GameWindow.update()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if Context.stat_screen_active then return end
|
||||||
|
|
||||||
-- Fetch and filter decisions locally
|
-- Fetch and filter decisions locally
|
||||||
local all_decisions_for_screen = Decision.get_for_screen(screen)
|
local all_decisions_for_screen = Decision.get_for_screen(screen)
|
||||||
_available_decisions = Decision.filter_available(all_decisions_for_screen)
|
_available_decisions = Decision.filter_available(all_decisions_for_screen)
|
||||||
|
|||||||
Reference in New Issue
Block a user