Lots of content
This commit is contained in:
Executable
+43
@@ -0,0 +1,43 @@
|
||||
-- Pure M1 controller. Only ephemeral session fields and state.stamina mutate.
|
||||
-- No engine access: the runtime supplies weapon, velocity, ground and water.
|
||||
local M = {}
|
||||
function M.delta(dt)
|
||||
if type(dt) ~= "number" or dt ~= dt or dt <= 0 then return 0 end
|
||||
return math.min(dt, 0.1) -- never replay stalls as movement/exhaustion
|
||||
end
|
||||
function M.step(session, state, controls, dt, env)
|
||||
controls, env = controls or {}, env or {}
|
||||
dt = M.delta(dt)
|
||||
local velocity = env.velocity or {x = 0, y = 0, z = 0}
|
||||
local grounded = env.grounded == true and math.abs(velocity.y or 0) < 0.2
|
||||
local swimming = env.swimming == true
|
||||
local moving = (velocity.x or 0)^2 + (velocity.z or 0)^2 > 0.04
|
||||
if state.stamina <= 8 and not session.exhausted then
|
||||
session.exhausted = true; session.sprint_released = false
|
||||
end
|
||||
if session.exhausted and not controls.aux1 then session.sprint_released = true end
|
||||
if session.exhausted and session.sprint_released and state.stamina >= 30 then
|
||||
session.exhausted, session.sprint_released = false, false
|
||||
end
|
||||
local blocking = env.weapon == "hearth:spear" and controls.RMB == true and not swimming
|
||||
local sprinting = controls.aux1 == true and controls.up == true and not controls.down
|
||||
and not controls.sneak and not blocking and grounded and not swimming
|
||||
and not session.exhausted and state.stamina > 8
|
||||
-- Keep survival rates identical to model.needs; runtime restores its duplicate
|
||||
-- stamina result but retains that model's sprint hunger/thirst expenditure.
|
||||
local rate = sprinting and -13 or ((state.food > 0 and state.water > 0) and 9 or 2)
|
||||
state.stamina = math.max(0, math.min(100, state.stamina + rate * dt))
|
||||
if sprinting and state.stamina <= 8 then
|
||||
session.exhausted, session.sprint_released, sprinting = true, false, false
|
||||
end
|
||||
local target = swimming and 0.75 or (blocking and 0.6 or (sprinting and 1.45 or 1))
|
||||
if not swimming and not blocking and (state.wet or 0) >= 60 then target = target * 0.95 end
|
||||
local speed = session.movement_speed or 1
|
||||
local change = math.max(-3 * dt, math.min(3 * dt, target - speed))
|
||||
speed = speed + change
|
||||
session.movement_speed, session.sprinting, session.blocking = speed, sprinting, blocking
|
||||
session.grounded, session.swimming, session.moving = grounded, swimming, moving
|
||||
return {speed = speed, sprinting = sprinting, blocking = blocking,
|
||||
grounded = grounded, swimming = swimming, moving = moving}
|
||||
end
|
||||
return M
|
||||
Reference in New Issue
Block a user