PropertyValue
rdfs:label
  • Source:SLASH'EM 0.0.7E7F2/o init.c
rdfs:comment
  • Below is the full text to o_init.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/o_init.c#line123]], for example. The latest source code for vanilla NetHack is at Source code.
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • Below is the full text to o_init.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/o_init.c#line123]], for example. The latest source code for vanilla NetHack is at Source code. 1. /* SCCS Id: @(#)o_init.c 3.4 1999/12/09 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "lev.h" /* save & restore info */ 7. 8. STATIC_DCL void FDECL(setgemprobs, (d_level*)); 9. STATIC_DCL void FDECL(shuffle,(int,int,BOOLEAN_P)); 10. STATIC_DCL void NDECL(shuffle_all); 11. STATIC_DCL boolean FDECL(interesting_to_discover,(int)); 12. 13. static NEARDATA short disco[NUM_OBJECTS] = DUMMY; 14. 15. #ifdef USE_TILES 16. STATIC_DCL void NDECL(shuffle_tiles); 17. extern short glyph2tile[]; /* from tile.c */ 18. 19. /* Shuffle tile assignments to match descriptions, so a red potion isn't 20. * displayed with a blue tile and so on. 21. * 22. * Tile assignments are not saved, and shouldn't be so that a game can 23. * be resumed on an otherwise identical non-tile-using binary, so we have 24. * to reshuffle the assignments from oc_descr_idx information when a game 25. * is restored. So might as well do that the first time instead of writing 26. * another routine. 27. */ 28. STATIC_OVL void 29. shuffle_tiles() 30. { 31. int i; 32. short tmp_tilemap[NUM_OBJECTS]; 33. 34. for (i = 0; i < NUM_OBJECTS; i++) 35. tmp_tilemap[i] = 36. glyph2tile[objects[i].oc_descr_idx + GLYPH_OBJ_OFF]; 37. 38. for (i = 0; i < NUM_OBJECTS; i++) 39. glyph2tile[i + GLYPH_OBJ_OFF] = tmp_tilemap[i]; 40. } 41. #endif /* USE_TILES */ 42. 43. #ifdef PROXY_GRAPHICS 44. STATIC_DCL void NDECL(shuffle_proxy_glyphs); 45. extern short glyph2proxy[]; /* from glyphmap.c */ 46. 47. /* Shuffle proxy glyph assignments for the same reason as tiles 48. * (internal glyphs are based on object numbers, proxy glyphs 49. * are based on object descriptions). 50. */ 51. STATIC_OVL void 52. shuffle_proxy_glyphs() 53. { 54. int i; 55. short tmp_glyphmap[NUM_OBJECTS]; 56. 57. for (i = 0; i < NUM_OBJECTS; i++) 58. tmp_glyphmap[i] = 59. glyph2proxy[objects[i].oc_descr_idx + GLYPH_OBJ_OFF]; 60. 61. for (i = 0; i < NUM_OBJECTS; i++) 62. glyph2proxy[i + GLYPH_OBJ_OFF] = tmp_glyphmap[i]; 63. } 64. #endif /* USE_TILES */ 65. 66. STATIC_OVL void 67. setgemprobs(dlev) 68. d_level *dlev; 69. { 70. int j, first, lev; 71. 72. if (dlev) 73. lev = (ledger_no(dlev) > maxledgerno()) 74. ? maxledgerno() : ledger_no(dlev); 75. else 76. lev = 0; 77. first = bases[GEM_CLASS]; 78. 79. for(j = 0; j < 9-lev/3; j++) 80. objects[first+j].oc_prob = 0; 81. first += j; 82. if (first > LAST_GEM || objects[first].oc_class != GEM_CLASS || 83. OBJ_NAME(objects[first]) == (char *)0) { 84. raw_printf("Not enough gems? - first=%d j=%d LAST_GEM=%d", 85. first, j, LAST_GEM); 86. wait_synch(); 87. } 88. for (j = first; j <= LAST_GEM; j++) 89. /* KMH, balance patch -- valuable gems now sum to 171 */ 90. objects[j].oc_prob = (171+j-first)/(LAST_GEM+1-first); 91. } 92. 93. /* shuffle descriptions on objects o_low to o_high */ 94. STATIC_OVL void 95. shuffle(o_low, o_high, domaterial) 96. int o_low, o_high; 97. boolean domaterial; 98. { 99. int i, j, num_to_shuffle; 100. short sw; 101. int color; 102. 103. for (num_to_shuffle = 0, j=o_low; j <= o_high; j++) 104. if (!objects[j].oc_name_known) num_to_shuffle++; 105. if (num_to_shuffle < 2) return; 106. 107. for (j=o_low; j <= o_high; j++) { 108. if (objects[j].oc_name_known) continue; 109. do 110. i = j + rn2(o_high-j+1); 111. while (objects[i].oc_name_known); 112. sw = objects[j].oc_descr_idx; 113. objects[j].oc_descr_idx = objects[i].oc_descr_idx; 114. objects[i].oc_descr_idx = sw; 115. sw = objects[j].oc_tough; 116. objects[j].oc_tough = objects[i].oc_tough; 117. objects[i].oc_tough = sw; 118. color = objects[j].oc_color; 119. objects[j].oc_color = objects[i].oc_color; 120. objects[i].oc_color = color; 121. 122. /* shuffle material */ 123. if (domaterial) { 124. sw = objects[j].oc_material; 125. objects[j].oc_material = objects[i].oc_material; 126. objects[i].oc_material = sw; 127. } 128. } 129. } 130. 131. void 132. init_objects() 133. { 134. register int i, first, last, sum; 135. register char oclass; 136. #ifdef TEXTCOLOR 137. # define COPY_OBJ_DESCR(o_dst,o_src) \ 138. o_dst.oc_descr_idx = o_src.oc_descr_idx,\ 139. o_dst.oc_color = o_src.oc_color 140. #else 141. # define COPY_OBJ_DESCR(o_dst,o_src) o_dst.oc_descr_idx = o_src.oc_descr_idx 142. #endif 143. 144. /* bug fix to prevent "initialization error" abort on Intel Xenix. 145. * reported by mikew@semike 146. */ 147. for (i = 0; i < MAXOCLASSES; i++) 148. bases[i] = 0; 149. /* initialize object descriptions */ 150. for (i = 0; i < NUM_OBJECTS; i++) 151. objects[i].oc_name_idx = objects[i].oc_descr_idx = i; 152. /* init base; if probs given check that they add up to 1000, 153. otherwise compute probs */ 154. first = 0; 155. while( first < NUM_OBJECTS ) { 156. oclass = objects[first].oc_class; 157. last = first+1; 158. while (last < NUM_OBJECTS && objects[last].oc_class == oclass) last++; 159. bases[(int)oclass] = first; 160. 161. if (oclass == GEM_CLASS) { 162. setgemprobs((d_level *)0); 163. 164. if (rn2(2)) { /* change turquoise from green to blue? */ 165. COPY_OBJ_DESCR(objects[TURQUOISE],objects[SAPPHIRE]); 166. } 167. if (rn2(2)) { /* change aquamarine from green to blue? */ 168. COPY_OBJ_DESCR(objects[AQUAMARINE],objects[SAPPHIRE]); 169. } 170. switch (rn2(4)) { /* change fluorite from violet? */ 171. case 0: break; 172. case 1: /* blue */ 173. COPY_OBJ_DESCR(objects[FLUORITE],objects[SAPPHIRE]); 174. break; 175. case 2: /* white */ 176. COPY_OBJ_DESCR(objects[FLUORITE],objects[DIAMOND]); 177. break; 178. case 3: /* green */ 179. COPY_OBJ_DESCR(objects[FLUORITE],objects[EMERALD]); 180. break; 181. } 182. } 183. check: 184. sum = 0; 185. for(i = first; i < last; i++) sum += objects[i].oc_prob; 186. if(sum == 0) { 187. for(i = first; i < last; i++) 188. objects[i].oc_prob = (1000+i-first)/(last-first); 189. goto check; 190. } 191. if(sum != sum) 192. error("init-prob error for class %d (%d%%)", oclass, sum); 193. first = last; 194. } 195. /* shuffle descriptions */ 196. shuffle_all(); 197. #ifdef USE_TILES 198. shuffle_tiles(); 199. #endif 200. #ifdef PROXY_GRAPHICS 201. shuffle_proxy_glyphs(); 202. #endif 203. } 204. 205. STATIC_OVL void 206. shuffle_all() 207. { 208. int first, last, oclass; 209. 210. for (oclass = 1; oclass < MAXOCLASSES; oclass++) { 211. first = bases[oclass]; 212. last = first+1; 213. while (last < NUM_OBJECTS && objects[last].oc_class == oclass) 214. last++; 215. 216. if (OBJ_DESCR(objects[first]) != (char *)0 && 217. oclass != TOOL_CLASS && 218. oclass != WEAPON_CLASS && 219. oclass != ARMOR_CLASS && 220. oclass != GEM_CLASS) { 221. int j = last-1; 222. 223. if (oclass == POTION_CLASS) 224. /* water and following have fixed descriptions */ 225. j = POT_WATER - 1; 226. else if (oclass == AMULET_CLASS || 227. oclass == SCROLL_CLASS || 228. oclass == SPBOOK_CLASS) { 229. while (!objects[j].oc_magic || objects[j].oc_unique) 230. j--; 231. } 232. 233. /* non-magical amulets, scrolls, and spellbooks 234. * (ex. imitation Amulets, blank, scrolls of mail) 235. * and one-of-a-kind magical artifacts at the end of 236. * their class in objects[] have fixed descriptions. 237. */ 238. shuffle(first, j, TRUE); 239. } 240. } 241. 242. /* shuffle the helmets */ 243. shuffle(HELMET, HELM_OF_TELEPATHY, FALSE); 244. 245. /* shuffle the gloves */ 246. shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE); 247. 248. /* shuffle the robes */ 249. shuffle(ROBE, ROBE_OF_WEAKNESS, FALSE); 250. 251. /* shuffle the cloaks */ 252. shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE); 253. 254. /* shuffle the boots [if they change, update find_skates() below] */ 255. shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); 256. } 257. 258. /* find the object index for snow boots; used [once] by slippery ice code */ 259. int 260. find_skates() 261. { 262. register int i; 263. register const char *s; 264. 265. for (i = SPEED_BOOTS; i <= LEVITATION_BOOTS; i++) 266. if ((s = OBJ_DESCR(objects[i])) != 0 && !strcmp(s, "snow boots")) 267. return i; 268. 269. impossible("snow boots not found?"); 270. return -1; /* not 0, or caller would try again each move */ 271. } 272. 273. void 274. oinit() /* level dependent initialization */ 275. { 276. setgemprobs(&u.uz); 277. } 278. 279. void 280. savenames(fd, mode) 281. int fd, mode; 282. { 283. register int i; 284. unsigned int len; 285. 286. if (perform_bwrite(mode)) { 287. bwrite(fd, (genericptr_t)bases, sizeof bases); 288. bwrite(fd, (genericptr_t)disco, sizeof disco); 289. bwrite(fd, (genericptr_t)objects, 290. sizeof(struct objclass) * NUM_OBJECTS); 291. } 292. /* as long as we use only one version of Hack we 293. need not save oc_name and oc_descr, but we must save 294. oc_uname for all objects */ 295. for (i = 0; i < NUM_OBJECTS; i++) 296. if (objects[i].oc_uname) { 297. if (perform_bwrite(mode)) { 298. len = strlen(objects[i].oc_uname)+1; 299. bwrite(fd, (genericptr_t)&len, sizeof len); 300. bwrite(fd, (genericptr_t)objects[i].oc_uname, len); 301. } 302. if (release_data(mode)) { 303. free((genericptr_t)objects[i].oc_uname); 304. objects[i].oc_uname = 0; 305. } 306. } 307. } 308. 309. void 310. restnames(fd) 311. register int fd; 312. { 313. register int i; 314. unsigned int len; 315. 316. mread(fd, (genericptr_t) bases, sizeof bases); 317. mread(fd, (genericptr_t) disco, sizeof disco); 318. mread(fd, (genericptr_t) objects, sizeof(struct objclass) * NUM_OBJECTS); 319. for (i = 0; i < NUM_OBJECTS; i++) 320. if (objects[i].oc_uname) { 321. mread(fd, (genericptr_t) &len, sizeof len); 322. objects[i].oc_uname = (char *) alloc(len); 323. mread(fd, (genericptr_t)objects[i].oc_uname, len); 324. } 325. #ifdef USE_TILES 326. shuffle_tiles(); 327. #endif 328. #ifdef PROXY_GRAPHICS 329. shuffle_proxy_glyphs(); 330. #endif 331. } 332. 333. void 334. discover_object(oindx, mark_as_known, credit_hero) 335. register int oindx; 336. boolean mark_as_known; 337. boolean credit_hero; 338. { 339. /* KMH -- If we are hallucinating, we aren't sure of the object description */ 340. if (Hallucination) return; 341. 342. if (!objects[oindx].oc_name_known) { 343. register int dindx, acls = objects[oindx].oc_class; 344. 345. /* Loop thru disco[] 'til we find the target (which may have been 346. uname'd) or the next open slot; one or the other will be found 347. before we reach the next class... 348. */ 349. for (dindx = bases[acls]; disco[dindx] != 0; dindx++) 350. if (disco[dindx] == oindx) break; 351. disco[dindx] = oindx; 352. 353. if (mark_as_known) { 354. objects[oindx].oc_name_known = 1; 355. if (credit_hero) exercise(A_WIS, TRUE); 356. } 357. if (moves > 1L) update_inventory(); 358. } 359. } 360. 361. /* if a class name has been cleared, we may need to purge it from disco[] */ 362. void 363. undiscover_object(oindx) 364. register int oindx; 365. { 366. if (!objects[oindx].oc_name_known) { 367. register int dindx, acls = objects[oindx].oc_class; 368. register boolean found = FALSE; 369. 370. /* find the object; shift those behind it forward one slot */ 371. for (dindx = bases[acls]; 372. dindx < NUM_OBJECTS && disco[dindx] != 0 373. && objects[dindx].oc_class == acls; dindx++) 374. if (found) 375. disco[dindx-1] = disco[dindx]; 376. else if (disco[dindx] == oindx) 377. found = TRUE; 378. 379. /* clear last slot */ 380. if (found) disco[dindx-1] = 0; 381. else impossible("named object not in disco"); 382. update_inventory(); 383. } 384. } 385. 386. STATIC_OVL boolean 387. interesting_to_discover(i) 388. register int i; 389. { 390. /* Pre-discovered objects are now printed with a '*' */ 391. return((boolean)(objects[i].oc_uname != (char *)0 || 392. (objects[i].oc_name_known && OBJ_DESCR(objects[i]) != (char *)0))); 393. } 394. 395. /* items that should stand out once they're known */ 396. static short uniq_objs[] = { 397. AMULET_OF_YENDOR, 398. SPE_BOOK_OF_THE_DEAD, 399. CANDELABRUM_OF_INVOCATION, 400. BELL_OF_OPENING, 401. }; 402. 403. int 404. dodiscovered() /* free after Robert Viduya */ 405. { 406. register int i, dis; 407. int ct = 0; 408. char *s, oclass, prev_class, classes[MAXOCLASSES]; 409. char buf[BUFSZ]; /* WAC */ 410. winid tmpwin; 411. anything any; 412. menu_item *selected; 413. 414. tmpwin = create_nhwindow(NHW_MENU); 415. /* 416. * Use the add_menu() interface so that eg., GTK windowing port 417. * can display the relevant glyphs --ALI 418. */ 419. start_menu(tmpwin); 420. 421. any.a_void = 0; 422. add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_BOLD, "Discoveries", 423. MENU_UNSELECTED); 424. add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", 425. MENU_UNSELECTED); 426. 427. /* gather "unique objects" into a pseudo-class; note that they'll 428. also be displayed individually within their regular class */ 429. for (i = dis = 0; i < SIZE(uniq_objs); i++) 430. if (objects[uniq_objs[i]].oc_name_known) { 431. if (!dis++) 432. add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, 433. "Unique Items", MENU_UNSELECTED); 434. Sprintf(buf, " %s", OBJ_NAME(objects[uniq_objs[i]])); 435. add_menu(tmpwin, objnum_to_glyph(uniq_objs[i]), &any, 436. 0, 0, ATR_NONE, buf, MENU_UNSELECTED); 437. ++ct; 438. } 439. /* display any known artifacts as another pseudo-class */ 440. ct += disp_artifact_discoveries(tmpwin); 441. 442. /* several classes are omitted from packorder; one is of interest here */ 443. Strcpy(classes, flags.inv_order); 444. if (!index(classes, VENOM_CLASS)) { 445. s = eos(classes); 446. *s++ = VENOM_CLASS; 447. *s = '\0'; 448. } 449. 450. for (s = classes; *s; s++) { 451. oclass = *s; 452. prev_class = oclass + 1; /* forced different from oclass */ 453. for (i = bases[(int)oclass]; 454. i < NUM_OBJECTS && objects[i].oc_class == oclass; i++) { 455. if ((dis = disco[i]) && interesting_to_discover(dis)) { 456. ct++; 457. if (oclass != prev_class) { 458. add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, 459. let_to_name(oclass, FALSE), MENU_UNSELECTED); 460. prev_class = oclass; 461. } 462. Sprintf(buf, "%s %s",(objects[dis].oc_pre_discovered ? "*" : " "), 463. obj_typename(dis)); 464. add_menu(tmpwin, objnum_to_glyph(dis), &any, 0, 0, 465. ATR_NONE, buf, MENU_UNSELECTED); 466. } 467. } 468. } 469. end_menu(tmpwin, (char *) 0); 470. if (ct == 0) { 471. You("haven't discovered anything yet..."); 472. } else 473. (void) select_menu(tmpwin, PICK_NONE, &selected); 474. destroy_nhwindow(tmpwin); 475. 476. return 0; 477. } 478. 479. /*o_init.c*/