cypher.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /* $NetBSD: cypher.c,v 1.22 2003/08/07 09:37:01 agc Exp $ */
  2. /*
  3. * Copyright (c) 1983, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the University nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #include <sys/cdefs.h>
  31. #ifndef lint
  32. #if 0
  33. static char sccsid[] = "@(#)cypher.c 8.2 (Berkeley) 4/28/95";
  34. #else
  35. __RCSID("$NetBSD: cypher.c,v 1.22 2003/08/07 09:37:01 agc Exp $");
  36. #endif
  37. #endif /* not lint */
  38. #include "extern.h"
  39. int
  40. cypher()
  41. {
  42. int n;
  43. int junk;
  44. int lflag = -1;
  45. char buffer[10];
  46. char *filename, *rfilename;
  47. size_t filename_len;
  48. while (wordnumber <= wordcount) {
  49. if (wordtype[wordnumber] != VERB &&
  50. !(wordtype[wordnumber] == OBJECT && wordvalue[wordnumber] == KNIFE)) {
  51. printf("%s: How's that?\n",
  52. (wordnumber == wordcount) ? words[0] : words[wordnumber]);
  53. return (-1);
  54. }
  55. switch (wordvalue[wordnumber]) {
  56. case AUXVERB:
  57. /*
  58. * Take the following word as the verb (e.g.
  59. * "make love", "climb up").
  60. */
  61. wordnumber++;
  62. continue;
  63. case UP:
  64. if (location[position].access || wiz || tempwiz) {
  65. if (!location[position].access)
  66. puts("Zap! A gust of wind lifts you up.");
  67. if (!moveplayer(location[position].up, AHEAD))
  68. return (-1);
  69. } else {
  70. puts("There is no way up.");
  71. return (-1);
  72. }
  73. lflag = 0;
  74. break;
  75. case DOWN:
  76. if (!moveplayer(location[position].down, AHEAD))
  77. return (-1);
  78. lflag = 0;
  79. break;
  80. case LEFT:
  81. if (!moveplayer(left, LEFT))
  82. return (-1);
  83. lflag = 0;
  84. break;
  85. case RIGHT:
  86. if (!moveplayer(right, RIGHT))
  87. return (-1);
  88. lflag = 0;
  89. break;
  90. case AHEAD:
  91. if (!moveplayer(ahead, AHEAD))
  92. return (-1);
  93. lflag = 0;
  94. break;
  95. case BACK:
  96. if (!moveplayer(back, BACK))
  97. return (-1);
  98. lflag = 0;
  99. break;
  100. case SHOOT:
  101. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  102. int things;
  103. things = 0;
  104. for (n = 0; n < NUMOFOBJECTS; n++)
  105. if (testbit(location[position].objects, n) && objsht[n]) {
  106. things++;
  107. wordvalue[wordnumber + 1] = n;
  108. wordnumber = shoot();
  109. }
  110. if (!things)
  111. puts("Nothing to shoot at!");
  112. wordnumber++;
  113. wordnumber++;
  114. } else
  115. shoot();
  116. break;
  117. case TAKE:
  118. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  119. int things;
  120. things = 0;
  121. for (n = 0; n < NUMOFOBJECTS; n++)
  122. if (testbit(location[position].objects, n) && objsht[n]) {
  123. things++;
  124. wordvalue[wordnumber + 1] = n;
  125. /* Some objects (type NOUNS)
  126. * have special treatment in
  127. * take(). For these we
  128. * must set the type to NOUNS.
  129. * However for SWORD and BODY
  130. * all it does is find which
  131. * of many objects is meant,
  132. * so we need do nothing here.
  133. * BATHGOD must become
  134. * NORMGOD as well. NOUNS
  135. * with no special case
  136. * must be included here to
  137. * get the right error. DOOR
  138. * cannot occur as an object
  139. * so need not be included. */
  140. switch(n) {
  141. case BATHGOD:
  142. wordvalue[wordnumber + 1] = NORMGOD;
  143. /* FALLTHROUGH */
  144. case NORMGOD:
  145. case AMULET:
  146. case MEDALION:
  147. case TALISMAN:
  148. case MAN:
  149. case TIMER:
  150. case NATIVE:
  151. wordtype[wordnumber + 1] = NOUNS;
  152. break;
  153. default:
  154. wordtype[wordnumber + 1] = OBJECT;
  155. }
  156. wordnumber = take(location[position].objects);
  157. }
  158. wordnumber++;
  159. wordnumber++;
  160. if (!things)
  161. puts("Nothing to take!");
  162. } else
  163. take(location[position].objects);
  164. break;
  165. case DROP:
  166. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  167. int things;
  168. things = 0;
  169. for (n = 0; n < NUMOFOBJECTS; n++)
  170. if (testbit(inven, n)) {
  171. things++;
  172. wordvalue[wordnumber + 1] = n;
  173. wordnumber = drop("Dropped");
  174. }
  175. wordnumber++;
  176. wordnumber++;
  177. if (!things)
  178. puts("Nothing to drop!");
  179. } else
  180. drop("Dropped");
  181. break;
  182. case KICK:
  183. case THROW:
  184. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  185. int things, wv;
  186. things = 0;
  187. wv = wordvalue[wordnumber];
  188. for (n = 0; n < NUMOFOBJECTS; n++)
  189. if (testbit(inven, n) ||
  190. (testbit(location[position].objects, n) && objsht[n])) {
  191. things++;
  192. wordvalue[wordnumber + 1] = n;
  193. wordnumber = throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
  194. }
  195. wordnumber += 2;
  196. if (!things)
  197. printf("Nothing to %s!\n", wv == KICK ? "kick" : "throw");
  198. } else
  199. throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
  200. break;
  201. case TAKEOFF:
  202. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  203. int things;
  204. things = 0;
  205. for (n = 0; n < NUMOFOBJECTS; n++)
  206. if (testbit(wear, n)) {
  207. things++;
  208. wordvalue[wordnumber + 1] = n;
  209. wordnumber = takeoff();
  210. }
  211. wordnumber += 2;
  212. if (!things)
  213. puts("Nothing to take off!");
  214. } else
  215. takeoff();
  216. break;
  217. case DRAW:
  218. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  219. int things;
  220. things = 0;
  221. for (n = 0; n < NUMOFOBJECTS; n++)
  222. if (testbit(wear, n)) {
  223. things++;
  224. wordvalue[wordnumber + 1] = n;
  225. wordnumber = draw();
  226. }
  227. wordnumber += 2;
  228. if (!things)
  229. puts("Nothing to draw!");
  230. } else
  231. draw();
  232. break;
  233. case PUTON:
  234. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  235. int things;
  236. things = 0;
  237. for (n = 0; n < NUMOFOBJECTS; n++)
  238. if (testbit(location[position].objects, n) && objsht[n]) {
  239. things++;
  240. wordvalue[wordnumber + 1] = n;
  241. wordnumber = puton();
  242. }
  243. wordnumber += 2;
  244. if (!things)
  245. puts("Nothing to put on!");
  246. } else
  247. puton();
  248. break;
  249. case WEARIT:
  250. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  251. int things;
  252. things = 0;
  253. for (n = 0; n < NUMOFOBJECTS; n++)
  254. if (testbit(inven, n)) {
  255. things++;
  256. wordvalue[wordnumber + 1] = n;
  257. wordnumber = wearit();
  258. }
  259. wordnumber += 2;
  260. if (!things)
  261. puts("Nothing to wear!");
  262. } else
  263. wearit();
  264. break;
  265. case EAT:
  266. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  267. int things;
  268. things = 0;
  269. for (n = 0; n < NUMOFOBJECTS; n++)
  270. if (testbit(inven, n)) {
  271. things++;
  272. wordvalue[wordnumber + 1] = n;
  273. wordnumber = eat();
  274. }
  275. wordnumber += 2;
  276. if (!things)
  277. puts("Nothing to eat!");
  278. } else
  279. eat();
  280. break;
  281. case PUT:
  282. put();
  283. break;
  284. case INVEN:
  285. if (ucard(inven)) {
  286. puts("You are holding:\n");
  287. for (n = 0; n < NUMOFOBJECTS; n++)
  288. if (testbit(inven, n))
  289. printf("\t%s\n", objsht[n]);
  290. if (WEIGHT == 0)
  291. printf("\n= %d kilogram%s (can't lift any weight%s)\n",
  292. carrying,
  293. (carrying == 1 ? "." : "s."),
  294. (carrying ? " or move with what you have" : ""));
  295. else
  296. printf("\n= %d kilogram%s (%d%%)\n",
  297. carrying,
  298. (carrying == 1 ? "." : "s."),
  299. carrying * 100 / WEIGHT);
  300. if (CUMBER == 0)
  301. printf("Your arms can't pick anything up.\n");
  302. else
  303. printf("Your arms are %d%% full.\n",
  304. encumber * 100 / CUMBER);
  305. } else
  306. puts("You aren't carrying anything.");
  307. if (ucard(wear)) {
  308. puts("\nYou are wearing:\n");
  309. for (n = 0; n < NUMOFOBJECTS; n++)
  310. if (testbit(wear, n))
  311. printf("\t%s\n", objsht[n]);
  312. } else
  313. puts("\nYou are stark naked.");
  314. if (card(injuries, NUMOFINJURIES)) {
  315. puts("\nYou have suffered:\n");
  316. for (n = 0; n < NUMOFINJURIES; n++)
  317. if (injuries[n])
  318. printf("\t%s\n", ouch[n]);
  319. printf("\nYou can still carry up to %d kilogram%s\n", WEIGHT, (WEIGHT == 1 ? "." : "s."));
  320. } else
  321. puts("\nYou are in perfect health.");
  322. wordnumber++;
  323. break;
  324. case USE:
  325. lflag = use();
  326. break;
  327. case OPEN:
  328. if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
  329. int things;
  330. things = 0;
  331. for (n = 0; n < NUMOFOBJECTS; n++)
  332. if (testbit(inven, n)) {
  333. things++;
  334. wordvalue[wordnumber + 1] = n;
  335. dooropen();
  336. }
  337. wordnumber += 2;
  338. if (!things)
  339. puts("Nothing to open!");
  340. } else
  341. dooropen();
  342. break;
  343. case LOOK:
  344. if (!notes[CANTSEE] || testbit(inven, LAMPON) ||
  345. testbit(location[position].objects, LAMPON)
  346. || matchlight) {
  347. beenthere[position] = 2;
  348. writedes();
  349. printobjs();
  350. if (matchlight) {
  351. puts("\nYour match splutters out.");
  352. matchlight = 0;
  353. }
  354. } else
  355. puts("I can't see anything.");
  356. return (-1);
  357. break;
  358. case SU:
  359. if (wiz || tempwiz) {
  360. printf("\nRoom (was %d) = ", position);
  361. fgets(buffer, 10, stdin);
  362. if (*buffer != '\n')
  363. sscanf(buffer, "%d", &position);
  364. printf("Time (was %d) = ", ourtime);
  365. fgets(buffer, 10, stdin);
  366. if (*buffer != '\n')
  367. sscanf(buffer, "%d", &ourtime);
  368. printf("Fuel (was %d) = ", fuel);
  369. fgets(buffer, 10, stdin);
  370. if (*buffer != '\n')
  371. sscanf(buffer, "%d", &fuel);
  372. printf("Torps (was %d) = ", torps);
  373. fgets(buffer, 10, stdin);
  374. if (*buffer != '\n')
  375. sscanf(buffer, "%d", &torps);
  376. printf("CUMBER (was %d) = ", CUMBER);
  377. fgets(buffer, 10, stdin);
  378. if (*buffer != '\n')
  379. sscanf(buffer, "%d", &CUMBER);
  380. printf("WEIGHT (was %d) = ", WEIGHT);
  381. fgets(buffer, 10, stdin);
  382. if (*buffer != '\n')
  383. sscanf(buffer, "%d", &WEIGHT);
  384. printf("Clock (was %d) = ", ourclock);
  385. fgets(buffer, 10, stdin);
  386. if (*buffer != '\n')
  387. sscanf(buffer, "%d", &ourclock);
  388. printf("Wizard (was %d, %d) = ", wiz, tempwiz);
  389. fgets(buffer, 10, stdin);
  390. if (*buffer != '\n') {
  391. sscanf(buffer, "%d", &junk);
  392. if (!junk)
  393. tempwiz = wiz = 0;
  394. }
  395. printf("\nDONE.\n");
  396. return (0);
  397. } else
  398. puts("You aren't a wizard.");
  399. break;
  400. case SCORE:
  401. printf("\tPLEASURE\tPOWER\t\tEGO\n");
  402. printf("\t%3d\t\t%3d\t\t%3d\n\n", pleasure, power, ego);
  403. printf("This gives you the rating of %s in %d turns.\n", rate(), ourtime);
  404. printf("You have visited %d out of %d rooms this run (%d%%).\n", card(beenthere, NUMOFROOMS), NUMOFROOMS, card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS);
  405. break;
  406. case KNIFE:
  407. case KILL:
  408. murder();
  409. break;
  410. case UNDRESS:
  411. case RAVAGE:
  412. ravage();
  413. break;
  414. case SAVE:
  415. printf("\nSave file name (default %s): ",
  416. DEFAULT_SAVE_FILE);
  417. filename = fgetln(stdin, &filename_len);
  418. if (filename_len == 0
  419. || (filename_len == 1 && filename[0] == '\n'))
  420. rfilename = save_file_name(DEFAULT_SAVE_FILE,
  421. strlen(DEFAULT_SAVE_FILE));
  422. else {
  423. if (filename[filename_len - 1] == '\n')
  424. filename_len--;
  425. rfilename = save_file_name(filename,
  426. filename_len);
  427. }
  428. save(rfilename);
  429. free(rfilename);
  430. break;
  431. case VERBOSE:
  432. verbose = 1;
  433. printf("[Maximum verbosity]\n");
  434. break;
  435. case BRIEF:
  436. verbose = 0;
  437. printf("[Standard verbosity]\n");
  438. break;
  439. case FOLLOW:
  440. lflag = follow();
  441. break;
  442. case GIVE:
  443. give();
  444. break;
  445. case KISS:
  446. kiss();
  447. break;
  448. case LOVE:
  449. love();
  450. break;
  451. case RIDE:
  452. lflag = ride();
  453. break;
  454. case DRIVE:
  455. lflag = drive();
  456. break;
  457. case LIGHT:
  458. light();
  459. break;
  460. case LAUNCH:
  461. if (!launch())
  462. return (-1);
  463. else
  464. lflag = 0;
  465. break;
  466. case LANDIT:
  467. if (!land())
  468. return (-1);
  469. else
  470. lflag = 0;
  471. break;
  472. case TIME:
  473. chime();
  474. break;
  475. case SLEEP:
  476. zzz();
  477. break;
  478. case DIG:
  479. dig();
  480. break;
  481. case JUMP:
  482. lflag = jump();
  483. break;
  484. case BURY:
  485. bury();
  486. break;
  487. case SWIM:
  488. puts("Surf's up!");
  489. break;
  490. case DRINK:
  491. drink();
  492. break;
  493. case QUIT:
  494. die();
  495. default:
  496. puts("How's that?");
  497. return (-1);
  498. break;
  499. }
  500. if (wordnumber < wordcount && *words[wordnumber++] == ',')
  501. continue;
  502. else
  503. return (lflag);
  504. }
  505. return (lflag);
  506. }