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

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/world.h 9.9 KB · 173 lines raw
#ifndef WORLD_WORLD_H
#define WORLD_WORLD_H

/* Owns all objects and the terrain; runs physics and draws them. */

#include <stdbool.h>

#include "world/object.h"
#include "world/terrain.h"
#include "render/renderer.h"
#include "world/hose.h"
#include "world/nav.h"
#include "world/chips.h"
#include "world/grid.h"

/* Sounds things make this frame (game/sound.c plays them, then empties the list):
   where, how loud (0..1), and for steps what's underfoot. */
typedef enum {
    NOISE_STEP,   /* a foot set down (surface: STEP_*) */
    NOISE_CHOP,   /* an axe into wood */
    NOISE_CLINK,  /* a bottle against a bottle (a crate) */
    NOISE_SMASH,  /* glass breaking */
    NOISE_THUD,   /* somebody (or something heavy) hitting the ground */
    NOISE_CRASH,  /* a tree coming down */
    NOISE_SNAP,   /* a dry branch breaking underfoot */
    NOISE_VOICE,  /* somebody saying something (surface: VOICE_* | syllables << 2) */
    NOISE_BARK,   /* Alice (surface: how many woofs) */
    NOISE_GULP,   /* a sip (surface 0), a bite (1) */
    NOISE_FLUSH,  /* the toilet */
    NOISE_RUSTLE, /* into a bush: leaves and twigs */
    NOISE_CREAK,  /* a gate opening or shutting */
    NOISE_SLAM,   /* a car door, the boot */
    NOISE_PANT,   /* Alice panting: one breath out and in (surface: breaths per 10 s) */
    NOISE_COUNT
} NoiseKind;
enum { STEP_GRASS, STEP_GRAVEL, STEP_HARD, STEP_EARTH, STEP_MUD, STEP_WOOD, STEP_WATER };
enum { VOICE_DEEP, VOICE_MAN, VOICE_WOMAN };
typedef struct { NoiseKind kind; Vec3 at; float loud; int surface; } Noise;
#define WORLD_NOISES 96

#define WORLD_CASH 1200.0f /* € in the cash box at the start */
#define WORLD_FIELD_CELLS 520 /* the Kartoffelacker's cells (field.h FIELD_CELLS) */
#define WORLD_BERLIN_FROM 400.0f /* x beyond this: Berlin, off the map (manor.h BERLIN_X) */
/* What a weekend is for (decided at the Herberge): the floors, the side jobs, or a party. */
enum { FOCUS_NONE, FOCUS_FLOORS, FOCUS_SIDE, FOCUS_PARTY };
/* The why questions (game_why.c): what festivals do today, found out on the way. */
enum { WHY_URINELLA, WHY_AWARENESS, WHY_SHIRT, WHY_COUNT };
enum { WHY_UNKNOWN, WHY_RAISED, WHY_UNDERSTOOD, WHY_YES, WHY_NO }; /* (how far each is: World.why) */

/* The big old tree (game_bigtree.c, ai_jobs.c): how far its felling has got. */
enum { BT_STANDING, BT_ROPE, BT_NOTCH, BT_PULL, BT_CUT, BT_FALLING, BT_DOWN };
typedef struct {
    int      step;          /* BT_*: standing (nobody's looked at it), the rope up, the notch, on the rope, the back cut, falling, down */
    float    work;          /* person-hours into the notch; real s into the back cut */
    float    rope_h;        /* m up the tree the rope's caught over a branch (0: not up) */
    float    rope_wait;     /* game s Enrico's waited for somebody to throw it up */
    int      pullers;       /* on the rope when it went */
    float    off;           /* degrees it fell off where it should */
    bool     lines_down;    /* it took the phone line down */
    bool     told;          /* (how it went: said) */
} BigTree;
/* Something heavy on top of somebody, a bad fall: a broken arm or leg (world/injury.c). */
enum { INJ_NONE, INJ_ARM, INJ_LEG };

/* The festival weekend (game_festival.c): what's on, for the people (ai_fest.c). */
enum { FEST_NONE, FEST_SETUP, FEST_OPEN, FEST_WARNED, FEST_STORM, FEST_LEAVING, FEST_OVER };
#define FEST_FLOORS 4
typedef struct {
    int      stage;            /* FEST_*: none (a build weekend), the last bits before the gates open, open, ... */
    unsigned on;               /* bit k: floor k playing now (0 Hofbuehne, 1 Obstwiese, 2 Kartoffelacker, 3 hidden) */
    float    good[FEST_FLOORS]; /* how good each floor is (0: not built enough to play) */
    Vec3     dance[FEST_FLOORS]; /* the middle of the dance floor in front of each stage ... */
    Vec3     front[FEST_FLOORS]; /* ... and which way the stage looks */
    float    bpm[FEST_FLOORS];  /* each floor's tempo */
    float    clock;            /* real s: the beat's clock (everybody on a floor moves to it) */
    Vec3     shelter[3];       /* the storm: doors to get in at (the main building, the barn, your garages' kitchen) */
    bool     awareness;        /* the why questions said yes to: an awareness team on shift ... */
    bool     shirts;           /* ... no shirt, no service */
    int      helped;           /* the awareness team saw to somebody lying drunk: this often (counted by them, ai_fest.c) */
    int      litter;           /* the guests' litter lying about now (counted by the game: they stop dropping more at LITTER_MOST) */
} Fest;

typedef struct World {
    float    dt_props;   /* (this frame's step, for the props that move: gates) */
    float    game_dt;    /* (this frame's step in game seconds) */
    Object **objects;
    int      count;
    int      capacity;
    Terrain  terrain;
    bool     has_terrain;
    unsigned rng;          /* dice for small accidents */
    Mesh     flames;       /* on people who walked into a fire */
    Mesh     hose_piece;   /* drawn again and again along a garden hose */
    Mesh     hose_tape;    /* ... and round it where it's mended */
    HoseRope hoses[HOSE_MAX];
    Chips    chips;        /* wood chips and sawdust flying off work */
    Grid     grid;         /* where things are, by ground cell (built each frame) */
    float    hour;         /* time of day (set by the game) */
    float    rain;         /* 0..1 how hard it rains now (see weather.h) ... */
    float    rain_goal, rain_left; /* ... where it's going, for how much longer (game s) */
    int      weather;      /* WeatherKind: on its own, or set (dev menu) */
    float    wet;          /* 0..1 everything wet from the rain (dries over hours) */
    float    flash;        /* 0..1 lightning just now (fades in a moment) ... */
    float    thunder_in;   /* ... the thunder after it, in this many seconds (0: none coming) ... */
    bool     thunder;      /* ... rolling just now (this frame: the game says so) */
    Vec3     wind;         /* m/s the air moves now (gusts and all; flat) ... */
    float    wind_goal;    /* ... 0..1 how windy it's getting (x WIND_MAX m/s) ... */
    float    wind_level;   /* ... how windy it is (eases to the goal) ... */
    float    wind_angle;   /* ... where it blows to (wanders) ... */
    float    wind_left;    /* ... game s till it changes ... */
    float    gust, gust_t; /* ... a gust now (0..1), and its clock */
    int      wind_kind;    /* WindKind: on its own, or set (dev menu) */
    struct Object *tent_blowing; /* a tent the wind is pushing about just now (or NULL) */
    Vec3     eye;          /* where the camera is (set by the game: the rain falls round it) */
    Noise    noises[WORLD_NOISES]; /* sounds made this frame (see Noise) */
    int      noise_count;
    struct RainDrops *drops;
    float    cash;         /* € in the festival's cash box (shopping runs: game_shop.c) ... */
    bool     shopping;     /* ... one on its way (the car's off) */
    unsigned char mown[WORLD_FIELD_CELLS]; /* the Kartoffelacker's grass: how far each cell is mown (field.c) ... */
    int      mow_rev;      /* ... changed this often (the grass is built again) */
    int      snails_rescued, snails_killed; /* the vineyard snails (field.c) ... */
    bool     inspected;    /* ... the regulatory office has been */
    int      focus;        /* FOCUS_*: what this weekend is for (the game sets it) */
    int      why[WHY_COUNT]; /* the why questions: WHY_UNKNOWN .. WHY_NO (game_why.c; talk.c answers them) ... */
    int      why_heard;    /* ... bit k: came up at the Herberge (not seen on the ground) */
    Fest     fest;         /* the festival weekend (set by the game every frame) */
    BigTree  bigtree;      /* the big old tree's felling */
    float    aware;        /* 0..1 how much the people here look out for each other (game_touch.c: the mood, kind acts, harassment seen) */
    struct { struct Object *by, *whom; int what, part; } touched[8]; /* touches this frame worth noticing (people/touch.c) ... */
    int      touched_n;    /* ... how many (the game looks at them: who saw it) */
    int      tree_fine;    /* EUR just fined for a tree that wasn't to be felled (the game says so, then 0) ... */
    int      tree_fine_kind; /* ... 1 one of Kurti's apple trees, 2 a protected one */
} World;

/* A sound made here (dropped when the list is full: nobody's listening). */
void World_noise(World *world, NoiseKind kind, Vec3 at, float loud);
void World_noiseOn(World *world, NoiseKind kind, Vec3 at, float loud, int surface);

void World_init(World *world);
void World_destroy(World *world);

/* Takes ownership of obj. On failure obj is destroyed and false is returned. */
bool World_add(World *world, Object *obj);

/*
 * Height of the surface a foot would stand on at (x, z): the terrain or the
 * top of an object, searching down from from_y. Characters and carried
 * items are ignored.
 */
float World_groundHeight(const World *world, float x, float z, float from_y);

/*
 * The first thing along a ray (dir: unit) within max that skip doesn't leave
 * out (skip may be NULL: all but characters and held things): its distance,
 * or -1. hit and normal (towards the ray) may be NULL.
 */
typedef bool (*RaySkip)(const Object *o, const void *ctx);
float World_rayCast(const World *world, Vec3 origin, Vec3 dir, float max, RaySkip skip, const void *ctx,
                    Object **hit, Vec3 *normal);

/* Builds the ground once all static objects are placed (it levels around them). */
bool World_buildTerrain(World *world);

/* dt in real seconds, game_dt in game seconds (grass recovery). */
void World_update(World *world, float dt, float game_dt);
void World_drawShadows(const World *world, Renderer *renderer);
/* draw_player = false in first person (the camera is inside the player). */
void World_draw(World *world, Renderer *renderer, bool draw_player);
/* What floats in the air (rain, smoke, chips): after the sky, so it shows against it too. */
void World_drawAir(World *world, Renderer *renderer);

#endif /* WORLD_WORLD_H */