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);
* 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;
+ }
}
}
{
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;
/* 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);
}
}
/* 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;
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;
}
{
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;
{
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;
{
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;
}
{
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;
{
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;
{
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;
}
{
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;
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;
{
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;
}
{
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;
}
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;
}
{
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;
}
}
/* 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;
{
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;
* 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;
}
{
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;
+ }
}
}
{
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;
/* 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;
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);
}
/* 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;
}
}
/* 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;
}
}
* 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);
}
}
#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,
};
// 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
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];
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
* 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
* 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.
* 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 */
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);
}
* 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
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.
* 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,
* 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
* 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;
}
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;
static void sig_handler(int signo)
{
- if (signo == SIGINT){
- if (logfp != NULL)
- fflush(logfp);
- }
+ if (signo == SIGINT) {
+ if (logfp != NULL)
+ fflush(logfp);
+ }
exit(0);
}
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);
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);
{
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;
}
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
* 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;
* 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,
* 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;
}
{
++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;
}
}
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;
}
* 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
* 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;
/* 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
* 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);
+ }
}
}
* 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;
/* 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);
+ }
}
}
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;
}
}
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)
* 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
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);
}
}
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);
}
}
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;
{
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;
}
{
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
{
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);
}
{
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)
{
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. */
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)
* 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;
}
{
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,
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)
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;
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().
*
* 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;
}
}
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;
}
/* 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. */
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;
}
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
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
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;
}
/* 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
* 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. */
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);