singe/testScripts/scene69.singe
2026-09-14 14:20:17 -05:00

179 lines
5.8 KiB
Text

-- The editor's milestone 6 (FORGE.md): a picker narrowed by typing, a file field offering the
-- game's files, walk areas and hotspot outlines drawn corner by corner, the dialogue outline, and
-- building with the current room first. Driven by keys and canvas presses, as the others are.
FORGE_LIBRARY = true
dofile("Forge/Forge.singe")
local font = fontLoad("Singe/FreeSansBold.ttf", 15)
local out = singeGetDataPath()
local work = out .. "adv.game"
fontSelect(font)
fontQuality(FONT_QUALITY_BLENDED)
overlaySetResolution(720, 480)
local source = assert(io.open("testScripts/author/adventure2d.game", "r"))
local copy = assert(io.open(work, "w"))
copy:write(source:read("a"))
source:close()
copy:close()
if not forgeBegin(work) then
debugPrint("EDIT FAIL could not open " .. work)
singeQuit()
end
local frames = 0
local stage = 0
local function key(code, character)
forgeKey(character or 0, code.value)
end
local function typeIn(text)
for c in string.gmatch(text, ".") do
key(SCANCODE.A, string.byte(c))
end
end
local function step()
if stage == 1 then
-- A rule's condition picked by typing part of its name.
key(SCANCODE.TAB)
key(SCANCODE.TAB)
key(SCANCODE.N)
key(SCANCODE.C)
typeIn("keyH")
local shown = forgePickItems()
key(SCANCODE.RETURN)
local rule = FORGE.game.rules[#FORGE.game.rules]
if #shown == 1 and rule.when[1][1] == "keyHeld" then
debugPrint("EDIT typing keyH left one condition and ENTER took it: " .. rule.when[1][1])
else
debugPrint("EDIT FAIL the narrowed picker showed " .. #shown .. " and took " .. tostring(rule.when[1] and rule.when[1][1]))
end
elseif stage == 2 then
-- A file field offers the files under the game's directory.
key(SCANCODE.TAB) -- tracks
key(SCANCODE.TAB) -- dialogues
key(SCANCODE.TAB) -- entities
key(SCANCODE.TAB) -- kinds
FORGE.kindName = "hero"
forgeKindSet(FORGE.game.kinds.hero, "look", "sprite")
FORGE.lastField = "look.anchor"
key(SCANCODE.RETURN) -- look.file: the picker
if FORGE.picker == nil then
debugPrint("EDIT FAIL a file field did not open the picker")
end
typeIn("testScripts/strip")
key(SCANCODE.RETURN)
debugPrint("EDIT the hero's sprite file is now " .. tostring(FORGE.game.kinds.hero.look.file))
if FORGE.game.kinds.hero.look.file ~= "testScripts/strip.png" then
debugPrint("EDIT FAIL the file picker did not set the file")
end
forgeKindSet(FORGE.game.kinds.hero, "look", "box")
elseif stage == 3 then
-- A walk area drawn corner by corner, then a hotspot's outline.
key(SCANCODE.TAB) -- rules
key(SCANCODE.TAB) -- tracks
key(SCANCODE.TAB) -- dialogues
key(SCANCODE.TAB) -- entities
forgeSelect(nil)
local walks = #(forgeRoom().walk or {})
key(SCANCODE.V)
forgePress(300, 320)
forgePress(500, 320)
forgePress(400, 400)
key(SCANCODE.V)
if #forgeRoom().walk == walks + 1 and #forgeRoom().walk[walks + 1] == 6 then
debugPrint("EDIT a walk area of three corners was drawn")
else
debugPrint("EDIT FAIL the room has " .. #(forgeRoom().walk or {}) .. " walk areas")
end
for index, entry in ipairs(forgeRoom().entities) do
if entry.id == "door" then
forgeSelect(index)
end
end
key(SCANCODE.V)
forgePress(570, 180)
forgePress(630, 180)
forgePress(630, 300)
forgePress(570, 300)
key(SCANCODE.RETURN)
local spot = FORGE.game.kinds.door.behaviours[1]
if spot.polygon and #spot.polygon == 8 then
debugPrint("EDIT the door's outline has four corners")
else
debugPrint("EDIT FAIL the door's outline is " .. tostring(spot.polygon and #spot.polygon))
end
elseif stage == 4 then
-- The dialogue outline: a node added and named, a choice added, an action picked for it.
key(SCANCODE.TAB) -- kinds
key(SCANCODE.TAB) -- rules
key(SCANCODE.TAB) -- tracks
key(SCANCODE.TAB) -- dialogues
debugPrint("EDIT the outline starts on dialogue '" .. tostring(FORGE.dialogue) .. "' with " .. #forgeDialogueRows() .. " rows")
key(SCANCODE.A) -- a node in the guard's dialogue
key(SCANCODE.RETURN) -- its name
typeIn("bye")
key(SCANCODE.RETURN) -- who
key(SCANCODE.ESCAPE)
key(SCANCODE.A) -- a choice in it
key(SCANCODE.T)
typeIn("addSc")
key(SCANCODE.RETURN)
local node = FORGE.game.dialogues.guard.nodes.bye
if node and node.choices[1] and node.choices[1].act[1][1] == "addScore" then
debugPrint("EDIT a node 'bye' with a choice that adds to the score went into the guard's dialogue")
else
debugPrint("EDIT FAIL the node is " .. tostring(node) .. "; rows " .. #forgeDialogueRows())
end
elseif stage == 5 then
-- Saved, and built with the second room first.
key(SCANCODE.S)
local built = forgeBuild(out .. "adv.singe", 2)
local text = assert(io.open(built, "r")):read("a")
local yard = text:find('name = "yard"', 1, true)
local hall = text:find('name = "hall"', 1, true)
debugPrint("EDIT built from the yard: yard before hall " .. tostring(yard ~= nil and hall ~= nil and yard < hall) .. "; the dialogue carries bye: " .. tostring(text:find('"bye"', 1, true) ~= nil))
if not (yard and hall and yard < hall) then
debugPrint("EDIT FAIL the built game does not start in the yard")
end
debugPrint("EDIT RESULT done")
end
end
function onOverlayUpdate()
frames = frames + 1
if frames % 14 == 0 and stage < 6 then
stage = stage + 1
step()
end
forgeDraw(nil, nil)
colorForeground(255, 255, 255, 255)
fontPrint(210, 8, "editor, stage " .. stage)
if frames == 30 or frames == 58 or frames == 72 then
singeScreenshot()
end
if frames > 100 then
singeQuit()
end
return OVERLAY_UPDATED
end