-- Third-person action (FORGE.md's catalogue): a camera orbiting the hero under injected mouse -- motion, keys moving the hero relative to it, enemies following across the mesh, and a sword -- swung by a key at what is in reach. dofile("Forge/AuthorCompile.singe") local font = fontLoad("Singe/FreeSansBold.ttf", 18) fontSelect(font) fontQuality(FONT_QUALITY_BLENDED) dofile(authorBuild("testScripts/author/thirdperson.game", singeGetDataPath() .. "thirdperson.singe")) local gameUpdate = onOverlayUpdate local frames = 0 local shots = 0 local kills = 0 local yawStart = nil local startX = nil local lastSwing = 0 local GIVE_UP = 40 local realEvent = authorEvent function authorEvent(name, event) if name == "death" then kills = kills + 1 end return realEvent(name, event) end function onOverlayUpdate() local t = authorTime() local hero = authorEntity("hero") local camera = authorEntity("camera") local hx, hy, hz = authorPosition(hero) frames = frames + 1 yawStart = yawStart or camera.yaw startX = startX or hx -- Orbit the camera a quarter turn over the first second, then walk forward for two. if frames >= 5 and frames < 35 then authorMouseMoved(0, 0, 15, 0) elseif frames == 35 then authorKeyDown(0, SCANCODE.W.value) elseif frames == 155 then authorKeyUp(0, SCANCODE.W.value) end -- Swing at anything close. if (t - lastSwing > 0.4) then for _, enemy in ipairs(authorEach("enemy")) do if (enemy.vars.state ~= "dead") and (authorDistance3D(enemy, hero) < 2.2) then authorKeyDown(0, SCANCODE.SPACE.value) authorKeyUp(0, SCANCODE.SPACE.value) lastSwing = t break end end end local r = gameUpdate() colorForeground(255, 255, 255, 255) fontPrint(12, 450, string.format("authored third person, %.1fs, yaw %.0f, hero %.1f,%.1f, kills %d, swings %d", t, camera.yaw, hx, hz, kills, AUTHOR_VARS.swings)) if (shots == 0 and frames == 40) or (shots == 1 and kills > 0) then shots = shots + 1 singeScreenshot() end local hive = authorEntity("hive") if (hive.vars.made >= 4 and authorCount("enemy") == 0 and t > 5) or (t > GIVE_UP) then debugPrint(string.format("TPS RESULT kills=%d swings=%d health=%d yawTurned=%.0f movedX=%.1f after=%.1fs", kills, AUTHOR_VARS.swings, AUTHOR_VARS.health, camera.yaw - yawStart, hx - startX, t)) if kills < 3 then debugPrint("TPS FAIL fewer than three enemies were cut down") end if math.abs(camera.yaw - yawStart) < 60 then debugPrint("TPS FAIL the camera did not orbit") end if math.abs(hx - startX) < 1 then debugPrint("TPS FAIL walking forward after the orbit did not move the hero sideways in the world") end singeQuit() end return r end