#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 #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 */