X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=main.c;h=a740b42158bed8529e89e80256a9989dc77957aa;hb=9cd7c53d789a8a3bc845ff8f6b0e6b46af631627;hp=b318cd0f5ce948593696bb3bbe3a4595ed33c24c;hpb=1e05134b477b817ebe5032ee74b1832b21bb8e1e;p=open-adventure.git diff --git a/main.c b/main.c index b318cd0..a740b42 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ /* - * Copyright (c) 1977, 2005 by Will Crowther and Don Woods - * Copyright (c) 2017 by Eric S. Raymond - * SPDX-License-Identifier: BSD-2-clause + * SPDX-FileCopyrightText: 1977, 2005 by Will Crowther and Don Woods + * SPDX-FileCopyrightText: 2017 by Eric S. Raymond + * SPDX-License-Identifier: BSD-2-Clause */ #include @@ -24,7 +24,7 @@ void autosave(void) { if (autosave_fp != NULL) { rewind(autosave_fp); - savefile(autosave_fp, /* version (auto): */0); + savefile(autosave_fp); fflush(autosave_fp); } } @@ -55,8 +55,13 @@ char *myreadline(const char *prompt) * logfiles for testing purposes. */ /* Normal case - no script arguments */ - if (settings.argc == 0) - return readline(prompt); + if (settings.argc == 0) { + char *ln = readline(prompt); + if (ln == NULL) { + fputs(prompt, stdout); + } + return ln; + } char *buf = malloc(LINESIZE + 1); for (;;) { @@ -99,71 +104,71 @@ 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) { case 0: /* cave */ - if (game.prop[GRATE] == GRATE_CLOSED && !HERE(KEYS)) + 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.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD) + if (game.objects[BIRD].place == game.loc && TOTING(ROD) && game.oldobj == BIRD) break; return; case 2: /* snake */ if (HERE(SNAKE) && !HERE(BIRD)) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; case 3: /* maze */ - if (game.atloc[game.loc] == NO_OBJECT && - game.atloc[game.oldloc] == NO_OBJECT && - game.atloc[game.oldlc2] == NO_OBJECT && + if (game.locs[game.loc].atloc == NO_OBJECT && + game.locs[game.oldloc].atloc == NO_OBJECT && + 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.prop[EMERALD] != STATE_NOTFOUND && game.prop[PYRAMID] == STATE_NOTFOUND) + if (game.objects[EMERALD].prop != STATE_NOTFOUND && game.objects[PYRAMID].prop == STATE_NOTFOUND) 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.atloc[game.loc] == NO_OBJECT && - game.atloc[game.oldloc] == NO_OBJECT && - game.atloc[game.oldlc2] == NO_OBJECT) + if (game.locs[game.loc].atloc == NO_OBJECT && + game.locs[game.oldloc].atloc == NO_OBJECT && + game.locs[game.oldlc2].atloc == NO_OBJECT) break; return; 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.prop[JADE] < 0) + if (game.tally == 1 && game.objects[JADE].prop < 0) break; - game.hintlc[hint] = 0; + game.hints[hint].lc = 0; return; default: // LCOV_EXCL_LINE // Should never happen @@ -171,12 +176,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; } } @@ -194,8 +199,7 @@ static bool spotted_by_pirate(int i) * that game.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.prop[CHEST] != STATE_NOTFOUND) + if (game.loc == game.chloc || game.objects[CHEST].prop != STATE_NOTFOUND) return true; int snarfed = 0; bool movechest = false, robplayer = false; @@ -208,8 +212,7 @@ static bool spotted_by_pirate(int i) game.loc == objects[EMERALD].plac)) { continue; } - if (TOTING(treasure) || - HERE(treasure)) + if (TOTING(treasure) || HERE(treasure)) ++snarfed; if (TOTING(treasure)) { movechest = true; @@ -217,7 +220,7 @@ static bool spotted_by_pirate(int i) } } /* Force chest placement before player finds last treasure */ - if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == LOC_NOWHERE && HERE(LAMP) && game.prop[LAMP] == LAMP_BRIGHT) { + if (game.tally == 1 && snarfed == 0 && game.objects[CHEST].place == LOC_NOWHERE && HERE(LAMP) && game.objects[LAMP].prop == LAMP_BRIGHT) { rspeak(PIRATE_SPOTTED); movechest = true; } @@ -226,13 +229,13 @@ static bool spotted_by_pirate(int i) if (movechest) { move(CHEST, game.chloc); move(MESSAG, game.chloc2); - game.dloc[PIRATE] = game.chloc; - game.odloc[PIRATE] = game.chloc; - game.dseen[PIRATE] = false; + game.dwarves[PIRATE].loc = game.chloc; + game.dwarves[PIRATE].oldloc = game.chloc; + game.dwarves[PIRATE].seen = false; } else { /* You might get a hint of the pirate's presence even if the * chest doesn't move... */ - if (game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20)) + if (game.dwarves[PIRATE].oldloc != game.dwarves[PIRATE].loc && PCT(20)) rspeak(PIRATE_RUSTLES); } if (robplayer) { @@ -242,7 +245,7 @@ static bool spotted_by_pirate(int i) continue; if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac))) { - if (AT(treasure) && game.fixed[treasure] == IS_FREE) + if (AT(treasure) && game.objects[treasure].fixed == IS_FREE) carry(treasure, game.loc); if (TOTING(treasure)) drop(treasure, game.chloc); @@ -271,9 +274,7 @@ static bool dwarfmove(void) * steal return toll, and dwarves can't meet the bear. Also * means dwarves won't follow him into dead end in maze, but * c'est la vie. They'll wait for him outside the dead end. */ - if (game.loc == LOC_NOWHERE || - FORCED(game.loc) || - CNDBIT(game.newloc, COND_NOARRR)) + if (game.loc == LOC_NOWHERE || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR)) return true; /* Dwarf activity level ratchets up */ @@ -288,22 +289,21 @@ static bool dwarfmove(void) * replace him with the alternate. */ if (game.dflag == 1) { if (!INDEEP(game.loc) || - (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || - PCT(85)))) + (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85)))) return true; game.dflag = 2; for (int i = 1; i <= 2; i++) { int j = 1 + randrange(NDWARVES - 1); if (PCT(50)) - game.dloc[j] = 0; + game.dwarves[j].loc = 0; } /* Alternate initial loc for dwarf, in case one of them * starts out on top of the adventurer. */ for (int i = 1; i <= NDWARVES - 1; i++) { - if (game.dloc[i] == game.loc) - game.dloc[i] = DALTLC; // - game.odloc[i] = game.dloc[i]; + if (game.dwarves[i].loc == game.loc) + game.dwarves[i].loc = DALTLC; // + game.dwarves[i].oldloc = game.dwarves[i].loc; } rspeak(DWARF_RAN); drop(AXE, game.loc); @@ -320,11 +320,11 @@ static bool dwarfmove(void) attack = 0; stick = 0; for (int i = 1; i <= NDWARVES; i++) { - if (game.dloc[i] == 0) + if (game.dwarves[i].loc == 0) continue; /* Fill tk array with all the places this dwarf might go. */ unsigned int j = 1; - kk = tkey[game.dloc[i]]; + kk = tkey[game.dwarves[i].loc]; if (kk != 0) do { enum desttype_t desttype = travel[kk].desttype; @@ -334,14 +334,14 @@ static bool dwarfmove(void) continue; else if (!INDEEP(game.newloc)) continue; - else if (game.newloc == game.odloc[i]) + else if (game.newloc == game.dwarves[i].oldloc) continue; else if (j > 1 && game.newloc == tk[j - 1]) continue; else if (j >= DIM(tk) - 1) /* This can't actually happen. */ continue; // LCOV_EXCL_LINE - else if (game.newloc == game.dloc[i]) + else if (game.newloc == game.dwarves[i].loc) continue; else if (FORCED(game.newloc)) continue; @@ -352,25 +352,25 @@ static bool dwarfmove(void) tk[j++] = game.newloc; } while (!travel[kk++].stop); - tk[j] = game.odloc[i]; + tk[j] = game.dwarves[i].oldloc; if (j >= 2) --j; j = 1 + randrange(j); - game.odloc[i] = game.dloc[i]; - game.dloc[i] = tk[j]; - game.dseen[i] = (game.dseen[i] && INDEEP(game.loc)) || - (game.dloc[i] == game.loc || - game.odloc[i] == game.loc); - if (!game.dseen[i]) + game.dwarves[i].oldloc = game.dwarves[i].loc; + game.dwarves[i].loc = tk[j]; + game.dwarves[i].seen = (game.dwarves[i].seen && INDEEP(game.loc)) || + (game.dwarves[i].loc == game.loc || + game.dwarves[i].oldloc == game.loc); + if (!game.dwarves[i].seen) continue; - game.dloc[i] = game.loc; + game.dwarves[i].loc = game.loc; if (spotted_by_pirate(i)) continue; /* This threatening little dwarf is in the room with him! */ ++game.dtotal; - if (game.odloc[i] == game.dloc[i]) { + if (game.dwarves[i].oldloc == game.dwarves[i].loc) { ++attack; - if (game.knfloc >= 0) + if (game.knfloc >= LOC_NOWHERE) game.knfloc = game.loc; if (randrange(1000) < 95 * (game.dflag - 2)) ++stick; @@ -439,9 +439,9 @@ static void croak(void) /* If player wishes to continue, we empty the liquids in the * user's inventory, turn off the lamp, and drop all items * where he died. */ - game.place[WATER] = game.place[OIL] = LOC_NOWHERE; + game.objects[WATER].place = game.objects[OIL].place = LOC_NOWHERE; if (TOTING(LAMP)) - game.prop[LAMP] = LAMP_DARK; + game.objects[LAMP].prop = LAMP_DARK; for (int j = 1; j <= NOBJECTS; j++) { int i = NOBJECTS + 1 - j; if (TOTING(i)) { @@ -458,8 +458,7 @@ static void describe_location(void) { const char* msg = locations[game.loc].description.small; - if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || - msg == NO_MESSAGE) + if (MOD(game.locs[game.loc].abbrev, game.abbnum) == 0 || msg == NO_MESSAGE) msg = locations[game.loc].description.big; if (!FORCED(game.loc) && DARK(game.loc)) { @@ -552,7 +551,7 @@ static void playermove(int motion) rspeak(NO_MORE_DETAIL); ++game.detail; game.wzdark = false; - game.abbrev[game.loc] = 0; + game.locs[game.loc].abbrev = 0; return; } else if (motion == CAVE) { /* Cave. Different messages depending on whether above ground. */ @@ -567,8 +566,7 @@ static void playermove(int motion) /* Look for a way to fulfil the motion verb passed in - travel_entry indexes * the beginning of the motion entries for here (game.loc). */ for (;;) { - if ((travel[travel_entry].motion == HERE) || - travel[travel_entry].motion == motion) + if ((travel[travel_entry].motion == HERE) || travel[travel_entry].motion == motion) break; if (travel[travel_entry].stop) { /* Couldn't find an entry matching the motion word passed @@ -622,17 +620,15 @@ static void playermove(int motion) if (condtype < cond_not) { /* YAML N and [pct N] conditionals */ if (condtype == cond_goto || condtype == cond_pct) { - if (condarg1 == 0 || - PCT(condarg1)) + if (condarg1 == 0 || PCT(condarg1)) break; /* else fall through */ } /* YAML [with OBJ] clause */ - else if (TOTING(condarg1) || - (condtype == cond_with && AT(condarg1))) + else if (TOTING(condarg1) || (condtype == cond_with && AT(condarg1))) break; /* else fall through to check [not OBJ STATE] */ - } else if (game.prop[condarg1] != condarg2) + } else if (game.objects[condarg1].prop != condarg2) break; /* We arrive here on conditional failure. @@ -668,8 +664,7 @@ static void playermove(int motion) game.newloc = (game.loc == LOC_PLOVER) ? LOC_ALCOVE : LOC_PLOVER; - if (game.holdng > 1 || - (game.holdng == 1 && !TOTING(EMERALD))) { + if (game.holdng > 1 || (game.holdng == 1 && !TOTING(EMERALD))) { game.newloc = game.loc; rspeak(MUST_DROP); } @@ -703,9 +698,9 @@ static void playermove(int motion) * (standard travel entries check for * game.prop[TROLL]=TROLL_UNPAID.) Special stuff * for bear. */ - if (game.prop[TROLL] == TROLL_PAIDONCE) { + if (game.objects[TROLL].prop == TROLL_PAIDONCE) { pspeak(TROLL, look, true, TROLL_PAIDONCE); - game.prop[TROLL] = TROLL_UNPAID; + game.objects[TROLL].prop = TROLL_UNPAID; DESTROY(TROLL2); move(TROLL2 + NOBJECTS, IS_FREE); move(TROLL, objects[TROLL].plac); @@ -715,15 +710,15 @@ static void playermove(int motion) return; } else { game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc; - if (game.prop[TROLL] == TROLL_UNPAID) - game.prop[TROLL] = TROLL_PAIDONCE; + if (game.objects[TROLL].prop == TROLL_UNPAID) + game.objects[TROLL].prop = TROLL_PAIDONCE; if (!TOTING(BEAR)) return; state_change(CHASM, BRIDGE_WRECKED); - game.prop[TROLL] = TROLL_GONE; + game.objects[TROLL].prop = TROLL_GONE; drop(BEAR, game.newloc); - game.fixed[BEAR] = IS_FIXED; - game.prop[BEAR] = BEAR_DEAD; + game.objects[BEAR].fixed = IS_FIXED; + game.objects[BEAR].prop = BEAR_DEAD; game.oldlc2 = game.newloc; croak(); return; @@ -741,7 +736,7 @@ static void playermove(int motion) static void lampcheck(void) /* Check game limit and lamp timers */ { - if (game.prop[LAMP] == LAMP_BRIGHT) + if (game.objects[LAMP].prop == LAMP_BRIGHT) --game.limit; /* Another way we can force an end to things is by having the @@ -751,9 +746,9 @@ static void lampcheck(void) * Second is for other cases of lamp dying. Even after it goes * out, he can explore outside for a while if desired. */ if (game.limit <= WARNTIME) { - if (HERE(BATTERY) && game.prop[BATTERY] == FRESH_BATTERIES && HERE(LAMP)) { + if (HERE(BATTERY) && game.objects[BATTERY].prop == FRESH_BATTERIES && HERE(LAMP)) { rspeak(REPLACE_BATTERIES); - game.prop[BATTERY] = DEAD_BATTERIES; + game.objects[BATTERY].prop = DEAD_BATTERIES; #ifdef __unused__ /* This code from the original game seems to have been faulty. * No tests ever passed the guard, and with the guard removed @@ -766,9 +761,9 @@ static void lampcheck(void) game.lmwarn = false; } else if (!game.lmwarn && HERE(LAMP)) { game.lmwarn = true; - if (game.prop[BATTERY] == DEAD_BATTERIES) + if (game.objects[BATTERY].prop == DEAD_BATTERIES) rspeak(MISSING_BATTERIES); - else if (game.place[BATTERY] == LOC_NOWHERE) + else if (game.objects[BATTERY].place == LOC_NOWHERE) rspeak(LAMP_DIM); else rspeak(GET_BATTERIES); @@ -776,7 +771,7 @@ static void lampcheck(void) } if (game.limit == 0) { game.limit = -1; - game.prop[LAMP] = LAMP_DARK; + game.objects[LAMP].prop = LAMP_DARK; if (HERE(LAMP)) rspeak(LAMP_OUT); } @@ -829,23 +824,23 @@ static bool closecheck(void) * know the bivalve is an oyster. *And*, the dwarves must * have been activated, since we've found chest. */ if (game.clock1 == 0) { - game.prop[GRATE] = GRATE_CLOSED; - game.prop[FISSURE] = UNBRIDGED; + game.objects[GRATE].prop = GRATE_CLOSED; + game.objects[FISSURE].prop = UNBRIDGED; for (int i = 1; i <= NDWARVES; i++) { - game.dseen[i] = false; - game.dloc[i] = LOC_NOWHERE; + game.dwarves[i].seen = false; + game.dwarves[i].loc = LOC_NOWHERE; } DESTROY(TROLL); move(TROLL + NOBJECTS, IS_FREE); move(TROLL2, objects[TROLL].plac); move(TROLL2 + NOBJECTS, objects[TROLL].fixd); juggle(CHASM); - if (game.prop[BEAR] != BEAR_DEAD) + if (game.objects[BEAR].prop != BEAR_DEAD) DESTROY(BEAR); - game.prop[CHAIN] = CHAIN_HEAP; - game.fixed[CHAIN] = IS_FREE; - game.prop[AXE] = AXE_HERE; - game.fixed[AXE] = IS_FREE; + game.objects[CHAIN].prop = CHAIN_HEAP; + game.objects[CHAIN].fixed = IS_FREE; + game.objects[AXE].prop = AXE_HERE; + game.objects[AXE].fixed = IS_FREE; rspeak(CAVE_CLOSING); game.clock1 = -1; game.closng = true; @@ -868,28 +863,28 @@ static bool closecheck(void) * objects he might be carrying (lest he have some which * could cause trouble, such as the keys). We describe the * flash of light and trundle back. */ - game.prop[BOTTLE] = put(BOTTLE, LOC_NE, EMPTY_BOTTLE); - game.prop[PLANT] = put(PLANT, LOC_NE, PLANT_THIRSTY); - game.prop[OYSTER] = put(OYSTER, LOC_NE, STATE_FOUND); - game.prop[LAMP] = put(LAMP, LOC_NE, LAMP_DARK); - game.prop[ROD] = put(ROD, LOC_NE, STATE_FOUND); - game.prop[DWARF] = 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, 0); 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); - game.prop[SIGN] = ENDGAME_SIGN; - game.prop[SNAKE] = put(SNAKE, LOC_SW, SNAKE_CHASED); - game.prop[BIRD] = put(BIRD, LOC_SW, BIRD_CAGED); - game.prop[CAGE] = put(CAGE, LOC_SW, STATE_FOUND); - game.prop[ROD2] = put(ROD2, LOC_SW, STATE_FOUND); - game.prop[PILLOW] = put(PILLOW, LOC_SW, STATE_FOUND); - - game.prop[MIRROR] = put(MIRROR, LOC_NE, STATE_FOUND); - game.fixed[MIRROR] = LOC_SW; + move(GRATE, LOC_SW); + move(SIGN, LOC_SW); + game.objects[SIGN].prop = ENDGAME_SIGN; + 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); + + put(MIRROR, LOC_NE, STATE_FOUND); + game.objects[MIRROR].fixed = LOC_SW; for (int i = 1; i <= NOBJECTS; i++) { if (TOTING(i)) @@ -915,21 +910,23 @@ static void listobjects(void) * get full score. */ { if (!DARK(game.loc)) { - ++game.abbrev[game.loc]; - for (int i = game.atloc[game.loc]; i != 0; i = game.link[i]) { + ++game.locs[game.loc].abbrev; + for (int i = game.locs[game.loc].atloc; i != 0; i = game.link[i]) { obj_t obj = i; if (obj > NOBJECTS) obj = obj - NOBJECTS; if (obj == STEPS && TOTING(NUGGET)) continue; - if (game.prop[obj] < 0) { + if (game.objects[obj].prop < 0) { if (game.closed) continue; - game.prop[obj] = STATE_FOUND; + game.objects[obj].prop = STATE_FOUND; if (obj == RUG) - game.prop[RUG] = RUG_DRAGON; + game.objects[RUG].prop = RUG_DRAGON; if (obj == CHAIN) - game.prop[CHAIN] = CHAINING_BEAR; + game.objects[CHAIN].prop = CHAINING_BEAR; + if (obj == EGGS) + game.seenbigwords = true; --game.tally; /* Note: There used to be a test here to see whether the * player had blown it so badly that he could never ever see @@ -946,9 +943,9 @@ static void listobjects(void) * gross blunder isn't likely to find everything else anyway * (so goes the rationalisation). */ } - int kk = game.prop[obj]; + int kk = game.objects[obj].prop; if (obj == STEPS) - kk = (game.loc == game.fixed[STEPS]) + kk = (game.loc == game.objects[STEPS].fixed) ? STEPS_UP : STEPS_DOWN; pspeak(obj, look, true, kk); @@ -1047,7 +1044,7 @@ static bool do_move(void) * place) let him get out (and attacked). */ if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc, COND_NOARRR)) { for (size_t i = 1; i <= NDWARVES - 1; i++) { - if (game.odloc[i] == game.newloc && game.dseen[i]) { + if (game.dwarves[i].oldloc == game.newloc && game.dwarves[i].seen) { game.newloc = game.loc; rspeak(DWARF_BLOCK); break; @@ -1064,7 +1061,7 @@ static bool do_move(void) /* The easiest way to get killed is to fall into a pit in * pitch darkness. */ - if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(35)) { // FIXME: magic number + if (!FORCED(game.loc) && DARK(game.loc) && game.wzdark && PCT(PIT_KILL_PROB)) { rspeak(PIT_FALL); game.oldlc2 = game.loc; croak(); @@ -1101,11 +1098,11 @@ static bool do_command(void) * 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.prop[OYSTER] < 0 && TOTING(OYSTER)) + if (game.objects[OYSTER].prop < 0 && TOTING(OYSTER)) pspeak(OYSTER, look, true, 1); for (size_t i = 1; i <= NOBJECTS; i++) { - if (TOTING(i) && game.prop[i] < 0) - game.prop[i] = STASHED(i); + if (TOTING(i) && game.objects[i].prop < 0) + game.objects[i].prop = STASHED(i); } } @@ -1256,20 +1253,23 @@ int main(int argc, char *argv[]) /* Options. */ #if defined ADVENT_AUTOSAVE - const char* opts = "l:oa:"; + const char* opts = "dl:oa:"; const char* usage = "Usage: %s [-l logfilename] [-o] [-a filename] [script...]\n"; FILE *rfp = NULL; const char* autosave_filename = NULL; #elif !defined ADVENT_NOSAVE - const char* opts = "l:or:"; + const char* opts = "dl:or:"; const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n"; FILE *rfp = NULL; #else - const char* opts = "l:o"; + const char* opts = "dl:o"; const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; #endif while ((ch = getopt(argc, argv, opts)) != EOF) { switch (ch) { + case 'd': // LCOV_EXCL_LINE + settings.debug +=1; // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE case 'l': settings.logfp = fopen(optarg, "w"); if (settings.logfp == NULL)