ludic.things: a Thing's seats (a run of the game's seat rows, saved; a bit per seat taken, not); ludic.character: char_sit takes the seat's top and its height above the feet, char_sit_leave names where standing up goes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e84a59aeff
commit
a22b8a572b
12 changed files with 107 additions and 11 deletions
|
|
@ -67,14 +67,14 @@ still stick.
|
|||
| `char_update(ix, iz, run, jump, dyaw, dpitch, dt)` | a frame from explicit input; `char_tick(dt)` reads `CharacterInput` (nothing while held) |
|
||||
| `char_teleport(x, z, yaw)`, `char_stand_on`, `char_push_to`, `char_face`, `char_halt`, `char_go_limp`, `char_resume_swim(dive, depth, breath)`, `char_map_changed()` | placing and stopping the body |
|
||||
| `char_config(walk, run)`, `char_allow_run(on)` | 3.2 and 6.8 m/s by default; a spent body cannot run or jump |
|
||||
| `char_sit(x, z, yaw, mode)`, `char_sit_here() -> CHAR_SAT / _STOOD / _NOT_RIDING / _NOT_AIRBORNE / _NOT_STEEP / _NOT_WET`, `char_stand()` | sitting (`CHAR_SIT_SEAT`, `CHAR_SIT_GROUND`) |
|
||||
| `char_sit(x, y, z, yaw, mode, h)` (y the seat's top, h its height above the feet), `char_sit_leave(x, z)` (where standing up goes), `char_sit_here() -> CHAR_SAT / _STOOD / _NOT_RIDING / _NOT_AIRBORNE / _NOT_STEEP / _NOT_WET`, `char_stand()` | sitting (`CHAR_SIT_SEAT`, `CHAR_SIT_GROUND`) |
|
||||
| `char_hold(reason)`, `char_release(reason)` (`CHAR_HOLD_SCREEN`, `CHAR_HOLD_STAGE`) | holds by reason: two holders cannot release each other |
|
||||
| `char_board(x, z, yaw)`, `char_ride_at(x, y, z, yaw, speed)`, `char_step_off(x, z)` | carried by something (`CharacterBody.riding`/`ride`) |
|
||||
| `char_safe_spot(x, z, from_y, max_depth) -> bool`, `body_safe_x()`, `body_safe_z()` | somewhere to put a body down |
|
||||
| `char_knock(vx, vz, up)` | knocked off its feet (a shove): the walker carries it and it lands where the world lets it |
|
||||
| `char_stand_at(x, z, from_y)` | the ground with a collider's top when it is a step, for a put-down |
|
||||
| `char_camera(dt)`, `char_camera_third(dt)`, `char_look(yaw, pitch)`, `char_look_pitch`, `char_orbit(dist)`, `char_lock_orbit`, `char_set_fps`, `char_fps_toggle() -> CHAR_EYES_*` | the camera; read it back with `body_eye_x/y/z/yaw/pitch()` and `body_eyes_now()` |
|
||||
| `body_x()`, `body_y()`, `body_z()`, `body_yaw()`, `body_speed()`, `body_moving()`, `body_run()`, `body_phase()`, `body_time()`, `body_water()`, `body_airborne()`, `body_vy()`, `body_landing()`, `body_steep()`, `body_step()`, `body_sitting()`, `body_sit_mode()`, `body_sit_t()`, `body_swimming()`, `body_diving()`, `body_depth()`, `body_breath()`, `body_breath_max()`, `body_floating()`, `body_swim_phase()`, `body_can_run()`, `body_held()`, `body_fps()`, `body_cam_yaw()`, `body_cam_pitch()`, `body_cam_dist()` | the queries |
|
||||
| `body_x()`, `body_y()`, `body_z()`, `body_yaw()`, `body_speed()`, `body_moving()`, `body_run()`, `body_phase()`, `body_time()`, `body_water()`, `body_airborne()`, `body_vy()`, `body_landing()`, `body_steep()`, `body_step()`, `body_sitting()`, `body_sit_mode()`, `body_sit_t()`, `body_sit_y()`, `body_sit_h()`, `body_swimming()`, `body_diving()`, `body_depth()`, `body_breath()`, `body_breath_max()`, `body_floating()`, `body_swim_phase()`, `body_can_run()`, `body_held()`, `body_fps()`, `body_cam_yaw()`, `body_cam_pitch()`, `body_cam_dist()` | the queries |
|
||||
| `char_wrap(a)`, `char_toward(cur, target, rate)`, `char_ease(t)` | the helpers a pose needs |
|
||||
| `char_facts() -> Queue<CharacterFact>` | `{ what, x, y, z, v }`: `CHAR_LANDED`, `_JUMPED`, `_FOOTFALL`, `_TOO_STEEP` (once per refusal), `_STARTED_SWIMMING`, `_LEFT_WATER`, `_OUT_OF_AIR` (v: seconds), `_CURRENT` (every 12 s) |
|
||||
| `char_reset()`, `char_system() -> System` | `"character"`, `PH_INPUT`, nothing saved: where a body stands is the game's to write |
|
||||
|
|
|
|||
|
|
@ -76,8 +76,12 @@ export state CharacterState {
|
|||
chr_sit_mode: int = 0
|
||||
chr_sit_t: float = 0.0 # 0 standing .. 1 sat, eased over a quarter second
|
||||
chr_sit_x: float = 0.0 # the seat's point, walked to over the blend
|
||||
chr_sit_y: float = 0.0 # the seat's top
|
||||
chr_sit_z: float = 0.0
|
||||
chr_sit_h: float = 0.0 # the seat's top above the feet; 0 on the ground
|
||||
chr_sit_yaw: float = 0.0
|
||||
chr_leave_x: float = 0.0 # where standing up leaves the seat for
|
||||
chr_leave_z: float = 0.0
|
||||
chr_swim: bool = false
|
||||
chr_dive: bool = false
|
||||
chr_depth: float = 0.0 # metres below the surface
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ export function body_step(character_st: CharacterState) -> float { return charac
|
|||
export function body_sitting(character_st: CharacterState) -> bool { return character_st.chr_sit }
|
||||
export function body_sit_mode(character_st: CharacterState) -> int { return character_st.chr_sit_mode }
|
||||
export function body_sit_t(character_st: CharacterState) -> float { return character_st.chr_sit_t }
|
||||
export function body_sit_y(character_st: CharacterState) -> float { return character_st.chr_sit_y }
|
||||
export function body_sit_h(character_st: CharacterState) -> float { return character_st.chr_sit_h }
|
||||
export function body_swimming(character_st: CharacterState) -> bool { return character_st.chr_swim }
|
||||
export function body_diving(character_st: CharacterState) -> bool { return character_st.chr_dive }
|
||||
export function body_depth(character_st: CharacterState) -> float { return character_st.chr_depth }
|
||||
|
|
|
|||
|
|
@ -1,18 +1,31 @@
|
|||
# sit.ludic - sitting: on a seat's point, or on the ground where the body stands. The pose either
|
||||
# side is a still one, so the sit's own weight (body_sit_t) eases 0 -> 1 over a quarter second and
|
||||
# the body walks the last step to the seat over the same time rather than jumping there.
|
||||
export function char_sit(character_st: mut CharacterState, x: float, z: float, yaw: float, mode: int) -> void {
|
||||
|
||||
# y is the seat's top and h how far above the feet it is, so the feet rest y - h (0 on the ground);
|
||||
# standing up leaves from the seat's own point unless char_sit_leave names another
|
||||
export function char_sit(character_st: mut CharacterState, x: float, y: float, z: float, yaw: float, mode: int, h: float) -> void {
|
||||
character_st.chr_sit = true
|
||||
character_st.chr_sit_mode = mode
|
||||
character_st.chr_speed = 0.0
|
||||
character_st.chr_move = 0.0
|
||||
character_st.chr_run = 0.0
|
||||
character_st.chr_sit_x = x
|
||||
character_st.chr_sit_y = y
|
||||
character_st.chr_sit_z = z
|
||||
character_st.chr_sit_h = Math.max(h, 0.0)
|
||||
character_st.chr_sit_yaw = yaw
|
||||
character_st.chr_leave_x = x
|
||||
character_st.chr_leave_z = z
|
||||
character_st.chr_water = CharacterGround.water(character_st.chr_x, character_st.chr_z)
|
||||
}
|
||||
|
||||
# where the body stands when it gets up out of this seat: in front of a bench, beside a boat's thwart
|
||||
export function char_sit_leave(character_st: mut CharacterState, x: float, z: float) -> void {
|
||||
character_st.chr_leave_x = x
|
||||
character_st.chr_leave_z = z
|
||||
}
|
||||
|
||||
function chr_sit_tick(character_st: mut CharacterState, dt: float) -> void {
|
||||
var want = 0.0
|
||||
if character_st.chr_sit { want = 1.0 }
|
||||
|
|
@ -22,7 +35,7 @@ function chr_sit_tick(character_st: mut CharacterState, dt: float) -> void {
|
|||
character_st.chr_x = Math.lerp(character_st.chr_x, character_st.chr_sit_x, k)
|
||||
character_st.chr_z = Math.lerp(character_st.chr_z, character_st.chr_sit_z, k)
|
||||
character_st.chr_yaw = character_st.chr_yaw + char_wrap(character_st.chr_sit_yaw - character_st.chr_yaw) * k
|
||||
character_st.chr_y = CharacterGround.height(character_st.chr_x, character_st.chr_z)
|
||||
character_st.chr_y = Math.lerp(character_st.chr_y, character_st.chr_sit_y - character_st.chr_sit_h, k)
|
||||
character_st.chr_water = CharacterGround.water(character_st.chr_x, character_st.chr_z)
|
||||
}
|
||||
|
||||
|
|
@ -38,17 +51,18 @@ export function char_sit_here(character_st: mut CharacterState) -> int {
|
|||
if character_st.chr_air { return CHAR_NOT_AIRBORNE }
|
||||
if CharacterGround.slope(character_st.chr_x, character_st.chr_z) > 0.35 { return CHAR_NOT_STEEP }
|
||||
if character_st.chr_y < character_st.chr_water + 0.9 { return CHAR_NOT_WET }
|
||||
char_sit(character_st, character_st.chr_x, character_st.chr_z, character_st.chr_yaw, CHAR_SIT_GROUND)
|
||||
char_sit(character_st, character_st.chr_x, character_st.chr_y, character_st.chr_z, character_st.chr_yaw, CHAR_SIT_GROUND, 0.0)
|
||||
return CHAR_SAT
|
||||
}
|
||||
|
||||
# standing up out of a seat put down against a boulder or a bank must not leave the body inside it
|
||||
export function char_stand(character_st: mut CharacterState) -> void {
|
||||
character_st.chr_sit = false
|
||||
if char_safe_spot(character_st, character_st.chr_x, character_st.chr_z, character_st.chr_y, 0.0) {
|
||||
let from_y = character_st.chr_y
|
||||
if char_safe_spot(character_st, character_st.chr_leave_x, character_st.chr_leave_z, from_y, 0.0) {
|
||||
character_st.chr_x = character_st.chr_safe_x
|
||||
character_st.chr_z = character_st.chr_safe_z
|
||||
character_st.chr_y = CharacterGround.height(character_st.chr_x, character_st.chr_z)
|
||||
character_st.chr_y = char_stand_at(character_st.chr_x, character_st.chr_z, from_y)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ program CharacterTest {
|
|||
test "a seat against the boulder holds the body still: the walker never pushes it off the seat" (character_st: mut CharacterState, character_test_st: mut CharacterTestState) {
|
||||
fresh(character_st, 0.0, 4.5, 0.0)
|
||||
char_update(character_st, 0.0, 0.0, false, false, 0.0, 0.0, 1.0 / 60.0)
|
||||
char_sit(character_st, 0.0, 5.7, 0.0, CHAR_SIT_SEAT)
|
||||
char_sit(character_st, 0.0, body_y(character_st) + 0.45, 5.7, 0.0, CHAR_SIT_SEAT, 0.45)
|
||||
for i in 0 .. 90 { char_update(character_st, 0.0, 0.0, false, false, 0.0, 0.0, 1.0 / 60.0) }
|
||||
var most = 0.0
|
||||
for i in 0 .. 120 {
|
||||
|
|
@ -349,7 +349,7 @@ program CharacterTest {
|
|||
expect(body_eyes_now(character_st))
|
||||
expect_near(body_eye_y(character_st), 1.62, 0.05)
|
||||
expect_eq(char_fps_toggle(character_st), CHAR_EYES_OFF)
|
||||
char_sit(character_st, 0.0, 0.0, 0.0, CHAR_SIT_SEAT)
|
||||
char_sit(character_st, 0.0, 0.45, 0.0, 0.0, CHAR_SIT_SEAT, 0.45)
|
||||
expect_eq(char_fps_toggle(character_st), CHAR_EYES_SITTING)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue