Source:NetHack 3.0.0/mkobj.c
Revision as of 04:55, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/mkobj.c moved to Source:NetHack 3.0.0/mkobj.c: Robot: moved page)
Below is the full text to mkobj.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mkobj.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)mkobj.c 3.0 88/10/30 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. struct icp { 8. int iprob; /* probability of an item type */ 9. char ilet; /* item class */ 10. }; 11. 12. const struct icp mkobjprobs[] = { 13. {10, WEAPON_SYM}, 14. {10, ARMOR_SYM}, 15. {20, FOOD_SYM}, 16. { 8, TOOL_SYM}, 17. { 8, GEM_SYM}, 18. #ifdef SPELLS 19. {16, POTION_SYM}, 20. {16, SCROLL_SYM}, 21. { 4, SPBOOK_SYM}, 22. #else 23. {18, POTION_SYM}, 24. {18, SCROLL_SYM}, 25. #endif 26. { 4, WAND_SYM}, 27. { 3, RING_SYM}, 28. { 1, AMULET_SYM}}; 29. 30. const struct icp boxiprobs[] = { 31. {18, GEM_SYM}, 32. #ifdef SPELLS 33. {15, FOOD_SYM}, 34. {20, POTION_SYM}, 35. {20, SCROLL_SYM}, 36. {15, SPBOOK_SYM}, 37. #else 38. {20, FOOD_SYM}, 39. {25, POTION_SYM}, 40. {25, SCROLL_SYM}, 41. #endif 42. { 6, WAND_SYM}, 43. { 5, RING_SYM}, 44. { 1, AMULET_SYM}}; 45. 46. #ifdef REINCARNATION 47. const struct icp rogueprobs[] = { 48. {12, WEAPON_SYM}, 49. {12, ARMOR_SYM}, 50. {22, FOOD_SYM}, 51. {22, POTION_SYM}, 52. {22, SCROLL_SYM}, 53. { 5, WAND_SYM}, 54. { 5, RING_SYM}}; 55. #endif 56. 57. const struct icp hellprobs[] = { 58. {20, WEAPON_SYM}, 59. {20, ARMOR_SYM}, 60. {16, FOOD_SYM}, 61. {12, TOOL_SYM}, 62. {10, GEM_SYM}, 63. { 1, POTION_SYM}, 64. { 1, SCROLL_SYM}, 65. { 8, WAND_SYM}, 66. { 8, RING_SYM}, 67. { 4, AMULET_SYM}}; 68. 69. static int mksx=0, mksy=0; 70. 71. struct obj * 72. mkobj_at(let,x,y) 73. char let; 74. int x,y; 75. { 76. register struct obj *otmp; 77. 78. mksx = x; mksy = y; 79. /* We might need to know the X, Y coordinates while creating the 80. * object, i.e. to insure shop boxes are empty. 81. * Yes, this is a horrible kludge... 82. */ 83. otmp = mkobj(let,TRUE); 84. otmp->ox = x; 85. otmp->oy = y; 86. otmp->nobj = fobj; 87. fobj = otmp; 88. levl[x][y].omask = 1; 89. mksx = mksy = 0; 90. return(otmp); 91. } 92. 93. struct obj * 94. mksobj_at(otyp,x,y) 95. int otyp,x,y; 96. { 97. register struct obj *otmp; 98. 99. mksx = x; mksy = y; 100. otmp = mksobj(otyp,TRUE); 101. otmp->ox = x; 102. otmp->oy = y; 103. otmp->nobj = fobj; 104. levl[x][y].omask = 1; 105. mksx = mksy = 0; 106. return((fobj = otmp)); 107. } 108. 109. struct obj * 110. mkobj(let, artif) 111. char let; 112. boolean artif; 113. { 114. register int tprob, i, prob = rnd(1000); 115. 116. if(let == RANDOM_SYM) { 117. struct icp *iprobs = 118. #ifdef REINCARNATION 119. (dlevel == rogue_level) ? rogueprobs : 120. #endif 121. Inhell ? hellprobs : 122. mkobjprobs; 123. 124. for(tprob = rnd(100); 125. (tprob -= iprobs->iprob) > 0; 126. iprobs++); 127. let = iprobs->ilet; 128. } 129. 130. i = bases[letindex(let)]; 131. while((prob -= objects[i].oc_prob) > 0) i++; 132. 133. if(objects[i].oc_olet != let || !objects[i].oc_name) 134. panic("probtype error, let=%c i=%d", let, i); 135. 136. return(mksobj(i, artif)); 137. } 138. 139. static void 140. mkbox_cnts(box) 141. /* Note: does not check to see if it overloaded the box weight; usually 142. * possible only with corpses in ice boxes. 143. */ 144. struct obj *box; 145. { 146. register int n; 147. register struct obj *otmp; 148. 149. if(in_shop(mksx, mksy)) return; /* boxes are empty in shops */ 150. 151. switch(box->otyp) { 152. case ICE_BOX: n = 20; break; 153. case CHEST: n = 5; break; 154. case LARGE_BOX: n = 3; break; 155. case SACK: 156. case BAG_OF_HOLDING: n = 1; break; 157. default: n = 0; break; 158. } 159. 160. for(n = rn2(n+1); n > 0; n--) { 161. if (box->otyp == ICE_BOX) { 162. otmp = mksobj(CORPSE, TRUE); 163. otmp->age = moves; 164. } else { 165. register int tprob; 166. struct icp *iprobs = boxiprobs; 167. 168. for(tprob = rnd(100); 169. (tprob -= iprobs->iprob) > 0; 170. iprobs++); 171. otmp = mkobj(iprobs->ilet, TRUE); 172. } 173. if (otmp) { 174. otmp->cobj = box; 175. otmp->nobj = fcobj; 176. fcobj = otmp; 177. inc_cwt(box, otmp); 178. } 179. } 180. return; 181. } 182. 183. int 184. rndmonnum() { /* select a random, common monster type */ 185. 186. register struct permonst *ptr; 187. register int i; 188. 189. /* Plan A: get a level-appropriate common monster */ 190. ptr = rndmonst(); 191. if (ptr) return(monsndx(ptr)); 192. 193. /* Plan B: get any common monster */ 194. do { 195. ptr = &mons[(i = rn2(NUMMONS))]; 196. } while((ptr->geno & G_NOGEN) || (!Inhell && (ptr->geno & G_HELL))); 197. 198. return(i); 199. } 200. 201. const char dknowns[] = { WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM, 202. #ifdef SPELLS 203. SPBOOK_SYM, 204. #endif 205. WEAPON_SYM, 0}; 206. 207. /*ARGSUSED*/ 208. struct obj * 209. mksobj(otyp, artif) 210. int otyp; 211. boolean artif; 212. { 213. int tryct; 214. struct obj *otmp; 215. char let = objects[otyp].oc_olet; 216. 217. otmp = newobj(0); 218. *otmp = zeroobj; 219. otmp->age = moves; 220. otmp->o_id = flags.ident++; 221. otmp->quan = 1; 222. otmp->olet = let; 223. otmp->otyp = otyp; 224. otmp->dknown = index(dknowns, let) ? 0 : 1; 225. if (!uses_known(otmp)) 226. otmp->known = 1; 227. switch(let) { 228. case WEAPON_SYM: 229. otmp->quan = (otmp->otyp <= SHURIKEN) ? rn1(6,6) : 1; 230. if(!rn2(11)) { 231. otmp->spe = rne(2); 232. otmp->blessed = rn2(2); 233. } else if(!rn2(10)) { 234. curse(otmp); 235. otmp->spe = -rne(2); 236. } else blessorcurse(otmp, 10); 237. 238. #ifdef NAMED_ITEMS 239. if(artif && !rn2(20)) mkartifact(&otmp); 240. #endif 241. break; 242. case FOOD_SYM: 243. if(otmp->otyp == CORPSE) { 244. /* overridden by mkcorpse_at() */ 245. do otmp->corpsenm = rndmonnum(); 246. while (mons[otmp->corpsenm].geno & G_NOCORPSE); 247. break; 248. } else if(otmp->otyp == EGG) { 249. if(!rn2(3)) { /* "live" eggs */ 250. register struct permonst *ptr; 251. for(tryct = 0; 252. (!(ptr = rndmonst()) || 253. (!lays_eggs(ptr) && ptr != &mons[PM_KILLER_BEE])) && 254. tryct < 100; 255. tryct++); 256. if(tryct < 100) otmp->corpsenm = monsndx(ptr); 257. else otmp->corpsenm = -1; /* empty */ 258. } else otmp->corpsenm = -1; /* empty */ 259. } else if(otmp->otyp == TIN) { 260. if(!rn2(10)) { 261. otmp->spe = 1; /* spinach */ 262. otmp->corpsenm = -1; 263. } else do { 264. otmp->corpsenm = rndmonnum(); 265. } while (mons[otmp->corpsenm].geno & G_NOCORPSE); 266. blessorcurse(otmp, 10); 267. } else if (otmp->otyp == SLIME_MOLD) 268. otmp->spe = current_fruit; 269. /* fall into next case */ 270. case GEM_SYM: 271. if (otmp->otyp == LOADSTONE) curse(otmp); 272. else if (otmp->otyp == ROCK) otmp->quan = rn1(6,6); 273. else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2; 274. else otmp->quan = 1; 275. break; 276. case TOOL_SYM: 277. switch(otmp->otyp) { 278. case LAMP: otmp->spe = rnd(10); 279. blessorcurse(otmp, 5); 280. break; 281. case MAGIC_LAMP: otmp->spe = 1; 282. blessorcurse(otmp, 2); 283. break; 284. case KEY: /* key # index */ 285. case SKELETON_KEY: otmp->spe = rn2(N_LOX); 286. break; 287. case CHEST: /* lock # index */ 288. case LARGE_BOX: otmp->spe = rn2(N_LOX); 289. otmp->olocked = !!(rn2(5)); 290. otmp->otrapped = !(rn2(10)); 291. case ICE_BOX: 292. case SACK: 293. case BAG_OF_HOLDING: mkbox_cnts(otmp); 294. break; 295. case MAGIC_MARKER: otmp->spe = rn1(70,30); 296. break; 297. case CRYSTAL_BALL: otmp->spe = rnd(5); 298. blessorcurse(otmp, 2); 299. break; 300. case BAG_OF_TRICKS: otmp->spe = rnd(20); 301. break; 302. case FIGURINE: otmp->corpsenm = rndmonnum(); 303. blessorcurse(otmp, 4); 304. break; 305. #ifdef MUSIC 306. case MAGIC_FLUTE: 307. case MAGIC_HARP: 308. case FROST_HORN: 309. case FIRE_HORN: 310. case DRUM_OF_EARTHQUAKE: 311. otmp->spe = rn1(5,4); 312. break; 313. #endif /* MUSIC /**/ 314. } 315. break; 316. case AMULET_SYM: 317. if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION || 318. otmp->otyp == AMULET_OF_CHANGE || 319. otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) { 320. curse(otmp); 321. } else blessorcurse(otmp, 10); 322. case VENOM_SYM: 323. case CHAIN_SYM: 324. case BALL_SYM: 325. break; 326. case POTION_SYM: 327. case SCROLL_SYM: 328. #ifdef MAIL 329. if (otmp->otyp != SCR_MAIL) 330. #endif 331. blessorcurse(otmp, 4); 332. break; 333. #ifdef SPELLS 334. case SPBOOK_SYM: 335. blessorcurse(otmp, 17); 336. break; 337. #endif 338. case ARMOR_SYM: 339. if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS || 340. otmp->otyp == LEVITATION_BOOTS || 341. otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT || 342. otmp->otyp == GAUNTLETS_OF_FUMBLING || 343. !rn2(11))) { 344. curse(otmp); 345. otmp->spe = -rne(2); 346. } else if(!rn2(10)) { 347. otmp->spe = rne(2); 348. otmp->blessed = rn2(2); 349. } else blessorcurse(otmp, 10); 350. if(otmp->otyp == DRAGON_SCALE_MAIL) 351. otmp->corpsenm = PM_GREY_DRAGON + 352. rn2(PM_YELLOW_DRAGON-PM_GREY_DRAGON+1); 353. break; 354. case WAND_SYM: 355. #ifdef HARD 356. if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else 357. #else 358. if(otmp->otyp == WAN_WISHING) otmp->spe = 3; else 359. #endif 360. otmp->spe = rn1(5, 361. (objects[otmp->otyp].bits & NODIR) ? 11 : 4); 362. blessorcurse(otmp, 17); 363. otmp->recharged = 0; /* used to control recharging */ 364. break; 365. case RING_SYM: 366. if(objects[otmp->otyp].oc_charged) { 367. blessorcurse(otmp, 3); 368. if(rn2(10)) { 369. if(rn2(10) && bcsign(otmp)) 370. otmp->spe = bcsign(otmp) * rne(3); 371. else otmp->spe = rn2(2) ? rne(3) : -rne(3); 372. } 373. if (otmp->spe < 0 && rn2(5)) curse(otmp); 374. } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION || 375. #ifdef POLYSELF 376. otmp->otyp == RIN_POLYMORPH || 377. #endif 378. otmp->otyp == RIN_AGGRAVATE_MONSTER || 379. otmp->otyp == RIN_HUNGER || !rn2(9))) { 380. curse(otmp); 381. } 382. break; 383. case ROCK_SYM: 384. switch (otmp->otyp) { 385. case STATUE: 386. /* contains book? */ 387. otmp->spe = (rn2(dlevel/2 + 10) > 10); 388. /* overridden by mkstatue() */ 389. otmp->corpsenm = rndmonnum(); 390. otmp->owt = mons[otmp->corpsenm].cwt; 391. } 392. break; 393. default: 394. impossible("impossible mkobj %d, sym '%c'.", otmp->otyp, let); 395. return (struct obj *)0; 396. } 397. otmp->owt = weight(otmp); 398. return(otmp); 399. } 400. 401. void 402. bless(otmp) 403. register struct obj *otmp; 404. { 405. otmp->cursed = 0; 406. otmp->blessed = 1; 407. return; 408. } 409. 410. void 411. curse(otmp) 412. register struct obj *otmp; 413. { 414. otmp->blessed = 0; 415. otmp->cursed = 1; 416. return; 417. } 418. 419. void 420. blessorcurse(otmp, chance) 421. register struct obj *otmp; 422. register int chance; 423. { 424. if(otmp->blessed || otmp->cursed) return; 425. 426. if(!rn2(chance)) 427. if(!rn2(2) || Inhell) { /* in hell, don't usually bless items */ 428. curse(otmp); 429. } else { 430. bless(otmp); 431. } 432. return; 433. } 434. 435. int 436. bcsign(otmp) 437. register struct obj *otmp; 438. { 439. return(!!otmp->blessed - !!otmp->cursed); 440. } 441. 442. int 443. letter(c) { 444. return(('@' <= c && c <= 'Z') || ('a' <= c && c <= 'z')); 445. } 446. 447. int 448. weight(obj) 449. register struct obj *obj; 450. { 451. register int wt = objects[obj->otyp].oc_weight; 452. 453. if (Is_container(obj)) { 454. struct obj *contents; 455. for(contents=fcobj; contents; contents=contents->nobj) { 456. if (contents->cobj == obj) 457. inc_cwt(obj, contents); 458. } 459. return obj->owt; 460. } 461. if (obj->otyp == CORPSE && obj->corpsenm > -1) 462. return obj->quan * mons[obj->corpsenm].cwt; 463. else if (obj->otyp == STATUE && obj->corpsenm > -1) 464. return obj->quan * (mons[obj->corpsenm].cwt * 3 / 2); 465. return(wt ? wt*obj->quan : (obj->quan + 1)>>1); 466. } 467. 468. void 469. mkgold(num,x,y) 470. long num; 471. int x, y; 472. { 473. register struct gold *gold; 474. register long amount = (num ? num : 1 + (rnd(dlevel+2) * rnd(30))); 475. 476. if(levl[x][y].gmask) { 477. gold = g_at(x,y); 478. gold->amount += amount; 479. } else { 480. gold = newgold(); 481. gold->ngold = fgold; 482. gold->gx = x; 483. gold->gy = y; 484. gold->amount = amount; 485. fgold = gold; 486. levl[x][y].gmask = 1; 487. /* do sth with display? */ 488. } 489. return; 490. } 491. 492. struct obj * 493. mkcorpse_at(ptr, x, y) 494. register struct permonst *ptr; 495. int x, y; 496. { 497. register struct obj *otmp; 498. 499. otmp = mksobj_at(CORPSE, x, y); 500. if(otmp) { 501. otmp->corpsenm = monsndx(ptr); 502. otmp->owt = ptr->cwt; 503. } 504. return(otmp); 505. } 506. 507. struct obj * 508. mk_tt_corpse(x, y) 509. register int x, y; 510. { 511. register struct obj *otmp; 512. 513. if((otmp = mksobj(CORPSE,FALSE))) { 514. otmp->ox = x; 515. otmp->oy = y; 516. if(otmp = tt_oname(otmp)) { 517. otmp->nobj = fobj; 518. fobj = otmp; 519. levl[x][y].omask = 1; 520. } 521. } 522. return(otmp); 523. } 524. 525. struct obj * 526. mkstatue(ptr, x, y) 527. register struct permonst *ptr; 528. int x, y; 529. { 530. register struct obj *otmp; 531. 532. if((otmp = mksobj_at(STATUE, x, y))) { 533. 534. if(ptr) otmp->corpsenm = monsndx(ptr); 535. else otmp->corpsenm = rndmonnum(); 536. } 537. return(otmp); 538. } 539. 540. struct obj * 541. mk_named_object(objtype, ptr, x, y, nm, lth) 542. int objtype; /* CORPSE or STATUE */ 543. register struct permonst *ptr; 544. int x, y; 545. char * nm; 546. register int lth; 547. { 548. struct obj *otmp; 549. register struct obj *obj2; 550. 551. if (lth == 0) { 552. switch(objtype) { 553. case STATUE: return (mkstatue(ptr, x, y)); 554. case CORPSE: return (mkcorpse_at(ptr, x, y)); 555. default: impossible("making named type %d", objtype); 556. return mksobj_at(objtype, x, y); 557. } 558. } 559. 560. if((otmp = mksobj(objtype,FALSE))) { 561. obj2 = newobj(lth); 562. *obj2 = *otmp; 563. obj2->corpsenm = monsndx(ptr); 564. obj2->owt = ptr->cwt; 565. obj2->onamelth = lth; 566. Strcpy (ONAME(obj2), nm); 567. free( (genericptr_t)otmp); 568. obj2->ox = x; 569. obj2->oy = y; 570. obj2->nobj = fobj; 571. fobj = obj2; 572. levl[x][y].omask = 1; 573. return(obj2); 574. } else return((struct obj *)0); 575. } 576. 577. #ifdef MEDUSA 578. struct obj * 579. mk_tt_statue(x, y) 580. register int x, y; 581. { 582. register struct obj *otmp; 583. 584. if((otmp = mksobj(STATUE,FALSE))) { 585. otmp->ox = x; 586. otmp->oy = y; 587. if(otmp = tt_oname(otmp)) { 588. otmp->nobj = fobj; 589. fobj = otmp; 590. levl[x][y].omask = 1; 591. otmp->spe = 0; 592. /* player statues never contain books */ 593. } 594. } 595. return(otmp); 596. } 597. #endif 598. 599. boolean 600. is_flammable(otmp) 601. register struct obj *otmp; 602. { 603. return((objects[otmp->otyp].oc_material == WOOD || 604. objects[otmp->otyp].oc_material == 0)); 605. 606. } 607. 608. boolean 609. is_rustprone(otmp) 610. register struct obj *otmp; 611. { 612. return(objects[otmp->otyp].oc_material == METAL); 613. } 614. 615. void 616. set_omask(x, y) 617. register xchar x, y; 618. { 619. levl[x][y].gmask = (g_at(x, y) != (struct gold *)0); 620. levl[x][y].omask = (o_at(x, y) != (struct obj *)0); 621. }