Nimbin[12]?Games / Entropie / entropie/src/world/guests.c

Entropie git · main

Entropie festival game; first steps

sdl c game entropie cmake · first commit 2026-10-10 · last commit 2026-11-02 (18 hours ago) · synced 10 hours ago

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.gz
entropie/src/world/guests.c 5.4 KB · 97 lines raw
#include "world/guests.h"
#include "world/cast.h"
#include "render/figure.h"

#include <math.h>
#include <stdio.h>

static const char *const WOMEN[] = { "Lena", "Mia", "Hanna", "Sophie", "Lea", "Marie", "Nele", "Clara", "Ida", "Frieda",
                                     "Paula", "Greta", "Emma", "Luisa", "Merle", "Ronja", "Alma", "Jule" };
static const char *const MEN[]   = { "Jonas", "Felix", "Paul", "Ben", "Lukas", "Moritz", "Finn", "Emil", "Theo", "Anton",
                                     "Jakob", "Niklas", "Ole", "Malte", "Hannes", "Bruno", "Leon", "Max" };
#define COUNTOF(a) ((int)(sizeof(a) / sizeof((a)[0])))

static unsigned mix(unsigned h) {
    h ^= h >> 16; h *= 0x7feb352du; h ^= h >> 15; h *= 0x846ca68bu; h ^= h >> 16;
    return h;
}
/* 0..1, the same for the same guest and question */
static float dice(int k, unsigned q) { return (float)(mix((unsigned)k * 7919u + q * 104729u) & 0xffffu) / 65535.0f; }
static Vec3 pick(const Vec3 *from, int n, float d) { return from[(int)(d * (float)n) % n]; }

static const Vec3 SKINS[]  = { { 0.96f, 0.80f, 0.68f }, { 0.92f, 0.74f, 0.60f }, { 0.86f, 0.66f, 0.50f }, { 0.72f, 0.52f, 0.38f },
                               { 0.56f, 0.38f, 0.26f }, { 0.40f, 0.27f, 0.19f } };
static const Vec3 HAIRS[]  = { { 0.12f, 0.10f, 0.10f }, { 0.30f, 0.19f, 0.12f }, { 0.55f, 0.38f, 0.22f }, { 0.80f, 0.66f, 0.40f },
                               { 0.70f, 0.30f, 0.16f }, { 0.20f, 0.45f, 0.55f }, { 0.75f, 0.35f, 0.60f } };
static const Vec3 SHIRTS[] = { { 0.88f, 0.86f, 0.80f }, { 0.12f, 0.12f, 0.14f }, { 0.86f, 0.30f, 0.30f }, { 0.25f, 0.45f, 0.75f },
                               { 0.95f, 0.70f, 0.20f }, { 0.40f, 0.65f, 0.40f }, { 0.65f, 0.40f, 0.75f }, { 0.95f, 0.55f, 0.65f },
                               { 0.20f, 0.70f, 0.70f } };
static const Vec3 PANTS[]  = { { 0.22f, 0.26f, 0.40f }, { 0.15f, 0.15f, 0.16f }, { 0.50f, 0.44f, 0.34f }, { 0.35f, 0.38f, 0.30f },
                               { 0.60f, 0.25f, 0.30f }, { 0.75f, 0.72f, 0.65f } };

int Guest_mate(int k) { return k % 2 ? k + 1 : k - 1; }

Object *Guest_create(int k, Vec3 at) {
    bool female = dice(k, 1) < 0.5f;
    float kg = female ? 55.0f + 20.0f * dice(k, 2) : 68.0f + 25.0f * dice(k, 2);
    Object *o = Object_create(OBJ_HUMAN, PALETTE_MODERN, at, vec3(0.5f, 1.75f, 0.25f), kg);
    if (!o) return NULL;
    o->guest = k;
    o->supporter = ((k - 1) / 2) % 4 == 0; /* (one pair in four: a free ticket for 2 x 6 h of work) */
    char name[32];
    snprintf(name, sizeof name, "%s", female ? WOMEN[(int)(dice(k, 3) * COUNTOF(WOMEN)) % COUNTOF(WOMEN)]
                                             : MEN[(int)(dice(k, 3) * COUNTOF(MEN)) % COUNTOF(MEN)]);
    Object_setPerson(o, name, dice(k, 4) < 0.12f ? HAND_LEFT : HAND_RIGHT);
    FigureLook worn = Figure_wardrobe(5 + k);
    o->look = worn;
    o->look.skin = pick(SKINS, COUNTOF(SKINS), dice(k, 5));
    o->look.hair = pick(HAIRS, COUNTOF(HAIRS), dice(k, 6) * (dice(k, 7) < 0.8f ? 0.57f : 1.0f)); /* (mostly natural) */
    o->look.shirt = pick(SHIRTS, COUNTOF(SHIRTS), dice(k, 8));
    o->look.pants = pick(PANTS, COUNTOF(PANTS), dice(k, 9));
    o->look.shoes = vec3(0.2f + 0.6f * dice(k, 10), 0.18f + 0.5f * dice(k, 10), 0.16f + 0.4f * dice(k, 11));
    o->look.height = female ? 1.58f + 0.17f * dice(k, 12) : 1.70f + 0.18f * dice(k, 12);
    o->look.hair_style = female ? (dice(k, 13) < 0.8f ? HAIR_LONG : HAIR_SHORT) : (dice(k, 13) < 0.2f ? HAIR_LONG : HAIR_SHORT);
    o->look.long_sleeves = dice(k, 14) < 0.3f;
    float g = dice(k, 15);
    o->look.garment = female ? (g < 0.3f ? GARMENT_SKIRT : g < 0.5f ? GARMENT_DRESS : g < 0.75f ? GARMENT_SHORTS : GARMENT_TROUSERS)
                             : (g < 0.45f ? GARMENT_SHORTS : GARMENT_TROUSERS);
    o->look.hat = dice(k, 16) < 0.2f ? HAT_CAP : dice(k, 16) < 0.28f ? HAT_BEANIE : HAT_NONE;
    o->look.hat_color = pick(SHIRTS, COUNTOF(SHIRTS), dice(k, 17));
    o->female = female;
    o->urinella = false;
    o->urinellas = 0;
    o->temperament.pride = dice(k, 18) - 0.5f;
    o->temperament.energy = 0.2f + 0.7f * dice(k, 19);  /* (festival people: lively) */
    o->temperament.nerves = 0.6f * dice(k, 20) - 0.3f;
    o->tolerance = 0.7f + 0.6f * dice(k, 21);
    o->fitness = 0.3f + 0.6f * dice(k, 22);
    o->wits = 0.4f + 0.4f * dice(k, 23);
    o->height_fear = 0.5f * dice(k, 24);
    o->smoker = dice(k, 25) < 0.4f ? 0.3f + 0.5f * dice(k, 26) : 0.0f;
    o->cigarettes = o->smoker > 0.0f ? 6 + (int)(14.0f * dice(k, 27)) : 0;
    o->lighter = o->smoker > 0.0f;
    o->craving = 0.3f;
    o->commitment = 0.0f;
    o->fun = 0.55f + 0.15f * dice(k, 28);
    o->like = 0.2f + 0.15f * dice(k, 40); /* (strangers to you) */
    o->love = 0.1f * dice(k, 41);
    o->ai.character.willing = 0.2f + 0.3f * dice(k, 29);
    o->ai.character.tempo = 1.0f;
    o->ai.character.ponder = 0.5f;
    o->tempo = 1.0f;
    for (int q = 0; q < ORDER_COUNT; q++) o->skill[q] = 0.2f + 0.3f * dice(k, 30 + (unsigned)q);
    Object_setHeight(o, o->look.height);
    o->pace = 1.0f + 0.12f * o->temperament.energy;
    return o;
}

/* Up on the meadow right of the strip of wood, below the lane to the chicken halls: three rows of six. */
Vec3 Guest_campSpot(int k) {
    int pair = ((k - 1) / 2) % GUEST_SPOTS;
    int col = pair % 6, row = pair / 6;
    return vec3(9.0f + 4.0f * (float)col + (row % 2 ? 1.3f : 0.0f), 0.0f, 86.0f + 3.8f * (float)row);
}

Vec3 Guest_campDoor(void) { return vec3(0.0f, 0.0f, -1.0f); }

Vec3 Guest_gate(void) { return vec3(63.0f, 0.0f, 89.5f); }