128 lines
4.2 KiB
Lua
128 lines
4.2 KiB
Lua
--- @section CommuteGlitch
|
|
CommuteGlitch = {}
|
|
|
|
--- Gets the current commute glitch level.
|
|
--- @within CommuteGlitch
|
|
--- @return number Current glitch level (0-7).
|
|
function CommuteGlitch.get_level()
|
|
return Context and (Context.commute_glitch_level or 0) or 0
|
|
end
|
|
|
|
--- Increments the glitch counter. Called on each office screen init at asc level 7.
|
|
--- Caps at 6; use enter_truth() to reach 7.
|
|
--- @within CommuteGlitch
|
|
function CommuteGlitch.increment()
|
|
if not Context then return end
|
|
if Context.commute_glitch_level >= 7 then return end
|
|
Context.commute_glitch_level = math.min(6, (Context.commute_glitch_level or 0) + 1)
|
|
end
|
|
|
|
--- Resets the glitch counter and hides the glitch overlay. Called when going home.
|
|
--- @within CommuteGlitch
|
|
function CommuteGlitch.reset()
|
|
if not Context then return end
|
|
Context.commute_glitch_level = 0
|
|
Glitch.hide()
|
|
end
|
|
|
|
--- Jumps to glitch level 7 (full corruption). Called by go_to_truth.
|
|
--- @within CommuteGlitch
|
|
function CommuteGlitch.enter_truth()
|
|
if not Context then return end
|
|
Context.commute_glitch_level = 7
|
|
Glitch.show()
|
|
Ascension.start_flash()
|
|
end
|
|
|
|
--- Returns true when ascension level is 7 (ASCENSIO step active).
|
|
--- @within CommuteGlitch
|
|
--- @return boolean Whether the commute glitch system is active.
|
|
function CommuteGlitch.is_active()
|
|
return Ascension.get_level() == 7
|
|
end
|
|
|
|
--- Returns the music playback speed for the current glitch level.
|
|
--- TIC-80 default speed is 6; each step past 1 adds 2.
|
|
--- @within CommuteGlitch
|
|
--- @return number Speed value for music().
|
|
function CommuteGlitch.music_speed()
|
|
local level = CommuteGlitch.get_level()
|
|
if level <= 1 then return 6 end
|
|
return 6 + (level - 1) * 2
|
|
end
|
|
|
|
--- Returns a corrupted copy of a sprite drawable list.
|
|
--- Applies flip_y and norman_echo id replacements based on glitch level.
|
|
--- Entries marked norman_echo should be drawn via draw_sprite_list for palette change handling.
|
|
--- @within CommuteGlitch
|
|
--- @param list table Drawable sprite list from Sprite.list_randomize.
|
|
--- @return table Corrupted copy of the list.
|
|
function CommuteGlitch.corrupt_sprite_list(list)
|
|
local level = CommuteGlitch.get_level()
|
|
if level < 3 or not list then return list end
|
|
local result = {}
|
|
for i, entry in ipairs(list) do
|
|
local e = {}
|
|
for k, v in pairs(entry) do e[k] = v end
|
|
if level >= 7 then
|
|
e.id = "norman_echo"
|
|
else
|
|
local n_flip = (level >= 5) and 2 or 1
|
|
local n_echo = (level >= 5) and 2 or (level >= 4) and 1 or 0
|
|
if i <= n_flip then e.flip_y = 1 end
|
|
if i > n_flip and i <= n_flip + n_echo then e.id = "norman_echo" end
|
|
end
|
|
table.insert(result, e)
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- Palette indices for Norman echo color remap.
|
|
-- Implementer: pick ECHO_SRC as one of Norman's main body colors and ECHO_DST
|
|
-- as a contrasting or wrong palette color by inspecting the sprite sheet.
|
|
local ECHO_SRC = 4
|
|
local ECHO_DST = 14
|
|
|
|
-- Base nibble address of the PALETTE MAP in VRAM.
|
|
local PALETTE_MAP_ADDR = 0x03FF0 * 2
|
|
|
|
--- Draws a sprite list, applying a PALETTE MAP remap for norman_echo entries.
|
|
--- Uses poke4 to remap ECHO_SRC → ECHO_DST before drawing echoes, then restores.
|
|
--- @within CommuteGlitch
|
|
--- @param list table Drawable sprite list (may contain mixed normal and echo entries).
|
|
function CommuteGlitch.draw_sprite_list(list)
|
|
if not list then return end
|
|
local normal, echo = {}, {}
|
|
for _, entry in ipairs(list) do
|
|
if entry.id == "norman_echo" then
|
|
table.insert(echo, entry)
|
|
else
|
|
table.insert(normal, entry)
|
|
end
|
|
end
|
|
if #normal > 0 then
|
|
Sprite.draw_list(normal)
|
|
end
|
|
if #echo > 0 then
|
|
poke4(PALETTE_MAP_ADDR + ECHO_SRC, ECHO_DST)
|
|
Sprite.draw_list(echo)
|
|
poke4(PALETTE_MAP_ADDR + ECHO_SRC, ECHO_SRC)
|
|
end
|
|
end
|
|
|
|
local _flicker_tick = 0
|
|
|
|
--- Draws a random tile-flicker effect over the background (glitch level 7).
|
|
--- Every 3 frames draws 6 random 8x8 rects in random palette colors.
|
|
--- @within CommuteGlitch
|
|
function CommuteGlitch.draw_background_flicker()
|
|
_flicker_tick = (_flicker_tick + 1) % 3
|
|
if _flicker_tick ~= 0 then return end
|
|
for _ = 1, 6 do
|
|
local tx = math.random(0, math.floor(Config.screen.width / 8) - 1) * 8
|
|
local ty = math.random(0, math.floor(Config.screen.height / 8) - 1) * 8
|
|
local color = math.random(0, 15)
|
|
rect(tx, ty, 8, 8, color)
|
|
end
|
|
end
|