Below is the full text to u_init.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/u_init.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license. |
1. /* SCCS Id: @(#)u_init.c 1.4 87/08/08 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* u_init.c - version 1.0.3 */ 4. 5. #include <stdio.h> 6. #include <signal.h> 7. #include "hack.h" 8. #ifdef GENIX 9. #define void int 10. #endif 11. 12. #define Strcpy (void) strcpy 13. #define Strcat (void) strcat 14. #define UNDEF_TYP 0 15. #define UNDEF_SPE '\177' 16. extern struct obj *addinv(); 17. extern char *eos(); 18. extern char plname[]; 19. 20. struct you zerou; 21. char pl_character[PL_CSIZ]; 22. char *(roles[]) = { /* must all have distinct first letter */ 23. /* roles[4] & [7] may be changed for females */ 24. "Archeologist", "Tourist", "Fighter", "Knight", "Cave-man", 25. #ifdef NEWCLASS 26. "Samurai", "Ninja", "Priest", 27. #endif 28. #ifdef KAA 29. "Valkyrie", "Elf", "Healer", 30. #endif 31. "Wizard" 32. }; 33. #define NR_OF_ROLES SIZE(roles) 34. char rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */ 35. 36. struct trobj { 37. uchar trotyp; 38. schar trspe; 39. char trolet; 40. Bitfield(trquan,6); 41. Bitfield(trknown,1); 42. }; 43. 44. #ifdef WIZARD 45. struct trobj Extra_objs[] = { 46. { 0, 0, 0, 0, 0 }, 47. { 0, 0, 0, 0, 0 } 48. }; 49. #endif 50. 51. struct trobj Cave_man[] = { 52. #ifdef KAA 53. { CLUB, 1, WEAPON_SYM, 1, 1 }, 54. #else 55. { MACE, 1, WEAPON_SYM, 1, 1 }, 56. #endif 57. { BOW, 1, WEAPON_SYM, 1, 1 }, 58. { ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */ 59. { LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 }, 60. { 0, 0, 0, 0, 0} 61. }; 62. 63. struct trobj Fighter[] = { 64. { TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 }, 65. { RING_MAIL, 0, ARMOR_SYM, 1, 1 }, 66. { 0, 0, 0, 0, 0 } 67. }; 68. 69. struct trobj Knight[] = { 70. { LONG_SWORD, 0, WEAPON_SYM, 1, 1 }, 71. { SPEAR, 2, WEAPON_SYM, 1, 1 }, 72. { RING_MAIL, 1, ARMOR_SYM, 1, 1 }, 73. { HELMET, 0, ARMOR_SYM, 1, 1 }, 74. { SHIELD, 0, ARMOR_SYM, 1, 1 }, 75. { PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1 }, 76. { 0, 0, 0, 0, 0 } 77. }; 78. 79. #ifdef KAA 80. struct trobj Elf[] = { 81. { SHORT_SWORD, 0, WEAPON_SYM, 1, 1 }, 82. { BOW, 0, WEAPON_SYM, 1, 1 }, 83. { ARROW, 0, WEAPON_SYM, 25, 1 }, 84. { UNDEF_TYP, 0, ARMOR_SYM, 1, 1 }, 85. { 0, 0, 0, 0, 0 } 86. }; 87. 88. struct trobj Valkyrie[] = { 89. { LONG_SWORD, 1, WEAPON_SYM, 1, 1 }, 90. { SHIELD, 3, ARMOR_SYM, 1, 1 }, 91. { FOOD_RATION, 0, FOOD_SYM, 1, 1 }, 92. { 0, 0, 0, 0, 0 } 93. }; 94. 95. struct trobj Healer[] = { 96. { STETHOSCOPE, 0, TOOL_SYM, 1, 0 }, 97. { POT_HEALING, 0, POTION_SYM, 4, 0 }, 98. { POT_EXTRA_HEALING, 0, POTION_SYM, 4, 0 }, 99. { APPLE, 0, FOOD_SYM, 5, 0 }, 100. { 0, 0, 0, 0, 0} 101. }; 102. #endif /* KAA /**/ 103. 104. struct trobj Archeologist[] = { 105. { STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 }, 106. { UNDEF_TYP, 0, POTION_SYM, 2, 0 }, 107. { FOOD_RATION, 0, FOOD_SYM, 3, 1 }, 108. { PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0 }, 109. { ICE_BOX, 0, TOOL_SYM, 1, 0 }, 110. { 0, 0, 0, 0, 0} 111. }; 112. 113. struct trobj Tinopener[] = { 114. { CAN_OPENER, 0, TOOL_SYM, 1, 1 }, 115. { 0, 0, 0, 0, 0 } 116. }; 117. 118. #ifdef MARKER 119. struct trobj Magicmarker[] = { 120. { MAGIC_MARKER, 50, TOOL_SYM, 1, 0 }, 121. { 0, 0, 0, 0, 0 } 122. }; 123. #endif 124. 125. #ifdef WALKIES 126. struct trobj Leash[] = { 127. { LEASH, 0, CHAIN_SYM, 1, 0 }, 128. { 0, 0, 0, 0, 0 } 129. }; 130. #endif 131. 132. struct trobj Tourist[] = { 133. { UNDEF_TYP, 0, FOOD_SYM, 10, 1 }, 134. { POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 }, 135. { EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 }, 136. { DART, 2, WEAPON_SYM, 25, 1 }, /* quan is variable */ 137. { 0, 0, 0, 0, 0 } 138. }; 139. 140. struct trobj Wizard[] = { 141. { ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1 }, 142. { UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 }, 143. { UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 }, 144. { UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 }, 145. { UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 }, 146. #ifdef SPELLS 147. { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 1, 0 }, 148. #endif 149. { 0, 0, 0, 0, 0 } 150. }; 151. 152. #ifdef NEWCLASS 153. struct trobj Samurai[] = { 154. { KATANA, 0, WEAPON_SYM, 1, 1 }, 155. { BOW, 1, WEAPON_SYM, 1, 1 }, 156. { ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */ 157. { SPLINT_MAIL, 0, ARMOR_SYM, 1, 1}, 158. { 0, 0, 0, 0, 0 } 159. }; 160. 161. struct trobj Ninja[] = { 162. { KATANA, 0, WEAPON_SYM, 1, 1 }, 163. { SHURIKEN, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */ 164. { LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1}, 165. { 0, 0, 0, 0, 0 } 166. }; 167. 168. struct trobj Priest[] = { 169. { CHAIN_MAIL, 0, ARMOR_SYM, 1, 1 }, 170. { SHIELD, 0, ARMOR_SYM, 1, 1 }, 171. { MACE, 1, WEAPON_SYM, 1, 1 }, 172. #ifdef SPELLS 173. { UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 0 }, 174. #endif 175. { 0, 0, 0, 0, 0 } 176. }; 177. #endif /* NEWCLASS /**/ 178. 179. u_init(){ 180. register int i; 181. char exper = 'y', pc; 182. extern char readchar(); 183. if(flags.female) { /* should have been set in HACKOPTIONS */ 184. roles[4] = "Cave-woman"; 185. #ifdef NEWCLASS 186. roles[7] = "Priestess"; 187. #endif 188. } 189. for(i = 0; i < NR_OF_ROLES; i++) 190. rolesyms[i] = roles[i][0]; 191. rolesyms[i] = 0; 192. 193. if(pc = pl_character[0]) { 194. if('a' <= pc && pc <= 'z') pc += 'A'-'a'; 195. if((i = role_index(pc)) >= 0) 196. goto got_suffix; /* implies experienced */ 197. printf("\nUnknown role: %c\n", pc); 198. pl_character[0] = pc = 0; 199. } 200. 201. printf("\nShall I pick a character for you (yes, no, or quit) ? [ynq] "); 202. 203. while(!index("yYnNqQ", (exper = readchar()))) bell(); 204. 205. printf("%c\n", exper); /* echo */ 206. 207. if (index("qQ", exper)) { 208. clearlocks(); 209. settty((char *) 0); 210. exit(0); 211. } 212. 213. if(index("Yy", exper)) { 214. exper = 0; 215. goto beginner; 216. } 217. 218. printf("\n Tell me what kind of character you are:\n"); 219. printf(" Are you"); 220. for(i = 0; i < NR_OF_ROLES; i++) { 221. printf(" %s %s", index("AEIOU",roles[i][0]) ? "an" : "a", roles[i]); 222. if((((i + 1) % 4) == 0) && (i != NR_OF_ROLES -1)) printf(",\n\t"); 223. else if(i < NR_OF_ROLES - 2) printf(","); 224. if(i == NR_OF_ROLES - 2) printf(" or"); 225. } 226. printf("? [%s or q(quit)] ", rolesyms); 227. 228. while(pc = readchar()) { 229. if (pc == 'q' || pc == 'Q') { 230. 231. clearlocks(); 232. settty((char *) 0); 233. exit(0); 234. } 235. if('a' <= pc && pc <= 'z') pc += 'A'-'a'; 236. if((i = role_index(pc)) >= 0) { 237. printf("%c\n", pc); /* echo */ 238. (void) fflush(stdout); /* should be seen */ 239. break; 240. } 241. if(pc == '\n') break; 242. bell(); 243. } 244. if(pc == '\n') pc = 0; 245. 246. beginner: 247. if(!pc) { 248. i = rn2(NR_OF_ROLES); 249. pc = rolesyms[i]; 250. printf("\nThis game you will be %s %s%s.\n", 251. (exper || index("AEIOU", roles[i][0])) ? "an" : "a", 252. exper ? "experienced " : "", roles[i]); 253. getret(); 254. /* give him some feedback in case mklev takes much time */ 255. (void) putchar('\n'); 256. (void) fflush(stdout); 257. } 258. if(exper) { 259. roles[i][0] = pc; 260. } 261. 262. got_suffix: 263. 264. (void) strncpy(pl_character, roles[i], PL_CSIZ-1); 265. pl_character[PL_CSIZ-1] = 0; 266. flags.beginner = 1; 267. u = zerou; 268. u.usym = '@'; 269. u.ulevel = 1; 270. #ifdef SPELLS 271. u.uen = u.uenmax = 1; 272. #endif 273. #ifdef PRAYERS 274. u.ublesscnt = 300; /* no prayers just yet */ 275. u.ublessed = 0; /* not worthy yet */ 276. u.ugangr = 0; /* gods not angry */ 277. #endif 278. #ifdef KAA 279. u.mh = u.mhmax = u.umonnum = u.mtimedone = 0; 280. #endif 281. init_uhunger(); 282. #ifdef QUEST 283. u.uhorizon = 6; 284. #endif 285. uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain = 286. uleft = uright = 0; 287. #ifdef SPELLS 288. for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL; 289. #endif 290. switch(pc) { 291. case 'c': 292. case 'C': 293. Cave_man[2].trquan = 12 + rnd(9)*rnd(9); 294. u.uhp = u.uhpmax = 16; 295. u.ustr = u.ustrmax = 18; 296. ini_inv(Cave_man); 297. break; 298. case 't': 299. case 'T': 300. #ifdef KAA 301. objects[POT_EXTRA_HEALING].oc_name_known=1; 302. #endif 303. Tourist[3].trquan = 20 + rnd(20); 304. u.ugold = u.ugold0 = rnd(1000); 305. u.uhp = u.uhpmax = 10; 306. u.ustr = u.ustrmax = 8; 307. ini_inv(Tourist); 308. if(!rn2(25)) ini_inv(Tinopener); 309. #ifdef MARKER 310. else if(!rn2(25)) ini_inv(Magicmarker); 311. #endif 312. #ifdef WALKIES 313. else if(!rn2(25)) ini_inv(Leash); 314. #endif 315. break; 316. case 'w': 317. case 'W': 318. for(i=1; i<=4; i++) if(!rn2(5)) 319. Wizard[i].trquan += rn2(3) - 1; 320. u.uhp = u.uhpmax = 15; 321. u.ustr = u.ustrmax = 16; 322. #ifdef SPELLS 323. u.uen = u.uenmax += rn2(4); 324. #endif 325. ini_inv(Wizard); 326. #ifdef MARKER 327. if(!rn2(5)) ini_inv(Magicmarker); 328. #endif 329. break; 330. case 'a': 331. case 'A': 332. Fast = INTRINSIC; 333. Stealth = INTRINSIC; 334. u.uhp = u.uhpmax = 12; 335. u.ustr = u.ustrmax = 10; 336. ini_inv(Archeologist); 337. if(!rn2(10)) ini_inv(Tinopener); 338. #ifdef MARKER 339. else if(!rn2(10)) ini_inv(Magicmarker); 340. #endif 341. break; 342. #ifdef KAA 343. case 'e': 344. case 'E': 345. Elf[2].trquan = 15+rnd(20); 346. Elf[3].trotyp = (rn2(2) ? ELFIN_CHAIN_MAIL : ELVEN_CLOAK); 347. Fast = INTRINSIC; 348. HSee_invisible = INTRINSIC; 349. u.uhp = u.uhpmax = 16; 350. u.ustr = u.ustrmax = 16; 351. ini_inv(Elf); 352. break; 353. case 'v': 354. case 'V': 355. Stealth = INTRINSIC; 356. HCold_resistance = INTRINSIC; 357. flags.female = TRUE; 358. u.uhp = u.uhpmax = 16; 359. u.ustr = u.ustrmax = 17; 360. ini_inv(Valkyrie); 361. break; 362. case 'h': 363. case 'H': 364. objects[POT_HEALING].oc_name_known=1; 365. objects[POT_EXTRA_HEALING].oc_name_known=1; 366. HPoison_resistance = INTRINSIC; 367. u.uhp = u.uhpmax = 16; 368. u.ustr = u.ustrmax = 15; 369. ini_inv(Healer); 370. break; 371. #endif 372. case 'k': 373. case 'K': 374. u.uhp = u.uhpmax = 12; 375. u.ustr = u.ustrmax = 10; 376. ini_inv(Knight); 377. break; 378. case 'f': 379. case 'F': 380. u.uhp = u.uhpmax = 14; 381. u.ustr = u.ustrmax = 17; 382. ini_inv(Fighter); 383. break; 384. #ifdef NEWCLASS 385. case 's': 386. case 'S': 387. Fast = INTRINSIC; 388. u.uhp = u.uhpmax = 16; 389. u.ustr = u.ustrmax = 16; 390. Samurai[2].trquan = 12 + rnd(9)*rnd(9); 391. ini_inv(Samurai); 392. break; 393. case 'n': 394. case 'N': 395. Fast = INTRINSIC; 396. Stealth = INTRINSIC; 397. u.uhp = u.uhpmax = 15; 398. u.ustr = u.ustrmax = 10; 399. Ninja[1].trquan = 12 + rnd(9)*rnd(9); 400. ini_inv(Ninja); 401. break; 402. case 'p': 403. case 'P': 404. u.uhp = u.uhpmax = 13; 405. u.ustr = u.ustrmax = 15; 406. # ifdef SPELLS 407. u.uen = u.uenmax += rn2(4); 408. # endif 409. ini_inv(Priest); 410. # ifdef KAA 411. uwep->dknown = 1; /* bless his primary weapon */ 412. # endif 413. # ifdef MARKER 414. if(!rn2(10)) ini_inv(Magicmarker); 415. # endif 416. break; 417. #endif /* NEWCLASS /**/ 418. default: /* impossible */ 419. u.uhp = u.uhpmax = 12; 420. u.ustr = u.ustrmax = 16; 421. } 422. find_ac(); 423. if(!rn2(20)) { 424. register int d = rn2(7) - 2; /* biased variation */ 425. u.ustr += d; 426. u.ustrmax += d; 427. } 428. 429. #ifdef WIZARD 430. if(wizard) wiz_inv(); 431. #endif 432. 433. /* make sure he can carry all he has - especially for T's */ 434. while(inv_weight() > 0 && u.ustr < 118) 435. u.ustr++, u.ustrmax++; 436. } 437. 438. ini_inv(trop) register struct trobj *trop; { 439. register struct obj *obj; 440. extern struct obj *mkobj(); 441. while(trop->trolet) { 442. obj = mkobj(trop->trolet); 443. obj->known = trop->trknown; 444. /* not obj->dknown = 1; - let him look at it at least once */ 445. obj->cursed = 0; 446. if(obj->olet == WEAPON_SYM){ 447. obj->quan = trop->trquan; 448. trop->trquan = 1; 449. } 450. if(trop->trspe != UNDEF_SPE) 451. obj->spe = trop->trspe; 452. if(trop->trotyp != UNDEF_TYP) 453. obj->otyp = trop->trotyp; 454. else 455. if(obj->otyp == WAN_WISHING) /* gitpyr!robert */ 456. obj->otyp = WAN_DEATH; 457. obj->owt = weight(obj); /* defined after setting otyp+quan */ 458. obj = addinv(obj); 459. if(obj->olet == ARMOR_SYM){ 460. switch(obj->otyp){ 461. case SHIELD: 462. if(!uarms) setworn(obj, W_ARMS); 463. break; 464. case HELMET: 465. if(!uarmh) setworn(obj, W_ARMH); 466. break; 467. case PAIR_OF_GLOVES: 468. if(!uarmg) setworn(obj, W_ARMG); 469. break; 470. case ELVEN_CLOAK: 471. if(!uarm2) 472. setworn(obj, W_ARM); 473. break; 474. default: 475. if(!uarm) setworn(obj, W_ARM); 476. } 477. } 478. /* below changed by GAN 01/09/87 to allow wielding of 479. * pick-axe or can-opener if there is no weapon 480. */ 481. if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE || 482. obj->otyp == CAN_OPENER) 483. if(!uwep) setuwep(obj); 484. #ifndef PYRAMID_BUG 485. if(--trop->trquan) continue; /* make a similar object */ 486. #else 487. if(trop->trquan) { /* check if zero first */ 488. --trop->trquan; 489. if(trop->trquan) 490. continue; /* make a similar object */ 491. } 492. #endif 493. trop++; 494. } 495. } 496. 497. #ifdef WIZARD 498. wiz_inv(){ 499. register struct trobj *trop = &Extra_objs[0]; 500. extern char *getenv(); 501. register char *ep = getenv("INVENT"); 502. register int type; 503. while(ep && *ep) { 504. type = atoi(ep); 505. ep = index(ep, ','); 506. if(ep) while(*ep == ',' || *ep == ' ') ep++; 507. if(type <= 0 || type > NROFOBJECTS) continue; 508. trop->trotyp = type; 509. trop->trolet = objects[type].oc_olet; 510. trop->trspe = 4; 511. trop->trknown = 1; 512. trop->trquan = 1; 513. ini_inv(trop); 514. } 515. /* give him a wand of wishing by default */ 516. trop->trotyp = WAN_WISHING; 517. trop->trolet = WAND_SYM; 518. trop->trspe = 20; 519. trop->trknown = 1; 520. trop->trquan = 1; 521. ini_inv(trop); 522. } 523. #endif /* WIZARD /**/ 524. 525. plnamesuffix() { 526. register char *p; 527. if(p = rindex(plname, '-')) { 528. *p = 0; 529. pl_character[0] = p[1]; 530. pl_character[1] = 0; 531. if(!plname[0]) { 532. askname(); 533. plnamesuffix(); 534. } 535. } 536. } 537. 538. role_index(pc) 539. char pc; 540. { /* must be called only from u_init() */ 541. /* so that rolesyms[] is defined */ 542. register char *cp; 543. 544. if(cp = index(rolesyms, pc)) 545. return(cp - rolesyms); 546. return(-1); 547. }