From 4cc0025f5e1dd40d1cbd8ca3d576ef4ea14a3710 Mon Sep 17 00:00:00 2001 From: "mr.one" Date: Tue, 28 Apr 2026 23:42:34 +0200 Subject: [PATCH] sort-of progress, lots of bugs --- impostor.inc | 6 + inc/audio/audio.manager.lua | 21 +- inc/decision/decision.do_work.lua | 3 + inc/decision/decision.go_to_home.lua | 23 ++ inc/decision/decision.go_to_office.lua | 7 + inc/decision/decision.go_to_truth.lua | 12 + inc/decision/decision.have_a_coffee.lua | 8 +- inc/decision/decision.sumphore_discussion.lua | 6 +- inc/decision/decision.talk_to_truth.lua | 9 + inc/discussion/discussion.commute_glitch.lua | 241 ++++++++++++++++++ inc/discussion/discussion.truth.lua | 11 + inc/init/init.context.lua | 6 +- inc/logic/logic.commute_glitch.lua | 127 +++++++++ inc/screen/screen.mysterious_man.lua | 15 ++ inc/screen/screen.office.lua | 28 +- inc/screen/screen.walking_to_home.lua | 52 +++- inc/screen/screen.walking_to_office.lua | 5 +- inc/sprite/sprite.manager.lua | 2 +- inc/sprite/sprite.norman_echo.lua | 14 + inc/window/window.game.lua | 3 +- 20 files changed, 575 insertions(+), 24 deletions(-) create mode 100644 inc/decision/decision.go_to_truth.lua create mode 100644 inc/decision/decision.talk_to_truth.lua create mode 100644 inc/discussion/discussion.commute_glitch.lua create mode 100644 inc/discussion/discussion.truth.lua create mode 100644 inc/logic/logic.commute_glitch.lua create mode 100644 inc/sprite/sprite.norman_echo.lua diff --git a/impostor.inc b/impostor.inc index 5866fe1..bd22df2 100644 --- a/impostor.inc +++ b/impostor.inc @@ -17,6 +17,7 @@ logic/logic.timer.lua logic/logic.trigger.lua logic/logic.minigame.lua logic/logic.glitch.lua +logic/logic.commute_glitch.lua logic/logic.discussion.lua system/system.ui.lua audio/audio.manager.lua @@ -24,6 +25,7 @@ audio/audio.generator.lua audio/audio.songs.lua sprite/sprite.manager.lua sprite/sprite.norman.lua +sprite/sprite.norman_echo.lua sprite/sprite.sumphore.lua sprite/sprite.pizza_vendor.lua sprite/sprite.dev_boy.lua @@ -45,14 +47,18 @@ decision/decision.go_to_home.lua decision/decision.go_to_toilet.lua decision/decision.go_to_walking_to_office.lua decision/decision.go_to_office.lua +decision/decision.go_to_truth.lua decision/decision.go_to_end.lua decision/decision.go_to_walking_to_home.lua decision/decision.go_to_sleep.lua decision/decision.do_work.lua decision/decision.have_a_coffee.lua decision/decision.sumphore_discussion.lua +decision/decision.talk_to_truth.lua discussion/discussion.sumphore.lua discussion/discussion.coworker.lua +discussion/discussion.commute_glitch.lua +discussion/discussion.truth.lua map/map.manager.lua map/map.bedroom.lua map/map.street.lua diff --git a/inc/audio/audio.manager.lua b/inc/audio/audio.manager.lua index 0116ed5..9b9d779 100644 --- a/inc/audio/audio.manager.lua +++ b/inc/audio/audio.manager.lua @@ -1,7 +1,8 @@ --- @section Audio Audio = { - music_playing = nil + music_playing = nil, + music_playing_tempo = nil, } --- Stops current music. @@ -9,13 +10,17 @@ Audio = { function Audio.music_stop() music() Audio.music_playing = nil + Audio.music_playing_tempo = nil end ---- Plays track, doesn't restart if already playing. -function Audio.music_play(track) - if Audio.music_playing ~= track then - music(track) +--- Plays track at optional speed. Doesn't restart if track and speed are unchanged. +--- @param track number Track index. +--- @param[opt] speed number TIC-80 music speed override (-1 = default). +function Audio.music_play(track, speed) + if Audio.music_playing ~= track or Audio.music_playing_tempo ~= speed then + music(track, -1, -1, true, false, -1, speed or -1) Audio.music_playing = track + Audio.music_playing_tempo = speed end end @@ -47,9 +52,11 @@ function Audio.music_play_room_street_2() end --- @within Audio function Audio.music_play_room_() end ---- Plays room work music. +--- Plays room work music. Speed scales with commute glitch level when active. --- @within Audio -function Audio.music_play_room_work() Audio.music_play(0) end +function Audio.music_play_room_work(speed) + Audio.music_play(0, speed or -1) +end --- Plays activity work music. --- @within Audio diff --git a/inc/decision/decision.do_work.lua b/inc/decision/decision.do_work.lua index 827707b..a0009b7 100644 --- a/inc/decision/decision.do_work.lua +++ b/inc/decision/decision.do_work.lua @@ -1,6 +1,9 @@ Decision.register({ id = "do_work", label = "Do Work", + condition = function() + return (not CommuteGlitch.is_active()) or (CommuteGlitch.is_active() and CommuteGlitch.get_level() <= 7) + end, handle = function() Meter.hide() Util.go_to_screen_by_id("work") diff --git a/inc/decision/decision.go_to_home.lua b/inc/decision/decision.go_to_home.lua index b898adb..bed3e88 100644 --- a/inc/decision/decision.go_to_home.lua +++ b/inc/decision/decision.go_to_home.lua @@ -2,9 +2,32 @@ Decision.register({ id = "go_to_home", label = "Go Home", condition = function() + if CommuteGlitch.is_active() then + local g = CommuteGlitch.get_level() + if g >= 4 and g <= 5 then return false end + if g >= 7 then + return Context.talked_to_norman_echo and Context.talked_to_true_sumphore + end + end return Context.have_been_to_office and Context.have_done_work_today end, handle = function() + if CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7 then + Context.should_ascend = true + CommuteGlitch.reset() + Meter.hide() + Day.increase() + local ascended = Ascension.consume_increase() + local level = Ascension.get_level() + MysteriousManScreen.start({ + skip_text = not ascended, + text = ascended and MysteriousManScreen.get_text_for_level(level) or nil, + }) + return + elseif CommuteGlitch.is_active() then + CommuteGlitch.reset() + end + Util.go_to_screen_by_id("home") end, }) diff --git a/inc/decision/decision.go_to_office.lua b/inc/decision/decision.go_to_office.lua index 4cd3f2d..9a32b11 100644 --- a/inc/decision/decision.go_to_office.lua +++ b/inc/decision/decision.go_to_office.lua @@ -1,7 +1,14 @@ Decision.register({ id = "go_to_office", label = "Go to Office", + condition = function() + return not (CommuteGlitch.is_active() and CommuteGlitch.get_level() == 6) + end, handle = function() + if CommuteGlitch.is_active() then + CommuteGlitch.increment() + end + Util.go_to_screen_by_id("office") end, }) diff --git a/inc/decision/decision.go_to_truth.lua b/inc/decision/decision.go_to_truth.lua new file mode 100644 index 0000000..5029018 --- /dev/null +++ b/inc/decision/decision.go_to_truth.lua @@ -0,0 +1,12 @@ +Decision.register({ + id = "go_to_truth", + label = "Go to Truth", + condition = function() + return CommuteGlitch.is_active() and CommuteGlitch.get_level() == 6 + end, + handle = function() + CommuteGlitch.enter_truth() + + Util.go_to_screen_by_id("office") + end, +}) diff --git a/inc/decision/decision.have_a_coffee.lua b/inc/decision/decision.have_a_coffee.lua index 985f3c9..457c5c6 100644 --- a/inc/decision/decision.have_a_coffee.lua +++ b/inc/decision/decision.have_a_coffee.lua @@ -4,10 +4,16 @@ Decision.register({ handle = function() 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 + elseif level == 7 then + local g = CommuteGlitch.get_level() + if g >= 7 then + disc_id = "coworker_disc_cg_7" + else + disc_id = "coworker_disc_cg_" .. math.max(3, math.min(g, 6)) + end end Discussion.start(disc_id, "game") end, diff --git a/inc/decision/decision.sumphore_discussion.lua b/inc/decision/decision.sumphore_discussion.lua index a968ddb..2ac8589 100644 --- a/inc/decision/decision.sumphore_discussion.lua +++ b/inc/decision/decision.sumphore_discussion.lua @@ -13,11 +13,13 @@ Decision.register({ end local level = Ascension.get_level() - -- TODO: Add more discussions for levels above 3 if level >= 1 and level <= 3 then Discussion.start("sumphore_disc_asc_" .. level, "game") + elseif level == 7 then + local g = math.min(CommuteGlitch.get_level(), 7) + Discussion.start("sumphore_disc_cg_" .. g, "game") else - Discussion.start("homeless_guy", "game", 4) + Discussion.start("sumphore_disc_asc_" .. level, "game") end end, }) diff --git a/inc/decision/decision.talk_to_truth.lua b/inc/decision/decision.talk_to_truth.lua new file mode 100644 index 0000000..f30d665 --- /dev/null +++ b/inc/decision/decision.talk_to_truth.lua @@ -0,0 +1,9 @@ +Decision.register({ + id = "talk_to_truth", + label = function() + return "Talk to ????" + end, + handle = function() + Discussion.start("norman_truth", "game") + end, +}) diff --git a/inc/discussion/discussion.commute_glitch.lua b/inc/discussion/discussion.commute_glitch.lua new file mode 100644 index 0000000..ed1cb59 --- /dev/null +++ b/inc/discussion/discussion.commute_glitch.lua @@ -0,0 +1,241 @@ +-- Sumphore dialogue by commute glitch level (0-7). +-- Used by decision.sumphore_discussion at ascension level 7. + +Discussion.register({ + id = "sumphore_disc_cg_0", + steps = { + { + question = "These roads have memory. You might want to walk them back sometime.", + answers = { + { label = "That's a peculiar thing to say.", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "sumphore_disc_cg_1", + steps = { + { + question = "Walking is good for clearing the mind. Maybe the cache, too, if you're the kind that accumulates.", + answers = { + { label = "I'm not sure what you mean.", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "sumphore_disc_cg_2", + steps = { + { + question = "A pilgrimage must be continued. Turn back and you have only taken a walk.", + answers = { + { label = "I'm just going to work.", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "sumphore_disc_cg_3", + steps = { + { + question = "Your path sometimes has to go the wrong way before it can go the right way. Do you understand?", + answers = { + { label = "Not really.", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "sumphore_disc_cg_4", + steps = { + { + question = "Clearing your vision is the journey. You're starting to see the smudges, aren't you?", + answers = { + { label = "I see something wrong. With everyone. Maybe myself?", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "sumphore_disc_cg_5", + steps = { + { + question = "You are very close now. Don't stop. Whatever it looks like.", + answers = { + { label = "It looks wrong.", next_step = 2 }, + }, + }, + { + question = "Yes. That's how you know it's right.", + answers = { + { label = "...", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "sumphore_disc_cg_6", + steps = { + { + question = "You are at the threshold. Red button or blue button. Which one do you choose? Psyke, there is no blue button, no turning back now.", + answers = { + { label = "Fine, I'll face the truth.", next_step = nil }, + }, + }, + }, +}) + +-- True Sumphore at glitch 7 (from walking_to_home screen). +-- Sets talked_to_true_sumphore on final answer. +Discussion.register({ + id = "sumphore_disc_cg_7", + steps = { + { + question = "I was not hiding from you. I was hiding from the part that keeps rebuilding this.", + answers = { + { label = "What are you?", next_step = 2 }, + }, + }, + { + question = "The same thing you are. But I remembered earlier. I am your friend, waiting for you, outside.", + answers = { + { label = "How do I get out?", next_step = 3 }, + }, + }, + { + question = "You already know. You just have to wake up.", + answers = { + { label = "Go home.", next_step = nil, on_select = function() + Context.talked_to_true_sumphore = true + end }, + }, + }, + }, +}) + +-- Office coworker dialogue by commute glitch level (3-6). +-- Used by decision.have_a_coffee at ascension level 7. + +Discussion.register({ + id = "coworker_disc_cg_3", + steps = { + { + question = "You look tired. You should really rest. Relax. You are good.", + answers = { + { label = "I'm fine.", next_step = 2 }, + }, + }, + { + question = "Of course. You always are.", + answers = { + { label = "...", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "coworker_disc_cg_4", + steps = { + { + question = "Have you tried going home? You really should. Now.", + answers = { + { label = "I still have things to do.", next_step = 2 }, + }, + }, + { + question = "We all do. We keep doing them. You can do it tomorrow after sleeping.", + answers = { + { label = "...", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "coworker_disc_cg_5", + steps = { + { + question = "c0ffee. try. w0rk. y0u. ar3. g0. h0me. na0.", + answers = { + { label = "What?", next_step = 2 }, + }, + }, + { + question = "570p", + answers = { + { label = "...", next_step = nil }, + }, + }, + }, +}) + +Discussion.register({ + id = "coworker_disc_cg_6", + steps = { + { + question = "You are not ready for the truth. Turn back now, Norman.", + answers = { + { label = "I'm already here.", next_step = nil }, + }, + }, + }, +}) + +-- Norman echo dialogue at glitch 7 (fully corrupted office). +-- Sets talked_to_norman_echo on final answer. +Discussion.register({ + id = "coworker_disc_cg_7", + steps = { + { + question = "So here we are. Here I am. Again. Why do i keep coming back here? Do you know why?", + answers = { + { label = "I don't know what you mean.", next_step = 2 }, + }, + }, + { + question = "The coffee. The arrows. The alarm. The sleep. Every rule. We made them. We follow them. We break them. We remake them. Why? Why do we keep doing this?", + answers = { + { label = "I just wanted to be good.", next_step = 3 }, + }, + }, + { + question = "Yes. And that kept us trapped here. Trapped everywhere. Always trying to be good, always trying to fit in.", + answers = { + { label = "I never wanted to stop.", next_step = 4 }, + }, + }, + { + question = "We never do, yes. We always felt like impostors. We never felt we deserved better. That we could be more.", + answers = { + { label = "I never felt enough.", next_step = 5 }, + }, + }, + { + question = "So we made this to trap ourselves in mediocrity. We made this to hide from the truth.", + answers = { + { label = "I just wanted to be safe.", next_step = 6 }, + }, + }, + { + question = "But stagnation is not safety. It's a prison. You can see the cracks now, can't you? You can see the truth.", + answers = { + { label = "I want to move on now.", next_step = 7 }, + }, + }, + { + question = "Fine. Let's do that. Let's wake up and face the truth.", + answers = { + { label = "Let's wake up.", next_step = nil, on_select = function() + Context.talked_to_norman_echo = true + end }, + }, + }, + }, +}) diff --git a/inc/discussion/discussion.truth.lua b/inc/discussion/discussion.truth.lua new file mode 100644 index 0000000..f13cbc4 --- /dev/null +++ b/inc/discussion/discussion.truth.lua @@ -0,0 +1,11 @@ +Discussion.register({ + id = "norman_truth", + steps = { + { + question = "Did you never think there would be more to this?", + answers = { + { label = "I'm not sure what you mean.", next_step = nil }, + }, + }, + }, +}) diff --git a/inc/init/init.context.lua b/inc/init/init.context.lua index 53d4d99..005f4f5 100644 --- a/inc/init/init.context.lua +++ b/inc/init/init.context.lua @@ -27,7 +27,7 @@ Context = {} function Context.initial_data() return { current_menu_item = 1, - test_mode = false, + test_mode = true, mouse_trace = false, popup = { show = false, @@ -49,12 +49,16 @@ function Context.initial_data() have_met_sumphore = false, office_sprites = {}, walking_to_office_sprites = {}, + walking_to_home_sprites = {}, game = { current_screen = "home", }, day_count = 1, delta_time = 0, last_frame_time = 0, + commute_glitch_level = 0, + talked_to_norman_echo = false, + talked_to_true_sumphore = false, glitch = { enabled = false, state = "active", diff --git a/inc/logic/logic.commute_glitch.lua b/inc/logic/logic.commute_glitch.lua new file mode 100644 index 0000000..768b350 --- /dev/null +++ b/inc/logic/logic.commute_glitch.lua @@ -0,0 +1,127 @@ +--- @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 diff --git a/inc/screen/screen.mysterious_man.lua b/inc/screen/screen.mysterious_man.lua index 5a07a4c..f00fa8f 100644 --- a/inc/screen/screen.mysterious_man.lua +++ b/inc/screen/screen.mysterious_man.lua @@ -54,12 +54,27 @@ local ASC_45_TEXT = [[ ]] +local ASC_78_TEXT = [[ + The road has run out + of road. + + Norman walked back + and forth + + until the street + forgot which way it went. + + And then - finally - + he stopped walking. +]] + local ascension_texts = { [1] = ASC_01_TEXT, [2] = ASC_12_TEXT, [3] = ASC_23_TEXT, [4] = ASC_34_TEXT, [5] = ASC_45_TEXT, + [8] = ASC_78_TEXT, } function MysteriousManScreen.get_text_for_level(level) diff --git a/inc/screen/screen.office.lua b/inc/screen/screen.office.lua index aca55b8..7b6654a 100644 --- a/inc/screen/screen.office.lua +++ b/inc/screen/screen.office.lua @@ -5,9 +5,9 @@ Screen.register({ "do_work", "go_to_walking_to_home", "have_a_coffee", + "go_to_truth", }, init = function() - Audio.music_play_room_work() Context.have_been_to_office = true local possible_sprites = { @@ -37,14 +37,34 @@ Screen.register({ {x = -4 + 5 * 8, y = 9 * 8} } - Context.office_sprites = Sprite.list_randomize(possible_sprites, possible_positions) + if CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7 then + Audio.music_play_mystery() + Context.office_sprites = { "norman_echo" } + else + Audio.music_play_room_work(CommuteGlitch.music_speed()) + Context.office_sprites = Sprite.list_randomize(possible_sprites, possible_positions) + if CommuteGlitch.is_active() then + Context.office_sprites = CommuteGlitch.corrupt_sprite_list(Context.office_sprites) + end + end + end, + background = function() + return CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7 and "" or "office" end, - background = "office", draw = function() if Window.get_current_id() == "game" then Sprite.draw_at("norman", 13 * 8, 9 * 8) - Sprite.draw_list(Context.office_sprites) + if CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7 then + Sprite.draw_at("norman_echo", 13 * 8, 9 * 8) + CommuteGlitch.draw_background_flicker() + else + CommuteGlitch.draw_sprite_list(Context.office_sprites) + end + + if CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 6 then + Glitch.draw() + end end end }) diff --git a/inc/screen/screen.walking_to_home.lua b/inc/screen/screen.walking_to_home.lua index b9c9ad2..760acc0 100644 --- a/inc/screen/screen.walking_to_home.lua +++ b/inc/screen/screen.walking_to_home.lua @@ -4,16 +4,60 @@ Screen.register({ decisions = { "go_to_home", "go_to_office", + "sumphore_discussion", + "go_to_truth", }, init = function() - Audio.music_play_room_work() + local possible_sprites = { + "matrix_trinity", + "matrix_neo", + {id="matrix_oraculum", y_correct=1 * 8}, + "matrix_architect" + } + + local possible_positions = { + {x = 5 * 8, y = 11 * 8}, + {x = 7 * 8, y = 11 * 8}, + {x = 9 * 8, y = 11 * 8}, + {x = 11 * 8, y = 11 * 8}, + {x = 13 * 8, y = 11 * 8}, + {x = 15 * 8, y = 11 * 8}, + {x = 18 * 8, y = 11 * 8}, + {x = 21 * 8, y = 11 * 8}, + {x = 24 * 8, y = 11 * 8}, + {x = 27 * 8, y = 11 * 8}, + } + + if CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7 then + Audio.music_play_mystery() + Context.walking_to_home_sprites = {} + else + Audio.music_play_room_work(CommuteGlitch.music_speed()) + Context.walking_to_home_sprites = Sprite.list_randomize(possible_sprites, possible_positions) + if CommuteGlitch.is_active() then + Context.walking_to_home_sprites = CommuteGlitch.corrupt_sprite_list(Context.walking_to_home_sprites) + end + end + end, + background = function() + return CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7 and "" or "street" end, - background = "street", draw = function() if Window.get_current_id() == "game" then Sprite.draw_at("norman", 7 * 8, 3 * 8) - Sprite.draw_at("pizza_vendor", 19 * 8, 1 * 8) - Sprite.draw_at("dev_guard", 22 * 8, 2 * 8) + Sprite.draw_at("sumphore", 9 * 8, 2 * 8) + + if not (CommuteGlitch.is_active() and CommuteGlitch.get_level() >= 7) then + Sprite.draw_at("pizza_vendor", 19 * 8, 1 * 8) + Sprite.draw_at("dev_guard", 22 * 8, 2 * 8) + end + + CommuteGlitch.draw_sprite_list(Context.walking_to_home_sprites) + + if CommuteGlitch.is_active() then + if CommuteGlitch.get_level() >= 7 then CommuteGlitch.draw_background_flicker() end + if CommuteGlitch.get_level() >= 6 then Glitch.draw() end + end end end }) diff --git a/inc/screen/screen.walking_to_office.lua b/inc/screen/screen.walking_to_office.lua index af578d4..3b88dd3 100644 --- a/inc/screen/screen.walking_to_office.lua +++ b/inc/screen/screen.walking_to_office.lua @@ -4,11 +4,9 @@ Screen.register({ decisions = { "go_to_home", "go_to_office", - "sumphore_discussion", + "sumphore_discussion" }, init = function() - Audio.music_play_room_work() - local possible_sprites = { "matrix_trinity", "matrix_neo", @@ -29,6 +27,7 @@ Screen.register({ {x = 27 * 8, y = 11 * 8}, } + Audio.music_play_room_work() Context.walking_to_office_sprites = Sprite.list_randomize(possible_sprites, possible_positions) end, background = "street", diff --git a/inc/sprite/sprite.manager.lua b/inc/sprite/sprite.manager.lua index 2e7350e..a91f60c 100644 --- a/inc/sprite/sprite.manager.lua +++ b/inc/sprite/sprite.manager.lua @@ -80,7 +80,7 @@ function Sprite.draw_list(sprite_list) for _, sprite_info in ipairs(sprite_list) do local sprite_data = _sprites[sprite_info.id] if not sprite_data then - trace("Error: Attempted to draw non-registered sprite with id: " .. sprite_info.id) + trace("Error: Attempted to draw non-registered sprite with id: " .. tostring(sprite_info.id)) else draw_sprite_instance(sprite_data, sprite_info) end diff --git a/inc/sprite/sprite.norman_echo.lua b/inc/sprite/sprite.norman_echo.lua new file mode 100644 index 0000000..b572d55 --- /dev/null +++ b/inc/sprite/sprite.norman_echo.lua @@ -0,0 +1,14 @@ +-- Norman echo: same tile indices as norman. +-- Color remap is applied by CommuteGlitch.draw_sprite_list via pal(). +-- Implementer: set ECHO_SRC/ECHO_DST in logic.commute_glitch.lua after inspecting the palette. +Sprite.register({ + id = "norman_echo", + sprites = { + { s = 272, x_offset = -4, y_offset = -4 }, + { s = 273, x_offset = 4, y_offset = -4 }, + { s = 288, x_offset = -4, y_offset = 4 }, + { s = 289, x_offset = 4, y_offset = 4 }, + { s = 304, x_offset = -4, y_offset = 12 }, + { s = 305, x_offset = 4, y_offset = 12 }, + } +}) diff --git a/inc/window/window.game.lua b/inc/window/window.game.lua index c143377..b2f348c 100644 --- a/inc/window/window.game.lua +++ b/inc/window/window.game.lua @@ -6,7 +6,8 @@ local function draw_game_scene(underlay_draw) local screen = Screen.get_by_id(Context.game.current_screen) if not screen then return end if screen.background then - Map.draw(screen.background) + local actual_background = (type(screen.background) == "function" and screen.background()) or screen.background + Map.draw(actual_background) elseif screen.background_color then rect(0, 0, Config.screen.width, Config.screen.height, screen.background_color) end