Files
libretro/bios/Other/Recalbox/game.lua
Abdessamad Derraz 13c561888d v2: automated BIOS platform with full pipeline
Reorganized 6 branches into bios/Manufacturer/Console/.
Scrapers for RetroArch, Batocera, Recalbox, and libretro core-info.
Platform-aware verification replicating native logic per platform.
Pack generation with dedup, alias resolution, variant support.
CI/CD: weekly auto-scrape, auto-release, PR validation.
Large files (>50MB) stored as GitHub Release assets, auto-fetched at build time.
2026-03-17 10:54:39 +01:00

3317 lines
123 KiB
Lua

-- DirkSimple; a dirt-simple player for FMV games.
--
-- Please see the file LICENSE.txt in the source's root directory.
--
-- This file written by Ryan C. Gordon.
--
DirkSimple.gametitle = "Cliff Hanger"
-- CVARS
local starting_lives = 6 -- number of lives player gets at startup. Six was the maximum that arcade cabinet dip switches allowed.
local infinite_lives = false -- set to true to not lose a life on failure.
local show_lives_and_score = true -- if true, overlay current lives and score at top of laserdisc video during scenes. This is usually enabled in arcade cabinets' dip switches.
local show_hints = true -- if true, overlay hints about the expected move at the bottom of the laserdisc video during scenes. This is often enabled in arcade cabinets' dip switches.
local show_full_hints = false -- if true, instead of "ACTION" or "STICK" it tells you the exact necessary move. The real version doesn't do this!
local show_hanging_scene = false -- They show Cliff getting hanged (get it, CLIFF HANGER?!?) after each failure and it takes forever and it is kinda disturbing. There's a dip switch to disable it. Set it to false to disable it here, too.
local show_should_have_hint = 3 -- show "SHOULD HAVE USED FEET" etc after X failures in a row (zero to disable, 1 shows on every failure).
local allow_buy_in = true -- allow player to continue on game over?
local god_mode = false -- if true, game plays correct moves automatically, so you never fail.
DirkSimple.cvars = {
{ name="starting_lives", desc="Number of lives player starts with", values="6|5|4|3|2|1", setter=function(name, value) starting_lives = DirkSimple.to_int(value) end },
{ name="infinite_lives", desc="Don't lose a life when failing", values="false|true", setter=function(name, value) infinite_lives = DirkSimple.to_bool(value) end },
{ name="show_lives_and_score", desc="Show score and lives remaining at top of screen", values="true|false", setter=function(name, value) show_lives_and_score = DirkSimple.to_bool(value) end },
{ name="show_hints", desc="Show hints at bottom of screen about expected moves", values="true|false", setter=function(name, value) show_hints = DirkSimple.to_bool(value) end },
{ name="show_full_hints", desc="Show exact required moves on the HUD", values="false|true", setter=function(name, value) show_full_hints = DirkSimple.to_bool(value) end },
{ name="show_hanging_scene", desc="Show Cliff being hanged after each failure", values="false|true", setter=function(name, value) show_hanging_scene = DirkSimple.to_bool(value) end },
{ name="show_should_have_hint", desc="Show the correct choice after X failures in a row", values="3|2|always|never", setter=function(name, value) if value == "always" then value = 1 elseif value == "never" then value = 0 else value = DirkSimple.to_int(value) end show_should_have_hint = value end },
{ name="allow_buy_in", desc="Allow player to continue on game over", values="true|false", setter=function(name, value) allow_buy_in = DirkSimple.to_bool(value) end },
{ name="god_mode", desc="Game plays itself perfectly, never failing", values="false|true", setter=function(name, value) god_mode = DirkSimple.to_bool(value) end }
}
-- SOME INITIAL SETUP STUFF
local scenes = nil -- gets set up later in the file.
local test_scene = nil -- set to index of scene to test. nil otherwise!
local test_sequence_num = nil -- set to index of sequence to test. nil otherwise!
--test_scene = 5 ; test_sequence = 1
-- GAME STATE
local scene_manager = {}
local alltime_highscores = nil -- set up later in the file
local today_highscores = nil -- set up later in the file
-- FUNCTIONS
-- Cliff Hanger counts frames at 29.97fps, not 23.976fps like Dragon's Lair.
local function laserdisc_frame_to_ms(frame)
return (frame / 29.97) * 1000.0
end
local function seek_laserdisc_to(frame)
-- will suspend ticking until the seek completes and reset sequence tick count
scene_manager.last_seek = laserdisc_frame_to_ms(frame - 6)
scene_manager.unserialize_offset = 0
DirkSimple.start_clip(scene_manager.last_seek)
end
local function halt_laserdisc()
-- will suspend ticking until the seek completes and reset sequence tick count
scene_manager.last_seek = -1
scene_manager.unserialize_offset = 0
DirkSimple.halt_video()
end
local function setup_scene_manager()
scene_manager.initialized = true
scene_manager.accepted_input = nil
scene_manager.attract_mode_state = 0
scene_manager.death_mode_state = 0
scene_manager.scene_start_state = 0
scene_manager.scene_start_tick_offset = 0
scene_manager.game_over_state = 0
scene_manager.player_initials = { ' ', ' ', ' ' }
scene_manager.player_initials_entered = 0
scene_manager.player_initials_selected_glyph = 0
scene_manager.lives_left = starting_lives
scene_manager.current_score = 0
scene_manager.last_failed_scene = 0
scene_manager.last_failed_sequence = 0
scene_manager.failures_in_a_row = 0
scene_manager.last_seek = 0
scene_manager.current_scene = nil
scene_manager.current_scene_num = 0
scene_manager.current_sequence = nil
scene_manager.current_sequence_num = 0
scene_manager.current_scene_ticks = 0
scene_manager.laserdisc_frame = 0
scene_manager.unserialize_offset = 0
end
-- Cliff Hanger only draws "characters" to a grid on the screen. It could not
-- draw outside the grid (one character filled a cell, you couldn't draw
-- in the middle to straddle two cells, which means you could not position
-- anything by pixel position if it didn't align to the grid. Think of it
-- as a fancy text terminal.
-- Coordinates and sizes are in character blocks (8x8 pixels). The logical
-- screen here is 40x24 blocks, so we'll scale as appropriate to match the
-- laserdisc video resolution.
local function draw_sprite_chars(name, sx, sy, sw, sh, dx, dy, modr, modg, modb)
-- scale dest coords for the screen resolution.
-- some percentage of the laserdisc video height is letterboxing, don't count that part.
local blockh = (DirkSimple.video_height - (DirkSimple.video_height * 0.216666)) / 24.0
local blockw = DirkSimple.video_width / 40.0
dx = DirkSimple.truncate(DirkSimple.truncate(dx) * blockw)
dy = DirkSimple.truncate((DirkSimple.truncate(dy) * blockh) + (DirkSimple.video_height * 0.10))
local dw = DirkSimple.truncate((sw * blockw) + 0.5)
local dh = DirkSimple.truncate((sh * blockh) + 0.5)
-- convert from source blocks to pixels
sx = DirkSimple.truncate(sx) * 8
sy = DirkSimple.truncate(sy) * 8
sw = DirkSimple.truncate(sw) * 8
sh = DirkSimple.truncate(sh) * 8
--DirkSimple.log("draw_sprite(" .. sx .. ", " .. sy .. ", " .. sw .. ", " .. sh .. ", " .. dx .. ", " .. dy .. ", " .. dw .. ", " .. dh .. ")")
DirkSimple.draw_sprite(name, sx, sy, sw, sh, dx, dy, dw, dh, modr, modg, modb)
end
local chartable = nil
local function draw_text(str, x, y, modr, modg, modb)
if chartable == nil then
local x = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[~]^~`abcdefghijklmnopqrstuvwxyz{|}"
local bytelist = { x:byte(1, #x) }
chartable = {}
for i,ch in ipairs(bytelist) do
chartable[ch] = i
end
end
local bytes = { str:byte(1, #str) }
for i,ch in ipairs(bytes) do
local idx = chartable[ch]
if idx == nil then
idx = 1
end
draw_sprite_chars("cliffglyphs", idx - 1, 0, 1, 1, x, y, modr, modg, modb)
x = x + 1
end
end
local function draw_rectangle(x, y, w, h, r, g, b)
draw_sprite_chars("cliffglyphs", 99, 0, 1, 1, x, y, r, g, b)
draw_sprite_chars("cliffglyphs", 98, 0, 1, 1, x+w+1, y, r, g, b)
draw_sprite_chars("cliffglyphs", 101, 0, 1, 1, x, y+h+1, r, g, b)
draw_sprite_chars("cliffglyphs", 100, 0, 1, 1, x+w+1, y+h+1, r, g, b)
for i = 1,w,1 do
draw_sprite_chars("cliffglyphs", 96, 0, 1, 1, x+i, y, r, g, b)
draw_sprite_chars("cliffglyphs", 96, 0, 1, 1, x+i, y+h+1, r, g, b)
end
for i = 1,h,1 do
draw_sprite_chars("cliffglyphs", 97, 0, 1, 1, x, y+i, r, g, b)
draw_sprite_chars("cliffglyphs", 97, 0, 1, 1, x+w+1, y+i, r, g, b)
end
end
local function draw_standard_rectangle(idx, r, g, b)
draw_rectangle(idx, idx, 38 - (idx * 2), 21 - (idx * 2), r, g, b)
end
-- these color values come from Daphne's TMS9128NL code.
local colortable = { -- red, blue, green triplets.
black = { 0, 0, 0 },
medium_green = { 26, 219, 36 },
light_green = { 109, 255, 109 },
dark_blue = { 36, 36, 255 },
light_blue = { 73, 109, 255 },
dark_red = { 182, 36, 36 },
purple = { 125, 0, 128 }, -- daphne uses this for Cliff Hanger's move prompts, looks more accurate to the arcade than dark_red.
light_cyan = { 73, 219, 255 },
medium_red = { 255, 36, 36 },
light_red = { 255, 109, 109 },
dark_yellow = { 219, 219, 36 },
light_yellow = { 219, 219, 146 },
dark_green = { 36, 146, 36 },
magenta = { 219, 73, 182 },
grey = { 182, 182, 182 },
white = { 255, 255, 255 }
}
local function mapcolor(name)
if colortable[name] == nil then
name = "black"
end
local triplet = colortable[name]
return triplet[1], triplet[2], triplet[3]
end
local start_attract_mode = nil -- predeclare
local attract_mode_flash_colors = { -- just foreground
"white", "light_yellow", "medium_red", "dark_yellow", "dark_blue", "dark_green", "light_green"
}
local function start_scene(scenenum, sequencenum)
if test_scene ~= nil then
scenenum = test_scene
sequencenum = test_sequence
if sequencenum == nil then
sequencenum = 0
end
end
local start_of_scene = (sequencenum == 0)
if start_of_scene then
sequencenum = 1
end
local seqname = nil
if (scenes[scenenum] ~= nil) and (scenes[scenenum].moves ~= nil) and (scenes[scenenum].moves[sequencenum] ~= nil) then
seqname = scenes[scenenum].moves[sequencenum].name
end
if seqname ~= nil then
seqname = " (" .. seqname .. ")"
else
seqname = ''
end
DirkSimple.log("Starting scene " .. scenenum .. " (" .. scenes[scenenum].scene_name .. "), sequence " .. sequencenum .. seqname)
scene_manager.current_scene_num = scenenum
scene_manager.current_scene = scenes[scenenum]
scene_manager.current_sequence_num = sequencenum
scene_manager.current_sequence = scene_manager.current_scene.moves[sequencenum]
scene_manager.accepted_input = nil
scene_manager.scene_start_state = 1
if not start_of_scene then
scene_manager.scene_start_state = 2
end
end
local function start_game()
DirkSimple.log("Start game!")
setup_scene_manager()
halt_laserdisc()
start_scene(1, 0)
end
local function draw_high_scores(ticks)
DirkSimple.clear_screen(mapcolor("magenta"))
draw_rectangle(0, 0, 19, 22, mapcolor("white"))
draw_rectangle(20, 0, 18, 22, mapcolor("white"))
draw_text("The Highest Scores", 2, 1, mapcolor("white"))
-- this only shows the default scores for now. We could manage actual scores, though!
for i,v in ipairs(alltime_highscores) do
if ticks >= (i * 100) then
local score = "" .. v[2]
local y = 2 + (i * 2)
draw_text(v[1], 2, y, mapcolor("white"))
draw_text(score, 19 - #score, y, mapcolor("white"))
end
end
if ticks >= 1100 then
draw_text("High Scores Today", 22, 1, mapcolor("white"))
for i,v in ipairs(today_highscores) do
if ticks >= (1100 + (i * 100)) then
local score = "" .. v[2]
local y = 2 + (i * 2)
draw_text(v[1], 22, y, mapcolor("white"))
draw_text(score, 39 - #score, y, mapcolor("white"))
end
end
end
end
local function tick_attract_mode(inputs)
-- !!! FIXME: if someone wants to make this frame-perfect, feel free to adjust all the magic tick values in this function.
local ticks = scene_manager.current_scene_ticks
if scene_manager.attract_mode_state == 1 then -- state == 1? Showing initial intro before laserdisc starts playing.
if ticks <= 2000 then -- Sliding in initial logo.
DirkSimple.clear_screen(mapcolor("black"))
draw_sprite_chars("logo", 0, 0, 20, 10, 31 - (31 * (ticks / 2000)), 0, mapcolor("light_blue"))
elseif ticks <= 3000 then -- waiting to flash
DirkSimple.clear_screen(mapcolor("black"))
draw_sprite_chars("logo", 0, 0, 20, 10, 0, 0, mapcolor("light_blue"))
elseif ticks <= 3128 then -- flash
DirkSimple.clear_screen(mapcolor("light_blue"))
draw_sprite_chars("logo", 0, 0, 20, 10, 0, 0, mapcolor("dark_red"))
elseif ticks <= 3256 then -- flash2
DirkSimple.clear_screen(mapcolor("light_blue"))
draw_sprite_chars("logo", 0, 0, 20, 10, 0, 0, mapcolor("white"))
else -- into the main graphics screen, before laserdisc kicks in.
local flashticks = ticks - 8384
local fg = "black"
local bg = "light_blue"
if flashticks > 0 then
local flashidx = DirkSimple.truncate(flashticks / 128.0)
if flashidx > #attract_mode_flash_colors then
flashidx = #attract_mode_flash_colors -- moving on to next mode, but do this one more time for this last frame.
scene_manager.attract_mode_state = scene_manager.attract_mode_state + 1
seek_laserdisc_to(6) -- start the laserdisc attract mode video playing.
end
fg = attract_mode_flash_colors[flashidx]
if flashidx == #attract_mode_flash_colors then -- last one chooses a black background.
bg = "black"
end
end
DirkSimple.clear_screen(mapcolor(bg))
draw_sprite_chars("logo", 0, 0, 20, 10, 0, 0, mapcolor(fg))
if ticks > 4256 then
draw_text("A Laser Disc Video Game", 8, 16, mapcolor(fg))
end
if ticks > 5256 then -- show byline
draw_text("BY STERN ELECTRONICS, INC.", 7, 18, mapcolor(fg))
end
if ticks > 6256 then -- show number of credits
draw_text("FREE PLAY", 15, 23, mapcolor(fg))
end
end
elseif scene_manager.attract_mode_state == 2 then -- state == 2? Started actual laserdisc attract mode video playing.
if scene_manager.laserdisc_frame >= 1546 then
DirkSimple.clear_screen(mapcolor("dark_blue"))
halt_laserdisc()
scene_manager.attract_mode_state = scene_manager.attract_mode_state + 1 -- move on to original game's credits page.
return
end
elseif scene_manager.attract_mode_state == 3 then -- state == 3? Show developer credits.
-- ticks were reset by the halt_laserdisc call that ended state 2.
DirkSimple.clear_screen(mapcolor("dark_blue"))
draw_text("Designed & Programmed By", 8, 7, mapcolor("white"))
if ticks >= 1000 then
draw_text("PAUL M. RUBENSTEIN", 11, 10, mapcolor("white"))
end
if ticks >= 1100 then
draw_text("BOB KOWALSKI", 13, 12, mapcolor("white"))
end
if ticks >= 1200 then
draw_text("JON MICHAEL HOGAN", 11, 14, mapcolor("white"))
end
if ticks >= 1300 then
draw_text("EDWARD J. MARCH JR.", 10, 16, mapcolor("white"))
end
if ticks >= 1400 then
local total = DirkSimple.truncate((ticks - 1400) / 128)
if total > 5 then
total = 5
end
for i = 1,total,1 do
draw_standard_rectangle(i-1, mapcolor("white"))
end
end
if ticks >= 6300 then -- move on to next state.
halt_laserdisc() -- just reset ticks for next state
scene_manager.attract_mode_state = scene_manager.attract_mode_state + 1 -- move on to DirkSimple credits page.
end
elseif scene_manager.attract_mode_state == 4 then -- state == 4? Added a DirkSimple credits page.
DirkSimple.clear_screen(mapcolor("medium_red"))
draw_text("Rebuilt for DirkSimple By", 7, 7, mapcolor("white"))
if ticks >= 1000 then
draw_text("RYAN C. GORDON", 13, 12, mapcolor("white"))
end
if ticks >= 1500 then
draw_text("https://icculus.org/dirksimple", 5, 17, mapcolor("light_yellow"))
end
if ticks >= 1600 then
local total = DirkSimple.truncate((ticks - 1600) / 128)
if total > 3 then
total = 3
end
for i = 1,total,1 do
draw_standard_rectangle(i-1, mapcolor("white"))
end
end
if ticks >= 4000 then -- move on to next state.
halt_laserdisc() -- just reset ticks for next state
scene_manager.attract_mode_state = scene_manager.attract_mode_state + 1 -- move on to high scores.
end
elseif scene_manager.attract_mode_state == 5 then -- state == 5? High scores list.
draw_high_scores(ticks)
if ticks >= 5000 then -- move on to next state.
halt_laserdisc() -- just reset ticks for next state
scene_manager.attract_mode_state = scene_manager.attract_mode_state + 1 -- move on to instructions
end
elseif scene_manager.attract_mode_state == 6 then -- state == 6? Instructions.
DirkSimple.clear_screen(mapcolor("dark_blue"))
if ticks >= 128 then
draw_text("Move the joystick in the", 8, 3, mapcolor("white"))
end
if ticks >= 256 then
draw_text("direction Cliff or his car", 7, 4, mapcolor("white"))
end
if ticks >= 386 then
draw_text("moves on the screen", 10, 5, mapcolor("white"))
end
if ticks >= 770 then
draw_text("Stick right if object moves", 6, 9, mapcolor("white"))
end
if ticks >= 898 then
draw_text("toward right edge of screen", 6, 10, mapcolor("white"))
end
if ticks >= 1226 then
draw_text("Stick left if object moves", 7, 12, mapcolor("white"))
end
if ticks >= 1354 then
draw_text("toward left edge of screen", 7, 13, mapcolor("white"))
end
if ticks >= 1682 then
draw_text("Stick up if object moves", 8, 15, mapcolor("white"))
end
if ticks >= 1810 then
draw_text("toward upper edge of screen", 6, 16, mapcolor("white"))
end
if ticks >= 2138 then
draw_text("Stick down if object moves", 7, 18, mapcolor("white"))
end
if ticks >= 2266 then
draw_text("toward bottom edge of screen", 6, 19, mapcolor("white"))
end
if ticks >= 2366 then
draw_standard_rectangle(0, mapcolor("white"))
end
if ticks >= 2466 then
draw_standard_rectangle(1, mapcolor("white"))
end
if ticks >= 12522 then
scene_manager.attract_mode_state = 1 -- restart attract mode.
halt_laserdisc() -- just reset ticks for next state
end
end
if inputs ~= nil and inputs.pressed["start"] then
start_game()
end
end
start_attract_mode = function()
DirkSimple.log("Starting attract mode")
setup_scene_manager()
scene_manager.attract_mode_state = 1
halt_laserdisc()
tick_attract_mode(nil) -- start right now.
end
local function game_over(won)
DirkSimple.log("Game over!")
scene_manager.accepted_input = nil
halt_laserdisc() -- blank laserdisc frame, reset ticks.
if won then
scene_manager.game_over_state = 1
elseif allow_buy_in then
scene_manager.game_over_state = 2
else
scene_manager.game_over_state = 3
end
end
local failure_flash_colors = { -- { foreground, background }
{ "white", "dark_blue" },
{ "white", "dark_red" },
{ "dark_blue", "white" },
{ "dark_red", "white" },
{ "white", "dark_blue" },
{ "white", "dark_red" },
{ "white", "dark_blue" },
{ "white", "dark_red" }
}
local function draw_failure_screen(ticks)
local actions = scene_manager.current_sequence.correct_moves
local msg = "Y O U ' V E B L O W N I T !"
if (#actions > 0) and (show_should_have_hint > 0) and (scene_manager.failures_in_a_row >= show_should_have_hint) then
local input = actions[1]
if input == "up" then
msg = " SHOULD HAVE GONE UP !"
elseif input == "down" then
msg = " SHOULD HAVE GONE DOWN !"
elseif input == "left" then
msg = " SHOULD HAVE GONE LEFT !"
elseif input == "right" then
msg = " SHOULD HAVE GONE RIGHT !"
elseif input == "hands" then
msg = " SHOULD HAVE USED YOUR HAND !"
elseif input == "feet" then
msg = " SHOULD HAVE USED YOUR FEET !"
end
end
local flashidx = DirkSimple.truncate(ticks / 96) + 1
if flashidx > #failure_flash_colors then
flashidx = #failure_flash_colors
end
local flashcolor = failure_flash_colors[flashidx]
local fg = flashcolor[1]
local bg = flashcolor[2]
DirkSimple.clear_screen(mapcolor(bg))
for i = 1,40,1 do
draw_sprite_chars("cliffglyphs", 96, 0, 1, 1, i-1, 6, mapcolor(fg))
draw_sprite_chars("cliffglyphs", 96, 0, 1, 1, i-1, 16, mapcolor(fg))
end
draw_text("PLAYER # 1", 15, 9, mapcolor(fg))
draw_text(msg, 4, 13, mapcolor(fg))
end
local function tick_death_scene()
local ticks = scene_manager.current_scene_ticks
if scene_manager.death_mode_state == 0 then -- not showing a death sequence.
return
elseif scene_manager.death_mode_state == 1 then -- the "YOU'VE BLOWN IT" screen
draw_failure_screen(ticks)
if ticks >= 2000 then
scene_manager.death_mode_state = scene_manager.death_mode_state + 1 -- show laserdisc death video
seek_laserdisc_to(scene_manager.current_sequence.death_start_frame)
end
elseif scene_manager.death_mode_state == 2 then -- showing the laserdisc death video clip.
local end_frame = scene_manager.current_sequence.death_end_frame
if not show_hanging_scene then
end_frame = end_frame - 260
end
if scene_manager.laserdisc_frame >= end_frame then
scene_manager.death_mode_state = 0 -- done.
if scene_manager.lives_left == 0 then
game_over(false)
else
-- In Cliff Hanger, you have to complete each scene in order, before you can do a different one.
-- don't halt the laserdisc here, the audio from the death scene plays over the start screen.
start_scene(scene_manager.current_scene_num, scene_manager.current_sequence.restart_move) -- move back to where the sequence prescribes.
scene_manager.scene_start_tick_offset = ticks
end
end
end
end
local function kill_player()
if (not infinite_lives) and (test_scene == nil) then
scene_manager.lives_left = scene_manager.lives_left - 1
end
DirkSimple.log("Killing player (lives now left=" .. scene_manager.lives_left .. ")")
if (scene_manager.last_failed_scene == scene_manager.current_scene_num) and (scene_manager.last_failed_sequence == scene_manager.current_sequence_num) then
scene_manager.failures_in_a_row = scene_manager.failures_in_a_row + 1
else
scene_manager.failures_in_a_row = 1
scene_manager.last_failed_scene = scene_manager.current_scene_num
scene_manager.last_failed_sequence = scene_manager.current_sequence_num
end
scene_manager.death_mode_state = 1
halt_laserdisc() -- set the scene tick count back to zero; ticking the death scene will start the disc once the initial message is done.
draw_failure_screen(0)
end
local function move_was_made(inputs, actions)
if actions ~= nil then
for i,v in ipairs(actions) do
local input = v
if input == "hands" then
input = "action"
elseif input == "feet" then
input = "action2"
end
if inputs.pressed[input] then -- we got one!
DirkSimple.log("accepted action '" .. v .. "' at " .. tostring(scene_manager.current_scene_ticks / 1000.0))
return v
end
end
end
return nil
end
local function draw_hud_lives_left()
local lives = scene_manager.lives_left
if lives > 6 then
lives = 6
end
draw_sprite_chars("cliffglyphs", 95, 0, 1, 1, 21, 0, mapcolor("black"))
draw_sprite_chars("cliffglyphs", 95, 0, 1, 1, 20, 0, mapcolor("black"))
draw_sprite_chars("cliffglyphs", 94, 0, 1, 1, 20, 0, mapcolor("purple"))
for i = 1,lives,1 do
draw_sprite_chars("cliffglyphs", 95, 0, 1, 1, 20-i, 0, mapcolor("black"))
draw_sprite_chars("cliffglyphs", 112, 0, 1, 1, 20-i, 0, mapcolor("purple"))
end
draw_sprite_chars("cliffglyphs", 95, 0, 1, 1, 20-(lives+1), 0, mapcolor("black"))
draw_sprite_chars("cliffglyphs", 60, 0, 1, 1, 20-(lives+1), 0, mapcolor("purple"))
end
local function draw_hud_current_score()
local score = "" .. scene_manager.current_score
local scorex = 10 - #score
for i = 1,#score+3,1 do -- draw black background for text
draw_sprite_chars("cliffglyphs", 95, 0, 1, 1, (scorex-2) + i, 0, mapcolor("black"))
end
draw_text(score, scorex, y, mapcolor("purple"))
draw_sprite_chars("cliffglyphs", 60, 0, 1, 1, scorex - 1, 0, mapcolor("purple"))
draw_sprite_chars("cliffglyphs", 94, 0, 1, 1, scorex + #score, 0, mapcolor("purple"))
end
local function draw_hud_action_hint(actions)
if (actions == nil) or (#actions == 0) then
return
end
local hint = nil
local hintx = nil
if show_full_hints then
hint = ""
local comma = ""
for i,v in ipairs(actions) do
hint = hint .. comma .. v
comma = ", "
end
hintx = (40 - (#hint + 5)) / 2
else
for i,v in ipairs(actions) do
local input = v
if input == "up" or input == "down" or input == "left" or input == "right" then
hint = "STICK"
hintx = 15
break
elseif input == "hands" or input == "feet" then
hint = "ACTION"
hintx = 14
break
end
end
end
if hint ~= nil then
for i = 1,(#hint+5),1 do -- draw black background for text
draw_sprite_chars("cliffglyphs", 95, 0, 1, 1, (hintx - 1) + i, 23, mapcolor("black"))
end
draw_sprite_chars("cliffglyphs", 60, 0, 1, 1, hintx, 23, mapcolor("purple"))
draw_text(hint, hintx + 2, 23, mapcolor("purple"))
draw_sprite_chars("cliffglyphs", 94, 0, 1, 1, hintx + #hint + 4, 23, mapcolor("purple"))
end
end
local function tick_game(inputs)
-- if sequence is nil, we've run through all the moves for the scene and are just waiting on the scene to finish playing.
local sequence = scene_manager.current_sequence
local laserdisc_frame = scene_manager.laserdisc_frame
local ticks = scene_manager.current_scene_ticks
--DirkSimple.log("TICK GAME: ticks=" .. ticks .. ", laserdisc_frame=" .. laserdisc_frame)
if show_lives_and_score then
draw_hud_lives_left()
draw_hud_current_score()
end
-- see if it's time to shift to the next sequence.
if (sequence ~= nil) and (laserdisc_frame >= sequence.end_frame) then
if (scene_manager.accepted_input == nil) and (sequence.correct_moves ~= nil) and (#sequence.correct_moves ~= 0) and (not god_mode) then
-- uhoh, player did nothing, they blew it.
kill_player()
return
end
-- ok, you survived this sequence, moving on to the next!
scene_manager.accepted_input = nil
scene_manager.current_sequence_num = scene_manager.current_sequence_num + 1
scene_manager.current_sequence = scene_manager.current_scene.moves[scene_manager.current_sequence_num]
sequence = scene_manager.current_sequence
if sequence == nil then -- did we run out of sequences?
DirkSimple.log("Finished all sequences in this scene!")
else
local seqname = sequence.name
if seqname ~= nil then
seqname = " (" .. seqname .. ")"
else
seqname = ''
end
DirkSimple.log("Moving on to sequence " .. scene_manager.current_sequence_num .. seqname)
end
end
-- are we in the window for moves in this sequence?
if (sequence ~= nil) and (scene_manager.accepted_input == nil) and (laserdisc_frame >= sequence.start_frame) then
if move_was_made(inputs, sequence.incorrect_moves) and (not god_mode) then
kill_player()
return
else
if show_hints then
draw_hud_action_hint(sequence.correct_moves)
end
if #sequence.correct_moves > 0 then
if god_mode then
scene_manager.accepted_input = sequence.correct_moves[1]
else
scene_manager.accepted_input = move_was_made(inputs, sequence.correct_moves)
end
if scene_manager.accepted_input ~= nil then -- correct move was just made!
scene_manager.current_score = scene_manager.current_score + 5000
end
end
end
end
-- see if the entire scene has ended.
if laserdisc_frame >= scene_manager.current_scene.end_frame then
scene_manager.current_score = scene_manager.current_score + 10000
if scene_manager.current_scene_num >= #scenes then -- out of scenes? You won the game!
game_over(true)
else
halt_laserdisc()
start_scene(scene_manager.current_scene_num + 1, 0)
end
end
end
local function draw_start_play_screen(ticks)
DirkSimple.clear_screen(mapcolor("dark_blue"))
draw_text("PLAYER # 1", 15, 9, mapcolor("white"))
local lives_left = scene_manager.lives_left
if lives_left == starting_lives then
draw_text("G O O D L U C K ! ! !", 8, 13, mapcolor("white"))
else
local scorestr = "" .. scene_manager.current_score
draw_text("YOUR SCORE IS", 7, 12, mapcolor("white"))
draw_text(scorestr, 21 + (8 - #scorestr), 12, mapcolor("white"))
local lives_left_msg = "You have 1 life left."
if lives_left > 1 then
lives_left_msg = "You have " .. lives_left .. " lives left."
end
draw_text(lives_left_msg, 7, 14, mapcolor("white"))
end
local total = DirkSimple.truncate(ticks / 64) + 1
if total > 5 then
total = 5
end
for i = 1,total,1 do
draw_standard_rectangle(i-1, mapcolor("white"))
end
end
local function tick_scene_start()
if scene_manager.scene_start_state > 0 then
local ticks = scene_manager.current_scene_ticks - scene_manager.scene_start_tick_offset
draw_start_play_screen(ticks)
if ticks > 2000 then
halt_laserdisc() -- this just makes the engine replace the current frame of video with black
if scene_manager.scene_start_state == 1 then
seek_laserdisc_to(scene_manager.current_scene.start_frame)
else
seek_laserdisc_to(scene_manager.current_sequence.start_frame)
end
scene_manager.scene_start_state = 0
scene_manager.scene_start_tick_offset = 0
end
end
end
local function draw_buy_in_screen(ticks, timeleft)
DirkSimple.clear_screen(mapcolor("magenta"))
local total = DirkSimple.truncate(ticks / 64) + 1
if total > 5 then
total = 5
end
for i = 1,total,1 do
draw_standard_rectangle(i-1, mapcolor("white"))
end
if ticks > 320 then
draw_text("PLAYER # 1", 15, 7, mapcolor("white"))
draw_text("If you wish to continue", 8, 9, mapcolor("white"))
draw_text("playing this level", 11, 10, mapcolor("white"))
draw_text("Press Player 1 button", 9, 14, mapcolor("white"))
draw_text("Time left to buy-in : " .. timeleft, 8, 17, mapcolor("white"))
end
end
local function draw_congrats_screen(ticks)
if ticks < (96 * 64) then
local fg = "light_blue"
local bg = "light_red"
DirkSimple.clear_screen(mapcolor(bg))
local segment = DirkSimple.truncate(ticks / 96) % 3
if segment == 0 then
draw_text("* * * * * * * * *", 7, 9, mapcolor(fg))
draw_text(" ", 7, 10, mapcolor(fg))
draw_text("* CONGRATULATIONS ", 7, 11, mapcolor(fg))
draw_text(" *", 7, 12, mapcolor(fg))
draw_text(" YOU HAVE COMPLETED ", 7, 13, mapcolor(fg))
draw_text("* THIS CHALLENGE ", 7, 14, mapcolor(fg))
draw_text(" *", 7, 15, mapcolor(fg))
draw_text(" * * * * * * * ", 7, 16, mapcolor(fg))
elseif segment == 1 then
draw_text(" * * * * * * * * ", 7, 9, mapcolor(fg))
draw_text("* *", 7, 10, mapcolor(fg))
draw_text(" CONGRATULATIONS ", 7, 11, mapcolor(fg))
draw_text(" ", 7, 12, mapcolor(fg))
draw_text("* YOU HAVE COMPLETED *", 7, 13, mapcolor(fg))
draw_text(" THIS CHALLENGE ", 7, 14, mapcolor(fg))
draw_text(" ", 7, 15, mapcolor(fg))
draw_text("* * * * * * * * *", 7, 16, mapcolor(fg))
elseif segment == 2 then
draw_text(" * * * * * * * * ", 7, 9, mapcolor(fg))
draw_text(" ", 7, 10, mapcolor(fg))
draw_text(" CONGRATULATIONS *", 7, 11, mapcolor(fg))
draw_text("* ", 7, 12, mapcolor(fg))
draw_text(" YOU HAVE COMPLETED ", 7, 13, mapcolor(fg))
draw_text(" THIS CHALLENGE *", 7, 14, mapcolor(fg))
draw_text("* ", 7, 15, mapcolor(fg))
draw_text("* * * * * * * * ", 7, 16, mapcolor(fg))
end
else
local fg = "white"
local bg = "dark_blue"
if ticks < ((96 * 64) + (32 * 30)) then
if (DirkSimple.truncate(ticks / 32) % 2) == 1 then
bg = "dark_red"
end
end
draw_text("*************************", 7, 9, mapcolor(fg))
draw_text("* *", 7, 10, mapcolor(fg))
draw_text("* CONGRATULATIONS *", 7, 11, mapcolor(fg))
draw_text("* *", 7, 12, mapcolor(fg))
draw_text("* YOU HAVE COMPLETED *", 7, 13, mapcolor(fg))
draw_text("* THIS CHALLENGE *", 7, 14, mapcolor(fg))
draw_text("* *", 7, 15, mapcolor(fg))
draw_text("*************************", 7, 16, mapcolor(fg))
end
end
local game_over_flash_colors = { -- { foreground, background }
{ "black", "black" },
{ "medium_green", "black" },
{ "light_green", "black" },
{ "dark_blue", "black" },
{ "light_blue", "black" },
{ "dark_red", "black" },
{ "light_cyan", "black" },
{ "medium_red", "black" },
{ "light_red", "black" },
{ "dark_yellow", "black" },
{ "light_yellow", "black" },
{ "dark_green", "black" },
{ "magenta", "black" },
{ "grey", "dark_blue" },
{ "white", "dark_red" },
{ "white", "dark_blue" },
{ "white", "black" },
{ "white", "black" },
}
local function draw_game_over_screen(ticks)
local flashidx = DirkSimple.truncate(ticks / 160) + 1
if flashidx > #game_over_flash_colors then
flashidx = #game_over_flash_colors
end
local flashcolor = game_over_flash_colors[flashidx]
local fg = flashcolor[1]
local bg = flashcolor[2]
DirkSimple.clear_screen(mapcolor(bg))
draw_text("******************", 12, 9, mapcolor(fg))
draw_text("* *", 12, 10, mapcolor(fg))
draw_text("* YOUR GAME *", 12, 11, mapcolor(fg))
draw_text("* *", 12, 12, mapcolor(fg))
draw_text("* IS NOW OVER *", 12, 13, mapcolor(fg))
draw_text("* *", 12, 14, mapcolor(fg))
draw_text("******************", 12, 15, mapcolor(fg))
end
local initial_entry_string = "abcdefghijklmnopqrstuvwxyz *?"; -- everything but the backspace at the end
local function draw_highscore_entry_screen()
local scorestr = "" .. scene_manager.current_score
local fg = "dark_red"
local selected = scene_manager.player_initials_selected_glyph
local backspace = 63 -- glyph index
local caret = 62 -- glyph index
DirkSimple.clear_screen(mapcolor("black"))
draw_text("CONGRATULATIONS PLAYER 1", 8, 1, mapcolor(fg))
draw_text("YOUR SCORE", 9, 3, mapcolor(fg))
draw_text(scorestr, 20 + (8 - #scorestr), 3, mapcolor(fg))
draw_text("IS IN THE TOP TEN SCORES", 8, 5, mapcolor(fg))
draw_text("PLEASE ENTER YOUR INITIALS", 7, 8, mapcolor(fg))
draw_text(initial_entry_string, 5, 11, mapcolor(fg))
draw_sprite_chars("cliffglyphs", backspace, 0, 1, 1, 34, 11, mapcolor(fg))
draw_sprite_chars("cliffglyphs", caret, 0, 1, 1, 5 + selected, 12, mapcolor(fg))
draw_rectangle(18, 13, 3, 1, mapcolor(fg))
for i = 1,scene_manager.player_initials_entered,1 do
draw_text(scene_manager.player_initials[i], 18+i, 14, mapcolor(fg))
end
if scene_manager.player_initials_entered < 3 then
local x = 18+scene_manager.player_initials_entered+1
if selected == 29 then -- backspace?
draw_sprite_chars("cliffglyphs", backspace, 0, 1, 1, x, 14, mapcolor(fg))
else
draw_text(initial_entry_string:sub(selected + 1, selected + 1), x, 14, mapcolor(fg))
end
end
draw_text("YOU CAN USE", 14, 17, mapcolor(fg))
draw_text("THE JOYSTICK TO SELECT LETTERS", 5, 19, mapcolor(fg))
draw_text("BUT YOU MUST USE", 12, 21, mapcolor(fg))
draw_text("YOUR HANDS TO ENTER THEM.", 7, 23, mapcolor(fg))
end
local function insert_highscore(list, name, score)
for i,v in ipairs(list) do
if score > v[2] then
table.insert(list, i, { name, score })
table.remove(list)
break
end
end
end
local function tick_game_over(inputs)
local ticks = scene_manager.current_scene_ticks
if scene_manager.game_over_state == 1 then -- game_over_state == 1? You won!
draw_congrats_screen(ticks)
if ticks >= (((96 * 64) + (32 * 30)) + 2000) then
halt_laserdisc() -- this just makes the tick count go back to zero.
scene_manager.game_over_state = scene_manager.game_over_state + 2 -- skip over buy-in, there's no game left to continue.
end
elseif scene_manager.game_over_state == 2 then -- game_over_state == 2? "Buy in" mode, where they let you continue (for more money in the arcade, of course).
local timeleft = 9 - DirkSimple.truncate((ticks - 320) / 1000)
local showtimeleft = timeleft
if showtimeleft <= 0 then
showtimeleft = 1 -- bump so the last frame doesn't render to zero.
end
draw_buy_in_screen(ticks, showtimeleft)
if inputs ~= nil and inputs.pressed["start"] then -- user decided to continue current game
scene_manager.lives_left = starting_lives
scene_manager.game_over_state = 0
start_scene(scene_manager.current_scene_num, scene_manager.current_sequence.restart_move) -- move back to where the sequence prescribes.
scene_manager.scene_start_tick_offset = 0
elseif timeleft == 0 then
halt_laserdisc() -- this just makes the tick count go back to zero.
scene_manager.game_over_state = scene_manager.game_over_state + 1 -- move on to actual game over screen.
end
elseif scene_manager.game_over_state == 3 then -- game_over_state == 3? Decide if this was a high score.
scene_manager.game_over_state = scene_manager.game_over_state + 1 -- Maybe move on to entering player initials.
if scene_manager.current_score < today_highscores[#today_highscores][2] then -- today's lowest highscore must be lower than any alltime high score, so we don't check that.
scene_manager.game_over_state = scene_manager.game_over_state + 1 -- skip initial entry, go right to game over.
end
return tick_game_over(inputs) -- do it right now.
elseif scene_manager.game_over_state == 4 then -- game_over_state == 4? User is entering initials.
if inputs.pressed["left"] then
if scene_manager.player_initials_selected_glyph == 0 then
scene_manager.player_initials_selected_glyph = 29
else
scene_manager.player_initials_selected_glyph = scene_manager.player_initials_selected_glyph - 1
end
end
if inputs.pressed["right"] then
scene_manager.player_initials_selected_glyph = (scene_manager.player_initials_selected_glyph + 1) % 30
end
if inputs.pressed["action"] then
local selected = scene_manager.player_initials_selected_glyph
if selected == 29 then -- backspace?
if scene_manager.player_initials_entered > 0 then
scene_manager.player_initials[scene_manager.player_initials_entered] = ' '
scene_manager.player_initials_entered = scene_manager.player_initials_entered - 1
end
else
scene_manager.player_initials_entered = scene_manager.player_initials_entered + 1
scene_manager.player_initials[scene_manager.player_initials_entered] = initial_entry_string:sub(selected + 1, selected + 1);
if scene_manager.player_initials_entered == 3 then
local finalstr = scene_manager.player_initials[1] .. scene_manager.player_initials[2] .. scene_manager.player_initials[3]
finalstr = finalstr:upper()
DirkSimple.log("Player entered high score initials '" .. finalstr .. "' for a score of " .. scene_manager.current_score)
insert_highscore(alltime_highscores, finalstr, scene_manager.current_score)
insert_highscore(today_highscores, finalstr, scene_manager.current_score)
halt_laserdisc() -- this just makes the tick count go back to zero.
scene_manager.game_over_state = scene_manager.game_over_state + 1 -- move on to actual Game Over.
end
end
end
draw_highscore_entry_screen()
elseif scene_manager.game_over_state == 5 then -- game_over_state == 5? Actual game over screen.
draw_game_over_screen(ticks)
if ticks >= ((160 * #game_over_flash_colors) + 2000) then
halt_laserdisc() -- this just makes the tick count go back to zero.
scene_manager.game_over_state = scene_manager.game_over_state + 1 -- move on to high score list
end
elseif scene_manager.game_over_state == 6 then -- game_over_state == 6? Show high scores.
draw_high_scores(ticks)
if ticks >= 5000 then -- we're done, go back to attract mode.
start_attract_mode()
end
end
end
DirkSimple.tick = function(ticks, sequenceticks, inputs)
scene_manager.current_scene_ticks = sequenceticks + scene_manager.unserialize_offset
if scene_manager.last_seek == -1 then
scene_manager.laserdisc_frame = -1
else
scene_manager.laserdisc_frame = ((scene_manager.last_seek + scene_manager.current_scene_ticks) / (1000.0 / 29.97)) + 6
end
if scene_manager.attract_mode_state ~= 0 then
tick_attract_mode(inputs)
elseif scene_manager.death_mode_state ~= 0 then
tick_death_scene()
elseif scene_manager.scene_start_state ~= 0 then
tick_scene_start()
elseif scene_manager.game_over_state ~= 0 then
tick_game_over(inputs)
elseif scene_manager.current_scene == nil then
start_attract_mode()
else
tick_game(inputs)
end
end
DirkSimple.serialize = function()
if not scene_manager.initialized then
setup_scene_manager() -- just so we can serialize a default state.
end
local state = {}
state[#state + 1] = 2 -- current serialization version
state[#state + 1] = scene_manager.lives_left
state[#state + 1] = scene_manager.current_score
state[#state + 1] = scene_manager.last_failed_scene
state[#state + 1] = scene_manager.last_failed_sequence
state[#state + 1] = scene_manager.failures_in_a_row
state[#state + 1] = scene_manager.attract_mode_state
state[#state + 1] = scene_manager.death_mode_state
state[#state + 1] = scene_manager.game_over_state
state[#state + 1] = scene_manager.player_initials[1]:byte()
state[#state + 1] = scene_manager.player_initials[2]:byte()
state[#state + 1] = scene_manager.player_initials[3]:byte()
state[#state + 1] = scene_manager.player_initials_entered
state[#state + 1] = scene_manager.player_initials_selected_glyph
state[#state + 1] = scene_manager.scene_start_state
state[#state + 1] = scene_manager.scene_start_tick_offset
state[#state + 1] = scene_manager.last_seek
state[#state + 1] = scene_manager.current_scene_num
state[#state + 1] = scene_manager.current_sequence_num
state[#state + 1] = scene_manager.current_scene_ticks
state[#state + 1] = scene_manager.accepted_input
return state
end
DirkSimple.unserialize = function(state)
-- !!! FIXME: this function assumes that `state` is completely valid. It doesn't check array length or data types.
setup_scene_manager()
local idx = 1
local version = state[idx] ; idx = idx + 1
if version == 1 then idx = idx + 1 end -- this was scene_manager.infinite_lives, but that's a cvar now.
scene_manager.lives_left = state[idx] ; idx = idx + 1
scene_manager.current_score = state[idx] ; idx = idx + 1
scene_manager.last_failed_scene = state[idx] ; idx = idx + 1
scene_manager.last_failed_sequence = state[idx] ; idx = idx + 1
scene_manager.failures_in_a_row = state[idx] ; idx = idx + 1
scene_manager.attract_mode_state = state[idx] ; idx = idx + 1
scene_manager.death_mode_state = state[idx] ; idx = idx + 1
scene_manager.game_over_state = state[idx] ; idx = idx + 1
scene_manager.player_initials[1] = string.char(state[idx]) ; idx = idx + 1
scene_manager.player_initials[2] = string.char(state[idx]) ; idx = idx + 1
scene_manager.player_initials[3] = string.char(state[idx]) ; idx = idx + 1
scene_manager.player_initials_entered = state[idx] ; idx = idx + 1
scene_manager.player_initials_selected_glyph = state[idx] ; idx = idx + 1
scene_manager.scene_start_state = state[idx] ; idx = idx + 1
scene_manager.scene_start_tick_offset = state[idx] ; idx = idx + 1
scene_manager.last_seek = state[idx] ; idx = idx + 1
scene_manager.current_scene_num = state[idx] ; idx = idx + 1
scene_manager.current_sequence_num = state[idx] ; idx = idx + 1
scene_manager.current_scene_ticks = state[idx] ; idx = idx + 1
scene_manager.accepted_input = state[idx] ; idx = idx + 1
scene_manager.unserialize_offset = scene_manager.current_scene_ticks
if scene_manager.current_scene_num ~= 0 then
scene_manager.current_scene = scenes[scene_manager.current_scene_num]
if scene_manager.current_sequence_num ~= 0 then
scene_manager.current_sequence = scene_manager.current_scene[scene_manager.current_sequence_num]
end
end
if last_seek == -1 then
scene_manager.laserdisc_frame = -1
halt_laserdisc()
else
scene_manager.laserdisc_frame = ((scene_manager.last_seek + scene_manager.current_scene_ticks) / (1000.0 / 29.97)) + 6
DirkSimple.start_clip(scene_manager.last_seek + scene_manager.unserialize_offset)
end
return true
end
setup_scene_manager() -- Call this during initial load to make sure the table is ready to go.
local default_highscores = {
{ "JMH", 1000000 },
{ "PMR", 90000 },
{ "EMJ", 80000 },
{ "APH", 70000 },
{ "VAV", 60000 },
{ "MAS", 50000 },
{ "JON", 40000 },
{ "WHO", 30000 },
{ "HP?", 20000 },
{ "JIM", 10000 }
}
local function initialize_highscore()
local retval = {}
for i,v in ipairs(default_highscores) do
retval[i] = {}
retval[i][1] = default_highscores[i][1]
retval[i][2] = default_highscores[i][2]
end
return retval
end
alltime_highscores = initialize_highscore()
today_highscores = initialize_highscore()
-- The scene table!
-- https://www.jeffsromhack.com/code/cliffhanger.htm
scenes = {
-- scene 1
{
scene_name = "Casino Heist",
start_frame = 1547,
end_frame = 3160,
dunno1_frame = 0,
dunno2_frame = 0,
moves = {
{
name = "Running from the casino",
correct_moves = {},
incorrect_moves = {},
start_frame = 1800,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
name = "Jump first hurdle",
correct_moves = { "feet" },
incorrect_moves = { "hands" },
start_frame = 1928,
end_frame = 1987,
death_start_frame = 3930,
death_end_frame = 4234,
restart_move = 1
},
{
name = "Jump second hurdle",
correct_moves = { "feet" },
incorrect_moves = { "hands" },
start_frame = 1990,
end_frame = 2040,
death_start_frame = 3930,
death_end_frame = 4234,
restart_move = 2
},
{
name = "Get in the car, loser.",
correct_moves = { "hands" },
incorrect_moves = { "feet" },
start_frame = 2120,
end_frame = 2160,
death_start_frame = 3930,
death_end_frame = 4234,
restart_move = 2
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "down" },
start_frame = 2186,
end_frame = 2226,
death_start_frame = 3930,
death_end_frame = 4234,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 2276,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 7
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 2419,
end_frame = 2459,
death_start_frame = 3214,
death_end_frame = 3500,
restart_move = 7
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 2447,
end_frame = 2487,
death_start_frame = 3214,
death_end_frame = 3500,
restart_move = 7
},
{
correct_moves = { "down" },
incorrect_moves = { "hands", "feet", "up" },
start_frame = 2464,
end_frame = 2504,
death_start_frame = 3214,
death_end_frame = 3500,
restart_move = 7
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "up", "down", "right" },
start_frame = 2513,
end_frame = 2553,
death_start_frame = 3214,
death_end_frame = 3500,
restart_move = 7
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 2549,
end_frame = 2589,
death_start_frame = 3214,
death_end_frame = 3500,
restart_move = 7
},
{
correct_moves = { "hands" },
incorrect_moves = { "feet", "left", "right" },
start_frame = 2640,
end_frame = 2680,
death_start_frame = 3214,
death_end_frame = 3500,
restart_move = 7
},
}
},
-- scene 2
{
scene_name = "The Getaway",
start_frame = 4776,
end_frame = 8074,
dunno1_frame = 4592,
dunno2_frame = 0,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 5186,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "down" },
incorrect_moves = { "feet", "hands" },
start_frame = 5388,
end_frame = 5428,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "right", "down", "up" },
start_frame = 5418,
end_frame = 5458,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 5484,
end_frame = 5524,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 2
},
{
correct_moves = { "left" },
incorrect_moves = { "feet", "hands" },
start_frame = 5516,
end_frame = 5556,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 5560,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "right" },
incorrect_moves = { "feet", "hands" },
start_frame = 5600,
end_frame = 5640,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 7
},
{
correct_moves = { "right" },
incorrect_moves = { "feet", "hands" },
start_frame = 5680,
end_frame = 5720,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 7
},
{
correct_moves = { "left" },
incorrect_moves = { "feet", "hands" },
start_frame = 5710,
end_frame = 5750,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 7
},
{
correct_moves = { "left" },
incorrect_moves = { "feet", "hands" },
start_frame = 5752,
end_frame = 5792,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 7
},
{
correct_moves = { "right" },
incorrect_moves = { "feet", "hands", "left", "up", "down" },
start_frame = 5802,
end_frame = 5842,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 7
},
{
correct_moves = { "down" },
incorrect_moves = { "feet", "hands" },
start_frame = 5874,
end_frame = 5914,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 7
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 5920,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right", "up", "down" },
start_frame = 6000,
end_frame = 6040,
death_start_frame = 9794,
death_end_frame = 10081,
restart_move = 14
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 6108,
end_frame = 6148,
death_start_frame = 9794,
death_end_frame = 10081,
restart_move = 14
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right", "up", "down" },
start_frame = 6278,
end_frame = 6318,
death_start_frame = 9794,
death_end_frame = 10081,
restart_move = 14
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 6342,
end_frame = 6382,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 14
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet", "left", "down" },
start_frame = 6496,
end_frame = 6536,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 14
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 6694,
end_frame = 6734,
death_start_frame = 10105,
death_end_frame = 10427,
restart_move = 14
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right", "up", "down" },
start_frame = 6904,
end_frame = 6944,
death_start_frame = 10105,
death_end_frame = 10427,
restart_move = 14
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 6974,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "down" },
incorrect_moves = { "hands", "feet", "left", "right", "up" },
start_frame = 7015,
end_frame = 7055,
death_start_frame = 10105,
death_end_frame = 10427,
restart_move = 22
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right", "up", "down" },
start_frame = 7114,
end_frame = 7154,
death_start_frame = 10105,
death_end_frame = 10427,
restart_move = 22
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 7202,
end_frame = 7242,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 22
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 7239,
end_frame = 7279,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 22
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 7284,
end_frame = 7324,
death_start_frame = 8120,
death_end_frame = 8409,
restart_move = 22
},
{
correct_moves = { "feet" },
incorrect_moves = { "hands", "left", "right", "up", "down" },
start_frame = 7403,
end_frame = 7443,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 22
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 7470,
end_frame = 7510,
death_start_frame = 8439,
death_end_frame = 8732,
restart_move = 22
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 7958,
end_frame = 7998,
death_start_frame = 11753,
death_end_frame = 12215,
restart_move = 22
},
}
},
-- scene 3
{
scene_name = "Rooftops",
start_frame = 12397,
end_frame = 17248,
dunno1_frame = 12247,
dunno2_frame = 0,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 12460,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 12702,
end_frame = 12742,
death_start_frame = 17251,
death_end_frame = 17820,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 12725,
end_frame = 12765,
death_start_frame = 17251,
death_end_frame = 17820,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 13601,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 13866,
end_frame = 13906,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 13888,
end_frame = 13918,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 13898,
end_frame = 13928,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 13944,
end_frame = 13984,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 14044,
end_frame = 14084,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 14256,
end_frame = 14296,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 14343,
end_frame = 14383,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 5
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 14569,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 14668,
end_frame = 14708,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 13
},
{
correct_moves = { "down" },
incorrect_moves = { "hands", "feet" },
start_frame = 14694,
end_frame = 14734,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 13
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 14788,
end_frame = 14818,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 13
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 14818,
end_frame = 14858,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 13
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 15014,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 15143,
end_frame = 15183,
death_start_frame = 18596,
death_end_frame = 19889,
restart_move = 18
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "up" },
start_frame = 15221,
end_frame = 15261,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 18
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 15232,
end_frame = 15272,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 18
},
{
correct_moves = { "down" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 15253,
end_frame = 15293,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 18
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 15270,
end_frame = 15310,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 18
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet", "down" },
start_frame = 15296,
end_frame = 15336,
death_start_frame = 19596,
death_end_frame = 19889,
restart_move = 18
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 15750,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet", "down" },
start_frame = 15884,
end_frame = 15914,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 16054,
end_frame = 16094,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 16094,
end_frame = 16134,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 16137,
end_frame = 16177,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 16170,
end_frame = 16210,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 16222,
end_frame = 16262,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 16254,
end_frame = 16294,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet", "right" },
start_frame = 16307,
end_frame = 16347,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet", "left" },
start_frame = 16339,
end_frame = 16379,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 16392,
end_frame = 16432,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 16424,
end_frame = 16464,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 16998,
end_frame = 17038,
death_start_frame = 18235,
death_end_frame = 18577,
restart_move = 25
},
}
},
-- scene 4
{
scene_name = "Highway",
start_frame = 20891,
end_frame = 23321,
dunno1_frame = 20741,
dunno2_frame = 0,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 21240,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 21553,
end_frame = 21583,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 21570,
end_frame = 21600,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 21594,
end_frame = 21614,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 21640,
end_frame = 21670,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 21669,
end_frame = 21699,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 21698,
end_frame = 21728,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 21727,
end_frame = 21757,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 21826,
end_frame = 21856,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 21897,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22004,
end_frame = 22034,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22050,
end_frame = 22080,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22065,
end_frame = 22095,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22097,
end_frame = 22117,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22102,
end_frame = 22132,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22146,
end_frame = 22176,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22160,
end_frame = 22190,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 11
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22224,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22237,
end_frame = 22267,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22250,
end_frame = 22280,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22264,
end_frame = 22294,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22326,
end_frame = 22356,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22345,
end_frame = 22375,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22384,
end_frame = 22404,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22403,
end_frame = 22433,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22424,
end_frame = 22454,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 19
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22492,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet", "left", "right", "down" },
start_frame = 22494,
end_frame = 22524,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22500,
end_frame = 22530,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22538,
end_frame = 22568,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22556,
end_frame = 22586,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22580,
end_frame = 22610,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22592,
end_frame = 22622,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22610,
end_frame = 22640,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 28
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22683,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22689,
end_frame = 22719,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22702,
end_frame = 22732,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22730,
end_frame = 22760,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22750,
end_frame = 22780,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22784,
end_frame = 22814,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22794,
end_frame = 22824,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22845,
end_frame = 22875,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 36
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 22925,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet", "left", "right", "down" },
start_frame = 22941,
end_frame = 22971,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 22955,
end_frame = 22985,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 22995,
end_frame = 23025,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 23010,
end_frame = 23040,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 23035,
end_frame = 23065,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 23046,
end_frame = 23076,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 23058,
end_frame = 23088,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 23148,
end_frame = 23178,
death_start_frame = 23358,
death_end_frame = 23640,
restart_move = 44
},
}
},
-- scene 5
{
scene_name = "The Castle Battle",
start_frame = 25728,
end_frame = 26387,
dunno1_frame = 25579,
dunno2_frame = 25727,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 25729,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 25715,
end_frame = 25745,
death_start_frame = 26423,
death_end_frame = 26705,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 25765,
end_frame = 25795,
death_start_frame = 26423,
death_end_frame = 26705,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 25795,
end_frame = 25825,
death_start_frame = 26423,
death_end_frame = 26705,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 25800,
end_frame = 25830,
death_start_frame = 26423,
death_end_frame = 26705,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 25808,
end_frame = 25838,
death_start_frame = 26423,
death_end_frame = 26705,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 25824,
end_frame = 25854,
death_start_frame = 26423,
death_end_frame = 26705,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 25931,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 25944,
end_frame = 25974,
death_start_frame = 27725,
death_end_frame = 28014,
restart_move = 9
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 25996,
end_frame = 26026,
death_start_frame = 27725,
death_end_frame = 28014,
restart_move = 9
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 26146,
end_frame = 26176,
death_start_frame = 27725,
death_end_frame = 28014,
restart_move = 9
},
}
},
-- scene 6
{
scene_name = "Finale",
start_frame = 28514,
end_frame = 31212,
dunno1_frame = 28363,
dunno2_frame = 28510,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 28836,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 28900,
end_frame = 28930,
death_start_frame = 31275,
death_end_frame = 31619,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 29422,
end_frame = 29452,
death_start_frame = 31275,
death_end_frame = 31619,
restart_move = 2
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 29622,
end_frame = 29652,
death_start_frame = 31275,
death_end_frame = 31619,
restart_move = 2
},
{
correct_moves = { "hands", "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 30098,
end_frame = 30128,
death_start_frame = 31999,
death_end_frame = 32379,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 30460,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 30794,
end_frame = 30814,
death_start_frame = 31999,
death_end_frame = 32379,
restart_move = 7
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 30804,
end_frame = 30834,
death_start_frame = 31999,
death_end_frame = 32379,
restart_move = 7
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 30834,
end_frame = 30864,
death_start_frame = 31999,
death_end_frame = 32379,
restart_move = 7
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 30890,
end_frame = 30920,
death_start_frame = 32399,
death_end_frame = 32692,
restart_move = 7
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 30954,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 31063,
end_frame = 31093,
death_start_frame = 32797,
death_end_frame = 33102,
restart_move = 12
},
}
},
-- scene 7
{
scene_name = "Finale II",
start_frame = 33255,
end_frame = 37138,
dunno1_frame = 33105,
dunno2_frame = 33252,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 31063,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33668,
end_frame = 33698,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33704,
end_frame = 33734,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 33710,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33720,
end_frame = 33750,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33733,
end_frame = 33763,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 33760,
end_frame = 33790,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33824,
end_frame = 33854,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33830,
end_frame = 33860,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 33840,
end_frame = 33870,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 33922,
end_frame = 33952,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 33938,
end_frame = 33968,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 33990,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 34030,
end_frame = 34060,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 14
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 34100,
end_frame = 34130,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 14
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 34130,
end_frame = 34160,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 14
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 34286,
end_frame = 34316,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 14
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 34402,
end_frame = 34432,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 14
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 34620,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 35012,
end_frame = 35042,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 20
},
{
correct_moves = { "down" },
incorrect_moves = { "hands", "feet" },
start_frame = 35170,
end_frame = 35200,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 20
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 35374,
end_frame = 35404,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 20
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 35785,
end_frame = 35815,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 20
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 35873,
end_frame = 35903,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 20
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 35889,
end_frame = 35919,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 20
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 35955,
end_frame = 35985,
death_start_frame = 39727,
death_end_frame = 40184,
restart_move = 20
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 36020,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 36164,
end_frame = 36194,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 28
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 36327,
end_frame = 36357,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 28
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 36477,
end_frame = 36507,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 28
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 36593,
end_frame = 36623,
death_start_frame = 37192,
death_end_frame = 37511,
restart_move = 28
},
}
},
-- scene 8
{
scene_name = "Ending",
start_frame = 41587,
end_frame = 46880,
dunno1_frame = 41436,
dunno2_frame = 41584,
moves = {
{
correct_moves = {},
incorrect_moves = {},
start_frame = 41587,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 41574,
end_frame = 41604,
death_start_frame = 46960,
death_end_frame = 47256,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 41662,
end_frame = 41692,
death_start_frame = 46960,
death_end_frame = 47256,
restart_move = 2
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 41713,
end_frame = 41743,
death_start_frame = 46960,
death_end_frame = 47256,
restart_move = 2
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 42550,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 42676,
end_frame = 42706,
death_start_frame = 47289,
death_end_frame = 47578,
restart_move = 6
},
{
correct_moves = { "up" },
incorrect_moves = { "hands", "feet" },
start_frame = 42827,
end_frame = 42857,
death_start_frame = 47289,
death_end_frame = 47578,
restart_move = 6
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 42860,
end_frame = 42890,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 6
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 42902,
end_frame = 42932,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 6
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43068,
end_frame = 43098,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 6
},
{
correct_moves = { "right" },
incorrect_moves = { "hands", "feet" },
start_frame = 43092,
end_frame = 43102,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 6
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 43163,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43261,
end_frame = 43291,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43286,
end_frame = 43306,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43295,
end_frame = 43325,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43307,
end_frame = 43337,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43320,
end_frame = 43350,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43345,
end_frame = 43375,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43367,
end_frame = 43397,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43434,
end_frame = 43464,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43449,
end_frame = 43479,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43476,
end_frame = 43506,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43515,
end_frame = 43545,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43531,
end_frame = 43561,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43541,
end_frame = 43571,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43556,
end_frame = 43586,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43580,
end_frame = 43610,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43603,
end_frame = 43633,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43670,
end_frame = 43700,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43685,
end_frame = 43715,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43712,
end_frame = 43742,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43756,
end_frame = 43786,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43771,
end_frame = 43801,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43789,
end_frame = 43819,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43816,
end_frame = 43846,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43863,
end_frame = 43893,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43888,
end_frame = 43908,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43899,
end_frame = 43929,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 43926,
end_frame = 43956,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 44151,
end_frame = 44181,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 44304,
end_frame = 44334,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 44437,
end_frame = 44467,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 44530,
end_frame = 44560,
death_start_frame = 47607,
death_end_frame = 47969,
restart_move = 13
},
{
correct_moves = {},
incorrect_moves = {},
start_frame = 45030,
end_frame = 0,
death_start_frame = 0,
death_end_frame = 0,
restart_move = 1
},
{
correct_moves = { "left" },
incorrect_moves = { "hands", "feet" },
start_frame = 45298,
end_frame = 45328,
death_start_frame = 48768,
death_end_frame = 49050,
restart_move = 45
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 45394,
end_frame = 45414,
death_start_frame = 46960,
death_end_frame = 47256,
restart_move = 45
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 45525,
end_frame = 45555,
death_start_frame = 46960,
death_end_frame = 47256,
restart_move = 45
},
{
correct_moves = { "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 45591,
end_frame = 45621,
death_start_frame = 49225,
death_end_frame = 49634,
restart_move = 45
},
{
correct_moves = { "hands", "feet" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 45618,
end_frame = 45648,
death_start_frame = 49225,
death_end_frame = 49634,
restart_move = 45
},
{
correct_moves = { "hands" },
incorrect_moves = { "left", "right", "up", "down" },
start_frame = 45685,
end_frame = 45715,
death_start_frame = 49225,
death_end_frame = 49634,
restart_move = 45
},
}
}
}
-- end of cliff.lua ...