147 lines
4.3 KiB
Text
147 lines
4.3 KiB
Text
-- Forge milestone 3, genre two: the same adventure in a modelled room from a fixed camera. The Walk areas baked to a
|
|
-- baked from the floor and a hotspot is what the ray through the pointer meets. Driven as scene64
|
|
-- is, with the pointer placed by where each hotspot projects.
|
|
--
|
|
dofile("Forge/AuthorCompile.singe")
|
|
|
|
local font = fontLoad("Singe/FreeSansBold.ttf", 16)
|
|
|
|
fontSelect(font)
|
|
fontQuality(FONT_QUALITY_BLENDED)
|
|
|
|
dofile(authorBuild("testScripts/author/adventure3d.game", singeGetDataPath() .. "adventure3d.singe"))
|
|
|
|
local gameUpdate = onOverlayUpdate
|
|
local frames = 0
|
|
local stage = 0
|
|
local shots = 0
|
|
local said = {}
|
|
local GIVE_UP = 90
|
|
|
|
local realSay = authorSay
|
|
function authorSay(text, seconds)
|
|
said[#said + 1] = tostring(text)
|
|
return realSay(text, seconds)
|
|
end
|
|
|
|
|
|
local function clickOn(verb, id)
|
|
local target = authorEntity(id)
|
|
local x, y, z = authorPosition(target)
|
|
local w, h = authorSize(target)
|
|
local sx, sy = sceneProject(x, y + h / 2, z)
|
|
|
|
authorSetVerb(verb)
|
|
authorSetPointer(1, sx, sy, true)
|
|
authorSwitchDown(SWITCH_BUTTON3)
|
|
authorSwitchUp(SWITCH_BUTTON3)
|
|
end
|
|
|
|
|
|
local function lastSaid()
|
|
return said[#said] or "(nothing)"
|
|
end
|
|
|
|
|
|
-- Each stage waits for the game to settle -- no sequence running, no line up, nobody walking --
|
|
-- or for a dialogue to offer its choices, before the next.
|
|
local function idle()
|
|
local hero = authorEntity("hero")
|
|
|
|
if authorChoices() ~= nil then
|
|
return true
|
|
end
|
|
|
|
return (not authorBusy()) and ((hero == nil) or not hero.walking)
|
|
end
|
|
|
|
|
|
local steps = {
|
|
function()
|
|
debugPrint("ADV3 the hall has a navigation mesh: " .. tostring(authorRoomNav() ~= nil) .. "; verb is " .. tostring(AUTHOR_VARS.verb))
|
|
clickOn("look", "door")
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 look at the door said: " .. lastSaid())
|
|
clickOn("take", "key")
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 took the key: has it " .. tostring(authorHas("key")) .. ", key gone " .. tostring(authorEntity("key") == nil) .. ", hero at " .. string.format("%.1f", authorX(authorEntity("hero"))) .. "," .. string.format("%.1f", authorField(authorEntity("hero"), "z")))
|
|
clickOn("open", "door")
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 the guard objects: " .. lastSaid())
|
|
clickOn("talk", "guard")
|
|
end,
|
|
function()
|
|
-- The dialogue is up: the first choice, then the one the key allows.
|
|
debugPrint("ADV3 the guard says: " .. lastSaid())
|
|
authorKeyDown(0, SCANCODE.MAIN_1.value)
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 and then: " .. lastSaid())
|
|
authorKeyDown(0, SCANCODE.MAIN_1.value)
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 allowed now: " .. tostring(AUTHOR_VARS.allowed) .. "; last line: " .. lastSaid())
|
|
authorSaid("look at the door")
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 typed 'look at the door': " .. lastSaid())
|
|
authorSaid("frobnicate the key")
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 typed nonsense: " .. lastSaid())
|
|
clickOn("open", "door")
|
|
end,
|
|
function()
|
|
debugPrint("ADV3 after the door: room " .. AUTHOR_ROOM.name .. ", score " .. AUTHOR_VARS.score .. ", outside " .. tostring(AUTHOR_VARS.outside))
|
|
authorSaveGame(1)
|
|
authorRestart()
|
|
debugPrint("ADV3 restarted: room " .. AUTHOR_ROOM.name .. ", score " .. AUTHOR_VARS.score)
|
|
authorLoadGame(1)
|
|
debugPrint("ADV3 loaded: room " .. AUTHOR_ROOM.name .. ", score " .. AUTHOR_VARS.score .. ", has key " .. tostring(authorHas("key")))
|
|
end,
|
|
function()
|
|
if AUTHOR_ROOM.name == "yard" and AUTHOR_VARS.score == 3 and authorHas("key") then
|
|
debugPrint("ADV3 RESULT done")
|
|
else
|
|
debugPrint("ADV3 FAIL room " .. AUTHOR_ROOM.name .. " score " .. AUTHOR_VARS.score)
|
|
end
|
|
singeQuit()
|
|
end
|
|
}
|
|
|
|
local waited = 0
|
|
|
|
function onOverlayUpdate()
|
|
local t = authorTime()
|
|
|
|
frames = frames + 1
|
|
-- Move on when the game is idle for a moment, or after a while regardless.
|
|
if idle() then
|
|
waited = waited + 1
|
|
else
|
|
waited = 0
|
|
end
|
|
if (stage < #steps) and ((waited > 12) or (frames == 20)) then
|
|
stage = stage + 1
|
|
waited = 0
|
|
steps[stage]()
|
|
end
|
|
|
|
local r = gameUpdate()
|
|
|
|
colorForeground(255, 255, 255, 255)
|
|
fontPrint(300, 450, string.format("adventure in 3D, stage %d, %.1fs", stage, t))
|
|
if (shots == 0 and stage == 2) or (shots == 1 and stage == 5) or (shots == 2 and stage == 10) then
|
|
shots = shots + 1
|
|
singeScreenshot()
|
|
end
|
|
if t > GIVE_UP then
|
|
debugPrint("ADV3 FAIL gave up at stage " .. stage)
|
|
singeQuit()
|
|
end
|
|
|
|
return r
|
|
end
|