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 1.98.0: people step up onto blocks and crates
- People step up onto a long block, crate or log in their way instead of always walking round: the sporty and fresh up to about hip height, the unfit, worn out or drunk only about knee high - Stepping over or onto something long at a slant starts at its face, not a metre early in mid-air (for you too)
entropie/Makefile | 2 +- entropie/README.md | 6 ++++-- entropie/STATE.md | 8 ++++++-- entropie/commit_message.txt | 12 ++++++------ entropie/src/people/ai.c | 24 ++++++++++++++++-------- entropie/src/world/object.c | 7 +++++++ entropie/src/world/object.h | 3 +++ entropie/src/world/physics.c | 14 +++++++++++++- 8 files changed, 56 insertions(+), 20 deletions(-) diff --git a/entropie/Makefile b/entropie/Makefile index 549e3b1..c9c7b4b 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 1.97.0 +VERSION := 1.98.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/README.md b/entropie/README.md index 15dad1c..e68e1ac 100644 --- a/entropie/README.md +++ b/entropie/README.md @@ -187,8 +187,10 @@ and satellite pictures (about 340 x 340 m). clumsy, drunk or hurrying), slower steps - and now and then a step off - Something you can't step over or onto (a tree, a post, a high crate, a wall's corner) that you'd only just catch: your body drifts past it to the side -- The others do it too: a long log across the way they step onto and walk on - (and wobble), shorter things they walk round +- The others do it too: a long log or block across the way they step onto and + walk on (and wobble), shorter things they walk round. How high they step up + is their own: the sporty and fresh up to about hip height, the unfit, worn + out or drunk only knee high - higher than that they go round - Off the edge of something you go once your middle is past it - no standing on air beside it; slopes (a roof, the ramp) no longer show invisible steps - The sporty fit their steps to what's coming, so a foot lands at a good diff --git a/entropie/STATE.md b/entropie/STATE.md index a194c05..47de684 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -138,6 +138,10 @@ Round 1.97: - Jacket off and with them (`jacket_hung` false, top not TOP_JACKET): `FigureLook.jacket_tied` (set in `world.c` dressForNight) -> `jacketTied` in figure.frag: a band over the hips, a knot in front with the two sleeve ends hanging (over a skirt's top), the rest hanging flat down the back. MAX_PARTS 31 -> 35 (and addPart stops at it). - Back on the rack (`ai.c` hangJacket): idle or wandering, warm (chill under 0.05), the rack within RACK_WALK 60 m: RACK_CHANCE 0.004/s x tidiness (0.5 + liking for clearing up - 0.4 drunk); there (`goTo` 0.6 m) a hand to it, `jacket_hung`. Gives up after JACKET_GIVE_UP or when getting cold again. +Round 1.98: +- NPCs step up onto higher things (`object.c` Object_stepUpMost: (0.38 + 0.37 fitness) x (0.75 + 0.25 vigor) - 0.25 drunk, 0.25-0.75 m scaled; the player 0.75). `ai.c` longToStepOnto: static things too (not a building's parts), 1.5 m long or more; up to ONTO_HIGH 0.55 anything, higher up to their own most if at least ONTO_DEEP 0.5 m deep. `physics.c` startStepOver: the "higher" step up for NPCs as high as Object_stepUpMost (it was the player only). +- Step over / onto: where the way meets the thing's near and far face from a ray (`Collider_ray`) instead of its projected radius - at a slant a long thing's corner made the step start 1 m early and land in the air before it. + 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); the coat rack (FURN_COATRACK, in your kitchen by the doors, garage coords 20.6 / 2.4) shows the jackets hanging on it (`Shapes_coatRack`, up to 6, a bitmask of whose in `shown`). `jacket_hung` (characters, true at the start): cold (chill 0.6+) and the jacket with them: on it goes (as before); hanging: NPCs `ai.want_jacket` -> `ai.c` fetchJacket (idle / wander: goTo the rack, on with it, "Ah, better."; gives up after 90 s or warm again); you are told once ("your jacket hangs on the rack in your garage") and click the rack (`game_actions.c` coatRack: on, or back onto it). Warm again: it comes off and stays with them. @@ -270,7 +274,7 @@ Most important first. - Joint jumps left in the audit: jog+stop 171, sprint 297 (worst 26 cm) - running into things: a hurried catch step swings through in a few frames (step 0.07 -> 0.34, the ankle up 20 cm). Capping the swing speed helped sprint (278) but made jumps, drunk walk and the NPCs worse - tried and reverted in 1.83; ladder 45: toes on the sloping roof (a landing step's toes snap onto the slope, 16 cm; blending them in made all walking worse), toes turning onto the rungs getting on from the top (14 cm) **Body and moving** -- Obstacle approach, still to do: NPCs stepping up onto higher things (now only what they'd stride over anyway); 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 +- 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: hands first (one reaches first, shoulder ahead), a knee up, the other foot next to it; or sit on it and lift the legs; or belly first and roll; by height, surface and person - 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) @@ -290,4 +294,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 1.97.0 (build 51512aa)` +State of `entropie 1.98.0 (build f761dd4)` diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt index 5433932..35ae27f 100644 --- a/entropie/commit_message.txt +++ b/entropie/commit_message.txt @@ -1,7 +1,7 @@ -entropie 1.97.0: jackets tied round the waist, back onto the rack +entropie 1.98.0: people step up onto blocks and crates -- A jacket taken off (by the fire, in the morning) is tied round the waist - by its sleeves: a band over the hips, the knot in front, the rest hanging - down the back -- Warm again, people take it back to the coat rack sooner or later (the - tidy sooner, the drunk later) +- People step up onto a long block, crate or log in their way instead of + always walking round: the sporty and fresh up to about hip height, the + unfit, worn out or drunk only about knee high +- Stepping over or onto something long at a slant starts at its face, not + a metre early in mid-air (for you too) diff --git a/entropie/src/people/ai.c b/entropie/src/people/ai.c index a365285..d844454 100644 --- a/entropie/src/people/ai.c +++ b/entropie/src/people/ai.c @@ -93,21 +93,29 @@ void Ai_useGrid(struct Grid *grid) { g_grid = grid; } struct World *g_world; void Ai_useWorld(struct World *world) { g_world = world; } -/* Something solid lying across the way, long (going round is a detour) and low - enough to step onto: people step up onto it and on (see physics: startStepOver). */ +/* Something solid in the way, long (going round is a detour) and low enough to + step onto: people step up onto it and on (see physics: startStepOver). Up to + ONTO_HIGH anything (they'd stride over it anyway); higher, as high as they go + up (Object_stepUpMost), if it's deep enough to land on (ONTO_DEEP). */ #define ONTO_LONG 1.5f /* m along at least */ -#define ONTO_HIGH 0.55f /* m above the feet at most (what they would stride over anyway) */ +#define ONTO_HIGH 0.55f /* m above the feet: what they would stride over anyway */ +#define ONTO_DEEP 0.5f /* m across at least, to step up onto it when higher */ static bool longToStepOnto(const Object *self, const Object *o) { - if (o->is_static || o->is_held || o->is_character || o->collider_count == 0 || !Physics_standsOn(o)) return false; + if (o->type == OBJ_WALL || o->is_held || o->is_character || o->collider_count == 0 || !Physics_standsOn(o)) return false; /* (a building's steps: see the stairs) */ const Collider *c = &o->colliders[0]; - float top = Object_colliderCenter(o, 0).y, longest = 0.0f; + float top = Object_colliderCenter(o, 0).y, longest = 0.0f, shortest = 1e9f; const float half[3] = { c->half_extents.x, c->half_extents.y, c->half_extents.z }; for (int k = 0; k < 3; k++) { top += fabsf(c->axes[k].y) * half[k]; - longest = fmaxf(longest, 2.0f * half[k] * sqrtf(c->axes[k].x * c->axes[k].x + c->axes[k].z * c->axes[k].z)); - } - return longest >= ONTO_LONG && top - self->position.y <= ONTO_HIGH; + if (fabsf(c->axes[k].y) > 0.95f) continue; /* (the upright one) */ + float flat = 2.0f * half[k] * sqrtf(c->axes[k].x * c->axes[k].x + c->axes[k].z * c->axes[k].z); + longest = fmaxf(longest, flat); + shortest = fminf(shortest, flat); + } + float high = top - self->position.y; + if (longest < ONTO_LONG) return false; + return high <= ONTO_HIGH || (high <= Object_stepUpMost(self) && shortest >= ONTO_DEEP * self->look.height / 1.75f); } #define WALL_RADIUS 0.24f /* m kept from a building's walls (a doorway 0.9 m wide leaves 0.4 m to aim through) */ diff --git a/entropie/src/world/object.c b/entropie/src/world/object.c index 40a3b07..f7019fc 100644 --- a/entropie/src/world/object.c +++ b/entropie/src/world/object.c @@ -584,6 +584,13 @@ float Object_vigor(const Object *obj) { return (0.5f + 0.5f * fminf(obj->needs.stamina / 0.3f, 1.0f)) * (1.0f - 0.25f * Object_tiredness(obj)); } +float Object_stepUpMost(const Object *obj) { + const float s = obj->look.height / 1.75f; + if (obj->type == OBJ_PLAYER) return 0.75f * s; /* (you decide yourself: as high as anyone, see physics.c STEP_UP_MOST) */ + float most = (0.38f + 0.37f * obj->fitness) * (0.75f + 0.25f * Object_vigor(obj)) - 0.25f * fminf(obj->drunk, 1.0f); + return clampf(most, 0.25f, 0.75f) * s; +} + float Object_topSpeed(const Object *obj) { return obj->top_speed * Object_vigor(obj) * (1.0f - 0.35f * fminf(obj->drunk, 1.0f)); } diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index 1384d44..d60bf79 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -367,6 +367,9 @@ float Object_caution(const Object *obj); /* Characters: 1 when fresh, down to 0.5 when exhausted (speed, strength, work). */ float Object_vigor(const Object *obj); +/* How high (m) someone walks up onto something solid (a block, a crate): the sporty + and fresh higher, the unfit, worn out or drunk lower; higher than that they go round. */ +float Object_stepUpMost(const Object *obj); /* Worn down by the day (sleepiness, felt by personality, fitness and drink): 0 fresh .. 1 done in. */ float Object_tiredness(const Object *obj); /* Characters: how fast they can sprint and jump right now (tired or drunk: less). */ diff --git a/entropie/src/world/physics.c b/entropie/src/world/physics.c index 6c26d60..b15effe 100644 --- a/entropie/src/world/physics.c +++ b/entropie/src/world/physics.c @@ -921,11 +921,23 @@ static bool startStepOver(Object *obj, Object *const *objects, int count, const float ahead = vec3_dot(rel, dir), beside = fabsf(rel.x * -dir.z + rel.z * dir.x); float top = Object_colliderCenter(o, 0).y + projectRadius(c, WORLD_UP) - obj->position.y; float near = ahead - reach, far = ahead + reach; + { /* (straight at a long thing at a slant: its faces where the way goes in and out, not its corners) */ + Vec3 from = vec3(obj->position.x, obj->position.y + fminf(0.5f * top, 0.2f * s), obj->position.z), center = Object_colliderCenter(o, 0); + float in = Collider_ray(c, center, from, dir, NULL); + if (in >= 0.0f) { + float back = Collider_ray(c, center, vec3_add(from, vec3_scale(dir, in + 20.0f)), vec3_scale(dir, -1.0f), NULL); + if (back >= 0.0f) { + near = in; + far = in + 20.0f - back; + reach = 0.5f * (far - near); + } + } + } /* up onto it: higher than a stride over, or something solid you can just as well stand on (a log, a crate) - no straddling then, you stand up there and walk on (nobody walks up onto tables) */ const bool you = obj->type == OBJ_PLAYER, person = you || obj->type == OBJ_HUMAN; bool up = person && standsOn(o) && top <= STEP_UP_MOST * s && side >= 0.12f * s && /* (a log end-on: a narrow step) */ - ((you && !over && top > STEP_OVER_HEIGHT * s && 2.0f * reach >= STEP_UP_ROOM * s) || /* (higher: only you - the others walk round) */ + (((you || top <= Object_stepUpMost(obj)) && !over && top > STEP_OVER_HEIGHT * s && 2.0f * reach >= STEP_UP_ROOM * s) || /* (higher: as high as they go up; else they walk round) */ (top >= STAND_LOWEST * s && 2.0f * reach >= STAND_ROOM * s && (you || top <= STEP_OVER_HEIGHT * 1.15f * s))); if (up) over = false; if (!over && !up) continue;