#ifndef WORLD_WETNESS_H #define WORLD_WETNESS_H /* * Water in and on the ground. * * Poured water (hose, watering can, pee) lands on the surface, runs * downhill, gathers in hollows and trampled paths and soaks in as fast and * as far as the soil takes it: asphalt and concrete take nothing, gravel * swallows it, a dirt track or the trodden yard only slowly. Wet soil * darkens; bare soft ground turns to mud (walking on it makes it worse). * It all dries again over hours. Pee leaves a stain and a smell until it * fades or is washed out. * * The ground is cut into cells of 1/6 m; only chunks that got wet are kept. */ #include #include #include "core/gl.h" /* What the ground is made of: how much water it holds, how fast it soaks in, whether it turns to mud. */ typedef enum { SOIL_MEADOW, /* loam under grass */ SOIL_YARD, /* trodden earth */ SOIL_TRACK, /* dirt track */ SOIL_FIELD, /* ploughed */ SOIL_FOREST, /* needles and humus */ SOIL_GRAVEL, SOIL_PAVED, /* asphalt, concrete */ SOIL_COUNT } Soil; struct WetChunk; typedef struct { struct WetChunk **chunks; /* WET_CHUNKS^2, NULL where it's dry */ int *live; /* indices of the chunks in use */ int live_count; GLuint texture; /* RGBA8: soil moisture, standing water, pee, mud */ float flow_time; /* real seconds not yet simulated */ float slow_time, slow_game; } Wetness; struct Terrain; bool Wetness_init(Wetness *w); /* Saves: the wet ground (each chunk in use: water, soil, pee, mud) out to / in from a file. Reading needs the terrain (and its wear) in place first. */ bool Wetness_write(const Wetness *w, FILE *f); bool Wetness_read(struct Terrain *t, FILE *f); void Wetness_destroy(Wetness *w); /* Liters landing on the ground around (x, z); pee: how much of it is pee (0..1). */ void Wetness_pour(struct Terrain *t, float x, float z, float liters, float radius, float pee); /* Runs the water (dt real seconds) and soaks, dries and fades (game_dt game seconds). */ void Wetness_update(struct Terrain *t, float dt, float game_dt); /* Uploads what changed to the texture. */ void Wetness_sync(Wetness *w); /* How muddy (0..1). */ float Wetness_mud(const Wetness *w, float x, float z); /* Standing water here (mm). */ float Wetness_water(const Wetness *w, float x, float z); /* How soft and wet for trampling (0..1): wet soil that can turn to mud. */ float Wetness_softness(const Wetness *w, float x, float z); /* The strongest pee smell within radius (0..1). */ float Wetness_pee(const Wetness *w, float x, float z, float radius); /* A footstep: squelches wet soft ground into mud. Returns how muddy it was (0..1). */ float Wetness_step(Wetness *w, float x, float z); #endif /* WORLD_WETNESS_H */