#ifndef WORLD_WORLD_H #define WORLD_WORLD_H /* Owns all objects and the terrain; runs physics and draws them. */ #include #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 */