WD* globals abolished. They're now members of the command block.
This commit is contained in:
parent
9714c9fc2a
commit
9437ccca36
4 changed files with 124 additions and 126 deletions
4
TODO
4
TODO
|
@ -3,10 +3,6 @@
|
||||||
The FORTRANish mess that once was is now mostly idiomatic C. Some issues
|
The FORTRANish mess that once was is now mostly idiomatic C. Some issues
|
||||||
remain to be cleaned up:
|
remain to be cleaned up:
|
||||||
|
|
||||||
* The remaining shared globals: WD1, WD1X, WD2, WD2X. These are used
|
|
||||||
rather promiscuously to pass around information that ought to be function
|
|
||||||
arguments in a modern language.
|
|
||||||
|
|
||||||
* Remaining unstructured gotos in do_command().
|
* Remaining unstructured gotos in do_command().
|
||||||
|
|
||||||
* The program is still pretty much typeless - full of magic numbers being
|
* The program is still pretty much typeless - full of magic numbers being
|
||||||
|
|
203
actions.c
203
actions.c
|
@ -4,17 +4,16 @@
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "newdb.h"
|
#include "newdb.h"
|
||||||
|
|
||||||
/* Limit visibility of ugly globals. Eventually these should go away. */
|
|
||||||
extern token_t WD1, WD1X, WD2, WD2X;
|
|
||||||
|
|
||||||
static int fill(token_t, token_t);
|
static int fill(token_t, token_t);
|
||||||
|
|
||||||
static int attack(FILE *input, token_t verb, token_t obj)
|
static int attack(FILE *input, struct command_t *command)
|
||||||
/* Attack. Assume target if unambiguous. "Throw" also links here.
|
/* Attack. Assume target if unambiguous. "Throw" also links here.
|
||||||
* Attackable objects fall into two categories: enemies (snake,
|
* Attackable objects fall into two categories: enemies (snake,
|
||||||
* dwarf, etc.) and others (bird, clam, machine). Ambiguous if 2
|
* dwarf, etc.) and others (bird, clam, machine). Ambiguous if 2
|
||||||
* enemies, or no enemies but 2 others. */
|
* enemies, or no enemies but 2 others. */
|
||||||
{
|
{
|
||||||
|
vocab_t verb = command->verb;
|
||||||
|
vocab_t obj = command->obj;
|
||||||
int spk = ACTSPK[verb];
|
int spk = ACTSPK[verb];
|
||||||
if (obj == 0 || obj == INTRANSITIVE) {
|
if (obj == 0 || obj == INTRANSITIVE) {
|
||||||
if (ATDWRF(game.loc) > 0)
|
if (ATDWRF(game.loc) > 0)
|
||||||
|
@ -81,8 +80,8 @@ static int attack(FILE *input, token_t verb, token_t obj)
|
||||||
* fixed), move rug there (not fixed), and move him there,
|
* fixed), move rug there (not fixed), and move him there,
|
||||||
* too. Then do a null motion to get new description. */
|
* too. Then do a null motion to get new description. */
|
||||||
RSPEAK(BARE_HANDS_QUERY);
|
RSPEAK(BARE_HANDS_QUERY);
|
||||||
GETIN(input, &WD1, &WD1X, &WD2, &WD2X);
|
GETIN(input, &command->wd1, &command->wd1x, &command->wd2, &command->wd2x);
|
||||||
if (WD1 != MAKEWD(WORD_YINIT) && WD1 != MAKEWD(WORD_YES))
|
if (command->wd1 != MAKEWD(WORD_YINIT) && command->wd1 != MAKEWD(WORD_YES))
|
||||||
return GO_CHECKFOO;
|
return GO_CHECKFOO;
|
||||||
PSPEAK(DRAGON, 3);
|
PSPEAK(DRAGON, 3);
|
||||||
game.prop[DRAGON] = 1;
|
game.prop[DRAGON] = 1;
|
||||||
|
@ -107,7 +106,7 @@ static int attack(FILE *input, token_t verb, token_t obj)
|
||||||
|
|
||||||
static int bigwords(token_t foo)
|
static int bigwords(token_t foo)
|
||||||
/* FEE FIE FOE FOO (AND FUM). Advance to next state if given in proper order.
|
/* FEE FIE FOE FOO (AND FUM). Advance to next state if given in proper order.
|
||||||
* Look up WD1 in section 3 of vocab to determine which word we've got. Last
|
* Look up foo 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). */
|
* word zips the eggs back to the giant room (unless already there). */
|
||||||
{
|
{
|
||||||
int k = VOCAB(foo, 3);
|
int k = VOCAB(foo, 3);
|
||||||
|
@ -792,32 +791,32 @@ static int quit(void)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read(token_t verb, token_t obj)
|
static int read(struct command_t *command)
|
||||||
/* Read. Print stuff based on objtxt. Oyster (?) is special case. */
|
/* Read. Print stuff based on objtxt. Oyster (?) is special case. */
|
||||||
{
|
{
|
||||||
if (obj == INTRANSITIVE) {
|
if (command->obj == INTRANSITIVE) {
|
||||||
obj = 0;
|
command->obj = 0;
|
||||||
for (int i = 1; i <= NOBJECTS; i++) {
|
for (int i = 1; i <= NOBJECTS; i++) {
|
||||||
if (HERE(i) && OBJTXT[i] != 0 && game.prop[i] >= 0)
|
if (HERE(i) && OBJTXT[i] != 0 && game.prop[i] >= 0)
|
||||||
obj = obj * NOBJECTS + i;
|
command->obj = command->obj * NOBJECTS + i;
|
||||||
}
|
}
|
||||||
if (obj > NOBJECTS || obj == 0 || DARK(game.loc)) return GO_UNKNOWN;
|
if (command->obj > NOBJECTS || command->obj == 0 || DARK(game.loc)) return GO_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DARK(game.loc)) {
|
if (DARK(game.loc)) {
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, command->wd1, command->wd1x);
|
||||||
RSPEAK(NO_SEE);
|
RSPEAK(NO_SEE);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
if (OBJTXT[obj] == 0 || game.prop[obj] < 0) {
|
if (OBJTXT[command->obj] == 0 || game.prop[command->obj] < 0) {
|
||||||
RSPEAK(ACTSPK[verb]);
|
RSPEAK(ACTSPK[command->verb]);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
if (obj == OYSTER && !game.clshnt) {
|
if (command->obj == OYSTER && !game.clshnt) {
|
||||||
game.clshnt = YES(arbitrary_messages[CLUE_QUERY], arbitrary_messages[WAYOUT_CLUE], arbitrary_messages[OK_MAN]);
|
game.clshnt = YES(arbitrary_messages[CLUE_QUERY], arbitrary_messages[WAYOUT_CLUE], arbitrary_messages[OK_MAN]);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
PSPEAK(obj, OBJTXT[obj] + game.prop[obj]);
|
PSPEAK(command->obj, OBJTXT[command->obj] + game.prop[command->obj]);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,19 +858,19 @@ static int rub(token_t verb, token_t obj)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int say(void)
|
static int say(struct command_t *command)
|
||||||
/* Say. Echo WD2 (or WD1 if no WD2 (SAY WHAT?, etc.).) Magic words override. */
|
/* Say. Echo WD2 (or WD1 if no WD2 (SAY WHAT?, etc.).) Magic words override. */
|
||||||
{
|
{
|
||||||
/* FIXME: ugly use of globals */
|
/* FIXME: ugly use of globals */
|
||||||
SETPRM(1, WD2, WD2X);
|
SETPRM(1, command->wd2, command->wd2x);
|
||||||
if (WD2 <= 0)
|
if (command->wd2 <= 0)
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, command->wd1, command->wd1x);
|
||||||
if (WD2 > 0)
|
if (command->wd2 > 0)
|
||||||
WD1 = WD2;
|
command->wd1 = command->wd2;
|
||||||
int wd = VOCAB(WD1, -1);
|
int wd = VOCAB(command->wd1, -1);
|
||||||
/* FIXME: Magic numbers */
|
/* FIXME: Magic numbers */
|
||||||
if (wd == 62 || wd == 65 || wd == 71 || wd == 2025 || wd == 2034) {
|
if (wd == 62 || wd == 65 || wd == 71 || wd == 2025 || wd == 2034) {
|
||||||
WD2 = 0;
|
command->wd2 = 0;
|
||||||
return GO_LOOKUP;
|
return GO_LOOKUP;
|
||||||
}
|
}
|
||||||
RSPEAK(OKEY_DOKEY);
|
RSPEAK(OKEY_DOKEY);
|
||||||
|
@ -885,22 +884,22 @@ static int throw_support(long spk)
|
||||||
return GO_MOVE;
|
return GO_MOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int throw (FILE *cmdin, long verb, token_t obj)
|
static int throw (FILE *cmdin, struct command_t *command)
|
||||||
/* Throw. Same as discard unless axe. Then same as attack except
|
/* Throw. Same as discard unless axe. Then same as attack except
|
||||||
* ignore bird, and if dwarf is present then one might be killed.
|
* ignore bird, and if dwarf is present then one might be killed.
|
||||||
* (Only way to do so!) Axe also special for dragon, bear, and
|
* (Only way to do so!) Axe also special for dragon, bear, and
|
||||||
* troll. Treasures special for troll. */
|
* troll. Treasures special for troll. */
|
||||||
{
|
{
|
||||||
int spk = ACTSPK[verb];
|
int spk = ACTSPK[command->verb];
|
||||||
if (TOTING(ROD2) && obj == ROD && !TOTING(ROD))obj = ROD2;
|
if (TOTING(ROD2) && command->obj == ROD && !TOTING(ROD))command->obj = ROD2;
|
||||||
if (!TOTING(obj)) {
|
if (!TOTING(command->obj)) {
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
if (obj >= MINTRS && obj <= MAXTRS && AT(TROLL)) {
|
if (command->obj >= MINTRS && command->obj <= MAXTRS && AT(TROLL)) {
|
||||||
spk = TROLL_SATISFIED;
|
spk = TROLL_SATISFIED;
|
||||||
/* Snarf a treasure for the troll. */
|
/* Snarf a treasure for the troll. */
|
||||||
DROP(obj, 0);
|
DROP(command->obj, 0);
|
||||||
MOVE(TROLL, 0);
|
MOVE(TROLL, 0);
|
||||||
MOVE(TROLL + NOBJECTS, 0);
|
MOVE(TROLL + NOBJECTS, 0);
|
||||||
DROP(TROLL2, PLAC[TROLL]);
|
DROP(TROLL2, PLAC[TROLL]);
|
||||||
|
@ -909,13 +908,13 @@ static int throw (FILE *cmdin, long verb, token_t obj)
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
if (obj == FOOD && HERE(BEAR)) {
|
if (command->obj == FOOD && HERE(BEAR)) {
|
||||||
/* But throwing food is another story. */
|
/* But throwing food is another story. */
|
||||||
obj = BEAR;
|
command->obj = BEAR;
|
||||||
return (feed(verb, obj));
|
return (feed(command->verb, command->obj));
|
||||||
}
|
}
|
||||||
if (obj != AXE)
|
if (command->obj != AXE)
|
||||||
return (discard(verb, obj, false));
|
return (discard(command->verb, command->obj, false));
|
||||||
else {
|
else {
|
||||||
int i = ATDWRF(game.loc);
|
int i = ATDWRF(game.loc);
|
||||||
if (i <= 0) {
|
if (i <= 0) {
|
||||||
|
@ -934,7 +933,8 @@ static int throw (FILE *cmdin, long verb, token_t obj)
|
||||||
RSPEAK(AXE_LOST);
|
RSPEAK(AXE_LOST);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
return (attack(cmdin, verb, 0));
|
command->obj = 0;
|
||||||
|
return (attack(cmdin, command));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (randrange(NDWARVES + 1) < game.dflag) {
|
if (randrange(NDWARVES + 1) < game.dflag) {
|
||||||
|
@ -995,14 +995,14 @@ static int wave(token_t verb, token_t obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int action(FILE *input, struct command_t command)
|
int action(FILE *input, struct command_t *command)
|
||||||
/* Analyse a verb. Remember what it was, go back for object if second word
|
/* Analyse a verb. Remember what it was, go back for object if second word
|
||||||
* unless verb is "say", which snarfs arbitrary second word.
|
* unless verb is "say", which snarfs arbitrary second word.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
token_t spk = ACTSPK[command.verb];
|
token_t spk = ACTSPK[command->verb];
|
||||||
|
|
||||||
if (command.part == unknown) {
|
if (command->part == unknown) {
|
||||||
/* Analyse an object word. See if the thing is here, whether
|
/* Analyse an object word. See if the thing is here, whether
|
||||||
* we've got a verb yet, and so on. Object must be here
|
* we've got a verb yet, and so on. Object must be here
|
||||||
* unless verb is "find" or "invent(ory)" (and no new verb
|
* unless verb is "find" or "invent(ory)" (and no new verb
|
||||||
|
@ -1010,74 +1010,74 @@ int action(FILE *input, struct command_t command)
|
||||||
* they are never actually dropped at any location, but might
|
* they are never actually dropped at any location, but might
|
||||||
* be here inside the bottle or urn or as a feature of the
|
* be here inside the bottle or urn or as a feature of the
|
||||||
* location. */
|
* location. */
|
||||||
if (HERE(command.obj))
|
if (HERE(command->obj))
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
else if (command.obj == GRATE) {
|
else if (command->obj == GRATE) {
|
||||||
if (game.loc == LOC_START || game.loc == LOC_VALLEY || game.loc == LOC_SLIT)
|
if (game.loc == LOC_START || game.loc == LOC_VALLEY || game.loc == LOC_SLIT)
|
||||||
command.obj = DPRSSN;
|
command->obj = DPRSSN;
|
||||||
if (game.loc == LOC_COBBLE || game.loc == LOC_DEBRIS || game.loc == LOC_AWKWARD ||
|
if (game.loc == LOC_COBBLE || game.loc == LOC_DEBRIS || game.loc == LOC_AWKWARD ||
|
||||||
game.loc == LOC_BIRD || game.loc == LOC_PITTOP)
|
game.loc == LOC_BIRD || game.loc == LOC_PITTOP)
|
||||||
command.obj = ENTRNC;
|
command->obj = ENTRNC;
|
||||||
if (command.obj != GRATE)
|
if (command->obj != GRATE)
|
||||||
return GO_MOVE;
|
return GO_MOVE;
|
||||||
} else if (command.obj == DWARF && ATDWRF(game.loc) > 0)
|
} else if (command->obj == DWARF && ATDWRF(game.loc) > 0)
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
else if ((LIQUID() == command.obj && HERE(BOTTLE)) || command.obj == LIQLOC(game.loc))
|
else if ((LIQUID() == command->obj && HERE(BOTTLE)) || command->obj == LIQLOC(game.loc))
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
else if (command.obj == OIL && HERE(URN) && game.prop[URN] != 0) {
|
else if (command->obj == OIL && HERE(URN) && game.prop[URN] != 0) {
|
||||||
command.obj = URN;
|
command->obj = URN;
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
} else if (command.obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) {
|
} else if (command->obj == PLANT && AT(PLANT2) && game.prop[PLANT2] != 0) {
|
||||||
command.obj = PLANT2;
|
command->obj = PLANT2;
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
} else if (command.obj == KNIFE && game.knfloc == game.loc) {
|
} else if (command->obj == KNIFE && game.knfloc == game.loc) {
|
||||||
game.knfloc = -1;
|
game.knfloc = -1;
|
||||||
spk = KNIVES_VANISH;
|
spk = KNIVES_VANISH;
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
} else if (command.obj == ROD && HERE(ROD2)) {
|
} else if (command->obj == ROD && HERE(ROD2)) {
|
||||||
command.obj = ROD2;
|
command->obj = ROD2;
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
} else if ((command.verb == FIND || command.verb == INVENT) && WD2 <= 0)
|
} else if ((command->verb == FIND || command->verb == INVENT) && command->wd2 <= 0)
|
||||||
/* FALL THROUGH */;
|
/* FALL THROUGH */;
|
||||||
else {
|
else {
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, command->wd1, command->wd1x);
|
||||||
RSPEAK(NO_SEE);
|
RSPEAK(NO_SEE);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WD2 > 0)
|
if (command->wd2 > 0)
|
||||||
return GO_WORD2;
|
return GO_WORD2;
|
||||||
if (command.verb != 0)
|
if (command->verb != 0)
|
||||||
command.part = transitive;
|
command->part = transitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (command.part) {
|
switch (command->part) {
|
||||||
case intransitive:
|
case intransitive:
|
||||||
if (WD2 > 0 && command.verb != SAY)
|
if (command->wd2 > 0 && command->verb != SAY)
|
||||||
return GO_WORD2;
|
return GO_WORD2;
|
||||||
if (command.verb == SAY)command.obj = WD2;
|
if (command->verb == SAY)command->obj = command->wd2;
|
||||||
if (command.obj == 0 || command.obj == INTRANSITIVE) {
|
if (command->obj == 0 || command->obj == INTRANSITIVE) {
|
||||||
/* Analyse an intransitive verb (ie, no object given yet). */
|
/* Analyse an intransitive verb (ie, no object given yet). */
|
||||||
switch (command.verb - 1) {
|
switch (command->verb - 1) {
|
||||||
case 0: /* CARRY */
|
case 0: /* CARRY */
|
||||||
return carry(command.verb, INTRANSITIVE);
|
return carry(command->verb, INTRANSITIVE);
|
||||||
case 1: /* DROP */
|
case 1: /* DROP */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 2: /* SAY */
|
case 2: /* SAY */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 3: /* UNLOC */
|
case 3: /* UNLOC */
|
||||||
return lock(command.verb, INTRANSITIVE);
|
return lock(command->verb, INTRANSITIVE);
|
||||||
case 4: { /* NOTHI */
|
case 4: { /* NOTHI */
|
||||||
RSPEAK(OK_MAN);
|
RSPEAK(OK_MAN);
|
||||||
return (GO_CLEAROBJ);
|
return (GO_CLEAROBJ);
|
||||||
}
|
}
|
||||||
case 5: /* LOCK */
|
case 5: /* LOCK */
|
||||||
return lock(command.verb, INTRANSITIVE);
|
return lock(command->verb, INTRANSITIVE);
|
||||||
case 6: /* LIGHT */
|
case 6: /* LIGHT */
|
||||||
return light(command.verb, INTRANSITIVE);
|
return light(command->verb, INTRANSITIVE);
|
||||||
case 7: /* EXTIN */
|
case 7: /* EXTIN */
|
||||||
return extinguish(command.verb, INTRANSITIVE);
|
return extinguish(command->verb, INTRANSITIVE);
|
||||||
case 8: /* WAVE */
|
case 8: /* WAVE */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 9: /* CALM */
|
case 9: /* CALM */
|
||||||
|
@ -1087,13 +1087,13 @@ int action(FILE *input, struct command_t command)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
case 11: /* ATTAC */
|
case 11: /* ATTAC */
|
||||||
return attack(input, command.verb, command.obj);
|
return attack(input, command);
|
||||||
case 12: /* POUR */
|
case 12: /* POUR */
|
||||||
return pour(command.verb, command.obj);
|
return pour(command->verb, command->obj);
|
||||||
case 13: /* EAT */
|
case 13: /* EAT */
|
||||||
return eat(command.verb, INTRANSITIVE);
|
return eat(command->verb, INTRANSITIVE);
|
||||||
case 14: /* DRINK */
|
case 14: /* DRINK */
|
||||||
return drink(command.verb, command.obj);
|
return drink(command->verb, command->obj);
|
||||||
case 15: /* RUB */
|
case 15: /* RUB */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 16: /* TOSS */
|
case 16: /* TOSS */
|
||||||
|
@ -1107,7 +1107,7 @@ int action(FILE *input, struct command_t command)
|
||||||
case 20: /* FEED */
|
case 20: /* FEED */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 21: /* FILL */
|
case 21: /* FILL */
|
||||||
return fill(command.verb, command.obj);
|
return fill(command->verb, command->obj);
|
||||||
case 22: /* BLAST */
|
case 22: /* BLAST */
|
||||||
blast();
|
blast();
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
|
@ -1115,11 +1115,12 @@ int action(FILE *input, struct command_t command)
|
||||||
score(scoregame);
|
score(scoregame);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
case 24: /* FOO */
|
case 24: /* FOO */
|
||||||
return bigwords(WD1);
|
return bigwords(command->wd1);
|
||||||
case 25: /* BRIEF */
|
case 25: /* BRIEF */
|
||||||
return brief();
|
return brief();
|
||||||
case 26: /* READ */
|
case 26: /* READ */
|
||||||
return read(command.verb, INTRANSITIVE);
|
command->obj = INTRANSITIVE;
|
||||||
|
return read(command);
|
||||||
case 27: /* BREAK */
|
case 27: /* BREAK */
|
||||||
return GO_UNKNOWN;
|
return GO_UNKNOWN;
|
||||||
case 28: /* WAKE */
|
case 28: /* WAKE */
|
||||||
|
@ -1129,7 +1130,7 @@ int action(FILE *input, struct command_t command)
|
||||||
case 30: /* RESU */
|
case 30: /* RESU */
|
||||||
return resume();
|
return resume();
|
||||||
case 31: /* FLY */
|
case 31: /* FLY */
|
||||||
return fly(command.verb, INTRANSITIVE);
|
return fly(command->verb, INTRANSITIVE);
|
||||||
case 32: /* LISTE */
|
case 32: /* LISTE */
|
||||||
return listen();
|
return listen();
|
||||||
case 33: /* ZZZZ */
|
case 33: /* ZZZZ */
|
||||||
|
@ -1140,27 +1141,27 @@ int action(FILE *input, struct command_t command)
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case transitive:
|
case transitive:
|
||||||
/* Analyse a transitive verb. */
|
/* Analyse a transitive verb. */
|
||||||
switch (command.verb - 1) {
|
switch (command->verb - 1) {
|
||||||
case 0: /* CARRY */
|
case 0: /* CARRY */
|
||||||
return carry(command.verb, command.obj);
|
return carry(command->verb, command->obj);
|
||||||
case 1: /* DROP */
|
case 1: /* DROP */
|
||||||
return discard(command.verb, command.obj, false);
|
return discard(command->verb, command->obj, false);
|
||||||
case 2: /* SAY */
|
case 2: /* SAY */
|
||||||
return say();
|
return say(command);
|
||||||
case 3: /* UNLOC */
|
case 3: /* UNLOC */
|
||||||
return lock(command.verb, command.obj);
|
return lock(command->verb, command->obj);
|
||||||
case 4: { /* NOTHI */
|
case 4: { /* NOTHI */
|
||||||
RSPEAK(OK_MAN);
|
RSPEAK(OK_MAN);
|
||||||
return (GO_CLEAROBJ);
|
return (GO_CLEAROBJ);
|
||||||
}
|
}
|
||||||
case 5: /* LOCK */
|
case 5: /* LOCK */
|
||||||
return lock(command.verb, command.obj);
|
return lock(command->verb, command->obj);
|
||||||
case 6: /* LIGHT */
|
case 6: /* LIGHT */
|
||||||
return light(command.verb, command.obj);
|
return light(command->verb, command->obj);
|
||||||
case 7: /* EXTI */
|
case 7: /* EXTI */
|
||||||
return extinguish(command.verb, command.obj);
|
return extinguish(command->verb, command->obj);
|
||||||
case 8: /* WAVE */
|
case 8: /* WAVE */
|
||||||
return wave(command.verb, command.obj);
|
return wave(command->verb, command->obj);
|
||||||
case 9: { /* CALM */
|
case 9: { /* CALM */
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
|
@ -1170,29 +1171,29 @@ int action(FILE *input, struct command_t command)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
case 11: /* ATTAC */
|
case 11: /* ATTAC */
|
||||||
return attack(input, command.verb, command.obj);
|
return attack(input, command);
|
||||||
case 12: /* POUR */
|
case 12: /* POUR */
|
||||||
return pour(command.verb, command.obj);
|
return pour(command->verb, command->obj);
|
||||||
case 13: /* EAT */
|
case 13: /* EAT */
|
||||||
return eat(command.verb, command.obj);
|
return eat(command->verb, command->obj);
|
||||||
case 14: /* DRINK */
|
case 14: /* DRINK */
|
||||||
return drink(command.verb, command.obj);
|
return drink(command->verb, command->obj);
|
||||||
case 15: /* RUB */
|
case 15: /* RUB */
|
||||||
return rub(command.verb, command.obj);
|
return rub(command->verb, command->obj);
|
||||||
case 16: /* TOSS */
|
case 16: /* TOSS */
|
||||||
return throw (input, command.verb, command.obj);
|
return throw(input, command);
|
||||||
case 17: { /* QUIT */
|
case 17: { /* QUIT */
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
case 18: /* FIND */
|
case 18: /* FIND */
|
||||||
return find(command.verb, command.obj);
|
return find(command->verb, command->obj);
|
||||||
case 19: /* INVEN */
|
case 19: /* INVEN */
|
||||||
return find(command.verb, command.obj);
|
return find(command->verb, command->obj);
|
||||||
case 20: /* FEED */
|
case 20: /* FEED */
|
||||||
return feed(command.verb, command.obj);
|
return feed(command->verb, command->obj);
|
||||||
case 21: /* FILL */
|
case 21: /* FILL */
|
||||||
return fill(command.verb, command.obj);
|
return fill(command->verb, command->obj);
|
||||||
case 22: /* BLAST */
|
case 22: /* BLAST */
|
||||||
blast();
|
blast();
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
|
@ -1209,11 +1210,11 @@ int action(FILE *input, struct command_t command)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
case 26: /* READ */
|
case 26: /* READ */
|
||||||
return read(command.verb, command.obj);
|
return read(command);
|
||||||
case 27: /* BREAK */
|
case 27: /* BREAK */
|
||||||
return vbreak(command.verb, command.obj);
|
return vbreak(command->verb, command->obj);
|
||||||
case 28: /* WAKE */
|
case 28: /* WAKE */
|
||||||
return wake(command.verb, command.obj);
|
return wake(command->verb, command->obj);
|
||||||
case 29: { /* SUSP */
|
case 29: { /* SUSP */
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
|
@ -1223,7 +1224,7 @@ int action(FILE *input, struct command_t command)
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
}
|
}
|
||||||
case 31: /* FLY */
|
case 31: /* FLY */
|
||||||
return fly(command.verb, command.obj);
|
return fly(command->verb, command->obj);
|
||||||
case 32: { /* LISTE */
|
case 32: { /* LISTE */
|
||||||
RSPEAK(spk);
|
RSPEAK(spk);
|
||||||
return GO_CLEAROBJ;
|
return GO_CLEAROBJ;
|
||||||
|
@ -1234,7 +1235,7 @@ int action(FILE *input, struct command_t command)
|
||||||
BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST);
|
BUG(TRANSITIVE_ACTION_VERB_EXCEEDS_GOTO_LIST);
|
||||||
case unknown:
|
case unknown:
|
||||||
/* Unknown verb, couldn't deduce object - might need hint */
|
/* Unknown verb, couldn't deduce object - might need hint */
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, command->wd1, command->wd1x);
|
||||||
RSPEAK(WHAT_DO);
|
RSPEAK(WHAT_DO);
|
||||||
return GO_CHECKHINT;
|
return GO_CHECKHINT;
|
||||||
default:
|
default:
|
||||||
|
|
4
advent.h
4
advent.h
|
@ -185,10 +185,12 @@ struct command_t {
|
||||||
enum speechpart part;
|
enum speechpart part;
|
||||||
vocab_t verb;
|
vocab_t verb;
|
||||||
vocab_t obj;
|
vocab_t obj;
|
||||||
|
token_t wd1, wd1x;
|
||||||
|
token_t wd2, wd2x;
|
||||||
};
|
};
|
||||||
|
|
||||||
void initialise(void);
|
void initialise(void);
|
||||||
int action(FILE *input, struct command_t command);
|
int action(FILE *input, struct command_t *command);
|
||||||
|
|
||||||
/* Phase codes for action returns.
|
/* Phase codes for action returns.
|
||||||
* These were at one time FORTRAN line numbers.
|
* These were at one time FORTRAN line numbers.
|
||||||
|
|
39
main.c
39
main.c
|
@ -41,7 +41,6 @@ long AMBER, AXE, BACK, BATTERY, BEAR, BIRD, BLOOD,
|
||||||
RUBY, RUG, SAPPH, SAY, SIGN, SNAKE,
|
RUBY, RUG, SAPPH, SAY, SIGN, SNAKE,
|
||||||
STEPS, STREAM, THROW, TRIDENT, TROLL, TROLL2,
|
STEPS, STREAM, THROW, TRIDENT, TROLL, TROLL2,
|
||||||
URN, VASE, VEND, VOLCANO, WATER;
|
URN, VASE, VEND, VOLCANO, WATER;
|
||||||
token_t WD1, WD1X, WD2, WD2X;
|
|
||||||
|
|
||||||
FILE *logfp = NULL, *rfp = NULL;
|
FILE *logfp = NULL, *rfp = NULL;
|
||||||
bool oldstyle = false;
|
bool oldstyle = false;
|
||||||
|
@ -1015,7 +1014,7 @@ L2600:
|
||||||
game.knfloc = 0;
|
game.knfloc = 0;
|
||||||
|
|
||||||
/* This is where we get a new command from the user */
|
/* This is where we get a new command from the user */
|
||||||
if (!GETIN(cmdin, &WD1, &WD1X, &WD2, &WD2X))
|
if (!GETIN(cmdin, &command.wd1, &command.wd1x, &command.wd2, &command.wd2x))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Every input, check "game.foobar" flag. If zero, nothing's
|
/* Every input, check "game.foobar" flag. If zero, nothing's
|
||||||
|
@ -1036,7 +1035,7 @@ L2607:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.verb == SAY && WD2 > 0)
|
if (command.verb == SAY && command.wd2 > 0)
|
||||||
command.verb = 0;
|
command.verb = 0;
|
||||||
if (command.verb == SAY) {
|
if (command.verb == SAY) {
|
||||||
command.part = transitive;
|
command.part = transitive;
|
||||||
|
@ -1048,8 +1047,8 @@ L2607:
|
||||||
} else
|
} else
|
||||||
lampcheck();
|
lampcheck();
|
||||||
|
|
||||||
V1 = VOCAB(WD1, -1);
|
V1 = VOCAB(command.wd1, -1);
|
||||||
V2 = VOCAB(WD2, -1);
|
V2 = VOCAB(command.wd2, -1);
|
||||||
if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) {
|
if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) {
|
||||||
if (LIQLOC(game.loc) == WATER) {
|
if (LIQLOC(game.loc) == WATER) {
|
||||||
RSPEAK(FEET_WET);
|
RSPEAK(FEET_WET);
|
||||||
|
@ -1058,37 +1057,37 @@ L2607:
|
||||||
}
|
}
|
||||||
goto L2012;
|
goto L2012;
|
||||||
}
|
}
|
||||||
if (V1 == ENTER && WD2 > 0) {
|
if (V1 == ENTER && command.wd2 > 0) {
|
||||||
WD1 = WD2;
|
command.wd1 = command.wd2;
|
||||||
WD1X = WD2X;
|
command.wd1x = command.wd2x;
|
||||||
wordclear(&WD2);
|
wordclear(&command.wd2);
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: Magic numbers */
|
/* FIXME: Magic numbers */
|
||||||
if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) ||
|
if (!((V1 != 1000 + WATER && V1 != 1000 + OIL) ||
|
||||||
(V2 != 1000 + PLANT && V2 != 1000 + DOOR))) {
|
(V2 != 1000 + PLANT && V2 != 1000 + DOOR))) {
|
||||||
if (AT(V2 - 1000))
|
if (AT(V2 - 1000))
|
||||||
WD2 = MAKEWD(WORD_POUR);
|
command.wd2 = MAKEWD(WORD_POUR);
|
||||||
}
|
}
|
||||||
if (V1 == 1000 + CAGE && V2 == 1000 + BIRD && HERE(CAGE) && HERE(BIRD))
|
if (V1 == 1000 + CAGE && V2 == 1000 + BIRD && HERE(CAGE) && HERE(BIRD))
|
||||||
WD1 = MAKEWD(WORD_CATCH);
|
command.wd1 = MAKEWD(WORD_CATCH);
|
||||||
}
|
}
|
||||||
L2620:
|
L2620:
|
||||||
if (wordeq(WD1, MAKEWD(WORD_WEST))) {
|
if (wordeq(command.wd1, MAKEWD(WORD_WEST))) {
|
||||||
++game.iwest;
|
++game.iwest;
|
||||||
if (game.iwest == 10)
|
if (game.iwest == 10)
|
||||||
RSPEAK(W_IS_WEST);
|
RSPEAK(W_IS_WEST);
|
||||||
}
|
}
|
||||||
if (wordeq(WD1, MAKEWD(WORD_GO)) && !wordempty(WD2)) {
|
if (wordeq(command.wd1, MAKEWD(WORD_GO)) && !wordempty(command.wd2)) {
|
||||||
if (++igo == 10)
|
if (++igo == 10)
|
||||||
RSPEAK(GO_UNNEEDED);
|
RSPEAK(GO_UNNEEDED);
|
||||||
}
|
}
|
||||||
Lookup:
|
Lookup:
|
||||||
defn = VOCAB(WD1, -1);
|
defn = VOCAB(command.wd1, -1);
|
||||||
if (defn == -1) {
|
if (defn == -1) {
|
||||||
/* Gee, I don't understand. */
|
/* Gee, I don't understand. */
|
||||||
if (fallback_handler(rawbuf))
|
if (fallback_handler(rawbuf))
|
||||||
continue;
|
continue;
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, command.wd1, command.wd1x);
|
||||||
RSPEAK(DONT_KNOW);
|
RSPEAK(DONT_KNOW);
|
||||||
goto L2600;
|
goto L2600;
|
||||||
}
|
}
|
||||||
|
@ -1115,7 +1114,7 @@ Lookup:
|
||||||
}
|
}
|
||||||
|
|
||||||
Laction:
|
Laction:
|
||||||
switch (action(cmdin, command)) {
|
switch (action(cmdin, &command)) {
|
||||||
case GO_TERMINATE:
|
case GO_TERMINATE:
|
||||||
return true;
|
return true;
|
||||||
case GO_MOVE:
|
case GO_MOVE:
|
||||||
|
@ -1133,14 +1132,14 @@ Laction:
|
||||||
goto Lookup;
|
goto Lookup;
|
||||||
case GO_WORD2:
|
case GO_WORD2:
|
||||||
/* Get second word for analysis. */
|
/* Get second word for analysis. */
|
||||||
WD1 = WD2;
|
command.wd1 = command.wd2;
|
||||||
WD1X = WD2X;
|
command.wd1x = command.wd2x;
|
||||||
wordclear(&WD2);
|
wordclear(&command.wd2);
|
||||||
goto L2620;
|
goto L2620;
|
||||||
case GO_UNKNOWN:
|
case GO_UNKNOWN:
|
||||||
/* Random intransitive verbs come here. Clear obj just in case
|
/* Random intransitive verbs come here. Clear obj just in case
|
||||||
* (see attack()). */
|
* (see attack()). */
|
||||||
SETPRM(1, WD1, WD1X);
|
SETPRM(1, command.wd1, command.wd1x);
|
||||||
RSPEAK(DO_WHAT);
|
RSPEAK(DO_WHAT);
|
||||||
command.obj = 0;
|
command.obj = 0;
|
||||||
goto L2600;
|
goto L2600;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue