Source:SLASH'EM 0.0.7E7F2/mkobj.c

Below is the full text to mkobj.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mkobj.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)mkobj.c	3.4	2002/10/07	*/ 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 "prop.h"  7. 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_DCL void FDECL(container_weight, (struct obj *)); 13.  STATIC_DCL struct obj *FDECL(save_mtraits, (struct obj *, struct monst *)); 14.  #ifdef WIZARD 15.  STATIC_DCL const char *FDECL(where_name, (int)); 16.  STATIC_DCL void FDECL(check_contained, (struct obj *,const char *)); 17.  #endif 18.  #endif /* OVL1 */ 19.   20.   extern struct obj *thrownobj;		/* defined in dothrow.c */ 21.   22.   /*#define DEBUG_EFFECTS*/	/* show some messages for debugging */ 23.   24.   struct icp { 25.      int  iprob;		/* probability of an item type */ 26.      char iclass;	/* item class */ 27.  };  28.    29.   #ifdef OVL1 30.   31.   /* STEPHEN WHITE'S NEW CODE */ 32.  /* [Tom] tried to fix this back up a little... */ 33.   /* KMH, balance patch -- changed again */ 34.  const struct icp mkobjprobs[] = { 35.  {10, WEAPON_CLASS}, 36.  {10, ARMOR_CLASS}, 37.  {20, FOOD_CLASS}, 38.  {10, TOOL_CLASS}, 39.  { 8, GEM_CLASS}, 40.  {15, POTION_CLASS}, 41.  {15, SCROLL_CLASS}, 42.  { 4, SPBOOK_CLASS}, 43.  { 4, WAND_CLASS}, 44.  { 4, RING_CLASS} 45.  /* KMH -- amulets now appear later in the game */ 46.  /*{ 0, AMULET_CLASS}*/ 47.  };  48.    49.   const struct icp boxiprobs[] = { 50.  {15, GEM_CLASS}, 51.  {10, FOOD_CLASS}, 52.  {20, POTION_CLASS}, 53.  {20, SCROLL_CLASS}, 54.  {12, SPBOOK_CLASS}, 55.  { 7, COIN_CLASS}, 56.  { 7, WAND_CLASS}, 57.  { 6, RING_CLASS}, 58.  { 3, AMULET_CLASS} 59.  };  60.    61.   #ifdef REINCARNATION 62.  const struct icp rogueprobs[] = { 63.  {12, WEAPON_CLASS}, 64.  {12, ARMOR_CLASS}, 65.  {22, FOOD_CLASS}, 66.  {22, POTION_CLASS}, 67.  {22, SCROLL_CLASS}, 68.  { 5, WAND_CLASS}, 69.  { 5, RING_CLASS} 70.  };  71.   #endif 72.   73.   const struct icp hellprobs[] = { 74.  {15, WEAPON_CLASS}, 75.  {15, ARMOR_CLASS}, 76.  {16, FOOD_CLASS}, 77.  {14, TOOL_CLASS}, 78.  {12, GEM_CLASS}, 79.  { 2, POTION_CLASS}, 80.  { 2, SCROLL_CLASS}, 81.  {10, WAND_CLASS}, 82.  {10, RING_CLASS}, 83.  { 4, AMULET_CLASS} 84.  };  85.    86.   struct obj * 87.  mkobj_at(let, x, y, artif) 88.  char let; 89.  int x, y;  90. boolean artif; 91.  {  92.   	struct obj *otmp; 93.   94.   	otmp = mkobj(let, artif); 95.  	place_object(otmp, x, y); 96.  	return(otmp); 97.  }  98.    99.   struct obj * 100. mksobj_at(otyp, x, y, init, artif) 101. int otyp, x, y;  102. boolean init, artif; 103. {  104.  	struct obj *otmp; 105.  106.  	otmp = mksobj(otyp, init, artif); 107. 	place_object(otmp, x, y); 108. 	return(otmp); 109. }  110.   111.  struct obj * 112. mkobj(oclass, artif) 113. char oclass; 114. boolean artif; 115. {  116.  	int tprob, i, prob = rnd(1000); 117.  118.  	if(oclass == RANDOM_CLASS) { 119. 		const struct icp *iprobs = 120. #ifdef REINCARNATION 121. 				    (Is_rogue_level(&u.uz)) ? 122. 				    (const struct icp *)rogueprobs : 123. #endif 124. 				    Inhell ? (const struct icp *)hellprobs : 125. 				    (const struct icp *)mkobjprobs; 126.  127.  		for(tprob = rnd(100);  128.  		    (tprob -= iprobs->iprob) > 0;  129.  		    iprobs++); 130. 		oclass = iprobs->iclass; 131. 	}  132.   133.  	i = bases[(int)oclass]; 134. 	while((prob -= objects[i].oc_prob) > 0) i++; 135.  136.  	if(objects[i].oc_class != oclass || !OBJ_NAME(objects[i])) 137. 		panic("probtype error, oclass=%d i=%d", (int) oclass, i); 138.  139.  	return(mksobj(i, TRUE, artif)); 140. }  141.   142.  STATIC_OVL void 143. mkbox_cnts(box) 144. struct obj *box; 145. {  146.  	register int n, minn = 0; 147. 	register struct obj *otmp; 148.  149.  	box->cobj = (struct obj *) 0; 150.  151.  	switch (box->otyp) { 152. 	case MEDICAL_KIT:	n = 60; 153. 				/* Initial inventory, no empty medical kits */ 154. 				if (moves <= 1 && !in_mklev) minn = 1; 155. 				break; 156. 	case ICE_BOX:		n = 20; break; 157. 	case CHEST:		n = 5; break; 158. 	case LARGE_BOX:		n = 3; break; 159. 	case SACK: 160. 	case OILSKIN_SACK: 161. 				/* initial inventory: sack starts out empty */ 162. 				if (moves <= 1 && !in_mklev) { n = 0; break; } 163. 				/*else FALLTHRU*/ 164. 	case BAG_OF_HOLDING:	n = 1; break; 165. 	default:		n = 0; break; 166. 	}  167.   168.  	for (n = rn1(n+1 - minn, minn); n > 0; n--) { 169. 	    if (box->otyp == MEDICAL_KIT) { 170. 		int supplies[] = { PHIAL, BANDAGE, PILL }; 171. 		if (!(otmp = mksobj(supplies[rn2(SIZE(supplies))], TRUE, TRUE))) 172. 		    continue; 173. 		else 174. 		    otmp->oinvis = FALSE; 175. 	    } else 176. 	    if (box->otyp == ICE_BOX) { 177. 		if (!(otmp = mksobj(CORPSE, TRUE, TRUE))) continue; 178. 		/* Note: setting age to 0 is correct. Age has a different 179. 		 * from usual meaning for objects stored in ice boxes. -KAA 180. 		 */  181.  		otmp->age = 0L; 182. 		if (otmp->timed) { 183. 		    (void) stop_timer(ROT_CORPSE, (genericptr_t)otmp); 184. 		    (void) stop_timer(MOLDY_CORPSE, (genericptr_t)otmp); 185. 		    (void) stop_timer(REVIVE_MON, (genericptr_t)otmp); 186. 		}  187.  	    } else { 188. 		register int tprob; 189. 		const struct icp *iprobs = boxiprobs; 190.  191.  		for (tprob = rnd(100); (tprob -= iprobs->iprob) > 0; iprobs++) 192. 		    ;  193.  		if (!(otmp = mkobj(iprobs->iclass, TRUE))) continue; 194.  195.  		/* handle a couple of special cases */ 196. 		if (otmp->oclass == COIN_CLASS) { 197. 		    /* 2.5 x level's usual amount; weight adjusted below */ 198. 		    otmp->quan = (long)(rnd(level_difficulty+5) * rnd(100)); 199. 		    otmp->owt = weight(otmp); 200. 		} else while (otmp->otyp == ROCK) { 201. 		    otmp->otyp = rnd_class(DILITHIUM_CRYSTAL, LOADSTONE); 202. 		    if (otmp->quan > 2L) otmp->quan = 1L; 203. 		    otmp->owt = weight(otmp); 204. 		}  205.  		if (box->otyp == BAG_OF_HOLDING) { 206. 		    if (Is_mbag(otmp)) { 207. 			otmp->otyp = SACK; 208. 			otmp->spe = 0; 209. 			otmp->owt = weight(otmp); 210. 		    } else while (otmp->otyp == WAN_CANCELLATION) 211. 			    otmp->otyp = rnd_class(WAN_LIGHT, WAN_FIREBALL); 212. 		}  213.  	    }  214.  	    (void) add_to_container(box, otmp); 215. 	}  216.  }  217.   218.  int 219. rndmonnum	/* select a random, common monster type */ 220. {  221.  	register struct permonst *ptr; 222. 	register int	i; 223.  224.  	/* Plan A: get a level-appropriate common monster */ 225. 	ptr = rndmonst; 226. 	if (ptr) return(monsndx(ptr)); 227.  228.  	/* Plan B: get any common monster */ 229. 	do { 230. 	    i = rn1(SPECIAL_PM - LOW_PM, LOW_PM); 231. 	    ptr = &mons[i]; 232. 	} while((ptr->geno & G_NOGEN) || (!Inhell && (ptr->geno & G_HELL))); 233.  234.  	return(i); 235. }  236.   237.  /*  238.   * Split obj so that it gets size gets reduced by num. The quantity num is 239. * put in the object structure delivered by this call. The returned object 240.  * has its wornmask cleared and is positioned just following the original 241.  * in the nobj chain (and nexthere chain when on the floor). 242.  */  243.  struct obj * 244. splitobj(obj, num) 245. struct obj *obj; 246. long num; 247. {  248.  	struct obj *otmp; 249.  250.  	if (obj->cobj || num <= 0L || obj->quan <= num) 251. 	    panic("splitobj");	/* can't split containers */ 252. 	otmp = newobj(obj->oxlth + obj->onamelth); 253. 	*otmp = *obj;		/* copies whole structure */ 254. 	otmp->o_id = flags.ident++; 255. 	if (!otmp->o_id) otmp->o_id = flags.ident++;	/* ident overflowed */ 256. 	otmp->timed = 0;	/* not timed, yet */ 257. 	otmp->lamplit = 0;	/* ditto */ 258. 	otmp->owornmask = 0L;	/* new object isn't worn */ 259. 	obj->quan -= num; 260. 	obj->owt = weight(obj); 261. 	otmp->quan = num; 262. 	otmp->owt = weight(otmp);	/* -= obj->owt ? */ 263.  	obj->nobj = otmp; 264. 	/* Only set nexthere when on the floor, nexthere is also used */ 265. 	/* as a back pointer to the container object when contained. */ 266.  	if (obj->where == OBJ_FLOOR) 267. 	    obj->nexthere = otmp; 268. 	if (obj->oxlth) 269. 	    (void)memcpy((genericptr_t)otmp->oextra, (genericptr_t)obj->oextra,  270.  			obj->oxlth); 271. 	if (obj->onamelth) 272. 	    (void)strncpy(ONAME(otmp), ONAME(obj), (int)obj->onamelth); 273. 	if (obj->unpaid) splitbill(obj,otmp); 274. 	if (obj->timed) obj_split_timers(obj, otmp); 275. 	if (obj_sheds_light(obj)) obj_split_light_source(obj, otmp); 276. 	return otmp; 277. }  278.   279.  /*  280.   * Insert otmp right after obj in whatever chain(s) it is on. Then extract 281.  * obj from the chain(s). This function does a literal swap. It is up to 282. * the caller to provide a valid context for the swap. When done, obj will 283.  * still exist, but not on any chain. 284.  *  285.   * Note:  Don't use use obj_extract_self -- we are doing an in-place swap, 286.  * not actually moving something. 287.  */  288.  void 289. replace_object(obj, otmp) 290. struct obj *obj; 291. struct obj *otmp; 292. {  293.      otmp->where = obj->where; 294.     switch (obj->where) { 295.     case OBJ_FREE: 296. 	/* do nothing */ 297. 	break; 298.     case OBJ_INVENT: 299. 	otmp->nobj = obj->nobj; 300. 	obj->nobj = otmp; 301. 	extract_nobj(obj, &invent); 302. 	break; 303.     case OBJ_CONTAINED: 304. 	otmp->nobj = obj->nobj; 305. 	otmp->ocontainer = obj->ocontainer; 306. 	obj->nobj = otmp; 307. 	extract_nobj(obj, &obj->ocontainer->cobj); 308. 	break; 309.     case OBJ_MINVENT: 310. 	otmp->nobj = obj->nobj; 311. 	otmp->ocarry =  obj->ocarry; 312. 	obj->nobj = otmp; 313. 	extract_nobj(obj, &obj->ocarry->minvent); 314. 	break; 315.     case OBJ_FLOOR: 316. 	otmp->nobj = obj->nobj; 317. 	otmp->nexthere = obj->nexthere; 318. 	otmp->ox = obj->ox; 319. 	otmp->oy = obj->oy; 320. 	obj->nobj = otmp; 321. 	obj->nexthere = otmp; 322. 	extract_nobj(obj, &fobj); 323. 	extract_nexthere(obj, &level.objects[obj->ox][obj->oy]); 324. 	break; 325.     case OBJ_MIGRATING: 326. 	otmp->nobj = obj->nobj; 327. 	obj->nobj = otmp; 328. 	extract_nobj(obj, &migrating_objs); 329. 	break; 330.     case OBJ_BURIED: 331. 	otmp->nobj = obj->nobj; 332. 	obj->nobj = otmp; 333. 	extract_nobj(obj, &level.buriedobjlist); 334. 	break; 335.     case OBJ_ONBILL: 336. 	otmp->nobj = obj->nobj; 337. 	obj->nobj = otmp; 338. 	extract_nobj(obj, &billobjs); 339. 	break; 340.     default: 341. 	panic("replace_object: obj position"); 342. 	break; 343.     }  344.  }  345.   346.  /*  347.   * Create a dummy duplicate to put on shop bill. The duplicate exists 348.  * only in the billobjs chain. This function is used when a shop object 349.  * is being altered, and a copy of the original is needed for billing 350.  * purposes. For example, when eating, where an interruption will yield 351.  * an object which is different from what it started out as; the "I x"  352. * command needs to display the original object. 353.  *  354.   * The caller is responsible for checking otmp->unpaid and 355.  * costly_spot(u.ux, u.uy). This function will make otmp no charge. 356.  *  357.   * Note that check_unpaid_usage should be used instead for partial 358.  * usage of an object. 359.  */  360.  void 361. bill_dummy_object(otmp) 362. register struct obj *otmp; 363. {  364.  	register struct obj *dummy, *obj; 365.  366.  	if (otmp->unpaid) 367. 	    subfrombill(otmp, shop_keeper(*u.ushops)); 368. 	dummy = newobj(otmp->oxlth + otmp->onamelth); 369. 	*dummy = *otmp; 370. 	if (Has_contents(otmp)) { 371. 	    for(obj = otmp->cobj; obj; obj = obj->nobj) 372. 		bill_dummy_object(obj); 373. 	    dummy->cobj = NULL; 374. 	}  375.  	dummy->where = OBJ_FREE; 376. 	dummy->o_id = flags.ident++; 377. 	if (!dummy->o_id) dummy->o_id = flags.ident++;	/* ident overflowed */ 378. 	dummy->timed = 0; 379. 	if (otmp->oxlth) 380. 	    (void)memcpy((genericptr_t)dummy->oextra,  381.  			(genericptr_t)otmp->oextra, otmp->oxlth); 382. 	if (otmp->onamelth) 383. 	    (void)strncpy(ONAME(dummy), ONAME(otmp), (int)otmp->onamelth); 384. 	if (Is_candle(dummy)) dummy->lamplit = 0; 385. 	addtobill(dummy, FALSE, TRUE, TRUE); 386. 	if (otmp->where != OBJ_INVENT) 387. 	    otmp->no_charge = 1; 388. 	otmp->unpaid = 0; 389. 	return; 390. }  391.   392.  #endif /* OVL1 */ 393. #ifdef OVLB 394.  395.  static const char dknowns[] = { 396. 		WAND_CLASS, RING_CLASS, POTION_CLASS, SCROLL_CLASS, 397. 		GEM_CLASS, SPBOOK_CLASS, WEAPON_CLASS, TOOL_CLASS, 0 398. };  399.   400.  struct obj * 401. mksobj(otyp, init, artif) 402. int otyp; 403. boolean init; 404. boolean artif; 405. {  406.  	int mndx, tryct; 407. 	struct obj *otmp; 408. 	char let = objects[otyp].oc_class; 409.  410.  	otmp = newobj(0); 411. 	*otmp = zeroobj; 412. 	otmp->age = monstermoves; 413. 	otmp->o_id = flags.ident++; 414. 	if (!otmp->o_id) otmp->o_id = flags.ident++;	/* ident overflowed */ 415. 	otmp->quan = 1L; 416. 	otmp->oclass = let; 417. 	otmp->otyp = otyp; 418. 	otmp->where = OBJ_FREE; 419. 	otmp->dknown = index(dknowns, let) ? 0 : 1; 420.  	otmp->oinvis = 0; 421. 	otmp->olocked = FALSE; /* ->recharged */ 422. 	otmp->altmode = WP_MODE_AUTO; 423. 	if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||  424.  			otmp->otyp == SHIELD_OF_REFLECTION) 425. 		otmp->dknown = 0; 426. 	if (!objects[otmp->otyp].oc_uses_known) 427. 		otmp->known = 1; 428. #ifdef INVISIBLE_OBJECTS 429. 	otmp->oinvis = !always_visible(otmp) && \ 430. 		(otmp->otyp != BOULDER || !In_sokoban(&u.uz)) && !rn2(1250); 431. #endif 432. 	if (init) switch (let) { 433. /* ---============STEPHEN WHITE'S NEW CODE============--- */ 434. 	case WEAPON_CLASS: 435. 		/* KMH, balance patch -- new macros */ 436. 		otmp->quan = is_multigen(otmp) ? (long) rn1(6,6) : 1L; 437. 		if(!rn2(11)) { 438. 			otmp->spe = rne(3); 439. 			otmp->blessed = rn2(2); 440. 		} else if(!rn2(10)) { 441. 			curse(otmp); 442. 			otmp->spe = -rne(3); 443. 		} else	blessorcurse(otmp, 10); 444. 		if (is_poisonable(otmp) && !rn2(100)) 445. 			otmp->opoisoned = 1; 446. 		if (artif && !rn2(20)) 447. 		    otmp = mk_artifact(otmp, (aligntyp)A_NONE); 448. #ifdef FIREARMS 449. 		if (otmp->otyp == STICK_OF_DYNAMITE) { 450. 			otmp->age = (otmp->cursed ? rn2(15) + 2 :  451.  					(otmp->blessed ? 15 : rn2(10) + 10)); 452. 		}  453.  #endif 454. 		break; 455. 	case FOOD_CLASS: 456. 	    otmp->odrained = 0; 457. 	    otmp->oeaten = 0; 458. 	    switch(otmp->otyp) { 459. 	    case CORPSE: 460. 		/* possibly overridden by mkcorpstat */ 461. 		tryct = 50; 462. 		do otmp->corpsenm = undead_to_corpse(rndmonnum); 463. 		while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0)); 464. 		if (tryct == 0) { 465. 		/* perhaps rndmonnum only wants to make G_NOCORPSE monsters on  466. this level; let's create an adventurer's corpse instead, then */ 467. 			otmp->corpsenm = PM_HUMAN; 468. 		}  469.  		/* timer set below */ 470. 		break; 471. 	    case EGG: 472. 		otmp->corpsenm = NON_PM;	/* generic egg */ 473. 		if (!rn2(3)) for (tryct = 200; tryct > 0; --tryct) { 474. 		    mndx = can_be_hatched(rndmonnum); 475. 		    if (mndx != NON_PM && !dead_species(mndx, TRUE)) { 476. 			otmp->corpsenm = mndx;		/* typed egg */ 477. 			attach_egg_hatch_timeout(otmp); 478. 			break; 479. 		    }  480.  		}  481.  		break; 482. 	    case TIN: 483. 		otmp->corpsenm = NON_PM;	/* empty (so far) */ 484. 		if (!rn2(6)) 485. 		    otmp->spe = 1;		/* spinach */ 486. 		else for (tryct = 200; tryct > 0; --tryct) { 487. 		    mndx = undead_to_corpse(rndmonnum); 488. 		    if (mons[mndx].cnutrit &&  489.  			    !(mvitals[mndx].mvflags & G_NOCORPSE)) { 490. 			otmp->corpsenm = mndx; 491. 			break; 492. 		    }  493.  		}  494.  		blessorcurse(otmp, 10); 495. 		break; 496. 	    case SLIME_MOLD: 497. 		otmp->spe = current_fruit; 498. 		break; 499. 	    case KELP_FROND: 500. 		otmp->quan = (long) rnd(2); 501. 		break; 502. 	    }  503.  	    if (otmp->otyp == CORPSE || otmp->otyp == MEAT_RING ||  504.  		otmp->otyp == KELP_FROND) break; 505. 	    /* fall into next case */ 506.  507.  /* ---============STEPHEN WHITE'S NEW CODE============--- */ 508. 	case GEM_CLASS: 509. 		/* KMH, balance patch -- healthstone replaces rotting/health */ 510. 		if (otmp->otyp == LOADSTONE || otmp->otyp == HEALTHSTONE) 511. 			curse(otmp); 512. 		else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6); 513. 		else if ((otmp->otyp != LUCKSTONE) && (otmp->otyp != HEALTHSTONE) &&  514.  				!rn2(6)) otmp->quan = 2L; 515. 		else otmp->quan = 1L; 516. 		break; 517. /* ---============STEPHEN WHITE'S NEW CODE============--- */ 518. 	case TOOL_CLASS: 519. 	    switch(otmp->otyp) { 520. 		case TALLOW_CANDLE: 521. 		case WAX_CANDLE: 522. 			otmp->spe = 1; 523. 					otmp->age = 20L * /* 400 or 200 */ 524. 					      (long)objects[otmp->otyp].oc_cost; 525. 					otmp->lamplit = 0; 526. 					otmp->quan = 1L + 527. 					      (long)(rn2(2) ? rn2(7) : 0); 528. 					blessorcurse(otmp, 5); 529. 					break; 530. 	        case TORCH:	        otmp->spe = 0; 531. 					otmp->age = (long) rn1(300,600); 532. 					otmp->lamplit = 0; 533. 					otmp->quan = rnd(3); 534. 					blessorcurse(otmp, 5); 535. 					break; 536. 		case BRASS_LANTERN: 537. 		case OIL_LAMP: 538. 			otmp->spe = 1; 539. 					otmp->age = (long) rn1(500,1000); 540. 					otmp->lamplit = 0; 541. 					blessorcurse(otmp, 5); 542. 					break; 543. 		case MAGIC_CANDLE: 544. 		case MAGIC_LAMP: 545. 			otmp->spe = 1; 546. 					otmp->lamplit = 0; 547. 					blessorcurse(otmp, 2); 548. 					break; 549. #ifdef LIGHTSABERS 550. 		case RED_DOUBLE_LIGHTSABER: 551. 					otmp->altmode = FALSE; 552. 		case GREEN_LIGHTSABER: 553. #ifdef D_SABER 554. 		case BLUE_LIGHTSABER: 555. #endif 556. 		case RED_LIGHTSABER: 557. 					otmp->lamplit = 0; 558. 					otmp->age = (long) rn1(500,1000); 559. 					blessorcurse(otmp, 2); 560. 					break; 561. #endif 562. 		case CHEST: 563. 		case LARGE_BOX: 564. 			otmp->olocked = !!(rn2(5)); 565. 					otmp->otrapped = !(rn2(10)); 566. 		case ICE_BOX: 567. 		case SACK: 568. 		case OILSKIN_SACK: 569. 		case BAG_OF_HOLDING: 570. 		case MEDICAL_KIT: 571. 			mkbox_cnts(otmp); 572. 					break; 573. #ifdef TOURIST 574. 		case EXPENSIVE_CAMERA: 575. #endif 576. 		case TINNING_KIT: 577. 		case MAGIC_MARKER: 578. 			otmp->spe = rn1(70,30); 579. 					break; 580. 		case CAN_OF_GREASE: 581. 			otmp->spe = rn1(25,10); 582. 					blessorcurse(otmp, 10); 583. 					break; 584. 		/* KMH, balance patch -- removed to prevent abuse 585. 		case ORB_OF_DESTRUCTION:blessorcurse(otmp, 2); 586. 					break; 587. 		case ORB_OF_CHARGING:   otmp->spe = rnd(10) + 5; 588. 					blessorcurse(otmp, 2); 589. 					break; 590. 		case ORB_OF_ENCHANTMENT:otmp->spe = rnd(3) + 1; 591. 					blessorcurse(otmp, 2); 592. 					break;*/ 593. 		case CRYSTAL_BALL: 594. 			otmp->spe = rn1(10,3); 595. 					blessorcurse(otmp, 2); 596. 					break; 597. 		case HORN_OF_PLENTY: 598. 		case BAG_OF_TRICKS: 599. 			otmp->spe = rn1(20,10); 600. 					break; 601. 		case FIGURINE:	{	int tryct2 = 0; 602. 					do 603. 					    otmp->corpsenm = rndmonnum; 604. 					while(is_human(&mons[otmp->corpsenm])  605.  						&& tryct2++ < 30); 606. 					blessorcurse(otmp, 4); 607. 					break; 608. 				}  609.  		case BELL_OF_OPENING: 610. 			otmp->spe = 3; 611. 					break; 612. 		case MAGIC_FLUTE: 613. 		case MAGIC_HARP: 614. 		case FROST_HORN: 615. 		case FIRE_HORN: 616. 		case DRUM_OF_EARTHQUAKE: 617. 		/* KMH, balance patch -- removed 618. 		case PAN_PIPE_OF_SUMMONING: 619. 		case PAN_PIPE_OF_THE_SEWERS: */ 620. 			otmp->spe = rn1(5,10); 621. 					break; 622. 	    }  623.  	    break; 624. 	case AMULET_CLASS: 625. 		if (otmp->otyp == AMULET_OF_YENDOR) flags.made_amulet = TRUE; 626. 		if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION || 627. 		   otmp->otyp == AMULET_OF_CHANGE || 628. 		   otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) { 629. 			curse(otmp); 630. 		} else	blessorcurse(otmp, 10); 631. 	case VENOM_CLASS: 632. 	case CHAIN_CLASS: 633. 	case BALL_CLASS: 634. 		break; 635. 	case POTION_CLASS: 636. 		if (otmp->otyp == POT_OIL) 637. 		    otmp->age = MAX_OIL_IN_FLASK;	/* amount of oil */ 638. 		/* fall through */ 639. 	case SCROLL_CLASS: 640. #ifdef MAIL 641. 		if (otmp->otyp != SCR_MAIL) 642. #endif 643. 			blessorcurse(otmp, 4); 644. 		break; 645. 	case SPBOOK_CLASS: 646. 		/* WAC charged books are easier to read */ 647. 		if (otmp->otyp != SPE_BOOK_OF_THE_DEAD) otmp->spe = rn1(3,2); 648. 		blessorcurse(otmp, 17); 649. 		break; 650. /* ---============STEPHEN WHITE'S NEW CODE============--- */ 651. 	case ARMOR_CLASS: 652. 		if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS || 653. 		   otmp->otyp == LEVITATION_BOOTS || 654. 		   otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT || 655. 		   otmp->otyp == GAUNTLETS_OF_FUMBLING || 656. 		   otmp->otyp == ROBE_OF_WEAKNESS || 657. 		   !rn2(11))) { 658. 			curse(otmp); 659. 			otmp->spe = -rne(3); 660. 		} else if(!rn2(10)) { 661. 			otmp->blessed = rn2(2); 662. 			otmp->spe = rne(3); 663. 		} else	blessorcurse(otmp, 10); 664. 		if (artif && !rn2(40)) 665. 		    otmp = mk_artifact(otmp, (aligntyp)A_NONE); 666. 		/* simulate lacquered armor for samurai */ 667. 		if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL &&  668.  		    (moves <= 1 || In_quest(&u.uz))) { 669. #ifdef UNIXPC 670. 			/* optimizer bitfield bug */ 671. 			otmp->oerodeproof = 1; 672. 			otmp->rknown = 1; 673. #else 674. 			otmp->oerodeproof = otmp->rknown = 1; 675. #endif 676. 		}  677.  		break; 678. /* ---============STEPHEN WHITE'S NEW CODE============--- */ 679. 	case WAND_CLASS: 680. 		if(otmp->otyp == WAN_WISHING) { 681. 			otmp->spe = rnd(3); 682. #ifdef INVISIBLE_OBJECTS 683. 			if (Is_stronghold(&u.uz)) otmp->oinvis = 1; 684. #endif 685. 			if(!rn2(2)) otmp->recharged = 1; 686. 		} else otmp->spe = rn1(5,  687.  			(objects[otmp->otyp].oc_dir == NODIR) ? 15 : 8); 688. 		blessorcurse(otmp, 17); 689. 		otmp->recharged = 0; /* used to control recharging */ 690. 		break; 691. 	case RING_CLASS: 692. 		if(objects[otmp->otyp].oc_charged) { 693. 		    blessorcurse(otmp, 3); 694. 		    if(rn2(10)) { 695. 			if(rn2(10) && bcsign(otmp)) 696. 			    otmp->spe = bcsign(otmp) * rne(3); 697. 			else otmp->spe = rn2(2) ? rne(3) : -rne(3); 698. 		    }  699.  		    /* make useless +0 rings much less common */ 700. 		    if (otmp->spe == 0) { 701. /*                     otmp->spe = rn2(4) - rn2(3); */ 702. 		       /* wow! +8! */ 703.  		       if (rn2(2)) otmp->spe = rne(8)+1; 704. 		       else otmp->spe = -(rne(8)+1); 705. 		    }  706.  		    /* negative rings are usually cursed */ 707. 		    if (otmp->spe < 0 && rn2(5)) curse(otmp); 708. 		} else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION || 709. 			  otmp->otyp == RIN_POLYMORPH || 710. 			  otmp->otyp == RIN_AGGRAVATE_MONSTER || 711. 			  otmp->otyp == RIN_SLEEPING || 712. 			  otmp->otyp == RIN_HUNGER || !rn2(9))) { 713. 			curse(otmp); 714. 		}  715.  		break; 716. 	case ROCK_CLASS: 717. 		switch (otmp->otyp) { 718. 		    case STATUE: 719. 			/* possibly overridden by mkcorpstat */ 720. 			otmp->corpsenm = rndmonnum; 721. 			if (!verysmall(&mons[otmp->corpsenm]) &&  722.  				rn2(level_difficulty/2 + 10) > 10) 723. 			    (void) add_to_container(otmp,  724.  						    mkobj(SPBOOK_CLASS,FALSE)); 725. 		}  726.  		break; 727. 	case COIN_CLASS: 728. 		break;	/* do nothing */ 729. 	default: 730. 		impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,  731.  						objects[otmp->otyp].oc_class); 732. 		return (struct obj *)0; 733. 	}  734.   735.  	/* Some things must get done (timers) even if init = 0 */ 736. 	switch (otmp->otyp) { 737. 	    case CORPSE: 738. 		start_corpse_timeout(otmp); 739. 		break; 740. 	}  741.   742.  	/* unique objects may have an associated artifact entry */ 743. 	if (objects[otyp].oc_unique && !otmp->oartifact) 744. 	    otmp = mk_artifact(otmp, (aligntyp)A_NONE); 745. 	otmp->owt = weight(otmp); 746. 	return(otmp); 747. }  748.   749.  /*  750.   * Start a corpse decay or revive timer. 751.  * This takes the age of the corpse into consideration as of 3.4.0. 752.  */  753.  void 754. start_corpse_timeout(body) 755. 	struct obj *body; 756. {  757.  	long when; 		/* rot away when this old */ 758. 	long corpse_age;	/* age of corpse          */ 759. 	int rot_adjust; 760. 	short action; 761.  762.  #define TAINT_AGE (50L)		/* age when corpses go bad */ 763. #define TROLL_REVIVE_CHANCE 37	/* 1/37 chance for 50 turns ~ 75% chance */ 764. #define MOLD_REVIVE_CHANCE 23	/*  1/23 chance for 50 turns ~ 90% chance */ 765. #define MOLDY_CHANCE 290	/*  1/290 chance for 200 turns ~ 50% chance */ 766. #define ROT_AGE (250L)		/* age when corpses rot away */ 767.  768.  	/* lizards and lichen don't rot or revive */ 769. 	if (body->corpsenm == PM_LIZARD || body->corpsenm == PM_LICHEN) return; 770.  771.  	action = ROT_CORPSE;		/* default action: rot away */ 772. 	rot_adjust = in_mklev ? 25 : 10;	/* give some variation */ 773. 	corpse_age = monstermoves - body->age; 774. 	if (corpse_age > ROT_AGE) 775. 		when = rot_adjust; 776. 	else 777. 		when = ROT_AGE - corpse_age; 778. 	when += (long)(rnz(rot_adjust) - rot_adjust); 779.  780.  	if (is_rider(&mons[body->corpsenm])) { 781. 		/*  782.  		 * Riders always revive. They have a 1/3 chance per turn 783. 		 * of reviving after 12 turns. Always revive by 500. 784. 		 */  785.  		action = REVIVE_MON; 786. 		for (when = 12L; when < 500L; when++) 787. 		    if (!rn2(3)) break; 788.  789.  	} else if (mons[body->corpsenm].mlet == S_TROLL && !body->norevive) { 790. 		long age; 791. 		for (age = 2; age <= TAINT_AGE; age++) 792. 		    if (!rn2(TROLL_REVIVE_CHANCE)) {	/* troll revives */ 793. 			action = REVIVE_MON; 794. 			when = age; 795. 			break; 796. 		    }  797.  	} else if (mons[body->corpsenm].mlet == S_FUNGUS) { 798. 		/* Fungi come back with a vengeance - if you don't eat it or  799. * destroy it, any live cells will quickly use the dead ones 800. 		 * as food and come back. 801. 		 */  802.  		long age; 803. 		for (age = 2; age <= TAINT_AGE; age++) 804. 		    if (!rn2(MOLD_REVIVE_CHANCE)) {    /* mold revives */ 805. 			action = REVIVE_MON; 806. 			when = age; 807. 			break; 808. 		    }  809.  	}  810.  	  811.  	if (action == ROT_CORPSE && !acidic(&mons[body->corpsenm])) { 812. 		/* Corpses get moldy 813. 		 */  814.  		long age; 815. 		for (age = TAINT_AGE + 1; age <= ROT_AGE; age++) 816. 		    if (!rn2(MOLDY_CHANCE)) {    /* "revives" as a random s_fungus */ 817. 			action = MOLDY_CORPSE; 818. 			when = age; 819. 			break; 820. 		    }  821.  	}  822.  	  823.  	if (body->norevive) body->norevive = 0; 824. 	(void) start_timer(when, TIMER_OBJECT, action, (genericptr_t)body); 825. }  826.   827.  void 828. bless(otmp) 829. register struct obj *otmp; 830. {  831.  #ifdef GOLDOBJ 832. 	if (otmp->oclass == COIN_CLASS) return; 833. #endif 834. 	otmp->cursed = 0; 835. 	otmp->blessed = 1; 836. 	if (carried(otmp) && confers_luck(otmp)) 837. 	    set_moreluck; 838. 	else if (otmp->otyp == HEALTHSTONE) 839. 	    recalc_health; 840. 	else if (otmp->otyp == BAG_OF_HOLDING) 841. 	    otmp->owt = weight(otmp); 842. 	else if (otmp->otyp == FIGURINE && otmp->timed) 843. 	    (void) stop_timer(FIG_TRANSFORM, (genericptr_t) otmp); 844. 	return; 845. }  846.   847.  void 848. unbless(otmp) 849. register struct obj *otmp; 850. {  851.  	otmp->blessed = 0; 852. 	if (carried(otmp) && confers_luck(otmp)) 853. 	    set_moreluck; 854. 	else if (otmp->otyp == HEALTHSTONE) 855. 	    recalc_health; 856. 	else if (otmp->otyp == BAG_OF_HOLDING) 857. 	    otmp->owt = weight(otmp); 858. 	else if (otmp->otyp == FIGURINE && otmp->timed) 859. 	    (void) stop_timer(FIG_TRANSFORM, (genericptr_t) otmp); 860. 	return; 861. }  862.   863.  void 864. curse(otmp) 865. register struct obj *otmp; 866. {  867.  #ifdef GOLDOBJ 868. 	if (otmp->oclass == COIN_CLASS) return; 869. #endif 870. 	otmp->blessed = 0; 871. 	otmp->cursed = 1; 872. 	/* welded two-handed weapon interferes with some armor removal */ 873. 	if (otmp == uwep && bimanual(uwep)) reset_remarm; 874. 	/* rules at top of wield.c state that twoweapon cannot be done 875. 	   with cursed alternate weapon */ 876. 	if (otmp == uswapwep && u.twoweap) 877. 	    drop_uswapwep; 878. 	/* some cursed items need immediate updating */ 879. 	if (carried(otmp) && confers_luck(otmp)) 880. 	    set_moreluck; 881. 	else if (otmp->otyp == HEALTHSTONE) 882. 	    recalc_health; 883. 	else if (otmp->otyp == BAG_OF_HOLDING) 884. 	    otmp->owt = weight(otmp); 885. 	else if (otmp->otyp == FIGURINE) { 886. 		if (otmp->corpsenm != NON_PM  887.  		    && !dead_species(otmp->corpsenm,TRUE)  888.  		    && (carried(otmp) || mcarried(otmp))) 889. 			attach_fig_transform_timeout(otmp); 890. 	}  891.  	return; 892. }  893.   894.  void 895. uncurse(otmp) 896. register struct obj *otmp; 897. {  898.  	otmp->cursed = 0; 899. 	if (carried(otmp) && confers_luck(otmp)) 900. 	    set_moreluck; 901. 	/* KMH, balance patch -- healthstones affect healing */ 902. 	else if (otmp->otyp == HEALTHSTONE) 903. 	    recalc_health; 904. 	else if (otmp->otyp == BAG_OF_HOLDING) 905. 	    otmp->owt = weight(otmp); 906. }  907.   908.  #endif /* OVLB */ 909. #ifdef OVL1 910.  911.  void 912. blessorcurse(otmp, chance) 913. register struct obj *otmp; 914. register int chance; 915. {  916.  	if(otmp->blessed || otmp->cursed) return; 917.  918.  	if(!rn2(chance)) { 919. 	    if(!rn2(2)) { 920. 		curse(otmp); 921. 	    } else { 922. 		bless(otmp); 923. 	    }  924.  	}  925.  	return; 926. }  927.   928.  #endif /* OVL1 */ 929. #ifdef OVLB 930.  931.  int 932. bcsign(otmp) 933. register struct obj *otmp; 934. {  935.  	return(!!otmp->blessed - !!otmp->cursed); 936. }  937.   938.  #endif /* OVLB */ 939. #ifdef OVL0 940.  941.  /*  942.   *  Calculate the weight of the given object. This will recursively follow 943.  *  and calculate the weight of any containers. 944.  *  945.   *  Note:  It is possible to end up with an incorrect weight if some part 946.  *	   of the code messes with a contained object and doesn't update the 947.  *	   container's weight. 948.  */  949.  int 950. weight(obj) 951. register struct obj *obj; 952. {  953.  	int wt = objects[obj->otyp].oc_weight; 954.  955.  	if (obj->otyp == LARGE_BOX && obj->spe == 1) /* Schroedinger's Cat */ 956. 		wt += mons[PM_HOUSECAT].cwt; 957. 	if (Is_container(obj) || obj->otyp == STATUE) { 958. 		struct obj *contents; 959. 		register int cwt = 0; 960.  961.  		if (obj->otyp == STATUE && obj->corpsenm >= LOW_PM) 962. 		    wt = (int)obj->quan * 963. 			 ((int)mons[obj->corpsenm].cwt * 3 / 2); 964.  965.  		for(contents=obj->cobj; contents; contents=contents->nobj) 966. 			cwt += weight(contents); 967. 		/* KMH -- support artifact BoH (including the Wallet of Perseus) 968. 		 *  969.  		 *  The weight of bags of holding is calculated as the weight 970. 		 *  of the bag plus the weight of the bag's contents modified 971. 		 *  as follows: 972. 		 *  973.  		 *      Bag status    Ordinary    Artifact 974. 		 *      --         975.  		 *      cursed          2x           4x 976. 		 *      blessed       (x + 3)/4   (x + 5)/6 977. 		 *      otherwise     (x + 1)/2   (x + 2)/3 978. 		 *  979.  		 *  The macro DELTA_CWT in pickup.c also implements these 980. 		 *  weight equations. 981. 		 *  982.  		 *  Note:  The above checks are performed in the given order. 983. 		 *	   this means that if an object is both blessed and 984. 		 *	   cursed (not supposed to happen), it will be treated 985. 		 *	   as cursed. 986. 		 */  987.  #define CEILDIV(x,y)	(((x)+(y)-1)/(y))	/* ceil(x/y) */ 988. 		if (obj->otyp == BAG_OF_HOLDING) 989. 			cwt = obj->cursed ? (cwt * (obj->oartifact ? 4 : 2)) : 990.  				CEILDIV(cwt, (obj->oartifact ? 3 : 2) * (obj->blessed ? 2 : 1)); 991.  #undef CEILDIV 992. 		return wt + cwt; 993. 	}  994.  	if (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM) { 995. 		long long_wt = (int)obj->quan * mons[obj->corpsenm].cwt; 996.  997.  		wt = (long_wt > LARGEST_INT) ? LARGEST_INT : (int)long_wt; 998. 		if (obj->oeaten) wt = eaten_stat(wt, obj); 999. 		return wt; 1000. 	} else if (obj->oclass == FOOD_CLASS && obj->oeaten) { 1001. 		return eaten_stat((int)obj->quan * wt, obj); 1002. 	} else if (obj->oclass == COIN_CLASS) 1003. 		return (int)((obj->quan + 50L) / 100L); 1004. 	else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0) 1005. 		return((int)(obj->owt));	/* kludge for "very" heavy iron ball */ 1006. 	return(wt ? wt*(int)obj->quan : ((int)obj->quan + 1)>>1); 1007. } 1008.  1009. static int treefruits[] = {APPLE,ORANGE,PEAR,BANANA,EUCALYPTUS_LEAF}; 1010. 1011. struct obj * 1012. rnd_treefruit_at(x,y) 1013. int x, y; 1014. { 1015. 	return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE); 1016. } 1017. #endif /* OVL0 */ 1018. #ifdef OVLB 1019. 1020. struct obj * 1021. mkgold(amount, x, y) 1022. long amount; 1023. int x, y; 1024. { 1025.     register struct obj *gold = g_at(x,y); 1026. 1027.     if (amount <= 0L) 1028. 	amount = (long)(1 + rnd(level_difficulty+2) * rnd(30)); 1029.    if (gold) { 1030. 	gold->quan += amount; 1031.    } else { 1032. 	gold = mksobj_at(GOLD_PIECE, x, y, TRUE, FALSE); 1033. 	gold->quan = amount; 1034.    }  1035.     gold->owt = weight(gold); 1036.    return (gold); 1037. } 1038.  1039. #endif /* OVLB */ 1040. #ifdef OVL1 1041. 1042. /* return TRUE if the corpse has special timing */ 1043. /* special timing is a timing that is not rotting or molding */ 1044. 1045. #define special_corpse(num)  (((num) == PM_LIZARD)		\  1046. 				|| ((num) == PM_LICHEN)		\  1047. 				|| (is_rider(&mons[num]))	\  1048. 				|| (mons[num].mlet == S_FUNGUS) \  1049. 				|| (mons[num].mlet == S_TROLL)) 1050. 1051. /*  1052.  * OEXTRA note: Passing mtmp causes mtraits to be saved 1053. * even if ptr passed as well, but ptr is always used for 1054. * the corpse type (corpsenm). That allows the corpse type 1055. * to be different from the original monster, 1056. *	i.e.  vampire -> human corpse 1057. * yet still allow restoration of the original monster upon 1058. * resurrection. 1059. */  1060. struct obj * 1061. mkcorpstat(objtype, mtmp, ptr, x, y, init) 1062. int objtype;	/* CORPSE or STATUE */ 1063. struct monst *mtmp; 1064. struct permonst *ptr; 1065. int x, y; 1066. boolean init; 1067. { 1068. 	register struct obj *otmp; 1069. 1070. 	if (objtype != CORPSE && objtype != STATUE) 1071. 	   impossible("making corpstat type %d", objtype); 1072. 	if (x == 0 && y == 0) {		/* special case - random placement */ 1073. 		otmp = mksobj(objtype, init, FALSE); 1074. 		if (otmp) rloco(otmp); 1075. 	} else 1076. 		otmp = mksobj_at(objtype, x, y, init, FALSE); 1077. 	if (otmp) { 1078. 	   if (mtmp) { 1079. 		struct obj *otmp2; 1080. 1081. 		if (!ptr) ptr = mtmp->data; 1082. 		/* save_mtraits frees original data pointed to by otmp */ 1083. 		otmp2 = save_mtraits(otmp, mtmp); 1084. 		if (otmp2) otmp = otmp2; 1085. 	   }  1086. 	    /* use the corpse or statue produced by mksobj as-is 1087. 	      unless `ptr' is non-null */ 1088. 	   if (ptr) { 1089. 		int old_corpsenm = otmp->corpsenm; 1090. 1091. 		otmp->corpsenm = monsndx(ptr); 1092. 		otmp->owt = weight(otmp); 1093. 		if (otmp->otyp == CORPSE && 1094. 			(special_corpse(old_corpsenm) || 1095. 				special_corpse(otmp->corpsenm))) { 1096. 		   obj_stop_timers(otmp); 1097. 		   start_corpse_timeout(otmp); 1098. 		} 1099. 	    }  1100. 	}  1101. 	return(otmp); 1102. } 1103.  1104. /*  1105.  * Attach a monster id to an object, to provide 1106. * a lasting association between the two. 1107. */  1108. struct obj * 1109. obj_attach_mid(obj, mid) 1110. struct obj *obj; 1111. unsigned mid; 1112. { 1113.     struct obj *otmp; 1114.    int lth, namelth; 1115. 1116.     if (!mid || !obj) return (struct obj *)0; 1117.    lth = sizeof(mid); 1118.    namelth = obj->onamelth ? strlen(ONAME(obj)) + 1 : 0; 1119.    if (namelth) 1120. 	otmp = realloc_obj(obj, lth, (genericptr_t) &mid, namelth, ONAME(obj)); 1121.    else { 1122. 	otmp = obj; 1123. 	otmp->oxlth = sizeof(mid); 1124. 	(void) memcpy((genericptr_t)otmp->oextra, (genericptr_t)&mid, 1125. 								sizeof(mid)); 1126.    }  1127.     if (otmp && otmp->oxlth) otmp->oattached = OATTACHED_M_ID;	/* mark it */ 1128.    return otmp; 1129. } 1130.  1131. static struct obj * 1132. save_mtraits(obj, mtmp) 1133. struct obj *obj; 1134. struct monst *mtmp; 1135. { 1136. 	struct obj *otmp; 1137. 	int lth, namelth; 1138. 1139. 	lth = sizeof(struct monst) + mtmp->mxlth + mtmp->mnamelth; 1140. 	namelth = obj->onamelth ? strlen(ONAME(obj)) + 1 : 0; 1141. 	otmp = realloc_obj(obj, lth, (genericptr_t) mtmp, namelth, ONAME(obj)); 1142. 	if (otmp && otmp->oxlth) { 1143. 		struct monst *mtmp2 = (struct monst *)otmp->oextra; 1144. 		if (mtmp->data) mtmp2->mnum = monsndx(mtmp->data); 1145. 		/* invalidate pointers */ 1146. 		/* m_id is needed to know if this is a revived quest leader */ 1147. 		/* but m_id must be cleared when loading bones */ 1148. 		mtmp2->nmon    = (struct monst *)0; 1149. 		mtmp2->data    = (struct permonst *)0; 1150. 		mtmp2->minvent = (struct obj *)0; 1151. 		otmp->oattached = OATTACHED_MONST;	/* mark it */ 1152. 	} 1153. 	return otmp; 1154. } 1155.  1156. /* returns a pointer to a new monst structure based on  1157. * the one contained within the obj. 1158. */  1159. struct monst * 1160. get_mtraits(obj, copyof) 1161. struct obj *obj; 1162. boolean copyof; 1163. { 1164. 	struct monst *mtmp = (struct monst *)0; 1165. 	struct monst *mnew = (struct monst *)0; 1166. 1167. 	if (obj->oxlth && obj->oattached == OATTACHED_MONST) 1168. 		mtmp = (struct monst *)obj->oextra; 1169. 	if (mtmp) { 1170. 	   if (copyof) { 1171. 		int lth = mtmp->mxlth + mtmp->mnamelth; 1172. 		mnew = newmonst(lth); 1173. 		lth += sizeof(struct monst); 1174. 		(void) memcpy((genericptr_t)mnew, 1175. 				(genericptr_t)mtmp, lth); 1176. 	   } else { 1177. 	     /* Never insert this returned pointer into mon chains! */ 1178. 	    	mnew = mtmp; 1179. 	   }  1180. }  1181. 	return mnew; 1182. } 1183.  1184. #endif /* OVL1 */ 1185. #ifdef OVLB 1186. 1187. /* make an object named after someone listed in the scoreboard file */ 1188. struct obj * 1189. mk_tt_object(objtype, x, y) 1190. int objtype; /* CORPSE or STATUE */ 1191. register int x, y; 1192. { 1193. 	register struct obj *otmp, *otmp2; 1194. 	boolean initialize_it; 1195. 1196. 	/* player statues never contain books */ 1197. 	initialize_it = (objtype != STATUE); 1198. 	if ((otmp = mksobj_at(objtype, x, y, initialize_it, FALSE)) != 0) { 1199. 	   /* tt_oname will return null if the scoreboard is empty */ 1200. 	   if ((otmp2 = tt_oname(otmp)) != 0) otmp = otmp2; 1201. 	} 1202. 	return(otmp); 1203. } 1204.  1205. /* make a new corpse or statue, uninitialized if a statue (i.e. no books) */ 1206. struct obj * 1207. mk_named_object(objtype, ptr, x, y, nm) 1208. int objtype;	/* CORPSE or STATUE */ 1209. struct permonst *ptr; 1210. int x, y; 1211. const char *nm; 1212. { 1213. 	struct obj *otmp; 1214. 1215. 	otmp = mkcorpstat(objtype, (struct monst *)0, ptr,  1216. 				x, y, (boolean)(objtype != STATUE)); 1217. 	if (nm) 1218. 		otmp = oname(otmp, nm); 1219. 	return(otmp); 1220. } 1221.  1222. boolean 1223. is_flammable(otmp) 1224. register struct obj *otmp; 1225. { 1226. 	int otyp = otmp->otyp; 1227. 	int omat = objects[otyp].oc_material; 1228. 1229. 	if (objects[otyp].oc_oprop == FIRE_RES || otyp == WAN_FIRE) 1230. 		return FALSE; 1231. 1232. 	return((boolean)((omat <= WOOD && omat != LIQUID) || omat == PLASTIC)); 1233. } 1234.  1235. boolean 1236. is_rottable(otmp) 1237. register struct obj *otmp; 1238. { 1239. 	int otyp = otmp->otyp; 1240. 1241. 	return((boolean)(objects[otyp].oc_material <= WOOD && 1242. 			objects[otyp].oc_material != LIQUID)); 1243. } 1244.  1245. #endif /* OVLB */ 1246. #ifdef OVL1 1247. 1248. /*  1249.  * These routines maintain the single-linked lists headed in level.objects[][] 1250. * and threaded through the nexthere fields in the object-instance structure. 1251. */  1252.  1253. /* put the object at the given location */ 1254. void 1255. place_object(otmp, x, y) 1256. register struct obj *otmp; 1257. int x, y; 1258. { 1259.     register struct obj *otmp2 = level.objects[x][y]; 1260. 1261.     if (otmp->where != OBJ_FREE) 1262. 	panic("place_object: obj not free"); 1263. 1264.     obj_no_longer_held(otmp); 1265.    if (otmp->otyp == BOULDER) block_point(x,y);	/* vision */ 1266. 1267.     /* obj goes under boulders */ 1268.    if (otmp2 && (otmp2->otyp == BOULDER)) { 1269. 	otmp->nexthere = otmp2->nexthere; 1270. 	otmp2->nexthere = otmp; 1271.    } else { 1272. 	otmp->nexthere = otmp2; 1273. 	level.objects[x][y] = otmp; 1274.    }  1275.  1276.     /* set the new object's location */ 1277.    otmp->ox = x;  1278. otmp->oy = y; 1279. 1280.    otmp->where = OBJ_FLOOR; 1281. 1282.     /* add to floor chain */ 1283.    otmp->nobj = fobj; 1284.    fobj = otmp; 1285.    if (otmp->timed) obj_timer_checks(otmp, x, y, 0); 1286. } 1287.  1288. #define ON_ICE(a) ((a)->recharged) 1289. #define ROT_ICE_ADJUSTMENT 2	/* rotting on ice takes 2 times as long */ 1290. 1291. /* If ice was affecting any objects correct that now 1292. * Also used for starting ice effects too. [zap.c] 1293. */ 1294. void 1295. obj_ice_effects(x, y, do_buried) 1296. int x, y; 1297. boolean do_buried; 1298. { 1299. 	struct obj *otmp; 1300. 1301. 	for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) { 1302. 		if (otmp->timed) obj_timer_checks(otmp, x, y, 0); 1303. 	} 1304. 	if (do_buried) { 1305. 	   for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) { 1306. 		if (otmp->ox == x && otmp->oy == y) { 1307. 			if (otmp->timed) obj_timer_checks(otmp, x, y, 0); 1308. 		} 1309. 	    }  1310. 	}  1311. }  1312.  1313. /*  1314.  * Returns an obj->age for a corpse object on ice, that would be the 1315. * actual obj->age if the corpse had just been lifted from the ice. 1316. * This is useful when just using obj->age in a check or calculation because 1317. * rot timers pertaining to the object don't have to be stopped and 1318. * restarted etc. 1319. */  1320. long 1321. peek_at_iced_corpse_age(otmp) 1322. struct obj *otmp; 1323. { 1324.     long age, retval = otmp->age; 1325.     1326.     if (otmp->otyp == CORPSE && ON_ICE(otmp)) { 1327. 	/* Adjust the age; must be same as obj_timer_checks for off ice*/ 1328. 	age = monstermoves - otmp->age; 1329. 	retval = otmp->age + (age / ROT_ICE_ADJUSTMENT); 1330. #ifdef DEBUG_EFFECTS 1331. 	pline_The("%s age has ice modifications:otmp->age = %ld, returning %ld.", 1332. 		s_suffix(doname(otmp)),otmp->age, retval); 1333. 	pline("Effective age of corpse: %ld.", 1334. 		monstermoves - retval); 1335. #endif 1336.    }  1337.     return retval; 1338. } 1339.  1340. STATIC_OVL void 1341. obj_timer_checks(otmp, x, y, force) 1342. struct obj *otmp; 1343. xchar x, y; 1344. int force;	/* 0 = no force so do checks, <0 = force off, >0 force on */ 1345. { 1346.     long tleft = 0L; 1347.    short action = ROT_CORPSE; 1348.    boolean restart_timer = FALSE; 1349.    boolean on_floor = (otmp->where == OBJ_FLOOR); 1350.    boolean buried = (otmp->where == OBJ_BURIED); 1351. 1352.     /* Check for corpses just placed on or in ice */ 1353.    if (otmp->otyp == CORPSE && (on_floor || buried) && is_ice(x,y)) { 1354. 	tleft = stop_timer(action, (genericptr_t)otmp); 1355. 	if (tleft == 0L) { 1356. 	   action = MOLDY_CORPSE; 1357. 	   tleft = stop_timer(action, (genericptr_t)otmp); 1358. 	   if (tleft == 0L) { 1359. 		action = REVIVE_MON; 1360. 		tleft = stop_timer(action, (genericptr_t)otmp); 1361. 	} 1362. 	}  1363. 	if (tleft != 0L) { 1364. 	   long age; 1365. 	    1366. 	    tleft = tleft - monstermoves; 1367. 	   /* mark the corpse as being on ice */ 1368. 	   ON_ICE(otmp) = 1; 1369. #ifdef DEBUG_EFFECTS 1370. 	   pline("%s is now on ice at %d,%d.", The(xname(otmp)),x,y); 1371. #endif 1372. 	   /* Adjust the time remaining */ 1373. 	   tleft *= ROT_ICE_ADJUSTMENT; 1374. 	   restart_timer = TRUE; 1375. 	   /* Adjust the age; must be same as in obj_ice_age */ 1376. 	   age = monstermoves - otmp->age; 1377. 	   otmp->age = monstermoves - (age * ROT_ICE_ADJUSTMENT); 1378. 	} 1379.     }  1380.     /* Check for corpses coming off ice */ 1381.    else if ((force < 0) ||  1382. 	     (otmp->otyp == CORPSE && ON_ICE(otmp) && 1383. 	    ((on_floor && !is_ice(x,y)) || !on_floor))) { 1384. 	tleft = stop_timer(action, (genericptr_t)otmp); 1385. 	if (tleft == 0L) { 1386. 	   action = MOLDY_CORPSE; 1387. 	   tleft = stop_timer(action, (genericptr_t)otmp); 1388. 	   if (tleft == 0L) { 1389. 		action = REVIVE_MON; 1390. 		tleft = stop_timer(action, (genericptr_t)otmp); 1391. 	} 1392. 	}  1393. 	if (tleft != 0L) { 1394. 		long age; 1395. 1396. 		tleft = tleft - monstermoves; 1397. 		ON_ICE(otmp) = 0; 1398. #ifdef DEBUG_EFFECTS 1399. 	   	pline("%s is no longer on ice at %d,%d.", The(xname(otmp)),x,y); 1400. #endif 1401. 		/* Adjust the remaining time */ 1402. 		tleft /= ROT_ICE_ADJUSTMENT; 1403. 		restart_timer = TRUE; 1404. 		/* Adjust the age */ 1405. 		age = monstermoves - otmp->age; 1406. 		otmp->age = otmp->age + (age / ROT_ICE_ADJUSTMENT); 1407. 	} 1408.     }  1409.     /* now re-start the timer with the appropriate modifications */ 1410.    if (restart_timer) 1411. 	(void) start_timer(tleft, TIMER_OBJECT, action, (genericptr_t)otmp); 1412. } 1413.  1414. #undef ON_ICE 1415. #undef ROT_ICE_ADJUSTMENT 1416. 1417. void 1418. remove_object(otmp) 1419. register struct obj *otmp; 1420. { 1421.     xchar x = otmp->ox; 1422.    xchar y = otmp->oy; 1423. 1424.     if (otmp->where != OBJ_FLOOR) 1425. 	panic("remove_object: obj not on floor"); 1426.    if (otmp->otyp == BOULDER) unblock_point(x,y); /* vision */ 1427.    extract_nexthere(otmp, &level.objects[x][y]); 1428.    extract_nobj(otmp, &fobj); 1429.    if (otmp->timed) obj_timer_checks(otmp,x,y,0); 1430. } 1431.  1432. /* throw away all of a monster's inventory */ 1433. void 1434. discard_minvent(mtmp) 1435. struct monst *mtmp; 1436. { 1437.     struct obj *otmp, *curr; 1438. 1439.     while (mtmp->minvent) { 1440. 	/* Move all contained objects out into the monster's main inventory 1441. 	 * so that we can easily check that every object (whether contained 1442. 	 * or not) does not evade destruction. 1443. 	 */ 1444. 	while (Has_contents((otmp = mtmp->minvent))) { 1445. 	   curr = otmp->cobj; 1446. 	   obj_extract_self(curr); 1447. 	   (void) add_to_minv(mtmp, curr); 1448. 	} 1449. 	obj_extract_self(otmp); 1450. 	if (evades_destruction(otmp)) { 1451. 	   impossible("%s discarded from %s inventory",  1452. 	      obj_typename(otmp->otyp), s_suffix(mon_nam(mtmp))); 1453. 	   place_object(otmp, mtmp->mx, mtmp->my); 1454. 	   continue; 1455. 	} 1456. 	obfree(otmp, (struct obj *)0);	/* dealloc_obj isn't sufficient */ 1457.    }  1458. }  1459.  1460. /*  1461.  * Free obj from whatever list it is on in preperation of deleting it or  1462. * moving it elsewhere. This will perform all high-level consequences 1463. * involved with removing the item. E.g. if the object is in the hero's 1464. * inventory and confers heat resistance, the hero will lose it. 1465. *  1466.  * Object positions: 1467. *	OBJ_FREE	not on any list 1468. *	OBJ_FLOOR	fobj, level.locations[][] chains (use remove_object) 1469. *	OBJ_CONTAINED	cobj chain of container object 1470. *	OBJ_INVENT	hero's invent chain (use freeinv) 1471. *	OBJ_MINVENT	monster's invent chain 1472. *	OBJ_MIGRATING	migrating chain 1473. *	OBJ_BURIED	level.buriedobjs chain 1474. *	OBJ_ONBILL	on billobjs chain 1475. */  1476. void 1477. obj_extract_self(obj) 1478.    struct obj *obj; 1479. { 1480.     switch (obj->where) { 1481. 	case OBJ_FREE: 1482. 	   break; 1483. 	case OBJ_FLOOR: 1484. 	   remove_object(obj); 1485. 	   break; 1486. 	case OBJ_CONTAINED: 1487. 	   extract_nobj(obj, &obj->ocontainer->cobj); 1488. 	   container_weight(obj->ocontainer); 1489. 	   break; 1490. 	case OBJ_INVENT: 1491. 	   freeinv(obj); 1492. 	   break; 1493. 	case OBJ_MINVENT: 1494. 	   extract_nobj(obj, &obj->ocarry->minvent); 1495. 	   break; 1496. 	case OBJ_MIGRATING: 1497. 	   extract_nobj(obj, &migrating_objs); 1498. 	   break; 1499. 	case OBJ_BURIED: 1500. 	   extract_nobj(obj, &level.buriedobjlist); 1501. 	   break; 1502. 	case OBJ_ONBILL: 1503. 	   extract_nobj(obj, &billobjs); 1504. 	   break; 1505. 	default: 1506. 	   panic("obj_extract_self"); 1507. 	   break; 1508.    }  1509. }  1510.  1511. /* Extract a contained indestructable object (if one exists) and return it */ 1512. struct obj * 1513. container_extract_indestructable(struct obj *obj) 1514. { 1515.     struct obj *otmp = obj->cobj, *indestructable = (struct obj *)0; 1516.    while (!indestructable && otmp) { 1517. 	if (Has_contents(otmp)) 1518. 	   indestructable = container_extract_indestructable(otmp); 1519. 	if (!indestructable && evades_destruction(otmp)) { 1520. 	   indestructable = otmp; 1521. 	   obj_extract_self(indestructable); 1522. 	} 1523. 	otmp = otmp->nobj; 1524.    }  1525.     return indestructable; 1526. } 1527.  1528. /* Extract the given object from the chain, following nobj chain. */ 1529. void 1530. extract_nobj(obj, head_ptr) 1531.    struct obj *obj, **head_ptr; 1532. { 1533.     struct obj *curr, *prev; 1534. 1535.     curr = *head_ptr; 1536.    for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nobj) { 1537. 	if (curr == obj) { 1538. 	   if (prev) 1539. 		prev->nobj = curr->nobj; 1540. 	   else 1541. 		*head_ptr = curr->nobj; 1542. 	   break; 1543. 	} 1544.     }  1545.     if (!curr) panic("extract_nobj: object lost"); 1546.    obj->where = OBJ_FREE; 1547. } 1548.  1549.  1550. /*  1551.  * Extract the given object from the chain, following nexthere chain. 1552. *  1553.  * This does not set obj->where, this function is expected to be called 1554. * in tandem with extract_nobj, which does set it. 1555. */  1556. void 1557. extract_nexthere(obj, head_ptr) 1558.    struct obj *obj, **head_ptr; 1559. { 1560.     struct obj *curr, *prev; 1561. 1562.     curr = *head_ptr; 1563.    for (prev = (struct obj *) 0; curr; prev = curr, curr = curr->nexthere) { 1564. 	if (curr == obj) { 1565. 	   if (prev) 1566. 		prev->nexthere = curr->nexthere; 1567. 	   else 1568. 		*head_ptr = curr->nexthere; 1569. 	   break; 1570. 	} 1571.     }  1572.     if (!curr) panic("extract_nexthere: object lost"); 1573. } 1574.  1575.  1576. /*  1577.  * Add obj to mon's inventory. If obj is able to merge with something already 1578. * in the inventory, then the passed obj is deleted and 1 is returned. 1579. * Otherwise 0 is returned. 1580. */  1581. int 1582. add_to_minv(mon, obj) 1583.    struct monst *mon; 1584.    struct obj *obj; 1585. { 1586.     struct obj *otmp; 1587. 1588.     if (obj->where != OBJ_FREE) 1589. 	panic("add_to_minv: obj not free"); 1590. 1591.     /* merge if possible */ 1592.    for (otmp = mon->minvent; otmp; otmp = otmp->nobj) 1593. 	if (merged(&otmp, &obj)) 1594. 	   return 1;	/* obj merged and then free'd */ 1595.    /* else insert; don't bother forcing it to end of chain */ 1596.    obj->where = OBJ_MINVENT; 1597.    obj->ocarry = mon; 1598.    obj->nobj = mon->minvent; 1599.    mon->minvent = obj; 1600.    return 0;	/* obj on mon's inventory chain */ 1601. } 1602.  1603. /*  1604.  * Add obj to container, make sure obj is "free". Returns (merged) obj. 1605. * The input obj may be deleted in the process. 1606. */  1607. struct obj * 1608. add_to_container(container, obj) 1609.    struct obj *container, *obj; 1610. { 1611.     struct obj *otmp; 1612. 1613.     if (obj->where != OBJ_FREE) 1614. 	panic("add_to_container: obj not free"); 1615.    if (container->where != OBJ_INVENT && container->where != OBJ_MINVENT) 1616. 	obj_no_longer_held(obj); 1617. 1618.     /* merge if possible */ 1619.    for (otmp = container->cobj; otmp; otmp = otmp->nobj) 1620. 	if (merged(&otmp, &obj)) return (otmp); 1621. 1622.     obj->where = OBJ_CONTAINED; 1623.    obj->ocontainer = container; 1624.    obj->nobj = container->cobj; 1625.    container->cobj = obj; 1626.    return (obj); 1627. } 1628.  1629. void 1630. add_to_migration(obj) 1631.    struct obj *obj; 1632. { 1633.     if (obj->where != OBJ_FREE) 1634. 	panic("add_to_migration: obj not free"); 1635. 1636.     obj->where = OBJ_MIGRATING; 1637.    obj->nobj = migrating_objs; 1638.    migrating_objs = obj; 1639. } 1640.  1641. void 1642. add_to_buried(obj) 1643.    struct obj *obj; 1644. { 1645.     if (obj->where != OBJ_FREE) 1646. 	panic("add_to_buried: obj not free"); 1647. 1648.     obj->where = OBJ_BURIED; 1649.    obj->nobj = level.buriedobjlist; 1650.    level.buriedobjlist = obj; 1651. } 1652.  1653. /* Recalculate the weight of this container and all of _its_ containers. */ 1654. STATIC_OVL void 1655. container_weight(container) 1656.    struct obj *container; 1657. { 1658.     container->owt = weight(container); 1659.    if (container->where == OBJ_CONTAINED) 1660. 	container_weight(container->ocontainer); 1661. /* 1662.     else if (container->where == OBJ_INVENT) 1663. 	recalculate load delay here ??? 1664. */ 1665. }  1666.  1667. /*  1668.  * Deallocate the object. _All_ objects should be run through here for 1669. * them to be deallocated. 1670. */  1671. void 1672. dealloc_obj(obj) 1673.    struct obj *obj; 1674. { 1675.     if (obj->where != OBJ_FREE) 1676. 	panic("dealloc_obj: obj not free"); 1677. 1678.     /* free up any timers attached to the object */ 1679.    if (obj->timed) 1680. 	obj_stop_timers(obj); 1681. 1682.     /*  1683.      * Free up any light sources attached to the object. 1684.     *  1685.      * We may want to just call del_light_source without any 1686.     * checks (requires a code change there). Otherwise this 1687.     * list must track all objects that can have a light source 1688.     * attached to it (and also requires lamplit to be set). 1689.     */  1690.     if (obj_sheds_light(obj)) 1691. 	del_light_source(LS_OBJECT, (genericptr_t) obj); 1692. 1693.     if (obj == thrownobj) thrownobj = (struct obj*)0; 1694. 1695.     free((genericptr_t) obj); 1696. } 1697.  1698. #if defined(OBJ_SANITY) || defined(WIZARD) 1699. # ifdef WIZARD 1700. # define msgprefix	"" 1701. # else 1702. # define msgprefix	"BUG (please report): " 1703. # endif 1704. 1705. /* Check all object lists for consistency. */ 1706. void 1707. obj_sanity_check 1708. { 1709.     int x, y;  1710. struct obj *obj; 1711.    struct monst *mon; 1712.    const char *mesg; 1713.    char obj_address[20], mon_address[20];  /* room for formatted pointers */ 1714. 1715.     mesg = "fobj sanity"; 1716.    for (obj = fobj; obj; obj = obj->nobj) { 1717. 	if (obj->where != OBJ_FLOOR) { 1718. 	   pline("%s%s obj %s %s@(%d,%d): %s\n", msgprefix, mesg,  1719. 		fmt_ptr((genericptr_t)obj, obj_address),  1720. 		where_name(obj->where),  1721. 		obj->ox, obj->oy, doname(obj)); 1722. 	} 1723. 	check_contained(obj, mesg); 1724.    }  1725.  1726.     mesg = "location sanity"; 1727.    for (x = 0; x < COLNO; x++) 1728. 	for (y = 0; y < ROWNO; y++) 1729. 	   for (obj = level.objects[x][y]; obj; obj = obj->nexthere) 1730. 		if (obj->where != OBJ_FLOOR) { 1731. 		   pline("%s%s obj %s %s@(%d,%d): %s\n", msgprefix, mesg,  1732. 			fmt_ptr((genericptr_t)obj, obj_address),  1733. 			where_name(obj->where),  1734. 			obj->ox, obj->oy, doname(obj)); 1735. 		} 1736.  1737.     mesg = "invent sanity"; 1738.    for (obj = invent; obj; obj = obj->nobj) { 1739. 	if (obj->where != OBJ_INVENT) { 1740. 	   pline("%s%s obj %s %s: %s\n", msgprefix, mesg,  1741. 		fmt_ptr((genericptr_t)obj, obj_address),  1742. 		where_name(obj->where), doname(obj)); 1743. 	} 1744. 	check_contained(obj, mesg); 1745.    }  1746.  1747.     mesg = "migrating sanity"; 1748.    for (obj = migrating_objs; obj; obj = obj->nobj) { 1749. 	if (obj->where != OBJ_MIGRATING) { 1750. 	   pline("%s%s obj %s %s: %s\n", msgprefix, mesg,  1751. 		fmt_ptr((genericptr_t)obj, obj_address),  1752. 		where_name(obj->where), doname(obj)); 1753. 	} 1754. 	check_contained(obj, mesg); 1755.    }  1756.  1757.     mesg = "buried sanity"; 1758.    for (obj = level.buriedobjlist; obj; obj = obj->nobj) { 1759. 	if (obj->where != OBJ_BURIED) { 1760. 	   pline("%s%s obj %s %s: %s\n", msgprefix, mesg,  1761. 		fmt_ptr((genericptr_t)obj, obj_address),  1762. 		where_name(obj->where), doname(obj)); 1763. 	} 1764. 	check_contained(obj, mesg); 1765.    }  1766.  1767.     mesg = "bill sanity"; 1768.    for (obj = billobjs; obj; obj = obj->nobj) { 1769. 	if (obj->where != OBJ_ONBILL) { 1770. 	   pline("%s%s obj %s %s: %s\n", msgprefix, mesg,  1771. 		fmt_ptr((genericptr_t)obj, obj_address),  1772. 		where_name(obj->where), doname(obj)); 1773. 	} 1774. 	/* shouldn't be a full container on the bill */ 1775. 	if (obj->cobj) { 1776. 	   pline("%s%s obj %s contains %s! %s\n", msgprefix, mesg,  1777. 		fmt_ptr((genericptr_t)obj, obj_address),  1778. 		something, doname(obj)); 1779. 	} 1780.     }  1781.  1782.     mesg = "minvent sanity"; 1783.    for (mon = fmon; mon; mon = mon->nmon) 1784. 	for (obj = mon->minvent; obj; obj = obj->nobj) { 1785. 	   if (obj->where != OBJ_MINVENT) { 1786. 		pline("%s%s obj %s %s: %s\n", msgprefix, mesg, 1787. 			fmt_ptr((genericptr_t)obj, obj_address),  1788. 			where_name(obj->where), doname(obj)); 1789. 	   }  1790. 	    if (obj->ocarry != mon) { 1791. 		pline("%s%s obj %s (%s) not held by mon %s (%s)\n", msgprefix, mesg, 1792. 			fmt_ptr((genericptr_t)obj, obj_address),  1793. 			doname(obj),  1794. 			fmt_ptr((genericptr_t)mon, mon_address),  1795. 			mon_nam(mon)); 1796. 	   }  1797. 	    check_contained(obj, mesg); 1798. 	} 1799. }  1800.  1801. /* This must stay consistent with the defines in obj.h. */ 1802. static const char *obj_state_names[NOBJ_STATES] = { 1803. 	"free",		"floor",	"contained",	"invent", 1804. 	"minvent",	"migrating",	"buried",	"onbill" 1805. }; 1806.  1807. STATIC_OVL const char * 1808. where_name(where) 1809.    int where; 1810. { 1811.     return (where<0 || where>=NOBJ_STATES) ? "unknown" : obj_state_names[where]; 1812. } 1813.  1814. /* obj sanity check: check objs contained by container */ 1815. STATIC_OVL void 1816. check_contained(container, mesg) 1817.    struct obj *container; 1818.    const char *mesg; 1819. { 1820.     struct obj *obj; 1821.    char obj1_address[20], obj2_address[20]; 1822. 1823.     for (obj = container->cobj; obj; obj = obj->nobj) { 1824. 	if (obj->where != OBJ_CONTAINED) 1825. 	   pline("%scontained %s obj %s: %s\n", msgprefix, mesg,  1826. 		fmt_ptr((genericptr_t)obj, obj1_address),  1827. 		where_name(obj->where)); 1828. 	else if (obj->ocontainer != container) 1829. 	   pline("%s%s obj %s not in container %s\n", msgprefix, mesg,  1830. 		fmt_ptr((genericptr_t)obj, obj1_address),  1831. 		fmt_ptr((genericptr_t)container, obj2_address)); 1832.    }  1833. }  1834. #endif /* OBJ_SANITY || WIZARD */ 1835. 1836. #endif /* OVL1 */ 1837. 1838. /*mkobj.c*/