From: Eric S. Raymond Date: Fri, 7 Apr 2023 20:11:04 +0000 (-0400) Subject: Encapsulate object-state state tests and setttings in macros. X-Git-Tag: 1.16~13 X-Git-Url: https://jxself.org/git/?a=commitdiff_plain;h=02987d0330cf586a90307ad7e8a06cfcde6f6b92;p=open-adventure.git Encapsulate object-state state tests and setttings in macros. This isn't a complete refwctoring, just the part than can be done with transparetly correct capture of inlinre logic into macros. No logic changes. Tests pass, 100% coverage. --- diff --git a/actions.c b/actions.c index 20f0b90..cbc8d3f 100644 --- a/actions.c +++ b/actions.c @@ -244,7 +244,7 @@ static phase_codes_t bigwords(vocab_t id) static void blast(void) /* Blast. No effect unless you've got dynamite, which is a neat trick! */ { - if (game.objects[ROD2].prop == STATE_NOTFOUND || !game.closed) + if (PROP_IS_NOTFOUND(ROD2) || !game.closed) rspeak(REQUIRES_DYNAMITE); else { if (HERE(ROD2)) { @@ -376,7 +376,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) } - if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && STASHED(BIRD) != BIRD_CAGED) { + if (obj == BIRD && game.objects[BIRD].prop != BIRD_CAGED && !PROP_IS_STASHED(BIRD)) { if (game.objects[BIRD].prop == BIRD_FOREST_UNCAGED) { DESTROY(BIRD); rspeak(BIRD_CRAP); @@ -393,7 +393,7 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) game.objects[BIRD].prop = BIRD_CAGED; } if ((obj == BIRD || obj == CAGE) && - (game.objects[BIRD].prop == BIRD_CAGED || STASHED(BIRD) == BIRD_CAGED)) { + (game.objects[BIRD].prop == BIRD_CAGED || PROP_STASHED(BIRD) == BIRD_CAGED)) { /* expression maps BIRD to CAGE and CAGE to BIRD */ carry(BIRD + CAGE - obj, game.loc); } @@ -403,8 +403,8 @@ static phase_codes_t vcarry(verb_t verb, obj_t obj) if (obj == BOTTLE && LIQUID() != NO_OBJECT) game.objects[LIQUID()].place = CARRIED; - if (GSTONE(obj) && game.objects[obj].prop != STATE_FOUND) { - game.objects[obj].prop = STATE_FOUND; + if (GSTONE(obj) && !PROP_IS_FOUND(obj)) { + PROP_SET_FOUND(obj); game.objects[CAVITY].prop = CAVITY_EMPTY; } rspeak(OK_MAN); @@ -936,7 +936,7 @@ static phase_codes_t listen(void) soundlatch = true; } for (obj_t i = 1; i <= NOBJECTS; i++) { - if (!HERE(i) || objects[i].sounds[0] == NULL || game.objects[i].prop < 0) + if (!HERE(i) || objects[i].sounds[0] == NULL || PROP_IS_STASHED_OR_UNSEEN(i)) continue; int mi = game.objects[i].prop; /* (ESR) Some unpleasant magic on object states here. Ideally @@ -1116,8 +1116,7 @@ static phase_codes_t read(command_t command) } else { pspeak(OYSTER, hear, true, 1); // Not really a sound, but oh well. } - } else if (objects[command.obj].texts[0] == NULL || - game.objects[command.obj].prop == STATE_NOTFOUND) { + } else if (objects[command.obj].texts[0] == NULL || PROP_IS_NOTFOUND(command.obj)) { speak(actions[command.verb].message); } else pspeak(command.obj, study, true, game.objects[command.obj].prop); @@ -1297,9 +1296,9 @@ static phase_codes_t wave(verb_t verb, obj_t obj) } if (game.objects[BIRD].prop == BIRD_UNCAGED && game.loc == game.objects[STEPS].place - && game.objects[JADE].prop == STATE_NOTFOUND) { + && PROP_IS_NOTFOUND(JADE)) { drop(JADE, game.loc); - game.objects[JADE].prop = STATE_FOUND; + PROP_SET_FOUND(JADE); --game.tally; rspeak(NECKLACE_FLY); return GO_CLEAROBJ; diff --git a/advent.h b/advent.h index 55d1b82..738d546 100644 --- a/advent.h +++ b/advent.h @@ -48,10 +48,19 @@ #define IS_FIXED -1 #define IS_FREE 0 -/* Map a state property value to a negative range, where the object cannot be +/* STASH map a state property value to a negative range, where the object cannot be * picked up but the value can be recovered later. Avoid colliding with -1, * which has its own meaning as STATE_NOTFOUND. */ -#define STASHED(obj) (-1 - game.objects[obj].prop) +#define PROP_STASHED(obj) (STATE_NOTFOUND - game.objects[obj].prop) +#define PROP_IS_STASHED(obj) (game.objects[obj].prop < STATE_NOTFOUND) +#define PROP_IS_NOTFOUND(obj) (game.objects[obj].prop == STATE_NOTFOUND) +/* Don't use this on an object wi nore thab 2 (unstashed) states */ +#define PROP_IS_FOUND(obj) (game.objects[obj].prop == STATE_FOUND) +/* Magic number -2 allows a PROP_STASHED version of state 1 */ +#define PROP_IS_INVALID(val) (val < -2 || val > 1) +#define PROP_IS_STASHED_OR_UNSEEN(obj) (game.objects[obj].prop < 0) +#define PROP_SET_FOUND(obj) (game.objects[obj].prop = STATE_FOUND) +#define PROP_SET_NOT_FOUND(obj) (game.objects[obj].prop = STATE_NOTFOUND) #define PROMPT "> " diff --git a/init.c b/init.c index c384f71..0813fb7 100644 --- a/init.c +++ b/init.c @@ -90,7 +90,7 @@ int initialise(void) for (int treasure = 1; treasure <= NOBJECTS; treasure++) { if (objects[treasure].is_treasure) { if (objects[treasure].inventory != 0) - game.objects[treasure].prop = STATE_NOTFOUND; + PROP_SET_NOT_FOUND(treasure); game.tally = game.tally - game.objects[treasure].prop; } } diff --git a/main.c b/main.c index a740b42..4b6165e 100644 --- a/main.c +++ b/main.c @@ -139,7 +139,7 @@ static void checkhints(void) game.hints[hint].lc = 0; return; case 4: /* dark */ - if (game.objects[EMERALD].prop != STATE_NOTFOUND && game.objects[PYRAMID].prop == STATE_NOTFOUND) + if (!PROP_IS_NOTFOUND(EMERALD) && PROP_IS_NOTFOUND(PYRAMID)) break; game.hints[hint].lc = 0; return; @@ -166,7 +166,7 @@ static void checkhints(void) break; return; case 9: /* jade */ - if (game.tally == 1 && game.objects[JADE].prop < 0) + if (game.tally == 1 && PROP_IS_STASHED_OR_UNSEEN(JADE)) break; game.hints[hint].lc = 0; return; @@ -196,10 +196,10 @@ static bool spotted_by_pirate(int i) /* The pirate's spotted him. Pirate leaves him alone once we've * found chest. K counts if a treasure is here. If not, and * tally=1 for an unseen chest, let the pirate be spotted. Note - * that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown + * that game.objexts,place[CHEST] = LOC_NOWHERE might mean that he's thrown * it to the troll, but in that case he's seen the chest - * (game.prop[CHEST] == STATE_FOUND). */ - if (game.loc == game.chloc || game.objects[CHEST].prop != STATE_NOTFOUND) + * PROP_IS_FOUND(CHEST) == true. */ + if (game.loc == game.chloc || !PROP_IS_NOTFOUND(CHEST)) return true; int snarfed = 0; bool movechest = false, robplayer = false; @@ -917,10 +917,10 @@ static void listobjects(void) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) continue; - if (game.objects[obj].prop < 0) { + if (PROP_IS_STASHED_OR_UNSEEN(obj)) { if (game.closed) continue; - game.objects[obj].prop = STATE_FOUND; + PROP_SET_FOUND(obj); if (obj == RUG) game.objects[RUG].prop = RUG_DRAGON; if (obj == CHAIN) @@ -1102,7 +1102,7 @@ static bool do_command(void) pspeak(OYSTER, look, true, 1); for (size_t i = 1; i <= NOBJECTS; i++) { if (TOTING(i) && game.objects[i].prop < 0) - game.objects[i].prop = STASHED(i); + game.objects[i].prop = PROP_STASHED(i); } } diff --git a/misc.c b/misc.c index 8889941..f224d4c 100644 --- a/misc.c +++ b/misc.c @@ -600,7 +600,7 @@ void put(obj_t object, loc_t where, int pval) * negated game.prop values for the repository objects. */ { move(object, where); - game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with STASHED + game.objects[object].prop = (-1) - pval;; // Needs to stay synchronized with PROP_STASHED } void carry(obj_t object, loc_t where) diff --git a/saveresume.c b/saveresume.c index 4cac034..ceda43c 100644 --- a/saveresume.c +++ b/saveresume.c @@ -229,8 +229,7 @@ bool is_valid(struct game_t valgame) /* Check that properties of objects aren't beyond expected */ for (obj_t obj = 0; obj <= NOBJECTS; obj++) { - /* Magic number -2 allows a STASHED version of state 1 */ - if (valgame.objects[obj].prop < -2 || valgame.objects[obj].prop > 1) { + if (PROP_IS_INVALID(valgame.objects[obj].prop)) { switch (obj) { case RUG: case DRAGON: diff --git a/score.c b/score.c index 2e804e4..ed9cded 100644 --- a/score.c +++ b/score.c @@ -50,7 +50,7 @@ int score(enum termination mode) k = 16; if (game.objects[i].prop > STATE_NOTFOUND) score += 2; - if (game.objects[i].place == LOC_BUILDING && game.objects[i].prop == STATE_FOUND) + if (game.objects[i].place == LOC_BUILDING && PROP_IS_FOUND(i)) score += k - 2; mxscor += k; }