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/src/people/ai.h raw
#ifndef PEOPLE_AI_H
#define PEOPLE_AI_H
/*
* Behaviour of the other people in the world.
*
* idle : stands around, turns towards the player when near
* wander : strolls to a random spot around home, avoiding obstacles
* help : walks beside a leader; when the leader grabs something it finds
* a free spot at the object, grabs too and pushes / pulls along
* fetch : walks to a beer bottle and picks it up
* drink : takes a sip or two, then puts the bottle down
* wake : someone passed out drunk for a while: goes over and shakes them awake
* needs : sleeps when tired, eats and drinks (lying food and bottles, or
* at the apple crate and water barrel), walks off for a pee
* tidy : people who like things clean pick up trash they pass and drop
* it in the container when they're not busy
* help : (also) when it's not clear what to do: takes something like what
* the leader carries, walks along with it and does the same with it
* (puts it down next to theirs, into the fire, into the bin)
* help : (also) understands the leader's wood work and carries it on:
* fells with them, takes the branches off, cuts and splits what
* lies around; fetches fitting tools; rests when worn out
* work : an order of their own: makes firewood of the wood around a
* place (and fells more trees if asked), then stacks it on the
* woodpile they were shown; collects the trash with a garbage
* bag and takes it to the container; looks after the fire (keeps
* wood in it, lights it when it gets dark, sits by it)
* person : everyone has their own character: jobs they like or hate (they
* are quicker at what they like), how willing they are to do what
* they're asked, and a few words about themselves. Tired or drunk,
* they say no more often. They suggest jobs that need doing
* pace : and their own way of working: quick or slow, thinking things
* over before starting on them or getting right to it, and breaks
* now and then (none, sitting down, a little walk, a chat)
* follow : being shown something: how to make firewood (watches until
* they get it) or where the woodpile goes (follows you there)
* talk : walks up to the player to offer help, ask what to do, or ask
* where the firewood should go; how chatty depends on temperament.
* Out of work only because the player has the axe: the bold ask
* for it, the others wait for it to be put down
*
* Steering looks ahead along a few directions and takes the first free one,
* so people walk around boxes, trees and each other instead of into them.
*/
#include <stdbool.h>
#include "math/linalg.h"
struct Object;
typedef enum {
AI_IDLE,
AI_WANDER,
AI_HELP,
AI_FETCH,
AI_DRINK,
AI_WAKE, /* goes over to someone asleep and shakes them awake */
AI_SUPPLY, /* eats or drinks at the apple crate / water barrel */
AI_PEE, /* walks off a bit for a pee */
AI_WORK, /* on an order: firewood (and more trees) on their own */
AI_FOLLOW, /* being shown something by the player */
AI_APPROACH, /* walks up to the player to say something */
AI_TABLE, /* over to a free chair at a table: sits a while, eats or drinks what they have there */
} AiMode;
typedef enum { ORDER_NONE, ORDER_FIREWOOD, ORDER_TREES, ORDER_TRASH, ORDER_FIRE, ORDER_COUNT } Order;
/* How someone takes a break from work */
typedef enum { BREAK_NONE, BREAK_SIT, BREAK_WALK, BREAK_CHAT, BREAK_COFFEE } BreakKind;
/* Who someone is */
typedef struct {
float likes[ORDER_COUNT]; /* -1 hates the job .. 1 loves it */
float willing; /* 0 = only what they fancy .. 1 = whatever they're asked */
float skill[ORDER_COUNT]; /* how good they are at it to begin with (0..1) */
const char *about; /* a few words about themselves */
/* How they work */
float tempo; /* 1 = normal; quicker strokes and steps above, slower below */
float ponder; /* seconds they think it over before starting on something */
BreakKind break_kind; /* what they do for a break ... */
float break_every; /* ... after about this many seconds of work ... */
float break_length; /* ... for about this long */
} Character;
/* What someone walks up to the player to talk about */
typedef enum { TOPIC_NONE, TOPIC_OFFER, TOPIC_ASK, TOPIC_SUGGEST, TOPIC_WHERE, TOPIC_ASK_HAND, TOPIC_TOOL } Topic;
typedef enum { SHOW_NONE, SHOW_HOW, SHOW_PLACE } Showing;
#define AI_SPEECH_MAX 80
#define AI_SKIPS 4 /* things they remember they couldn't get at */
#define AI_PATH_MAX 24 /* waypoints (see world/nav.h) */
typedef struct {
bool ready;
AiMode mode;
struct Object *leader; /* AI_HELP */
struct Object *target; /* AI_FETCH / AI_DRINK: the bottle, AI_WAKE: the sleeper */
bool pushing; /* AI_HELP: holding the leader's object */
float settled; /* AI_HELP / AI_FOLLOW: arrived (or blocked close by): off again once the spot is further than this; 0 = not there */
Vec3 home;
Vec3 goal; /* where we are walking to */
float timer; /* pause left / time in this mode */
float side; /* AI_HELP: -1 left of the leader, +1 right */
float detour; /* side we last walked around something (-1 / 1) */
Vec3 steer_dir; /* the way round an obstacle we're taking ... */
float steer_hold; /* ... for this much longer */
float boxed; /* no way through just now: wait this long before trying again (no dithering) */
Vec3 walk_dir; /* the way they walk (turns smoothly) */
const struct Object *steer_target; /* what we're walking up to ... */
float steer_best, steer_stall; /* ... closest so far, seconds without getting closer */
Vec3 path[AI_PATH_MAX]; /* a way round fixed things (when walking straight leads into a corner) */
int path_len, path_at;
Vec3 path_goal; /* ... where it leads */
float path_none; /* no way there: don't look again for this long */
float watch_time; /* watchdog: seconds without anything happening ... */
Vec3 watch_pos; /* ... since here ... */
int watch_mode; /* ... in this mode / order / with this target and these things in hand */
const struct Object *watch_target, *watch_items[2];
int watch_count;
float watch_job; /* job_time last frame (working on something counts as something happening) */
int watch_strikes; /* stuck again without anything happening in between */
float stuck; /* seconds without getting closer to the goal */
float closest;
int sips_left; /* AI_DRINK: sips still wanted */
float table_stay; /* AI_TABLE: seconds they sit there ... */
float table_pause; /* ... till the next bite or sip ... */
float table_chat; /* ... and the next word with the others there */
bool resting; /* AI_HELP: worn out, catching breath */
struct Object *tool; /* AI_HELP: tool we are going to fetch for the leader's job */
struct Object *copied; /* AI_HELP: the leader's item we copy (got one like it, do the same with it) */
int copy_sort; /* ... what sort of thing it is */
int copy_step; /* ... 0 = carrying along, then putting it down / in the fire / in the bin */
Vec3 copy_put; /* ... where ours goes */
unsigned rng;
/* Work orders and what this person knows */
Order order; /* AI_WORK */
Order pending; /* asked for, but first they need to be shown how */
Vec3 work_area;
bool knows_wood; /* knows how to make firewood */
struct Object *woodpile; /* the woodpile they were shown (NULL = don't know one) */
bool no_pile; /* told to leave the firewood where it is */
Showing showing; /* AI_FOLLOW */
int seen_jobs; /* the player's finished jobs when the showing began */
struct Object *job_target; /* wood being worked on */
float job_time;
struct Object *skip[AI_SKIPS]; /* didn't work out: leave these a while ... */
float skip_time[AI_SKIPS]; /* ... this much longer each */
float retry; /* lost the grip: wait a moment before trying again */
float jam_time; /* AI_HELP: the load doesn't move and we stand where it wants to go (seconds) */
float clear_time; /* ... so we keep off that side a while */
Vec3 clear_dir; /* ... (the way the load wants to go) */
Vec3 jam_from; /* (where the load was when we started to wonder) */
float shove_time; /* a pushed load has been shoving us this long (negative: a while not minding it) */
float dodge; /* stepping out of its way (seconds left) ... */
Vec3 dodge_dir; /* ... this way */
/* Talking */
Topic topic; /* AI_APPROACH: what they want to talk about */
bool ready_to_talk;
bool talking; /* in a conversation: stands still and listens */
float talk_cooldown;
char speech[AI_SPEECH_MAX];
Character character;
Order suggested; /* TOPIC_SUGGEST: the job they suggest */
Vec3 pee_cover; /* AI_PEE: what they pee behind (face it, or squat with the back to it) ... */
bool pee_hidden; /* ... if there is something */
float annoyed; /* 0..1: left waiting for an answer, ignored; eases off over minutes */
bool wants_bag; /* at the garbage bags: the world hands them one */
struct Object *empty_tray; /* at a full ashtray: the world tips it out into their hand */
bool tool_asked; /* asked the player for their axe (once per order) */
float tidy_pause; /* bending down for trash on the way (seconds left) */
float tray_time; /* on the way to empty the ashtray this long */
struct Object *sort_from; /* sorting the crates (ai_help.c sortCrates): to this one for a bottle that doesn't belong ... */
struct Object *sort_bottle; /* ... carrying this one over to its own crate ... */
float sort_time; /* ... this long already ... */
float sort_look; /* ... and looking again for one in this long */
bool want_jacket; /* cold, the pullover put down somewhere: off to get it */
bool want_smokes; /* out of cigarettes, nobody gives one: off to the machine */
float smokes_time; /* ... on the way this long */
bool asked_you; /* asked the player for one (nothing came of it: the machine next time) */
struct Object *take_from; /* a bottle from this crate, or the next thing out of this car's boot: please (see car.c Car_serve) */
bool sheltering; /* in out of the rain (ai.c shelter) */
bool rain_seated; /* ... sat down to wait it out (the garages' kitchen, the shelter) ... */
int rain_place; /* ... which of those (Site_rainPlaces), + 1 (0: not chosen yet) */
bool greet; /* just arrived: over to the fire, saying hello, sitting there till the work starts ... */
bool greet_stand; /* ... no room on the benches: standing with the others here instead ... */
Vec3 greet_at;
bool greet_asked; /* ... asked those on a bench to move up */
bool drying; /* wet through after the rain: sitting by the fire till dry */
bool timber; /* felling: waiting for somebody to get out from where it'll come down */
Vec3 dodge_to; /* warned off (a tree coming down): out to here ... */
float dodge_t; /* ... for this long */
struct Object *umbrella; /* rain: off to get this umbrella instead of going under a roof (ai.c shelter) */
float greet_left; /* just turned up: this long at the fire, then on with the day (0: till told otherwise) */
bool on_project; /* at work on their floor's stage (ai_project.c) ... */
float shift; /* ... game s into this go at it (then a break) ... */
float project_off; /* ... game s till they go back to it ... */
float held_up; /* ... game s it's been held up (material missing) ... */
struct Object *fetch; /* ... material they're bringing over to it (this long so far) */
float fetch_time;
bool errand; /* off somewhere on purpose: errand_to (a shopping run: the car's driver door;
showing the way: the spot) ... */
bool errand_there; /* ... and there */
Vec3 errand_to;
struct Object *errand_with; /* ... showing whoever this is the way: waiting for them when they fall behind */
bool meeting; /* in Berlin: at a meeting (or there between weekends) - sitting, listening, nothing else */
float remark; /* ... real s till the next remark about it */
float praised; /* game s till a "great work" counts again */
struct Object *share; /* rain: walking under this one's umbrella, at their side ... */
float share_time; /* ... this long so far */
struct Object *blown; /* the wind took this out of their hand: after it (ai.c fetchBlown) ... */
float blown_t; /* ... this long already */
struct Object *hang_on; /* warm, the pullover round the waist: over this (a railing, a chair) it goes ... */
float hang_wait; /* ... and not thought of again for this long */
bool going_in; /* a resident on the way into the house (ai.c goInside) */
struct Object *tent_job; /* lending a hand with this tent (ai.c pitchTents) ... */
float tent_time; /* ... this long */
bool tent_said; /* ... said so */
bool unload; /* unloading the car (ai.c unloadCar) ... */
bool unload_rest; /* ... put it down for a breather */
struct Object *unload_car;
float unload_time; /* ... on this trip this long */
float butt_time; /* holding a finished cigarette (Object.butt_held) this long ... */
bool butt_asked; /* ... and asked somebody for their pocket ashtray already */
int asking_you; /* asked the player for this (PocketNeed: a paper, a filter, tobacco), 0: nothing */
bool filter_asked; /* asked for a filter this time already (none: rolls one without) */
float jacket_time; /* ... on the way this long */
bool tool_waiting; /* waiting for the player to put the axe down */
unsigned char banned; /* tools (1 << ToolKind) they were told to leave alone ... */
unsigned char defies; /* ... and those they use anyway ("I know what I'm doing") */
unsigned char warned; /* tools they already said something about (using one they shouldn't) */
float risky; /* seconds until the next close call with a tool they shouldn't use */
float speech_time;
float lighter_time; /* until they next think about lighters (give one back, ask for theirs) */
float lighter_ask; /* until they ask anybody for a lighter again */
struct Object *set_aside[2]; /* put down to pee: picked up again after */
/* Getting the work place ready (ai_work.c prepareSpot) */
struct Object *prep_for; /* the piece it was looked at for ... */
int prep_stage; /* ... PREP_* */
Vec3 prep_spot; /* ... where the work goes (moving it) */
struct Object *prep_item; /* ... what's being cleared away */
struct Object *prep_helper; /* ... who was called over to help move it */
float prep_time;
bool chat_near; /* on a chat break: close enough (left again only well beyond) */
float hold_idle;
bool hold_there; /* ... at the spot (stands there till pushed well off it) */
float ladder_dir; /* on a ladder: +1 going up, -1 down */
float ladder_seek; /* until they look for a way up / down again */
Order paused_order; /* called away from this job (to help): back to it after, or when reminded ... */
Vec3 paused_area; /* ... there */
float high_time; /* seconds up high (a roof) ... */
bool high_said; /* ... said something about it */
bool heights_said; /* told they won't go up there (once each time they're asked) */
float ladder_climb_t; /* seconds up a ladder that leads nowhere */ /* holding a ladder nobody is on: seconds of that (then they let go) */
float sun_heat; /* seconds of hard work in the midday sun (the shirt comes off) */
float sniff_cooldown; /* until the next remark about a smell */
AiMode before; /* mode to go back to after being shown something */
/* Their way of working */
const struct Object *task_seen; /* the last thing they thought over before starting on it */
float ponder; /* thinking it over (seconds left) */
float streak; /* seconds worked since the last break */
float on_break; /* on a break (seconds left) */
Vec3 break_from; /* BREAK_WALK: where they set out from (and come back to) */
bool break_back; /* ... on the way back */
BreakKind break_now; /* this break: mostly their own kind, now and then another */
struct Object *break_at; /* BREAK_COFFEE: the stove (a coffee there) */
float break_sip; /* ... until the next sip */
struct Object *chat_with; /* BREAK_CHAT: who they're chatting with */
float chat_line; /* ... until the next thing said */
int chat_said;
/* The festival (ai_fest.c) */
int fest_floor; /* dancing at this floor (+1; 0 none) ... */
Vec3 fest_spot; /* ... their place on it ... */
float fest_time; /* ... real s at it so far (negative: till they feel like dancing again) */
struct Object *fest_who; /* the storm: off to warn this one; the awareness team: off to see to this one */
float fest_walk; /* ... on the way this long */
/* People and people (ai_touch.c) */
struct Object *step_in; /* off to tell this one to stop (they bothered step_for) ... */
struct Object *step_for;
float step_t; /* ... on the way this long */
struct Object *harass; /* a drunk guest after this one (the festival) ... */
float harass_walk; /* ... on the way this long */
} Ai;
/* Starts helping the leader; drops a bottle if needed. */
void Ai_help(struct Object *self, struct Object *leader);
void Ai_stopHelping(struct Object *self);
bool Ai_isHelping(const struct Object *self);
/* Called away from a job and didn't go back to it on their own: back to it now (reminded). False: no such job. */
bool Ai_resumePaused(struct Object *self);
/* Says something (a speech bubble for a few seconds). */
void Ai_say(struct Object *self, const char *text);
/* Starts working on an order around area (they must know how). */
void Ai_order(struct Object *self, Order order, Vec3 area);
/* A tree felled falling that way: the first thing it would come down on (a house, a car, a tent ...), or NULL. */
const struct Object *Ai_fallsOnto(const struct Object *tree, Vec3 dir);
/* Somebody where it'll come down (falling that way): told to get out (they step aside). True if anybody is there. */
bool Ai_warnFellingRoom(struct Object *feller, struct Object *const *objects, int count, struct Object *tree, Vec3 dir);
void Ai_stopWork(struct Object *self);
/* Follows the player to be shown how to do the pending order, or where the woodpile goes. */
void Ai_show(struct Object *self, Showing what, const struct Object *player);
void Ai_stopShowing(struct Object *self);
/* Now knows this woodpile and stacks firewood there. */
void Ai_setWoodpile(struct Object *self, struct Object *woodpile);
/* In a conversation or not; done = it ended (no new chat for a while). */
void Ai_setTalking(struct Object *self, bool talking);
/* Tools: a tool someone shouldn't use (the chainsaw unpractised, the axe or
the saw drunk) they use anyway, unless told not to - and the ignorant
don't listen. tool: a ToolKind. Ai_banTool: true = they'll leave it. */
bool Ai_shouldntUse(const struct Object *self, int tool);
bool Ai_banTool(struct Object *self, int tool, bool ban);
bool Ai_mayUse(const struct Object *self, int tool);
/* Time of day (hours) for everybody's plans. */
void Ai_setHour(float hour);
/* Does this job need doing right now (not much firewood, trash lying around, dark and no fire)? */
bool Ai_needed(const struct Object *self, struct Object *const *objects, int count, Order order);
/* Asked to do a job: yes or no, and what they say. their_idea: they asked for something to do. */
bool Ai_willDo(struct Object *self, struct Object *const *objects, int count, Order order, bool their_idea,
const char **reply);
/* How fast their work goes compared to normal: liking the job, condition, drink. */
float Ai_workRate(const struct Object *self);
/* The job someone is doing right now (ORDER_NONE: nothing). */
Order Ai_job(const struct Object *self);
/* Doing a job makes you better at it. */
void Ai_practice(struct Object *self, Order job, float amount);
/* The player calls out to them: they come over (or say why not). False if they didn't hear. */
bool Ai_call(struct Object *self, const struct Object *player);
/* Where things are (the world's cell grid): steering only looks at what's near. NULL: everything. */
struct Grid;
struct World;
void Ai_useGrid(struct Grid *grid);
/* The world (for climbing: ladders, edges). */
void Ai_useWorld(struct World *world);
/* Settled in (the car empty, the tents up): from now on they come to you with jobs (firewood, trees...). */
void Ai_setSettled(bool settled);
/* Before physics: chooses what to do and sets movement and facing. */
void Ai_update(struct Object *self, struct Object *const *objects, int count, float dt);
#endif /* PEOPLE_AI_H */