Compare commits
3 Commits
4cc0025f5e
...
credits-wi
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ba02c894c | |||
| 98fd6981cc | |||
| 3ed06353b8 |
@@ -24,6 +24,7 @@ globals = {
|
||||
"Minigame",
|
||||
"Window",
|
||||
"ContinuedWindow",
|
||||
"CreditsWindow",
|
||||
"TTGIntroWindow",
|
||||
"BriefIntroWindow",
|
||||
"TitleIntroWindow",
|
||||
|
||||
@@ -3,7 +3,6 @@ init/init.module.lua
|
||||
init/init.config.lua
|
||||
init/init.ascension.lua
|
||||
init/init.context.lua
|
||||
init/init.context_debug.lua
|
||||
system/system.util.lua
|
||||
system/system.print.lua
|
||||
system/system.input.lua
|
||||
@@ -17,7 +16,6 @@ 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
|
||||
@@ -25,7 +23,6 @@ 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
|
||||
@@ -47,18 +44,14 @@ 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
|
||||
@@ -80,13 +73,13 @@ window/window.intro.brief.lua
|
||||
window/window.menu.lua
|
||||
window/window.controls.lua
|
||||
window/window.audiotest.lua
|
||||
window/window.ascend_debug.lua
|
||||
window/window.popup.lua
|
||||
window/window.minigame.mash.lua
|
||||
window/window.minigame.rhythm.lua
|
||||
window/window.minigame.ddr.lua
|
||||
window/window.discussion.lua
|
||||
window/window.continued.lua
|
||||
window/window.credits.lua
|
||||
window/window.game.lua
|
||||
system/system.main.lua
|
||||
meta/meta.assets.lua
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
--- @section Audio
|
||||
|
||||
Audio = {
|
||||
music_playing = nil,
|
||||
music_playing_tempo = nil,
|
||||
music_playing = nil
|
||||
}
|
||||
|
||||
--- Stops current music.
|
||||
@@ -10,17 +9,13 @@ Audio = {
|
||||
function Audio.music_stop()
|
||||
music()
|
||||
Audio.music_playing = nil
|
||||
Audio.music_playing_tempo = nil
|
||||
end
|
||||
|
||||
--- 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)
|
||||
--- Plays track, doesn't restart if already playing.
|
||||
function Audio.music_play(track)
|
||||
if Audio.music_playing ~= track then
|
||||
music(track)
|
||||
Audio.music_playing = track
|
||||
Audio.music_playing_tempo = speed
|
||||
end
|
||||
end
|
||||
|
||||
@@ -52,11 +47,9 @@ function Audio.music_play_room_street_2() end
|
||||
--- @within Audio
|
||||
function Audio.music_play_room_() end
|
||||
|
||||
--- Plays room work music. Speed scales with commute glitch level when active.
|
||||
--- Plays room work music.
|
||||
--- @within Audio
|
||||
function Audio.music_play_room_work(speed)
|
||||
Audio.music_play(0, speed or -1)
|
||||
end
|
||||
function Audio.music_play_room_work() Audio.music_play(0) end
|
||||
|
||||
--- Plays activity work music.
|
||||
--- @within Audio
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
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")
|
||||
|
||||
@@ -2,32 +2,9 @@ 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,
|
||||
})
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
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,
|
||||
})
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
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,
|
||||
})
|
||||
@@ -4,16 +4,10 @@ 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,
|
||||
|
||||
@@ -13,13 +13,11 @@ 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("sumphore_disc_asc_" .. level, "game")
|
||||
Discussion.start("homeless_guy", "game", 4)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
Decision.register({
|
||||
id = "talk_to_truth",
|
||||
label = function()
|
||||
return "Talk to ????"
|
||||
end,
|
||||
handle = function()
|
||||
Discussion.start("norman_truth", "game")
|
||||
end,
|
||||
})
|
||||
@@ -1,241 +0,0 @@
|
||||
-- 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 },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -1,11 +0,0 @@
|
||||
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 },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -27,7 +27,7 @@ Context = {}
|
||||
function Context.initial_data()
|
||||
return {
|
||||
current_menu_item = 1,
|
||||
test_mode = true,
|
||||
test_mode = false,
|
||||
mouse_trace = false,
|
||||
popup = {
|
||||
show = false,
|
||||
@@ -49,16 +49,12 @@ 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",
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
-- Debug helper: start the game at a specific ascension level.
|
||||
-- Set enabled = true and asc_level = 0..Ascension.get_max_level() before launching.
|
||||
ContextDebug = {
|
||||
enabled = false,
|
||||
asc_level = 0,
|
||||
}
|
||||
|
||||
local _level_overrides = {
|
||||
[0] = {
|
||||
day_count = 1,
|
||||
home_norman_visible = true,
|
||||
have_been_to_office = false,
|
||||
have_done_work_today = false,
|
||||
have_met_sumphore = false,
|
||||
},
|
||||
}
|
||||
for i = 1, Ascension.get_max_level() do
|
||||
_level_overrides[i] = {
|
||||
day_count = i + 3,
|
||||
home_norman_visible = true,
|
||||
have_been_to_office = false,
|
||||
have_done_work_today = false,
|
||||
have_met_sumphore = true,
|
||||
}
|
||||
end
|
||||
|
||||
--- Returns Context.initial_data() overridden for the given ascension level.
|
||||
--- @within Context
|
||||
--- @param level number Target ascension level (0..Ascension.get_max_level()).
|
||||
--- @return table Debug-patched initial context data.
|
||||
function Context.initial_data_debug_asc(level)
|
||||
local data = Context.initial_data()
|
||||
data.test_mode = true
|
||||
data.game_in_progress = true
|
||||
data.ascension = { level = level }
|
||||
local overrides = _level_overrides[level] or _level_overrides[0]
|
||||
for k, v in pairs(overrides) do
|
||||
data[k] = v
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
for i = 0, Ascension.get_max_level() do
|
||||
Context["initial_data_debug_asc_" .. i] = function()
|
||||
return Context.initial_data_debug_asc(i)
|
||||
end
|
||||
end
|
||||
|
||||
--- Starts the game at the given ascension level (defaults to ContextDebug.asc_level).
|
||||
--- Wire this to a key or call it directly; do not use Context.new_game() when debugging.
|
||||
--- @within Context
|
||||
--- @param level number|nil Target ascension level.
|
||||
function Context.new_game_debug(level)
|
||||
ContextDebug.enabled = true
|
||||
ContextDebug.asc_level = level or ContextDebug.asc_level
|
||||
|
||||
local data = Context["initial_data_debug_asc_" .. ContextDebug.asc_level]()
|
||||
for k in pairs(Context) do
|
||||
if type(Context[k]) ~= "function" then Context[k] = nil end
|
||||
end
|
||||
for k, v in pairs(data) do Context[k] = v end
|
||||
|
||||
MenuWindow.refresh_menu_items()
|
||||
Screen.get_by_id(Context.game.current_screen).init()
|
||||
end
|
||||
@@ -1,127 +0,0 @@
|
||||
--- @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
|
||||
@@ -509,23 +509,23 @@
|
||||
-- 255:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
||||
-- </SPRITES>
|
||||
-- <MAP>
|
||||
-- 000:ffffffffff0010201020102010201020102010201020102000ffffffffff40404040404087f3f3f3f397a7b7c7d7a7e7f70818a7b7c7d7a7b7c7d7a70b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 001:ffffffffff0040404040404040404040404040404040404000ffffffffff40404040404087f3f3f3f328a7384858a76878f388a7384858a7384858a70b40403b4b4040404040404040404040404040404040404040404040400b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 002:ffffffffff00406070408090a040b0c0d0e0f001f001112100ffffffffff984098409840a8f3f3f3f3b8a7a7a7a7a7c8d8e8f8a7a7a7a7a7a7a7a7a70b405b6b7b4040404040404040404040404040d0e0f001f001f00111210b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 003:ffffffffff004031414051617140814091a1b1b1b1b1c1d100ffffffffff984098409840a8f3f3f3f3091919191919293949591919191919191919190b8b9babbb4040cbdbebfb0c401c2c2c2c3c4091a14c5c6c6c6c6cc1d10b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 004:ffffffffffe140f1024012223240814042a15262728292a2e1ffffffffff984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c8c9cacbc7282ccdcecfc0d401d3030302d4042a13d4d7282728292a27c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 005:ffffffffffb240c2d240e2f203132333435363738393a3b3b2ffffffffff984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d406d7d40e3958d9dadbdcd40ddedfded0e404353839383938393a3b35d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 006:ffffffffffe1c3d3c3d3e3f30414c3d32434445410201020e1ffffffffff404040404040798989898999a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a97c1e1e1e1e44542e1e1e1e3e1e444e4e4e541e243444544454445444547c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 007:ffffffffffb264748494a4b4c4d46494649464940040e4f4b2ffffffffff4040404040404040404040404040404040404040404040404040404040405d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 008:ffffffffffe1c30515d325d33545c3d355d3c3d365b17585e1ffffffffff4040404040404098989898404040404040404040404040404040404040407c1e7e8e1e1e1e9eae1ebe1e1e1e1e1e1e1e1e72821ebe1e72821ebe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 009:ffffffffffb264e395a5b594e39564c5d5946494e5b1b1f5b2ffffffffff4040404040404040404040404040404040404040404040404040404040405d1e05151ebe1ecedeeefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 010:ffffffffffe1c306162636d34656c3e3d5d3c3d376b1b1b1e1ffffffffff404040404040409898989840b9c9c9d9e9f90a0a0a0a4040400a0a0a0a407c1ee395eefe1e0f1f2f3f1e1e1e1e1e1e1e1ee3952f3f1ee3952f3f1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 011:ffffffffffb264946494649464948696a694649410201020b2ffffffffff4040404040404040404040401a2a3a4a5a6a7a40404040404040404040405d1ee3952f3f1e4f5f1ebe1e1e1e1e1e1e1e1ee3951ebe1ee3951ebe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 012:ffffffffffe1c37282d3c3d3c3d3b6c6d6d3c3d300e6f607e1ffffffffff4040404040404098989898408a9aaabaca9ada40404040404040404040407c1e4f5f1ebe1e0515eefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 013:ffffffffffb264e395946494649464946494649465172737b2ffffffffffeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea5d1e0515eefe1e6f7f2f3f1e1e1e1e1e1e1e1e6f7f2f3f1e6f7f2f3f1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 014:ffffffffffe1c34454d3c3d3c3d3c3d3c3d3c3d3e5b14757e1fffffffffff3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c1e6f7f2f3f1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 015:ffffffffffb2649464946494649464946494649476b1b1b1b2fffffffffff3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 016:ffffffffff0010201020766777001020102010201020102000fffffffffff3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f30b1b2b1b2b7667776777761b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 000:20102010200010201020102010201020102010201020102000102010201040404040404087f3f3f3f397a7b7c7d7a7e7f70818a7b7c7d7a7b7c7d7a70b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 001:40404040400040404040404040404040404040404040404000404040404040404040404087f3f3f3f328a7384858a76878f388a7384858a7384858a70b40403b4b4040404040404040404040404040404040404040404040400b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 002:408090a04000406070408090a040b0c0d0e0f001f001112100408090a040984098409840a8f3f3f3f3b8a7a7a7a7a7c8d8e8f8a7a7a7a7a7a7a7a7a70b405b6b7b4040404040404040404040404040d0e0f001f001f00111210b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 003:4051617140004031414051617140814091a1b1b1b1b1c1d1004051617140984098409840a8f3f3f3f3091919191919293949591919191919191919190b8b9babbb4040cbdbebfb0c401c2c2c2c3c4091a14c5c6c6c6c6cc1d10b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 004:4012223240e140f1024012223240814042a15262728292a2e14012223240984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c8c9cacbc7282ccdcecfc0d401d3030302d4042a13d4d7282728292a27c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 005:4040404040b240c2d240e2f203132333435363738393a3b3b24040404040984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d406d7d40e3958d9dadbdcd40ddedfded0e404353839383938393a3b35d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 006:d3c3d3c3d3e1c3d3c3d3e3f30414c3d32434445410201020e1c3d3c3d3c3404040404040798989898999a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a97c1e1e1e1e44542e1e1e1e3e1e444e4e4e541e243444544454445444547c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 007:9464354594b264748494a4b4c4d46494649464940040e4f4b264354594644040404040404040404040404040404040404040404040404040404040405d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 008:d3c3e395d3e1c30515d325d33545c3d355d3c3d365b17585e1c3e395d3254040404040404098989898404040404040404040404040404040404040407c1e7e8e1e1e1e9eae1ebe1e1e1e1e1e1e1e1e72821ebe1e72821ebe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 009:9464465694b264e395a5b594e39564c5d5946494e5b1b1f5b264e395a5b54040404040404040404040404040404040404040404040404040404040405d1e05151ebe1ecedeeefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 010:d3c3d3c3d3e1c306162636d34656c3e3d5d3c3d376b1b1b1e1c3e3952636404040404040409898989840b9c9c9d9e9f90a0a0a0a4040400a0a0a0a407c1ee395eefe1e0f1f2f3f1e1e1e1e1e1e1e1ee3952f3f1ee3952f3f1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 011:9464946494b264946494649464948696a694649410201020b264e395d3254040404040404040404040401a2a3a4a5a6a7a40404040404040404040405d1ee3952f3f1e4f5f1ebe1e1e1e1e1e1e1e1ee3951ebe1ee3951ebe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 012:d3c37282d3e1c37282d3c3d3c3d3b6c6d6d3c3d300e6f607e1c3e395a5b54040404040404098989898408a9aaabaca9ada40404040404040404040407c1e4f5f1ebe1e0515eefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 013:9464e39594b264e395946494649464946494649465172737b26406162636eaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea5d1e0515eefe1e6f7f2f3f1e1e1e1e1e1e1e1e6f7f2f3f1e6f7f2f3f1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 014:d3c34454d3e1c34454d3c3d3c3d3c3d3c3d3c3d3e5b14757e1c3d3c3d3c3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c1e6f7f2f3f1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 015:9464946494b2649464946494649464946494649476b1b1b1b26494649464f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- 016:201020102000102010207667770010201020102010201020001020102010f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f30b1b2b1b2b7667776777761b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
-- </MAP>
|
||||
-- <SFX>
|
||||
-- 016:00000000000000400040004000700070007000400040004000700070007000c000c000c000c000c000c000c000c000c000c000c000c000c000c000c0470000000000
|
||||
|
||||
@@ -54,27 +54,12 @@ 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)
|
||||
|
||||
@@ -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,34 +37,14 @@ Screen.register({
|
||||
{x = -4 + 5 * 8, y = 9 * 8}
|
||||
}
|
||||
|
||||
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"
|
||||
Context.office_sprites = Sprite.list_randomize(possible_sprites, possible_positions)
|
||||
end,
|
||||
background = "office",
|
||||
draw = function()
|
||||
if Window.get_current_id() == "game" then
|
||||
Sprite.draw_at("norman", 13 * 8, 9 * 8)
|
||||
|
||||
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
|
||||
Sprite.draw_list(Context.office_sprites)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
@@ -4,60 +4,16 @@ Screen.register({
|
||||
decisions = {
|
||||
"go_to_home",
|
||||
"go_to_office",
|
||||
"sumphore_discussion",
|
||||
"go_to_truth",
|
||||
},
|
||||
init = function()
|
||||
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"
|
||||
Audio.music_play_room_work()
|
||||
end,
|
||||
background = "street",
|
||||
draw = function()
|
||||
if Window.get_current_id() == "game" then
|
||||
Sprite.draw_at("norman", 7 * 8, 3 * 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
|
||||
Sprite.draw_at("pizza_vendor", 19 * 8, 1 * 8)
|
||||
Sprite.draw_at("dev_guard", 22 * 8, 2 * 8)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
@@ -4,9 +4,11 @@ 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",
|
||||
@@ -27,7 +29,6 @@ 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",
|
||||
|
||||
@@ -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: " .. tostring(sprite_info.id))
|
||||
trace("Error: Attempted to draw non-registered sprite with id: " .. sprite_info.id)
|
||||
else
|
||||
draw_sprite_instance(sprite_data, sprite_info)
|
||||
end
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
-- 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 },
|
||||
}
|
||||
})
|
||||
@@ -1,41 +0,0 @@
|
||||
--- @section AscendDebugWindow
|
||||
local _level = 0
|
||||
|
||||
--- Initialises the ASCEND debug start window.
|
||||
--- @within AscendDebugWindow
|
||||
function AscendDebugWindow.init()
|
||||
_level = 0
|
||||
end
|
||||
|
||||
--- Draws the ASCEND debug start window.
|
||||
--- @within AscendDebugWindow
|
||||
function AscendDebugWindow.draw()
|
||||
UI.draw_top_bar("ASCEND Debug Start")
|
||||
|
||||
local cx = Config.screen.width / 2
|
||||
local cy = Config.screen.height / 2
|
||||
|
||||
local left_arrow = _level > 0 and "<- " or " "
|
||||
local right_arrow = _level < Ascension.get_max_level() and " ->" or " "
|
||||
local label = left_arrow .. "Start at: " .. _level .. right_arrow
|
||||
Print.text_center(label, cx, cy - 4, Config.colors.white, false, 1)
|
||||
|
||||
Print.text_center("Z/select: start X/back: menu", cx, Config.screen.height - 10, Config.colors.dark_grey, false, 1)
|
||||
end
|
||||
|
||||
--- Updates the ASCEND debug start window logic.
|
||||
--- @within AscendDebugWindow
|
||||
function AscendDebugWindow.update()
|
||||
if Input.left() then
|
||||
_level = math.max(0, _level - 1)
|
||||
elseif Input.right() then
|
||||
_level = math.min(Ascension.get_max_level(), _level + 1)
|
||||
elseif Input.select() then
|
||||
Audio.sfx_select()
|
||||
Context.new_game_debug(_level)
|
||||
GameWindow.set_state("game")
|
||||
elseif Input.back() then
|
||||
Audio.sfx_deselect()
|
||||
GameWindow.set_state("menu")
|
||||
end
|
||||
end
|
||||
197
inc/window/window.credits.lua
Normal file
197
inc/window/window.credits.lua
Normal file
@@ -0,0 +1,197 @@
|
||||
--- @section CreditsWindow
|
||||
|
||||
local _time = 0.0
|
||||
local _scroll_x = 0.0
|
||||
local _scroll_total_w = 0
|
||||
local _scroll_chars = {}
|
||||
local _title_chars = {}
|
||||
local _title_total_w = 0
|
||||
local _stars = {}
|
||||
|
||||
local TITLE = "TELETYPE GAMES"
|
||||
|
||||
local SCROLL_PARTS = {
|
||||
"WEB: GAMES.TELETYPE.HU",
|
||||
"BBS: GAMES.TELETYPE.HU:2323",
|
||||
"IRC: LIBERA.CHAT #TELETYPEGAMES",
|
||||
"YOUTUBE.COM/@TELETYPEGAMES",
|
||||
}
|
||||
|
||||
local SCROLL_SEP = " * "
|
||||
|
||||
local SCROLL_SPEED = 55.0
|
||||
local SCROLL_Y = 129
|
||||
local SCROLL_ZONE_COLS = { 7, 4, 9 }
|
||||
|
||||
local TITLE_Y = 4
|
||||
local TITLE_FALL_DUR = 0.45
|
||||
local TITLE_DELAY_STEP = 0.18
|
||||
|
||||
local RASTER_COLS = { 1, 3, 9, 10, 11, 4, 11, 10, 9, 3, 1 }
|
||||
local RASTER_Y_TOP = 26
|
||||
local RASTER_Y_BOT = 110
|
||||
|
||||
local AUTHORS = {
|
||||
"Mr. Zero - Zsolt Tasnadi",
|
||||
"Mr. One - Balazs Tari",
|
||||
"Mr. Two - Zoltan Timar",
|
||||
"Mr. Three - Bela Mezo",
|
||||
}
|
||||
local AUTHORS_BASE_Y = 56
|
||||
local AUTHORS_LINE_H = 12
|
||||
local AUTHORS_ENTRY_DT = 0.65
|
||||
local AUTHORS_ENTRY_V = 2.5
|
||||
|
||||
local RAINBOW = { 4, 9, 3, 7, 13, 2, 9, 4 }
|
||||
local NUM_STARS = 40
|
||||
|
||||
--- Initialises credits state and pre-computes character metrics.
|
||||
--- @within CreditsWindow
|
||||
function CreditsWindow.init()
|
||||
_time = 0.0
|
||||
_scroll_x = Config.screen.width + 4.0
|
||||
|
||||
_title_chars = {}
|
||||
_title_total_w = 0
|
||||
for i = 1, #TITLE do
|
||||
local ch = TITLE:sub(i, i)
|
||||
local w = print(ch, 0, -100, 0, false, 2)
|
||||
_title_chars[i] = { ch = ch, ox = _title_total_w, w = w }
|
||||
_title_total_w = _title_total_w + w
|
||||
end
|
||||
|
||||
_scroll_chars = {}
|
||||
_scroll_total_w = 0
|
||||
local function append_str(str, col)
|
||||
for i = 1, #str do
|
||||
local ch = str:sub(i, i)
|
||||
local w = print(ch, 0, -100, 0, false, 1)
|
||||
_scroll_chars[#_scroll_chars + 1] = { ch = ch, ox = _scroll_total_w, w = w, col = col }
|
||||
_scroll_total_w = _scroll_total_w + w
|
||||
end
|
||||
end
|
||||
for _, part in ipairs(SCROLL_PARTS) do
|
||||
append_str(part, RAINBOW[math.random(#RAINBOW)])
|
||||
append_str(SCROLL_SEP, Config.colors.white)
|
||||
end
|
||||
|
||||
_stars = {}
|
||||
for i = 1, NUM_STARS do
|
||||
_stars[i] = {
|
||||
x = math.random(0, Config.screen.width - 1) + 0.0,
|
||||
y = math.random(0, Config.screen.height - 1),
|
||||
spd = (i % 3 + 1) * 10.0,
|
||||
col = ({ 1, 2, 4, 4 })[(i % 4) + 1],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_stars()
|
||||
for _, s in ipairs(_stars) do
|
||||
pix(math.floor(s.x), s.y, s.col)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_rasters()
|
||||
local cy = RASTER_Y_TOP + math.floor(math.sin(_time * 1.3) * 6)
|
||||
for i, col in ipairs(RASTER_COLS) do
|
||||
local y = cy + i - 1
|
||||
if y >= 0 and y < Config.screen.height then
|
||||
line(0, y, Config.screen.width - 1, y, col)
|
||||
end
|
||||
end
|
||||
local cy2 = RASTER_Y_BOT + math.floor(math.sin(_time * 1.7 + 1.5) * 5)
|
||||
for i, col in ipairs(RASTER_COLS) do
|
||||
local y = cy2 + i - 1
|
||||
if y >= 0 and y < Config.screen.height then
|
||||
line(0, y, Config.screen.width - 1, y, col)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function bounce_out(p)
|
||||
local n1, d1 = 7.5625, 2.75
|
||||
if p < 1 / d1 then
|
||||
return n1 * p * p
|
||||
elseif p < 2 / d1 then
|
||||
p = p - 1.5 / d1; return n1 * p * p + 0.75
|
||||
elseif p < 2.5 / d1 then
|
||||
p = p - 2.25 / d1; return n1 * p * p + 0.9375
|
||||
else
|
||||
p = p - 2.625 / d1; return n1 * p * p + 0.984375
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_title()
|
||||
local sx = math.floor((Config.screen.width - _title_total_w) / 2)
|
||||
local n = #_title_chars
|
||||
local max_dist = (n - 1) / 2.0
|
||||
for i, tc in ipairs(_title_chars) do
|
||||
local dist = math.abs(i - (n + 1) / 2.0)
|
||||
local delay = (max_dist - dist) * TITLE_DELAY_STEP
|
||||
local t = math.max(0, _time - delay)
|
||||
local p = math.min(1, t / TITLE_FALL_DUR)
|
||||
local y = math.floor(-14 + bounce_out(p) * (TITLE_Y + 14))
|
||||
print(tc.ch, sx + tc.ox + 1, y + 1, 0, false, 2)
|
||||
print(tc.ch, sx + tc.ox, y, Config.colors.light_blue, false, 2)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_authors()
|
||||
local col = Config.colors.light_blue
|
||||
for i, lbl in ipairs(AUTHORS) do
|
||||
local enter_t = math.max(0, _time - (i - 1) * AUTHORS_ENTRY_DT)
|
||||
local slide = math.max(0, 1 - enter_t * AUTHORS_ENTRY_V)
|
||||
local x_off = math.floor(slide * (Config.screen.width + 40))
|
||||
local yo = (slide < 0.01) and math.floor(math.sin(_time * 2.0 + i * 1.1) * 2) or 0
|
||||
Print.text(lbl, 12 + x_off, AUTHORS_BASE_Y + (i - 1) * AUTHORS_LINE_H + yo, col)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_scroller()
|
||||
local third = Config.screen.width / 3
|
||||
for pass = 0, 1 do
|
||||
local base = _scroll_x + pass * _scroll_total_w
|
||||
for _, sc in ipairs(_scroll_chars) do
|
||||
local x = math.floor(base + sc.ox)
|
||||
if x >= Config.screen.width then break end
|
||||
if x + sc.w > 0 then
|
||||
local zone = math.max(1, math.min(3, math.floor(x / third) + 1))
|
||||
print(sc.ch, x, SCROLL_Y, SCROLL_ZONE_COLS[zone], false, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Draws the credits window.
|
||||
--- @within CreditsWindow
|
||||
function CreditsWindow.draw()
|
||||
cls(Config.colors.black)
|
||||
draw_stars()
|
||||
draw_rasters()
|
||||
draw_title()
|
||||
Print.text_center("Authors", Config.screen.width / 2, 47, Config.colors.light_grey)
|
||||
draw_authors()
|
||||
draw_scroller()
|
||||
|
||||
end
|
||||
|
||||
--- Updates credits window logic.
|
||||
--- @within CreditsWindow
|
||||
function CreditsWindow.update()
|
||||
_time = _time + Context.delta_time
|
||||
|
||||
for _, s in ipairs(_stars) do
|
||||
s.x = s.x + s.spd * Context.delta_time
|
||||
if s.x >= Config.screen.width then s.x = s.x - Config.screen.width end
|
||||
end
|
||||
|
||||
_scroll_x = _scroll_x - SCROLL_SPEED * Context.delta_time
|
||||
if _scroll_x <= -_scroll_total_w then
|
||||
_scroll_x = _scroll_x + _scroll_total_w
|
||||
end
|
||||
|
||||
if Input.back() or Input.select() then
|
||||
Window.set_current("menu")
|
||||
end
|
||||
end
|
||||
@@ -6,8 +6,7 @@ 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
|
||||
local actual_background = (type(screen.background) == "function" and screen.background()) or screen.background
|
||||
Map.draw(actual_background)
|
||||
Map.draw(screen.background)
|
||||
elseif screen.background_color then
|
||||
rect(0, 0, Config.screen.width, Config.screen.height, screen.background_color)
|
||||
end
|
||||
|
||||
@@ -139,6 +139,13 @@ function MenuWindow.controls()
|
||||
Window.set_current("controls")
|
||||
end
|
||||
|
||||
--- Opens the credits screen.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.credits()
|
||||
CreditsWindow.init()
|
||||
Window.set_current("credits")
|
||||
end
|
||||
|
||||
--- Opens the audio test menu.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.audio_test()
|
||||
@@ -161,13 +168,6 @@ function MenuWindow.ddr_test()
|
||||
MinigameDDRWindow.start("menu", "generated", { special_mode = "only_nothing" })
|
||||
end
|
||||
|
||||
--- Opens the ASCEND debug start window.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.ascend_debug()
|
||||
AscendDebugWindow.init()
|
||||
GameWindow.set_state("ascend_debug")
|
||||
end
|
||||
|
||||
--- Refreshes the list of menu items based on current game state.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.refresh_menu_items()
|
||||
@@ -180,12 +180,12 @@ function MenuWindow.refresh_menu_items()
|
||||
table.insert(_menu_items, {label = "New Game", decision = MenuWindow.new_game})
|
||||
table.insert(_menu_items, {label = "Load Game", decision = MenuWindow.load_game})
|
||||
table.insert(_menu_items, {label = "Controls", decision = MenuWindow.controls})
|
||||
table.insert(_menu_items, {label = "Credits", decision = MenuWindow.credits})
|
||||
|
||||
if Context.test_mode then
|
||||
table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test})
|
||||
table.insert(_menu_items, {label = "To Be Continued...", decision = MenuWindow.continued})
|
||||
table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test})
|
||||
table.insert(_menu_items, {label = "Start at ASCEND N", decision = MenuWindow.ascend_debug})
|
||||
end
|
||||
|
||||
table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit})
|
||||
|
||||
@@ -22,9 +22,6 @@ Window.register("controls", ControlsWindow)
|
||||
AudioTestWindow = {}
|
||||
Window.register("audiotest", AudioTestWindow)
|
||||
|
||||
AscendDebugWindow = {}
|
||||
Window.register("ascend_debug", AscendDebugWindow)
|
||||
|
||||
MinigameButtonMashWindow = {}
|
||||
Window.register("minigame_button_mash", MinigameButtonMashWindow)
|
||||
|
||||
@@ -42,3 +39,6 @@ Window.register("discussion", DiscussionWindow)
|
||||
|
||||
ContinuedWindow = {}
|
||||
Window.register("continued", ContinuedWindow)
|
||||
|
||||
CreditsWindow = {}
|
||||
Window.register("credits", CreditsWindow)
|
||||
|
||||
Reference in New Issue
Block a user