Source:NetHack 3.2.0/mkobj.c

Below is the full text to mkobj.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2	96/02/29	*/ 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.  STATIC_DCL void FDECL(obj_timer_checks,(struct obj *, XCHAR_P, XCHAR_P, int)); 11.  #ifdef OVL1 12.  static void FDECL(container_weight, (struct obj *)); 13.  #ifdef WIZARD 14.  static const char *FDECL(where_name, (int)); 15.  static void FDECL(check_contained, (struct obj *,const char *)); 16.  #endif 17.  #endif /* OVL1 */ 18.   19.   /*#define DEBUG_EFFECTS		/* show some messages for debugging */ 20.   21.   struct icp { 22.      int  iprob;		/* probability of an item type */ 23.      char iclass;	/* item class */ 24.  };  25.    26.   #ifdef OVL1 27.   28.   const struct icp mkobjprobs[] = { 29.  {10, WEAPON_CLASS}, 30.  {10, ARMOR_CLASS}, 31.  {20, FOOD_CLASS}, 32.  { 8, TOOL_CLASS}, 33.  { 8, GEM_CLASS}, 34.  {16, POTION_CLASS}, 35.  {16, SCROLL_CLASS}, 36.  { 4, SPBOOK_CLASS}, 37.  { 4, WAND_CLASS}, 38.  { 3, RING_CLASS}, 39.  { 1, AMULET_CLASS} 40.  };  41.    42.   const struct icp boxiprobs[] = { 43.  {18, GEM_CLASS}, 44.  {15, FOOD_CLASS}, 45.  {18, POTION_CLASS}, 46.  {18, SCROLL_CLASS}, 47.  {12, SPBOOK_CLASS}, 48.  { 7, GOLD_CLASS}, 49.  { 6, WAND_CLASS}, 50.  { 5, RING_CLASS}, 51.  { 1, AMULET_CLASS} 52.  };  53.    54.   #ifdef REINCARNATION 55.  const struct icp rogueprobs[] = { 56.  {12, WEAPON_CLASS}, 57.  {12, ARMOR_CLASS}, 58.  {22, FOOD_CLASS}, 59.  {22, POTION_CLASS}, 60.  {22, SCROLL_CLASS}, 61.  { 5, WAND_CLASS}, 62.  { 5, RING_CLASS} 63.  };  64.   #endif 65.   66.   const struct icp hellprobs[] = { 67.  {20, WEAPON_CLASS}, 68.  {20, ARMOR_CLASS}, 69.  {16, FOOD_CLASS}, 70.  {12, TOOL_CLASS}, 71.  {10, GEM_CLASS}, 72.  { 1, POTION_CLASS}, 73.  { 1, SCROLL_CLASS}, 74.  { 8, WAND_CLASS}, 75.  { 8, RING_CLASS}, 76.  { 4, AMULET_CLASS} 77.  };  78.    79.   struct obj * 80.  mkobj_at(let,x,y, artif) 81.  char let; 82.  int x,y; 83.  boolean artif; 84.  {  85.   	register struct obj *otmp; 86.   87.   	otmp = mkobj(let,artif); 88.  	place_object(otmp, x, y); 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.   	otmp = mksobj(otyp,init,TRUE); 100. 	place_object(otmp, x, y); 101. 	return(otmp); 102. }  103.   104.  struct obj * 105. mkobj(oclass, artif) 106. char oclass; 107. boolean artif; 108. {  109.  	register int tprob, i, prob = rnd(1000); 110.  111.  	if(oclass == RANDOM_CLASS) { 112. 		const struct icp *iprobs = 113. #ifdef REINCARNATION 114. 				    (Is_rogue_level(&u.uz)) ? 115. 				    (const struct icp *)rogueprobs : 116. #endif 117. 				    Inhell ? (const struct icp *)hellprobs : 118. 				    (const struct icp *)mkobjprobs; 119.  120.  		for(tprob = rnd(100);  121.  		    (tprob -= iprobs->iprob) > 0;  122.  		    iprobs++); 123. 		oclass = iprobs->iclass; 124. 	}  125.   126.  	i = bases[(int)oclass]; 127. 	while((prob -= objects[i].oc_prob) > 0) i++; 128.  129.  	if(objects[i].oc_class != oclass || !OBJ_NAME(objects[i])) 130. 		panic("probtype error, oclass=%d i=%d", (int) oclass, i); 131.  132.  	return(mksobj(i, TRUE, artif)); 133. }  134.   135.  STATIC_OVL void 136. mkbox_cnts(box) 137. struct obj *box; 138. {  139.  	register int n;  140. register struct obj *otmp, *gold = 0; 141.  142.  	box->cobj = (struct obj *) 0; 143.  144.  	switch(box->otyp) { 145. 		case ICE_BOX:		n = 20; break; 146. 		case CHEST:		n = 5; break; 147. 		case LARGE_BOX:		n = 3; break; 148. 		case SACK: 149. 		case OILSKIN_SACK: 150. 				/* initial inventory: sack starts out empty */ 151. 				if (moves <= 1 && !in_mklev) { n = 0; break; } 152. 				/*else FALLTHRU*/ 153. 		case BAG_OF_HOLDING:	n = 1; break; 154. 		default:		n = 0; break; 155. 	}  156.   157.  	for (n = rn2(n+1); n > 0; n--) { 158. 	    if (box->otyp == ICE_BOX) { 159. 		if (!(otmp = mksobj(CORPSE, TRUE, TRUE))) continue; 160. 		/* Note: setting age to 0 is correct. Age has a different 161. 		 * from usual meaning for objects stored in ice boxes. -KAA 162. 		 */  163.  		otmp->age = 0L; 164. 		if (otmp->timed) { 165. 		    (void) stop_timer(ROT_CORPSE, (genericptr_t)otmp); 166. 		    (void) stop_timer(REVIVE_MON, (genericptr_t)otmp); 167. 		}  168.  	    } else { 169. 		register int tprob; 170. 		const struct icp *iprobs = boxiprobs; 171.  172.  		for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++) 173. 		    ;  174.  		if (!(otmp = mkobj(iprobs->iclass, TRUE))) continue; 175.  176.  		/* handle a couple of special cases */ 177. 		if (otmp->oclass == GOLD_CLASS) { 178. 		    /* 2.5 x level's usual amount; weight adjusted below */ 179. 		    otmp->quan = (long)(rnd(level_difficulty+2) * rnd(75)); 180. 		    if (gold) {			/* gold already in this box */ 181. 			gold->quan += otmp->quan;	/* merge */ 182. 			dealloc_obj(otmp);	/* note: not yet in any chain */ 183. 			continue; 184. 		    } else { 185. 			gold = otmp;		/* remember this object */ 186. 		    }  187.  		} else while (otmp->otyp == ROCK) { 188. 		    otmp->otyp = rnd_class(DILITHIUM_CRYSTAL, LOADSTONE); 189. 		    if (otmp->quan > 2L) otmp->quan = 1L; 190. 		    otmp->owt = weight(otmp); 191. 		}  192.  		if (box->otyp == BAG_OF_HOLDING) { 193. 		    if (Is_mbag(otmp)) { 194. 			otmp->otyp = SACK; 195. 			otmp->spe = 0; 196. 			otmp->owt = weight(otmp); 197. 		    } else while (otmp->otyp == WAN_CANCELLATION) 198. 			    otmp->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING); 199. 		}  200.  	    }  201.  	    add_to_container(box, 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. 	    i = rn1(SPECIAL_PM - LOW_PM, LOW_PM); 220. 	    ptr = &mons[i]; 221. 	} while((ptr->geno & G_NOGEN) || (!Inhell && (ptr->geno & G_HELL))); 222.  223.  	return(i); 224. }  225.   226.  /*  227.   * Split obj so that it gets size num. The remainder is put in the object 228.  * structure delivered by this call. The object is positioned just 229.  * following the original in the nobj chain (and nexthere chain when on  230.   * the floor). 231.  */  232.  struct obj * 233. splitobj(obj, num) 234. struct obj *obj; 235. long num; 236. {  237.  	struct obj *otmp; 238.  239.  	if (obj->cobj || num <= 0L || obj->quan < num) 240. 	    panic("splitobj");	/* can't split containers */ 241. 	otmp = newobj(obj->onamelth); 242. 	*otmp = *obj;		/* copies whole structure */ 243. 	otmp->o_id = flags.ident++; 244. 	if (!otmp->o_id) otmp->o_id = flags.ident++;	/* ident overflowed */ 245. 	otmp->timed = 0;	/* not timed, yet */ 246. 	otmp->lamplit = 0;	/* ditto */ 247. 	obj->quan = num; 248. 	obj->owt = weight(obj); 249. 	otmp->quan -= num; 250. 	otmp->owt = weight(otmp);	/* -= obj->owt ? */ 251.  	obj->nobj = otmp; 252. 	/* Only set nexthere when on the floor, nexthere is also used */ 253. 	/* as a back pointer to the container object when contained. */ 254.  	if (obj->where == OBJ_FLOOR) 255. 	    obj->nexthere = otmp; 256. 	if (obj->onamelth) 257. 	    (void)strncpy(ONAME(otmp), ONAME(obj), (int)obj->onamelth); 258. 	if (obj->unpaid) splitbill(obj,otmp); 259. 	if (obj->timed) obj_split_timers(obj, otmp); 260. 	if (obj_sheds_light(obj)) obj_split_light_source(obj, otmp); 261. 	return otmp; 262. }  263.   264.  /*  265.   * Create a dummy duplicate to put on shop bill. The duplicate exists 266.  * only in the billobjs chain. This function is used when a shop object 267.  * is being altered, and a copy of the original is needed for billing 268.  * purposes. For example, when eating, where an interruption will yield 269.  * an object which is different from what it started out as; the "I x"  270. * command needs to display the original object. 271.  */  272.  void 273. bill_dummy_object(otmp) 274. register struct obj *otmp; 275. {  276.  	register struct obj *dummy; 277.  278.  	if (otmp->unpaid) 279. 	    subfrombill(otmp, shop_keeper(*u.ushops)); 280. 	dummy = newobj(otmp->onamelth); 281. 	*dummy = *otmp; 282. 	dummy->where = OBJ_FREE; 283. 	dummy->o_id = flags.ident++; 284. 	if (!dummy->o_id) dummy->o_id = flags.ident++;	/* ident overflowed */ 285. 	dummy->timed = 0; 286. 	if (otmp->onamelth) 287. 	    (void)strncpy(ONAME(dummy), ONAME(otmp), (int)otmp->onamelth); 288. 	if (Is_candle(dummy)) dummy->lamplit = 0; 289. 	addtobill(dummy, FALSE, TRUE, TRUE); 290. }  291.   292.  #endif /* OVL1 */ 293. #ifdef OVLB 294.  295.  static const char dknowns[] = { 296. 		WAND_CLASS, RING_CLASS, POTION_CLASS, SCROLL_CLASS, 297. 		GEM_CLASS, SPBOOK_CLASS, WEAPON_CLASS, TOOL_CLASS, 0 298. };  299.   300.  struct obj * 301. mksobj(otyp, init, artif) 302. int otyp; 303. boolean init; 304. boolean artif; 305. {  306.  	int mndx, tryct; 307. 	struct obj *otmp; 308. 	char let = objects[otyp].oc_class; 309.  310.  	otmp = newobj(0); 311. 	*otmp = zeroobj; 312. 	otmp->age = monstermoves; 313. 	otmp->o_id = flags.ident++; 314. 	if (!otmp->o_id) otmp->o_id = flags.ident++;	/* ident overflowed */ 315. 	otmp->quan = 1L; 316. 	otmp->oclass = let; 317. 	otmp->otyp = otyp; 318. 	otmp->where = OBJ_FREE; 319. 	otmp->dknown = index(dknowns, let) ? 0 : 1; 320.  	if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||  321.  			otmp->otyp == SHIELD_OF_REFLECTION) 322. 		otmp->dknown = 0; 323. 	if (!objects[otmp->otyp].oc_uses_known) 324. 		otmp->known = 1; 325. 	if (init) switch (let) { 326. 	case WEAPON_CLASS: 327. 		otmp->quan = (otmp->otyp <= SHURIKEN) ? (long) rn1(6,6) : 1L; 328. 		if(!rn2(11)) { 329. 			otmp->spe = rne(3); 330. 			otmp->blessed = rn2(2); 331. 		} else if(!rn2(10)) { 332. 			curse(otmp); 333. 			otmp->spe = -rne(3); 334. 		} else	blessorcurse(otmp, 10); 335.  336.  		if (artif && !rn2(20)) 337. 		    otmp = mk_artifact(otmp, (aligntyp)A_NONE); 338. 		break; 339. 	case FOOD_CLASS: 340. 	    otmp->oeaten = 0; 341. 	    switch(otmp->otyp) { 342. 	    case CORPSE: 343. 		/* overridden by mkcorpstat */ 344. 		tryct = 50; 345. 		do otmp->corpsenm = undead_to_corpse(rndmonnum); 346. 		while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0)); 347. 		if (tryct == 0) { 348. 		/* perhaps rndmonnum only wants to make G_NOCORPSE monsters on  349. this level; let's create an adventurer's corpse instead, then */ 350. 			otmp->corpsenm = PM_HUMAN; 351. 		}  352.  		start_corpse_timeout(otmp); 353. 		break; 354. 	    case EGG: 355. 		otmp->corpsenm = NON_PM;	/* generic egg */ 356. 		if (!rn2(3)) for (tryct = 200; tryct > 0; --tryct) { 357. 		    mndx = can_be_hatched(rndmonnum); 358. 		    if (mndx != NON_PM && !dead_species(mndx, TRUE)) { 359. 			otmp->corpsenm = mndx;		/* typed egg */ 360. 			attach_egg_hatch_timeout(otmp); 361. 			break; 362. 		    }  363.  		}  364.  		break; 365. 	    case TIN: 366. 		otmp->corpsenm = NON_PM;	/* empty (so far) */ 367. 		if (!rn2(6)) 368. 		    otmp->spe = 1;		/* spinach */ 369. 		else for (tryct = 200; tryct > 0; --tryct) { 370. 		    mndx = undead_to_corpse(rndmonnum); 371. 		    if (mons[mndx].cnutrit &&  372.  			    !(mvitals[mndx].mvflags & G_NOCORPSE)) { 373. 			otmp->corpsenm = mndx; 374. 			break; 375. 		    }  376.  		}  377.  		blessorcurse(otmp, 10); 378. 		break; 379. 	    case SLIME_MOLD: 380. 		otmp->spe = current_fruit; 381. 		break; 382. 	    }  383.  	    if (otmp->otyp == CORPSE) break; 384. 	    /* fall into next case */ 385.  386.  	case GEM_CLASS: 387. 		if (otmp->otyp == LOADSTONE) curse(otmp); 388. 		else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6); 389. 		else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L; 390. 		else otmp->quan = 1L; 391. 		break; 392. 	case TOOL_CLASS: 393. 	    switch(otmp->otyp) { 394. 		case TALLOW_CANDLE: 395. 		case WAX_CANDLE:	otmp->spe = 1; 396. 					otmp->age = 20L * /* 400 or 200 */ 397. 					      (long)objects[otmp->otyp].oc_cost; 398. 					otmp->lamplit = 0; 399. 					otmp->quan = 1L + 400. 					      (long)(rn2(2) ? rn2(7) : 0); 401. 					blessorcurse(otmp, 5); 402. 					break; 403. 		case BRASS_LANTERN: 404. 		case OIL_LAMP:		otmp->spe = 1; 405. 					otmp->age = (long) rn1(500,1000); 406. 					otmp->lamplit = 0; 407. 					blessorcurse(otmp, 5); 408. 					break; 409. 		case MAGIC_LAMP:	otmp->spe = 1; 410. 					otmp->lamplit = 0; 411. 					blessorcurse(otmp, 2); 412. 					break; 413. 		case CHEST: 414. 		case LARGE_BOX:		otmp->olocked = !!(rn2(5)); 415. 					otmp->otrapped = !(rn2(10)); 416. 		case ICE_BOX: 417. 		case SACK: 418. 		case OILSKIN_SACK: 419. 		case BAG_OF_HOLDING:	mkbox_cnts(otmp); 420. 					break; 421. 		case MAGIC_MARKER:	otmp->spe = rn1(70,30); 422. 					break; 423. 		case CAN_OF_GREASE:	otmp->spe = rnd(25); 424. 					blessorcurse(otmp, 10); 425. 					break; 426. 		case CRYSTAL_BALL:	otmp->spe = rnd(5); 427. 					blessorcurse(otmp, 2); 428. 					break; 429. 		case HORN_OF_PLENTY: 430. 		case BAG_OF_TRICKS:	otmp->spe = rnd(20); 431. 					break; 432. 		case FIGURINE:	{	int tryct2 = 0; 433. 					do 434. 					    otmp->corpsenm = rndmonnum; 435. 					while(is_human(&mons[otmp->corpsenm])  436.  						&& tryct2++ < 30); 437. 					blessorcurse(otmp, 4); 438. 					break; 439. 				}  440.  		case BELL_OF_OPENING:   otmp->spe = 3; 441. 					break; 442. 		case MAGIC_FLUTE: 443. 		case MAGIC_HARP: 444. 		case FROST_HORN: 445. 		case FIRE_HORN: 446. 		case DRUM_OF_EARTHQUAKE: 447. 					otmp->spe = rn1(5,4); 448. 					break; 449. 	    }  450.  	    break; 451. 	case AMULET_CLASS: 452. 		if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION || 453. 		   otmp->otyp == AMULET_OF_CHANGE || 454. 		   otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) { 455. 			curse(otmp); 456. 		} else	blessorcurse(otmp, 10); 457. 	case VENOM_CLASS: 458. 	case CHAIN_CLASS: 459. 	case BALL_CLASS: 460. 		break; 461. 	case POTION_CLASS: 462. 		if (otmp->otyp == POT_OIL) 463. 		    otmp->age = MAX_OIL_IN_FLASK;	/* amount of oil */ 464. 		/* fall through */ 465. 	case SCROLL_CLASS: 466. #ifdef MAIL 467. 		if (otmp->otyp != SCR_MAIL) 468. #endif 469. 			blessorcurse(otmp, 4); 470. 		break; 471. 	case SPBOOK_CLASS: 472. 		blessorcurse(otmp, 17); 473. 		break; 474. 	case ARMOR_CLASS: 475. 		if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS || 476. 		   otmp->otyp == LEVITATION_BOOTS || 477. 		   otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT || 478. 		   otmp->otyp == GAUNTLETS_OF_FUMBLING || 479. 		   !rn2(11))) { 480. 			curse(otmp); 481. 			otmp->spe = -rne(3); 482. 		} else if(!rn2(10)) { 483. 			otmp->blessed = rn2(2); 484. 			otmp->spe = rne(3); 485. 		} else	blessorcurse(otmp, 10); 486. 		/* simulate lacquered armor for samurai */ 487. 		if (Role_is('S') && otmp->otyp == SPLINT_MAIL &&  488.  		    (moves <= 1 || In_quest(&u.uz))) { 489. #ifdef UNIXPC 490. 			/* optimizer bitfield bug */ 491. 			otmp->oerodeproof = 1; 492. 			otmp->rknown = 1; 493. #else 494. 			otmp->oerodeproof = otmp->rknown = 1; 495. #endif 496. 		}  497.  		break; 498. 	case WAND_CLASS: 499. 		if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else 500. 		otmp->spe = rn1(5,  501.  			(objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4); 502. 		blessorcurse(otmp, 17); 503. 		otmp->recharged = 0; /* used to control recharging */ 504. 		break; 505. 	case RING_CLASS: 506. 		if(objects[otmp->otyp].oc_charged) { 507. 		    blessorcurse(otmp, 3); 508. 		    if(rn2(10)) { 509. 			if(rn2(10) && bcsign(otmp)) 510. 			    otmp->spe = bcsign(otmp) * rne(3); 511. 			else otmp->spe = rn2(2) ? rne(3) : -rne(3); 512. 		    }  513.  		    /* make useless +0 rings much less common */ 514. 		    if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3); 515. 		    /* negative rings are usually cursed */ 516. 		    if (otmp->spe < 0 && rn2(5)) curse(otmp); 517. 		} else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION || 518. 			  otmp->otyp == RIN_POLYMORPH || 519. 			  otmp->otyp == RIN_AGGRAVATE_MONSTER || 520. 			  otmp->otyp == RIN_HUNGER || !rn2(9))) { 521. 			curse(otmp); 522. 		}  523.  		break; 524. 	case ROCK_CLASS: 525. 		switch (otmp->otyp) { 526. 		    case STATUE: 527. 			if (rn2(level_difficulty/2 + 10) > 10) { 528. 			    add_to_container(otmp, mkobj(SPBOOK_CLASS,FALSE)); 529. 			}  530.  			/* overridden by mkcorpstat */ 531. 			otmp->corpsenm = rndmonnum; 532. 		}  533.  		break; 534. 	case GOLD_CLASS: 535. 		break;	/* do nothing */ 536. 	default: 537. 		impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,  538.  						objects[otmp->otyp].oc_class); 539. 		return (struct obj *)0; 540. 	}  541.  	/* unique objects may have an associated artifact entry */ 542. 	if (objects[otyp].oc_unique && !otmp->oartifact) 543. 	    otmp = mk_artifact(otmp, (aligntyp)A_NONE); 544. 	otmp->owt = weight(otmp); 545. 	return(otmp); 546. }  547.   548.  /*  549.   * Start a corpse decay or revive timer. This assumes that the corpse 550.  * was just dropped and its age is 0. 551.  */  552.  void 553. start_corpse_timeout(body) 554. 	struct obj *body; 555. {  556.  	long when; 557. 	short action; 558.  559.  #define TAINT_AGE (50L)		/* age when corpses go bad */ 560. #define TROLL_REVIVE_CHANCE 37	/* 1/37 chance for 50 turns ~ 75% chance */ 561. #define ROT_AGE (250L)	/* age when corpses rot away */ 562.  563.  	/* lizards don't rot or revive */ 564. 	if (body->corpsenm == PM_LIZARD) return; 565.  566.  	action = ROT_CORPSE;		/* default action: rot away */ 567. 	when = ROT_AGE;			/* rot away when this old */ 568. 	if (is_rider(&mons[body->corpsenm])) { 569. 		/*  570.  		 * Riders always revive. They have a 1/3 chance per turn 571. 		 * of reviving after 12 turns. Always revive by 500. 572. 		 */  573.  		action = REVIVE_MON; 574. 		for (when = 12L; when < 500L; when++) 575. 		    if (!rn2(3)) break; 576.  577.  	} else if (mons[body->corpsenm].mlet == S_TROLL) { 578. 		long age; 579. 		for (age = 2; age <= TAINT_AGE; age++) 580. 		    if (!rn2(TROLL_REVIVE_CHANCE)) {	/* troll revives */ 581. 			action = REVIVE_MON; 582. 			when = age; 583. 			break; 584. 		    }  585.  	}  586.   587.  	(void) start_timer(when, TIMER_OBJECT, action, (genericptr_t)body); 588. }  589.   590.  void 591. bless(otmp) 592. register struct obj *otmp; 593. {  594.  	otmp->cursed = 0; 595. 	otmp->blessed = 1; 596. 	if (otmp->otyp == LUCKSTONE  597.  		|| (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) 598. 	    set_moreluck; 599. 	else if (otmp->otyp == BAG_OF_HOLDING) 600. 	    otmp->owt = weight(otmp); 601. 	return; 602. }  603.   604.  void 605. unbless(otmp) 606. register struct obj *otmp; 607. {  608.  	otmp->blessed = 0; 609. 	if (otmp->otyp == LUCKSTONE  610.  		|| (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) 611. 	    set_moreluck; 612. 	else if (otmp->otyp == BAG_OF_HOLDING) 613. 	    otmp->owt = weight(otmp); 614. }  615.   616.  void 617. curse(otmp) 618. register struct obj *otmp; 619. {  620.  	otmp->blessed = 0; 621. 	otmp->cursed = 1; 622. 	if (otmp->otyp == LUCKSTONE  623.  		|| (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) 624. 	    set_moreluck; 625. 	else if (otmp->otyp == BAG_OF_HOLDING) 626. 	    otmp->owt = weight(otmp); 627. 	return; 628. }  629.   630.  void 631. uncurse(otmp) 632. register struct obj *otmp; 633. {  634.  	otmp->cursed = 0; 635. 	if (otmp->otyp == LUCKSTONE  636.  		|| (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) 637. 	    set_moreluck; 638. 	else if (otmp->otyp == BAG_OF_HOLDING) 639. 		otmp->owt = weight(otmp); 640. }  641.   642.  #endif /* OVLB */ 643. #ifdef OVL1 644.  645.  void 646. blessorcurse(otmp, chance) 647. register struct obj *otmp; 648. register int chance; 649. {  650.  	if(otmp->blessed || otmp->cursed) return; 651.  652.  	if(!rn2(chance)) 653. 	    if(!rn2(2)) { 654. 		curse(otmp); 655. 	    } else { 656. 		bless(otmp); 657. 	    }  658.  	return; 659. }  660.   661.  #endif /* OVL1 */ 662. #ifdef OVLB 663.  664.  int 665. bcsign(otmp) 666. register struct obj *otmp; 667. {  668.  	return(!!otmp->blessed - !!otmp->cursed); 669. }  670.   671.  #endif /* OVLB */ 672. #ifdef OVL0 673.  674.  /*  675.   *  Calculate the weight of the given object. This will recursively follow 676.  *  and calculate the weight of any containers. 677.  *  678.   *  Note:  It is possible to end up with an incorrect weight if some part 679.  *	   of the code messes with a contained object and doesn't update the 680.  *	   container's weight. 681.  */  682.  int 683. weight(obj) 684. register struct obj *obj; 685. {  686.  	int wt = objects[obj->otyp].oc_weight; 687.  688.  	if (obj->otyp == LARGE_BOX && obj->spe == 1) /* Schroedinger's Cat */ 689. 		wt += mons[PM_HOUSECAT].cwt; 690. 	if (Is_container(obj) || obj->otyp == STATUE) { 691. 		struct obj *contents; 692. 		register int cwt = 0; 693.  694.  		if (obj->otyp == STATUE && obj->corpsenm >= LOW_PM) 695. 		    wt = (int)obj->quan * 696. 			 ((int)mons[obj->corpsenm].cwt * 3 / 2); 697.  698.  		for(contents=obj->cobj; contents; contents=contents->nobj) 699. 			cwt += weight(contents); 700. 		/*  701.  		 *  The weight of bags of holding is calculated as the weight 702. 		 *  of the bag plus the weight of the bag's contents modified 703. 		 *  as follows: 704. 		 *  705.  		 *	Bag status	Weight of contents 706. 		 *	--	--  707.  		 *	cursed			2x 708. 		 *	blessed			x/4 + 1 709. 		 *	otherwise		x/2 + 1 710. 		 *  711.  		 *  The macro DELTA_CWT in pickup.c also implements these 712. 		 *  weight equations. 713. 		 *  714.  		 *  Note:  The above checks are performed in the given order. 715. 		 *	   this means that if an object is both blessed and 716. 		 *	   cursed (not supposed to happen), it will be treated 717. 		 *	   as cursed. 718. 		 */  719.  		if (obj->otyp == BAG_OF_HOLDING) 720. 		    cwt = obj->cursed ? (cwt * 2) : 721. 					(1 + (cwt / (obj->blessed ? 4 : 2))); 722.  723.  		return wt + cwt; 724. 	}  725.  	if (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM) 726. 		return (int)obj->quan * mons[obj->corpsenm].cwt; 727. 	else if (obj->oclass == GOLD_CLASS) 728. 		return (int)((obj->quan + 50L) / 100L); 729. 	else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0) 730. 		return((int)(obj->owt));	/* kludge for "very" heavy iron ball */ 731. 	return(wt ? wt*(int)obj->quan : ((int)obj->quan + 1)>>1); 732. }  733.   734.  #endif /* OVL0 */ 735. #ifdef OVLB 736.  737.  void 738. mkgold(amount, x, y)  739. long amount; 740. int x, y;  741. { 742.      register struct obj *gold = g_at(x,y); 743.  744.      if (amount <= 0L) amount = (long)(1 + rnd(level_difficulty+2) * rnd(30)); 745.     if (gold) { 746. 	gold->quan += amount; 747.     } else { 748. 	gold = mksobj_at(GOLD_PIECE,x,y,TRUE); 749. 	gold->quan = amount; 750.     }  751.      gold->owt = weight(gold); 752. }  753.   754.  #endif /* OVLB */ 755. #ifdef OVL1 756.  757.  struct obj * 758. mkcorpstat(objtype, ptr, x, y, init) 759. int objtype;	/* CORPSE or STATUE */ 760. struct permonst *ptr; 761. int x, y;  762. boolean init; 763. {  764.  	register struct obj *otmp; 765.  766.  	if(objtype != CORPSE && objtype != STATUE) 767. 		impossible("making corpstat type %d", objtype); 768. 	otmp = mksobj_at(objtype, x, y, init); 769. 	if(otmp)  { 770. 		int old_corpsenm = otmp->corpsenm; 771. 		if(ptr)	otmp->corpsenm = monsndx(ptr); 772. 		else	otmp->corpsenm = rndmonnum; 773. 		otmp->owt = weight(otmp); 774.  775.  /* return TRUE if the corpse has special timing */ 776. #define special_corpse(num)  (((num) == PM_LIZARD)		\  777.  				|| (is_rider(&mons[num]))	\  778.  				|| (mons[num].mlet == S_TROLL)) 779.  780.  		if (otmp->otyp == CORPSE &&  781.  			(special_corpse(old_corpsenm) || 782. 				special_corpse(otmp->corpsenm))) { 783. 		    obj_stop_timers(otmp); 784. 		    start_corpse_timeout(otmp); 785. 		}  786.  	}  787.  	return(otmp); 788. }  789.   790.  #endif /* OVL1 */ 791. #ifdef OVLB 792.  793.  /* make an object named after someone listed in the scoreboard file */ 794. struct obj * 795. mk_tt_object(objtype, x, y)  796. int objtype; /* CORPSE or STATUE */ 797. register int x, y;  798. { 799.  	register struct obj *otmp, *otmp2; 800. 	boolean initialize_it; 801.  802.  	/* player statues never contain books */ 803. 	initialize_it = (objtype != STATUE); 804. 	if ((otmp = mksobj_at(objtype, x, y, initialize_it)) != 0) { 805. 	    /* tt_oname will return null if the scoreboard is empty */ 806. 	    if ((otmp2 = tt_oname(otmp)) != 0) otmp = otmp2; 807. 	}  808.  	return(otmp); 809. }  810.   811.  /* make a new corpse or statue, uninitialized if a statue (i.e. no books) */ 812. struct obj * 813. mk_named_object(objtype, ptr, x, y, nm) 814. int objtype;	/* CORPSE or STATUE */ 815. struct permonst *ptr; 816. int x, y;  817. const char *nm; 818. {  819.  	struct obj *otmp; 820.  821.  	otmp = mkcorpstat(objtype, ptr, x, y, (boolean)(objtype != STATUE)); 822. 	if (nm) 823. 		otmp = oname(otmp, nm); 824. 	return(otmp); 825. }  826.   827.  boolean 828. is_flammable(otmp) 829. register struct obj *otmp; 830. {  831.  	int otyp = otmp->otyp; 832.  833.  	if (objects[otyp].oc_oprop == FIRE_RES) return FALSE; 834.  835.  	return((boolean)(objects[otyp].oc_material <= WOOD && 836. 			objects[otyp].oc_material != LIQUID)); 837. }  838.   839.  #endif /* OVLB */ 840. #ifdef OVL1 841.  842.  /*  843.   * These routines maintain the single-linked lists headed in level.objects[][] 844.  * and threaded through the nexthere fields in the object-instance structure. 845.  */  846.   847.  /* put the object at the given location */ 848. void 849. place_object(otmp, x, y)  850. register struct obj *otmp; 851. int x, y;  852. { 853.      register struct obj *otmp2 = level.objects[x][y]; 854.  855.      if (otmp->where != OBJ_FREE) 856. 	panic("place_object: obj not free"); 857.  858.      if (otmp->otyp == BOULDER) block_point(x,y);	/* vision */ 859.  860.      /* obj goes under boulders */ 861.     if (otmp2 && (otmp2->otyp == BOULDER)) { 862. 	otmp->nexthere = otmp2->nexthere; 863. 	otmp2->nexthere = otmp; 864.     } else { 865. 	otmp->nexthere = otmp2; 866. 	level.objects[x][y] = otmp; 867.     }  868.   869.      /* set the new object's location */ 870.     otmp->ox = x;  871. otmp->oy = y; 872. 873.     otmp->where = OBJ_FLOOR; 874.  875.      /* add to floor chain */ 876.     otmp->nobj = fobj; 877.     fobj = otmp; 878.     if (otmp->timed) obj_timer_checks(otmp, x, y, 0); 879. }  880.   881.  #define ON_ICE(a) ((a)->recharged) 882. #define ROT_ICE_ADJUSTMENT 2	/* rotting on ice takes 2 times as long */ 883.  884.  /* If ice was affecting any objects correct that now 885.  * Also used for starting ice effects too. [zap.c] 886. */ 887.  void 888. obj_ice_effects(x, y, do_buried) 889. int x, y;  890. boolean do_buried; 891. {  892.  	struct obj *otmp; 893.  894.  	for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) { 895. 		if (otmp->timed) obj_timer_checks(otmp, x, y, 0); 896. 	}  897.  	if (do_buried) { 898. 	    for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) { 899.  		if (otmp->ox == x && otmp->oy == y) { 900. 			if (otmp->timed) obj_timer_checks(otmp, x, y, 0); 901. 		}  902.  	    }  903.  	}  904.  }  905.   906.  /*  907.   * Returns an obj->age for a corpse object on ice, that would be the 908.  * actual obj->age if the corpse had just been lifted from the ice. 909.  * This is useful when just using obj->age in a check or calculation because 910.  * rot timers pertaining to the object don't have to be stopped and 911.  * restarted etc. 912.  */  913.  long 914. peek_at_iced_corpse_age(otmp) 915. struct obj *otmp; 916. {  917.      long age, retval = otmp->age; 918.      919.      if (otmp->otyp == CORPSE && ON_ICE(otmp)) { 920. 	/* Adjust the age; must be same as obj_timer_checks for off ice*/ 921. 	age = monstermoves - otmp->age; 922. 	retval = otmp->age + (age / ROT_ICE_ADJUSTMENT); 923. #ifdef DEBUG_EFFECTS 924. 	pline_The("%s age has ice modifications:otmp->age = %ld, returning %ld.",  925.  		s_suffix(doname(otmp)),otmp->age, retval); 926. 	pline("Effective age of corpse: %ld.",  927.  		monstermoves - retval); 928. #endif 929.     }  930.      return retval; 931. }  932.   933.  static void 934. obj_timer_checks(otmp, x, y, force) 935. struct obj *otmp; 936. xchar x, y;  937. int force;	/* 0 = no force so do checks, <0 = force off, >0 force on */ 938. {  939.      long tleft = 0L; 940.     short action = ROT_CORPSE; 941.     boolean restart_timer = FALSE; 942.     boolean on_floor = (otmp->where == OBJ_FLOOR); 943.     boolean buried = (otmp->where == OBJ_BURIED); 944.  945.      /* Check for corpses just placed on or in ice */ 946.     if (otmp->otyp == CORPSE && (on_floor || buried) && is_ice(x,y)) { 947. 	tleft = stop_timer(action, (genericptr_t)otmp); 948. 	if (tleft == 0L) { 949. 		action = REVIVE_MON; 950. 		tleft = stop_timer(action, (genericptr_t)otmp); 951. 	}  952.  	if (tleft != 0L) { 953. 	    long age; 954. 	     955.  	    tleft = tleft - monstermoves; 956. 	    /* mark the corpse as being on ice */ 957. 	    ON_ICE(otmp) = 1; 958. #ifdef DEBUG_EFFECTS 959. 	    pline("%s is now on ice at %d,%d.", The(xname(otmp)),x,y); 960. #endif 961. 	    /* Adjust the time remaining */ 962. 	    tleft *= ROT_ICE_ADJUSTMENT; 963. 	    restart_timer = TRUE; 964. 	    /* Adjust the age; must be same as in obj_ice_age */ 965. 	    age = monstermoves - otmp->age; 966. 	    otmp->age = monstermoves - (age * ROT_ICE_ADJUSTMENT); 967. 	}  968.      }  969.      /* Check for corpses coming off ice */ 970.     else if ((force < 0) ||  971.  	     (otmp->otyp == CORPSE && ON_ICE(otmp) && 972. 	     ((on_floor && !is_ice(x,y)) || !on_floor))) { 973. 	tleft = stop_timer(action, (genericptr_t)otmp); 974. 	if (tleft == 0L) { 975. 		action = REVIVE_MON; 976. 		tleft = stop_timer(action, (genericptr_t)otmp); 977. 	}  978.  	if (tleft != 0L) { 979. 		long age; 980.  981.  		tleft = tleft - monstermoves; 982. 		ON_ICE(otmp) = 0; 983. #ifdef DEBUG_EFFECTS 984. 	    	pline("%s is no longer on ice at %d,%d.", The(xname(otmp)),x,y); 985. #endif 986. 		/* Adjust the remaining time */ 987. 		tleft /= ROT_ICE_ADJUSTMENT; 988. 		restart_timer = TRUE; 989. 		/* Adjust the age */ 990. 		age = monstermoves - otmp->age; 991. 		otmp->age = otmp->age + (age / ROT_ICE_ADJUSTMENT); 992. 	}  993.      }  994.      /* now re-start the timer with the appropriate modifications */ 995.     if (restart_timer) 996. 	(void) start_timer(tleft, TIMER_OBJECT, action, (genericptr_t)otmp); 997. }  998.   999.  #undef ON_ICE 1000. #undef ROT_ICE_ADJUSTMENT 1001. 1002. void 1003. remove_object(otmp) 1004. register struct obj *otmp; 1005. { 1006.     xchar x = otmp->ox; 1007.    xchar y = otmp->oy; 1008. 1009.     if (otmp->where != OBJ_FLOOR) 1010. 	panic("remove_object: obj not on floor"); 1011.    if (otmp->otyp == BOULDER) unblock_point(x,y); /* vision */ 1012.    extract_nexthere(otmp, &level.objects[x][y]); 1013.    extract_nobj(otmp, &fobj); 1014.    if (otmp->timed) obj_timer_checks(otmp,x,y,0); 1015. } 1016.  1017. /* throw away all of a monster's inventory */ 1018. void 1019. discard_minvent(mtmp) 1020. struct monst *mtmp; 1021. { 1022.     struct obj *otmp; 1023. 1024.     while ((otmp = mtmp->minvent) != 0) { 1025. 	obj_extract_self(otmp); 1026. 	obfree(otmp, (struct obj *)0);	/* dealloc_obj isn't sufficient */ 1027.    }  1028. }  1029.  1030. /*  1031.  * Free obj from whatever list it is on in preperation of deleting it or  1032. * moving it elsewhere. This will perform all high-level consequences 1033. * involved with removing the item. E.g. if the object is in the hero's 1034. * inventory and confers heat resistance, the hero will lose it. 1035. *  1036.  * Object positions: 1037. *	OBJ_FREE	not on any list 1038. *	OBJ_FLOOR	fobj, level.locations[][] chains (use remove_object) 1039. *	OBJ_CONTAINED	cobj chain of container object 1040. *	OBJ_INVENT	hero's invent chain (use freeinv) 1041. *	OBJ_MINVENT	monster's invent chain 1042. *	OBJ_MIGRATING	migrating chain 1043. *	OBJ_BURIED	level.buriedobjs chain 1044. *	OBJ_ONBILL	on billobjs chain 1045. */  1046. void 1047. obj_extract_self(obj) 1048.    struct obj *obj; 1049. { 1050.     switch (obj->where) { 1051. 	case OBJ_FREE: 1052. 	   break; 1053. 	case OBJ_FLOOR: 1054. 	   remove_object(obj); 1055. 	   break; 1056. 	case OBJ_CONTAINED: 1057. 	   extract_nobj(obj, &obj->ocontainer->cobj); 1058. 	   container_weight(obj->ocontainer); 1059. 	   break; 1060. 	case OBJ_INVENT: 1061. 	   freeinv(obj); 1062. 	   break; 1063. 	case OBJ_MINVENT: 1064. 	   extract_nobj(obj, &obj->ocarry->minvent); 1065. 	   break; 1066. 	case OBJ_MIGRATING: 1067. 	   extract_nobj(obj, &migrating_objs); 1068. 	   break; 1069. 	case OBJ_BURIED: 1070. 	   extract_nobj(obj, &level.buriedobjlist); 1071. 	   break; 1072. 	case OBJ_ONBILL: 1073. 	   extract_nobj(obj, &billobjs); 1074. 	   break; 1075. 	default: 1076. 	   panic("obj_extract_self"); 1077. 	   break; 1078.    }  1079. }  1080.  1081.  1082. /* Extract the given object from the chain, following nobj chain. */ 1083. void 1084. extract_nobj(obj, head_ptr) 1085.    struct obj *obj, **head_ptr; 1086. { 1087.     struct obj *curr, *prev; 1088. 1089.     curr = *head_ptr; 1090.    for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nobj) { 1091. 	if (curr == obj) { 1092. 	   if (prev) 1093. 		prev->nobj = curr->nobj; 1094. 	   else 1095. 		*head_ptr = curr->nobj; 1096. 	   break; 1097. 	} 1098.     }  1099.     if (!curr) panic("extract_nobj: object lost"); 1100.    obj->where = OBJ_FREE; 1101. } 1102.  1103.  1104. /*  1105.  * Extract the given object from the chain, following nexthere chain. 1106. *  1107.  * This does not set obj->where, this function is expected to be called 1108. * in tandem with extract_nobj, which does set it. 1109. */  1110. void 1111. extract_nexthere(obj, head_ptr) 1112.    struct obj *obj, **head_ptr; 1113. { 1114.     struct obj *curr, *prev; 1115. 1116.     curr = *head_ptr; 1117.    for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nexthere) { 1118. 	if (curr == obj) { 1119. 	   if (prev) 1120. 		prev->nexthere = curr->nexthere; 1121. 	   else 1122. 		*head_ptr = curr->nexthere; 1123. 	   break; 1124. 	} 1125.     }  1126.     if (!curr) panic("extract_nexthere: object lost"); 1127. } 1128.  1129.  1130. void 1131. add_to_minv(mon, obj) 1132.    struct monst *mon; 1133.    struct obj *obj; 1134. { 1135.     struct obj *otmp; 1136. 1137.     if (obj->where != OBJ_FREE) 1138. 	panic("add_to_minv: obj not free"); 1139. 1140.     /* merge if possible */ 1141.    for (otmp = mon->minvent; otmp; otmp = otmp->nobj) 1142. 	if (merged(&otmp, &obj)) 1143. 	   return; 1144.    /* else insert; don't bother forcing it to end of chain */ 1145.    obj->where = OBJ_MINVENT; 1146.    obj->ocarry = mon; 1147.    obj->nobj = mon->minvent; 1148.    mon->minvent = obj; 1149. } 1150.  1151. void 1152. add_to_container(container, obj) 1153.    struct obj *container, *obj; 1154. { 1155.     if (obj->where != OBJ_FREE) 1156. 	panic("add_to_container: obj not free"); 1157. 1158.     obj->where = OBJ_CONTAINED; 1159.    obj->ocontainer = container; 1160.    obj->nobj = container->cobj; 1161.    container->cobj = obj; 1162. } 1163.  1164. void 1165. add_to_migration(obj) 1166.    struct obj *obj; 1167. { 1168.     if (obj->where != OBJ_FREE) 1169. 	panic("add_to_migration: obj not free"); 1170. 1171.     obj->where = OBJ_MIGRATING; 1172.    obj->nobj = migrating_objs; 1173.    migrating_objs = obj; 1174. } 1175.  1176. void 1177. add_to_buried(obj) 1178.    struct obj *obj; 1179. { 1180.     if (obj->where != OBJ_FREE) 1181. 	panic("add_to_buried: obj not free"); 1182. 1183.     obj->where = OBJ_BURIED; 1184.    obj->nobj = level.buriedobjlist; 1185.    level.buriedobjlist = obj; 1186. } 1187.  1188. /* Recalculate the weight of this container and all of _its_ containers. */ 1189. static void 1190. container_weight(container) 1191.    struct obj *container; 1192. { 1193.     container->owt = weight(container); 1194.    if (container->where == OBJ_CONTAINED) 1195. 	container_weight(container->ocontainer); 1196. /* 1197.     else if (container->where == OBJ_INVENT) 1198. 	recalculate load delay here ??? 1199. */ 1200. }  1201.  1202. /*  1203.  * Deallocate the object. _All_ objects should be run through here for 1204. * them to be deallocated. 1205. */  1206. void 1207. dealloc_obj(obj) 1208.    struct obj *obj; 1209. { 1210.     if (obj->where != OBJ_FREE) 1211. 	panic("dealloc_obj: obj not free"); 1212. 1213.     /* free up any timers attached to the object */ 1214.    if (obj->timed) 1215. 	obj_stop_timers(obj); 1216. 1217.     /*  1218.      * Free up any light sources attached to the object. 1219.     *  1220.      * We may want to just call del_light_source without any 1221.     * checks (requires a code change there). Otherwise this 1222.     * list must track all objects that can have a light source 1223.     * attached to it (and also requires lamplit to be set). 1224.     */  1225.     if (obj_sheds_light(obj)) 1226. 	del_light_source(LS_OBJECT, (genericptr_t) obj); 1227. 1228.     free((genericptr_t) obj); 1229. } 1230.  1231. #ifdef WIZARD 1232. /* Check all object lists for consistency. */ 1233. void 1234. obj_sanity_check 1235. { 1236.     int x, y;  1237. struct obj *obj; 1238.    struct monst *mon; 1239.    const char *mesg; 1240.    char obj_address[20], mon_address[20];  /* room for formatted pointers */ 1241. 1242.     mesg = "fobj sanity"; 1243.    for (obj = fobj; obj; obj = obj->nobj) { 1244. 	if (obj->where != OBJ_FLOOR) { 1245. 	   pline("%s obj %s %s@(%d,%d): %s\n", mesg,  1246. 		fmt_ptr((genericptr_t)obj, obj_address),  1247. 		where_name(obj->where),  1248. 		obj->ox, obj->oy, doname(obj)); 1249. 	} 1250. 	check_contained(obj, mesg); 1251.    }  1252.  1253.     mesg = "location sanity"; 1254.    for (x = 0; x < COLNO; x++) 1255. 	for (y = 0; y < ROWNO; y++) 1256. 	   for (obj = level.objects[x][y]; obj; obj = obj->nexthere) 1257. 		if (obj->where != OBJ_FLOOR) { 1258. 		   pline("%s obj %s %s@(%d,%d): %s\n", mesg,  1259. 			fmt_ptr((genericptr_t)obj, obj_address),  1260. 			where_name(obj->where),  1261. 			obj->ox, obj->oy, doname(obj)); 1262. 		} 1263.  1264.     mesg = "invent sanity"; 1265.    for (obj = invent; obj; obj = obj->nobj) { 1266. 	if (obj->where != OBJ_INVENT) { 1267. 	   pline("%s obj %s %s: %s\n", mesg,  1268. 		fmt_ptr((genericptr_t)obj, obj_address),  1269. 		where_name(obj->where), doname(obj)); 1270. 	} 1271. 	check_contained(obj, mesg); 1272.    }  1273.  1274.     mesg = "migrating sanity"; 1275.    for (obj = migrating_objs; obj; obj = obj->nobj) { 1276. 	if (obj->where != OBJ_MIGRATING) { 1277. 	   pline("%s obj %s %s: %s\n", mesg,  1278. 		fmt_ptr((genericptr_t)obj, obj_address),  1279. 		where_name(obj->where), doname(obj)); 1280. 	} 1281. 	check_contained(obj, mesg); 1282.    }  1283.  1284.     mesg = "buried sanity"; 1285.    for (obj = level.buriedobjlist; obj; obj = obj->nobj) { 1286. 	if (obj->where != OBJ_BURIED) { 1287. 	   pline("%s obj %s %s: %s\n", mesg,  1288. 		fmt_ptr((genericptr_t)obj, obj_address),  1289. 		where_name(obj->where), doname(obj)); 1290. 	} 1291. 	check_contained(obj, mesg); 1292.    }  1293.  1294.     mesg = "bill sanity"; 1295.    for (obj = billobjs; obj; obj = obj->nobj) { 1296. 	if (obj->where != OBJ_ONBILL) { 1297. 	   pline("%s obj %s %s: %s\n", mesg,  1298. 		fmt_ptr((genericptr_t)obj, obj_address),  1299. 		where_name(obj->where), doname(obj)); 1300. 	} 1301. 	/* shouldn't be a full container on the bill */ 1302. 	if (obj->cobj) { 1303. 	   pline("%s obj %s contains something! %s\n", mesg,  1304. 		fmt_ptr((genericptr_t)obj, obj_address),  1305. 		doname(obj)); 1306. 	} 1307.     }  1308.  1309.     mesg = "minvent sanity"; 1310.    for (mon = fmon; mon; mon = mon->nmon) 1311. 	for (obj = mon->minvent; obj; obj = obj->nobj) { 1312. 	   if (obj->where != OBJ_MINVENT) { 1313. 		pline("%s obj %s %s: %s\n", mesg, 1314. 			fmt_ptr((genericptr_t)obj, obj_address),  1315. 			where_name(obj->where), doname(obj)); 1316. 	   }  1317. 	    if (obj->ocarry != mon) { 1318. 		pline("%s obj %s (%s) not held by mon %s (%s)\n", mesg, 1319. 			fmt_ptr((genericptr_t)obj, obj_address),  1320. 			doname(obj),  1321. 			fmt_ptr((genericptr_t)mon, mon_address),  1322. 			mon_nam(mon)); 1323. 	   }  1324. 	    check_contained(obj, mesg); 1325. 	} 1326. }  1327.  1328. /* This must stay consistent with the defines in obj.h. */ 1329. static const char *obj_state_names[NOBJ_STATES] = { 1330. 	"free",		"floor",	"contained",	"invent", 1331. 	"minvent",	"migrating",	"buried",	"onbill" 1332. }; 1333.  1334. static const char * 1335. where_name(where) 1336.    int where; 1337. { 1338.     return (where<0 || where>=NOBJ_STATES) ? "unknown" : obj_state_names[where]; 1339. } 1340.  1341. /* obj sanity check: check objs contained by container */ 1342. static void 1343. check_contained(container, mesg) 1344.    struct obj *container; 1345.    const char *mesg; 1346. { 1347.     struct obj *obj; 1348.    char obj1_address[20], obj2_address[20]; 1349. 1350.     for (obj = container->cobj; obj; obj = obj->nobj) { 1351. 	if (obj->where != OBJ_CONTAINED) 1352. 	   pline("contained %s obj %s: %s\n", mesg,  1353. 		fmt_ptr((genericptr_t)obj, obj1_address),  1354. 		where_name(obj->where)); 1355. 	else if (obj->ocontainer != container) 1356. 	   pline("%s obj %s not in container %s\n", mesg,  1357. 		fmt_ptr((genericptr_t)obj, obj1_address),  1358. 		fmt_ptr((genericptr_t)container, obj2_address)); 1359.    }  1360. }  1361. #endif /* WIZARD */ 1362. 1363. #endif /* OVL1 */ 1364. 1365. /*mkobj.c*/