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/pockets.c raw
#include "people/pockets.h"
#include <math.h>
bool Pockets_light(Object *who) {
if (!who->lighter || who->lighter_uses <= 0) return false;
who->lighter_uses--;
return true;
}
Object *Pockets_lighterNear(Object *who, Object *const *objects, int count, float range) {
Object *best = NULL;
for (int i = 0; i < count; i++) {
Object *o = objects[i];
if (o == who || !o->is_character || o->type == OBJ_DOG || !o->lighter || o->lighter_uses <= 0) continue;
float d = hypotf(o->position.x - who->position.x, o->position.z - who->position.z);
if (d < range) { range = d; best = o; }
}
return best;
}
void Pockets_passLighter(Object *from, Object *to) {
if (!from->lighter || to->lighter) return;
to->lighter = true;
to->lighter_uses = from->lighter_uses;
to->lighter_of = from->lighter_of == to ? NULL : from->lighter_of ? from->lighter_of : from; /* (back home: their own again) */
from->lighter = false;
from->lighter_of = NULL;
from->lighter_uses = 0;
}
bool Pockets_giveBack(Object *who) {
Object *owner = who->lighter_of;
if (!who->lighter || !owner || owner->lighter) return false;
Pockets_passLighter(who, owner);
return true;
}
int Pockets_refill(Object *who) {
int got = POCKET_URINELLAS - who->urinellas;
if (got < 0) got = 0;
who->urinellas = POCKET_URINELLAS;
return got;
}
static bool canRoll(const Object *who) { return who->tobacco > 0 && who->papers > 0; }
bool Pockets_hasSmoke(const Object *who) {
return who->cigarettes > 0 || canRoll(who);
}
bool Pockets_takeSmoke(Object *who, bool can_roll, bool *rolled) {
if (canRoll(who) && (can_roll || who->cigarettes <= 0)) {
if (!can_roll) return false; /* (only the makings, and no hands for rolling) */
who->tobacco--;
who->papers--;
if (who->filters > 0) who->filters--; /* (with a filter if there's one) */
*rolled = true;
return true;
}
if (who->cigarettes <= 0) return false;
who->cigarettes--;
*rolled = false;
return true;
}
Object *Pockets_smokesNear(Object *who, Object *const *objects, int count, float range) {
Object *best = NULL;
for (int i = 0; i < count; i++) {
Object *o = objects[i];
if (o == who || !o->is_character || o->type == OBJ_DOG || !Pockets_hasSmoke(o)) continue;
float d = hypotf(o->position.x - who->position.x, o->position.z - who->position.z);
if (d < range) { range = d; best = o; }
}
return best;
}
bool Pockets_giveSmoke(Object *from, Object *to) {
if (from->cigarettes > 0) from->cigarettes--;
else if (canRoll(from)) { from->tobacco--; from->papers--; if (from->filters > 0) from->filters--; } /* (rolls them one) */
else return false;
to->cigarettes++;
return true;
}
PocketNeed Pockets_need(const Object *who) {
if (who->cigarettes > 0 || (who->tobacco <= 0 && who->papers <= 0)) return POCKET_NOTHING;
if (who->papers <= 0) return POCKET_PAPERS;
if (who->tobacco <= 0) return POCKET_TOBACCO;
if (who->filter_habit && who->filters <= 0) return POCKET_FILTERS;
return POCKET_NOTHING;
}
static int spare(const Object *o, PocketNeed what) {
switch (what) {
case POCKET_PAPERS: return o->papers;
case POCKET_FILTERS: return o->filters;
case POCKET_TOBACCO: return o->tobacco;
case POCKET_ASHTRAY: return o->pocket_tray ? 2 : 0;
case POCKET_NOTHING: break;
}
return 0;
}
Object *Pockets_hasNear(Object *who, PocketNeed what, Object *const *objects, int count, float range) {
Object *best = NULL;
for (int i = 0; i < count; i++) {
Object *o = objects[i];
if (o == who || !o->is_character || o->type == OBJ_DOG || spare(o, what) <= 1) continue;
float d = hypotf(o->position.x - who->position.x, o->position.z - who->position.z);
if (d < range) { range = d; best = o; }
}
return best;
}
int Pockets_give(Object *from, Object *to, PocketNeed what) {
static const int SOME[] = { [POCKET_NOTHING] = 0, [POCKET_PAPERS] = 3, [POCKET_FILTERS] = 5, [POCKET_TOBACCO] = 2, [POCKET_ASHTRAY] = 1 };
int n = spare(from, what);
if (n > SOME[what]) n = SOME[what];
if (n <= 0) return 0;
switch (what) {
case POCKET_PAPERS: from->papers -= n; to->papers += n; break;
case POCKET_FILTERS: from->filters -= n; to->filters += n; break;
case POCKET_TOBACCO: from->tobacco -= n; to->tobacco += n; break;
case POCKET_ASHTRAY: if (!to->butt_held) return 0; to->butt_held = false; from->pocket_butts++; break;
case POCKET_NOTHING: break;
}
return n;
}
const char *Pockets_needName(PocketNeed what) {
switch (what) {
case POCKET_PAPERS: return "a paper";
case POCKET_FILTERS: return "a filter";
case POCKET_TOBACCO: return "a bit of tobacco";
case POCKET_ASHTRAY: return "your pocket ashtray";
case POCKET_NOTHING: break;
}
return "something";
}
int Pockets_slots(const Object *who) {
switch (who->look.garment) {
case GARMENT_TROUSERS: return who->work_trousers ? 8 : 4; /* (work trousers: thigh and leg pockets too) */
case GARMENT_SHORTS: return 4;
case GARMENT_SKIRT: return 2;
default: return 1; /* (a dress: one small one) */
}
}
int Pockets_used(const Object *who) {
return (who->cigarettes > 0) + (who->tobacco > 0) + (who->papers > 0) + (who->filters > 0) +
(who->lighter ? 1 : 0) + (who->keys ? 1 : 0) + (who->urinellas > 0) + (who->pocket_tray || who->pocket_butts > 0);
}
void Pockets_keepButt(Object *who) {
who->pocket_butts++;
who->butt_held = false;
}