Source:Mkobj.c

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