diff options
author | Paul Janzen <pjanzen@cvs.openbsd.org> | 2000-09-26 04:42:57 +0000 |
---|---|---|
committer | Paul Janzen <pjanzen@cvs.openbsd.org> | 2000-09-26 04:42:57 +0000 |
commit | 081be079b82a2b9dcf1d7c705032e009184290b4 (patch) | |
tree | 7ec64cfd94c4f374f423a2d1639f6ed60b6ea28a | |
parent | 1b52f89e205c620c377b41287725ba817dcd34bb (diff) |
Improve handling of multiple commands on one line. Tidy fight parser.
Handle "all" in one place (almost). Add AUXVERB category and OBJ_PERSON/
OBJ_NONOBJ flags. Most was discussed with jsm@netbsd.org, and some is from
him.
-rw-r--r-- | games/battlestar/battlestar.c | 45 | ||||
-rw-r--r-- | games/battlestar/com1.c | 25 | ||||
-rw-r--r-- | games/battlestar/com2.c | 67 | ||||
-rw-r--r-- | games/battlestar/com3.c | 7 | ||||
-rw-r--r-- | games/battlestar/com4.c | 24 | ||||
-rw-r--r-- | games/battlestar/com5.c | 21 | ||||
-rw-r--r-- | games/battlestar/com7.c | 12 | ||||
-rw-r--r-- | games/battlestar/cypher.c | 219 | ||||
-rw-r--r-- | games/battlestar/extern.h | 21 | ||||
-rw-r--r-- | games/battlestar/getcom.c | 11 | ||||
-rw-r--r-- | games/battlestar/globals.c | 29 | ||||
-rw-r--r-- | games/battlestar/parse.c | 7 | ||||
-rw-r--r-- | games/battlestar/words.c | 12 |
13 files changed, 267 insertions, 233 deletions
diff --git a/games/battlestar/battlestar.c b/games/battlestar/battlestar.c index 9f8a3247c19..b65b54a8b8d 100644 --- a/games/battlestar/battlestar.c +++ b/games/battlestar/battlestar.c @@ -1,4 +1,4 @@ -/* $OpenBSD: battlestar.c,v 1.10 2000/09/23 02:51:58 pjanzen Exp $ */ +/* $OpenBSD: battlestar.c,v 1.11 2000/09/26 04:42:54 pjanzen Exp $ */ /* $NetBSD: battlestar.c,v 1.3 1995/03/21 15:06:47 cgd Exp $ */ /* @@ -44,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)battlestar.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: battlestar.c,v 1.10 2000/09/23 02:51:58 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: battlestar.c,v 1.11 2000/09/26 04:42:54 pjanzen Exp $"; #endif #endif /* not lint */ @@ -80,35 +80,16 @@ main(argc, argv) initialize((argc > 2) ? argv[2] : DEFAULT_SAVE_FILE); else initialize(argv[1]); -start: - news(); - if (beenthere[position] <= ROOMDESC) - beenthere[position]++; - if (notes[LAUNCHED]) - crash(); /* decrements fuel & crash */ - if (matchlight) { - puts("Your match splutters out."); - matchlight = 0; - } - if (!notes[CANTSEE] || TestBit(inven, LAMPON) || - TestBit(location[position].objects, LAMPON)) { - writedes(); - printobjs(); - } else - puts("It's too dark to see anything in here!"); - whichway(location[position]); -run: - next = getcom(mainbuf, sizeof mainbuf, ">-: ", - "Please type in something."); - for (wordcount = 0; next && wordcount < NWORD - 1; wordcount++) - next = getword(next, words[wordcount], -1); - parse(); - switch (cypher()) { - case -1: - goto run; - case 0: - goto start; - default: - errx(1, "bad return from cypher(): please submit a bug report"); + + newlocation(); + for (;;) { + stop_cypher = 0; + next = getcom(mainbuf, sizeof mainbuf, ">-: ", + "Please type in something."); + for (wordcount = 0; next && wordcount < NWORD - 1; wordcount++) + next = getword(next, words[wordcount], -1); + parse(); + while (cypher()) + ; } } diff --git a/games/battlestar/com1.c b/games/battlestar/com1.c index 1262e4c55bb..de06ef36d5a 100644 --- a/games/battlestar/com1.c +++ b/games/battlestar/com1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com1.c,v 1.10 2000/09/24 21:55:22 pjanzen Exp $ */ +/* $OpenBSD: com1.c,v 1.11 2000/09/26 04:42:55 pjanzen Exp $ */ /* $NetBSD: com1.c,v 1.3 1995/03/21 15:06:51 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)com1.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: com1.c,v 1.10 2000/09/24 21:55:22 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: com1.c,v 1.11 2000/09/26 04:42:55 pjanzen Exp $"; #endif #endif /* not lint */ @@ -269,3 +269,24 @@ crash() ouch[hurt1], ouch[hurt2]); } } + +void +newlocation() +{ + news(); + if (beenthere[position] <= ROOMDESC) + beenthere[position]++; + if (notes[LAUNCHED]) + crash(); /* decrements fuel & crash */ + if (matchlight) { + puts("Your match splutters out."); + matchlight = 0; + } + if (!notes[CANTSEE] || TestBit(inven, LAMPON) || + TestBit(location[position].objects, LAMPON)) { + writedes(); + printobjs(); + } else + puts("It's too dark to see anything in here!"); + whichway(location[position]); +} diff --git a/games/battlestar/com2.c b/games/battlestar/com2.c index dc43b94008d..974157a06ed 100644 --- a/games/battlestar/com2.c +++ b/games/battlestar/com2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com2.c,v 1.11 2000/09/24 21:55:22 pjanzen Exp $ */ +/* $OpenBSD: com2.c,v 1.12 2000/09/26 04:42:55 pjanzen Exp $ */ /* $NetBSD: com2.c,v 1.3 1995/03/21 15:06:55 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)com2.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: com2.c,v 1.11 2000/09/24 21:55:22 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: com2.c,v 1.12 2000/09/26 04:42:55 pjanzen Exp $"; #endif #endif /* not lint */ @@ -64,8 +64,7 @@ wearit() default: printf("You can't wear %s%s!\n", - (IsPluralObject(value) ? "" : AorAn(value)), - objsht[value]); + A_OR_AN_OR_BLANK(value), objsht[value]); return (firstnumber); case KNIFE: @@ -94,8 +93,7 @@ wearit() encumber -= objcumber[value]; ourtime++; printf("You are now wearing %s%s.\n", - (IsPluralObject(value) ? "the " : - (AorAn(value))), objsht[value]); + A_OR_AN_OR_THE(value), objsht[value]); } else if (TestBit(wear, value)) printf("You are already wearing the %s.\n", @@ -117,17 +115,20 @@ wearit() int put() { /* synonyms = {buckle, strap, tie} */ - if (wordvalue[wordnumber + 1] == ON) { - wordvalue[++wordnumber] = PUTON; - return (cypher()); + if (inc_wordnumber(words[wordnumber], "what")) + return(-1); + if (wordvalue[wordnumber] == ON) { + wordvalue[wordnumber] = PUTON; + wordtype[wordnumber] = VERB; + return (cypher() - 1); } - if (wordvalue[wordnumber + 1] == DOWN) { - wordvalue[++wordnumber] = DROP; - return (cypher()); + if (wordvalue[wordnumber] == DOWN) { + wordvalue[wordnumber] = DROP; + wordtype[wordnumber] = VERB; + return (cypher() - 1); } puts("I don't understand what you want to put."); return (-1); - } int @@ -139,7 +140,8 @@ draw() int use() { - wordnumber++; + if (inc_wordnumber(words[wordnumber], "what")) + return(-1); if (wordvalue[wordnumber] == AMULET && TestBit(inven, AMULET) && position != FINAL) { puts("The amulet begins to glow."); @@ -150,6 +152,7 @@ use() whichway(location[position]); puts("The waves subside and it is possible to descend to the sea cave now."); ourtime++; + wordnumber++; return (-1); } } @@ -161,6 +164,7 @@ use() position = 229; ourtime++; notes[CANTSEE] = 0; + wordnumber++; return (0); } else if (position == FINAL) @@ -173,6 +177,7 @@ use() puts("You aren't holding the amulet."); else puts("There is no apparent use."); + wordnumber++; return (-1); } @@ -181,12 +186,13 @@ murder() { int n; + if (inc_wordnumber(words[wordnumber], "whom")) + return; for (n = 0; !((n == SWORD || n == KNIFE || n == TWO_HANDED || n == MACE || n == CLEAVER || n == BROAD || n == CHAIN || n == SHOVEL || n == HALBERD) && TestBit(inven, n)) && n < NUMOFOBJECTS; n++) ; if (n == NUMOFOBJECTS) { if (TestBit(inven, LASER)) { printf("Your laser should do the trick.\n"); - wordnumber++; switch(wordvalue[wordnumber]) { case NORMGOD: case TIMER: @@ -204,8 +210,7 @@ murder() puts("You can't kill that!"); else printf("You can't kill %s%s!\n", - (IsPluralObject(wordvalue[wordnumber]) ? "" : - AorAn(wordvalue[wordnumber])), + A_OR_AN_OR_BLANK(wordvalue[wordnumber]), objsht[wordvalue[wordnumber]]); break; } @@ -213,7 +218,6 @@ murder() puts("You don't have suitable weapons to kill."); } else { printf("Your %s should do the trick.\n", objsht[n]); - wordnumber++; switch (wordvalue[wordnumber]) { case NORMGOD: @@ -274,13 +278,14 @@ murder() objsht[wordvalue[wordnumber]]); } } + wordnumber++; } void ravage() { - while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount) - ; + if (inc_wordnumber(words[wordnumber], "whom")) + return; if (wordtype[wordnumber] == NOUNS && (TestBit(location[position].objects, wordvalue[wordnumber]) || (wordvalue[wordnumber] == NORMGOD && TestBit(location[position].objects, BATHGOD)))) { ourtime++; @@ -325,9 +330,12 @@ ravage() break; default: puts("You are perverted."); + wordnumber++; } - } else - puts("Who?"); + } else { + printf("%s: Who?\n", words[wordnumber]); + wordnumber++; + } } int @@ -354,3 +362,18 @@ follow() puts("There is no one to follow."); return (-1); } + +void +undress() +{ + if (inc_wordnumber(words[wordnumber], "whom")) + return; + if (wordvalue[wordnumber] == NORMGOD && + (TestBit(location[position].objects, NORMGOD)) && godready >= 2) { + wordnumber--; + love(); + } else { + wordnumber--; + ravage(); + } +} diff --git a/games/battlestar/com3.c b/games/battlestar/com3.c index a0390686826..ff2f27711c4 100644 --- a/games/battlestar/com3.c +++ b/games/battlestar/com3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com3.c,v 1.9 2000/09/24 21:55:23 pjanzen Exp $ */ +/* $OpenBSD: com3.c,v 1.10 2000/09/26 04:42:55 pjanzen Exp $ */ /* $NetBSD: com3.c,v 1.3 1995/03/21 15:07:00 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)com3.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: com3.c,v 1.9 2000/09/24 21:55:23 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: com3.c,v 1.10 2000/09/26 04:42:55 pjanzen Exp $"; #endif #endif /* not lint */ @@ -208,7 +208,7 @@ shoot() ClearBit(location[position].objects, value); ourtime++; printf("The %s explode%s\n", objsht[value], - (IsPluralObject(value) ? "." : "s.")); + (IS_PLURAL(value) ? "." : "s.")); if (value == BOMB) die(0); } else @@ -251,6 +251,7 @@ shoot() break; case NORMGOD: + case BATHGOD: if (TestBit(location[position].objects, BATHGOD)) { puts("The goddess is hit in the chest and splashes back against the rocks."); puts("Dark blood oozes from the charred blast hole. Her naked body floats in the"); diff --git a/games/battlestar/com4.c b/games/battlestar/com4.c index 5ea47299fb1..c4248c7ca27 100644 --- a/games/battlestar/com4.c +++ b/games/battlestar/com4.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com4.c,v 1.10 2000/09/23 03:02:36 pjanzen Exp $ */ +/* $OpenBSD: com4.c,v 1.11 2000/09/26 04:42:55 pjanzen Exp $ */ /* $NetBSD: com4.c,v 1.3 1995/03/21 15:07:04 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)com4.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: com4.c,v 1.10 2000/09/23 03:02:36 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: com4.c,v 1.11 2000/09/26 04:42:55 pjanzen Exp $"; #endif #endif /* not lint */ @@ -54,7 +54,9 @@ take(from) if (wordnumber < wordcount && wordvalue[wordnumber + 1] == OFF) { wordnumber++; wordvalue[wordnumber] = TAKEOFF; - return (cypher()); + wordtype[wordnumber] = VERB; + cypher(); + return (wordnumber); } else { wordnumber++; while (wordnumber <= wordcount && wordtype[wordnumber] == OBJECT) { @@ -76,16 +78,15 @@ take(from) win--; } else if (TestBit(inven, value)) printf("You're already holding %s%s.\n", - (IsPluralObject(value) ? "" : - (AorAn(value))), objsht[value]); + A_OR_AN_OR_BLANK(value), objsht[value]); else if (!TestBit(from, value)) printf("I don't see any %s around here.\n", objsht[value]); else if (!heavy) printf("The %s %s too heavy.\n", objsht[value], - (IsPluralObject(value) ? "are" : "is")); + IS_OR_ARE(value)); else printf("The %s %s too cumbersome to hold.\n", objsht[value], - (IsPluralObject(value) ? "are" : "is")); + IS_OR_ARE(value)); if (wordnumber < wordcount - 1 && wordvalue[++wordnumber] == AND) wordnumber++; else @@ -225,7 +226,7 @@ throw(name) deposit = location[position].down; break; } - wordnumber++; + wordnumber = first + 1; while (wordnumber <= wordcount) { value = wordvalue[wordnumber]; if (deposit && TestBit(location[position].objects, value)) { @@ -377,17 +378,18 @@ eat() case -2: puts("You can't eat that!"); + wordnumber++; return (firstnumber); case -1: puts("Eat what?"); + wordnumber++; return (firstnumber); default: printf("You can't eat %s%s!\n", - wordtype[wordnumber] == OBJECT && - IsPluralObject(value) ? "" : - (AorAn(value)), objsht[value]); + A_OR_AN_OR_BLANK(value), objsht[value]); + wordnumber++; return (firstnumber); case PAPAYAS: diff --git a/games/battlestar/com5.c b/games/battlestar/com5.c index 09d758e9b0c..198320a9b8d 100644 --- a/games/battlestar/com5.c +++ b/games/battlestar/com5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com5.c,v 1.8 2000/09/24 21:55:23 pjanzen Exp $ */ +/* $OpenBSD: com5.c,v 1.9 2000/09/26 04:42:55 pjanzen Exp $ */ /* $NetBSD: com5.c,v 1.3 1995/03/21 15:07:07 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)com5.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: com5.c,v 1.8 2000/09/24 21:55:23 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: com5.c,v 1.9 2000/09/26 04:42:55 pjanzen Exp $"; #endif #endif /* not lint */ @@ -47,8 +47,8 @@ static char rcsid[] = "$OpenBSD: com5.c,v 1.8 2000/09/24 21:55:23 pjanzen Exp $" void kiss() { - while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount) - ; + if (inc_wordnumber(words[wordnumber], "whom")) + return; /* The goddess must be "taken" first if bathing. */ if (wordtype[wordnumber] == NOUNS && wordvalue[wordnumber] == NORMGOD && TestBit(location[position].objects, BATHGOD)) { @@ -93,6 +93,7 @@ kiss() puts("I see nothing like that here."); } else puts("I'd prefer not to."); + wordnumber++; } void @@ -100,12 +101,13 @@ love() { int n; - while (wordtype[++wordnumber] != NOUNS && wordnumber <= wordcount) - ; + if (inc_wordnumber(words[wordnumber], "whom")) + return; if (wordtype[wordnumber] == NOUNS) { if ((TestBit(location[position].objects, BATHGOD) || TestBit(location[position].objects, NORMGOD)) && wordvalue[wordnumber] == NORMGOD) { + wordnumber++; if (loved) { printf("Loved.\n"); return; @@ -157,6 +159,7 @@ love() puts("Where's your lover?"); } else puts("It doesn't seem to work."); + wordnumber++; } int @@ -275,7 +278,11 @@ give() last1 = last2 = wordcount + 2; firstnumber = wordnumber; - while (wordtype[++wordnumber] != OBJECT && wordvalue[wordnumber] != AMULET && wordvalue[wordnumber] != MEDALION && wordvalue[wordnumber] != TALISMAN && wordnumber <= wordcount) + while (wordtype[++wordnumber] != OBJECT && + wordvalue[wordnumber] != AMULET && + wordvalue[wordnumber] != MEDALION && + wordvalue[wordnumber] != TALISMAN && + wordnumber <= wordcount) ; if (wordnumber <= wordcount) { obj = wordvalue[wordnumber]; diff --git a/games/battlestar/com7.c b/games/battlestar/com7.c index 179107fc9cc..94a0b618231 100644 --- a/games/battlestar/com7.c +++ b/games/battlestar/com7.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com7.c,v 1.8 2000/07/24 01:02:43 pjanzen Exp $ */ +/* $OpenBSD: com7.c,v 1.9 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: com7.c,v 1.3 1995/03/21 15:07:12 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)com7.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: com7.c,v 1.8 2000/07/24 01:02:43 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: com7.c,v 1.9 2000/09/26 04:42:56 pjanzen Exp $"; #endif #endif /* not lint */ @@ -55,6 +55,7 @@ fight(enemy, strength) int i; int exhaustion; + stop_cypher = 1; /* Don't parse the existing input line further */ fighton: ourtime++; snooze -= 5; @@ -66,8 +67,8 @@ fighton: } if (snooze - ourtime < 20) puts("You look tired! I hope you're able to fight."); - next = getcom(auxbuf, LINELENGTH, "<fight!>-: ", 0); - for (i = 0; next && i < 10; i++) + next = getcom(auxbuf, LINELENGTH, "<fight!>-: ", NULL); + for (i = 0; next && i < NWORD - 1; i++) next = getword(next, words[i], -1); parse(); switch (wordvalue[wordnumber]) { @@ -149,7 +150,7 @@ fighton: puts("His arm swings lifeless at his side."); break; case 2: - puts("Clutching his blood drenched shirt, he collapses stunned."); + puts("Clutching his blood-drenched shirt, he collapses, stunned."); break; } lifeline += 20; @@ -233,6 +234,7 @@ fighton: case DROP: case DRAW: + /* One call to cypher() does only the first command on the line */ cypher(); ourtime--; break; diff --git a/games/battlestar/cypher.c b/games/battlestar/cypher.c index e4addc5ebcc..38ee010e196 100644 --- a/games/battlestar/cypher.c +++ b/games/battlestar/cypher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cypher.c,v 1.11 2000/09/24 21:55:23 pjanzen Exp $ */ +/* $OpenBSD: cypher.c,v 1.12 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: cypher.c,v 1.3 1995/03/21 15:07:15 cgd Exp $ */ /* @@ -38,13 +38,18 @@ #if 0 static char sccsid[] = "@(#)cypher.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: cypher.c,v 1.11 2000/09/24 21:55:23 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: cypher.c,v 1.12 2000/09/26 04:42:56 pjanzen Exp $"; #endif #endif /* not lint */ #include "extern.h" #include "pathnames.h" +static void verb_with_all __P((unsigned int *, int, int (*)(void), const char *)); + +/* returns 0 if error or no more commands to do, + * 1 if there are more commands remaining on the current input line + */ int cypher() { @@ -56,72 +61,68 @@ cypher() size_t filename_len; while (wordnumber <= wordcount) { - if (wordtype[wordnumber] != VERB) { - printf("%s: How's that?\n", words[wordnumber]); - return (-1); + if (wordtype[wordnumber] != VERB && + !(wordtype[wordnumber] == OBJECT && + wordvalue[wordnumber] == KNIFE)) { + printf("%s: How's that?\n", + (wordnumber == wordcount) ? words[wordnumber - 1] : words[wordnumber]); + return (0); } switch (wordvalue[wordnumber]) { + case AUXVERB: + /* Take the following word as the verb */ + wordnumber++; + return(cypher()); + break; + case UP: if (location[position].access || wiz || tempwiz) { if (!location[position].access) puts("Zap! A gust of wind lifts you up."); if (!moveplayer(location[position].up, AHEAD)) - return (-1); + return (0); } else { puts("There is no way up."); - return (-1); + return (0); } lflag = 0; break; case DOWN: if (!moveplayer(location[position].down, AHEAD)) - return (-1); + return (0); lflag = 0; break; case LEFT: if (!moveplayer(left, LEFT)) - return (-1); + return (0); lflag = 0; break; case RIGHT: if (!moveplayer(right, RIGHT)) - return (-1); + return (0); lflag = 0; break; case AHEAD: if (!moveplayer(ahead, AHEAD)) - return (-1); + return (0); lflag = 0; break; case BACK: if (!moveplayer(back, BACK)) - return (-1); + return (0); lflag = 0; break; case SHOOT: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(location[position].objects, n) && objsht[n]) { - things++; - wordvalue[wordnumber + 1] = n; - wordnumber = shoot(); - } - if (!things) - puts("Nothing to shoot at!"); - wordnumber++; - wordnumber++; - } else - shoot(); + verb_with_all(location[position].objects, OBJ_PERSON, + shoot, "shoot at"); break; case TAKE: @@ -156,9 +157,8 @@ cypher() wordtype[wordnumber + 1] = OBJECT; } wordnumber = take(location[position].objects); + wordnumber += 2; } - wordnumber++; - wordnumber++; if (!things) puts("Nothing to take!"); } else @@ -205,88 +205,23 @@ cypher() break; case TAKEOFF: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(wear, n)) { - things++; - wordvalue[wordnumber + 1] = n; - wordnumber = takeoff(); - } - wordnumber += 2; - if (!things) - puts("Nothing to take off!"); - } else - takeoff(); + verb_with_all(wear, 0, takeoff, "take off"); break; case DRAW: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(wear, n)) { - things++; - wordvalue[wordnumber + 1] = n; - wordnumber = draw(); - } - wordnumber += 2; - if (!things) - puts("Nothing to draw!"); - } else - draw(); + verb_with_all(wear, 0, draw, "draw"); break; case PUTON: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(location[position].objects, n) && objsht[n]) { - things++; - wordvalue[wordnumber + 1] = n; - wordnumber = puton(); - } - wordnumber += 2; - if (!things) - puts("Nothing to put on!"); - } else - puton(); + verb_with_all(location[position].objects, 0, puton, "put on"); break; case WEARIT: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(inven, n)) { - things++; - wordvalue[wordnumber + 1] = n; - wordnumber = wearit(); - } - wordnumber += 2; - if (!things) - puts("Nothing to wear!"); - } else - wearit(); + verb_with_all(inven, 0, wearit, "wear"); break; case EAT: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(inven, n)) { - things++; - wordvalue[wordnumber + 1] = n; - wordnumber = eat(); - } - wordnumber += 2; - if (!things) - puts("Nothing to eat!"); - } else - eat(); + verb_with_all(inven, 0, eat, "eat"); break; case PUT: @@ -336,20 +271,7 @@ cypher() break; case OPEN: - if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { - int things; - things = 0; - for (n = 0; n < NUMOFOBJECTS; n++) - if (TestBit(inven, n)) { - things++; - wordvalue[wordnumber + 1] = n; - dooropen(); - } - wordnumber += 2; - if (!things) - puts("Nothing to open!"); - } else - dooropen(); + dooropen(); break; case LOOK: @@ -365,7 +287,7 @@ cypher() } } else puts("I can't see anything."); - return (-1); + return (0); /* No commands after a look */ break; case SU: @@ -406,7 +328,7 @@ cypher() tempwiz = wiz = 0; } printf("\nDONE.\n"); - return (0); + return (0); /* No commands after a SU */ } else puts("You aren't a wizard."); break; @@ -418,12 +340,15 @@ cypher() printf("You have visited %d out of %d rooms this run (%d%%).\n", card(beenthere, NUMOFROOMS), NUMOFROOMS, card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS); break; - case KNIFE: + /* case KNIFE: */ case KILL: murder(); break; case UNDRESS: + undress(); + break; + case RAVAGE: ravage(); break; @@ -486,14 +411,14 @@ cypher() case LAUNCH: if (!launch()) - return (-1); + return (0); else lflag = 0; break; case LANDIT: if (!land()) - return (-1); + return (0); else lflag = 0; break; @@ -531,14 +456,60 @@ cypher() default: puts("How's that?"); - return (-1); + return (0); break; } - if (wordnumber < wordcount && *words[wordnumber++] == ',') - continue; - else - return (lflag); + if (!lflag) + newlocation(); + if (wordnumber < wordcount && !stop_cypher && + (*words[wordnumber] == ',' || *words[wordnumber] == '.')) { + wordnumber++; + return (1); + } else + return (0); + } + return (0); +} + +int +inc_wordnumber(v, adv) + const char *v, *adv; +{ + wordnumber++; + if (wordnumber >= wordcount) { + printf("%c%s %s?\n", toupper(v[0]), v + 1, adv); + return(-1); } - return (lflag); + return(0); +} + +static void +verb_with_all(testarray, objflg, verbfunc, verbname) + unsigned int *testarray; + int objflg; + int (*verbfunc)(void); + const char *verbname; +{ + int things, n; + + things = 0; + if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) { + for (n = 0; n < NUMOFOBJECTS; n++) + if (TestBit(testarray, n) && + (objsht[n] || (objflg & objflags[n]))) { + things++; + wordvalue[wordnumber + 1] = n; + /* Assume it's a NOUN if no short description */ + if (objsht[n]) + wordtype[wordnumber + 1] = OBJECT; + else + wordtype[wordnumber + 1] = NOUNS; + wordnumber = verbfunc(); + } + wordnumber += 2; + if (!things) + printf("Nothing to %s!\n", verbname); + } else + verbfunc(); } diff --git a/games/battlestar/extern.h b/games/battlestar/extern.h index 15f982ea99d..5dd528d9f18 100644 --- a/games/battlestar/extern.h +++ b/games/battlestar/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.10 2000/09/24 21:55:24 pjanzen Exp $ */ +/* $OpenBSD: extern.h,v 1.11 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: extern.h,v 1.5 1995/04/24 12:22:18 cgd Exp $ */ /* @@ -59,9 +59,15 @@ #define TestBit(array, index) (array[index/BITS] & (1 << (index % BITS))) #define SetBit(array, index) (array[index/BITS] |= (1 << (index % BITS))) #define ClearBit(array, index) (array[index/BITS] &= ~(1 << (index % BITS))) - /* "a " vs "an " before an object */ -#define AorAn(value) (objflags[(value)] & OBJ_AN ? "an " : "a ") -#define IsPluralObject(value) (objflags[(value)] & OBJ_PLURAL) +/* + * These macros yield words to use with objects (followed but not preceded + * by spaces, or with no spaces if the expansion is the empty string). + */ +#define A_OR_AN(n) (objflags[(n)] & OBJ_AN ? "an " : "a ") +#define IS_PLURAL(n) (objflags[(n)] & OBJ_PLURAL) +#define A_OR_AN_OR_THE(n) (IS_PLURAL((n)) ? "the " : A_OR_AN((n))) +#define A_OR_AN_OR_BLANK(n) (IS_PLURAL((n)) ? "" : A_OR_AN((n))) +#define IS_OR_ARE(n) (IS_PLURAL((n)) ? "are " : "is ") /* well known rooms */ #define FINAL 275 @@ -199,6 +205,7 @@ #define OPEN 1053 #define VERBOSE 1054 #define BRIEF 1055 +#define AUXVERB 1056 /* injuries */ #define ARM 6 /* broken arm */ @@ -239,6 +246,8 @@ /* Flags for objects */ #define OBJ_PLURAL 1 #define OBJ_AN 2 +#define OBJ_PERSON 4 +#define OBJ_NONOBJ 8 /* footsteps, asteroids, etc. */ struct room { const char *name; @@ -273,6 +282,7 @@ extern char words[NWORD][WORDLEN]; extern int wordvalue[NWORD]; extern int wordtype[NWORD]; extern int wordcount, wordnumber; +extern int stop_cypher; /* continue parsing the current line? */ /* state of the game */ extern time_t ourtime; @@ -340,6 +350,7 @@ int follow __P((void)); char *getcom __P((char *, int, const char *, const char *)); char *getword __P((char *, char *, int)); int give __P((void)); +int inc_wordnumber __P((const char *, const char *)); void initialize __P((const char *)); int jump __P((void)); void kiss __P((void)); @@ -350,6 +361,7 @@ void live __P((void)); void love __P((void)); int moveplayer __P((int, int)); void murder __P((void)); +void newlocation __P((void)); void news __P((void)); void newway __P((int)); void open_score_file __P((void)); @@ -370,6 +382,7 @@ int takeoff __P((void)); int throw __P((const char *)); const char *truedirec __P((int, char)); int ucard __P((const unsigned int *)); +void undress __P((void)); int use __P((void)); int visual __P((void)); int wearit __P((void)); diff --git a/games/battlestar/getcom.c b/games/battlestar/getcom.c index 9da57cbaaf0..44297849c00 100644 --- a/games/battlestar/getcom.c +++ b/games/battlestar/getcom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getcom.c,v 1.9 2000/09/24 21:55:25 pjanzen Exp $ */ +/* $OpenBSD: getcom.c,v 1.10 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: getcom.c,v 1.3 1995/03/21 15:07:30 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)getcom.c 8.1 (Berkeley) 5/31/93"; #else -static char rcsid[] = "$OpenBSD: getcom.c,v 1.9 2000/09/24 21:55:25 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: getcom.c,v 1.10 2000/09/26 04:42:56 pjanzen Exp $"; #endif #endif /* not lint */ @@ -89,12 +89,13 @@ getword(buf1, buf2, flag) cnt = 1; while (isspace(*buf1)) buf1++; - if (*buf1 != ',') { + if (*buf1 != ',' && *buf1 != '.') { if (!*buf1) { - *buf2 = 0; + *buf2 = '\0'; return (0); } - while (cnt < WORDLEN && *buf1 && !isspace(*buf1) && *buf1 != ',') + while (cnt < WORDLEN && *buf1 && !isspace(*buf1) && + *buf1 != ',' && *buf1 != '.') if (flag < 0) { if (isupper(*buf1)) { *buf2++ = tolower(*buf1++); diff --git a/games/battlestar/globals.c b/games/battlestar/globals.c index 2d88ae6707b..72c4769efdc 100644 --- a/games/battlestar/globals.c +++ b/games/battlestar/globals.c @@ -1,4 +1,4 @@ -/* $OpenBSD: globals.c,v 1.9 2000/09/24 21:55:25 pjanzen Exp $ */ +/* $OpenBSD: globals.c,v 1.10 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: globals.c,v 1.3 1995/03/21 15:07:32 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)globals.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: globals.c,v 1.9 2000/09/24 21:55:25 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: globals.c,v 1.10 2000/09/26 04:42:56 pjanzen Exp $"; #endif #endif /* not lint */ @@ -221,14 +221,22 @@ const int objcumber[NUMOFOBJECTS] = { }; const int objflags[NUMOFOBJECTS] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, OBJ_PLURAL, 0, OBJ_PLURAL, - 0, OBJ_AN, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, OBJ_PLURAL, 0, 0, 0, - 0, 0, OBJ_AN, 0, OBJ_PLURAL, 0, 0, OBJ_PLURAL, - 0, 0, OBJ_PLURAL, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, OBJ_NONOBJ, OBJ_PERSON, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, OBJ_PLURAL, OBJ_NONOBJ, OBJ_PLURAL, + 0, OBJ_AN, 0, 0, + 0, 0, 0, OBJ_PERSON, + OBJ_PERSON, 0, 0, 0, + OBJ_PLURAL, 0, 0, 0, + 0, OBJ_NONOBJ, OBJ_AN | OBJ_PERSON, OBJ_NONOBJ, + OBJ_PLURAL, 0, OBJ_PERSON, OBJ_PLURAL, + 0, 0, OBJ_PLURAL, 0, + 0, 0, 0, OBJ_PERSON, + OBJ_PERSON, OBJ_PERSON, OBJ_PERSON, OBJ_NONOBJ, + OBJ_NONOBJ, OBJ_NONOBJ, 0, 0, + OBJ_AN, 0, OBJ_PERSON, 0, + 0, 0, 0, 0 }; int win = 1; @@ -243,6 +251,7 @@ char words[NWORD][WORDLEN]; int wordvalue[NWORD]; int wordtype[NWORD]; int wordcount, wordnumber; +int stop_cypher; /* continue parsing the current line? */ /* state of the game */ int ourtime; diff --git a/games/battlestar/parse.c b/games/battlestar/parse.c index 67272f6562e..ada345890ed 100644 --- a/games/battlestar/parse.c +++ b/games/battlestar/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.9 2000/09/24 21:55:26 pjanzen Exp $ */ +/* $OpenBSD: parse.c,v 1.10 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: parse.c,v 1.3 1995/03/21 15:07:48 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)parse.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: parse.c,v 1.9 2000/09/24 21:55:26 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: parse.c,v 1.10 2000/09/26 04:42:56 pjanzen Exp $"; #endif #endif /* not lint */ @@ -126,12 +126,13 @@ parse() for (n = 1; n < wordcount; n++) if (wordtype[n] == ADJS) { int i; - for (i = n + 1; i < wordcount; i++) { + for (i = n + 1; i <= wordcount; i++) { wordtype[i - 1] = wordtype[i]; wordvalue[i - 1] = wordvalue[i]; strlcpy(words[i - 1], words[i], WORDLEN); } wordcount--; + n--; } /* Don't let a comma mean AND if followed by a verb. */ for (n = 0; n < wordcount; n++) diff --git a/games/battlestar/words.c b/games/battlestar/words.c index 10da4fc1079..52792b43558 100644 --- a/games/battlestar/words.c +++ b/games/battlestar/words.c @@ -1,4 +1,4 @@ -/* $OpenBSD: words.c,v 1.7 2000/09/17 21:28:33 pjanzen Exp $ */ +/* $OpenBSD: words.c,v 1.8 2000/09/26 04:42:56 pjanzen Exp $ */ /* $NetBSD: words.c,v 1.3 1995/03/21 15:08:00 cgd Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)words.c 8.2 (Berkeley) 4/28/95"; #else -static char rcsid[] = "$OpenBSD: words.c,v 1.7 2000/09/17 21:28:33 pjanzen Exp $"; +static char rcsid[] = "$OpenBSD: words.c,v 1.8 2000/09/26 04:42:56 pjanzen Exp $"; #endif #endif /* not lint */ @@ -151,6 +151,7 @@ struct wlist wlist[] = { { "all", EVERYTHING, OBJECT, NULL }, { "and", AND, CONJ, NULL }, { ",", AND, CONJ, NULL }, + { ".", AND, CONJ, NULL }, { "kill", KILL, VERB, NULL }, { "fight", KILL, VERB, NULL }, { "ravage", RAVAGE, VERB, NULL }, @@ -212,9 +213,10 @@ struct wlist wlist[] = { { "purple", 0, ADJS, NULL }, { "kingly", 0, ADJS, NULL }, { "the", 0, ADJS, NULL }, - { "climb", 0, ADJS, NULL }, - { "move", 0, ADJS, NULL }, - { "make", 0, ADJS, NULL }, + { "climb", AUXVERB, VERB, NULL }, + { "move", AUXVERB, VERB, NULL }, + { "make", AUXVERB, VERB, NULL }, + { "go", AUXVERB, VERB, NULL }, { "to", 0, ADJS, NULL }, { 0, 0, 0, NULL } }; |