-- 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