X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=main.c;h=2e7fdf2cc1169d1e4c6bc5fa1bd2a2000be78b9e;hb=2db3bed3f1ee0a220bf1d1b818716afb90b30b35;hp=5e7d6abf932a1713c2c5f4e719cacae5a77d4325;hpb=eebc87f889b0fa1404684aa6e72dda5a5e53d96b;p=open-adventure.git diff --git a/main.c b/main.c index 5e7d6ab..2e7fdf2 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ /* - * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods - * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-FileCopyrightText: Copyright 1977, 2005 by Will Crowther and Don Woods, Copyright 2017 by Eric S. Raymond * SPDX-License-Identifier: BSD-2-Clause */ @@ -14,7 +13,6 @@ #include #include #include "advent.h" -#include "dungeon.h" #define DIM(a) (sizeof(a)/sizeof(a[0])) @@ -104,14 +102,14 @@ static void checkhints(void) { if (conditions[game.loc] >= game.conds) { for (int hint = 0; hint < NHINTS; hint++) { - if (game.hinted[hint]) + if (game.hints[hint].used) continue; if (!CNDBIT(game.loc, hint + 1 + COND_HBASE)) - game.hintlc[hint] = -1; - ++game.hintlc[hint]; + game.hints[hint].lc = -1; + ++game.hints[hint].lc; /* Come here if he's been int enough at required loc(s) for some * unused hint. */ - if (game.hintlc[hint] >= hints[hint].turns) { + if (game.hints[hint].lc >= hints[hint].turns) { int i; switch (hint) { @@ -119,7 +117,7 @@ static void checkhints(void) /* cave */ if (game.objects[GRATE].prop == GRATE_CLOSED && !HERE(KEYS)) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 1: /* bird */ if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) @@ -128,7 +126,7 @@ static void checkhints(void) case 2: /* snake */ if (HERE(SNAKE) && !HERE(BIRD)) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 3: /* maze */ if (game.locs[game.loc].atloc == NO_OBJECT && @@ -136,19 +134,19 @@ static void checkhints(void) game.locs[game.oldlc2].atloc == NO_OBJECT && game.holdng > 1) break; - game.hintlc[hint] = 0; + 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.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 5: /* witt */ break; case 6: /* urn */ if (game.dflag == 0) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 7: /* woods */ if (game.locs[game.loc].atloc == NO_OBJECT && @@ -159,16 +157,16 @@ static void checkhints(void) case 8: /* ogre */ i = atdwrf(game.loc); if (i < 0) { - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; } if (HERE(OGRE) && i == 0) 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.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; default: // LCOV_EXCL_LINE // Should never happen @@ -176,12 +174,12 @@ static void checkhints(void) } /* Fall through to hint display */ - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; if (!yes_or_no(hints[hint].question, arbitrary_messages[NO_MESSAGE], arbitrary_messages[OK_MAN])) return; rspeak(HINT_COST, hints[hint].penalty, hints[hint].penalty); - game.hinted[hint] = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]); - if (game.hinted[hint] && game.limit > WARNTIME) + game.hints[hint].used = yes_or_no(arbitrary_messages[WANT_HINT], hints[hint].hint, arbitrary_messages[OK_MAN]); + if (game.hints[hint].used && game.limit > WARNTIME) game.limit += WARNTIME * hints[hint].penalty; } } @@ -196,10 +194,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; @@ -783,19 +781,19 @@ static bool closecheck(void) * chest, which may of course never show up). Note that the * treasures need not have been taken yet, just located. Hence * clock1 must be large enough to get out of the cave (it only ticks - * while inside the cave). When it hits zero, we branch to 10000 to - * start closing the cave, and then sit back and wait for him to try - * to get out. If he doesn't within clock2 turns, we close the cave; - * if he does try, we assume he panics, and give him a few additional - * turns to get frantic before we close. When clock2 hits zero, we - * transport him into the final puzzle. Note that the puzzle depends - * upon all sorts of random things. For instance, there must be no - * water or oil, since there are beanstalks which we don't want to be - * able to water, since the code can't handle it. Also, we can have - * no keys, since there is a grate (having moved the fixed object!) - * there separating him from all the treasures. Most of these - * problems arise from the use of negative prop numbers to suppress - * the object descriptions until he's actually moved the objects. */ + * while inside the cave). When it hits zero, we start closing the + * cave, and then sit back and wait for him to try to get out. If he + * doesn't within clock2 turns, we close the cave; if he does try, we + * assume he panics, and give him a few additional turns to get + * frantic before we close. When clock2 hits zero, we transport him + * into the final puzzle. Note that the puzzle depends upon all + * sorts of random things. For instance, there must be no water or + * oil, since there are beanstalks which we don't want to be able to + * water, since the code can't handle it. Also, we can have no keys, + * since there is a grate (having moved the fixed object!) there + * separating him from all the treasures. Most of these problems + * arise from the use of negative prop numbers to suppress the object + * descriptions until he's actually moved the objects. */ { /* If a turn threshold has been met, apply penalties and tell * the player about it. */ @@ -859,31 +857,31 @@ static bool closecheck(void) * objects come from known locations and/or states (e.g. the * snake is known to have been destroyed and needn't be * carried away from its old "place"), making the various - * objects be handled differently. We also drop all other - * objects he might be carrying (lest he have some which + * objects be handled differently. We also drop all other + * objects he might be carrying (lest he has some which * could cause trouble, such as the keys). We describe the * flash of light and trundle back. */ - game.objects[BOTTLE].prop = put(BOTTLE, LOC_NE, EMPTY_BOTTLE); - game.objects[PLANT].prop = put(PLANT, LOC_NE, PLANT_THIRSTY); - game.objects[OYSTER].prop = put(OYSTER, LOC_NE, STATE_FOUND); - game.objects[LAMP].prop = put(LAMP, LOC_NE, LAMP_DARK); - game.objects[ROD].prop = put(ROD, LOC_NE, STATE_FOUND); - game.objects[DWARF].prop = put(DWARF, LOC_NE, 0); + put(BOTTLE, LOC_NE, EMPTY_BOTTLE); + put(PLANT, LOC_NE, PLANT_THIRSTY); + put(OYSTER, LOC_NE, STATE_FOUND); + put(LAMP, LOC_NE, LAMP_DARK); + put(ROD, LOC_NE, STATE_FOUND); + put(DWARF, LOC_NE, STATE_FOUND); game.loc = LOC_NE; game.oldloc = LOC_NE; game.newloc = LOC_NE; /* Leave the grate with normal (non-negative) property. * Reuse sign. */ - put(GRATE, LOC_SW, 0); - put(SIGN, LOC_SW, 0); + move(GRATE, LOC_SW); + move(SIGN, LOC_SW); game.objects[SIGN].prop = ENDGAME_SIGN; - game.objects[SNAKE].prop = put(SNAKE, LOC_SW, SNAKE_CHASED); - game.objects[BIRD].prop = put(BIRD, LOC_SW, BIRD_CAGED); - game.objects[CAGE].prop = put(CAGE, LOC_SW, STATE_FOUND); - game.objects[ROD2].prop = put(ROD2, LOC_SW, STATE_FOUND); - game.objects[PILLOW].prop = put(PILLOW, LOC_SW, STATE_FOUND); + put(SNAKE, LOC_SW, SNAKE_CHASED); + put(BIRD, LOC_SW, BIRD_CAGED); + put(CAGE, LOC_SW, STATE_FOUND); + put(ROD2, LOC_SW, STATE_FOUND); + put(PILLOW, LOC_SW, STATE_FOUND); - game.objects[MIRROR].prop = put(MIRROR, LOC_NE, STATE_FOUND); + put(MIRROR, LOC_NE, STATE_FOUND); game.objects[MIRROR].fixed = LOC_SW; for (int i = 1; i <= NOBJECTS; i++) { @@ -917,10 +915,14 @@ static void listobjects(void) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) continue; - if (game.objects[obj].prop < 0) { + /* (ESR) Warning: it looks like you could get away with + * running this code only on objects with the treasure + * property set. Nope. There is mystery here. + */ + 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) @@ -1094,15 +1096,16 @@ static bool do_command(void) while (command.state <= GIVEN) { if (game.closed) { - /* If closing time, check for any objects being toted with - * game.prop < 0 and stash them. This way objects won't be - * described until they've been picked up and put down - * separate from their respective piles. */ - if (game.objects[OYSTER].prop < 0 && TOTING(OYSTER)) + /* If closing time, check for any stashed objects + * being toted and unstash them. This way objects + * won't be described until they've been picked up + * and put down separate from their respective + * piles. */ + if ((PROP_IS_NOTFOUND(OYSTER) || PROP_IS_STASHED(OYSTER)) && TOTING(OYSTER)) 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); + if (TOTING(i) && (PROP_IS_NOTFOUND(i) || PROP_IS_STASHED(i))) + game.objects[i].prop = PROP_STASHED(i); } }