abstract
| - Below is the full text to mkobj.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/mkobj.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)mkobj.c 3.1 93/01/17 */ 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 "artifact.h" 7. #include "prop.h" 8. 9. STATIC_DCL void FDECL(mkbox_cnts,(struct obj *)); 10. 11. struct icp { 12. int iprob; /* probability of an item type */ 13. char ilet; /* item class */ 14. }; 15. 16. #ifdef OVL1 17. 18. const struct icp mkobjprobs[] = { 19. {10, WEAPON_CLASS}, 20. {10, ARMOR_CLASS}, 21. {20, FOOD_CLASS}, 22. { 8, TOOL_CLASS}, 23. { 8, GEM_CLASS}, 24. {16, POTION_CLASS}, 25. {16, SCROLL_CLASS}, 26. { 4, SPBOOK_CLASS}, 27. { 4, WAND_CLASS}, 28. { 3, RING_CLASS}, 29. { 1, AMULET_CLASS} 30. }; 31. 32. const struct icp boxiprobs[] = { 33. {18, GEM_CLASS}, 34. {15, FOOD_CLASS}, 35. {18, POTION_CLASS}, 36. {18, SCROLL_CLASS}, 37. {12, SPBOOK_CLASS}, 38. { 7, GOLD_CLASS}, 39. { 6, WAND_CLASS}, 40. { 5, RING_CLASS}, 41. { 1, AMULET_CLASS} 42. }; 43. 44. #ifdef REINCARNATION 45. const struct icp rogueprobs[] = { 46. {12, WEAPON_CLASS}, 47. {12, ARMOR_CLASS}, 48. {22, FOOD_CLASS}, 49. {22, POTION_CLASS}, 50. {22, SCROLL_CLASS}, 51. { 5, WAND_CLASS}, 52. { 5, RING_CLASS} 53. }; 54. #endif 55. 56. const struct icp hellprobs[] = { 57. {20, WEAPON_CLASS}, 58. {20, ARMOR_CLASS}, 59. {16, FOOD_CLASS}, 60. {12, TOOL_CLASS}, 61. {10, GEM_CLASS}, 62. { 1, POTION_CLASS}, 63. { 1, SCROLL_CLASS}, 64. { 8, WAND_CLASS}, 65. { 8, RING_CLASS}, 66. { 4, AMULET_CLASS} 67. }; 68. 69. static int NEARDATA mksx=0, NEARDATA mksy=0; 70. 71. struct obj * 72. mkobj_at(let,x,y, artif) 73. char let; 74. int x,y; 75. boolean artif; 76. { 77. register struct obj *otmp; 78. 79. mksx = x; mksy = y; 80. /* We need to know the X, Y coordinates while creating the object, 81. * to insure shop boxes are empty. 82. * Yes, this is a horrible kludge... 83. */ 84. otmp = mkobj(let,artif); 85. otmp->nobj = fobj; 86. fobj = otmp; 87. place_object(otmp, x, y); 88. mksx = mksy = 0; 89. return(otmp); 90. } 91. 92. struct obj * 93. mksobj_at(otyp,x,y,init) 94. int otyp,x,y; 95. boolean init; 96. { 97. register struct obj *otmp; 98. 99. mksx = x; mksy = y; 100. otmp = mksobj(otyp,init,TRUE); 101. otmp->nobj = fobj; 102. place_object(otmp, x, y); 103. mksx = mksy = 0; 104. return((fobj = otmp)); 105. } 106. 107. struct obj * 108. mkobj(let, artif) 109. char let; 110. boolean artif; 111. { 112. register int tprob, i, prob = rnd(1000); 113. 114. if(let == RANDOM_CLASS) { 115. const struct icp *iprobs = 116. #ifdef REINCARNATION 117. (Is_rogue_level(&u.uz)) ? 118. (const struct icp *)rogueprobs : 119. #endif 120. Inhell ? (const struct icp *)hellprobs : 121. (const struct icp *)mkobjprobs; 122. 123. for(tprob = rnd(100); 124. (tprob -= iprobs->iprob) > 0; 125. iprobs++); 126. let = iprobs->ilet; 127. } 128. 129. i = bases[letindex(let)]; 130. while((prob -= objects[i].oc_prob) > 0) i++; 131. 132. if(objects[i].oc_class != let || !OBJ_NAME(objects[i])) 133. panic("probtype error, let=%c i=%d", let, i); 134. 135. return(mksobj(i, TRUE, artif)); 136. } 137. 138. STATIC_OVL void 139. mkbox_cnts(box) 140. /* Note: does not check to see if it overloaded the box capacity; usually 141. * possible only with corpses in ice boxes. 142. */ 143. struct obj *box; 144. { 145. register int n; 146. register struct obj *otmp, *gold = 0; 147. 148. box->cobj = (struct obj *) 0; 149. 150. switch(box->otyp) { 151. case ICE_BOX: n = 20; break; 152. case CHEST: n = 5; break; 153. case LARGE_BOX: n = 3; break; 154. case SACK: 155. case OILSKIN_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. if (!(otmp = mksobj(CORPSE, TRUE, TRUE))) continue; 163. /* Note: setting age to 0 is correct. Age has a different 164. * from usual meaning for objects stored in ice boxes. -KAA 165. */ 166. otmp->age = 0L; 167. } else { 168. register int tprob; 169. const struct icp *iprobs = boxiprobs; 170. 171. for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++) 172. ; 173. if (!(otmp = mkobj(iprobs->ilet, TRUE))) continue; 174. 175. /* handle a couple of special cases */ 176. if (otmp->otyp == GOLD_PIECE) { 177. /* 2.5 x level's usual amount; weight adjusted below */ 178. otmp->quan = (long)(rnd(level_difficulty()+2) * rnd(75)); 179. if (gold) { /* gold already in this box */ 180. gold->quan += otmp->quan; /* merge */ 181. dealloc_obj(otmp); /* note: not yet in any chain */ 182. continue; 183. } else { 184. gold = otmp; /* remember this object */ 185. } 186. } else while (otmp->otyp == ROCK) { 187. otmp->otyp = rnd_class(DILITHIUM_CRYSTAL, LOADSTONE); 188. if (otmp->quan > 2L) otmp->quan = 1L; 189. otmp->owt = weight(otmp); 190. } 191. if (box->otyp == BAG_OF_HOLDING) { 192. if (Is_mbag(otmp)) { 193. otmp->otyp = SACK; 194. otmp->spe = 0; 195. otmp->owt = weight(otmp); 196. } else while (otmp->otyp == WAN_CANCELLATION) 197. otmp->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING); 198. } 199. } 200. otmp->nobj = box->cobj; 201. box->cobj = otmp; 202. } 203. if (gold) gold->owt = weight(gold); /* quantity was diddled */ 204. return; 205. } 206. 207. int 208. rndmonnum() /* select a random, common monster type */ 209. { 210. register struct permonst *ptr; 211. register int i; 212. 213. /* Plan A: get a level-appropriate common monster */ 214. ptr = rndmonst(); 215. if (ptr) return(monsndx(ptr)); 216. 217. /* Plan B: get any common monster */ 218. do { 219. ptr = &mons[(i = rn2(NUMMONS))]; 220. } while((ptr->geno & G_NOGEN) || (!Inhell && (ptr->geno & G_HELL))); 221. 222. return(i); 223. } 224. 225. #endif /* OVL1 */ 226. #ifdef OVLB 227. const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS, SCROLL_CLASS, 228. GEM_CLASS, SPBOOK_CLASS, WEAPON_CLASS, 0}; 229. 230. /*ARGSUSED*/ 231. struct obj * 232. mksobj(otyp, init, artif) 233. int otyp; 234. boolean init; 235. boolean artif; 236. { 237. int tryct; 238. struct obj *otmp; 239. char let = objects[otyp].oc_class; 240. 241. otmp = newobj(0); 242. *otmp = zeroobj; 243. otmp->age = monstermoves; 244. otmp->o_id = flags.ident++; 245. otmp->quan = 1L; 246. otmp->oclass = let; 247. otmp->otyp = otyp; 248. otmp->dknown = index(dknowns, let) ? 0 : 1; 249. if (!objects[otmp->otyp].oc_uses_known) 250. otmp->known = 1; 251. if (init) switch (let) { 252. case WEAPON_CLASS: 253. otmp->quan = (otmp->otyp <= SHURIKEN) ? (long) rn1(6,6) : 1L; 254. if(!rn2(11)) { 255. otmp->spe = rne(3); 256. otmp->blessed = rn2(2); 257. } else if(!rn2(10)) { 258. curse(otmp); 259. otmp->spe = -rne(3); 260. } else blessorcurse(otmp, 10); 261. 262. if (artif && !rn2(20)) 263. otmp = mk_artifact(otmp, (aligntyp)A_NONE); 264. break; 265. case FOOD_CLASS: 266. otmp->oeaten = 0; 267. switch(otmp->otyp) { 268. case CORPSE: 269. /* overridden by mkcorpstat() */ 270. do otmp->corpsenm = rndmonnum(); 271. while (mons[otmp->corpsenm].geno & G_NOCORPSE); 272. break; 273. case EGG: 274. if(!rn2(3)) { /* "live" eggs */ 275. register struct permonst *ptr; 276. for(tryct = 0; 277. (!(ptr = rndmonst()) || 278. (!lays_eggs(ptr) && ptr != &mons[PM_KILLER_BEE])) && 279. tryct < 100; 280. tryct++); 281. if(tryct < 100) otmp->corpsenm = monsndx(ptr); 282. else otmp->corpsenm = -1; /* empty */ 283. } else otmp->corpsenm = -1; /* empty */ 284. break; 285. case TIN: 286. if(!rn2(6)) { 287. otmp->spe = 1; /* spinach */ 288. otmp->corpsenm = -1; 289. } else do { 290. otmp->corpsenm = rndmonnum(); 291. } while (mons[otmp->corpsenm].geno & G_NOCORPSE); 292. blessorcurse(otmp, 10); 293. break; 294. #ifdef TUTTI_FRUTTI 295. case SLIME_MOLD: 296. otmp->spe = current_fruit; 297. break; 298. #endif 299. } 300. if (otmp->otyp == CORPSE) break; 301. /* fall into next case */ 302. 303. case GEM_CLASS: 304. if (otmp->otyp == LOADSTONE) curse(otmp); 305. else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6); 306. else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L; 307. else otmp->quan = 1L; 308. break; 309. case TOOL_CLASS: 310. switch(otmp->otyp) { 311. case TALLOW_CANDLE: 312. case WAX_CANDLE: otmp->spe = 1; 313. otmp->age = 20L * /* 400 or 200 */ 314. (long)objects[otmp->otyp].oc_cost; 315. otmp->lamplit = 0; 316. otmp->quan = 1L + 317. (long)(rn2(2) ? rn2(7) : 0); 318. blessorcurse(otmp, 5); 319. break; 320. case BRASS_LANTERN: 321. case OIL_LAMP: otmp->spe = 1; 322. otmp->age = (long) rn1(500,1000); 323. otmp->lamplit = 0; 324. blessorcurse(otmp, 5); 325. break; 326. case MAGIC_LAMP: otmp->spe = 1; 327. otmp->lamplit = 0; 328. blessorcurse(otmp, 2); 329. break; 330. case CHEST: 331. case LARGE_BOX: otmp->olocked = !!(rn2(5)); 332. otmp->otrapped = !(rn2(10)); 333. case ICE_BOX: 334. case SACK: 335. case OILSKIN_SACK: 336. case BAG_OF_HOLDING: mkbox_cnts(otmp); 337. break; 338. case MAGIC_MARKER: otmp->spe = rn1(70,30); 339. break; 340. case CAN_OF_GREASE: otmp->spe = rnd(25); 341. blessorcurse(otmp, 10); 342. break; 343. case CRYSTAL_BALL: otmp->spe = rnd(5); 344. blessorcurse(otmp, 2); 345. break; 346. case HORN_OF_PLENTY: 347. case BAG_OF_TRICKS: otmp->spe = rnd(20); 348. break; 349. case FIGURINE: { int tryct2 = 0; 350. do 351. otmp->corpsenm = rndmonnum(); 352. while(is_human(&mons[otmp->corpsenm]) 353. && tryct2++ < 30); 354. blessorcurse(otmp, 4); 355. break; 356. } 357. case BELL_OF_OPENING: otmp->spe = 3; 358. break; 359. case MAGIC_FLUTE: 360. case MAGIC_HARP: 361. case FROST_HORN: 362. case FIRE_HORN: 363. case DRUM_OF_EARTHQUAKE: 364. otmp->spe = rn1(5,4); 365. break; 366. } 367. break; 368. case AMULET_CLASS: 369. if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION || 370. otmp->otyp == AMULET_OF_CHANGE || 371. otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) { 372. curse(otmp); 373. } else blessorcurse(otmp, 10); 374. case VENOM_CLASS: 375. case CHAIN_CLASS: 376. case BALL_CLASS: 377. break; 378. case POTION_CLASS: 379. case SCROLL_CLASS: 380. #ifdef MAIL 381. if (otmp->otyp != SCR_MAIL) 382. #endif 383. blessorcurse(otmp, 4); 384. break; 385. case SPBOOK_CLASS: 386. blessorcurse(otmp, 17); 387. break; 388. case ARMOR_CLASS: 389. if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS || 390. otmp->otyp == LEVITATION_BOOTS || 391. otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT || 392. otmp->otyp == GAUNTLETS_OF_FUMBLING || 393. !rn2(11))) { 394. curse(otmp); 395. otmp->spe = -rne(3); 396. } else if(!rn2(10)) { 397. otmp->blessed = rn2(2); 398. otmp->spe = rne(3); 399. } else blessorcurse(otmp, 10); 400. break; 401. case WAND_CLASS: 402. if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else 403. otmp->spe = rn1(5, 404. (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4); 405. blessorcurse(otmp, 17); 406. otmp->recharged = 0; /* used to control recharging */ 407. break; 408. case RING_CLASS: 409. if(objects[otmp->otyp].oc_charged) { 410. blessorcurse(otmp, 3); 411. if(rn2(10)) { 412. if(rn2(10) && bcsign(otmp)) 413. otmp->spe = bcsign(otmp) * rne(3); 414. else otmp->spe = rn2(2) ? rne(3) : -rne(3); 415. } 416. /* make useless +0 rings much less common */ 417. if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3); 418. /* negative rings are usually cursed */ 419. if (otmp->spe < 0 && rn2(5)) curse(otmp); 420. } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION || 421. #ifdef POLYSELF 422. otmp->otyp == RIN_POLYMORPH || 423. #endif 424. otmp->otyp == RIN_AGGRAVATE_MONSTER || 425. otmp->otyp == RIN_HUNGER || !rn2(9))) { 426. curse(otmp); 427. } 428. break; 429. case ROCK_CLASS: 430. switch (otmp->otyp) { 431. case STATUE: 432. if (rn2(level_difficulty()/2 + 10) > 10) { 433. struct obj *book; 434. book = mkobj(SPBOOK_CLASS,FALSE); 435. otmp->cobj = book; 436. } 437. /* overridden by mkcorpstat() */ 438. otmp->corpsenm = rndmonnum(); 439. } 440. break; 441. case GOLD_CLASS: 442. break; /* do nothing */ 443. default: 444. impossible("impossible mkobj %d, sym '%c'.", otmp->otyp, objects[otmp->otyp].oc_class); 445. return (struct obj *)0; 446. } 447. /* unique objects may have an associated artifact entry */ 448. if (objects[otyp].oc_unique && !otmp->oartifact) 449. otmp = mk_artifact(otmp, (aligntyp)A_NONE); 450. otmp->owt = weight(otmp); 451. return(otmp); 452. } 453. 454. void 455. bless(otmp) 456. register struct obj *otmp; 457. { 458. otmp->cursed = 0; 459. otmp->blessed = 1; 460. if (otmp->otyp == LUCKSTONE 461. || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) { 462. int luckbon = stone_luck(TRUE); 463. if(!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0; 464. else if (luckbon >= 0) u.moreluck = LUCKADD; 465. else u.moreluck = -LUCKADD; 466. } else if (otmp->otyp == BAG_OF_HOLDING) 467. otmp->owt = weight(otmp); 468. return; 469. } 470. 471. void 472. unbless(otmp) 473. register struct obj *otmp; 474. { 475. otmp->blessed = 0; 476. if (otmp->otyp == LUCKSTONE 477. || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) { 478. int luckbon = stone_luck(TRUE); 479. if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0; 480. else if (luckbon >= 0) u.moreluck = LUCKADD; 481. else u.moreluck = -LUCKADD; 482. } else if (otmp->otyp == BAG_OF_HOLDING) 483. otmp->owt = weight(otmp); 484. } 485. 486. void 487. curse(otmp) 488. register struct obj *otmp; 489. { 490. otmp->blessed = 0; 491. otmp->cursed = 1; 492. if (otmp->otyp == LUCKSTONE 493. || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) { 494. int luckbon = stone_luck(TRUE); 495. if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0; 496. else if (luckbon >= 0) u.moreluck = LUCKADD; 497. else u.moreluck = -LUCKADD; 498. } else if (otmp->otyp == BAG_OF_HOLDING) 499. otmp->owt = weight(otmp); 500. return; 501. } 502. 503. void 504. uncurse(otmp) 505. register struct obj *otmp; 506. { 507. otmp->cursed = 0; 508. if (otmp->otyp == LUCKSTONE 509. || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) { 510. int luckbon = stone_luck(TRUE); 511. if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0; 512. else if (luckbon >= 0) u.moreluck = LUCKADD; 513. else u.moreluck = -LUCKADD; 514. } else if (otmp->otyp == BAG_OF_HOLDING) 515. otmp->owt = weight(otmp); 516. } 517. 518. #endif /* OVLB */ 519. #ifdef OVL1 520. void 521. blessorcurse(otmp, chance) 522. register struct obj *otmp; 523. register int chance; 524. { 525. if(otmp->blessed || otmp->cursed) return; 526. 527. if(!rn2(chance)) 528. if(!rn2(2)) { 529. curse(otmp); 530. } else { 531. bless(otmp); 532. } 533. return; 534. } 535. 536. #endif /* OVL1 */ 537. #ifdef OVLB 538. 539. int 540. bcsign(otmp) 541. register struct obj *otmp; 542. { 543. return(!!otmp->blessed - !!otmp->cursed); 544. } 545. 546. #endif /* OVLB */ 547. #ifdef OVL0 548. 549. /* 550. * Calculate the weight of the given object. This will recursively follow 551. * and calculate the weight of any containers. 552. * 553. * Note: It is possible to end up with an incorrect weight if some part 554. * of the code messes with a contained object and doesn't update the 555. * container's weight. 556. */ 557. int 558. weight(obj) 559. register struct obj *obj; 560. { 561. int wt = objects[obj->otyp].oc_weight; 562. 563. if (Is_container(obj) || obj->otyp == STATUE) { 564. struct obj *contents; 565. register int cwt = 0; 566. 567. if (obj->otyp == STATUE && obj->corpsenm > -1) 568. wt = (int)obj->quan * 569. ((int)mons[obj->corpsenm].cwt * 3 / 2); 570. 571. for(contents=obj->cobj; contents; contents=contents->nobj) 572. cwt += weight(contents); 573. /* 574. * The weight of bags of holding is calculated as the weight 575. * of the bag plus the weight of the bag's contents modified 576. * as follows: 577. * 578. * Bag status Weight of contents 579. * ---------- ------------------ 580. * cursed 2x 581. * blessed x/4 + 1 582. * otherwise x/2 + 1 583. * 584. * The macro DELTA_CWT in pickup.c also implements these 585. * weight equations. 586. * 587. * Note: The above checks are performed in the given order. 588. * this means that if an object is both blessed and 589. * cursed (not supposed to happen), it will be treated 590. * as cursed. 591. */ 592. if (obj->otyp == BAG_OF_HOLDING) 593. cwt = obj->cursed ? (cwt * 2) : 594. (1 + (cwt / (obj->blessed ? 4 : 2))); 595. 596. return wt + cwt; 597. } 598. if (obj->otyp == CORPSE && obj->corpsenm > -1) 599. return (int)obj->quan * mons[obj->corpsenm].cwt; 600. else if (obj->otyp == GOLD_PIECE) 601. return (int)((obj->quan + 500L) / 1000L); 602. return(wt ? wt*(int)obj->quan : ((int)obj->quan + 1)>>1); 603. } 604. 605. #endif /* OVL0 */ 606. #ifdef OVLB 607. 608. void 609. mkgold(amount, x, y) 610. long amount; 611. int x, y; 612. { 613. register struct obj *gold = g_at(x,y); 614. 615. if (amount <= 0L) amount = (long)(1 + rnd(level_difficulty()+2) * rnd(30)); 616. if (gold) { 617. gold->quan += amount; 618. } else { 619. gold = mksobj_at(GOLD_PIECE,x,y,TRUE); 620. gold->quan = amount; 621. } 622. gold->owt = weight(gold); 623. } 624. 625. #endif /* OVLB */ 626. #ifdef OVL1 627. struct obj * 628. mkcorpstat(objtype, ptr, x, y, init) 629. int objtype; /* CORPSE or STATUE */ 630. register struct permonst *ptr; 631. int x, y; 632. boolean init; 633. { 634. register struct obj *otmp; 635. 636. if(objtype != CORPSE && objtype != STATUE) 637. impossible("making corpstat type %d", objtype); 638. otmp = mksobj_at(objtype, x, y, init); 639. if(otmp) { 640. if(ptr) otmp->corpsenm = monsndx(ptr); 641. else otmp->corpsenm = rndmonnum(); 642. otmp->owt = weight(otmp); 643. } 644. return(otmp); 645. } 646. 647. #endif /* OVL1 */ 648. #ifdef OVLB 649. struct obj * 650. mk_tt_object(objtype, x, y) 651. int objtype; /* CORPSE or STATUE */ 652. register int x, y; 653. { 654. register struct obj *otmp; 655. 656. /* player statues never contain books */ 657. if ((otmp = mksobj_at(objtype,x,y,FALSE)) != 0) 658. otmp = tt_oname(otmp); 659. return(otmp); 660. } 661. 662. /* make a new corpse or statue, uninitialized if a statue (i.e. no books) */ 663. struct obj * 664. mk_named_object(objtype, ptr, x, y, nm, lth) 665. int objtype; /* CORPSE or STATUE */ 666. register struct permonst *ptr; 667. int x, y; 668. char * nm; 669. register int lth; 670. { 671. struct obj *otmp; 672. 673. otmp = mkcorpstat(objtype,ptr,x,y,(objtype != STATUE)); 674. if (lth > 0) { 675. /* Note: oname() is safe since otmp is first in both chains */ 676. otmp = oname(otmp, nm, FALSE); 677. fobj = otmp; 678. level.objects[x][y] = otmp; 679. if (is_pool(x,y)) water_damage(otmp,TRUE); 680. } 681. return(otmp); 682. } 683. 684. boolean 685. is_flammable(otmp) 686. register struct obj *otmp; 687. { 688. int otyp = otmp->otyp; 689. 690. if (objects[otyp].oc_oprop == FIRE_RES) return FALSE; 691. 692. return((objects[otyp].oc_material == WOOD || 693. objects[otyp].oc_material == 0)); 694. 695. } 696. 697. #endif /* OVLB */ 698. #ifdef OVL1 699. 700. /* 701. * These routines maintain the single-linked lists headed in level.objects[][] 702. * and threaded through the nexthere fields in the object-instance structure. 703. */ 704. 705. void 706. place_object(otmp, x, y) 707. /* put an object on top of the pile at the given location */ 708. register struct obj *otmp; 709. int x, y; 710. { 711. register struct obj *otmp2 = level.objects[x][y]; 712. 713. if (otmp->otyp == BOULDER) block_point(x,y); /* vision */ 714. 715. if (otmp2 && (otmp2->otyp == BOULDER)) { 716. otmp->nexthere = otmp2->nexthere; 717. otmp2->nexthere = otmp; 718. } else { 719. otmp->nexthere = otmp2; 720. level.objects[x][y] = otmp; 721. } 722. if (is_pool(x,y)) water_damage(otmp,TRUE); 723. 724. /* set the new object's location */ 725. otmp->ox = x; 726. otmp->oy = y; 727. } 728. 729. #endif /* OVL1 */ 730. #ifdef OVLB 731. void 732. remove_object(otmp) 733. register struct obj *otmp; 734. { 735. register struct obj *odel; 736. 737. if (otmp->otyp == BOULDER) unblock_point(otmp->ox,otmp->oy); /* vision */ 738. 739. if (otmp == level.objects[otmp->ox][otmp->oy]) 740. level.objects[otmp->ox][otmp->oy] = otmp->nexthere; 741. else 742. for (odel = level.objects[otmp->ox][otmp->oy]; 743. odel; odel = odel->nexthere) 744. if (odel->nexthere == otmp) { 745. odel->nexthere = otmp->nexthere; 746. break; 747. } 748. } 749. 750. void 751. move_object(otmp, x, y) 752. register struct obj *otmp; 753. int x, y; 754. { 755. remove_object(otmp); 756. place_object(otmp, x, y); 757. } 758. 759. #endif /* OVLB */ 760. 761. /*mkobj.c*/
|