Nimbin[12]?Games / Entropie / entropie/src/world/tools.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/tools.h 5.9 KB · 133 lines raw
#ifndef WORLD_TOOLS_H
#define WORLD_TOOLS_H

/*
 * Working wood with tools (or bare hands).
 *
 *   job      what it takes             axe   chainsaw  shears  hands
 *   fell     a standing tree           12       4        -       -
 *   delimb   one branch of the crown  1.5     1.5      1.5       3
 *   cut      a log in two               8       4        -       -
 *   split    a short log or half        3       -        -       -
 *   (numbers: strokes needed by someone fresh who doesn't mind the job;
 *    tired, drunk or disliking it takes more, liking it fewer)
 *
 * A stroke aims where the worker looks: the trunk of a standing tree (it is
 * cut where it is hit), the crown of a fallen one (branch by branch), the
 * spot on a log, or a short piece (split into firewood: halves, then
 * quarters). Several people can work on the same thing. The world turns
 * finished jobs into falling trees, branches, logs and firewood (see
 * game/forestry.h).
 *
 * The axe is carried with one hand near the head. To work, the hands slide
 * to the end of the handle; trunks are hit with a horizontal swing, wood on
 * the ground from above. The edge stops in the wood where it hits.
 */

#include <stdbool.h>

#include "math/linalg.h"

struct Object;

typedef enum {
    TOOL_NONE,      /* hands busy with something else */
    TOOL_HANDS,     /* bare hands: pulling branches off */
    TOOL_AXE,
    TOOL_SHEARS,
    TOOL_CHAINSAW,
} ToolKind;

typedef enum {
    JOB_NONE,
    JOB_FELL,       /* standing tree -> falls over */
    JOB_DELIMB,     /* fallen tree: a branch comes off; the last one leaves a log */
    JOB_CUT,        /* log -> two shorter logs */
    JOB_SPLIT,      /* short log -> two halves, half -> two quarters (firewood) */
    JOB_STUMP,      /* stump -> chopped out: roots in the ground and a chunk of wood */
} Job;

#define STUMP_WORK 14.0f /* strokes' worth to chop a stump out (axe: one each) */

#define WORK_DONE_MAX 4

typedef struct {
    Job            job;
    struct Object *target;
    float          at;       /* JOB_CUT: where along the log */
    Vec3           point;    /* where it happened */
} JobDone;

typedef struct {
    float          time;        /* > 0 during a stroke: seconds into it */
    ToolKind       tool;
    Job            job;
    struct Object *target;
    Vec3           point;       /* where the stroke lands (world) */
    float          cut_at;      /* JOB_CUT: distance along the log from its first end */
    int            hand;        /* hand holding a one-handed tool */

    /* What this person is busy with (helpers join in) */
    Job            last_job;
    struct Object *last_target;
    float          since;       /* seconds since the last stroke started */

    /* Finished jobs, taken by the world */
    JobDone        done[WORK_DONE_MAX];
    int            done_count;

    int            jobs_done;   /* how many jobs this worker finished (others learn by watching) */
    Vec3           aim;         /* where the worker looks (world, unit); zero = straight ahead */
    float          impact;      /* > 0 just after the tool bit into something */
    int            struck;      /* strokes that just bit (chips fly; taken by the world) */
    float          power;       /* work per stroke compared to normal (set each frame) */

    /* Pose of a held tool, solved every frame (see Tools_placeHeld) */
    float          ready;       /* axe: 0 = carried near the head .. 1 = hands at the end of the handle */
    Vec3           handle;      /* axe: world direction from the hand towards the head */
    Vec3           blade;       /* axe: world direction the edge faces */
    float          grip;        /* axe: hand along the handle, from its middle towards the head (m) */
    float          contact;     /* axe: 0..1, the edge sits at edge (stuck in the wood) */
    Vec3           edge;        /* axe: where the edge bites (world) */
    Vec3           saw_dir;     /* chainsaw: where the bar points while working (world) */
    float          saw_in;      /* chainsaw: 0 = carried .. 1 = bar in the wood */
} Work;

/* The tool in this character's hands (hand = the hand holding it, -1 = both). */
ToolKind Tools_held(const struct Object *who, int *hand);

/* Starts a stroke with whatever is held at whatever is in front. */
bool Tools_use(struct Object *who, struct Object *const *objects, int count);
/* Is there anything the held tool could work on right now? */
bool Tools_hasJob(const struct Object *who, struct Object *const *objects, int count);
/* Is something the held tool could work on close by (a step away, or a little to the side)? */
bool Tools_jobNearby(const struct Object *who, struct Object *const *objects, int count);
/* What the next stroke would work on (NULL = nothing). */
struct Object *Tools_target(const struct Object *who, struct Object *const *objects, int count);
bool Tools_isWorking(const struct Object *who);
/* How far a tree's felling cut is through (0..1). */
float Tools_fellDone(const struct Object *tree);

/* After Hands_update: holds the tool, moves the arms through the stroke and does the work. */
void Tools_update(struct Object *who, float dt);

/* After the skeleton is solved: puts a held tool into the hand.
   Returns false if the item isn't a tool posed here (Hands places it). */
bool Tools_placeHeld(struct Object *who, int hand, struct Object *item);

/* Returns a finished job and removes it. */
bool Tools_takeDone(struct Object *who, JobDone *done);

/* Could this tool do this job at all? */
bool Tools_canDo(ToolKind tool, Job job);

/* Short enough to split (a short log or a half), or long enough to cut. */
bool Tools_splittable(const struct Object *o);
bool Tools_cuttable(const struct Object *o);
/* Where to cut a log next so the pieces can be split (distance from its first end). */
float Tools_cutPoint(const struct Object *log, Vec3 near);

/* Ends of a log (world) and its length. */
void Tools_logEnds(const struct Object *log, Vec3 *a, Vec3 *b);

#endif /* WORLD_TOOLS_H */