# update.ludic - a frame of the body: the stick in the camera's frame, the step, the gait, the camera export function char_update(character_st: mut CharacterState, ix0: float, iz0: float, run0: bool, jump0: bool, dyaw: float, dpitch: float, dt: float) -> void { var run = run0 and character_st.chr_can_run var ix = ix0 var iz = iz0 var jump = jump0 character_st.chr_step = 0.0 character_st.chr_time = character_st.chr_time + dt character_st.chr_water = CharacterGround.water(character_st.chr_x, character_st.chr_z) chr_sit_tick(character_st, dt) if CharacterBody.riding() { chr_ride_update(character_st, ix, iz, run, dyaw, dpitch, dt) return } if CharacterBody.sneaking() { run = false } # sitting: any step stands up, and nothing else moves if character_st.chr_sit and (Math.abs(ix) > 0.3 or Math.abs(iz) > 0.3 or jump) { character_st.chr_sit = false } if character_st.chr_sit { ix = 0.0 iz = 0.0 jump = false } # the stick in the camera's frame: forward on the ground is (-sin yaw, -cos yaw) let cy = Math.cos(character_st.chr_cam_yaw) let sy = Math.sin(character_st.chr_cam_yaw) var dx = -sy * iz + cy * ix var dz = -cy * iz - sy * ix var mag = Math.sqrt(dx * dx + dz * dz) if mag > 1.0 { dx = dx / mag dz = dz / mag mag = 1.0 } chr_steer(character_st, dx, dz, mag, run, dt) # seated, the seat holds the body (chr_sit_tick): handed to the walker too, it was pushed off a # log or a bench and pulled back each frame, and shook var dist = 0.0 if not character_st.chr_sit or character_st.chr_swim { dist = chr_travel(character_st, dx, dz, -Math.sin(character_st.chr_yaw), -Math.cos(character_st.chr_yaw), jump, dt) } chr_gait(character_st, dist, dyaw, dpitch, dt) char_camera(character_st, dt) } # something else carries the body (CharacterBody.ride moves it with char_ride_at); the orbit # drifts behind whatever it is on function chr_ride_update(character_st: mut CharacterState, ix: float, iz: float, run: bool, dyaw: float, dpitch: float, dt: float) -> void { CharacterBody.ride(ix, iz, run, dt) chr_look(character_st, dyaw, dpitch) if dyaw == 0.0 and not CharacterInput.look_always() { character_st.chr_cam_yaw = character_st.chr_cam_yaw + char_wrap(character_st.chr_yaw - character_st.chr_cam_yaw) * Math.min(1.0, 1.5 * dt) } char_camera(character_st, dt) } # a frame from the input port: the game's devices, read once, stepping the body export function char_tick(character_st: mut CharacterState, dt: float) -> void { var ix = 0.0 var iz = 0.0 var run = false var jump = false var dyaw = 0.0 var dpitch = 0.0 if character_st.chr_holds == 0 { ix = CharacterInput.move_x() iz = CharacterInput.move_z() run = CharacterInput.run() jump = CharacterInput.jump() dyaw = CharacterInput.look_yaw() dpitch = CharacterInput.look_pitch() let wheel = CharacterInput.zoom() if wheel != 0.0 { character_st.chr_cam_dist = Math.clamp(character_st.chr_cam_dist - wheel * 0.35, 1.8, 9.0) } } char_update(character_st, ix, iz, run, jump, dyaw, dpitch, dt) }