-- The first-person shooter from FORGE.md's catalogue: a camera on the hero's eyes turned by mouse -- motion, a gun firing from the middle of the picture, keys moving relative to where the camera -- looks, and enemies walking the mesh after the hero. The mouse is injected to turn toward the -- nearest zombie's head before each shot. dofile("Forge/AuthorCompile.singe") local font = fontLoad("Singe/FreeSansBold.ttf", 18) fontSelect(font) fontQuality(FONT_QUALITY_BLENDED) dofile(authorBuild("testScripts/author/fps.game", singeGetDataPath() .. "fps.singe")) local gameUpdate = onOverlayUpdate local frames = 0 local shots = 0 local hits = 0 local kills = 0 local lastShot = 0 local walked = false local startZ = nil local GIVE_UP = 45 local LOOK_SPEED = 0.2 local realEvent = authorEvent function authorEvent(name, event) if name == "hit" then hits = hits + 1 elseif name == "death" then kills = kills + 1 end return realEvent(name, event) end function onOverlayUpdate() local t = authorTime() local hero = authorEntity("hero") local eyes = authorEntity("eyes") local hx, hy, hz = authorPosition(hero) frames = frames + 1 startZ = startZ or hz -- A step forward first, to show the keys move relative to the view. if frames == 5 then authorKeyDown(0, SCANCODE.W.value) elseif frames == 40 then authorKeyUp(0, SCANCODE.W.value) walked = true end -- Turn toward the nearest zombie's head and fire. if walked and (t - lastShot > 0.3) then local nearest, best = nil, math.huge for _, zombie in ipairs(authorEach("zombie")) do if zombie.vars.state ~= "dead" then local far = authorDistance3D(zombie, hero) if far < best then nearest, best = zombie, far end end end if nearest then local head = nodeFind("b_Head_05", nearest.model) local tx, ty, tz = nodeGetWorldPosition(head) local ex, ey, ez = authorPosition(eyes) local wantYaw = math.deg(math.atan(-(tx - ex), -(tz - ez))) local wantPitch = math.deg(math.atan(ty - ey, math.sqrt((tx - ex) ^ 2 + (tz - ez) ^ 2))) local dYaw = (eyes.yaw - wantYaw + 540) % 360 - 180 local dPitch = eyes.pitch - wantPitch authorMouseMoved(0, 0, dYaw / LOOK_SPEED, dPitch / LOOK_SPEED) if math.abs(dYaw) < 2 then authorSwitchDown(SWITCH_BUTTON3) authorSwitchUp(SWITCH_BUTTON3) lastShot = t end end end local r = gameUpdate() colorForeground(255, 255, 255, 255) fontPrint(12, 450, string.format("authored first person, %.1fs, yaw %.0f, hits %d, kills %d, zombies %d", t, eyes.yaw, hits, kills, authorCount("zombie"))) if (shots == 0 and t > 1) or (shots == 1 and kills > 0) or (shots == 2 and kills >= 4) then shots = shots + 1 singeScreenshot() end local hive = authorEntity("hive") if (hive.vars.made >= 6 and authorCount("zombie") == 0 and t > 5) or (t > GIVE_UP) then debugPrint(string.format("FPS RESULT kills=%d hits=%d health=%d bites=%d movedForward=%.1f after=%.1fs", kills, hits, AUTHOR_VARS.health, AUTHOR_VARS.bites, startZ - hz, t)) if kills < 4 then debugPrint("FPS FAIL fewer than four zombies were killed") end if startZ - hz < 1 then debugPrint("FPS FAIL W did not move the hero forward") end singeQuit() end return r end