Entropie git · main
Entropie festival game; first steps
C 88.5% Markdown 9.1% GLSL 2.3%git clone https://git.christianimmanuel.de/games/Entropie.gitwget https://git.christianimmanuel.de/games/Entropie/archive/Entropie.tar.gzentropie 2.21.0: the careful way up
- Hip-high ledges: less sporty and older people turn round, hop up to sit on the edge with the legs hanging, swing the legs up onto it (sitting cross-legged a moment) and stand up
build.sh | 2 ++ commit_message.txt | 8 +++---- entropie/Makefile | 2 +- entropie/README.md | 4 +++- entropie/STATE.md | 7 ++++-- entropie/src/people/climb.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ entropie/src/world/object.h | 4 ++++ entropie/src/world/world.c | 7 +++--- 8 files changed, 78 insertions(+), 11 deletions(-) diff --git a/build.sh b/build.sh index 3bb2829..8c57d4f 100644 --- a/build.sh +++ b/build.sh @@ -1 +1,3 @@ + +[ -f /home/Shared/Claude/entropie/commit_message.txt ] || exit cd .. && rm -rf entropie; mv $SHARED_CLAUDE/entropie/commit_message.txt . && tar -xvf $SHARED_CLAUDE/entropie/entropie.tar.gz && echo "$(git add . && git commit -m "$(cat commit_message.txt)")" && cd entropie && make clean && make && cat ../commit_message.txt diff --git a/commit_message.txt b/commit_message.txt index 0e1a9a7..755deb6 100644 --- a/commit_message.txt +++ b/commit_message.txt @@ -1,5 +1,5 @@ -entropie 2.20.0: C23, climbing hand by hand +entropie 2.21.0: the careful way up -- Build as C23 (-std=c23, or -std=c2x on compilers that call it that); - everything compiles clean, nothing needed changing -- Climbing a high ledge: one hand reaches the edge first, the other follows +- Hip-high ledges: less sporty and older people turn round, hop up to sit + on the edge with the legs hanging, swing the legs up onto it (sitting + cross-legged a moment) and stand up diff --git a/entropie/Makefile b/entropie/Makefile index df6f81e..278d9c1 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 2.20.0 +VERSION := 2.21.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/README.md b/entropie/README.md index 5c1fb1d..e922de1 100644 --- a/entropie/README.md +++ b/entropie/README.md @@ -336,7 +336,9 @@ and satellite pictures (about 340 x 340 m). - Walking up to something you can climb, your hands go onto its edge; pulling up, the feet push against its face, then one knee and foot come over the edge, then the other (never through it). The hands stay pressed on top and - the back bends over the edge + the back bends over the edge. One hand gets there first, the other follows +- Hip high, the less sporty and the old take the careful way: back to it, a + hop up to sit on the edge, legs swung up onto it, then stand up - Jumps take off from one foot (rarely both at once); at a run, the rear foot pushes off and the front one lands first - Drunk, walking into a wall or a person easily ends on the ground diff --git a/entropie/STATE.md b/entropie/STATE.md index 0c36bf7..ccbcc37 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -284,6 +284,9 @@ Round 2.20: - C23: the Makefile asks the compiler for `-std=c23` and falls back to `-std=c2x` (GCC 13 / Clang 17 and older call it that); everything compiles clean as C2x with -Wall -Wextra -Wpedantic -Wshadow. (It was C11 from the start, out of caution; nothing needed changing.) README: a C23 compiler (GCC 9+ / Clang 9+). - Climbing up a high ledge: one hand reaches the edge first (your main hand), the other follows from down by the shoulder (`Hands.edge_lead` / `edge_trail`, set by `Climb_update`: trailing till t 0.24, the unfit a bit longer). Checked on a 1.7 m wall: hand, hand, pull up, a knee on the top, over. +Round 2.21: +- The careful way up (`climb.c` sitWay, `ClimbMove.sit_way`): something SIT_LOW 0.55 .. SIT_HIGH 1.05 m high (scaled), for the less sporty (fitness under SIT_FIT 0.45) or old (pace under 0.8): turned round with the back to it, a hop up so the hips sit on the edge, legs hanging (hands behind on it), the knees swing up and round onto it (turning back to face it: sitting cross-legged on top for a moment), stood up. SIT_TIME 3.2 s fresh. The body sits for it (`world.c`: sit_goal from `climb_move.sit_now`, not the pull-up pose meanwhile). + Unfinished building (Shell_build, at SHELL_AT in the frame's frame): brick shell 6.4 x 4.7, walls 2.9, open front (2 m) to the frame (now only the front half: pillars at z -13.8 / -9.2), window holes, bare floor, tiled roof with slabs. Barn: brick courses on BUILDING_BRICK walls (`addBrickCourses`: mortar a shade lighter, so the ink doesn't trace it), ivy (`Shapes_ivy`, OBJ_STRUCTUREs) on both long sides; the woodpile (OBJ_WOODPILE "Woodpile", WOODPILE_A/B) left of the toilet, everybody's woodpile from the start (`scene.c` Scene_finish). Fireplace tripod: wooden poles, feet TRIPOD_OUT 0.9 m outside the stones, TRIPOD_PAST 0.4 m past the top, a lashing; each pole an OBJ_WALL along it ("Tripod pole"). Gates (FURN_GATE, green boards): in your garages' doorways (GATES: hinge, end), `gate_open` / `gate_t`, `hinge`, `gate_shut` / `gate_out`; Object_swingGate (1.2 s), driven by showProps; a click within 1.2 m opens / shuts both leaves. Props that show (1.89, `world.c` showProps every frame): the tin's mesh is built again when its butts change (`Shapes_ashtray`: up to 12 show, the ash rises, a heap from 14; `shown` = what's built). @@ -419,7 +422,7 @@ Most important first. **Body and moving** - Obstacle approach, still to do: thin round logs (under 0.2 m) are still stepped over; a step in between on top of something unstable (if clumsy); NPCs: pull up on their own for their own reasons (now only following a leader), jumping onto things -- Climbing rework, still to do: the shoulder going ahead with the first hand; other ways up by height, surface and person: sit on it and lift the legs, or belly first and roll (one hand first, the knee up, the other foot next to it: in) +- Climbing rework, still to do: the shoulder going ahead with the first hand; another way up by height, surface and person: belly first and roll (in: one hand first, the knee up, the other foot next to it; sitting on it and swinging the legs up) - Balance: hips over the feet, look for stable footing, play with balance - Personal movement styles, still to do: gesture variants; stepping over and climbing their own way; sporty ones more elegant (walking styles are in) - More gestures and feelings to pick personalities from: the lists in Body / Fidgets and Gestures can grow @@ -443,4 +446,4 @@ Most important first. - Drawing many figures on a real graphics card: not measured (software GL: 300 people cost 3x the rest of the scene) --- -State of `entropie 2.20.0 (build 025b698)` +State of `entropie 2.21.0 (build 3f347be)` diff --git a/entropie/src/people/climb.c b/entropie/src/people/climb.c index d6bfe67..2b6de15 100644 --- a/entropie/src/people/climb.c +++ b/entropie/src/people/climb.c @@ -6,6 +6,10 @@ /* What's in front at climbing distance and could be climbed from feet_y: its top (the edge), or -1e9 if nothing (too high, no room up there). */ #define CLIMB_CLEAR 0.05f /* m over where the hands go ... */ +#define SIT_LOW 0.55f /* the careful way up (sitting on it): something this high (scaled) ... */ +#define SIT_HIGH 1.05f /* ... up to this */ +#define SIT_FIT 0.45f /* ... for those less sporty than this (or old: slow on their feet) */ +#define SIT_TIME 3.2f /* s it takes (fresh) */ #define CLIMB_OVER 0.5f /* ... from this high over it at the body: the way there is clear */ static bool onlyWalls(const Object *o, const void *ctx) { @@ -97,6 +101,12 @@ int Climb_start(const World *world, Object *p, float top, Vec3 probe) { p->climb_move.time = (hard ? 1.3f + 0.7f * fmaxf(rise / s - CLIMB_EASY, 0.0f) : 0.6f + rise * 0.6f) / fmaxf(vigor, 0.4f) / (hard ? sport : sqrtf(sport)); p->climb_move.t = 0.0f; + /* hip high, and careful (not so sporty, or old): turned round, sat on it, legs up and over */ + p->climb_move.sit_way = !hard && rise > SIT_LOW * s && rise < SIT_HIGH * s && (p->fitness < SIT_FIT || (p->pace > 0.05f && p->pace < 0.8f)); + p->climb_move.sit_now = false; + p->climb_move.yaw0 = p->rotation.y; + p->climb_move.swing = p->main_hand == HAND_LEFT ? -1.0f : 1.0f; + if (p->climb_move.sit_way) p->climb_move.time = SIT_TIME / fmaxf(vigor, 0.4f); Climb_noteFeet(p); p->climbing = true; p->velocity = vec3_zero(); @@ -186,10 +196,55 @@ static void climbFeet(const World *world, Object *p, float t, bool high, float s } +/* The careful way up (hip high): turn round with the back to it, sit up on + the edge (hands behind on it), swing the legs up and round onto it (sitting + cross-legged on top for a moment), and stand up. */ +static void sitWay(const World *world, Object *p, float t, float s) { + ClimbMove *c = &p->climb_move; + const Vec3 a = c->from, b = c->to; + Vec3 f = vec3(b.x - a.x, 0.0f, b.z - a.z); + f = vec3_length(f) > 1e-3f ? vec3_normalize(f) : Object_facing(p); + const float rise = b.y - a.y; + /* where the hips sit on the edge: just over it; standing there (facing out) a step in front of it */ + Vec3 edge_in = vec3_add(vec3(a.x, a.y, a.z), vec3_scale(f, c->face + 0.12f * s)); + Vec3 stand = vec3_sub(edge_in, vec3_scale(f, 0.36f * s)); + float turn = smoothstepf(0.04f, 0.24f, t), swing = smoothstepf(0.48f, 0.76f, t), rise_up = smoothstepf(0.8f, 1.0f, t); + /* facing: round with the back to it, then round again (the legs coming up) to face onto it */ + p->rotation.y = c->yaw0 + c->swing * PI_F * (turn - swing); + Vec3 pos = vec3_lerp(vec3(a.x, a.y, a.z), stand, turn); /* a step back to it, turning */ + pos = vec3_lerp(pos, vec3(b.x, b.y, b.z), smoothstepf(0.5f, 0.8f, t)); /* up and onto it, swinging round */ + /* a hop up onto the edge (the hips on it, the legs hanging), then the legs up onto it */ + const float hang = fminf(0.45f * s, rise - 0.05f), hop = smoothstepf(0.24f, 0.4f, t), legs_up = smoothstepf(0.48f, 0.72f, t); + pos.y = lerpf(lerpf(a.y, b.y - hang, hop), b.y, legs_up); + p->position = pos; + p->velocity = vec3_zero(); + Object_syncColliders(p); + c->sit_now = turn > 0.7f && rise_up < 0.5f; /* (sitting down already as the turn ends: the body takes a moment to get down) */ + p->sit_style = swing > 0.5f ? SIT_GROUND : SIT_SEAT; /* on the edge, then cross-legged on top */ + p->body.seat_height = lerpf(lerpf(rise, hang, hop), 0.0f, legs_up) + 0.02f; + if (t > 0.2f && t < 0.62f) /* the hands behind on the edge, pushing up */ + Hands_holdEdge(p, vec3_add(edge_in, vec3(0.0f, rise, 0.0f)), c->across, 0.0f); + (void)world; +} + bool Climb_update(const World *world, Object *p, float dt) { const float s = p->look.height / 1.75f; ClimbMove *c = &p->climb_move; c->t += dt / c->time; + if (c->sit_way) { + float ts = clampf(c->t, 0.0f, 1.0f); + sitWay(world, p, ts, s); + if (ts >= 1.0f) { + p->climbing = false; + c->sit_now = false; + p->sit_style = SIT_SEAT; + p->body.seat_height = SEAT_HEIGHT; + p->is_grounded = true; + p->body.replant = true; + p->body.velocity = vec3_zero(); + } + return !p->climbing; + } float t = clampf(c->t, 0.0f, 1.0f); const Vec3 a = c->from, b = c->to; const float hang = c->hang; diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index 38c66eb..c9f4deb 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -123,6 +123,10 @@ typedef struct { float hang; /* feet this high while hanging on before the pull up */ float face; /* how far ahead of where it started the face of it is (m) */ Vec3 ankle0[2], toe0[2]; /* where the feet were when it started (eased from there) */ + bool sit_way; /* the careful way up something hip high: turn round, sit on it, legs up, stand up ... */ + bool sit_now; /* ... sitting on it right now (the body sits: see world.c) ... */ + float yaw0; /* ... facing the ledge when it started (rotation.y) */ + float swing; /* ... which way round the legs come up (+1 / -1) */ } ClimbMove; typedef struct Object { diff --git a/entropie/src/world/world.c b/entropie/src/world/world.c index f462d95..22e59f9 100644 --- a/entropie/src/world/world.c +++ b/entropie/src/world/world.c @@ -885,11 +885,12 @@ static void animateCharacter(World *world, Object *o, float dt) { } Object_leaveSeat(o, dt); o->body.stand_ahead = o->sitting && o->seat ? 0.12f : 0.0f; /* (feet clear of it) */ - o->body.on_ladder = o->on_ladder != NULL || o->climbing; /* (or pulling up over a ledge) */ - o->body.pulling_up = o->climbing && o->on_ladder == NULL; + const bool sit_climb = o->climbing && o->climb_move.sit_way; /* (the careful way up: sitting on it, not pulling up) */ + o->body.on_ladder = o->on_ladder != NULL || (o->climbing && !sit_climb); /* (or pulling up over a ledge) */ + o->body.pulling_up = o->climbing && o->on_ladder == NULL && !sit_climb; o->body.fitness = o->fitness; o->body.sulk = o->ai.annoyed; - o->body.sit_goal = o->sitting && !o->is_held && !settling ? 1.0f : 0.0f; /* cross-legged, or on a seat */ + o->body.sit_goal = (o->sitting && !o->is_held && !settling) || (sit_climb && o->climb_move.sit_now) ? 1.0f : 0.0f; /* cross-legged, or on a seat */ o->body.squat_pee = o->female && !(o->urinella && o->urinellas > 0) && !o->toilet; o->body.urinella_use = o->female && !o->body.squat_pee && !o->toilet; o->body.sit_style = o->sit_style;