hack.u_init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /* $NetBSD: hack.u_init.c,v 1.8 2004/11/05 21:30:32 dsl Exp $ */
  2. /*
  3. * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
  4. * Amsterdam
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * - Neither the name of the Stichting Centrum voor Wiskunde en
  19. * Informatica, nor the names of its contributors may be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  24. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  27. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  30. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /*
  36. * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms, with or without
  40. * modification, are permitted provided that the following conditions
  41. * are met:
  42. * 1. Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * 2. Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in the
  46. * documentation and/or other materials provided with the distribution.
  47. * 3. The name of the author may not be used to endorse or promote products
  48. * derived from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  52. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  53. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  54. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  55. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  56. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  57. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  58. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60. */
  61. #include <sys/cdefs.h>
  62. #ifndef lint
  63. __RCSID("$NetBSD: hack.u_init.c,v 1.8 2004/11/05 21:30:32 dsl Exp $");
  64. #endif /* not lint */
  65. #include <ctype.h>
  66. #include <signal.h>
  67. #include <stdlib.h>
  68. #include "hack.h"
  69. #include "extern.h"
  70. #define Strcpy (void) strcpy
  71. #define Strcat (void) strcat
  72. #define UNDEF_TYP 0
  73. #define UNDEF_SPE '\177'
  74. struct you zerou;
  75. char pl_character[PL_CSIZ];
  76. const char *(roles[]) = { /* must all have distinct first letter */
  77. /* roles[4] may be changed to -woman */
  78. "Tourist", "Speleologist", "Fighter", "Knight",
  79. "Cave-man", "Wizard"
  80. };
  81. #define NR_OF_ROLES SIZE(roles)
  82. char rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */
  83. struct trobj {
  84. uchar trotyp;
  85. schar trspe;
  86. char trolet;
  87. Bitfield(trquan, 6);
  88. Bitfield(trknown, 1);
  89. };
  90. #ifdef WIZARD
  91. struct trobj Extra_objs[] = {
  92. {0, 0, 0, 0, 0},
  93. {0, 0, 0, 0, 0}
  94. };
  95. #endif /* WIZARD */
  96. struct trobj Cave_man[] = {
  97. {MACE, 1, WEAPON_SYM, 1, 1},
  98. {BOW, 1, WEAPON_SYM, 1, 1},
  99. {ARROW, 0, WEAPON_SYM, 25, 1}, /* quan is variable */
  100. {LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1},
  101. {0, 0, 0, 0, 0}
  102. };
  103. struct trobj Fighter[] = {
  104. {TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1},
  105. {RING_MAIL, 0, ARMOR_SYM, 1, 1},
  106. {0, 0, 0, 0, 0}
  107. };
  108. struct trobj Knight[] = {
  109. {LONG_SWORD, 0, WEAPON_SYM, 1, 1},
  110. {SPEAR, 2, WEAPON_SYM, 1, 1},
  111. {RING_MAIL, 1, ARMOR_SYM, 1, 1},
  112. {HELMET, 0, ARMOR_SYM, 1, 1},
  113. {SHIELD, 0, ARMOR_SYM, 1, 1},
  114. {PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1},
  115. {0, 0, 0, 0, 0}
  116. };
  117. struct trobj Speleologist[] = {
  118. {STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1},
  119. {UNDEF_TYP, 0, POTION_SYM, 2, 0},
  120. {FOOD_RATION, 0, FOOD_SYM, 3, 1},
  121. {PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0},
  122. {ICE_BOX, 0, TOOL_SYM, 1, 0},
  123. {0, 0, 0, 0, 0}
  124. };
  125. struct trobj Tinopener[] = {
  126. {CAN_OPENER, 0, TOOL_SYM, 1, 1},
  127. {0, 0, 0, 0, 0}
  128. };
  129. struct trobj Tourist[] = {
  130. {UNDEF_TYP, 0, FOOD_SYM, 10, 1},
  131. {POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0},
  132. {EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1},
  133. {DART, 2, WEAPON_SYM, 25, 1}, /* quan is variable */
  134. {0, 0, 0, 0, 0}
  135. };
  136. struct trobj Wizard[] = {
  137. {ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1},
  138. {UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0},
  139. {UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0},
  140. {UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0},
  141. {UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0},
  142. {0, 0, 0, 0, 0}
  143. };
  144. void
  145. u_init()
  146. {
  147. int i;
  148. char exper = 'y', pc;
  149. if (flags.female) /* should have been set in HACKOPTIONS */
  150. roles[4] = "Cave-woman";
  151. for (i = 0; i < NR_OF_ROLES; i++)
  152. rolesyms[i] = roles[i][0];
  153. rolesyms[i] = 0;
  154. if ((pc = pl_character[0]) != '\0') {
  155. if (islower((unsigned char)pc))
  156. pc = toupper((unsigned char)pc);
  157. if ((i = role_index(pc)) >= 0)
  158. goto got_suffix; /* implies experienced */
  159. printf("\nUnknown role: %c\n", pc);
  160. pl_character[0] = pc = 0;
  161. }
  162. printf("\nAre you an experienced player? [ny] ");
  163. while (!strchr("ynYN \n\004", (exper = readchar())))
  164. bell();
  165. if (exper == '\004') /* Give him an opportunity to get out */
  166. end_of_input();
  167. printf("%c\n", exper); /* echo */
  168. if (strchr("Nn \n", exper)) {
  169. exper = 0;
  170. goto beginner;
  171. }
  172. printf("\nTell me what kind of character you are:\n");
  173. printf("Are you");
  174. for (i = 0; i < NR_OF_ROLES; i++) {
  175. printf(" a %s", roles[i]);
  176. if (i == 2) /* %% */
  177. printf(",\n\t");
  178. else if (i < NR_OF_ROLES - 2)
  179. printf(",");
  180. else if (i == NR_OF_ROLES - 2)
  181. printf(" or");
  182. }
  183. printf("? [%s] ", rolesyms);
  184. while ((pc = readchar()) != '\0') {
  185. if (islower((unsigned char)pc))
  186. pc = toupper((unsigned char)pc);
  187. if ((i = role_index(pc)) >= 0) {
  188. printf("%c\n", pc); /* echo */
  189. (void) fflush(stdout); /* should be seen */
  190. break;
  191. }
  192. if (pc == '\n')
  193. break;
  194. if (pc == '\004') /* Give him the opportunity to get
  195. * out */
  196. end_of_input();
  197. bell();
  198. }
  199. if (pc == '\n')
  200. pc = 0;
  201. beginner:
  202. if (!pc) {
  203. printf("\nI'll choose a character for you.\n");
  204. i = rn2(NR_OF_ROLES);
  205. pc = rolesyms[i];
  206. printf("This game you will be a%s %s.\n",
  207. exper ? "n experienced" : "",
  208. roles[i]);
  209. getret();
  210. /* give him some feedback in case mklev takes much time */
  211. (void) putchar('\n');
  212. (void) fflush(stdout);
  213. }
  214. #if 0
  215. /*
  216. * Given the above code, I can't see why this would ever change
  217. * anything; it does core pretty well, though. - cmh 4/20/93
  218. */
  219. if (exper) {
  220. roles[i][0] = pc;
  221. }
  222. #endif
  223. got_suffix:
  224. (void) strncpy(pl_character, roles[i], PL_CSIZ - 1);
  225. pl_character[PL_CSIZ - 1] = 0;
  226. flags.beginner = 1;
  227. u = zerou;
  228. u.usym = '@';
  229. u.ulevel = 1;
  230. init_uhunger();
  231. #ifdef QUEST
  232. u.uhorizon = 6;
  233. #endif /* QUEST */
  234. uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
  235. uleft = uright = 0;
  236. switch (pc) {
  237. case 'c':
  238. case 'C':
  239. Cave_man[2].trquan = 12 + rnd(9) * rnd(9);
  240. u.uhp = u.uhpmax = 16;
  241. u.ustr = u.ustrmax = 18;
  242. ini_inv(Cave_man);
  243. break;
  244. case 't':
  245. case 'T':
  246. Tourist[3].trquan = 20 + rnd(20);
  247. u.ugold = u.ugold0 = rnd(1000);
  248. u.uhp = u.uhpmax = 10;
  249. u.ustr = u.ustrmax = 8;
  250. ini_inv(Tourist);
  251. if (!rn2(25))
  252. ini_inv(Tinopener);
  253. break;
  254. case 'w':
  255. case 'W':
  256. for (i = 1; i <= 4; i++)
  257. if (!rn2(5))
  258. Wizard[i].trquan += rn2(3) - 1;
  259. u.uhp = u.uhpmax = 15;
  260. u.ustr = u.ustrmax = 16;
  261. ini_inv(Wizard);
  262. break;
  263. case 's':
  264. case 'S':
  265. Fast = INTRINSIC;
  266. Stealth = INTRINSIC;
  267. u.uhp = u.uhpmax = 12;
  268. u.ustr = u.ustrmax = 10;
  269. ini_inv(Speleologist);
  270. if (!rn2(10))
  271. ini_inv(Tinopener);
  272. break;
  273. case 'k':
  274. case 'K':
  275. u.uhp = u.uhpmax = 12;
  276. u.ustr = u.ustrmax = 10;
  277. ini_inv(Knight);
  278. break;
  279. case 'f':
  280. case 'F':
  281. u.uhp = u.uhpmax = 14;
  282. u.ustr = u.ustrmax = 17;
  283. ini_inv(Fighter);
  284. break;
  285. default: /* impossible */
  286. u.uhp = u.uhpmax = 12;
  287. u.ustr = u.ustrmax = 16;
  288. }
  289. find_ac();
  290. if (!rn2(20)) {
  291. int d = rn2(7) - 2; /* biased variation */
  292. u.ustr += d;
  293. u.ustrmax += d;
  294. }
  295. #ifdef WIZARD
  296. if (wizard)
  297. wiz_inv();
  298. #endif /* WIZARD */
  299. /* make sure he can carry all he has - especially for T's */
  300. while (inv_weight() > 0 && u.ustr < 118)
  301. u.ustr++, u.ustrmax++;
  302. }
  303. void
  304. ini_inv(trop)
  305. struct trobj *trop;
  306. {
  307. struct obj *obj;
  308. while (trop->trolet) {
  309. obj = mkobj(trop->trolet);
  310. obj->known = trop->trknown;
  311. /* not obj->dknown = 1; - let him look at it at least once */
  312. obj->cursed = 0;
  313. if (obj->olet == WEAPON_SYM) {
  314. obj->quan = trop->trquan;
  315. trop->trquan = 1;
  316. }
  317. if (trop->trspe != UNDEF_SPE)
  318. obj->spe = trop->trspe;
  319. if (trop->trotyp != UNDEF_TYP)
  320. obj->otyp = trop->trotyp;
  321. else if (obj->otyp == WAN_WISHING) /* gitpyr!robert */
  322. obj->otyp = WAN_DEATH;
  323. obj->owt = weight(obj); /* defined after setting otyp+quan */
  324. obj = addinv(obj);
  325. if (obj->olet == ARMOR_SYM) {
  326. switch (obj->otyp) {
  327. case SHIELD:
  328. if (!uarms)
  329. setworn(obj, W_ARMS);
  330. break;
  331. case HELMET:
  332. if (!uarmh)
  333. setworn(obj, W_ARMH);
  334. break;
  335. case PAIR_OF_GLOVES:
  336. if (!uarmg)
  337. setworn(obj, W_ARMG);
  338. break;
  339. case ELVEN_CLOAK:
  340. if (!uarm2)
  341. setworn(obj, W_ARM);
  342. break;
  343. default:
  344. if (!uarm)
  345. setworn(obj, W_ARM);
  346. }
  347. }
  348. if (obj->olet == WEAPON_SYM)
  349. if (!uwep)
  350. setuwep(obj);
  351. #ifndef PYRAMID_BUG
  352. if (--trop->trquan)
  353. continue; /* make a similar object */
  354. #else
  355. if (trop->trquan) { /* check if zero first */
  356. --trop->trquan;
  357. if (trop->trquan)
  358. continue; /* make a similar object */
  359. }
  360. #endif /* PYRAMID_BUG */
  361. trop++;
  362. }
  363. }
  364. #ifdef WIZARD
  365. void
  366. wiz_inv()
  367. {
  368. struct trobj *trop = &Extra_objs[0];
  369. char *ep = getenv("INVENT");
  370. int type;
  371. while (ep && *ep) {
  372. type = atoi(ep);
  373. ep = strchr(ep, ',');
  374. if (ep)
  375. while (*ep == ',' || *ep == ' ')
  376. ep++;
  377. if (type <= 0 || type > NROFOBJECTS)
  378. continue;
  379. trop->trotyp = type;
  380. trop->trolet = objects[type].oc_olet;
  381. trop->trspe = 4;
  382. trop->trknown = 1;
  383. trop->trquan = 1;
  384. ini_inv(trop);
  385. }
  386. /* give him a wand of wishing by default */
  387. trop->trotyp = WAN_WISHING;
  388. trop->trolet = WAND_SYM;
  389. trop->trspe = 20;
  390. trop->trknown = 1;
  391. trop->trquan = 1;
  392. ini_inv(trop);
  393. }
  394. #endif /* WIZARD */
  395. void
  396. plnamesuffix()
  397. {
  398. char *p;
  399. if ((p = strrchr(plname, '-')) != NULL) {
  400. *p = 0;
  401. pl_character[0] = p[1];
  402. pl_character[1] = 0;
  403. if (!plname[0]) {
  404. askname();
  405. plnamesuffix();
  406. }
  407. }
  408. }
  409. int
  410. role_index(pc)
  411. char pc;
  412. { /* must be called only from u_init() */
  413. /* so that rolesyms[] is defined */
  414. char *cp;
  415. if ((cp = strchr(rolesyms, pc)) != NULL)
  416. return (cp - rolesyms);
  417. return (-1);
  418. }