96 lines
3.2 KiB
Text
96 lines
3.2 KiB
Text
-- 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
|