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.74.0: no legs through the dress; Urinella pack and disposal
- Fix: legs showed through a skirt or dress standing normally; the thighs under it are cloth now and it's wider over the hips - Mila's Urinellas come in a pack of 3 (then she squats); now and then a mishap (on the shoes); used ones go into the bag, are dropped or flung away (drunk) as trash Includes 1.73.0 (if not committed separately): - Clothes: trousers, shorts, skirt, dress; squatting to pee trousers come down, a skirt or dress is gathered up Includes 1.72.0 (if not committed separately): - Fix: walking off the other way from something half stepped over left one foot planted behind, sliding along Includes 1.71.0 (if not committed separately): - Two-handed fidgets: rubbing the hands, hands behind the head, both hands on the hips Includes 1.70.0 (if not committed separately): - More one-hand gestures (neck, nose, ear, hair, thumb in the belt, hand on the chest, shading the eyes); mood and personal habits pick them Includes 1.69.0 (if not committed separately): - Faster with a crowd: 750 people 22 -> 14 ms a frame (kind index, cell grid for company, no foot checks far from you) Includes 1.68.0 (if not committed separately): - The walking map is updated in place when fixed things change (0.3 ms instead of 10 ms) Includes 1.67.0 (if not committed separately): - Pour your drink on the fire (C): a small fire goes out, a big one hisses, vodka flares up Includes 1.66.0 (if not committed separately): - Careful people sort the woodpile by length (front even) and put the branches lying about onto a heap at the end of the woodpile Includes 1.65.0 (if not committed separately): - Smooth off the ladder (a step back, one foot after the other) and taking it down (the hand reaches for the rail at chest height) Includes 1.64.0 (if not committed separately): - Smooth ladder and climbs: getting on, over the edge at the top, feet from where they are; the easy 1 m climb no longer drops you off again Includes 1.63.0 (if not committed separately): - The hose melts in the fire (leaks, burns through); duct tape and the shears mend it Includes 1.62.0 (if not committed separately): - Smooth pull-ups: no hop at the end, feet and knees ease over the edge, elbows and hands taking hold blend in (audit walk: joint jumps 161 -> 58) Includes 1.61.0 (if not committed separately): - A step ladder in the tool room: stands on its own, at a wall with its back to it; climb onto the wall from its top Includes 1.60.0 (if not committed separately): - A folding ladder (two 2.5 m halves on a hinge, 5 m open) beside the telescopic one; one click at a wall unfolds it and leans it there Includes 1.59.0 (if not committed separately): - Stepping up onto blocks above knee high; set moves and jumps only for things standing on the ground in front of you Includes 1.58.0 (if not committed separately): - Walking over knee-high things is one smooth set move that always finishes; at a run: jump up onto blocks, catch climbable edges
entropie/Makefile | 2 +- entropie/README.md | 6 ++++-- entropie/STATE.md | 7 ++++--- entropie/assets/shaders/figure.frag | 9 +++++---- entropie/commit_message.txt | 16 ++++++++++------ entropie/src/game/game_dev.c | 4 ++-- entropie/src/people/ai.c | 2 +- entropie/src/world/object.c | 2 +- entropie/src/world/object.h | 5 ++++- entropie/src/world/scene.c | 1 + entropie/src/world/world.c | 37 ++++++++++++++++++++++++++++++++++++- 11 files changed, 69 insertions(+), 22 deletions(-) diff --git a/entropie/Makefile b/entropie/Makefile index 3f02923..9b20a4c 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 1.73.0 +VERSION := 1.74.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/README.md b/entropie/README.md index 3a6691e..5277aa2 100644 --- a/entropie/README.md +++ b/entropie/README.md @@ -417,8 +417,10 @@ say no more often and don't come to you for a bit. Aim with the mouse, hold Shift to push harder (further, quicker done). Next to the toilet (the blue cabin by the barn) P takes you inside; the others use it too when it's not too far, and wait if it's occupied -- Women squat to pee, unless they have a Urinella (Mila does). Squatting, - trousers come down to the knees, a skirt or dress is gathered up +- Women squat to pee, unless they have a Urinella (Mila has a pack of 3). + Squatting, trousers come down to the knees, a skirt or dress is gathered up. + A used Urinella goes into the bag (tidy), is dropped (careless) or flung + away (drunk); now and then it ends up on the shoes - Clothes: trousers, shorts (Jonas), a skirt (Ida) or a dress (Mila) - The others use the toilet when it's free and not too far; busy (they wait a while, less when it's urgent) or far: a decently hidden spot behind a diff --git a/entropie/STATE.md b/entropie/STATE.md index 5cb3004..d2e8229 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -67,7 +67,8 @@ Talk topics: offer, ask, suggest, where (new woodpile spot), ask for a hand, ask - **Poses**: up, falling, lying down to sleep, down, getting up; sitting on a seat or cross-legged on the ground. Lying down (or falling) before ever having faced anywhere (asleep or passed out right where they stood): back, as usual (it collapsed into a heap "sitting over the floor") - **Fidgets** (standing about): shake a leg, rock on the toes, stretch, roll shoulders, stretch the neck, fold arms, tap a foot; two-handed: rubbing the hands (nervous), hands behind the head (at ease, proud, lively), both hands on the hips (proud) - **Gestures** (one hand, idle; `body.c` picks, `body_pose.c` gesturePalm): hip, scratching the head, chin, pocket, rubbing the neck, rubbing the nose, earlobe, back through the hair, thumb in the belt, hand on the chest, shading the eyes. Weighted by mood: proud (hip, hair, thumb), shy (pocket, neck, ear, chest), nervous (head, chin, nose, ear), tired (neck), lively (hair, shading). Everyone has two habits of their own (`habit`, x3 and x2) -- **Clothes** (`FigureLook.garment`, drawn in `figure.frag`): trousers, shorts (bare shins), a skirt (pants colour) or a dress (shirt colour): a cone from the waist to just below the knees, wider as the knees part; under it bare legs. Squatting to pee (`Skeleton.undress`, from the pee and the crouch): trousers down to the knees (hips and thighs bare, the trousers bunched round the shins), a skirt or dress gathered up to the hips. Cast: You and Ben trousers, Jonas shorts, Ida a skirt, Mila a dress +- **Clothes** (`FigureLook.garment`, drawn in `figure.frag`): trousers, shorts (bare shins), a skirt (pants colour) or a dress (shirt colour): a cone from the waist to just below the knees, wider as the knees part; under it bare legs. Squatting to pee (`Skeleton.undress`, from the pee and the crouch): trousers down to the knees (hips and thighs bare, the trousers bunched round the shins), a skirt or dress gathered up to the hips. Cast: You and Ben trousers, Jonas shorts, Ida a skirt, Mila a dress Under a skirt or dress the thighs are cloth too (a leg pressing out shows as cloth, not leg through it), the cone 0.165 m round at the top. +- **Urinella** (`world.c` usedUrinella, when she's done): a pack of 3 (`urinellas`; none left: she squats). Mishap now and then (4 % + 25 % drunk + 12 % clumsy: on the shoes, dirtier). Then tidy (into the bag: 75 % - 60 % drunk - 25 % clumsy + 10 % pride), else dropped at her feet or flung (more often the drunker) as trash ("Used Urinella") - **Face**: mouth, eyelids, brows, smile, gaze; drunk, tired, shy, proud show in it - **Falls**: straight over, knees first, twisting, diving forward; reeling back first; stumbles over the foot that caught - **Where a fall lands**: the way it was going if there's room, else turned aside or shorter (crumpling at the foot of a wall); lies across things up to 0.5 m high, never into or over higher ones; no part of the body goes into what it comes down on (lifted onto it, limbs refitted); sitting, the legs rest on what lies in front; the lift eases in and out (5 m/s), no jumps @@ -150,7 +151,7 @@ Most important first. - More gestures and feelings to pick personalities from: the lists in Body / Fidgets and Gestures can grow **People** -- Peeing, still to do: open the fly standing; Urinella (some don't like it; mishaps; tidy, careless or high disposal) +- Peeing, still to do: open the fly standing; some women don't like the Urinella - Clothing, still to do: more outfits for extra people (they all wear trousers), jackets at night **Tools for us** @@ -160,4 +161,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.73.0 (build 79fb1fb)` +State of `entropie 1.74.0 (build 6c0e954)` diff --git a/entropie/assets/shaders/figure.frag b/entropie/assets/shaders/figure.frag index 5759dca..5948b73 100644 --- a/entropie/assets/shaders/figure.frag +++ b/entropie/assets/shaders/figure.frag @@ -99,7 +99,8 @@ void buildBody() { bool down = undress > 0.5; int lower = garment == 3 ? M_SHIRT : M_PANTS; int hips = (garment == 0 && down) ? M_SKIN : lower; - int thigh = (garment == 0 && !down) || garment == 1 ? M_PANTS : M_SKIN; + // (under a skirt or dress the thighs wear it too: where a leg presses out, it's cloth, not leg) + int thigh = garment >= 2 ? (down ? M_SKIN : lower) : (garment == 0 && !down) || garment == 1 ? M_PANTS : M_SKIN; int shin = garment == 0 ? M_PANTS : M_SKIN; // Pelvis spans the hips, so the thighs grow out of it @@ -110,9 +111,9 @@ void buildBody() { if (garment >= 2) { vec3 knees = 0.5 * (joints[J_KNEE_L] + joints[J_KNEE_R]); vec3 top = pelvis + spineDir * 0.07; - vec3 hem = mix(knees + vec3(0.0, -0.04, 0.0), top, 0.6 * undress); - float wide = 0.5 * length(joints[J_KNEE_L] - joints[J_KNEE_R]) + 0.075; - addPart(top, hem, 0.135, max(wide, 0.15), 0.03, 0.85, lower); + vec3 hem = mix(knees + vec3(0.0, -0.06, 0.0), top, 0.6 * undress); + float wide = 0.5 * length(joints[J_KNEE_L] - joints[J_KNEE_R]) + 0.08; + addPart(top, hem, 0.165, max(wide, 0.165), 0.03, 0.8, lower); // (over the hips and thighs, wider as the knees part) } // Legs and feet diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt index 8d7b7fb..769d497 100644 --- a/entropie/commit_message.txt +++ b/entropie/commit_message.txt @@ -1,10 +1,14 @@ -entropie 1.73.0: clothes - trousers, shorts, skirt, dress +entropie 1.74.0: no legs through the dress; Urinella pack and disposal -- People wear trousers, shorts (Jonas), a skirt (Ida) or a dress (Mila); - skirts and dresses are a cone from the waist to the knees that widens - as the knees part, bare legs under them -- Squatting to pee: trousers come down to the knees, a skirt or dress is - gathered up to the hips +- Fix: legs showed through a skirt or dress standing normally; the thighs + under it are cloth now and it's wider over the hips +- Mila's Urinellas come in a pack of 3 (then she squats); now and then a + mishap (on the shoes); used ones go into the bag, are dropped or flung + away (drunk) as trash + +Includes 1.73.0 (if not committed separately): +- Clothes: trousers, shorts, skirt, dress; squatting to pee trousers come + down, a skirt or dress is gathered up Includes 1.72.0 (if not committed separately): - Fix: walking off the other way from something half stepped over left diff --git a/entropie/src/game/game_dev.c b/entropie/src/game/game_dev.c index 05fa510..8432f63 100644 --- a/entropie/src/game/game_dev.c +++ b/entropie/src/game/game_dev.c @@ -82,7 +82,7 @@ void game_dev(Game *game, const Input *input) { } switch ((DevRow)row) { case DEV_FEMALE: o->female = !o->female; break; - case DEV_URINELLA: o->urinella = !o->urinella; break; + case DEV_URINELLA: o->urinella = !o->urinella; o->urinellas = o->urinella ? URINELLA_PACK : 0; break; case DEV_SPORTY: setFitness(o, step01(o->fitness, dir, 0.05f)); break; case DEV_DRUNK: o->drunk = fminf(1.5f, fmaxf(0.0f, o->drunk + (float)dir * 0.1f)); break; case DEV_ENERGY: n->stamina = step01(n->stamina, dir, 0.1f); break; @@ -116,7 +116,7 @@ static void devLine(const Object *o, int row, char *out) { switch ((DevRow)row) { case DEV_WHO: snprintf(out, 96, "Who: %s%s", o->name, o->type == OBJ_PLAYER ? " (you)" : ""); break; case DEV_FEMALE: snprintf(out, 96, "Female: %s", o->female ? "yes" : "no"); break; - case DEV_URINELLA: snprintf(out, 96, "Urinella: %s", o->urinella ? "yes" : "no"); break; + case DEV_URINELLA: snprintf(out, 96, "Urinella: %s (%d left)", o->urinella ? "yes" : "no", o->urinellas); break; case DEV_SPORTY: snprintf(out, 96, "Sporty: %.2f", o->fitness); break; case DEV_DRUNK: snprintf(out, 96, "Drunk: %.1f", o->drunk); break; case DEV_ENERGY: snprintf(out, 96, "Energy: %.0f%%", n->stamina * 100.0f); break; diff --git a/entropie/src/people/ai.c b/entropie/src/people/ai.c index 0c347ac..ab22fb5 100644 --- a/entropie/src/people/ai.c +++ b/entropie/src/people/ai.c @@ -710,7 +710,7 @@ static void updatePee(Object *self, Object *const *objects, int count, float dt) } if (dist < ARRIVE_DISTANCE * 2.0f || (!toilet && isStuck(ai, dist, dt))) { stand(self); - bool squat = self->female && !self->urinella; + bool squat = self->female && !(self->urinella && self->urinellas > 0); self->body.pee_aim = vec3_zero(); if (ai->pee_hidden && dist < 1.5f) { /* face it (or squat with the back to it), aim at its foot */ Vec3 to = vec3(ai->pee_cover.x - self->position.x, 0.0f, ai->pee_cover.z - self->position.z); diff --git a/entropie/src/world/object.c b/entropie/src/world/object.c index 23bf799..baf0186 100644 --- a/entropie/src/world/object.c +++ b/entropie/src/world/object.c @@ -989,7 +989,7 @@ void Object_describe(const Object *obj, char *out, size_t size) { case OBJ_TRASH: { static const char *const WHAT[] = { [PALETTE_STANDARD] = "Plastic bottle", [PALETTE_GROUND] = "Broken board", [PALETTE_MODERN] = "Empty can", [PALETTE_WARM] = "Paper" }; - snprintf(out, size, "%s - trash", WHAT[obj->variant & 3]); + snprintf(out, size, "%s - trash", obj->name[0] ? obj->name : WHAT[obj->variant & 3]); break; } case OBJ_BAG: diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index c0b90ad..49ee372 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -97,6 +97,8 @@ typedef struct { #define OBJECT_MAX_COLLIDERS 3 +#define URINELLA_PACK 3 /* disposable Urinellas in a pack */ + typedef struct Object { ObjectType type; Vec3 position; /* base point (bottom center) */ @@ -162,7 +164,8 @@ typedef struct Object { bool spraying; /* characters: watering (hose or can) this frame */ float pour; /* characters: 0 = can hanging .. 1 = lifted and tipped, pouring */ bool female; /* characters: squats to pee, unless ... */ - bool urinella; /* ... she has one of these */ + bool urinella; /* ... she has one of these (a pack of them) ... */ + int urinellas; /* ... fresh ones left (none left: she squats like the others) */ float dirt; /* characters: 0 = clean .. 1 = filthy (peeing outdoors, lying in the dirt) */ int scrapes; /* characters: shins and knees scraped on things (too fast, or clumsy) */ float scrape_cool; /* (seconds before the next one counts) */ diff --git a/entropie/src/world/scene.c b/entropie/src/world/scene.c index 48f1059..1664f23 100644 --- a/entropie/src/world/scene.c +++ b/entropie/src/world/scene.c @@ -135,6 +135,7 @@ Object *Scene_load(World *world) { obj->ai.character = CHARACTERS[characters % TEMPERAMENT_COUNT]; obj->female = FEMALE[characters % TEMPERAMENT_COUNT]; obj->urinella = URINELLA[characters % TEMPERAMENT_COUNT]; + obj->urinellas = obj->urinella ? URINELLA_PACK : 0; for (int k = 0; k < ORDER_COUNT; k++) obj->skill[k] = obj->ai.character.skill[k]; obj->tempo = obj->ai.character.tempo; characters++; diff --git a/entropie/src/world/world.c b/entropie/src/world/world.c index 4883aaa..ae15944 100644 --- a/entropie/src/world/world.c +++ b/entropie/src/world/world.c @@ -7,6 +7,7 @@ #include "world/site.h" #include "world/physics.h" +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -179,6 +180,39 @@ static void spawnSick(World *world, const Object *o) { if (stink && World_add(world, stink)) sick->stink = stink; } +/* Done with a disposable Urinella: now and then it goes wrong (drunk, clumsy: + on the shoes); then it's wrapped up and into the bag (the tidy), dropped + where she stands (the careless) or flung away (drunk and wild). */ +static float worldDice(World *world) { + world->rng = world->rng * 1103515245u + 12345u; + return (float)((world->rng >> 8) & 0xFFFFu) / 65536.0f; +} + +static void usedUrinella(World *world, Object *o) { + o->urinellas--; + const float drunk = fminf(o->drunk, 1.0f), clumsy = Body_clumsiness(&o->body); + const bool talks = o->type == OBJ_HUMAN; + if (worldDice(world) < 0.04f + 0.25f * drunk + 0.12f * clumsy) { + o->dirt = fminf(1.0f, o->dirt + 0.12f); + if (talks) Ai_say(o, "Oops... that went on my shoes."); + } + float tidy = 0.75f - 0.6f * drunk - 0.25f * clumsy + 0.1f * o->temperament.pride; + float r = worldDice(world); + if (r < tidy) { + if (talks && o->urinellas == 0) Ai_say(o, "That was my last Urinella."); + return; /* (wrapped up, into the bag: binned later) */ + } + Vec3 f = Object_facing(o); + bool fling = r > tidy + (1.0f - tidy) * (0.7f - 0.5f * drunk); /* (the wilder, the likelier it flies) */ + Vec3 at = vec3_add(o->position, vec3_add(vec3_scale(f, fling ? 0.3f : 0.15f), vec3(0.0f, fling ? 1.2f : 0.5f, 0.0f))); + Object *used = Object_create(OBJ_TRASH, PALETTE_STANDARD, at, vec3_zero(), 0.03f); + if (!used) return; + snprintf(used->name, sizeof(used->name), "Used Urinella"); + if (fling) used->velocity = vec3_add(vec3_scale(f, 3.0f + 2.0f * worldDice(world)), vec3(0.0f, 4.0f, 0.0f)); /* (up and away) */ + if (!World_add(world, used)) { Object_destroy(used); return; } + if (talks) Ai_say(o, fling ? "Wheee - away with it!" : o->urinellas == 0 ? "That was my last one." : "Whatever..."); +} + /* Done peeing (it went into the ground while it ran: see animateCharacter). Where most of it came down, the smell rises (one smell for a spot). In a toilet: nothing, and out again. */ @@ -194,6 +228,7 @@ static void spawnPee(World *world, Object *o) { return; } bool squat = o->body.squat_pee; + if (!squat && o->female && o->urinella && o->urinellas > 0) usedUrinella(world, o); Vec3 at = squat || vec3_length(vec3_sub(o->pee_hit, o->position)) > 4.0f ? vec3_add(o->position, vec3_scale(Object_facing(o), squat ? -0.05f : 0.4f)) : o->pee_hit; o->dirt = fminf(1.0f, o->dirt + (squat ? 0.15f : 0.06f)); @@ -560,7 +595,7 @@ static void animateCharacter(World *world, Object *o, float dt) { 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.squat_pee = o->female && !o->urinella && !o->toilet; + o->body.squat_pee = o->female && !(o->urinella && o->urinellas > 0) && !o->toilet; o->body.sit_style = o->sit_style; BodyFrame frame = { .position = o->position,