From b3057f038bc990e216c1763f7de1f485892296d2 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 18 Jun 2017 06:18:51 -0400 Subject: [PATCH] Re-format to consistent indent style with "make indent". --- actions.c | 1510 +++++++++++++++++++++++++----------------------- common.c | 52 +- dungeon.c | 879 ++++++++++++++-------------- init.c | 258 ++++----- main.c | 1551 +++++++++++++++++++++++++------------------------- misc.c | 622 ++++++++++---------- saveresume.c | 55 +- score.c | 110 ++-- 8 files changed, 2567 insertions(+), 2470 deletions(-) diff --git a/actions.c b/actions.c index ad91e03..58d808b 100644 --- a/actions.c +++ b/actions.c @@ -23,91 +23,88 @@ static int attack(FILE *input, long verb, token_t obj) int spk = ACTSPK[verb]; int d = ATDWRF(game.loc); if (obj == 0) { - if (d > 0) - obj=DWARF; - if (HERE(SNAKE))obj=obj*NOBJECTS+SNAKE; - if (AT(DRAGON) && game.prop[DRAGON] == 0)obj=obj*NOBJECTS+DRAGON; - if (AT(TROLL))obj=obj*NOBJECTS+TROLL; - if (AT(OGRE))obj=obj*NOBJECTS+OGRE; - if (HERE(BEAR) && game.prop[BEAR] == 0)obj=obj*NOBJECTS+BEAR; - if (obj > NOBJECTS) return GO_UNKNOWN; - if (obj == 0) { - /* Can't attack bird or machine by throwing axe. */ - if (HERE(BIRD) && verb != THROW)obj=BIRD; - if (HERE(VEND) && verb != THROW)obj=obj*NOBJECTS+VEND; - /* Clam and oyster both treated as clam for intransitive case; - * no harm done. */ - if (HERE(CLAM) || HERE(OYSTER))obj=NOBJECTS*obj+CLAM; - if (obj > NOBJECTS) - return GO_UNKNOWN; - } + if (d > 0) + obj = DWARF; + if (HERE(SNAKE))obj = obj * NOBJECTS + SNAKE; + if (AT(DRAGON) && game.prop[DRAGON] == 0)obj = obj * NOBJECTS + DRAGON; + if (AT(TROLL))obj = obj * NOBJECTS + TROLL; + if (AT(OGRE))obj = obj * NOBJECTS + OGRE; + if (HERE(BEAR) && game.prop[BEAR] == 0)obj = obj * NOBJECTS + BEAR; + if (obj > NOBJECTS) return GO_UNKNOWN; + if (obj == 0) { + /* Can't attack bird or machine by throwing axe. */ + if (HERE(BIRD) && verb != THROW)obj = BIRD; + if (HERE(VEND) && verb != THROW)obj = obj * NOBJECTS + VEND; + /* Clam and oyster both treated as clam for intransitive case; + * no harm done. */ + if (HERE(CLAM) || HERE(OYSTER))obj = NOBJECTS * obj + CLAM; + if (obj > NOBJECTS) + return GO_UNKNOWN; + } } if (obj == BIRD) { - spk=UNHAPPY_BIRD; - if (game.closed) - { - RSPEAK(spk); - return GO_CLEAROBJ; - } - DESTROY(BIRD); - game.prop[BIRD]=0; - spk=BIRD_DEAD; - } - else if (obj == VEND) { - PSPEAK(VEND,game.prop[VEND]+2); - game.prop[VEND]=3-game.prop[VEND]; - return GO_CLEAROBJ; + spk = UNHAPPY_BIRD; + if (game.closed) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + DESTROY(BIRD); + game.prop[BIRD] = 0; + spk = BIRD_DEAD; + } else if (obj == VEND) { + PSPEAK(VEND, game.prop[VEND] + 2); + game.prop[VEND] = 3 - game.prop[VEND]; + return GO_CLEAROBJ; } - if (obj == 0)spk=NO_TARGET; - if (obj == CLAM || obj == OYSTER)spk=SHELL_IMPERVIOUS; - if (obj == SNAKE)spk=SNAKE_WARNING; - if (obj == DWARF)spk=BARE_HANDS_QUERY; + if (obj == 0)spk = NO_TARGET; + if (obj == CLAM || obj == OYSTER)spk = SHELL_IMPERVIOUS; + if (obj == SNAKE)spk = SNAKE_WARNING; + if (obj == DWARF)spk = BARE_HANDS_QUERY; if (obj == DWARF && game.closed) return GO_DWARFWAKE; - if (obj == DRAGON)spk=ALREADY_DEAD; - if (obj == TROLL)spk=ROCKY_TROLL; - if (obj == OGRE)spk=OGRE_DODGE; + if (obj == DRAGON)spk = ALREADY_DEAD; + if (obj == TROLL)spk = ROCKY_TROLL; + if (obj == OGRE)spk = OGRE_DODGE; if (obj == OGRE && d > 0) { - RSPEAK(spk); - RSPEAK(KNIFE_THROWN); - DESTROY(OGRE); - int dwarves=0; - for (int i=1; i < PIRATE; i++) { - if (game.dloc[i] == game.loc) { - ++dwarves; - game.dloc[i] = LOC_LONGWEST; - game.dseen[i]=false; - } - } - spk = (dwarves > 1) ? OGRE_PANIC1 : OGRE_PANIC2; - } - else if (obj == BEAR) - /* FIXME: Arithmetic on message numbers */ - spk = BEAR_HANDS+(game.prop[BEAR]+1)/2; + RSPEAK(spk); + RSPEAK(KNIFE_THROWN); + DESTROY(OGRE); + int dwarves = 0; + for (int i = 1; i < PIRATE; i++) { + if (game.dloc[i] == game.loc) { + ++dwarves; + game.dloc[i] = LOC_LONGWEST; + game.dseen[i] = false; + } + } + spk = (dwarves > 1) ? OGRE_PANIC1 : OGRE_PANIC2; + } else if (obj == BEAR) + /* FIXME: Arithmetic on message numbers */ + spk = BEAR_HANDS + (game.prop[BEAR] + 1) / 2; else if (obj == DRAGON && game.prop[DRAGON] == 0) { - /* Fun stuff for dragon. If he insists on attacking it, win! - * Set game.prop to dead, move dragon to central loc (still - * fixed), move rug there (not fixed), and move him there, - * too. Then do a null motion to get new description. */ - RSPEAK(BARE_HANDS_QUERY); - GETIN(input,&WD1,&WD1X,&WD2,&WD2X); - if (WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) - return GO_CHECKFOO; - PSPEAK(DRAGON,3); - game.prop[DRAGON]=1; - game.prop[RUG]=0; - int k=(PLAC[DRAGON]+FIXD[DRAGON])/2; - MOVE(DRAGON+NOBJECTS,-1); - MOVE(RUG+NOBJECTS,0); - MOVE(DRAGON,k); - MOVE(RUG,k); - DROP(BLOOD,k); - for (obj=1; obj<=NOBJECTS; obj++) { - if (game.place[obj] == PLAC[DRAGON] || game.place[obj] == FIXD[DRAGON]) - MOVE(obj,k); - } - game.loc=k; - return GO_MOVE; + /* Fun stuff for dragon. If he insists on attacking it, win! + * Set game.prop to dead, move dragon to central loc (still + * fixed), move rug there (not fixed), and move him there, + * too. Then do a null motion to get new description. */ + RSPEAK(BARE_HANDS_QUERY); + GETIN(input, &WD1, &WD1X, &WD2, &WD2X); + if (WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) + return GO_CHECKFOO; + PSPEAK(DRAGON, 3); + game.prop[DRAGON] = 1; + game.prop[RUG] = 0; + int k = (PLAC[DRAGON] + FIXD[DRAGON]) / 2; + MOVE(DRAGON + NOBJECTS, -1); + MOVE(RUG + NOBJECTS, 0); + MOVE(DRAGON, k); + MOVE(RUG, k); + DROP(BLOOD, k); + for (obj = 1; obj <= NOBJECTS; obj++) { + if (game.place[obj] == PLAC[DRAGON] || game.place[obj] == FIXD[DRAGON]) + MOVE(obj, k); + } + game.loc = k; + return GO_MOVE; } RSPEAK(spk); @@ -119,34 +116,34 @@ static int bigwords(long foo) * Look up WD1 in section 3 of vocab to determine which word we've got. Last * word zips the eggs back to the giant room (unless already there). */ { - int k=VOCAB(foo,3); - int spk=NOTHING_HAPPENS; - if (game.foobar != 1-k) { - if (game.foobar != 0)spk=START_OVER; - RSPEAK(spk); - return GO_CLEAROBJ; + int k = VOCAB(foo, 3); + int spk = NOTHING_HAPPENS; + if (game.foobar != 1 - k) { + if (game.foobar != 0)spk = START_OVER; + RSPEAK(spk); + return GO_CLEAROBJ; } else { - game.foobar=k; - if (k != 4) { - RSPEAK(OK_MAN); - return GO_CLEAROBJ; - } - game.foobar=0; - if (game.place[EGGS]==PLAC[EGGS] || (TOTING(EGGS) && game.loc==PLAC[EGGS])) { - RSPEAK(spk); - return GO_CLEAROBJ; - } else { - /* Bring back troll if we steal the eggs back from him before - * crossing. */ - if (game.place[EGGS]==0 && game.place[TROLL]==0 && game.prop[TROLL]==0) - game.prop[TROLL]=1; - k=2; - if (HERE(EGGS))k=1; - if (game.loc == PLAC[EGGS])k=0; - MOVE(EGGS,PLAC[EGGS]); - PSPEAK(EGGS,k); - return GO_CLEAROBJ; - } + game.foobar = k; + if (k != 4) { + RSPEAK(OK_MAN); + return GO_CLEAROBJ; + } + game.foobar = 0; + if (game.place[EGGS] == PLAC[EGGS] || (TOTING(EGGS) && game.loc == PLAC[EGGS])) { + RSPEAK(spk); + return GO_CLEAROBJ; + } else { + /* Bring back troll if we steal the eggs back from him before + * crossing. */ + if (game.place[EGGS] == 0 && game.place[TROLL] == 0 && game.prop[TROLL] == 0) + game.prop[TROLL] = 1; + k = 2; + if (HERE(EGGS))k = 1; + if (game.loc == PLAC[EGGS])k = 0; + MOVE(EGGS, PLAC[EGGS]); + PSPEAK(EGGS, k); + return GO_CLEAROBJ; + } } } @@ -155,14 +152,14 @@ static int bivalve(token_t verb, token_t obj) { int spk; bool is_oyster = (obj == OYSTER); - spk= is_oyster ? OYSTER_OPENS : PEARL_FALLS; - if (TOTING(obj))spk= is_oyster ? DROP_OYSTER : DROP_CLAM; - if (!TOTING(TRIDNT))spk= is_oyster ? OYSTER_OPENER : CLAM_OPENER; - if (verb == LOCK)spk=HUH_MAN; + spk = is_oyster ? OYSTER_OPENS : PEARL_FALLS; + if (TOTING(obj))spk = is_oyster ? DROP_OYSTER : DROP_CLAM; + if (!TOTING(TRIDNT))spk = is_oyster ? OYSTER_OPENER : CLAM_OPENER; + if (verb == LOCK)spk = HUH_MAN; if (spk == PEARL_FALLS) { - DESTROY(CLAM); - DROP(OYSTER,game.loc); - DROP(PEARL,LOC_CULDESAC); + DESTROY(CLAM); + DROP(OYSTER, game.loc); + DROP(PEARL, LOC_CULDESAC); } RSPEAK(spk); return GO_CLEAROBJ; @@ -172,15 +169,15 @@ static void blast(void) /* Blast. No effect unless you've got dynamite, which is a neat trick! */ { if (game.prop[ROD2] < 0 || !game.closed) - RSPEAK(REQUIRES_DYNAMITE); + RSPEAK(REQUIRES_DYNAMITE); else { - game.bonus=VICTORY_MESSAGE; - if (game.loc == LOC_NE) - game.bonus=DEFEAT_MESSAGE; - if (HERE(ROD2)) - game.bonus=SPLATTER_MESSAGE; - RSPEAK(game.bonus); - score(endgame); + game.bonus = VICTORY_MESSAGE; + if (game.loc == LOC_NE) + game.bonus = DEFEAT_MESSAGE; + if (HERE(ROD2)) + game.bonus = SPLATTER_MESSAGE; + RSPEAK(game.bonus); + score(endgame); } } @@ -188,17 +185,17 @@ static int vbreak(token_t verb, token_t obj) /* Break. Only works for mirror in repository and, of course, the vase. */ { int spk = ACTSPK[verb]; - if (obj == MIRROR)spk=TOO_FAR; + if (obj == MIRROR)spk = TOO_FAR; if (obj == VASE && game.prop[VASE] == 0) { - if (TOTING(VASE))DROP(VASE,game.loc); - game.prop[VASE]=2; - game.fixed[VASE]= -1; - spk=BREAK_VASE; + if (TOTING(VASE))DROP(VASE, game.loc); + game.prop[VASE] = 2; + game.fixed[VASE] = -1; + spk = BREAK_VASE; } else { - if (obj == MIRROR && game.closed) { - RSPEAK(BREAK_MIRROR); - return GO_DWARFWAKE; - } + if (obj == MIRROR && game.closed) { + RSPEAK(BREAK_MIRROR); + return GO_DWARFWAKE; + } } RSPEAK(spk); return GO_CLEAROBJ; @@ -207,8 +204,8 @@ static int vbreak(token_t verb, token_t obj) static int brief(void) /* Brief. Intransitive only. Suppress long descriptions after first time. */ { - game.abbnum=10000; - game.detail=3; + game.abbnum = 10000; + game.detail = 3; RSPEAK(BRIEF_CONFIRM); return GO_CLEAROBJ; } @@ -220,74 +217,76 @@ static int carry(token_t verb, token_t obj) { int spk; if (obj == INTRANSITIVE) { - /* Carry, no object given yet. OK if only one object present. */ - if(game.atloc[game.loc] == 0 || - game.link[game.atloc[game.loc]] != 0 || - ATDWRF(game.loc) > 0) - return GO_UNKNOWN; - obj=game.atloc[game.loc]; + /* Carry, no object given yet. OK if only one object present. */ + if (game.atloc[game.loc] == 0 || + game.link[game.atloc[game.loc]] != 0 || + ATDWRF(game.loc) > 0) + return GO_UNKNOWN; + obj = game.atloc[game.loc]; } - if (TOTING(obj)) {RSPEAK(ALREADY_CARRYING); return GO_CLEAROBJ;} - spk=YOU_JOKING; - if (obj == PLANT && game.prop[PLANT] <= 0)spk=DEEP_ROOTS; - if (obj == BEAR && game.prop[BEAR] == 1)spk=BEAR_CHAINED; - if (obj == CHAIN && game.prop[BEAR] != 0)spk=STILL_LOCKED; - if (obj == URN)spk=URN_NOBUDGE; - if (obj == CAVITY)spk=DOUGHNUT_HOLES; - if (obj == BLOOD)spk=FEW_DROPS; - if (obj == RUG && game.prop[RUG] == 2)spk=RUG_HOVERS; - if (obj == SIGN)spk=HAND_PASSTHROUGH; + if (TOTING(obj)) { + RSPEAK(ALREADY_CARRYING); + return GO_CLEAROBJ; + } + spk = YOU_JOKING; + if (obj == PLANT && game.prop[PLANT] <= 0)spk = DEEP_ROOTS; + if (obj == BEAR && game.prop[BEAR] == 1)spk = BEAR_CHAINED; + if (obj == CHAIN && game.prop[BEAR] != 0)spk = STILL_LOCKED; + if (obj == URN)spk = URN_NOBUDGE; + if (obj == CAVITY)spk = DOUGHNUT_HOLES; + if (obj == BLOOD)spk = FEW_DROPS; + if (obj == RUG && game.prop[RUG] == 2)spk = RUG_HOVERS; + if (obj == SIGN)spk = HAND_PASSTHROUGH; if (obj == MESSAG) { - RSPEAK(REMOVE_MESSAGE); - DESTROY(MESSAG); - return GO_CLEAROBJ; + RSPEAK(REMOVE_MESSAGE); + DESTROY(MESSAG); + return GO_CLEAROBJ; } if (game.fixed[obj] != 0) { - RSPEAK(spk); - return GO_CLEAROBJ; + RSPEAK(spk); + return GO_CLEAROBJ; } if (obj == WATER || obj == OIL) { - if (!HERE(BOTTLE) || LIQUID() != obj) { - if (TOTING(BOTTLE) && game.prop[BOTTLE] == 1) - return(fill(verb, BOTTLE)); - else { - if (game.prop[BOTTLE] != 1)spk=BOTTLE_FULL; - if (!TOTING(BOTTLE))spk=NO_CONTAINER; - RSPEAK(spk); - return GO_CLEAROBJ; - } - } - obj = BOTTLE; + if (!HERE(BOTTLE) || LIQUID() != obj) { + if (TOTING(BOTTLE) && game.prop[BOTTLE] == 1) + return (fill(verb, BOTTLE)); + else { + if (game.prop[BOTTLE] != 1)spk = BOTTLE_FULL; + if (!TOTING(BOTTLE))spk = NO_CONTAINER; + RSPEAK(spk); + return GO_CLEAROBJ; + } + } + obj = BOTTLE; } - spk=CARRY_LIMIT; + spk = CARRY_LIMIT; if (game.holdng >= INVLIMIT) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - else if (obj == BIRD && game.prop[BIRD] != 1 && -1-game.prop[BIRD] != 1) { - if (game.prop[BIRD] == 2) { - DESTROY(BIRD); - RSPEAK(BIRD_CRAP); - return GO_CLEAROBJ; - } - if (!TOTING(CAGE))spk=CANNOT_CARRY; - if (TOTING(ROD))spk=BIRD_EVADES; - if (spk == CANNOT_CARRY || spk == BIRD_EVADES) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - game.prop[BIRD]=1; + RSPEAK(spk); + return GO_CLEAROBJ; + } else if (obj == BIRD && game.prop[BIRD] != 1 && -1 - game.prop[BIRD] != 1) { + if (game.prop[BIRD] == 2) { + DESTROY(BIRD); + RSPEAK(BIRD_CRAP); + return GO_CLEAROBJ; + } + if (!TOTING(CAGE))spk = CANNOT_CARRY; + if (TOTING(ROD))spk = BIRD_EVADES; + if (spk == CANNOT_CARRY || spk == BIRD_EVADES) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + game.prop[BIRD] = 1; } - if ((obj==BIRD || obj==CAGE) && (game.prop[BIRD]==1 || -1-game.prop[BIRD]==1)) - CARRY(BIRD+CAGE-obj,game.loc); - CARRY(obj,game.loc); + if ((obj == BIRD || obj == CAGE) && (game.prop[BIRD] == 1 || -1 - game.prop[BIRD] == 1)) + CARRY(BIRD + CAGE - obj, game.loc); + CARRY(obj, game.loc); if (obj == BOTTLE && LIQUID() != 0) - game.place[LIQUID()] = CARRIED; + game.place[LIQUID()] = CARRIED; if (GSTONE(obj) && game.prop[obj] != 0) { - game.prop[obj]=0; - game.prop[CAVITY]=1; + game.prop[obj] = 0; + game.prop[CAVITY] = 1; } RSPEAK(OK_MAN); return GO_CLEAROBJ; @@ -298,25 +297,28 @@ static int chain(token_t verb) { int spk; if (verb != LOCK) { - spk=CHAIN_UNLOCKED; - if (game.prop[BEAR] == 0)spk=BEAR_BLOCKS; - if (game.prop[CHAIN] == 0)spk=ALREADY_UNLOCKED; - if (spk != CHAIN_UNLOCKED) {RSPEAK(spk); return GO_CLEAROBJ;} - game.prop[CHAIN]=0; - game.fixed[CHAIN]=0; - if (game.prop[BEAR] != 3)game.prop[BEAR]=2; - game.fixed[BEAR]=2-game.prop[BEAR]; + spk = CHAIN_UNLOCKED; + if (game.prop[BEAR] == 0)spk = BEAR_BLOCKS; + if (game.prop[CHAIN] == 0)spk = ALREADY_UNLOCKED; + if (spk != CHAIN_UNLOCKED) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + game.prop[CHAIN] = 0; + game.fixed[CHAIN] = 0; + if (game.prop[BEAR] != 3)game.prop[BEAR] = 2; + game.fixed[BEAR] = 2 - game.prop[BEAR]; } else { - spk=CHAIN_LOCKED; - if (game.prop[CHAIN] != 0)spk=ALREADY_LOCKED; - if (game.loc != PLAC[CHAIN])spk=NO_LOCKSITE; - if (spk != CHAIN_LOCKED) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - game.prop[CHAIN]=2; - if (TOTING(CHAIN))DROP(CHAIN,game.loc); - game.fixed[CHAIN]= -1; + spk = CHAIN_LOCKED; + if (game.prop[CHAIN] != 0)spk = ALREADY_LOCKED; + if (game.loc != PLAC[CHAIN])spk = NO_LOCKSITE; + if (spk != CHAIN_LOCKED) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + game.prop[CHAIN] = 2; + if (TOTING(CHAIN))DROP(CHAIN, game.loc); + game.fixed[CHAIN] = -1; } RSPEAK(spk); return GO_CLEAROBJ; @@ -329,68 +331,71 @@ static int discard(token_t verb, token_t obj, bool just_do_it) { int spk = ACTSPK[verb]; if (!just_do_it) { - if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj=ROD2; - if (!TOTING(obj)) {RSPEAK(spk); return GO_CLEAROBJ;} + if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj = ROD2; + if (!TOTING(obj)) { + RSPEAK(spk); + return GO_CLEAROBJ; + } if (obj == BIRD && HERE(SNAKE)) { RSPEAK(BIRD_ATTACKS); if (game.closed) return GO_DWARFWAKE; DESTROY(SNAKE); /* Set game.prop for use by travel options */ - game.prop[SNAKE]=1; + game.prop[SNAKE] = 1; } else if ((GSTONE(obj) && AT(CAVITY) && game.prop[CAVITY] != 0)) { RSPEAK(GEM_FITS); - game.prop[obj]=1; - game.prop[CAVITY]=0; + game.prop[obj] = 1; + game.prop[CAVITY] = 0; if (HERE(RUG) && ((obj == EMRALD && game.prop[RUG] != 2) || (obj == RUBY && - game.prop[RUG] == 2))) { - spk=RUG_RISES; - if (TOTING(RUG))spk=RUG_WIGGLES; - if (obj == RUBY)spk=RUG_SETTLES; + game.prop[RUG] == 2))) { + spk = RUG_RISES; + if (TOTING(RUG))spk = RUG_WIGGLES; + if (obj == RUBY)spk = RUG_SETTLES; RSPEAK(spk); if (spk != RUG_WIGGLES) { - int k = 2-game.prop[RUG]; + int k = 2 - game.prop[RUG]; game.prop[RUG] = k; if (k == 2) k = PLAC[SAPPH]; - MOVE(RUG+NOBJECTS, k); + MOVE(RUG + NOBJECTS, k); } } } else if (obj == COINS && HERE(VEND)) { DESTROY(COINS); - DROP(BATTER,game.loc); - PSPEAK(BATTER,0); + DROP(BATTER, game.loc); + PSPEAK(BATTER, 0); return GO_CLEAROBJ; } else if (obj == BIRD && AT(DRAGON) && game.prop[DRAGON] == 0) { RSPEAK(BIRD_BURNT); DESTROY(BIRD); - game.prop[BIRD]=0; + game.prop[BIRD] = 0; return GO_CLEAROBJ; } else if (obj == BEAR && AT(TROLL)) { RSPEAK(TROLL_SCAMPERS); - MOVE(TROLL,0); - MOVE(TROLL+NOBJECTS,0); - MOVE(TROLL2,PLAC[TROLL]); - MOVE(TROLL2+NOBJECTS,FIXD[TROLL]); + MOVE(TROLL, 0); + MOVE(TROLL + NOBJECTS, 0); + MOVE(TROLL2, PLAC[TROLL]); + MOVE(TROLL2 + NOBJECTS, FIXD[TROLL]); JUGGLE(CHASM); - game.prop[TROLL]=2; + game.prop[TROLL] = 2; } else if (obj != VASE || game.loc == PLAC[PILLOW]) { RSPEAK(OK_MAN); } else { - game.prop[VASE]=2; - if (AT(PILLOW))game.prop[VASE]=0; - PSPEAK(VASE,game.prop[VASE]+1); - if (game.prop[VASE] != 0)game.fixed[VASE]= -1; + game.prop[VASE] = 2; + if (AT(PILLOW))game.prop[VASE] = 0; + PSPEAK(VASE, game.prop[VASE] + 1); + if (game.prop[VASE] != 0)game.fixed[VASE] = -1; } } int k = LIQUID(); - if (k == obj)obj=BOTTLE; + if (k == obj)obj = BOTTLE; if (obj == BOTTLE && k != 0) - game.place[k] = NOWHERE; - if (obj == CAGE && game.prop[BIRD] == 1)DROP(BIRD,game.loc); - DROP(obj,game.loc); + game.place[k] = NOWHERE; + if (obj == CAGE && game.prop[BIRD] == 1)DROP(BIRD, game.loc); + DROP(obj, game.loc); if (obj != BIRD) return GO_CLEAROBJ; - game.prop[BIRD]=0; - if (FOREST(game.loc))game.prop[BIRD]=2; + game.prop[BIRD] = 0; + if (FOREST(game.loc))game.prop[BIRD] = 2; return GO_CLEAROBJ; } @@ -400,19 +405,19 @@ static int drink(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == 0 && LIQLOC(game.loc) != WATER && (LIQUID() != WATER || !HERE(BOTTLE))) - return GO_UNKNOWN; + return GO_UNKNOWN; if (obj != BLOOD) { - if (obj != 0 && obj != WATER)spk=RIDICULOUS_ATTEMPT; - if (spk != RIDICULOUS_ATTEMPT && LIQUID() == WATER && HERE(BOTTLE)) { - game.prop[BOTTLE] = 1; - game.place[WATER] = NOWHERE; - spk=BOTTLE_EMPTY; - } + if (obj != 0 && obj != WATER)spk = RIDICULOUS_ATTEMPT; + if (spk != RIDICULOUS_ATTEMPT && LIQUID() == WATER && HERE(BOTTLE)) { + game.prop[BOTTLE] = 1; + game.place[WATER] = NOWHERE; + spk = BOTTLE_EMPTY; + } } else { - DESTROY(BLOOD); - game.prop[DRAGON]=2; - OBJSND[BIRD]=OBJSND[BIRD]+3; - spk=HEAD_BUZZES; + DESTROY(BLOOD); + game.prop[DRAGON] = 2; + OBJSND[BIRD] = OBJSND[BIRD] + 3; + spk = HEAD_BUZZES; } RSPEAK(spk); return GO_CLEAROBJ; @@ -424,18 +429,18 @@ static int eat(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == INTRANSITIVE) { - if (!HERE(FOOD)) - return GO_UNKNOWN; - DESTROY(FOOD); - spk=THANKS_DELICIOUS; + if (!HERE(FOOD)) + return GO_UNKNOWN; + DESTROY(FOOD); + spk = THANKS_DELICIOUS; } else { - if (obj == FOOD) { - DESTROY(FOOD); - spk=THANKS_DELICIOUS; - } - if (obj == BIRD || obj == SNAKE || obj == CLAM || obj == OYSTER || obj == - DWARF || obj == DRAGON || obj == TROLL || obj == BEAR || obj == - OGRE)spk=LOST_APPETITE; + if (obj == FOOD) { + DESTROY(FOOD); + spk = THANKS_DELICIOUS; + } + if (obj == BIRD || obj == SNAKE || obj == CLAM || obj == OYSTER || obj == + DWARF || obj == DRAGON || obj == TROLL || obj == BEAR || obj == + OGRE)spk = LOST_APPETITE; } RSPEAK(spk); return GO_CLEAROBJ; @@ -446,22 +451,20 @@ static int extinguish(token_t verb, int obj) { int spk = ACTSPK[verb]; if (obj == INTRANSITIVE) { - if (HERE(LAMP) && game.prop[LAMP] == 1)obj=LAMP; - if (HERE(URN) && game.prop[URN] == 2)obj=obj*NOBJECTS+URN; - if (obj == INTRANSITIVE || obj == 0 || obj > NOBJECTS) return GO_UNKNOWN; + if (HERE(LAMP) && game.prop[LAMP] == 1)obj = LAMP; + if (HERE(URN) && game.prop[URN] == 2)obj = obj * NOBJECTS + URN; + if (obj == INTRANSITIVE || obj == 0 || obj > NOBJECTS) return GO_UNKNOWN; } if (obj == URN) { - game.prop[URN]=game.prop[URN]/2; - spk=URN_DARK; - } - else if (obj == LAMP) { - game.prop[LAMP]=0; - RSPEAK(LAMP_OFF); - spk = DARK(game.loc) ? PITCH_DARK : NO_MESSAGE; - } - else if (obj == DRAGON || obj == VOLCAN) - spk=BEYOND_POWER; + game.prop[URN] = game.prop[URN] / 2; + spk = URN_DARK; + } else if (obj == LAMP) { + game.prop[LAMP] = 0; + RSPEAK(LAMP_OFF); + spk = DARK(game.loc) ? PITCH_DARK : NO_MESSAGE; + } else if (obj == DRAGON || obj == VOLCAN) + spk = BEYOND_POWER; RSPEAK(spk); return GO_CLEAROBJ; } @@ -472,41 +475,37 @@ static int feed(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == BIRD) { - RSPEAK(BIRD_PINING); - return GO_CLEAROBJ; - } - else if (obj == SNAKE || obj == DRAGON || obj == TROLL) { - spk=NOTHING_EDIBLE; - if (obj == DRAGON && game.prop[DRAGON] != 0)spk=RIDICULOUS_ATTEMPT; - if (obj == TROLL)spk=TROLL_VICES; - if (obj == SNAKE && !game.closed && HERE(BIRD)) { - DESTROY(BIRD); - game.prop[BIRD]=0; - spk = BIRD_DEVOURED; - } - } - else if (obj == DWARF) { - if (HERE(FOOD)) { - game.dflag += 2; - spk = REALLY_MAD; - } - } - else if (obj == BEAR) { - if (game.prop[BEAR] == 0)spk=NOTHING_EDIBLE; - if (game.prop[BEAR] == 3)spk=RIDICULOUS_ATTEMPT; - if (HERE(FOOD)) { - DESTROY(FOOD); - game.prop[BEAR]=1; - game.fixed[AXE]=0; - game.prop[AXE]=0; - spk=BEAR_TAMED; - } - } - else if (obj == OGRE) { - if (HERE(FOOD)) - spk=OGRE_FULL; + RSPEAK(BIRD_PINING); + return GO_CLEAROBJ; + } else if (obj == SNAKE || obj == DRAGON || obj == TROLL) { + spk = NOTHING_EDIBLE; + if (obj == DRAGON && game.prop[DRAGON] != 0)spk = RIDICULOUS_ATTEMPT; + if (obj == TROLL)spk = TROLL_VICES; + if (obj == SNAKE && !game.closed && HERE(BIRD)) { + DESTROY(BIRD); + game.prop[BIRD] = 0; + spk = BIRD_DEVOURED; + } + } else if (obj == DWARF) { + if (HERE(FOOD)) { + game.dflag += 2; + spk = REALLY_MAD; + } + } else if (obj == BEAR) { + if (game.prop[BEAR] == 0)spk = NOTHING_EDIBLE; + if (game.prop[BEAR] == 3)spk = RIDICULOUS_ATTEMPT; + if (HERE(FOOD)) { + DESTROY(FOOD); + game.prop[BEAR] = 1; + game.fixed[AXE] = 0; + game.prop[AXE] = 0; + spk = BEAR_TAMED; + } + } else if (obj == OGRE) { + if (HERE(FOOD)) + spk = OGRE_FULL; } else { - spk=AM_GAME; + spk = AM_GAME; } RSPEAK(spk); return GO_CLEAROBJ; @@ -519,50 +518,53 @@ int fill(token_t verb, token_t obj) int k; int spk = ACTSPK[verb]; if (obj == VASE) { - spk=ARENT_CARRYING; - if (LIQLOC(game.loc) == 0)spk=FILL_INVALID; - if (LIQLOC(game.loc) == 0 || !TOTING(VASE)) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - RSPEAK(SHATTER_VASE); - game.prop[VASE] = 2; - game.fixed[VASE]= -1; - return(discard(verb, obj, true)); - } - else if (obj == URN) { - spk=FULL_URN; - if (game.prop[URN] != 0) {RSPEAK(spk); return GO_CLEAROBJ;} - spk=FILL_INVALID; - k=LIQUID(); - if (k == 0 || !HERE(BOTTLE)) {RSPEAK(spk); return GO_CLEAROBJ;} - game.place[k] = NOWHERE; - game.prop[BOTTLE] = 1; - if (k == OIL)game.prop[URN]=1; - spk=WATER_URN+game.prop[URN]; - RSPEAK(spk); - return GO_CLEAROBJ; - } - else if (obj != 0 && obj != BOTTLE) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - else if (obj == 0 && !HERE(BOTTLE)) - return GO_UNKNOWN; - spk=BOTTLED_WATER; + spk = ARENT_CARRYING; + if (LIQLOC(game.loc) == 0)spk = FILL_INVALID; + if (LIQLOC(game.loc) == 0 || !TOTING(VASE)) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + RSPEAK(SHATTER_VASE); + game.prop[VASE] = 2; + game.fixed[VASE] = -1; + return (discard(verb, obj, true)); + } else if (obj == URN) { + spk = FULL_URN; + if (game.prop[URN] != 0) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + spk = FILL_INVALID; + k = LIQUID(); + if (k == 0 || !HERE(BOTTLE)) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + game.place[k] = NOWHERE; + game.prop[BOTTLE] = 1; + if (k == OIL)game.prop[URN] = 1; + spk = WATER_URN + game.prop[URN]; + RSPEAK(spk); + return GO_CLEAROBJ; + } else if (obj != 0 && obj != BOTTLE) { + RSPEAK(spk); + return GO_CLEAROBJ; + } else if (obj == 0 && !HERE(BOTTLE)) + return GO_UNKNOWN; + spk = BOTTLED_WATER; if (LIQLOC(game.loc) == 0) - spk=NO_LIQUID; + spk = NO_LIQUID; if (HERE(URN) && game.prop[URN] != 0) - spk=URN_NOPOUR; + spk = URN_NOPOUR; if (LIQUID() != 0) - spk=BOTTLE_FULL; + spk = BOTTLE_FULL; if (spk == 107) { - game.prop[BOTTLE]=MOD(COND[game.loc],4)/2*2; - k=LIQUID(); - if (TOTING(BOTTLE)) - game.place[k] = CARRIED; - if (k == OIL) - spk=BOTTLED_OIL; + game.prop[BOTTLE] = MOD(COND[game.loc], 4) / 2 * 2; + k = LIQUID(); + if (TOTING(BOTTLE)) + game.place[k] = CARRIED; + if (k == OIL) + spk = BOTTLED_OIL; } RSPEAK(spk); return GO_CLEAROBJ; @@ -573,12 +575,12 @@ static int find(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (AT(obj) || - (LIQUID() == obj && AT(BOTTLE)) || - obj == LIQLOC(game.loc) || - (obj == DWARF && ATDWRF(game.loc) > 0)) - spk=YOU_HAVEIT; - if (game.closed)spk=NEEDED_NEreplace; - if (TOTING(obj))spk=ALREADY_CARRYING; + (LIQUID() == obj && AT(BOTTLE)) || + obj == LIQLOC(game.loc) || + (obj == DWARF && ATDWRF(game.loc) > 0)) + spk = YOU_HAVEIT; + if (game.closed)spk = NEEDED_NEreplace; + if (TOTING(obj))spk = ALREADY_CARRYING; RSPEAK(spk); return GO_CLEAROBJ; } @@ -588,27 +590,30 @@ static int fly(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == INTRANSITIVE) { - if (game.prop[RUG] != 2)spk=RUG_NOTHING2; - if (!HERE(RUG))spk=FLAP_ARMS; - if (spk == RUG_NOTHING2 || spk == FLAP_ARMS) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - obj=RUG; + if (game.prop[RUG] != 2)spk = RUG_NOTHING2; + if (!HERE(RUG))spk = FLAP_ARMS; + if (spk == RUG_NOTHING2 || spk == FLAP_ARMS) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + obj = RUG; } if (obj != RUG) { - RSPEAK(spk); - return GO_CLEAROBJ; + RSPEAK(spk); + return GO_CLEAROBJ; + } + spk = RUG_NOTHING1; + if (game.prop[RUG] != 2) { + RSPEAK(spk); + return GO_CLEAROBJ; } - spk=RUG_NOTHING1; - if (game.prop[RUG] != 2) {RSPEAK(spk); return GO_CLEAROBJ;} - game.oldlc2=game.oldloc; - game.oldloc=game.loc; - game.newloc=game.place[RUG]+game.fixed[RUG]-game.loc; - spk=RUG_GOES; + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; + game.newloc = game.place[RUG] + game.fixed[RUG] - game.loc; + spk = RUG_GOES; if (game.prop[SAPPH] >= 0) - spk=RUG_RETURNS; + spk = RUG_RETURNS; RSPEAK(spk); return GO_TERMINATE; } @@ -616,19 +621,19 @@ static int fly(token_t verb, token_t obj) static int inven(void) /* Inventory. If object, treat same as find. Else report on current burden. */ { - int spk=NO_CARRY; - for (int i=1; i<=NOBJECTS; i++) { - if (i == BEAR || !TOTING(i)) - continue; - if (spk == NO_CARRY) - RSPEAK(NOW_HOLDING); - game.blklin=false; - PSPEAK(i,-1); - game.blklin=true; - spk=NO_MESSAGE; + int spk = NO_CARRY; + for (int i = 1; i <= NOBJECTS; i++) { + if (i == BEAR || !TOTING(i)) + continue; + if (spk == NO_CARRY) + RSPEAK(NOW_HOLDING); + game.blklin = false; + PSPEAK(i, -1); + game.blklin = true; + spk = NO_MESSAGE; } if (TOTING(BEAR)) - spk=TAME_BEAR; + spk = TAME_BEAR; RSPEAK(spk); return GO_CLEAROBJ; } @@ -638,36 +643,35 @@ static int light(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == INTRANSITIVE) { - if (HERE(LAMP) && game.prop[LAMP] == 0 && game.limit >= 0)obj=LAMP; - if (HERE(URN) && game.prop[URN] == 1)obj=obj*NOBJECTS+URN; - if (obj == INTRANSITIVE || obj == 0 || obj > NOBJECTS) return GO_UNKNOWN; + if (HERE(LAMP) && game.prop[LAMP] == 0 && game.limit >= 0)obj = LAMP; + if (HERE(URN) && game.prop[URN] == 1)obj = obj * NOBJECTS + URN; + if (obj == INTRANSITIVE || obj == 0 || obj > NOBJECTS) return GO_UNKNOWN; } if (obj == URN) { - if (game.prop[URN] == 0) { - RSPEAK(URN_EMPTY); - } else { - game.prop[URN] = 2; - RSPEAK(URN_LIT); - } - return GO_CLEAROBJ; + if (game.prop[URN] == 0) { + RSPEAK(URN_EMPTY); + } else { + game.prop[URN] = 2; + RSPEAK(URN_LIT); + } + return GO_CLEAROBJ; } else { - if (obj != LAMP) - { - RSPEAK(spk); - return GO_CLEAROBJ; - } - spk=LAMP_OUT; - if (game.limit < 0) { - RSPEAK(spk); - return GO_CLEAROBJ; - } - game.prop[LAMP]=1; - RSPEAK(LAMP_ON); - if (game.wzdark) - return GO_TOP; - else - return GO_CLEAROBJ; + if (obj != LAMP) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + spk = LAMP_OUT; + if (game.limit < 0) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + game.prop[LAMP] = 1; + RSPEAK(LAMP_ON); + if (game.wzdark) + return GO_TOP; + else + return GO_CLEAROBJ; } } @@ -675,21 +679,21 @@ static int listen(void) /* Listen. Intransitive only. Print stuff based on objsnd/locsnd. */ { int k; - int spk=ALL_SILENT; - k=LOCSND[game.loc]; + int spk = ALL_SILENT; + k = LOCSND[game.loc]; if (k != 0) { - RSPEAK(labs(k)); - if (k < 0) return GO_CLEAROBJ; - spk=NO_MESSAGE; + RSPEAK(labs(k)); + if (k < 0) return GO_CLEAROBJ; + spk = NO_MESSAGE; } - SETPRM(1,game.zzword,0); - for (int i=1; i<=NOBJECTS; i++) { - if (!HERE(i) || OBJSND[i] == 0 || game.prop[i] < 0) - continue; - PSPEAK(i,OBJSND[i]+game.prop[i]); - spk=NO_MESSAGE; - if (i == BIRD && OBJSND[i]+game.prop[i] == 8) - DESTROY(BIRD); + SETPRM(1, game.zzword, 0); + for (int i = 1; i <= NOBJECTS; i++) { + if (!HERE(i) || OBJSND[i] == 0 || game.prop[i] < 0) + continue; + PSPEAK(i, OBJSND[i] + game.prop[i]); + spk = NO_MESSAGE; + if (i == BIRD && OBJSND[i] + game.prop[i] == 8) + DESTROY(BIRD); } RSPEAK(spk); return GO_CLEAROBJ; @@ -700,40 +704,43 @@ static int lock(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == INTRANSITIVE) { - spk=NOTHING_LOCKED; - if (HERE(CLAM))obj=CLAM; - if (HERE(OYSTER))obj=OYSTER; - if (AT(DOOR))obj=DOOR; - if (AT(GRATE))obj=GRATE; - if (obj != 0 && HERE(CHAIN)) return GO_UNKNOWN; - if (HERE(CHAIN))obj=CHAIN; - if (obj == 0) {RSPEAK(spk); return GO_CLEAROBJ;} + spk = NOTHING_LOCKED; + if (HERE(CLAM))obj = CLAM; + if (HERE(OYSTER))obj = OYSTER; + if (AT(DOOR))obj = DOOR; + if (AT(GRATE))obj = GRATE; + if (obj != 0 && HERE(CHAIN)) return GO_UNKNOWN; + if (HERE(CHAIN))obj = CHAIN; + if (obj == 0) { + RSPEAK(spk); + return GO_CLEAROBJ; + } } - + /* Lock, unlock object. Special stuff for opening clam/oyster * and for chain. */ if (obj == CLAM || obj == OYSTER) - return bivalve(verb, obj); - if (obj == DOOR)spk=RUSTY_DOOR; - if (obj == DOOR && game.prop[DOOR] == 1)spk=OK_MAN; - if (obj == CAGE)spk=NO_LOCK; - if (obj == KEYS)spk=CANNOT_UNLOCK; + return bivalve(verb, obj); + if (obj == DOOR)spk = RUSTY_DOOR; + if (obj == DOOR && game.prop[DOOR] == 1)spk = OK_MAN; + if (obj == CAGE)spk = NO_LOCK; + if (obj == KEYS)spk = CANNOT_UNLOCK; if (obj == GRATE || obj == CHAIN) { - spk=NO_KEYS; - if (HERE(KEYS)) { - if (obj == CHAIN) - return chain(verb); - if (game.closng) { - spk=EXIT_CLOSED; - if (!game.panic)game.clock2=15; - game.panic=true; - } else { - spk=game.prop[GRATE] ? GRATE_LOCKED : ALREADY_LOCKED; - game.prop[GRATE]=1; - if (verb == LOCK)game.prop[GRATE]=0; - spk=game.prop[GRATE] ? GRATE_UNLOCKED : GRATE_LOCKED; - } - } + spk = NO_KEYS; + if (HERE(KEYS)) { + if (obj == CHAIN) + return chain(verb); + if (game.closng) { + spk = EXIT_CLOSED; + if (!game.panic)game.clock2 = 15; + game.panic = true; + } else { + spk = game.prop[GRATE] ? GRATE_LOCKED : ALREADY_LOCKED; + game.prop[GRATE] = 1; + if (verb == LOCK)game.prop[GRATE] = 0; + spk = game.prop[GRATE] ? GRATE_UNLOCKED : GRATE_LOCKED; + } + } } RSPEAK(spk); return GO_CLEAROBJ; @@ -744,39 +751,50 @@ static int pour(token_t verb, token_t obj) * special tests for pouring water or oil on plant or rusty door. */ { int spk = ACTSPK[verb]; - if (obj == BOTTLE || obj == 0)obj=LIQUID(); + if (obj == BOTTLE || obj == 0)obj = LIQUID(); if (obj == 0) return GO_UNKNOWN; - if (!TOTING(obj)) {RSPEAK(spk); return GO_CLEAROBJ;} - spk=CANT_POUR; - if (obj != OIL && obj != WATER) {RSPEAK(spk); return GO_CLEAROBJ;} + if (!TOTING(obj)) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + spk = CANT_POUR; + if (obj != OIL && obj != WATER) { + RSPEAK(spk); + return GO_CLEAROBJ; + } if (HERE(URN) && game.prop[URN] == 0) - return fill(verb, URN); + return fill(verb, URN); game.prop[BOTTLE] = 1; game.place[obj] = NOWHERE; - spk=GROUND_WET; - if (!(AT(PLANT) || AT(DOOR))) - {RSPEAK(spk); return GO_CLEAROBJ;} + spk = GROUND_WET; + if (!(AT(PLANT) || AT(DOOR))) { + RSPEAK(spk); + return GO_CLEAROBJ; + } if (!AT(DOOR)) { - spk=SHAKING_LEAVES; - if (obj != WATER) {RSPEAK(spk); return GO_CLEAROBJ;} - PSPEAK(PLANT,game.prop[PLANT]+3); - game.prop[PLANT]=MOD(game.prop[PLANT]+1,3); - game.prop[PLANT2]=game.prop[PLANT]; - return GO_MOVE; + spk = SHAKING_LEAVES; + if (obj != WATER) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + PSPEAK(PLANT, game.prop[PLANT] + 3); + game.prop[PLANT] = MOD(game.prop[PLANT] + 1, 3); + game.prop[PLANT2] = game.prop[PLANT]; + return GO_MOVE; } else { - game.prop[DOOR]=0; - if (obj == OIL)game.prop[DOOR]=1; - spk=RUSTED_HINGES+game.prop[DOOR]; - RSPEAK(spk); - return GO_CLEAROBJ; + game.prop[DOOR] = 0; + if (obj == OIL)game.prop[DOOR] = 1; + spk = RUSTED_HINGES + game.prop[DOOR]; + RSPEAK(spk); + return GO_CLEAROBJ; } } static int quit(FILE *input) /* Quit. Intransitive only. Verify intent and exit if that's what he wants. */ { - if (YES(input,REALLY_QUIT,OK_MAN,OK_MAN)) - score(quitgame); + if (YES(input, REALLY_QUIT, OK_MAN, OK_MAN)) + score(quitgame); return GO_CLEAROBJ; } @@ -785,48 +803,48 @@ static int read(FILE *input, token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj == INTRANSITIVE) { - obj = 0; - for (int i=1; i<=NOBJECTS; i++) { - if (HERE(i) && OBJTXT[i] != 0 && game.prop[i] >= 0) - obj = obj * NOBJECTS + i; - } - if (obj > NOBJECTS || obj == 0 || DARK(game.loc)) return GO_UNKNOWN; + obj = 0; + for (int i = 1; i <= NOBJECTS; i++) { + if (HERE(i) && OBJTXT[i] != 0 && game.prop[i] >= 0) + obj = obj * NOBJECTS + i; + } + if (obj > NOBJECTS || obj == 0 || DARK(game.loc)) return GO_UNKNOWN; } - + if (DARK(game.loc)) { - SETPRM(1,WD1,WD1X); - RSPEAK(NO_SEE); - return GO_CLEAROBJ; + SETPRM(1, WD1, WD1X); + RSPEAK(NO_SEE); + return GO_CLEAROBJ; } if (OBJTXT[obj] == 0 || game.prop[obj] < 0) { - RSPEAK(spk); - return GO_CLEAROBJ; + RSPEAK(spk); + return GO_CLEAROBJ; } if (obj == OYSTER && !game.clshnt) { - game.clshnt=YES(input,CLUE_QUERY,WAYOUT_CLUE,OK_MAN); - return GO_CLEAROBJ; + game.clshnt = YES(input, CLUE_QUERY, WAYOUT_CLUE, OK_MAN); + return GO_CLEAROBJ; } - PSPEAK(obj,OBJTXT[obj]+game.prop[obj]); + PSPEAK(obj, OBJTXT[obj] + game.prop[obj]); return GO_CLEAROBJ; } static int reservoir(void) /* Z'ZZZ (word gets recomputed at startup; different each game). */ { - if (!AT(RESER) && game.loc != game.fixed[RESER]-1) { - RSPEAK(NOTHING_HAPPENS); - return GO_CLEAROBJ; + if (!AT(RESER) && game.loc != game.fixed[RESER] - 1) { + RSPEAK(NOTHING_HAPPENS); + return GO_CLEAROBJ; } else { - PSPEAK(RESER,game.prop[RESER]+1); - game.prop[RESER]=1-game.prop[RESER]; - if (AT(RESER)) - return GO_CLEAROBJ; - else { - game.oldlc2=game.loc; - game.newloc=0; - RSPEAK(NOT_BRIGHT); - return GO_TERMINATE; - } + PSPEAK(RESER, game.prop[RESER] + 1); + game.prop[RESER] = 1 - game.prop[RESER]; + if (AT(RESER)) + return GO_CLEAROBJ; + else { + game.oldlc2 = game.loc; + game.newloc = 0; + RSPEAK(NOT_BRIGHT); + return GO_TERMINATE; + } } } @@ -835,14 +853,14 @@ static int rub(token_t verb, token_t obj) { int spk = ACTSPK[verb]; if (obj != LAMP) - spk=PECULIAR_NOTHING; + spk = PECULIAR_NOTHING; if (obj == URN && game.prop[URN] == 2) { - DESTROY(URN); - DROP(AMBER,game.loc); - game.prop[AMBER]=1; - --game.tally; - DROP(CAVITY,game.loc); - spk=URN_GENIES; + DESTROY(URN); + DROP(AMBER, game.loc); + game.prop[AMBER] = 1; + --game.tally; + DROP(CAVITY, game.loc); + spk = URN_GENIES; } RSPEAK(spk); return GO_CLEAROBJ; @@ -852,16 +870,16 @@ static int say(void) /* Say. Echo WD2 (or WD1 if no WD2 (SAY WHAT?, etc.).) Magic words override. */ { /* FIXME: ugly use of globals */ - SETPRM(1,WD2,WD2X); + SETPRM(1, WD2, WD2X); if (WD2 <= 0) - SETPRM(1,WD1,WD1X); + SETPRM(1, WD1, WD1X); if (WD2 > 0) - WD1=WD2; - int wd=VOCAB(WD1,-1); + WD1 = WD2; + int wd = VOCAB(WD1, -1); /* FIXME: Magic numbers */ if (wd == 62 || wd == 65 || wd == 71 || wd == 2025 || wd == 2034) { - WD2=0; - return GO_LOOKUP; + WD2 = 0; + return GO_LOOKUP; } RSPEAK(OKEY_DOKEY); return GO_CLEAROBJ; @@ -870,72 +888,72 @@ static int say(void) static int throw_support(long spk) { RSPEAK(spk); - DROP(AXE,game.loc); + DROP(AXE, game.loc); return GO_MOVE; } -static int throw(FILE *cmdin, long verb, token_t obj) +static int throw (FILE *cmdin, long verb, token_t obj) /* Throw. Same as discard unless axe. Then same as attack except * ignore bird, and if dwarf is present then one might be killed. * (Only way to do so!) Axe also special for dragon, bear, and * troll. Treasures special for troll. */ { int spk = ACTSPK[verb]; - if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj=ROD2; + if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj = ROD2; if (!TOTING(obj)) { - RSPEAK(spk); - return GO_CLEAROBJ; + RSPEAK(spk); + return GO_CLEAROBJ; } if (obj >= MINTRS && obj <= MAXTRS && AT(TROLL)) { - spk=TROLL_SATISFIED; + spk = TROLL_SATISFIED; /* Snarf a treasure for the troll. */ - DROP(obj,0); - MOVE(TROLL,0); - MOVE(TROLL+NOBJECTS,0); - DROP(TROLL2,PLAC[TROLL]); - DROP(TROLL2+NOBJECTS,FIXD[TROLL]); + DROP(obj, 0); + MOVE(TROLL, 0); + MOVE(TROLL + NOBJECTS, 0); + DROP(TROLL2, PLAC[TROLL]); + DROP(TROLL2 + NOBJECTS, FIXD[TROLL]); JUGGLE(CHASM); RSPEAK(spk); - return GO_CLEAROBJ; + return GO_CLEAROBJ; } if (obj == FOOD && HERE(BEAR)) { - /* But throwing food is another story. */ - obj=BEAR; - return(feed(verb, obj)); + /* But throwing food is another story. */ + obj = BEAR; + return (feed(verb, obj)); } if (obj != AXE) - return(discard(verb, obj, false)); - int i=ATDWRF(game.loc); + return (discard(verb, obj, false)); + int i = ATDWRF(game.loc); if (i <= 0) { if (AT(DRAGON) && game.prop[DRAGON] == 0) { - spk=DRAGON_SCALES; + spk = DRAGON_SCALES; return throw_support(spk); } if (AT(TROLL)) { - spk=TROLL_RETURNS; + spk = TROLL_RETURNS; return throw_support(spk); } if (AT(OGRE)) { - spk=OGRE_DODGE; + spk = OGRE_DODGE; return throw_support(spk); } if (HERE(BEAR) && game.prop[BEAR] == 0) { /* This'll teach him to throw the axe at the bear! */ - DROP(AXE,game.loc); + DROP(AXE, game.loc); game.fixed[AXE] = -1; game.prop[AXE] = 1; JUGGLE(BEAR); RSPEAK(AXE_LOST); - return GO_CLEAROBJ; + return GO_CLEAROBJ; } - return(attack(cmdin, verb, 0)); + return (attack(cmdin, verb, 0)); } - if (randrange(NDWARVES+1) < game.dflag) { + if (randrange(NDWARVES + 1) < game.dflag) { return throw_support(DWARF_DODGES); } - game.dseen[i]=false; - game.dloc[i]=0; + game.dseen[i] = false; + game.dloc[i] = 0; return throw_support((++game.dkill == 1) ? DWARF_SMOKE : KILLED_DWARF); } @@ -950,11 +968,11 @@ static int wake(token_t verb, token_t obj) /* Wake. Only use is to disturb the dwarves. */ { if (obj != DWARF || !game.closed) { - RSPEAK(ACTSPK[verb]); - return GO_CLEAROBJ; + RSPEAK(ACTSPK[verb]); + return GO_CLEAROBJ; } else { - RSPEAK(PROD_DWARF); - return GO_DWARFWAKE; + RSPEAK(PROD_DWARF); + return GO_DWARFWAKE; } } @@ -962,31 +980,34 @@ static int wave(token_t verb, token_t obj) /* Wave. No effect unless waving rod at fissure or at bird. */ { int spk = ACTSPK[verb]; - if ((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2)))spk=ARENT_CARRYING; + if ((!TOTING(obj)) && (obj != ROD || !TOTING(ROD2)))spk = ARENT_CARRYING; if (obj != ROD || - !TOTING(obj) || - (!HERE(BIRD) && (game.closng || !AT(FISSUR)))) { - RSPEAK(spk); - return GO_CLEAROBJ; + !TOTING(obj) || + (!HERE(BIRD) && (game.closng || !AT(FISSUR)))) { + RSPEAK(spk); + return GO_CLEAROBJ; } - if (HERE(BIRD))spk=FREE_FLY+MOD(game.prop[BIRD],2); + if (HERE(BIRD))spk = FREE_FLY + MOD(game.prop[BIRD], 2); if (spk == 206 && game.loc == game.place[STEPS] && game.prop[JADE] < 0) { - DROP(JADE,game.loc); - game.prop[JADE]=0; - --game.tally; - spk=NECKLACE_FLY; - RSPEAK(spk); - return GO_CLEAROBJ; + DROP(JADE, game.loc); + game.prop[JADE] = 0; + --game.tally; + spk = NECKLACE_FLY; + RSPEAK(spk); + return GO_CLEAROBJ; } else { - if (game.closed) { - RSPEAK(spk); - return GO_DWARFWAKE; - } - if (game.closng || !AT(FISSUR)) {RSPEAK(spk); return GO_CLEAROBJ;} - if (HERE(BIRD))RSPEAK(spk); - game.prop[FISSUR]=1-game.prop[FISSUR]; - PSPEAK(FISSUR,2-game.prop[FISSUR]); - return GO_CLEAROBJ; + if (game.closed) { + RSPEAK(spk); + return GO_DWARFWAKE; + } + if (game.closng || !AT(FISSUR)) { + RSPEAK(spk); + return GO_CLEAROBJ; + } + if (HERE(BIRD))RSPEAK(spk); + game.prop[FISSUR] = 1 - game.prop[FISSUR]; + PSPEAK(FISSUR, 2 - game.prop[FISSUR]); + return GO_CLEAROBJ; } } @@ -995,155 +1016,242 @@ int action(FILE *input, enum speechpart part, long verb, token_t obj) * unless verb is "say", which snarfs arbitrary second word. */ { - token_t spk=ACTSPK[verb]; + token_t spk = ACTSPK[verb]; - if (part == unknown) - { - /* Analyse an object word. See if the thing is here, whether - * we've got a verb yet, and so on. Object must be here - * unless verb is "find" or "invent(ory)" (and no new verb - * yet to be analysed). Water and oil are also funny, since - * they are never actually dropped at any location, but might - * be here inside the bottle or urn or as a feature of the - * location. */ - if (HERE(obj)) - /* FALL THROUGH */; - else if (obj == GRATE) { - if (game.loc == LOC_START || game.loc == LOC_VALLEY || game.loc == LOC_SLIT) - obj=DPRSSN; - if (game.loc == LOC_COBBLE || game.loc == LOC_DEBRIS || game.loc == LOC_AWKWARD || - game.loc == LOC_BIRD || game.loc == LOC_PITTOP) - obj=ENTRNC; - if (obj != GRATE) - return GO_MOVE; - } - else if (obj == DWARF && ATDWRF(game.loc) > 0) - /* FALL THROUGH */; - else if ((LIQUID() == obj && HERE(BOTTLE)) || obj == LIQLOC(game.loc)) - /* FALL THROUGH */; - else if (obj == OIL && HERE(URN) && game.prop[URN] != 0) { - obj=URN; - /* FALL THROUGH */; - } - else if (obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) { - obj=PLANT2; - /* FALL THROUGH */; - } - else if (obj == KNIFE && game.knfloc == game.loc) { - game.knfloc= -1; - spk=KNIVES_VANISH; - RSPEAK(spk); - return GO_CLEAROBJ; - } - else if (obj == ROD && HERE(ROD2)) { - obj=ROD2; - /* FALL THROUGH */; - } - else if ((verb == FIND || verb == INVENT) && WD2 <= 0) - /* FALL THROUGH */; - else { - SETPRM(1,WD1,WD1X); - RSPEAK(NO_SEE); - return GO_CLEAROBJ; - } + if (part == unknown) { + /* Analyse an object word. See if the thing is here, whether + * we've got a verb yet, and so on. Object must be here + * unless verb is "find" or "invent(ory)" (and no new verb + * yet to be analysed). Water and oil are also funny, since + * they are never actually dropped at any location, but might + * be here inside the bottle or urn or as a feature of the + * location. */ + if (HERE(obj)) + /* FALL THROUGH */; + else if (obj == GRATE) { + if (game.loc == LOC_START || game.loc == LOC_VALLEY || game.loc == LOC_SLIT) + obj = DPRSSN; + if (game.loc == LOC_COBBLE || game.loc == LOC_DEBRIS || game.loc == LOC_AWKWARD || + game.loc == LOC_BIRD || game.loc == LOC_PITTOP) + obj = ENTRNC; + if (obj != GRATE) + return GO_MOVE; + } else if (obj == DWARF && ATDWRF(game.loc) > 0) + /* FALL THROUGH */; + else if ((LIQUID() == obj && HERE(BOTTLE)) || obj == LIQLOC(game.loc)) + /* FALL THROUGH */; + else if (obj == OIL && HERE(URN) && game.prop[URN] != 0) { + obj = URN; + /* FALL THROUGH */; + } else if (obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) { + obj = PLANT2; + /* FALL THROUGH */; + } else if (obj == KNIFE && game.knfloc == game.loc) { + game.knfloc = -1; + spk = KNIVES_VANISH; + RSPEAK(spk); + return GO_CLEAROBJ; + } else if (obj == ROD && HERE(ROD2)) { + obj = ROD2; + /* FALL THROUGH */; + } else if ((verb == FIND || verb == INVENT) && WD2 <= 0) + /* FALL THROUGH */; + else { + SETPRM(1, WD1, WD1X); + RSPEAK(NO_SEE); + return GO_CLEAROBJ; + } - if (WD2 > 0) - return GO_WORD2; - if (verb != 0) - part = transitive; + if (WD2 > 0) + return GO_WORD2; + if (verb != 0) + part = transitive; } - switch(part) - { - case intransitive: - if (WD2 > 0 && verb != SAY) return(2800); - if (verb == SAY)obj=WD2; - if (obj == 0 || obj == INTRANSITIVE) { - /* Analyse an intransitive verb (ie, no object given yet). */ - switch (verb-1) { - case 0: /* CARRY */ return carry(verb, INTRANSITIVE); - case 1: /* DROP */ return GO_UNKNOWN; - case 2: /* SAY */ return GO_UNKNOWN; - case 3: /* UNLOC */ return lock(verb, INTRANSITIVE); - case 4: /* NOTHI */ {RSPEAK(OK_MAN); return(GO_CLEAROBJ);} - case 5: /* LOCK */ return lock(verb, INTRANSITIVE); - case 6: /* LIGHT */ return light(verb, INTRANSITIVE); - case 7: /* EXTIN */ return extinguish(verb, INTRANSITIVE); - case 8: /* WAVE */ return GO_UNKNOWN; - case 9: /* CALM */ return GO_UNKNOWN; - case 10: /* WALK */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 11: /* ATTAC */ return attack(input, verb, obj); - case 12: /* POUR */ return pour(verb, obj); - case 13: /* EAT */ return eat(verb, INTRANSITIVE); - case 14: /* DRINK */ return drink(verb, obj); - case 15: /* RUB */ return GO_UNKNOWN; - case 16: /* TOSS */ return GO_UNKNOWN; - case 17: /* QUIT */ return quit(input); - case 18: /* FIND */ return GO_UNKNOWN; - case 19: /* INVEN */ return inven(); - case 20: /* FEED */ return GO_UNKNOWN; - case 21: /* FILL */ return fill(verb, obj); - case 22: /* BLAST */ blast(); return GO_CLEAROBJ; - case 23: /* SCOR */ return vscore(); - case 24: /* FOO */ return bigwords(WD1); - case 25: /* BRIEF */ return brief(); - case 26: /* READ */ return read(input, verb, INTRANSITIVE); - case 27: /* BREAK */ return GO_UNKNOWN; - case 28: /* WAKE */ return GO_UNKNOWN; - case 29: /* SUSP */ return suspend(input); - case 30: /* RESU */ return resume(input); - case 31: /* FLY */ return fly(verb, INTRANSITIVE); - case 32: /* LISTE */ return listen(); - case 33: /* ZZZZ */ return reservoir(); - } - BUG(23); - } - /* FALLTHRU */ - case transitive: - /* Analyse a transitive verb. */ - switch (verb-1) { - case 0: /* CARRY */ return carry(verb, obj); - case 1: /* DROP */ return discard(verb, obj, false); - case 2: /* SAY */ return say(); - case 3: /* UNLOC */ return lock(verb, obj); - case 4: /* NOTHI */ {RSPEAK(OK_MAN); return(GO_CLEAROBJ);} - case 5: /* LOCK */ return lock(verb, obj); - case 6: /* LIGHT */ return light(verb, obj); - case 7: /* EXTI */ return extinguish(verb, obj); - case 8: /* WAVE */ return wave(verb, obj); - case 9: /* CALM */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 10: /* WALK */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 11: /* ATTAC */ return attack(input, verb, obj); - case 12: /* POUR */ return pour(verb, obj); - case 13: /* EAT */ return eat(verb, obj); - case 14: /* DRINK */ return drink(verb, obj); - case 15: /* RUB */ return rub(verb, obj); - case 16: /* TOSS */ return throw(input, verb, obj); - case 17: /* QUIT */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 18: /* FIND */ return find(verb, obj); - case 19: /* INVEN */ return find(verb, obj); - case 20: /* FEED */ return feed(verb, obj); - case 21: /* FILL */ return fill(verb, obj); - case 22: /* BLAST */ blast(); return GO_CLEAROBJ; - case 23: /* SCOR */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 24: /* FOO */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 25: /* BRIEF */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 26: /* READ */ return read(input, verb, obj); - case 27: /* BREAK */ return vbreak(verb, obj); - case 28: /* WAKE */ return wake(verb, obj); - case 29: /* SUSP */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 30: /* RESU */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 31: /* FLY */ return fly(verb, obj); - case 32: /* LISTE */ {RSPEAK(spk); return GO_CLEAROBJ;} - case 33: /* ZZZZ */ return reservoir(); - } - BUG(24); - case unknown: - /* Unknown verb, couldn't deduce object - might need hint */ - SETPRM(1,WD1,WD1X); - RSPEAK(WHAT_DO); - return GO_CHECKHINT; + switch (part) { + case intransitive: + if (WD2 > 0 && verb != SAY) return (2800); + if (verb == SAY)obj = WD2; + if (obj == 0 || obj == INTRANSITIVE) { + /* Analyse an intransitive verb (ie, no object given yet). */ + switch (verb - 1) { + case 0: /* CARRY */ + return carry(verb, INTRANSITIVE); + case 1: /* DROP */ + return GO_UNKNOWN; + case 2: /* SAY */ + return GO_UNKNOWN; + case 3: /* UNLOC */ + return lock(verb, INTRANSITIVE); + case 4: { /* NOTHI */ + RSPEAK(OK_MAN); + return (GO_CLEAROBJ); + } + case 5: /* LOCK */ + return lock(verb, INTRANSITIVE); + case 6: /* LIGHT */ + return light(verb, INTRANSITIVE); + case 7: /* EXTIN */ + return extinguish(verb, INTRANSITIVE); + case 8: /* WAVE */ + return GO_UNKNOWN; + case 9: /* CALM */ + return GO_UNKNOWN; + case 10: { /* WALK */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 11: /* ATTAC */ + return attack(input, verb, obj); + case 12: /* POUR */ + return pour(verb, obj); + case 13: /* EAT */ + return eat(verb, INTRANSITIVE); + case 14: /* DRINK */ + return drink(verb, obj); + case 15: /* RUB */ + return GO_UNKNOWN; + case 16: /* TOSS */ + return GO_UNKNOWN; + case 17: /* QUIT */ + return quit(input); + case 18: /* FIND */ + return GO_UNKNOWN; + case 19: /* INVEN */ + return inven(); + case 20: /* FEED */ + return GO_UNKNOWN; + case 21: /* FILL */ + return fill(verb, obj); + case 22: /* BLAST */ + blast(); + return GO_CLEAROBJ; + case 23: /* SCOR */ + return vscore(); + case 24: /* FOO */ + return bigwords(WD1); + case 25: /* BRIEF */ + return brief(); + case 26: /* READ */ + return read(input, verb, INTRANSITIVE); + case 27: /* BREAK */ + return GO_UNKNOWN; + case 28: /* WAKE */ + return GO_UNKNOWN; + case 29: /* SUSP */ + return suspend(input); + case 30: /* RESU */ + return resume(input); + case 31: /* FLY */ + return fly(verb, INTRANSITIVE); + case 32: /* LISTE */ + return listen(); + case 33: /* ZZZZ */ + return reservoir(); + } + BUG(23); + } + /* FALLTHRU */ + case transitive: + /* Analyse a transitive verb. */ + switch (verb - 1) { + case 0: /* CARRY */ + return carry(verb, obj); + case 1: /* DROP */ + return discard(verb, obj, false); + case 2: /* SAY */ + return say(); + case 3: /* UNLOC */ + return lock(verb, obj); + case 4: { /* NOTHI */ + RSPEAK(OK_MAN); + return (GO_CLEAROBJ); + } + case 5: /* LOCK */ + return lock(verb, obj); + case 6: /* LIGHT */ + return light(verb, obj); + case 7: /* EXTI */ + return extinguish(verb, obj); + case 8: /* WAVE */ + return wave(verb, obj); + case 9: { /* CALM */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 10: { /* WALK */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 11: /* ATTAC */ + return attack(input, verb, obj); + case 12: /* POUR */ + return pour(verb, obj); + case 13: /* EAT */ + return eat(verb, obj); + case 14: /* DRINK */ + return drink(verb, obj); + case 15: /* RUB */ + return rub(verb, obj); + case 16: /* TOSS */ + return throw (input, verb, obj); + case 17: { /* QUIT */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 18: /* FIND */ + return find(verb, obj); + case 19: /* INVEN */ + return find(verb, obj); + case 20: /* FEED */ + return feed(verb, obj); + case 21: /* FILL */ + return fill(verb, obj); + case 22: /* BLAST */ + blast(); + return GO_CLEAROBJ; + case 23: { /* SCOR */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 24: { /* FOO */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 25: { /* BRIEF */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 26: /* READ */ + return read(input, verb, obj); + case 27: /* BREAK */ + return vbreak(verb, obj); + case 28: /* WAKE */ + return wake(verb, obj); + case 29: { /* SUSP */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 30: { /* RESU */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 31: /* FLY */ + return fly(verb, obj); + case 32: { /* LISTE */ + RSPEAK(spk); + return GO_CLEAROBJ; + } + case 33: /* ZZZZ */ + return reservoir(); + } + BUG(24); + case unknown: + /* Unknown verb, couldn't deduce object - might need hint */ + SETPRM(1, WD1, WD1X); + RSPEAK(WHAT_DO); + return GO_CHECKHINT; default: - BUG(99); + BUG(99); } } diff --git a/common.c b/common.c index 61394ec..a53f4f5 100644 --- a/common.c +++ b/common.c @@ -1,34 +1,34 @@ #include "common.h" const char advent_to_ascii[] = { - ' ', '!', '\"', '\'', '(', ')', '*', '+', ',', '-', - '.', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', - 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - 'x', 'y', 'z', '%', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', - '\x06', '\x07', '\x08', '\x00', '\x00', '\x0b', '\x0c', '\r', '\x0e', '\x0f', - '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', - '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', '#', '$', '&', '/', - ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', - '^', '_', '`', '{', '|', '}', '~', '\x00', + ' ', '!', '\"', '\'', '(', ')', '*', '+', ',', '-', + '.', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', + 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', + 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '%', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', + '\x06', '\x07', '\x08', '\x00', '\x00', '\x0b', '\x0c', '\r', '\x0e', '\x0f', + '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', + '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', '#', '$', '&', '/', + ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', + '^', '_', '`', '{', '|', '}', '~', '\x00', }; /* Rendered from the now-gone MPINIT() function */ const char ascii_to_advent[] = { - 74, 75, 76, 77, 78, 79, 80, 81, 82, 0, - 0, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 0, 1, 2, 106, 107, 63, 108, 3, - 4, 5, 6, 7, 8, 9, 10, 109, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 110, 111, - 112, 113, 114, 115, 116, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 117, 118, 119, 120, 121, 122, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 123, 124, 125, 126, 83, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 0, + 0, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 0, 1, 2, 106, 107, 63, 108, 3, + 4, 5, 6, 7, 8, 9, 10, 109, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 110, 111, + 112, 113, 114, 115, 116, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 117, 118, 119, 120, 121, 122, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 123, 124, 125, 126, 83, }; diff --git a/dungeon.c b/dungeon.c index 5b94d95..1ca2832 100644 --- a/dungeon.c +++ b/dungeon.c @@ -24,7 +24,7 @@ // Global variables for use in functions below that can gradually disappear as code is cleaned up static long LNLENG; static long LNPOSN; -static char INLINE[LINESIZE+1]; +static char INLINE[LINESIZE + 1]; static long OLDLOC; // Storage for what comes out of the database @@ -34,11 +34,11 @@ long CLSSES; long TRNVLS; long TABNDX; long HNTMAX; -long PTEXT[NOBJECTS+1]; +long PTEXT[NOBJECTS + 1]; long RTEXT[RTXSIZ + 1]; long CTEXT[CLSMAX + 1]; -long OBJSND[NOBJECTS+1]; -long OBJTXT[NOBJECTS+1]; +long OBJSND[NOBJECTS + 1]; +long OBJTXT[NOBJECTS + 1]; long STEXT[LOCSIZ + 1]; long LTEXT[LOCSIZ + 1]; long COND[LOCSIZ + 1]; @@ -51,245 +51,234 @@ long TRNVAL[TRNSIZ + 1]; long TRAVEL[TRVSIZ + 1]; long KTAB[TABSIZ + 1]; long ATAB[TABSIZ + 1]; -long PLAC[NOBJECTS+1]; -long FIXD[NOBJECTS+1]; +long PLAC[NOBJECTS + 1]; +long FIXD[NOBJECTS + 1]; long ACTSPK[VRBSIZ + 1]; long HINTS[HNTSIZ + 1][HINTLEN]; static bool is_set(long var, long position) { - long mask = 1l << position; - bool result = (var & mask) == mask; - return(result); + long mask = 1l << position; + bool result = (var & mask) == mask; + return (result); } -static long GETTXT(long SKIP,long ONEWRD, long UPPER) +static long GETTXT(long SKIP, long ONEWRD, long UPPER) { - /* Take characters from an input line and pack them into 30-bit words. - * Skip says to skip leading blanks. ONEWRD says stop if we come to a - * blank. UPPER says to map all letters to uppercase. If we reach the - * end of the line, the word is filled up with blanks (which encode as 0's). - * If we're already at end of line when GETTXT is called, we return -1. */ - - long TEXT; - static long SPLITTING = -1; - - if(LNPOSN != SPLITTING) - SPLITTING = -1; - TEXT= -1; - while (true) { - if(LNPOSN > LNLENG) - return(TEXT); - if((!SKIP) || INLINE[LNPOSN] != 0) - break; - LNPOSN=LNPOSN+1; - } - - TEXT=0; - for (int I=1; I<=TOKLEN; I++) { - TEXT=TEXT*64; - if(LNPOSN > LNLENG || (ONEWRD && INLINE[LNPOSN] == 0)) - continue; - char current=INLINE[LNPOSN]; - if(current < 63) { - SPLITTING = -1; - if(UPPER && current >= 37) - current=current-26; - TEXT=TEXT+current; - LNPOSN=LNPOSN+1; - continue; - } - if(SPLITTING != LNPOSN) { - TEXT=TEXT+63; - SPLITTING = LNPOSN; - continue; - } - - TEXT=TEXT+current-63; - SPLITTING = -1; - LNPOSN=LNPOSN+1; - } - - return(TEXT); + /* Take characters from an input line and pack them into 30-bit words. + * Skip says to skip leading blanks. ONEWRD says stop if we come to a + * blank. UPPER says to map all letters to uppercase. If we reach the + * end of the line, the word is filled up with blanks (which encode as 0's). + * If we're already at end of line when GETTXT is called, we return -1. */ + + long TEXT; + static long SPLITTING = -1; + + if (LNPOSN != SPLITTING) + SPLITTING = -1; + TEXT = -1; + while (true) { + if (LNPOSN > LNLENG) + return (TEXT); + if ((!SKIP) || INLINE[LNPOSN] != 0) + break; + LNPOSN = LNPOSN + 1; + } + + TEXT = 0; + for (int I = 1; I <= TOKLEN; I++) { + TEXT = TEXT * 64; + if (LNPOSN > LNLENG || (ONEWRD && INLINE[LNPOSN] == 0)) + continue; + char current = INLINE[LNPOSN]; + if (current < 63) { + SPLITTING = -1; + if (UPPER && current >= 37) + current = current - 26; + TEXT = TEXT + current; + LNPOSN = LNPOSN + 1; + continue; + } + if (SPLITTING != LNPOSN) { + TEXT = TEXT + 63; + SPLITTING = LNPOSN; + continue; + } + + TEXT = TEXT + current - 63; + SPLITTING = -1; + LNPOSN = LNPOSN + 1; + } + + return (TEXT); } -static void BUG(long NUM) { - - /* The following conditions are currently considered fatal bugs. Numbers < 20 - * are detected while reading the database; the others occur at "run time". - * 0 Message line > 70 characters - * 1 Null line in message - * 2 Too many words of messages - * 3 Too many travel options - * 4 Too many vocabulary words - * 5 Required vocabulary word not found - * 6 Too many RTEXT messages - * 7 Too many hints - * 8 Location has cond bit being set twice - * 9 Invalid section number in database - * 10 Too many locations - * 11 Too many class or turn messages - * 20 Special travel (500>L>300) exceeds goto list - * 21 Ran off end of vocabulary table - * 22 Vocabulary type (N/1000) not between 0 and 3 - * 23 Intransitive action verb exceeds goto list - * 24 Transitive action verb exceeds goto list - * 25 Conditional travel entry with no alternative - * 26 Location has no travel entries - * 27 Hint number exceeds goto list - * 28 Invalid month returned by date function - * 29 Too many parameters given to SETPRM */ - - fprintf(stderr, "Fatal error %ld. See source code for interpretation.\n", NUM); - exit(EXIT_FAILURE); +static void BUG(long NUM) +{ + + /* The following conditions are currently considered fatal bugs. Numbers < 20 + * are detected while reading the database; the others occur at "run time". + * 0 Message line > 70 characters + * 1 Null line in message + * 2 Too many words of messages + * 3 Too many travel options + * 4 Too many vocabulary words + * 5 Required vocabulary word not found + * 6 Too many RTEXT messages + * 7 Too many hints + * 8 Location has cond bit being set twice + * 9 Invalid section number in database + * 10 Too many locations + * 11 Too many class or turn messages + * 20 Special travel (500>L>300) exceeds goto list + * 21 Ran off end of vocabulary table + * 22 Vocabulary type (N/1000) not between 0 and 3 + * 23 Intransitive action verb exceeds goto list + * 24 Transitive action verb exceeds goto list + * 25 Conditional travel entry with no alternative + * 26 Location has no travel entries + * 27 Hint number exceeds goto list + * 28 Invalid month returned by date function + * 29 Too many parameters given to SETPRM */ + + fprintf(stderr, "Fatal error %ld. See source code for interpretation.\n", NUM); + exit(EXIT_FAILURE); } -static void MAPLIN(FILE *OPENED) { - /* Read a line of input, from the specified input source, - * translate the chars to integers in the range 0-126 and store - * them in the common array "INLINE". Integer values are as follows: - * 0 = space [ASCII CODE 40 octal, 32 decimal] - * 1-2 = !" [ASCII 41-42 octal, 33-34 decimal] - * 3-10 = '()*+,-. [ASCII 47-56 octal, 39-46 decimal] - * 11-36 = upper-case letters - * 37-62 = lower-case letters - * 63 = percent (%) [ASCII 45 octal, 37 decimal] - * 64-73 = digits, 0 through 9 - * Remaining characters can be translated any way that is convenient; - * The "TYPE" routine below is used to map them back to characters when - * necessary. The above mappings are required so that certain special - * characters are known to fit in 6 bits and/or can be easily spotted. - * Array elements beyond the end of the line should be filled with 0, - * and LNLENG should be set to the index of the last character. - * - * If the data file uses a character other than space (e.g., tab) to - * separate numbers, that character should also translate to 0. - * - * This procedure may use the map1,map2 arrays to maintain static data for - * the mapping. MAP2(1) is set to 0 when the program starts - * and is not changed thereafter unless the routines on this page choose - * to do so. */ - - do { - if (NULL == fgets(INLINE + 1, sizeof(INLINE) - 1, OPENED)) { - printf("Failed fgets()\n"); - } - } - while (!feof(OPENED) && INLINE[1] == '#'); - - LNLENG = 0; - for (size_t i = 1; i < sizeof(INLINE) && INLINE[i] != 0; ++i) - { - char val = INLINE[i]; - INLINE[i] = ascii_to_advent[(unsigned)val]; - if (INLINE[i] != 0) - LNLENG = i; - } - LNPOSN = 1; +static void MAPLIN(FILE *OPENED) +{ + /* Read a line of input, from the specified input source, + * translate the chars to integers in the range 0-126 and store + * them in the common array "INLINE". Integer values are as follows: + * 0 = space [ASCII CODE 40 octal, 32 decimal] + * 1-2 = !" [ASCII 41-42 octal, 33-34 decimal] + * 3-10 = '()*+,-. [ASCII 47-56 octal, 39-46 decimal] + * 11-36 = upper-case letters + * 37-62 = lower-case letters + * 63 = percent (%) [ASCII 45 octal, 37 decimal] + * 64-73 = digits, 0 through 9 + * Remaining characters can be translated any way that is convenient; + * The "TYPE" routine below is used to map them back to characters when + * necessary. The above mappings are required so that certain special + * characters are known to fit in 6 bits and/or can be easily spotted. + * Array elements beyond the end of the line should be filled with 0, + * and LNLENG should be set to the index of the last character. + * + * If the data file uses a character other than space (e.g., tab) to + * separate numbers, that character should also translate to 0. + * + * This procedure may use the map1,map2 arrays to maintain static data for + * the mapping. MAP2(1) is set to 0 when the program starts + * and is not changed thereafter unless the routines on this page choose + * to do so. */ + + do { + if (NULL == fgets(INLINE + 1, sizeof(INLINE) - 1, OPENED)) { + printf("Failed fgets()\n"); + } + } while (!feof(OPENED) && INLINE[1] == '#'); + + LNLENG = 0; + for (size_t i = 1; i < sizeof(INLINE) && INLINE[i] != 0; ++i) { + char val = INLINE[i]; + INLINE[i] = ascii_to_advent[(unsigned)val]; + if (INLINE[i] != 0) + LNLENG = i; + } + LNPOSN = 1; } -static long GETNUM(FILE *source) { - /* Obtain the next integer from an input line. If K>0, we first read a - * new input line from a file; if K<0, we read a line from the keyboard; - * if K=0 we use a line that has already been read (and perhaps partially - * scanned). If we're at the end of the line or encounter an illegal - * character (not a digit, hyphen, or blank), we return 0. */ - - long DIGIT, GETNUM, SIGN; - - if(source != NULL) MAPLIN(source); - GETNUM = 0; - - while (INLINE[LNPOSN] == 0) { - if (LNPOSN > LNLENG) return(GETNUM); - ++LNPOSN; - } - - if(INLINE[LNPOSN] != 9) - { - SIGN=1; - } - else - { - SIGN= -1; - LNPOSN=LNPOSN+1; - } - while (!(LNPOSN > LNLENG || INLINE[LNPOSN] == 0)) - { - DIGIT=INLINE[LNPOSN]-64; - if(DIGIT < 0 || DIGIT > 9) - { - GETNUM=0; - break; - } - GETNUM=GETNUM*10+DIGIT; - LNPOSN=LNPOSN+1; - } - - GETNUM=GETNUM*SIGN; - LNPOSN=LNPOSN+1; - return(GETNUM); +static long GETNUM(FILE *source) +{ + /* Obtain the next integer from an input line. If K>0, we first read a + * new input line from a file; if K<0, we read a line from the keyboard; + * if K=0 we use a line that has already been read (and perhaps partially + * scanned). If we're at the end of the line or encounter an illegal + * character (not a digit, hyphen, or blank), we return 0. */ + + long DIGIT, GETNUM, SIGN; + + if (source != NULL) MAPLIN(source); + GETNUM = 0; + + while (INLINE[LNPOSN] == 0) { + if (LNPOSN > LNLENG) return (GETNUM); + ++LNPOSN; + } + + if (INLINE[LNPOSN] != 9) { + SIGN = 1; + } else { + SIGN = -1; + LNPOSN = LNPOSN + 1; + } + while (!(LNPOSN > LNLENG || INLINE[LNPOSN] == 0)) { + DIGIT = INLINE[LNPOSN] - 64; + if (DIGIT < 0 || DIGIT > 9) { + GETNUM = 0; + break; + } + GETNUM = GETNUM * 10 + DIGIT; + LNPOSN = LNPOSN + 1; + } + + GETNUM = GETNUM * SIGN; + LNPOSN = LNPOSN + 1; + return (GETNUM); } /* Sections 1, 2, 5, 6, 10, 14. Read messages and set up pointers. */ static void read_messages(FILE* database, long sect) { - long KK=LINUSE; - while(true) - { - long loc; - LINUSE=KK; - loc=GETNUM(database); - if(LNLENG >= LNPOSN+70)BUG(0); - if(loc == -1) return; - if(LNLENG < LNPOSN)BUG(1); - do { - KK=KK+1; - if(KK >= LINSIZ)BUG(2); - LINES[KK]=GETTXT(false,false,false); - } - while(LINES[KK] != -1); - LINES[LINUSE]=KK; - if(loc == OLDLOC) continue; - OLDLOC=loc; - LINES[LINUSE]= -KK; - if(sect == 14) - { - TRNVLS=TRNVLS+1; - if(TRNVLS > TRNSIZ)BUG(11); - TTEXT[TRNVLS]=LINUSE; - TRNVAL[TRNVLS]=loc; - continue; - } - if(sect == 10) - { - CLSSES=CLSSES+1; - if(CLSSES > CLSMAX)BUG(11); - CTEXT[CLSSES]=LINUSE; - CVAL[CLSSES]=loc; - continue; - } - if(sect == 6) - { - if(loc > RTXSIZ)BUG(6); - RTEXT[loc]=LINUSE; - continue; - } - if(sect == 5) - { - if(loc > 0 && loc <= NOBJECTS)PTEXT[loc]=LINUSE; - continue; - } - if(loc > LOCSIZ)BUG(10); - if(sect == 1) - { - LTEXT[loc]=LINUSE; - continue; - } - - STEXT[loc]=LINUSE; - } + long KK = LINUSE; + while (true) { + long loc; + LINUSE = KK; + loc = GETNUM(database); + if (LNLENG >= LNPOSN + 70)BUG(0); + if (loc == -1) return; + if (LNLENG < LNPOSN)BUG(1); + do { + KK = KK + 1; + if (KK >= LINSIZ)BUG(2); + LINES[KK] = GETTXT(false, false, false); + } while (LINES[KK] != -1); + LINES[LINUSE] = KK; + if (loc == OLDLOC) continue; + OLDLOC = loc; + LINES[LINUSE] = -KK; + if (sect == 14) { + TRNVLS = TRNVLS + 1; + if (TRNVLS > TRNSIZ)BUG(11); + TTEXT[TRNVLS] = LINUSE; + TRNVAL[TRNVLS] = loc; + continue; + } + if (sect == 10) { + CLSSES = CLSSES + 1; + if (CLSSES > CLSMAX)BUG(11); + CTEXT[CLSSES] = LINUSE; + CVAL[CLSSES] = loc; + continue; + } + if (sect == 6) { + if (loc > RTXSIZ)BUG(6); + RTEXT[loc] = LINUSE; + continue; + } + if (sect == 5) { + if (loc > 0 && loc <= NOBJECTS)PTEXT[loc] = LINUSE; + continue; + } + if (loc > LOCSIZ)BUG(10); + if (sect == 1) { + LTEXT[loc] = LINUSE; + continue; + } + + STEXT[loc] = LINUSE; + } } /* The stuff for section 3 is encoded here. Each "from-location" gets a @@ -299,27 +288,22 @@ static void read_messages(FILE* database, long sect) * of the first option at location N. */ static void read_section3_stuff(FILE* database) { - long loc; - while((loc=GETNUM(database)) != -1) - { - long newloc=GETNUM(NULL); - long L; - if(KEY[loc] == 0) - { - KEY[loc]=TRVS; - } - else - { - TRAVEL[TRVS-1]= -TRAVEL[TRVS-1]; - } - while((L=GETNUM(NULL)) != 0) - { - TRAVEL[TRVS]=newloc*1000+L; - TRVS=TRVS+1; - if(TRVS == TRVSIZ)BUG(3); - } - TRAVEL[TRVS-1]= -TRAVEL[TRVS-1]; - } + long loc; + while ((loc = GETNUM(database)) != -1) { + long newloc = GETNUM(NULL); + long L; + if (KEY[loc] == 0) { + KEY[loc] = TRVS; + } else { + TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1]; + } + while ((L = GETNUM(NULL)) != 0) { + TRAVEL[TRVS] = newloc * 1000 + L; + TRVS = TRVS + 1; + if (TRVS == TRVSIZ)BUG(3); + } + TRAVEL[TRVS - 1] = -TRAVEL[TRVS - 1]; + } } /* Here we read in the vocabulary. KTAB(N) is the word number, ATAB(N) is @@ -327,13 +311,12 @@ static void read_section3_stuff(FILE* database) * as an end-marker. */ static void read_vocabulary(FILE* database) { - for (TABNDX=1; TABNDX<=TABSIZ; TABNDX++) - { - KTAB[TABNDX]=GETNUM(database); - if(KTAB[TABNDX] == -1) return; - ATAB[TABNDX]=GETTXT(true,true,true); - } /* end loop */ - BUG(4); + for (TABNDX = 1; TABNDX <= TABSIZ; TABNDX++) { + KTAB[TABNDX] = GETNUM(database); + if (KTAB[TABNDX] == -1) return; + ATAB[TABNDX] = GETTXT(true, true, true); + } /* end loop */ + BUG(4); } /* Read in the initial locations for each object. Also the immovability info. @@ -341,138 +324,158 @@ static void read_vocabulary(FILE* database) * objects (including the snake), or = second loc for two-placed objects. */ static void read_initial_locations(FILE* database) { - long OBJ; - while((OBJ=GETNUM(database)) != -1) - { - PLAC[OBJ]=GETNUM(NULL); - FIXD[OBJ]=GETNUM(NULL); - } + long OBJ; + while ((OBJ = GETNUM(database)) != -1) { + PLAC[OBJ] = GETNUM(NULL); + FIXD[OBJ] = GETNUM(NULL); + } } /* Read default message numbers for action verbs, store in ACTSPK. */ static void read_action_verb_message_nr(FILE* database) { - long verb; - while((verb=GETNUM(database)) != -1) - { - ACTSPK[verb]=GETNUM(NULL); - } + long verb; + while ((verb = GETNUM(database)) != -1) { + ACTSPK[verb] = GETNUM(NULL); + } } /* Read info about available liquids and other conditions, store in COND. */ static void read_conditions(FILE* database) { - long K; - while((K=GETNUM(database)) != -1) - { - long loc; - while((loc=GETNUM(NULL)) != 0) - { - if(is_set(COND[loc],K)) BUG(8); - COND[loc]=COND[loc] + (1l << K); - } - } + long K; + while ((K = GETNUM(database)) != -1) { + long loc; + while ((loc = GETNUM(NULL)) != 0) { + if (is_set(COND[loc], K)) BUG(8); + COND[loc] = COND[loc] + (1l << K); + } + } } /* Read data for hints. */ static void read_hints(FILE* database) { - long K; - HNTMAX=0; - while((K=GETNUM(database)) != -1) - { - if(K <= 0 || K > HNTSIZ)BUG(7); - for (int I=1; I<=4; I++) - { - HINTS[K][I] =GETNUM(NULL); - } /* end loop */ - HNTMAX=(HNTMAX>K ? HNTMAX : K); - } + long K; + HNTMAX = 0; + while ((K = GETNUM(database)) != -1) { + if (K <= 0 || K > HNTSIZ)BUG(7); + for (int I = 1; I <= 4; I++) { + HINTS[K][I] = GETNUM(NULL); + } /* end loop */ + HNTMAX = (HNTMAX > K ? HNTMAX : K); + } } /* Read the sound/text info, store in OBJSND, OBJTXT, LOCSND. */ static void read_sound_text(FILE* database) { - long K; - while((K=GETNUM(database)) != -1) - { - long KK=GETNUM(NULL); - long I=GETNUM(NULL); - if(I != 0) - { - OBJSND[K]=(KK>0 ? KK : 0); - OBJTXT[K]=(I>0 ? I : 0); - continue; - } - - LOCSND[K]=KK; - } + long K; + while ((K = GETNUM(database)) != -1) { + long KK = GETNUM(NULL); + long I = GETNUM(NULL); + if (I != 0) { + OBJSND[K] = (KK > 0 ? KK : 0); + OBJTXT[K] = (I > 0 ? I : 0); + continue; + } + + LOCSND[K] = KK; + } } -static int read_database(FILE* database) { - - /* Clear out the various text-pointer arrays. All text is stored in array - * lines; each line is preceded by a word pointing to the next pointer (i.e. - * the word following the end of the line). The pointer is negative if this is - * first line of a message. The text-pointer arrays contain indices of - * pointer-words in lines. STEXT(N) is short description of location N. - * LTEXT(N) is long description. PTEXT(N) points to message for game.prop(N)=0. - * Successive prop messages are found by chasing pointers. RTEXT contains - * section 6's stuff. CTEXT(N) points to a player-class message. TTEXT is for - * section 14. We also clear COND (see description of section 9 for details). */ - - for (int I=1; I<=NOBJECTS; I++) { - PTEXT[I] = 0; - OBJSND[I] = 0; - OBJTXT[I] = 0; - } - for (int I=1; I<=RTXSIZ; I++) { - RTEXT[I] = 0; - } - for (int I=1; I<=CLSMAX; I++) { - CTEXT[I] = 0; - } - for (int I=1; I<=LOCSIZ; I++) { - STEXT[I] = 0; - LTEXT[I] = 0; - COND[I] = 0; - KEY[I] = 0; - LOCSND[I] = 0; - } - - LINUSE = 1; - TRVS = 1; - CLSSES = 0; - TRNVLS = 0; - - /* Start new data section. Sect is the section number. */ - - while(true) - { - long sect=GETNUM(database); - OLDLOC= -1; - switch (sect) - { - case 0: return(0); - case 1: read_messages(database, sect); break; - case 2: read_messages(database, sect); break; - case 3: read_section3_stuff(database); break; - case 4: read_vocabulary(database); break; - case 5: read_messages(database, sect); break; - case 6: read_messages(database, sect); break; - case 7: read_initial_locations(database); break; - case 8: read_action_verb_message_nr(database); break; - case 9: read_conditions(database); break; - case 10: read_messages(database, sect); break; - case 11: read_hints(database); break; - case 12: break; - case 13: read_sound_text(database); break; - case 14: read_messages(database, sect); break; - default: BUG(9); - } - } +static int read_database(FILE* database) +{ + + /* Clear out the various text-pointer arrays. All text is stored in array + * lines; each line is preceded by a word pointing to the next pointer (i.e. + * the word following the end of the line). The pointer is negative if this is + * first line of a message. The text-pointer arrays contain indices of + * pointer-words in lines. STEXT(N) is short description of location N. + * LTEXT(N) is long description. PTEXT(N) points to message for game.prop(N)=0. + * Successive prop messages are found by chasing pointers. RTEXT contains + * section 6's stuff. CTEXT(N) points to a player-class message. TTEXT is for + * section 14. We also clear COND (see description of section 9 for details). */ + + for (int I = 1; I <= NOBJECTS; I++) { + PTEXT[I] = 0; + OBJSND[I] = 0; + OBJTXT[I] = 0; + } + for (int I = 1; I <= RTXSIZ; I++) { + RTEXT[I] = 0; + } + for (int I = 1; I <= CLSMAX; I++) { + CTEXT[I] = 0; + } + for (int I = 1; I <= LOCSIZ; I++) { + STEXT[I] = 0; + LTEXT[I] = 0; + COND[I] = 0; + KEY[I] = 0; + LOCSND[I] = 0; + } + + LINUSE = 1; + TRVS = 1; + CLSSES = 0; + TRNVLS = 0; + + /* Start new data section. Sect is the section number. */ + + while (true) { + long sect = GETNUM(database); + OLDLOC = -1; + switch (sect) { + case 0: + return (0); + case 1: + read_messages(database, sect); + break; + case 2: + read_messages(database, sect); + break; + case 3: + read_section3_stuff(database); + break; + case 4: + read_vocabulary(database); + break; + case 5: + read_messages(database, sect); + break; + case 6: + read_messages(database, sect); + break; + case 7: + read_initial_locations(database); + break; + case 8: + read_action_verb_message_nr(database); + break; + case 9: + read_conditions(database); + break; + case 10: + read_messages(database, sect); + break; + case 11: + read_hints(database); + break; + case 12: + break; + case 13: + read_sound_text(database); + break; + case 14: + read_messages(database, sect); + break; + default: + BUG(9); + } + } } /* Finish constructing internal data format */ @@ -489,103 +492,99 @@ static int read_database(FILE* database) { static void write_0d(FILE* header_file, long single, const char* varname) { - fprintf(header_file, "LOCATION long %s INITIALIZE(= %ld);\n", varname, single); + fprintf(header_file, "LOCATION long %s INITIALIZE(= %ld);\n", varname, single); } static void write_1d(FILE* header_file, long array[], long dim, const char* varname) { - fprintf(header_file, "LOCATION long %s[] INITIALIZE(= {\n", varname); - for (int i = 0; i < dim; ++i) - { - if (i % 10 == 0) - { - if (i > 0) - fprintf(header_file, "\n"); - fprintf(header_file, " "); - } - fprintf(header_file, "%ld, ", array[i]); - } - fprintf(header_file, "\n});\n"); + fprintf(header_file, "LOCATION long %s[] INITIALIZE(= {\n", varname); + for (int i = 0; i < dim; ++i) { + if (i % 10 == 0) { + if (i > 0) + fprintf(header_file, "\n"); + fprintf(header_file, " "); + } + fprintf(header_file, "%ld, ", array[i]); + } + fprintf(header_file, "\n});\n"); } static void write_hints(FILE* header_file, long matrix[][HINTLEN], long dim1, long dim2, const char* varname) { - fprintf(header_file, "LOCATION long %s[][%ld] INITIALIZE(= {\n", varname, dim2); - for (int i = 0; i < dim1; ++i) - { - fprintf(header_file, " {"); - for (int j = 0; j < dim2; ++j) - { - fprintf(header_file, "%ld, ", matrix[i][j]); - } - fprintf(header_file, "},\n"); - } - fprintf(header_file, "});\n"); + fprintf(header_file, "LOCATION long %s[][%ld] INITIALIZE(= {\n", varname, dim2); + for (int i = 0; i < dim1; ++i) { + fprintf(header_file, " {"); + for (int j = 0; j < dim2; ++j) { + fprintf(header_file, "%ld, ", matrix[i][j]); + } + fprintf(header_file, "},\n"); + } + fprintf(header_file, "});\n"); } static void write_file(FILE* header_file) { - int MAXDIE; - for (int i=0; i<=4; i++) { - long x = 2*i+81; - if(RTEXT[x] != 0) - MAXDIE=i+1; - } - - - fprintf(header_file, "#ifndef DATABASE_H\n"); - fprintf(header_file, "#define DATABASE_H\n"); - fprintf(header_file, "\n"); - - fprintf(header_file, "#include \"common.h\"\n"); - fprintf(header_file, "#define TABSIZ 330\n"); - fprintf(header_file, "#define HNTSIZ 20\n"); - fprintf(header_file, "#define TOKLEN %d\n", TOKLEN); - fprintf(header_file, "#define MAXDIE %d\n", MAXDIE); - fprintf(header_file, "\n"); - - fprintf(header_file, "\n"); - fprintf(header_file, "#ifdef DEFINE_GLOBALS_FROM_INCLUDES\n"); - fprintf(header_file, "#define LOCATION\n"); - fprintf(header_file, "#define INITIALIZE(...) __VA_ARGS__\n"); - fprintf(header_file, "#else\n"); - fprintf(header_file, "#define LOCATION extern\n"); - fprintf(header_file, "#define INITIALIZE(...)\n"); - fprintf(header_file, "#endif\n"); - fprintf(header_file, "\n"); - - // content variables - write_0d(header_file, TRNVLS, "TRNVLS"); - write_0d(header_file, HNTMAX, "HNTMAX"); - write_1d(header_file, OBJSND, NOBJECTS + 1, "OBJSND"); - write_1d(header_file, OBJTXT, NOBJECTS + 1, "OBJTXT"); - write_1d(header_file, COND, LOCSIZ + 1, "COND"); - write_1d(header_file, KEY, LOCSIZ + 1, "KEY"); - write_1d(header_file, LOCSND, LOCSIZ + 1, "LOCSND"); - write_1d(header_file, CVAL, CLSMAX + 1, "CVAL"); - write_1d(header_file, TRNVAL, TRNSIZ + 1, "TRNVAL"); - write_1d(header_file, TRAVEL, TRVSIZ + 1, "TRAVEL"); - write_1d(header_file, KTAB, TABSIZ + 1, "KTAB"); - write_1d(header_file, ATAB, TABSIZ + 1, "ATAB"); - write_1d(header_file, PLAC, NOBJECTS + 1, "PLAC"); - write_1d(header_file, FIXD, NOBJECTS + 1, "FIXD"); - write_1d(header_file, ACTSPK, VRBSIZ + 1, "ACTSPK"); - write_hints(header_file, HINTS, HNTSIZ + 1, 5, "HINTS"); - - fprintf(header_file, "#undef LOCATION\n"); - fprintf(header_file, "#undef INITIALIZE\n"); - fprintf(header_file, "#endif\n"); + int MAXDIE; + for (int i = 0; i <= 4; i++) { + long x = 2 * i + 81; + if (RTEXT[x] != 0) + MAXDIE = i + 1; + } + + + fprintf(header_file, "#ifndef DATABASE_H\n"); + fprintf(header_file, "#define DATABASE_H\n"); + fprintf(header_file, "\n"); + + fprintf(header_file, "#include \"common.h\"\n"); + fprintf(header_file, "#define TABSIZ 330\n"); + fprintf(header_file, "#define HNTSIZ 20\n"); + fprintf(header_file, "#define TOKLEN %d\n", TOKLEN); + fprintf(header_file, "#define MAXDIE %d\n", MAXDIE); + fprintf(header_file, "\n"); + + fprintf(header_file, "\n"); + fprintf(header_file, "#ifdef DEFINE_GLOBALS_FROM_INCLUDES\n"); + fprintf(header_file, "#define LOCATION\n"); + fprintf(header_file, "#define INITIALIZE(...) __VA_ARGS__\n"); + fprintf(header_file, "#else\n"); + fprintf(header_file, "#define LOCATION extern\n"); + fprintf(header_file, "#define INITIALIZE(...)\n"); + fprintf(header_file, "#endif\n"); + fprintf(header_file, "\n"); + + // content variables + write_0d(header_file, TRNVLS, "TRNVLS"); + write_0d(header_file, HNTMAX, "HNTMAX"); + write_1d(header_file, OBJSND, NOBJECTS + 1, "OBJSND"); + write_1d(header_file, OBJTXT, NOBJECTS + 1, "OBJTXT"); + write_1d(header_file, COND, LOCSIZ + 1, "COND"); + write_1d(header_file, KEY, LOCSIZ + 1, "KEY"); + write_1d(header_file, LOCSND, LOCSIZ + 1, "LOCSND"); + write_1d(header_file, CVAL, CLSMAX + 1, "CVAL"); + write_1d(header_file, TRNVAL, TRNSIZ + 1, "TRNVAL"); + write_1d(header_file, TRAVEL, TRVSIZ + 1, "TRAVEL"); + write_1d(header_file, KTAB, TABSIZ + 1, "KTAB"); + write_1d(header_file, ATAB, TABSIZ + 1, "ATAB"); + write_1d(header_file, PLAC, NOBJECTS + 1, "PLAC"); + write_1d(header_file, FIXD, NOBJECTS + 1, "FIXD"); + write_1d(header_file, ACTSPK, VRBSIZ + 1, "ACTSPK"); + write_hints(header_file, HINTS, HNTSIZ + 1, 5, "HINTS"); + + fprintf(header_file, "#undef LOCATION\n"); + fprintf(header_file, "#undef INITIALIZE\n"); + fprintf(header_file, "#endif\n"); } int main(void) { - FILE* database = fopen("adventure.text", "r"); - read_database(database); - fclose(database); + FILE* database = fopen("adventure.text", "r"); + read_database(database); + fclose(database); - FILE* header_file = fopen("database.h", "w"); - write_file(header_file); - fclose(header_file); + FILE* header_file = fopen("database.h", "w"); + write_file(header_file); + fclose(header_file); - return(EXIT_SUCCESS); + return (EXIT_SUCCESS); } diff --git a/init.c b/init.c index ca9d194..b2ad785 100644 --- a/init.c +++ b/init.c @@ -30,7 +30,7 @@ * 1000 non-synonymous vocabulary words * 300 locations * 100 objects - * Note: + * Note: * - the object count limit has been abstracted as NOBJECTS * - the random message limit has been abstracted as RTXSIZ * - maximum locations limit has been abstracted as LOCSIZ @@ -173,21 +173,21 @@ void initialise(void) { if (oldstyle) - printf("Initialising...\n"); + printf("Initialising...\n"); - for (int i=1; i<=NOBJECTS; i++) { - game.place[i] = NOWHERE; - game.prop[i] = 0; - game.link[i+NOBJECTS]=game.link[i]=0; + for (int i = 1; i <= NOBJECTS; i++) { + game.place[i] = NOWHERE; + game.prop[i] = 0; + game.link[i + NOBJECTS] = game.link[i] = 0; } - for (int i=1; i<=LOCSIZ; i++) { - game.abbrev[i]=0; - if (!(locations[i].description.big == 0 || KEY[i] == 0)) { - int k=KEY[i]; - if(MOD(labs(TRAVEL[k]),1000) == 1)COND[i]=2; - } - game.atloc[i]=0; + for (int i = 1; i <= LOCSIZ; i++) { + game.abbrev[i] = 0; + if (!(locations[i].description.big == 0 || KEY[i] == 0)) { + int k = KEY[i]; + if (MOD(labs(TRAVEL[k]), 1000) == 1)COND[i] = 2; + } + game.atloc[i] = 0; } /* Set up the game.atloc and game.link arrays as described above. @@ -197,115 +197,115 @@ void initialise(void) * This also sets up "game.place" and "fixed" as copies of "PLAC" and * "FIXD". Also, since two-placed objects are typically best * described last, we'll drop them first. */ - for (int i=1; i<=NOBJECTS; i++) { - int k=NOBJECTS + 1 - i; - if(FIXD[k] > 0) { - DROP(k+NOBJECTS,FIXD[k]); - DROP(k,PLAC[k]); - } + for (int i = 1; i <= NOBJECTS; i++) { + int k = NOBJECTS + 1 - i; + if (FIXD[k] > 0) { + DROP(k + NOBJECTS, FIXD[k]); + DROP(k, PLAC[k]); + } } - for (int i=1; i<=NOBJECTS; i++) { - int k=NOBJECTS + 1 - i; - game.fixed[k]=FIXD[k]; - if(PLAC[k] != 0 && FIXD[k] <= 0) - DROP(k,PLAC[k]); + for (int i = 1; i <= NOBJECTS; i++) { + int k = NOBJECTS + 1 - i; + game.fixed[k] = FIXD[k]; + if (PLAC[k] != 0 && FIXD[k] <= 0) + DROP(k, PLAC[k]); } /* Treasures, as noted earlier, are objects MINTRS through MAXTRS * Their props are initially -1, and are set to 0 the first time * they are described. game.tally keeps track of how many are * not yet found, so we know when to close the cave. */ - game.tally=0; - for (int treasure=MINTRS; treasure<=MAXTRS; treasure++) { - if(object_descriptions[treasure].inventory != 0) - game.prop[treasure]= -1; - game.tally=game.tally-game.prop[treasure]; + game.tally = 0; + for (int treasure = MINTRS; treasure <= MAXTRS; treasure++) { + if (object_descriptions[treasure].inventory != 0) + game.prop[treasure] = -1; + game.tally = game.tally - game.prop[treasure]; } /* Clear the hint stuff. game.hintlc[i] is how long he's been at LOC * with cond bit i. game.hinted[i] is true iff hint i has been * used. */ - for (int i=1; i<=HNTMAX; i++) { - game.hinted[i]=false; - game.hintlc[i]=0; + for (int i = 1; i <= HNTMAX; i++) { + game.hinted[i] = false; + game.hintlc[i] = 0; } /* Define some handy mnemonics. These correspond to object numbers. */ - AXE=VOCWRD(12405,1); - BATTER=VOCWRD(201202005,1); - BEAR=VOCWRD(2050118,1); - BIRD=VOCWRD(2091804,1); - BLOOD=VOCWRD(212151504,1); - BOTTLE=VOCWRD(215202012,1); - CAGE=VOCWRD(3010705,1); - CAVITY=VOCWRD(301220920,1); - CHASM=VOCWRD(308011913,1); - CLAM=VOCWRD(3120113,1); - DOOR=VOCWRD(4151518,1); - DRAGON=VOCWRD(418010715,1); - DWARF=VOCWRD(423011806,1); - FISSUR=VOCWRD(609191921,1); - FOOD=VOCWRD(6151504,1); - GRATE=VOCWRD(718012005,1); - KEYS=VOCWRD(11052519,1); - KNIFE=VOCWRD(1114090605,1); - LAMP=VOCWRD(12011316,1); - MAGZIN=VOCWRD(1301070126,1); - MESSAG=VOCWRD(1305191901,1); - MIRROR=VOCWRD(1309181815,1); - OGRE=VOCWRD(15071805,1); - OIL=VOCWRD(150912,1); - OYSTER=VOCWRD(1525192005,1); - PILLOW=VOCWRD(1609121215,1); - PLANT=VOCWRD(1612011420,1); - PLANT2=PLANT+1; - RESER=VOCWRD(1805190518,1); - ROD=VOCWRD(181504,1); - ROD2=ROD+1; - SIGN=VOCWRD(19090714,1); - SNAKE=VOCWRD(1914011105,1); - STEPS=VOCWRD(1920051619,1); - TROLL=VOCWRD(2018151212,1); - TROLL2=TROLL+1; - URN=VOCWRD(211814,1); - VEND=VOCWRD(1755140409,1); - VOLCAN=VOCWRD(1765120301,1); - WATER=VOCWRD(1851200518,1); + AXE = VOCWRD(12405, 1); + BATTER = VOCWRD(201202005, 1); + BEAR = VOCWRD(2050118, 1); + BIRD = VOCWRD(2091804, 1); + BLOOD = VOCWRD(212151504, 1); + BOTTLE = VOCWRD(215202012, 1); + CAGE = VOCWRD(3010705, 1); + CAVITY = VOCWRD(301220920, 1); + CHASM = VOCWRD(308011913, 1); + CLAM = VOCWRD(3120113, 1); + DOOR = VOCWRD(4151518, 1); + DRAGON = VOCWRD(418010715, 1); + DWARF = VOCWRD(423011806, 1); + FISSUR = VOCWRD(609191921, 1); + FOOD = VOCWRD(6151504, 1); + GRATE = VOCWRD(718012005, 1); + KEYS = VOCWRD(11052519, 1); + KNIFE = VOCWRD(1114090605, 1); + LAMP = VOCWRD(12011316, 1); + MAGZIN = VOCWRD(1301070126, 1); + MESSAG = VOCWRD(1305191901, 1); + MIRROR = VOCWRD(1309181815, 1); + OGRE = VOCWRD(15071805, 1); + OIL = VOCWRD(150912, 1); + OYSTER = VOCWRD(1525192005, 1); + PILLOW = VOCWRD(1609121215, 1); + PLANT = VOCWRD(1612011420, 1); + PLANT2 = PLANT + 1; + RESER = VOCWRD(1805190518, 1); + ROD = VOCWRD(181504, 1); + ROD2 = ROD + 1; + SIGN = VOCWRD(19090714, 1); + SNAKE = VOCWRD(1914011105, 1); + STEPS = VOCWRD(1920051619, 1); + TROLL = VOCWRD(2018151212, 1); + TROLL2 = TROLL + 1; + URN = VOCWRD(211814, 1); + VEND = VOCWRD(1755140409, 1); + VOLCAN = VOCWRD(1765120301, 1); + WATER = VOCWRD(1851200518, 1); /* Objects from MINTRS through MAXTRS are treasures. Here are a few. */ - AMBER=VOCWRD(113020518,1); - CHAIN=VOCWRD(308010914,1); - CHEST=VOCWRD(308051920,1); - COINS=VOCWRD(315091419,1); - EGGS=VOCWRD(5070719,1); - EMRALD=VOCWRD(513051801,1); - JADE=VOCWRD(10010405,1); - NUGGET=VOCWRD(7151204,1); - PEARL=VOCWRD(1605011812,1); - PYRAM=VOCWRD(1625180113,1); - RUBY=VOCWRD(18210225,1); - RUG=VOCWRD(182107,1); - SAPPH=VOCWRD(1901161608,1); - TRIDNT=VOCWRD(2018090405,1); - VASE=VOCWRD(22011905,1); + AMBER = VOCWRD(113020518, 1); + CHAIN = VOCWRD(308010914, 1); + CHEST = VOCWRD(308051920, 1); + COINS = VOCWRD(315091419, 1); + EGGS = VOCWRD(5070719, 1); + EMRALD = VOCWRD(513051801, 1); + JADE = VOCWRD(10010405, 1); + NUGGET = VOCWRD(7151204, 1); + PEARL = VOCWRD(1605011812, 1); + PYRAM = VOCWRD(1625180113, 1); + RUBY = VOCWRD(18210225, 1); + RUG = VOCWRD(182107, 1); + SAPPH = VOCWRD(1901161608, 1); + TRIDNT = VOCWRD(2018090405, 1); + VASE = VOCWRD(22011905, 1); /* These are motion-verb numbers. */ - BACK=VOCWRD(2010311,0); - CAVE=VOCWRD(3012205,0); - DPRSSN=VOCWRD(405161805,0); - ENTER=VOCWRD(514200518,0); - ENTRNC=VOCWRD(514201801,0); - LOOK=VOCWRD(12151511,0); - NUL=VOCWRD(14211212,0); - STREAM=VOCWRD(1920180501,0); + BACK = VOCWRD(2010311, 0); + CAVE = VOCWRD(3012205, 0); + DPRSSN = VOCWRD(405161805, 0); + ENTER = VOCWRD(514200518, 0); + ENTRNC = VOCWRD(514201801, 0); + LOOK = VOCWRD(12151511, 0); + NUL = VOCWRD(14211212, 0); + STREAM = VOCWRD(1920180501, 0); /* And some action verbs. */ - FIND=VOCWRD(6091404,2); - INVENT=VOCWRD(914220514,2); - LOCK=VOCWRD(12150311,2); - SAY=VOCWRD(190125,2); - THROW=VOCWRD(2008181523,2); + FIND = VOCWRD(6091404, 2); + INVENT = VOCWRD(914220514, 2); + LOCK = VOCWRD(12150311, 2); + SAY = VOCWRD(190125, 2); + THROW = VOCWRD(2008181523, 2); /* Initialise the dwarves. game.dloc is loc of dwarves, * hard-wired in. game.odloc is prior loc of each dwarf, @@ -325,16 +325,16 @@ void initialise(void) * loc stored in game.chloc2. */ game.chloc = LOC_DEADEND12; game.chloc2 = LOC_DEADEND13; - for (int i=1; i<=NDWARVES; i++) { - game.dseen[i]=false; + for (int i = 1; i <= NDWARVES; i++) { + game.dseen[i] = false; } - game.dflag=0; + game.dflag = 0; game.dloc[1] = LOC_KINGHALL; game.dloc[2] = LOC_WESTBANK; game.dloc[3] = LOC_Y2; game.dloc[4] = LOC_ALIKE3; game.dloc[5] = LOC_COMPLEX; - game.dloc[6]=game.chloc; + game.dloc[6] = game.chloc; /* Other random flags and counters, as follows: * game.abbnum How often we should print non-abbreviated descriptions @@ -357,30 +357,30 @@ void initialise(void) * game.trnluz # points lost so far due to number of turns used * game.turns Tallies how many commands he's given (ignores yes/no) * Logicals were explained earlier */ - game.turns=0; - game.trndex=1; - game.thresh= -1; + game.turns = 0; + game.trndex = 1; + game.thresh = -1; if (TRNVLS > 0) - game.thresh=MOD(TRNVAL[1],100000)+1; - game.trnluz=0; - game.lmwarn=false; - game.iwest=0; - game.knfloc=0; - game.detail=0; - game.abbnum=5; - game.numdie=0; - game.holdng=0; - game.dkill=0; - game.foobar=0; - game.bonus=0; - game.clock1=30; - game.clock2=50; - game.conds=SETBIT(11); - game.saved=0; - game.closng=false; - game.panic=false; - game.closed=false; - game.clshnt=false; - game.novice=false; - game.blklin=true; + game.thresh = MOD(TRNVAL[1], 100000) + 1; + game.trnluz = 0; + game.lmwarn = false; + game.iwest = 0; + game.knfloc = 0; + game.detail = 0; + game.abbnum = 5; + game.numdie = 0; + game.holdng = 0; + game.dkill = 0; + game.foobar = 0; + game.bonus = 0; + game.clock1 = 30; + game.clock2 = 50; + game.conds = SETBIT(11); + game.saved = 0; + game.closng = false; + game.panic = false; + game.closed = false; + game.clshnt = false; + game.novice = false; + game.blklin = true; } diff --git a/main.c b/main.c index 526eda1..405d9d3 100644 --- a/main.c +++ b/main.c @@ -27,20 +27,20 @@ struct game_t game; -long LNLENG, LNPOSN, PARMS[MAXPARMS+1]; -char rawbuf[LINESIZE], INLINE[LINESIZE+1]; +long LNLENG, LNPOSN, PARMS[MAXPARMS + 1]; +char rawbuf[LINESIZE], INLINE[LINESIZE + 1]; long AMBER, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, - BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, - CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS, - EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD, - GRATE, HINT, INVENT, JADE, KEYS, - KNIFE, LAMP, LOCK, LOOK, MAGZIN, - MESSAG, MIRROR, NUGGET, NUL, OGRE, OIL, OYSTER, - PEARL, PILLOW, PLANT, PLANT2, PYRAM, RESER, ROD, ROD2, - RUBY, RUG, SAPPH, SAY, SIGN, SNAKE, - STEPS, STREAM, THROW, TRIDNT, TROLL, TROLL2, - URN, VASE, VEND, VOLCAN, WATER; + BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, + CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS, + EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD, + GRATE, HINT, INVENT, JADE, KEYS, + KNIFE, LAMP, LOCK, LOOK, MAGZIN, + MESSAG, MIRROR, NUGGET, NUL, OGRE, OIL, OYSTER, + PEARL, PILLOW, PLANT, PLANT2, PYRAM, RESER, ROD, ROD2, + RUBY, RUG, SAPPH, SAY, SIGN, SNAKE, + STEPS, STREAM, THROW, TRIDNT, TROLL, TROLL2, + URN, VASE, VEND, VOLCAN, WATER; long WD1, WD1X, WD2, WD2X; FILE *logfp = NULL, *rfp = NULL; @@ -50,10 +50,10 @@ bool prompt = true; static void sig_handler(int signo) { - if (signo == SIGINT){ - if (logfp != NULL) - fflush(logfp); - } + if (signo == SIGINT) { + if (logfp != NULL) + fflush(logfp); + } exit(0); } @@ -74,35 +74,35 @@ static bool do_command(FILE *); int main(int argc, char *argv[]) { int ch; - -/* Options. */ + + /* Options. */ while ((ch = getopt(argc, argv, "l:or:s")) != EOF) { - switch (ch) { - case 'l': - logfp = fopen(optarg, "w"); - if (logfp == NULL) - fprintf(stderr, - "advent: can't open logfile %s for write\n", - optarg); - signal(SIGINT, sig_handler); - break; - case 'o': - oldstyle = true; - editline = prompt = false; - break; - case 'r': - rfp = fopen(optarg, "r"); - if (rfp == NULL) - fprintf(stderr, - "advent: can't open save file %s for read\n", - optarg); - signal(SIGINT, sig_handler); - break; - case 's': - editline = false; - break; - } + switch (ch) { + case 'l': + logfp = fopen(optarg, "w"); + if (logfp == NULL) + fprintf(stderr, + "advent: can't open logfile %s for write\n", + optarg); + signal(SIGINT, sig_handler); + break; + case 'o': + oldstyle = true; + editline = prompt = false; + break; + case 'r': + rfp = fopen(optarg, "r"); + if (rfp == NULL) + fprintf(stderr, + "advent: can't open save file %s for read\n", + optarg); + signal(SIGINT, sig_handler); + break; + case 's': + editline = false; + break; + } } linenoiseHistorySetMaxLen(350); @@ -130,24 +130,24 @@ int main(int argc, char *argv[]) initialise(); /* Start-up, dwarf stuff */ - game.zzword=RNDVOC(3,0); + game.zzword = RNDVOC(3, 0); game.newloc = LOC_START; game.loc = LOC_START; - game.limit=330; - if (!rfp){ - game.novice=YES(stdin, WELCOME_YOU,CAVE_NEARBY,NO_MESSAGE); - if (game.novice)game.limit=1000; + game.limit = 330; + if (!rfp) { + game.novice = YES(stdin, WELCOME_YOU, CAVE_NEARBY, NO_MESSAGE); + if (game.novice)game.limit = 1000; } else { restore(rfp); } if (logfp) - fprintf(logfp, "seed %ld\n", seedval); + fprintf(logfp, "seed %ld\n", seedval); /* interpret commands until EOF or interrupt */ for (;;) { - if (!do_command(stdin)) - break; + if (!do_command(stdin)) + break; } /* show score and exit */ score(quitgame); @@ -158,13 +158,13 @@ static bool fallback_handler(char *buf) { long sv; if (sscanf(buf, "seed %ld", &sv) == 1) { - set_seed(sv); - printf("Seed set to %ld\n", sv); - // autogenerated, so don't charge user time for it. - --game.turns; - // here we reconfigure any global game state that uses random numbers - game.zzword=RNDVOC(3,0); - return true; + set_seed(sv); + printf("Seed set to %ld\n", sv); + // autogenerated, so don't charge user time for it. + --game.turns; + // here we reconfigure any global game state that uses random numbers + game.zzword = RNDVOC(3, 0); + return true; } return false; } @@ -177,98 +177,96 @@ static bool fallback_handler(char *buf) static void checkhints(FILE *cmdin) { if (COND[game.loc] >= game.conds) { - for (int hint=1; hint<=HNTMAX; hint++) { - if (game.hinted[hint]) - continue; - if (!CNDBIT(game.loc,hint+HBASE)) - game.hintlc[hint]= -1; - ++game.hintlc[hint]; - /* Come here if he's been long enough at required loc(s) for some - * unused hint. */ - if (game.hintlc[hint] >= HINTS[hint][1]) - { - int i; - - switch (hint-1) - { - case 0: - /* cave */ - if (game.prop[GRATE] == 0 && !HERE(KEYS)) - break; - game.hintlc[hint]=0; - return; - case 1: /* bird */ - if (game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD) - break; - return; - case 2: /* snake */ - if (HERE(SNAKE) && !HERE(BIRD)) - break; - game.hintlc[hint]=0; - return; - case 3: /* maze */ - if (game.atloc[game.loc] == 0 && - game.atloc[game.oldloc] == 0 && - game.atloc[game.oldlc2] == 0 && - game.holdng > 1) - break; - game.hintlc[hint]=0; - return; - case 4: /* dark */ - if (game.prop[EMRALD] != -1 && game.prop[PYRAM] == -1) - break; - game.hintlc[hint]=0; - return; - case 5: /* witt */ - break; - case 6: /* urn */ - if (game.dflag == 0) - break; - game.hintlc[hint]=0; - return; - case 7: /* woods */ - if (game.atloc[game.loc] == 0 && - game.atloc[game.oldloc] == 0 && - game.atloc[game.oldlc2] == 0) - break; - return; - case 8: /* ogre */ - i=ATDWRF(game.loc); - if (i < 0) { - game.hintlc[hint]=0; - return; - } - if (HERE(OGRE) && i == 0) - break; - return; - case 9: /* jade */ - if (game.tally == 1 && game.prop[JADE] < 0) - break; - game.hintlc[hint]=0; - return; - default: - BUG(27); - break; - } - - /* Fall through to hint display */ - game.hintlc[hint]=0; - if (!YES(cmdin,HINTS[hint][3],NO_MESSAGE,OK_MAN)) - return; - SETPRM(1,HINTS[hint][2],HINTS[hint][2]); - RSPEAK(HINT_COST); - game.hinted[hint]=YES(cmdin,WANT_HINT,HINTS[hint][4],OK_MAN); - if (game.hinted[hint] && game.limit > WARNTIME) - game.limit += WARNTIME*HINTS[hint][2]; - } - } + for (int hint = 1; hint <= HNTMAX; hint++) { + if (game.hinted[hint]) + continue; + if (!CNDBIT(game.loc, hint + HBASE)) + game.hintlc[hint] = -1; + ++game.hintlc[hint]; + /* Come here if he's been long enough at required loc(s) for some + * unused hint. */ + if (game.hintlc[hint] >= HINTS[hint][1]) { + int i; + + switch (hint - 1) { + case 0: + /* cave */ + if (game.prop[GRATE] == 0 && !HERE(KEYS)) + break; + game.hintlc[hint] = 0; + return; + case 1: /* bird */ + if (game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD) + break; + return; + case 2: /* snake */ + if (HERE(SNAKE) && !HERE(BIRD)) + break; + game.hintlc[hint] = 0; + return; + case 3: /* maze */ + if (game.atloc[game.loc] == 0 && + game.atloc[game.oldloc] == 0 && + game.atloc[game.oldlc2] == 0 && + game.holdng > 1) + break; + game.hintlc[hint] = 0; + return; + case 4: /* dark */ + if (game.prop[EMRALD] != -1 && game.prop[PYRAM] == -1) + break; + game.hintlc[hint] = 0; + return; + case 5: /* witt */ + break; + case 6: /* urn */ + if (game.dflag == 0) + break; + game.hintlc[hint] = 0; + return; + case 7: /* woods */ + if (game.atloc[game.loc] == 0 && + game.atloc[game.oldloc] == 0 && + game.atloc[game.oldlc2] == 0) + break; + return; + case 8: /* ogre */ + i = ATDWRF(game.loc); + if (i < 0) { + game.hintlc[hint] = 0; + return; + } + if (HERE(OGRE) && i == 0) + break; + return; + case 9: /* jade */ + if (game.tally == 1 && game.prop[JADE] < 0) + break; + game.hintlc[hint] = 0; + return; + default: + BUG(27); + break; + } + + /* Fall through to hint display */ + game.hintlc[hint] = 0; + if (!YES(cmdin, HINTS[hint][3], NO_MESSAGE, OK_MAN)) + return; + SETPRM(1, HINTS[hint][2], HINTS[hint][2]); + RSPEAK(HINT_COST); + game.hinted[hint] = YES(cmdin, WANT_HINT, HINTS[hint][4], OK_MAN); + if (game.hinted[hint] && game.limit > WARNTIME) + game.limit += WARNTIME * HINTS[hint][2]; + } + } } } static bool spotted_by_pirate(int i) { - if (i != PIRATE) - return false; + if (i != PIRATE) + return false; /* The pirate's spotted him. He leaves him alone once we've * found chest. K counts if a treasure is here. If not, and @@ -277,51 +275,51 @@ static bool spotted_by_pirate(int i) * it to the troll, but in that case he's seen the chest * (game.prop=0). */ if (game.loc == game.chloc || game.prop[CHEST] >= 0) - return true; - int snarfed=0; + return true; + int snarfed = 0; bool movechest = false, robplayer = false; - for (int treasure=MINTRS; treasure<=MAXTRS; treasure++) { - /* Pirate won't take pyramid from plover room or dark - * room (too easy!). */ - if (treasure==PYRAM && (game.loc==PLAC[PYRAM] || game.loc==PLAC[EMRALD])) { - continue; - } - if (TOTING(treasure) || HERE(treasure)) - ++snarfed; - if (TOTING(treasure)) { - movechest = true; - robplayer = true; - } + for (int treasure = MINTRS; treasure <= MAXTRS; treasure++) { + /* Pirate won't take pyramid from plover room or dark + * room (too easy!). */ + if (treasure == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD])) { + continue; + } + if (TOTING(treasure) || HERE(treasure)) + ++snarfed; + if (TOTING(treasure)) { + movechest = true; + robplayer = true; + } } /* Force chest placement before player finds last treasure */ if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == NOWHERE && HERE(LAMP) && game.prop[LAMP] == 1) { - RSPEAK(PIRATE_SPOTTED); - movechest = true; + RSPEAK(PIRATE_SPOTTED); + movechest = true; } /* Do things in this order (chest move before robbery) so chest is listed * last at the maze location. */ if (movechest) { - MOVE(CHEST,game.chloc); - MOVE(MESSAG,game.chloc2); - game.dloc[PIRATE]=game.chloc; - game.odloc[PIRATE]=game.chloc; - game.dseen[PIRATE]=false; + MOVE(CHEST, game.chloc); + MOVE(MESSAG, game.chloc2); + game.dloc[PIRATE] = game.chloc; + game.odloc[PIRATE] = game.chloc; + game.dseen[PIRATE] = 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)) - RSPEAK(PIRATE_RUSTLES); + /* 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)) + RSPEAK(PIRATE_RUSTLES); } if (robplayer) { - RSPEAK(PIRATE_POUNCES); - for (int treasure=MINTRS; treasure<=MAXTRS; treasure++) { - if (!(treasure == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) { - if (AT(treasure) && game.fixed[treasure] == 0) - CARRY(treasure,game.loc); - if (TOTING(treasure)) - DROP(treasure,game.chloc); - } - } + RSPEAK(PIRATE_POUNCES); + for (int treasure = MINTRS; treasure <= MAXTRS; treasure++) { + if (!(treasure == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) { + if (AT(treasure) && game.fixed[treasure] == 0) + CARRY(treasure, game.loc); + if (TOTING(treasure)) + DROP(treasure, game.chloc); + } + } } return true; @@ -346,36 +344,36 @@ static bool dwarfmove(void) * 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 == 0 || FORCED(game.loc) || CNDBIT(game.newloc,NOARRR)) - return true; + if (game.loc == 0 || FORCED(game.loc) || CNDBIT(game.newloc, NOARRR)) + return true; /* Dwarf activity level ratchets up */ if (game.dflag == 0) { - if (INDEEP(game.loc)) - game.dflag=1; - return true; + if (INDEEP(game.loc)) + game.dflag = 1; + return true; } /* When we encounter the first dwarf, we kill 0, 1, or 2 of * the 5 dwarves. If any of the survivors is at loc, * replace him with the alternate. */ if (game.dflag == 1) { - if (!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc,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; - } - for (int i=1; i<=NDWARVES-1; i++) { - if (game.dloc[i] == game.loc) - game.dloc[i]=DALTLC; - game.odloc[i]=game.dloc[i]; - } - RSPEAK(DWARF_RAN); - DROP(AXE,game.loc); - return true; + if (!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc, 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; + } + for (int i = 1; i <= NDWARVES - 1; i++) { + if (game.dloc[i] == game.loc) + game.dloc[i] = DALTLC; + game.odloc[i] = game.dloc[i]; + } + RSPEAK(DWARF_RAN); + DROP(AXE, game.loc); + return true; } /* Things are in full swing. Move each dwarf at random, @@ -384,75 +382,75 @@ static bool dwarfmove(void) * unless there's no alternative. If they don't have to * move, they attack. And, of course, dead dwarves don't do * much of anything. */ - game.dtotal=0; - attack=0; - stick=0; - for (int i=1; i<=NDWARVES; i++) { - if (game.dloc[i] == 0) - continue; - /* Fill tk array with all the places this dwarf might go. */ - int j=1; - kk=KEY[game.dloc[i]]; - if (kk != 0) - do { - game.newloc=MOD(labs(TRAVEL[kk])/1000,1000); - /* Have we avoided a dwarf encounter? */ - bool avoided = (SPECIAL(game.newloc) || - !INDEEP(game.newloc) || - game.newloc == game.odloc[i] || - (j > 1 && game.newloc == tk[j-1]) || - j >= 20 || - game.newloc == game.dloc[i] || - FORCED(game.newloc) || - (i == PIRATE && CNDBIT(game.newloc,NOARRR)) || - labs(TRAVEL[kk])/1000000 == 100); - if (!avoided) { - tk[j++] = game.newloc; - } - ++kk; - } while - (TRAVEL[kk-1] >= 0); - tk[j]=game.odloc[i]; - 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]) continue; - game.dloc[i]=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]) { - ++attack; - if (game.knfloc >= 0) - game.knfloc=game.loc; - if (randrange(1000) < 95*(game.dflag-2)) - ++stick; - } + game.dtotal = 0; + attack = 0; + stick = 0; + for (int i = 1; i <= NDWARVES; i++) { + if (game.dloc[i] == 0) + continue; + /* Fill tk array with all the places this dwarf might go. */ + int j = 1; + kk = KEY[game.dloc[i]]; + if (kk != 0) + do { + game.newloc = MOD(labs(TRAVEL[kk]) / 1000, 1000); + /* Have we avoided a dwarf encounter? */ + bool avoided = (SPECIAL(game.newloc) || + !INDEEP(game.newloc) || + game.newloc == game.odloc[i] || + (j > 1 && game.newloc == tk[j - 1]) || + j >= 20 || + game.newloc == game.dloc[i] || + FORCED(game.newloc) || + (i == PIRATE && CNDBIT(game.newloc, NOARRR)) || + labs(TRAVEL[kk]) / 1000000 == 100); + if (!avoided) { + tk[j++] = game.newloc; + } + ++kk; + } while + (TRAVEL[kk - 1] >= 0); + tk[j] = game.odloc[i]; + 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]) continue; + game.dloc[i] = 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]) { + ++attack; + if (game.knfloc >= 0) + game.knfloc = game.loc; + if (randrange(1000) < 95 * (game.dflag - 2)) + ++stick; + } } /* Now we know what's happening. Let's tell the poor sucker about it. * Note that various of the "knife" messages must have specific relative * positions in the RSPEAK database. */ if (game.dtotal == 0) - return true; - SETPRM(1,game.dtotal,0); - RSPEAK(DWARF_PACK+1/game.dtotal); /* FIXME: Arithmetic on message number */ + return true; + SETPRM(1, game.dtotal, 0); + RSPEAK(DWARF_PACK + 1 / game.dtotal); /* FIXME: Arithmetic on message number */ if (attack == 0) - return true; - if (game.dflag == 2)game.dflag=3; - SETPRM(1,attack,0); - int k=6; - if (attack > 1)k=THROWN_KNIVES; + return true; + if (game.dflag == 2)game.dflag = 3; + SETPRM(1, attack, 0); + int k = 6; + if (attack > 1)k = THROWN_KNIVES; RSPEAK(k); - SETPRM(1,stick,0); - RSPEAK(k+1+2/(1+stick)); /* FIXME: Arithmetic on message number */ + SETPRM(1, stick, 0); + RSPEAK(k + 1 + 2 / (1 + stick)); /* FIXME: Arithmetic on message number */ if (stick == 0) - return true; - game.oldlc2=game.loc; + return true; + game.oldlc2 = game.loc; return false; } @@ -481,28 +479,28 @@ static void croak(FILE *cmdin) { ++game.numdie; if (game.closng) { - /* He died during closing time. No resurrection. Tally up a - * death and exit. */ - RSPEAK(DEATH_CLOSING); - score(endgame); + /* He died during closing time. No resurrection. Tally up a + * death and exit. */ + RSPEAK(DEATH_CLOSING); + score(endgame); } /* FIXME: Arithmetic on message numbers */ - else if (game.numdie == MAXDIE || !YES(cmdin,WATCH_IT+game.numdie*2,WHICH_WAY+game.numdie*2,OK_MAN)) - score(endgame); + else if (game.numdie == MAXDIE || !YES(cmdin, WATCH_IT + game.numdie * 2, WHICH_WAY + game.numdie * 2, OK_MAN)) + score(endgame); else { - game.place[WATER] = game.place[OIL] = NOWHERE; - if (TOTING(LAMP)) - game.prop[LAMP]=0; - for (int j=1; j<=NOBJECTS; j++) { - int i=NOBJECTS + 1 - j; - if (TOTING(i)) { - /* Always leave lamp where it's accessible aboveground */ - DROP(i, (i == LAMP) ? LOC_START : game.oldlc2); - } - } - game.loc = LOC_BUILDING; - game.oldloc=game.loc; + game.place[WATER] = game.place[OIL] = NOWHERE; + if (TOTING(LAMP)) + game.prop[LAMP] = 0; + for (int j = 1; j <= NOBJECTS; j++) { + int i = NOBJECTS + 1 - j; + if (TOTING(i)) { + /* Always leave lamp where it's accessible aboveground */ + DROP(i, (i == LAMP) ? LOC_START : game.oldlc2); + } + } + game.loc = LOC_BUILDING; + game.oldloc = game.loc; } } @@ -516,200 +514,196 @@ static void croak(FILE *cmdin) static bool playermove(FILE *cmdin, token_t verb, int motion) { - int scratchloc, k2, kk=KEY[game.loc]; - game.newloc=game.loc; + int scratchloc, k2, kk = KEY[game.loc]; + game.newloc = game.loc; if (kk == 0) - BUG(26); + BUG(26); if (motion == NUL) - return true; + return true; else if (motion == BACK) { - /* Handle "go back". Look for verb which goes from game.loc to - * game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion. - * k2 saves entry -> forced loc -> previous loc. */ - motion=game.oldloc; - if (FORCED(motion)) - motion=game.oldlc2; - game.oldlc2=game.oldloc; - game.oldloc=game.loc; - k2=0; - if (motion == game.loc)k2=FORGOT_PATH; - if (CNDBIT(game.loc,NOBACK))k2=TWIST_TURN; - if (k2 == 0) { - for (;;) { - scratchloc=MOD((labs(TRAVEL[kk])/1000),1000); - if (scratchloc != motion) { - if (!SPECIAL(scratchloc)) { - if (FORCED(scratchloc) && MOD((labs(TRAVEL[KEY[scratchloc]])/1000),1000) == motion) - k2=kk; - } - if (TRAVEL[kk] >= 0) { - ++kk; - continue; - } - kk=k2; - if (kk == 0) { - RSPEAK(NOT_CONNECTED); - return true; - } - } - - motion=MOD(labs(TRAVEL[kk]),1000); - kk=KEY[game.loc]; - break; /* fall through to ordinary travel */ - } - } else { - RSPEAK(k2); - return true; - } - } - else if (motion == LOOK) { - /* Look. Can't give more detail. Pretend it wasn't dark - * (though it may now be dark) so he won't fall into a - * pit while staring into the gloom. */ - if (game.detail < 3) - RSPEAK(NO_MORE_DETAIL); - ++game.detail; - game.wzdark=false; - game.abbrev[game.loc]=0; - return true; - } - else if (motion == CAVE) { - /* Cave. Different messages depending on whether above ground. */ - RSPEAK((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL); - return true; - } - else { - /* none of the specials */ - game.oldlc2=game.oldloc; - game.oldloc=game.loc; + /* Handle "go back". Look for verb which goes from game.loc to + * game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion. + * k2 saves entry -> forced loc -> previous loc. */ + motion = game.oldloc; + if (FORCED(motion)) + motion = game.oldlc2; + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; + k2 = 0; + if (motion == game.loc)k2 = FORGOT_PATH; + if (CNDBIT(game.loc, NOBACK))k2 = TWIST_TURN; + if (k2 == 0) { + for (;;) { + scratchloc = MOD((labs(TRAVEL[kk]) / 1000), 1000); + if (scratchloc != motion) { + if (!SPECIAL(scratchloc)) { + if (FORCED(scratchloc) && MOD((labs(TRAVEL[KEY[scratchloc]]) / 1000), 1000) == motion) + k2 = kk; + } + if (TRAVEL[kk] >= 0) { + ++kk; + continue; + } + kk = k2; + if (kk == 0) { + RSPEAK(NOT_CONNECTED); + return true; + } + } + + motion = MOD(labs(TRAVEL[kk]), 1000); + kk = KEY[game.loc]; + break; /* fall through to ordinary travel */ + } + } else { + RSPEAK(k2); + return true; + } + } else if (motion == LOOK) { + /* Look. Can't give more detail. Pretend it wasn't dark + * (though it may now be dark) so he won't fall into a + * pit while staring into the gloom. */ + if (game.detail < 3) + RSPEAK(NO_MORE_DETAIL); + ++game.detail; + game.wzdark = false; + game.abbrev[game.loc] = 0; + return true; + } else if (motion == CAVE) { + /* Cave. Different messages depending on whether above ground. */ + RSPEAK((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL); + return true; + } else { + /* none of the specials */ + game.oldlc2 = game.oldloc; + game.oldloc = game.loc; } /* ordinary travel */ for (;;) { - scratchloc=labs(TRAVEL[kk]); - if (MOD(scratchloc,1000) == 1 || MOD(scratchloc,1000) == motion) - break; - if (TRAVEL[kk] < 0) { - /* FIXME: Magic numbers! */ - /* Non-applicable motion. Various messages depending on - * word given. */ - int spk=CANT_APPLY; - if (motion >= 43 && motion <= 50)spk=BAD_DIRECTION; - if (motion == 29 || motion == 30)spk=BAD_DIRECTION; - if (motion == 7 || motion == 36 || motion == 37)spk=UNSURE_FACING; - if (motion == 11 || motion == 19)spk=NO_INOUT_HERE; - if (verb == FIND || verb == INVENT)spk=NEreplace; - if (motion == 62 || motion == 65)spk=NOTHING_HAPPENS; - if (motion == 17)spk=WHICH_WAY; - RSPEAK(spk); - return true; - } - ++kk; + scratchloc = labs(TRAVEL[kk]); + if (MOD(scratchloc, 1000) == 1 || MOD(scratchloc, 1000) == motion) + break; + if (TRAVEL[kk] < 0) { + /* FIXME: Magic numbers! */ + /* Non-applicable motion. Various messages depending on + * word given. */ + int spk = CANT_APPLY; + if (motion >= 43 && motion <= 50)spk = BAD_DIRECTION; + if (motion == 29 || motion == 30)spk = BAD_DIRECTION; + if (motion == 7 || motion == 36 || motion == 37)spk = UNSURE_FACING; + if (motion == 11 || motion == 19)spk = NO_INOUT_HERE; + if (verb == FIND || verb == INVENT)spk = NEreplace; + if (motion == 62 || motion == 65)spk = NOTHING_HAPPENS; + if (motion == 17)spk = WHICH_WAY; + RSPEAK(spk); + return true; + } + ++kk; } - scratchloc=scratchloc/1000; + scratchloc = scratchloc / 1000; do { - /* - * (ESR) This special-travel loop may have to be repeated if it includes - * the plover passage. Same deal for any future cases wgerw we beed to - * block travel and then redo it once the blocking condition has been - * removed. - */ - for (;;) { - game.newloc=scratchloc/1000; - motion=MOD(game.newloc,100); - if (!SPECIAL(game.newloc)) { - if (game.newloc <= 100) { - if (game.newloc == 0 || PCT(game.newloc)) - break; - /* else fall through */ - } if (TOTING(motion) || (game.newloc > 200 && AT(motion))) - break; - /* else fall through */ - } - else if (game.prop[motion] != game.newloc/100-3) - break; - do { - if (TRAVEL[kk] < 0)BUG(25); - ++kk; - game.newloc=labs(TRAVEL[kk])/1000; - } while - (game.newloc == scratchloc); - scratchloc=game.newloc; - } - - game.newloc=MOD(scratchloc,1000); - if (!SPECIAL(game.newloc)) - return true; - if (game.newloc <= 500) { - game.newloc=game.newloc-SPECIALBASE; - switch (game.newloc) - { - case 1: - /* Travel 301. Plover-alcove passage. Can carry only - * emerald. Note: travel table must include "useless" - * entries going through passage, which can never be used for - * actual motion, but can be spotted by "go back". */ - /* FIXME: Arithmetic on location numbers */ - game.newloc=99+100-game.loc; - if (game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) - return true; - game.newloc=game.loc; - RSPEAK(MUST_DROP); - return true; - case 2: - /* Travel 302. Plover transport. Drop the emerald (only use - * special travel if toting it), so he's forced to use the - * plover-passage to get it out. Having dropped it, go back and - * pretend he wasn't carrying it after all. */ - DROP(EMRALD,game.loc); - do { - if (TRAVEL[kk] < 0)BUG(25); - ++kk; - game.newloc=labs(TRAVEL[kk])/1000; - } while - (game.newloc == scratchloc); - continue; /* back to top of do/while loop */ - case 3: - /* Travel 303. Troll bridge. Must be done only as special - * motion so that dwarves won't wander across and encounter - * the bear. (They won't follow the player there because - * that region is forbidden to the pirate.) If - * game.prop(TROLL)=1, he's crossed since paying, so step out - * and block him. (standard travel entries check for - * game.prop(TROLL)=0.) Special stuff for bear. */ - if (game.prop[TROLL] == 1) { - PSPEAK(TROLL,1); - game.prop[TROLL]=0; - MOVE(TROLL2,0); - MOVE(TROLL2+NOBJECTS,0); - MOVE(TROLL,PLAC[TROLL]); - MOVE(TROLL+NOBJECTS,FIXD[TROLL]); - JUGGLE(CHASM); - game.newloc=game.loc; - return true; - } else { - game.newloc=PLAC[TROLL]+FIXD[TROLL]-game.loc; - if (game.prop[TROLL] == 0)game.prop[TROLL]=1; - if (!TOTING(BEAR)) return true; - RSPEAK(BRIDGE_COLLAPSE); - game.prop[CHASM]=1; - game.prop[TROLL]=2; - DROP(BEAR,game.newloc); - game.fixed[BEAR]= -1; - game.prop[BEAR]=3; - game.oldlc2=game.newloc; - croak(cmdin); - return false; - } - } - BUG(20); - } + /* + * (ESR) This special-travel loop may have to be repeated if it includes + * the plover passage. Same deal for any future cases wgerw we beed to + * block travel and then redo it once the blocking condition has been + * removed. + */ + for (;;) { + game.newloc = scratchloc / 1000; + motion = MOD(game.newloc, 100); + if (!SPECIAL(game.newloc)) { + if (game.newloc <= 100) { + if (game.newloc == 0 || PCT(game.newloc)) + break; + /* else fall through */ + } + if (TOTING(motion) || (game.newloc > 200 && AT(motion))) + break; + /* else fall through */ + } else if (game.prop[motion] != game.newloc / 100 - 3) + break; + do { + if (TRAVEL[kk] < 0)BUG(25); + ++kk; + game.newloc = labs(TRAVEL[kk]) / 1000; + } while + (game.newloc == scratchloc); + scratchloc = game.newloc; + } + + game.newloc = MOD(scratchloc, 1000); + if (!SPECIAL(game.newloc)) + return true; + if (game.newloc <= 500) { + game.newloc = game.newloc - SPECIALBASE; + switch (game.newloc) { + case 1: + /* Travel 301. Plover-alcove passage. Can carry only + * emerald. Note: travel table must include "useless" + * entries going through passage, which can never be used for + * actual motion, but can be spotted by "go back". */ + /* FIXME: Arithmetic on location numbers */ + game.newloc = 99 + 100 - game.loc; + if (game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) + return true; + game.newloc = game.loc; + RSPEAK(MUST_DROP); + return true; + case 2: + /* Travel 302. Plover transport. Drop the emerald (only use + * special travel if toting it), so he's forced to use the + * plover-passage to get it out. Having dropped it, go back and + * pretend he wasn't carrying it after all. */ + DROP(EMRALD, game.loc); + do { + if (TRAVEL[kk] < 0)BUG(25); + ++kk; + game.newloc = labs(TRAVEL[kk]) / 1000; + } while + (game.newloc == scratchloc); + continue; /* back to top of do/while loop */ + case 3: + /* Travel 303. Troll bridge. Must be done only as special + * motion so that dwarves won't wander across and encounter + * the bear. (They won't follow the player there because + * that region is forbidden to the pirate.) If + * game.prop(TROLL)=1, he's crossed since paying, so step out + * and block him. (standard travel entries check for + * game.prop(TROLL)=0.) Special stuff for bear. */ + if (game.prop[TROLL] == 1) { + PSPEAK(TROLL, 1); + game.prop[TROLL] = 0; + MOVE(TROLL2, 0); + MOVE(TROLL2 + NOBJECTS, 0); + MOVE(TROLL, PLAC[TROLL]); + MOVE(TROLL + NOBJECTS, FIXD[TROLL]); + JUGGLE(CHASM); + game.newloc = game.loc; + return true; + } else { + game.newloc = PLAC[TROLL] + FIXD[TROLL] - game.loc; + if (game.prop[TROLL] == 0)game.prop[TROLL] = 1; + if (!TOTING(BEAR)) return true; + RSPEAK(BRIDGE_COLLAPSE); + game.prop[CHASM] = 1; + game.prop[TROLL] = 2; + DROP(BEAR, game.newloc); + game.fixed[BEAR] = -1; + game.prop[BEAR] = 3; + game.oldlc2 = game.newloc; + croak(cmdin); + return false; + } + } + BUG(20); + } } while - (false); + (false); /* FIXME: Arithmetic on location number, becoming a message number */ - RSPEAK(game.newloc-500); - game.newloc=game.loc; + RSPEAK(game.newloc - 500); + game.newloc = game.loc; return true; } @@ -735,7 +729,7 @@ static bool closecheck(void) * objects. */ { if (game.tally == 0 && INDEEP(game.loc) && game.loc != 33) - --game.clock1; + --game.clock1; /* When the first warning comes, we lock the grate, destroy * the bridge, kill all the dwarves (and the pirate), remove @@ -750,78 +744,77 @@ static bool closecheck(void) * can refer to it. Also also, he's gotten the pearl, so we * 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]=0; - game.prop[FISSUR]=0; - for (int i=1; i<=NDWARVES; i++) { - game.dseen[i]=false; - game.dloc[i]=0; - } - MOVE(TROLL,0); - MOVE(TROLL+NOBJECTS,0); - MOVE(TROLL2,PLAC[TROLL]); - MOVE(TROLL2+NOBJECTS,FIXD[TROLL]); - JUGGLE(CHASM); - if (game.prop[BEAR] != 3)DESTROY(BEAR); - game.prop[CHAIN]=0; - game.fixed[CHAIN]=0; - game.prop[AXE]=0; - game.fixed[AXE]=0; - RSPEAK(CAVE_CLOSING); - game.clock1= -1; - game.closng=true; - return true; + if (game.clock1 == 0) { + game.prop[GRATE] = 0; + game.prop[FISSUR] = 0; + for (int i = 1; i <= NDWARVES; i++) { + game.dseen[i] = false; + game.dloc[i] = 0; + } + MOVE(TROLL, 0); + MOVE(TROLL + NOBJECTS, 0); + MOVE(TROLL2, PLAC[TROLL]); + MOVE(TROLL2 + NOBJECTS, FIXD[TROLL]); + JUGGLE(CHASM); + if (game.prop[BEAR] != 3)DESTROY(BEAR); + game.prop[CHAIN] = 0; + game.fixed[CHAIN] = 0; + game.prop[AXE] = 0; + game.fixed[AXE] = 0; + RSPEAK(CAVE_CLOSING); + game.clock1 = -1; + game.closng = true; + return true; } else if (game.clock1 < 0) - --game.clock2; + --game.clock2; if (game.clock2 == 0) { - /* Once he's panicked, and clock2 has run out, we come here - * to set up the storage room. The room has two locs, - * hardwired as 115 (ne) and 116 (sw). At the ne end, we - * place empty bottles, a nursery of plants, a bed of - * oysters, a pile of lamps, rods with stars, sleeping - * dwarves, and him. At the sw end we place grate over - * treasures, snake pit, covey of caged birds, more rods, and - * pillows. A mirror stretches across one wall. Many of the - * 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 - * could cause trouble, such as the keys). We describe the - * flash of light and trundle back. */ - game.prop[BOTTLE]=PUT(BOTTLE,LOC_NE,1); - game.prop[PLANT]=PUT(PLANT,LOC_NE,0); - game.prop[OYSTER]=PUT(OYSTER,LOC_NE,0); - OBJTXT[OYSTER]=3; - game.prop[LAMP]=PUT(LAMP,LOC_NE,0); - game.prop[ROD]=PUT(ROD,LOC_NE,0); - game.prop[DWARF]=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); - ++OBJTXT[SIGN]; - game.prop[SNAKE]=PUT(SNAKE,LOC_SW,1); - game.prop[BIRD]=PUT(BIRD,LOC_SW,1); - game.prop[CAGE]=PUT(CAGE,LOC_SW,0); - game.prop[ROD2]=PUT(ROD2,LOC_SW,0); - game.prop[PILLOW]=PUT(PILLOW,LOC_SW,0); - - game.prop[MIRROR]=PUT(MIRROR,LOC_NE,0); - game.fixed[MIRROR]=LOC_SW; - - for (int i=1; i<=NOBJECTS; i++) { - if (TOTING(i)) - DESTROY(i); - } - - RSPEAK(CAVE_CLOSED); - game.closed=true; - return true; + /* Once he's panicked, and clock2 has run out, we come here + * to set up the storage room. The room has two locs, + * hardwired as 115 (ne) and 116 (sw). At the ne end, we + * place empty bottles, a nursery of plants, a bed of + * oysters, a pile of lamps, rods with stars, sleeping + * dwarves, and him. At the sw end we place grate over + * treasures, snake pit, covey of caged birds, more rods, and + * pillows. A mirror stretches across one wall. Many of the + * 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 + * could cause trouble, such as the keys). We describe the + * flash of light and trundle back. */ + game.prop[BOTTLE] = PUT(BOTTLE, LOC_NE, 1); + game.prop[PLANT] = PUT(PLANT, LOC_NE, 0); + game.prop[OYSTER] = PUT(OYSTER, LOC_NE, 0); + OBJTXT[OYSTER] = 3; + game.prop[LAMP] = PUT(LAMP, LOC_NE, 0); + game.prop[ROD] = PUT(ROD, LOC_NE, 0); + game.prop[DWARF] = 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); + ++OBJTXT[SIGN]; + game.prop[SNAKE] = PUT(SNAKE, LOC_SW, 1); + game.prop[BIRD] = PUT(BIRD, LOC_SW, 1); + game.prop[CAGE] = PUT(CAGE, LOC_SW, 0); + game.prop[ROD2] = PUT(ROD2, LOC_SW, 0); + game.prop[PILLOW] = PUT(PILLOW, LOC_SW, 0); + + game.prop[MIRROR] = PUT(MIRROR, LOC_NE, 0); + game.fixed[MIRROR] = LOC_SW; + + for (int i = 1; i <= NOBJECTS; i++) { + if (TOTING(i)) + DESTROY(i); + } + + RSPEAK(CAVE_CLOSED); + game.closed = true; + return true; } return false; @@ -831,7 +824,7 @@ static void lampcheck(void) /* Check game limit and lamp timers */ { if (game.prop[LAMP] == 1) - --game.limit; + --game.limit; /* Another way we can force an end to things is by having the * lamp give out. When it gets close, we come here to warn @@ -840,27 +833,26 @@ static void lampcheck(void) * Second is for other cases of lamp dying. 12400 is when it * goes out. Even then, he can explore outside for a while * if desired. */ - if (game.limit <= WARNTIME && HERE(BATTER) && game.prop[BATTER]==0 && HERE(LAMP)) - { - RSPEAK(REPLACE_BATTERIES); - game.prop[BATTER]=1; - if (TOTING(BATTER)) - DROP(BATTER,game.loc); - game.limit=game.limit+2500; - game.lmwarn=false; + if (game.limit <= WARNTIME && HERE(BATTER) && game.prop[BATTER] == 0 && HERE(LAMP)) { + RSPEAK(REPLACE_BATTERIES); + game.prop[BATTER] = 1; + if (TOTING(BATTER)) + DROP(BATTER, game.loc); + game.limit = game.limit + 2500; + game.lmwarn = false; } else if (game.limit == 0) { - game.limit= -1; - game.prop[LAMP]=0; - if (HERE(LAMP)) - RSPEAK(LAMP_OUT); + game.limit = -1; + game.prop[LAMP] = 0; + if (HERE(LAMP)) + RSPEAK(LAMP_OUT); } else if (game.limit <= WARNTIME) { - if (!game.lmwarn && HERE(LAMP)) { - game.lmwarn=true; - int spk=GET_BATTERIES; - if (game.place[BATTER] == NOWHERE)spk=LAMP_DIM; - if (game.prop[BATTER] == 1)spk=MISSING_BATTERIES; - RSPEAK(spk); - } + if (!game.lmwarn && HERE(LAMP)) { + game.lmwarn = true; + int spk = GET_BATTERIES; + if (game.place[BATTER] == NOWHERE)spk = LAMP_DIM; + if (game.prop[BATTER] == 1)spk = MISSING_BATTERIES; + RSPEAK(spk); + } } } @@ -874,46 +866,46 @@ 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]) { - long obj=i; - if (obj > NOBJECTS)obj=obj-NOBJECTS; - if (obj == STEPS && TOTING(NUGGET)) - continue; - if (game.prop[obj] < 0) { - if (game.closed) - continue; - game.prop[obj]=0; - if (obj == RUG || obj == CHAIN) - game.prop[obj]=1; - --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 - * the remaining treasures, and if so the lamp was zapped to - * 35 turns. But the tests were too simple-minded; things - * like killing the bird before the snake was gone (can never - * see jewelry), and doing it "right" was hopeless. E.G., - * could cross troll bridge several times, using up all - * available treasures, breaking vase, using coins to buy - * batteries, etc., and eventually never be able to get - * across again. If bottle were left on far side, could then - * never get eggs or trident, and the effects propagate. So - * the whole thing was flushed. anyone who makes such a - * gross blunder isn't likely to find everything else anyway - * (so goes the rationalisation). */ - } - int kk=game.prop[obj]; - if (obj == STEPS && game.loc == game.fixed[STEPS]) - kk=1; - PSPEAK(obj,kk); - } + ++game.abbrev[game.loc]; + for (int i = game.atloc[game.loc]; i != 0; i = game.link[i]) { + long obj = i; + if (obj > NOBJECTS)obj = obj - NOBJECTS; + if (obj == STEPS && TOTING(NUGGET)) + continue; + if (game.prop[obj] < 0) { + if (game.closed) + continue; + game.prop[obj] = 0; + if (obj == RUG || obj == CHAIN) + game.prop[obj] = 1; + --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 + * the remaining treasures, and if so the lamp was zapped to + * 35 turns. But the tests were too simple-minded; things + * like killing the bird before the snake was gone (can never + * see jewelry), and doing it "right" was hopeless. E.G., + * could cross troll bridge several times, using up all + * available treasures, breaking vase, using coins to buy + * batteries, etc., and eventually never be able to get + * across again. If bottle were left on far side, could then + * never get eggs or trident, and the effects propagate. So + * the whole thing was flushed. anyone who makes such a + * gross blunder isn't likely to find everything else anyway + * (so goes the rationalisation). */ + } + int kk = game.prop[obj]; + if (obj == STEPS && game.loc == game.fixed[STEPS]) + kk = 1; + PSPEAK(obj, kk); + } } } static bool do_command(FILE *cmdin) -/* Get and execute a command */ +/* Get and execute a command */ { - long verb=0, V1, V2; + long verb = 0, V1, V2; long kmod, defn; static long igo = 0; static long obj = 0; @@ -921,206 +913,219 @@ static bool do_command(FILE *cmdin) /* Can't leave cave once it's closing (except by main office). */ if (OUTSID(game.newloc) && game.newloc != 0 && game.closng) { - RSPEAK(EXIT_CLOSED); - game.newloc=game.loc; - if (!game.panic)game.clock2=15; - game.panic=true; + RSPEAK(EXIT_CLOSED); + game.newloc = game.loc; + if (!game.panic)game.clock2 = 15; + game.panic = true; } /* See if a dwarf has seen him and has come from where he * wants to go. If so, the dwarf's blocking his way. If * coming from place forbidden to pirate (dwarves rooted in * place) let him get out (and attacked). */ - if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc,NOARRR)) { - for (size_t i=1; i<=NDWARVES-1; i++) { - if (game.odloc[i] == game.newloc && game.dseen[i]) { - game.newloc=game.loc; - RSPEAK(DWARF_BLOCK); - break; - } - } + if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc, NOARRR)) { + for (size_t i = 1; i <= NDWARVES - 1; i++) { + if (game.odloc[i] == game.newloc && game.dseen[i]) { + game.newloc = game.loc; + RSPEAK(DWARF_BLOCK); + break; + } + } } - game.loc=game.newloc; + game.loc = game.newloc; if (!dwarfmove()) - croak(cmdin); + croak(cmdin); /* Describe the current location and (maybe) get next command. */ for (;;) { - if (game.loc == 0) - croak(cmdin); - const char* msg = locations[game.loc].description.small; - if (MOD(game.abbrev[game.loc],game.abbnum) == 0 || msg == 0) - msg=locations[game.loc].description.big; - if (!FORCED(game.loc) && DARK(game.loc)) { - /* The easiest way to get killed is to fall into a pit in - * pitch darkness. */ - if (game.wzdark && PCT(35)) { - RSPEAK(PIT_FALL); - game.oldlc2 = game.loc; - croak(cmdin); - continue; /* back to top of main interpreter loop */ - } - msg=arbitrary_messages[PITCH_DARK]; - } - if (TOTING(BEAR))RSPEAK(TAME_BEAR); - newspeak(msg); - if (FORCED(game.loc)) { - if (playermove(cmdin, verb, 1)) - return true; - else - continue; /* back to top of main interpreter loop */ - } - if (game.loc == 33 && PCT(25) && !game.closng)RSPEAK(SAYS_PLUGH); - - listobjects(); - - L2012: - verb=0; - game.oldobj=obj; - obj=0; - - L2600: - checkhints(cmdin); - - /* If closing time, check for any objects being toted with - * game.prop < 0 and set the prop to -1-game.prop. This way - * objects won't be described until they've been picked up - * and put down separate from their respective piles. Don't - * tick game.clock1 unless well into cave (and not at Y2). */ - if (game.closed) { - if (game.prop[OYSTER] < 0 && TOTING(OYSTER)) - PSPEAK(OYSTER,1); - for (size_t i=1; i<=NOBJECTS; i++) { - if (TOTING(i) && game.prop[i] < 0) - game.prop[i] = -1-game.prop[i]; - } - } - game.wzdark=DARK(game.loc); - if (game.knfloc > 0 && game.knfloc != game.loc) - game.knfloc=0; - - /* This is where we get a new command from the user */ - if (!GETIN(cmdin, &WD1,&WD1X,&WD2,&WD2X)) - return false; - - /* Every input, check "game.foobar" flag. If zero, nothing's - * going on. If pos, make neg. If neg, he skipped a word, - * so make it zero. */ - L2607: - game.foobar=(game.foobar>0 ? -game.foobar : 0); - ++game.turns; - if (game.turns == game.thresh) { - newspeak(turn_threshold_messages[game.trndex]); - game.trnluz=game.trnluz+TRNVAL[game.trndex]/100000; - ++game.trndex; - game.thresh = -1; - if (game.trndex <= TRNVLS) - game.thresh=MOD(TRNVAL[game.trndex],100000)+1; - } - if (verb == SAY && WD2 > 0) - verb=0; - if (verb == SAY) { - part=transitive; - goto Laction; - } - if (closecheck()) { - if (game.closed) - return true; - } else - lampcheck(); - - V1=VOCAB(WD1,-1); - V2=VOCAB(WD2,-1); - if (V1 == ENTER && (V2 == STREAM || V2 == 1000+WATER)) { - if(LIQLOC(game.loc) == WATER){ - RSPEAK(FEET_WET); - } else { - RSPEAK(WHERE_QUERY); - } - goto L2012; - } - if (V1 == ENTER && WD2 > 0) { - WD1=WD2; - WD1X=WD2X; - WD2=0; - } else { - if (!((V1 != 1000+WATER && V1 != 1000+OIL) || - (V2 != 1000+PLANT && V2 != 1000+DOOR))) { - if (AT(V2-1000)) - WD2=MAKEWD(16152118); - } - if (V1 == 1000+CAGE && V2 == 1000+BIRD && HERE(CAGE) && HERE(BIRD)) - WD1=MAKEWD(301200308); - } - L2620: - if (WD1 == MAKEWD(23051920)) { - ++game.iwest; - if (game.iwest == 10) - RSPEAK(W_IS_WEST); - } - if (WD1 == MAKEWD( 715) && WD2 != 0) { - if (++igo == 10) - RSPEAK(GO_UNNEEDED); - } - Lookup: - defn = VOCAB(WD1,-1); - if (defn == -1) { - /* Gee, I don't understand. */ - if (fallback_handler(rawbuf)) - continue; - SETPRM(1,WD1,WD1X); - RSPEAK(DONT_KNOW); - goto L2600; - } - kmod=MOD(defn,1000); - switch (defn/1000) - { - case 0: - if (playermove(cmdin, verb, kmod)) - return true; - else - continue; /* back to top of main interpreter loop */ - case 1: part=unknown; obj = kmod; break; - case 2: part=intransitive; verb = kmod; break; - case 3: RSPEAK(kmod); goto L2012; - default: BUG(22); - } - - Laction: - switch (action(cmdin, part, verb, obj)) { - case GO_TERMINATE: - return true; - case GO_MOVE: - playermove(cmdin, verb, NUL); - return true; - case GO_TOP: continue; /* back to top of main interpreter loop */ - case GO_CLEAROBJ: goto L2012; - case GO_CHECKHINT: goto L2600; - case GO_CHECKFOO: goto L2607; - case GO_LOOKUP: goto Lookup; - case GO_WORD2: - /* Get second word for analysis. */ - WD1=WD2; - WD1X=WD2X; - WD2=0; - goto L2620; - case GO_UNKNOWN: - /* Random intransitive verbs come here. Clear obj just in case - * (see attack()). */ - SETPRM(1,WD1,WD1X); - RSPEAK(DO_WHAT); - obj=0; - goto L2600; - case GO_DWARFWAKE: - /* Oh dear, he's disturbed the dwarves. */ - RSPEAK(DWARVES_AWAKEN); - score(endgame); - return true; - default: - BUG(99); - } + if (game.loc == 0) + croak(cmdin); + const char* msg = locations[game.loc].description.small; + if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0) + msg = locations[game.loc].description.big; + if (!FORCED(game.loc) && DARK(game.loc)) { + /* The easiest way to get killed is to fall into a pit in + * pitch darkness. */ + if (game.wzdark && PCT(35)) { + RSPEAK(PIT_FALL); + game.oldlc2 = game.loc; + croak(cmdin); + continue; /* back to top of main interpreter loop */ + } + msg = arbitrary_messages[PITCH_DARK]; + } + if (TOTING(BEAR))RSPEAK(TAME_BEAR); + newspeak(msg); + if (FORCED(game.loc)) { + if (playermove(cmdin, verb, 1)) + return true; + else + continue; /* back to top of main interpreter loop */ + } + if (game.loc == 33 && PCT(25) && !game.closng)RSPEAK(SAYS_PLUGH); + + listobjects(); + +L2012: + verb = 0; + game.oldobj = obj; + obj = 0; + +L2600: + checkhints(cmdin); + + /* If closing time, check for any objects being toted with + * game.prop < 0 and set the prop to -1-game.prop. This way + * objects won't be described until they've been picked up + * and put down separate from their respective piles. Don't + * tick game.clock1 unless well into cave (and not at Y2). */ + if (game.closed) { + if (game.prop[OYSTER] < 0 && TOTING(OYSTER)) + PSPEAK(OYSTER, 1); + for (size_t i = 1; i <= NOBJECTS; i++) { + if (TOTING(i) && game.prop[i] < 0) + game.prop[i] = -1 - game.prop[i]; + } + } + game.wzdark = DARK(game.loc); + if (game.knfloc > 0 && game.knfloc != game.loc) + game.knfloc = 0; + + /* This is where we get a new command from the user */ + if (!GETIN(cmdin, &WD1, &WD1X, &WD2, &WD2X)) + return false; + + /* Every input, check "game.foobar" flag. If zero, nothing's + * going on. If pos, make neg. If neg, he skipped a word, + * so make it zero. */ +L2607: + game.foobar = (game.foobar > 0 ? -game.foobar : 0); + ++game.turns; + if (game.turns == game.thresh) { + newspeak(turn_threshold_messages[game.trndex]); + game.trnluz = game.trnluz + TRNVAL[game.trndex] / 100000; + ++game.trndex; + game.thresh = -1; + if (game.trndex <= TRNVLS) + game.thresh = MOD(TRNVAL[game.trndex], 100000) + 1; + } + if (verb == SAY && WD2 > 0) + verb = 0; + if (verb == SAY) { + part = transitive; + goto Laction; + } + if (closecheck()) { + if (game.closed) + return true; + } else + lampcheck(); + + V1 = VOCAB(WD1, -1); + V2 = VOCAB(WD2, -1); + if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) { + if (LIQLOC(game.loc) == WATER) { + RSPEAK(FEET_WET); + } else { + RSPEAK(WHERE_QUERY); + } + goto L2012; + } + if (V1 == ENTER && WD2 > 0) { + WD1 = WD2; + WD1X = WD2X; + WD2 = 0; + } else { + if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) || + (V2 != 1000 + PLANT && V2 != 1000 + DOOR))) { + if (AT(V2 - 1000)) + WD2 = MAKEWD(16152118); + } + if (V1 == 1000 + CAGE && V2 == 1000 + BIRD && HERE(CAGE) && HERE(BIRD)) + WD1 = MAKEWD(301200308); + } +L2620: + if (WD1 == MAKEWD(23051920)) { + ++game.iwest; + if (game.iwest == 10) + RSPEAK(W_IS_WEST); + } + if (WD1 == MAKEWD( 715) && WD2 != 0) { + if (++igo == 10) + RSPEAK(GO_UNNEEDED); + } +Lookup: + defn = VOCAB(WD1, -1); + if (defn == -1) { + /* Gee, I don't understand. */ + if (fallback_handler(rawbuf)) + continue; + SETPRM(1, WD1, WD1X); + RSPEAK(DONT_KNOW); + goto L2600; + } + kmod = MOD(defn, 1000); + switch (defn / 1000) { + case 0: + if (playermove(cmdin, verb, kmod)) + return true; + else + continue; /* back to top of main interpreter loop */ + case 1: + part = unknown; + obj = kmod; + break; + case 2: + part = intransitive; + verb = kmod; + break; + case 3: + RSPEAK(kmod); + goto L2012; + default: + BUG(22); + } + +Laction: + switch (action(cmdin, part, verb, obj)) { + case GO_TERMINATE: + return true; + case GO_MOVE: + playermove(cmdin, verb, NUL); + return true; + case GO_TOP: + continue; /* back to top of main interpreter loop */ + case GO_CLEAROBJ: + goto L2012; + case GO_CHECKHINT: + goto L2600; + case GO_CHECKFOO: + goto L2607; + case GO_LOOKUP: + goto Lookup; + case GO_WORD2: + /* Get second word for analysis. */ + WD1 = WD2; + WD1X = WD2X; + WD2 = 0; + goto L2620; + case GO_UNKNOWN: + /* Random intransitive verbs come here. Clear obj just in case + * (see attack()). */ + SETPRM(1, WD1, WD1X); + RSPEAK(DO_WHAT); + obj = 0; + goto L2600; + case GO_DWARFWAKE: + /* Oh dear, he's disturbed the dwarves. */ + RSPEAK(DWARVES_AWAKEN); + score(endgame); + return true; + default: + BUG(99); + } } } diff --git a/misc.c b/misc.c index 978e4b6..2b9159b 100644 --- a/misc.c +++ b/misc.c @@ -12,34 +12,31 @@ char* xstrdup(const char* s) { - char* ptr = strdup(s); - if (ptr == NULL) - { - fprintf(stderr, "Out of memory!\n"); - exit(EXIT_FAILURE); + char* ptr = strdup(s); + if (ptr == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(EXIT_FAILURE); } - return(ptr); + return (ptr); } void packed_to_token(long packed, char token[6]) { - // Unpack and map back to ASCII. - for (int i = 0; i < 5; ++i) - { - char advent = (packed >> i * 6) & 63; - token[4 - i] = advent_to_ascii[(int) advent]; + // Unpack and map back to ASCII. + for (int i = 0; i < 5; ++i) { + char advent = (packed >> i * 6) & 63; + token[4 - i] = advent_to_ascii[(int) advent]; } - // Ensure the last character is \0. - token[5] = '\0'; + // Ensure the last character is \0. + token[5] = '\0'; - // Replace trailing whitespace with \0. - for (int i = 4; i >= 0; --i) - { - if (token[i] == ' ' || token[i] == '\t') - token[i] = '\0'; - else - break; + // Replace trailing whitespace with \0. + for (int i = 4; i >= 0; --i) { + if (token[i] == ' ' || token[i] == '\t') + token[i] = '\0'; + else + break; } } @@ -47,109 +44,97 @@ void packed_to_token(long packed, char token[6]) void newspeak(const char* msg) { - // Do nothing if we got a null pointer. - if (msg == NULL) - return; - - // Do nothing if we got an empty string. - if (strlen(msg) == 0) - return; - - // Print a newline if the global game.blklin says to. - if (game.blklin == true) - printf("\n"); - - // Create a copy of our string, so we can edit it. - char* copy = xstrdup(msg); - - // Staging area for stringified parameters. - char parameters[5][100]; // FIXME: to be replaced with dynamic allocation - - // Handle format specifiers (including the custom %C, %L, %S) by adjusting the parameter accordingly, and replacing the specifier with %s. - int pi = 0; // parameter index - for (int i = 0; i < (int)strlen(msg); ++i) - { - if (msg[i] == '%') - { - ++pi; - - // Integer specifier. In order to accommodate the fact that PARMS can have both legitimate integers *and* packed tokens, stringify everything. Future work may eliminate the need for this. - if (msg[i + 1] == 'd') - { - copy[i + 1] = 's'; - sprintf(parameters[pi], "%ld", PARMS[pi]); - } - - // Unmodified string specifier. - if (msg[i + 1] == 's') - { - packed_to_token(PARMS[pi], parameters[pi]); - } - - // Singular/plural specifier. - if (msg[i + 1] == 'S') - { - copy[i + 1] = 's'; - if (PARMS[pi - 1] > 1) // look at the *previous* parameter (which by necessity must be numeric) - { - sprintf(parameters[pi], "%s", "s"); - } - else - { - sprintf(parameters[pi], "%s", ""); - } - } - - // All-lowercase specifier. - if (msg[i + 1] == 'L') - { - copy[i + 1] = 's'; - packed_to_token(PARMS[pi], parameters[pi]); - for (int j = 0; j < (int)strlen(parameters[pi]); ++j) - { - parameters[pi][j] = tolower(parameters[pi][j]); - } - } - - // First char uppercase, rest lowercase. - if (msg[i + 1] == 'C') - { - copy[i + 1] = 's'; - packed_to_token(PARMS[pi], parameters[pi]); - for (int j = 0; j < (int)strlen(parameters[pi]); ++j) - { - parameters[pi][j] = tolower(parameters[pi][j]); - } - parameters[pi][0] = toupper(parameters[pi][0]); - } - } + // Do nothing if we got a null pointer. + if (msg == NULL) + return; + + // Do nothing if we got an empty string. + if (strlen(msg) == 0) + return; + + // Print a newline if the global game.blklin says to. + if (game.blklin == true) + printf("\n"); + + // Create a copy of our string, so we can edit it. + char* copy = xstrdup(msg); + + // Staging area for stringified parameters. + char parameters[5][100]; // FIXME: to be replaced with dynamic allocation + + // Handle format specifiers (including the custom %C, %L, %S) by adjusting the parameter accordingly, and replacing the specifier with %s. + int pi = 0; // parameter index + for (int i = 0; i < (int)strlen(msg); ++i) { + if (msg[i] == '%') { + ++pi; + + // Integer specifier. In order to accommodate the fact that PARMS can have both legitimate integers *and* packed tokens, stringify everything. Future work may eliminate the need for this. + if (msg[i + 1] == 'd') { + copy[i + 1] = 's'; + sprintf(parameters[pi], "%ld", PARMS[pi]); + } + + // Unmodified string specifier. + if (msg[i + 1] == 's') { + packed_to_token(PARMS[pi], parameters[pi]); + } + + // Singular/plural specifier. + if (msg[i + 1] == 'S') { + copy[i + 1] = 's'; + if (PARMS[pi - 1] > 1) { // look at the *previous* parameter (which by necessity must be numeric) + sprintf(parameters[pi], "%s", "s"); + } else { + sprintf(parameters[pi], "%s", ""); + } + } + + // All-lowercase specifier. + if (msg[i + 1] == 'L') { + copy[i + 1] = 's'; + packed_to_token(PARMS[pi], parameters[pi]); + for (int j = 0; j < (int)strlen(parameters[pi]); ++j) { + parameters[pi][j] = tolower(parameters[pi][j]); + } + } + + // First char uppercase, rest lowercase. + if (msg[i + 1] == 'C') { + copy[i + 1] = 's'; + packed_to_token(PARMS[pi], parameters[pi]); + for (int j = 0; j < (int)strlen(parameters[pi]); ++j) { + parameters[pi][j] = tolower(parameters[pi][j]); + } + parameters[pi][0] = toupper(parameters[pi][0]); + } + } } - // Render the final string. - char rendered[2000]; // FIXME: to be replaced with dynamic allocation - sprintf(rendered, copy, parameters[1], parameters[2], parameters[3], parameters[4]); // FIXME: to be replaced with vsprintf() + // Render the final string. + char rendered[2000]; // FIXME: to be replaced with dynamic allocation + sprintf(rendered, copy, parameters[1], parameters[2], parameters[3], parameters[4]); // FIXME: to be replaced with vsprintf() - // Print the message. - printf("%s\n", rendered); + // Print the message. + printf("%s\n", rendered); - free(copy); + free(copy); } -void PSPEAK(vocab_t msg,int skip) +void PSPEAK(vocab_t msg, int skip) /* Find the skip+1st message from msg and print it. msg should be * the index of the inventory message for object. (INVEN+N+1 message * is game.prop=N message). */ { - if (skip >= 0) - newspeak(object_descriptions[msg].longs[skip]); - else - newspeak(object_descriptions[msg].inventory); + if (skip >= 0) + newspeak(object_descriptions[msg].longs[skip]); + else + newspeak(object_descriptions[msg].inventory); } void RSPEAK(vocab_t i) /* Print the i-th "random" message (section 6 of database). */ { - newspeak(arbitrary_messages[i]); + newspeak(arbitrary_messages[i]); } void SETPRM(long first, long p1, long p2) @@ -157,16 +142,16 @@ void SETPRM(long first, long p1, long p2) * are stored into PARMS(first) and PARMS(first+1). */ { if (first >= MAXPARMS) - BUG(29); + BUG(29); else { - PARMS[first] = p1; - PARMS[first+1] = p2; + PARMS[first] = p1; + PARMS[first + 1] = p2; } } bool GETIN(FILE *input, - long *pword1, long *pword1x, - long *pword2, long *pword2x) + long *pword1, long *pword1x, + long *pword2, long *pword2x) /* Get a command from the adventurer. Snarf out the first word, pad it with * blanks, and return it in WORD1. Chars 6 thru 10 are returned in WORD1X, in * case we need to print out the whole word in an error message. Any number of @@ -176,27 +161,27 @@ bool GETIN(FILE *input, long junk; for (;;) { - if (game.blklin) - TYPE0(); - if (!MAPLIN(input)) - return false; - *pword1=GETTXT(true,true,true); - if (game.blklin && *pword1 < 0) - continue; - *pword1x=GETTXT(false,true,true); - do { - junk=GETTXT(false,true,true); - } while - (junk > 0); - *pword2=GETTXT(true,true,true); - *pword2x=GETTXT(false,true,true); - do { - junk=GETTXT(false,true,true); - } while - (junk > 0); - if (GETTXT(true,true,true) <= 0) - return true; - RSPEAK(TWO_WORDS); + if (game.blklin) + TYPE0(); + if (!MAPLIN(input)) + return false; + *pword1 = GETTXT(true, true, true); + if (game.blklin && *pword1 < 0) + continue; + *pword1x = GETTXT(false, true, true); + do { + junk = GETTXT(false, true, true); + } while + (junk > 0); + *pword2 = GETTXT(true, true, true); + *pword2x = GETTXT(false, true, true); + do { + junk = GETTXT(false, true, true); + } while + (junk > 0); + if (GETTXT(true, true, true) <= 0) + return true; + RSPEAK(TWO_WORDS); } } @@ -207,17 +192,17 @@ long YES(FILE *input, vocab_t x, vocab_t y, vocab_t z) token_t reply, junk1, junk2, junk3; for (;;) { - RSPEAK(x); - GETIN(input, &reply, &junk1, &junk2, &junk3); - if (reply == MAKEWD(250519) || reply == MAKEWD(25)) { - RSPEAK(y); - return true; - } - if (reply == MAKEWD(1415) || reply == MAKEWD(14)) { - RSPEAK(z); - return false; - } - RSPEAK(PLEASE_ANSWER); + RSPEAK(x); + GETIN(input, &reply, &junk1, &junk2, &junk3); + if (reply == MAKEWD(250519) || reply == MAKEWD(25)) { + RSPEAK(y); + return true; + } + if (reply == MAKEWD(1415) || reply == MAKEWD(14)) { + RSPEAK(z); + return false; + } + RSPEAK(PLEASE_ANSWER); } } @@ -234,39 +219,39 @@ long GETTXT(bool skip, bool onewrd, bool upper) static long splitting = -1; if (LNPOSN != splitting) - splitting = -1; - text= -1; + splitting = -1; + text = -1; while (true) { - if (LNPOSN > LNLENG) - return(text); - if ((!skip) || INLINE[LNPOSN] != 0) - break; - ++LNPOSN; + if (LNPOSN > LNLENG) + return (text); + if ((!skip) || INLINE[LNPOSN] != 0) + break; + ++LNPOSN; } - text=0; - for (int I=1; I<=TOKLEN; I++) { - text=text*64; - if (LNPOSN > LNLENG || (onewrd && INLINE[LNPOSN] == 0)) - continue; - char current=INLINE[LNPOSN]; - if (current < ascii_to_advent['%']) { - splitting = -1; - if (upper && current >= ascii_to_advent['a']) - current=current-26; - text=text+current; - ++LNPOSN; - continue; - } - if (splitting != LNPOSN) { - text=text+ascii_to_advent['%']; - splitting = LNPOSN; - continue; - } - - text=text+current-ascii_to_advent['%']; - splitting = -1; - ++LNPOSN; + text = 0; + for (int I = 1; I <= TOKLEN; I++) { + text = text * 64; + if (LNPOSN > LNLENG || (onewrd && INLINE[LNPOSN] == 0)) + continue; + char current = INLINE[LNPOSN]; + if (current < ascii_to_advent['%']) { + splitting = -1; + if (upper && current >= ascii_to_advent['a']) + current = current - 26; + text = text + current; + ++LNPOSN; + continue; + } + if (splitting != LNPOSN) { + text = text + ascii_to_advent['%']; + splitting = LNPOSN; + continue; + } + + text = text + current - ascii_to_advent['%']; + splitting = -1; + ++LNPOSN; } return text; @@ -283,13 +268,13 @@ token_t MAKEWD(long letters) { long i = 1, word = 0; - for (long k=letters; k != 0; k=k/100) { - word=word+i*(MOD(k,50)+10); - i=i*64; - if (MOD(k,100) > 50)word=word+i*5; + for (long k = letters; k != 0; k = k / 100) { + word = word + i * (MOD(k, 50) + 10); + i = i * 64; + if (MOD(k, 100) > 50)word = word + i * 5; } - i=64L*64L*64L*64L*64L/i; - word=word*i; + i = 64L * 64L * 64L * 64L * 64L / i; + word = word * i; return word; } @@ -299,16 +284,16 @@ void TYPE0(void) { long temp; - temp=LNLENG; - LNLENG=0; + temp = LNLENG; + LNLENG = 0; TYPE(); - LNLENG=temp; + LNLENG = temp; return; } /* Data structure routines */ -long VOCAB(long id, long init) +long VOCAB(long id, long init) /* Look up ID in the vocabulary (ATAB) and return its "definition" (KTAB), or * -1 if not found. If INIT is positive, this is an initialisation call setting * up a keyword variable, and not finding it constitutes a bug. It also means @@ -318,21 +303,21 @@ long VOCAB(long id, long init) { long lexeme; - for (long i=1; i<=TABSIZ; i++) { - if (KTAB[i] == -1) { - lexeme= -1; - if (init < 0) - return(lexeme); - BUG(5); - } - if (init >= 0 && KTAB[i]/1000 != init) - continue; - if (ATAB[i] == id) { - lexeme=KTAB[i]; - if (init >= 0) - lexeme=MOD(lexeme,1000); - return(lexeme); - } + for (long i = 1; i <= TABSIZ; i++) { + if (KTAB[i] == -1) { + lexeme = -1; + if (init < 0) + return (lexeme); + BUG(5); + } + if (init >= 0 && KTAB[i] / 1000 != init) + continue; + if (ATAB[i] == id) { + lexeme = KTAB[i]; + if (init >= 0) + lexeme = MOD(lexeme, 1000); + return (lexeme); + } } BUG(21); } @@ -343,10 +328,10 @@ void JUGGLE(long object) { long i, j; - i=game.place[object]; - j=game.fixed[object]; - MOVE(object,i); - MOVE(object+NOBJECTS,j); + i = game.place[object]; + j = game.fixed[object]; + MOVE(object, i); + MOVE(object + NOBJECTS, j); } void MOVE(long object, long where) @@ -357,24 +342,24 @@ void MOVE(long object, long where) { long from; - if (object > NOBJECTS) - from=game.fixed[object-NOBJECTS]; + if (object > NOBJECTS) + from = game.fixed[object - NOBJECTS]; else - from=game.place[object]; + from = game.place[object]; if (from != NOWHERE && from != CARRIED && !SPECIAL(from)) - CARRY(object,from); - DROP(object,where); + CARRY(object, from); + DROP(object, where); } long PUT(long object, long where, long pval) /* PUT is the same as MOVE, except it returns a value used to set up the * negated game.prop values for the repository objects. */ { - MOVE(object,where); - return (-1)-pval;; + MOVE(object, where); + return (-1) - pval;; } -void CARRY(long object, long where) +void CARRY(long object, long where) /* Start toting an object, removing it from the list of things at its former * location. Incr holdng unless it was already being toted. If object>NOBJECTS * (moving "fixed" second loc), don't change game.place or game.holdng. */ @@ -382,20 +367,20 @@ void CARRY(long object, long where) long temp; if (object <= NOBJECTS) { - if (game.place[object] == CARRIED) - return; - game.place[object] = CARRIED; - ++game.holdng; + if (game.place[object] == CARRIED) + return; + game.place[object] = CARRIED; + ++game.holdng; } if (game.atloc[where] == object) { - game.atloc[where]=game.link[object]; - return; + game.atloc[where] = game.link[object]; + return; } - temp=game.atloc[where]; + temp = game.atloc[where]; while (game.link[temp] != object) { - temp=game.link[temp]; + temp = game.link[temp]; } - game.link[temp]=game.link[object]; + game.link[temp] = game.link[object]; } void DROP(long object, long where) @@ -403,15 +388,14 @@ void DROP(long object, long where) * game.holdng if the object was being toted. */ { if (object > NOBJECTS) - game.fixed[object-NOBJECTS] = where; - else - { - if (game.place[object] == CARRIED) - --game.holdng; - game.place[object] = where; + game.fixed[object - NOBJECTS] = where; + else { + if (game.place[object] == CARRIED) + --game.holdng; + game.place[object] = where; } if (where <= 0) - return; + return; game.link[object] = game.atloc[where]; game.atloc[where] = object; } @@ -423,17 +407,17 @@ long ATDWRF(long where) { long at; - at =0; + at = 0; if (game.dflag < 2) - return(at); + return (at); at = -1; - for (long i=1; i<=NDWARVES-1; i++) { - if (game.dloc[i] == where) - return i; - if (game.dloc[i] != 0) - at=0; + for (long i = 1; i <= NDWARVES - 1; i++) { + if (game.dloc[i] == where) + return i; + if (game.dloc[i] != 0) + at = 0; } - return(at); + return (at); } /* Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value, @@ -442,7 +426,7 @@ long ATDWRF(long where) long SETBIT(long bit) /* Returns 2**bit for use in constructing bit-masks. */ { - return(1 << bit); + return (1 << bit); } bool TSTBIT(long mask, int bit) @@ -480,21 +464,20 @@ long RNDVOC(long second, long force) long rnd = force; if (rnd == 0) { - for (int i = 1; i <= 5; i++) { - long j = 11 + randrange(26); - if (i == 2) - j = second; - rnd = rnd * 64 + j; - } + for (int i = 1; i <= 5; i++) { + long j = 11 + randrange(26); + if (i == 2) + j = second; + rnd = rnd * 64 + j; + } } long div = 64L * 64L * 64L; for (int i = 1; i <= TABSIZ; i++) { - if (MOD(ATAB[i]/div, 64L) == second) - { - ATAB[i] = rnd; - break; - } + if (MOD(ATAB[i] / div, 64L) == second) { + ATAB[i] = rnd; + break; + } } return rnd; @@ -538,7 +521,7 @@ bool MAPLIN(FILE *fp) bool eof; /* Read a line of input, from the specified input source. - * This logic is complicated partly because it has to serve + * This logic is complicated partly because it has to serve * several cases with different requirements and partly because * of a quirk in linenoise(). * @@ -551,80 +534,79 @@ bool MAPLIN(FILE *fp) * fed redirected stdin. * * The logging is a bit of a mess because there are two distinct cases - * in which you want to echo commands. One is when shipping them to + * in which you want to echo commands. One is when shipping them to * a log under the -l option, in which case you want to suppress * prompt generation (so test logs are unadorned command sequences). - * On the other hand, if you redirected stdin and are feeding the program + * On the other hand, if you redirected stdin and are feeding the program * a logfile, you *do* want prompt generation - it makes checkfiles * easier to read when the commands are marked by a preceding prompt. */ do { - if (!editline) { - if (prompt) - fputs("> ", stdout); - IGNORE(fgets(rawbuf,sizeof(rawbuf)-1,fp)); - eof = (feof(fp)); - } else { - char *cp = linenoise("> "); - eof = (cp == NULL); - if (!eof) { - strncpy(rawbuf, cp, sizeof(rawbuf)-1); - linenoiseHistoryAdd(rawbuf); - strncat(rawbuf, "\n", sizeof(rawbuf) - strlen(rawbuf) - 1); - linenoiseFree(cp); - } - } + if (!editline) { + if (prompt) + fputs("> ", stdout); + IGNORE(fgets(rawbuf, sizeof(rawbuf) - 1, fp)); + eof = (feof(fp)); + } else { + char *cp = linenoise("> "); + eof = (cp == NULL); + if (!eof) { + strncpy(rawbuf, cp, sizeof(rawbuf) - 1); + linenoiseHistoryAdd(rawbuf); + strncat(rawbuf, "\n", sizeof(rawbuf) - strlen(rawbuf) - 1); + linenoiseFree(cp); + } + } } while - (!eof && rawbuf[0] == '#'); + (!eof && rawbuf[0] == '#'); if (eof) { - if (logfp && fp == stdin) - fclose(logfp); - return false; + if (logfp && fp == stdin) + fclose(logfp); + return false; } else { - FILE *efp = NULL; - if (logfp && fp == stdin) - efp = logfp; - else if (!isatty(0)) - efp = stdout; - if (efp != NULL) - { - if (prompt && efp == stdout) - fputs("> ", efp); - IGNORE(fputs(rawbuf, efp)); - } - strcpy(INLINE+1, rawbuf); - /* translate the chars to integers in the range 0-126 and store - * them in the common array "INLINE". Integer values are as follows: - * 0 = space [ASCII CODE 40 octal, 32 decimal] - * 1-2 = !" [ASCII 41-42 octal, 33-34 decimal] - * 3-10 = '()*+,-. [ASCII 47-56 octal, 39-46 decimal] - * 11-36 = upper-case letters - * 37-62 = lower-case letters - * 63 = percent (%) [ASCII 45 octal, 37 decimal] - * 64-73 = digits, 0 through 9 - * Remaining characters can be translated any way that is convenient; - * The "TYPE" routine below is used to map them back to characters when - * necessary. The above mappings are required so that certain special - * characters are known to fit in 6 bits and/or can be easily spotted. - * Array elements beyond the end of the line should be filled with 0, - * and LNLENG should be set to the index of the last character. - * - * If the data file uses a character other than space (e.g., tab) to - * separate numbers, that character should also translate to 0. - * - * This procedure may use the map1,map2 arrays to maintain static data for - * the mapping. MAP2(1) is set to 0 when the program starts - * and is not changed thereafter unless the routines on this page choose - * to do so. */ - LNLENG=0; - for (long i=1; i<=(long)sizeof(INLINE) && INLINE[i]!=0; i++) { - long val=INLINE[i]; - INLINE[i]=ascii_to_advent[val]; - if (INLINE[i] != 0) - LNLENG=i; - } - LNPOSN=1; - return true; + FILE *efp = NULL; + if (logfp && fp == stdin) + efp = logfp; + else if (!isatty(0)) + efp = stdout; + if (efp != NULL) { + if (prompt && efp == stdout) + fputs("> ", efp); + IGNORE(fputs(rawbuf, efp)); + } + strcpy(INLINE + 1, rawbuf); + /* translate the chars to integers in the range 0-126 and store + * them in the common array "INLINE". Integer values are as follows: + * 0 = space [ASCII CODE 40 octal, 32 decimal] + * 1-2 = !" [ASCII 41-42 octal, 33-34 decimal] + * 3-10 = '()*+,-. [ASCII 47-56 octal, 39-46 decimal] + * 11-36 = upper-case letters + * 37-62 = lower-case letters + * 63 = percent (%) [ASCII 45 octal, 37 decimal] + * 64-73 = digits, 0 through 9 + * Remaining characters can be translated any way that is convenient; + * The "TYPE" routine below is used to map them back to characters when + * necessary. The above mappings are required so that certain special + * characters are known to fit in 6 bits and/or can be easily spotted. + * Array elements beyond the end of the line should be filled with 0, + * and LNLENG should be set to the index of the last character. + * + * If the data file uses a character other than space (e.g., tab) to + * separate numbers, that character should also translate to 0. + * + * This procedure may use the map1,map2 arrays to maintain static data for + * the mapping. MAP2(1) is set to 0 when the program starts + * and is not changed thereafter unless the routines on this page choose + * to do so. */ + LNLENG = 0; + for (long i = 1; i <= (long)sizeof(INLINE) && INLINE[i] != 0; i++) { + long val = INLINE[i]; + INLINE[i] = ascii_to_advent[val]; + if (INLINE[i] != 0) + LNLENG = i; + } + LNPOSN = 1; + return true; } } @@ -636,15 +618,15 @@ void TYPE(void) long i; if (LNLENG == 0) { - printf("\n"); - return; + printf("\n"); + return; } - for (i=1; i<=LNLENG; i++) { - INLINE[i]=advent_to_ascii[(int) INLINE[i]]; + for (i = 1; i <= LNLENG; i++) { + INLINE[i] = advent_to_ascii[(int) INLINE[i]]; } - INLINE[LNLENG+1]=0; - printf("%s\n", INLINE+1); + INLINE[LNLENG + 1] = 0; + printf("%s\n", INLINE + 1); return; } diff --git a/saveresume.c b/saveresume.c index 5cc9726..6f570b9 100644 --- a/saveresume.c +++ b/saveresume.c @@ -31,7 +31,8 @@ struct save_t save; /* Suspend and resume */ int suspend(FILE *input) -{ /* Suspend. Offer to save things in a file, but charging +{ + /* Suspend. Offer to save things in a file, but charging * some points (so can't win by using saved games to retry * battles or to start over after learning zzword). * If ADVENT_NOSAVE is defined, do nothing instead. */ @@ -43,21 +44,21 @@ int suspend(FILE *input) FILE *fp = NULL; RSPEAK(SUSPEND_WARNING); - if (!YES(input,THIS_ACCEPTABLE,OK_MAN,OK_MAN)) return GO_CLEAROBJ; - game.saved=game.saved+5; + if (!YES(input, THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ; + game.saved = game.saved + 5; while (fp == NULL) { - char* name = linenoise("\nFile name: "); - if (name == NULL) - return GO_TOP; - fp = fopen(name, WRITE_MODE); - if (fp == NULL) - printf("Can't open file %s, try again.\n", name); - linenoiseFree(name); + char* name = linenoise("\nFile name: "); + if (name == NULL) + return GO_TOP; + fp = fopen(name, WRITE_MODE); + if (fp == NULL) + printf("Can't open file %s, try again.\n", name); + linenoiseFree(name); } - DATIME(&i,&k); - k=i+650*k; + DATIME(&i, &k); + k = i + 650 * k; save.savetime = k; save.mode = -1; save.version = VRSION; @@ -71,7 +72,8 @@ int suspend(FILE *input) } int resume(FILE *input) -{ /* Resume. Read a suspended game back from a file. +{ + /* Resume. Read a suspended game back from a file. * If ADVENT_NOSAVE is defined, do nothing instead. */ #ifdef ADVENT_NOSAVE @@ -80,25 +82,26 @@ int resume(FILE *input) FILE *fp = NULL; if (game.loc != 1 || game.abbrev[1] != 1) { - RSPEAK(RESUME_ABANDON); - if (!YES(input,THIS_ACCEPTABLE,OK_MAN,OK_MAN)) return GO_CLEAROBJ; + RSPEAK(RESUME_ABANDON); + if (!YES(input, THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ; } while (fp == NULL) { - char* name = linenoise("\nFile name: "); - if (name == NULL) - return GO_TOP; - fp = fopen(name, READ_MODE); - if (fp == NULL) - printf("Can't open file %s, try again.\n", name); - linenoiseFree(name); + char* name = linenoise("\nFile name: "); + if (name == NULL) + return GO_TOP; + fp = fopen(name, READ_MODE); + if (fp == NULL) + printf("Can't open file %s, try again.\n", name); + linenoiseFree(name); } return restore(fp); } int restore(FILE* fp) -{ /* Read and restore game state from file, assuming +{ + /* Read and restore game state from file, assuming * sane initial state. * If ADVENT_NOSAVE is defined, do nothing instead. */ #ifdef ADVENT_NOSAVE @@ -108,14 +111,14 @@ int restore(FILE* fp) IGNORE(fread(&save, sizeof(struct save_t), 1, fp)); fclose(fp); if (save.version != VRSION) { - SETPRM(1,save.version/10,MOD(save.version,10)); - SETPRM(3,VRSION/10,MOD(VRSION,10)); + SETPRM(1, save.version / 10, MOD(save.version, 10)); + SETPRM(3, VRSION / 10, MOD(VRSION, 10)); RSPEAK(VERSION_SKEW); } else { memcpy(&game, &save.game, sizeof(struct game_t)); OBJSND[BIRD] = save.bird; OBJTXT[OYSTER] = save.bivalve; - game.zzword=RNDVOC(3,game.zzword); + game.zzword = RNDVOC(3, game.zzword); } return GO_TOP; } diff --git a/score.c b/score.c index 7b0269d..c0f28fa 100644 --- a/score.c +++ b/score.c @@ -34,17 +34,17 @@ void score(enum termination mode) /* First tally up the treasures. Must be in building and not broken. * Give the poor guy 2 points just for finding each treasure. */ - for (long i=MINTRS; i<=MAXTRS; i++) { - if(object_descriptions[i].inventory != 0) { - long k=12; - if(i == CHEST)k=14; - if(i > CHEST)k=16; - if(game.prop[i] >= 0) - score += 2; - if(game.place[i] == LOC_BUILDING && game.prop[i] == 0) - score += k-2; - mxscor += k; - } + for (long i = MINTRS; i <= MAXTRS; i++) { + if (object_descriptions[i].inventory != 0) { + long k = 12; + if (i == CHEST)k = 14; + if (i > CHEST)k = 16; + if (game.prop[i] >= 0) + score += 2; + if (game.place[i] == LOC_BUILDING && game.prop[i] == 0) + score += k - 2; + mxscor += k; + } } /* Now look at how he finished and how far he got. MAXDIE and @@ -53,30 +53,30 @@ void score(enum termination mode) * indicates whether he reached the endgame. And if he got as far as * "cave closed" (indicated by "game.closed"), then bonus is zero for * mundane exits or 133, 134, 135 if he blew it (so to speak). */ - score += (MAXDIE-game.numdie)*10; - mxscor += MAXDIE*10; - if(mode == endgame) - score += 4; + score += (MAXDIE - game.numdie) * 10; + mxscor += MAXDIE * 10; + if (mode == endgame) + score += 4; mxscor += 4; - if(game.dflag != 0)score += 25; + if (game.dflag != 0)score += 25; mxscor += 25; - if(game.closng)score += 25; + if (game.closng)score += 25; mxscor += 25; - if(game.closed) { - if(game.bonus == 0) - score += 10; - if(game.bonus == SPLATTER_MESSAGE) - score += 25; - if(game.bonus == DEFEAT_MESSAGE) - score += 30; - if(game.bonus == VICTORY_MESSAGE) - score += 45; + if (game.closed) { + if (game.bonus == 0) + score += 10; + if (game.bonus == SPLATTER_MESSAGE) + score += 25; + if (game.bonus == DEFEAT_MESSAGE) + score += 30; + if (game.bonus == VICTORY_MESSAGE) + score += 45; } mxscor += 45; /* Did he come to Witt's End as he should? */ - if(game.place[MAGZIN] == LOC_WITTSEND) - score += 1; + if (game.place[MAGZIN] == LOC_WITTSEND) + score += 1; mxscor += 1; /* Round it off. */ @@ -84,40 +84,40 @@ void score(enum termination mode) mxscor += 2; /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */ - for (long i=1; i<=HNTMAX; i++) { - if(game.hinted[i]) - score=score-HINTS[i][2]; + for (long i = 1; i <= HNTMAX; i++) { + if (game.hinted[i]) + score = score - HINTS[i][2]; } - if(game.novice) - score -= 5; - if(game.clshnt) - score -= 10; - score=score-game.trnluz-game.saved; + if (game.novice) + score -= 5; + if (game.clshnt) + score -= 10; + score = score - game.trnluz - game.saved; /* Return to score command if that's where we came from. */ - if(mode == scoregame) { - SETPRM(1,score,mxscor); - SETPRM(3,game.turns,game.turns); - RSPEAK(GARNERED_POINTS); - return; + if (mode == scoregame) { + SETPRM(1, score, mxscor); + SETPRM(3, game.turns, game.turns); + RSPEAK(GARNERED_POINTS); + return; } /* that should be good enough. Let's tell him all about it. */ - if(score+game.trnluz+1 >= mxscor && game.trnluz != 0) - RSPEAK(TOOK_LONG); - if(score+game.saved+1 >= mxscor && game.saved != 0) - RSPEAK(WITHOUT_SUSPENDS); - SETPRM(1,score,mxscor); - SETPRM(3,game.turns,game.turns); + if (score + game.trnluz + 1 >= mxscor && game.trnluz != 0) + RSPEAK(TOOK_LONG); + if (score + game.saved + 1 >= mxscor && game.saved != 0) + RSPEAK(WITHOUT_SUSPENDS); + SETPRM(1, score, mxscor); + SETPRM(3, game.turns, game.turns); RSPEAK(TOTAL_SCORE); - for (long i=1; i<=(long)CLSSES; i++) { - if(CVAL[i] >= score) { - newspeak(class_messages[i]); - i=CVAL[i]+1-score; - SETPRM(1,i,i); - RSPEAK(NEXT_HIGHER); - exit(0); - } + for (long i = 1; i <= (long)CLSSES; i++) { + if (CVAL[i] >= score) { + newspeak(class_messages[i]); + i = CVAL[i] + 1 - score; + SETPRM(1, i, i); + RSPEAK(NEXT_HIGHER); + exit(0); + } } RSPEAK(OFF_SCALE); RSPEAK(NO_HIGHER); -- 2.31.1