# walk.ludic - the step itself: swimming, in the air, or on the ground; the distance, for the gait function chr_travel(base_st: mut BaseState, character_st: mut CharacterState, dx: float, dz: float, fx: float, fz: float, jump: bool, dt: float) -> float { if character_st.chr_swim { chr_swim_tick(base_st, character_st, dx, dz, jump, dt) return character_st.chr_speed * dt } if character_st.chr_air { return chr_fly(base_st, character_st, dx, dz, dt) } return chr_walk(base_st, character_st, fx, fz, jump, dt) } # ballistic: gravity, the takeoff's velocity carried, a little steering function chr_fly(base_st: mut BaseState, character_st: mut CharacterState, dx: float, dz: float, dt: float) -> float { character_st.chr_vy = character_st.chr_vy - 14.0 * dt character_st.chr_air_vx = character_st.chr_air_vx + dx * (4.0 * dt) character_st.chr_air_vz = character_st.chr_air_vz + dz * (4.0 * dt) chr_push(character_st, character_st.chr_x + character_st.chr_air_vx * dt, character_st.chr_z + character_st.chr_air_vz * dt, 0.35, character_st.chr_y, character_st.chr_y + CHAR_BODY) character_st.chr_y = character_st.chr_y + character_st.chr_vy * dt let ground = char_stand_at(character_st.chr_out_x, character_st.chr_out_z, character_st.chr_y) character_st.chr_x = character_st.chr_out_x character_st.chr_z = character_st.chr_out_z if character_st.chr_y < ground and character_st.chr_vy < 0.0 { character_st.chr_y = ground character_st.chr_air = false character_st.chr_land = 0.22 character_st.chr_speed = Math.sqrt(character_st.chr_air_vx * character_st.chr_air_vx + character_st.chr_air_vz * character_st.chr_air_vz) chr_say(base_st, character_st, CHAR_LANDED, character_st.chr_speed) } return character_st.chr_speed * (dt * 0.4) } # on the ground: a step, unless a slope refuses it or the water takes the body; then a jump function chr_walk(base_st: mut BaseState, character_st: mut CharacterState, fx: float, fz: float, jump: bool, dt: float) -> float { var dist = character_st.chr_speed * dt if dist > 0.0 { dist = chr_walk_step(base_st, character_st, fx, fz, dist) } else { character_st.chr_y = CharacterGround.height(character_st.chr_x, character_st.chr_z) } if jump and character_st.chr_can_run and character_st.chr_land < 0.05 { character_st.chr_air = true character_st.chr_vy = 5.0 character_st.chr_air_vx = fx * character_st.chr_speed character_st.chr_air_vz = fz * character_st.chr_speed chr_say(base_st, character_st, CHAR_JUMPED, 0.0) } return dist } function chr_walk_step(base_st: mut BaseState, character_st: mut CharacterState, fx: float, fz: float, dist: float) -> float { chr_push(character_st, character_st.chr_x + fx * dist, character_st.chr_z + fz * dist, 0.35, character_st.chr_y, character_st.chr_y + CHAR_BODY) let nx = character_st.chr_out_x let nz = character_st.chr_out_z let nh = char_stand_at(nx, nz, character_st.chr_y) if char_slope_blocks(character_st, nh, fx, fz) { if not (character_st.chr_steep > 0.0) { chr_say(base_st, character_st, CHAR_TOO_STEEP, nh - character_st.chr_y) } character_st.chr_steep = 1.2 character_st.chr_speed = 0.0 return 0.0 } # the lake shelves: shin-deep is a wade, and past CHAR_WADE_MAX it is a swim. Entering owns # the position and the height this frame, or the body sits on the bed for one frame. if nh < CharacterGround.water(nx, nz) - CHAR_WADE_MAX { chr_enter_water(base_st, character_st, nx, nz) return dist } let mx = nx - character_st.chr_x let mz = nz - character_st.chr_z character_st.chr_step = Math.sqrt(mx * mx + mz * mz) character_st.chr_x = nx character_st.chr_z = nz character_st.chr_y = nh return dist }