Source:SLASH'EM 0.0.7E7F2/worn.c

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

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

1.   /*	SCCS Id: @(#)worn.c	3.4	2003/01/08	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   STATIC_DCL void FDECL(m_lose_armor, (struct monst *,struct obj *)); 8.   STATIC_DCL void FDECL(m_dowear_type, (struct monst *,long, BOOLEAN_P, BOOLEAN_P)); 9.   STATIC_DCL int FDECL(extra_pref, (struct monst *, struct obj *)); 10.   11.   const struct worn { 12.  	long w_mask; 13.  	struct obj **w_obj; 14.  } worn[] = { 15.  	{ W_ARM, &uarm }, 16.  	{ W_ARMC, &uarmc }, 17.  	{ W_ARMH, &uarmh }, 18.  	{ W_ARMS, &uarms }, 19.  	{ W_ARMG, &uarmg }, 20.  	{ W_ARMF, &uarmf }, 21.  #ifdef TOURIST 22.  	{ W_ARMU, &uarmu }, 23.  #endif 24.  	{ W_RINGL, &uleft }, 25.  	{ W_RINGR, &uright }, 26.  	{ W_WEP, &uwep }, 27.  	{ W_SWAPWEP, &uswapwep }, 28.  	{ W_QUIVER, &uquiver }, 29.  	{ W_AMUL, &uamul }, 30.  	{ W_TOOL, &ublindf }, 31.  	{ W_BALL, &uball }, 32.  	{ W_CHAIN, &uchain }, 33.  #ifdef STEED 34.  	{ W_SADDLE, &usaddle }, 35.  #endif 36.  	{ 0, 0 }  37.   };  38.    39.   /* this only allows for one blocking property per item */ 40.  /* KMH -- Added Hobbits & stealth */ 41.  /* This only allows for one blocking item per property */ 42.  #define w_blocks(o,m) \ 43.  		((o->otyp == MUMMY_WRAPPING && ((m) & W_ARMC)) ? INVIS : \  44.   		 (o->otyp == CORNUTHAUM && ((m) & W_ARMH) && \ 45.  			!Role_if(PM_WIZARD)) ? CLAIRVOYANT : \  46.   		 (is_boots(o) && o->otyp != ELVEN_BOOTS && ((m) & W_ARMF) && \ 47.  		 	Role_if(PM_HOBBIT)) ? STEALTH : 0) 48.  		/* note: monsters don't have clairvoyance, so your role 49.  		   has no significant effect on their use of w_blocks */ 50.   51.   /* KMH, intrinsic patch. 52.   * Updated to use the extrinsic and blocked fields. 53.   */  54.   void 55.  setworn(obj, mask) 56.  register struct obj *obj; 57.  long mask; 58.  {  59.   	register const struct worn *wp; 60.  	register struct obj *oobj; 61.  	register int p;  62. 63.  	if ((mask & (W_ARM|I_SPECIAL)) == (W_ARM|I_SPECIAL)) { 64.  	    /* restoring saved game; no properties are conferred via skin */ 65.  	    uskin = obj; 66.  	 /* assert( !uarm ); */ 67.  	} else { 68.  	    for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) { 69.  		oobj = *(wp->w_obj); 70.  		if(oobj && !(oobj->owornmask & wp->w_mask)) 71.  			impossible("Setworn: mask = %ld.", wp->w_mask); 72.  		if(oobj) { 73.  		    if (u.twoweap && (oobj->owornmask & (W_WEP|W_SWAPWEP))) { 74.  			if (uswapwep) 75.  			    unwield(uswapwep, FALSE); 76.  			u.twoweap = 0; 77.  		    }  78.   		    oobj->owornmask &= ~wp->w_mask; 79.  		    if (wp->w_mask & ~(W_SWAPWEP|W_QUIVER)) { 80.  			/* leave as "x = x  y", here and below, for broken 81.  			 * compilers */ 82.  			p = objects[oobj->otyp].oc_oprop; 83.  			u.uprops[p].extrinsic = 84.  					u.uprops[p].extrinsic & ~wp->w_mask; 85.  			if ((p = w_blocks(oobj,mask)) != 0) 86.  			    u.uprops[p].blocked &= ~wp->w_mask; 87.  			if (oobj->oartifact) 88.  			    set_artifact_intrinsic(oobj, 0, mask); 89.  		    }  90.   		}  91.   		*(wp->w_obj) = obj; 92.  		if(obj) { 93.  		    obj->owornmask |= wp->w_mask; 94.  		    /* Prevent getting/blocking intrinsics from wielding 95.  		     * potions, through the quiver, etc. 96.  		     * Allow weapon-tools, too. 97.  		     * wp_mask should be same as mask at this point. 98.  		     */  99.   		    if (wp->w_mask & ~(W_SWAPWEP|W_QUIVER)) { 100. 			if (obj->oclass == WEAPON_CLASS || is_weptool(obj) ||  101.  					    mask != W_WEP) { 102. 			    p = objects[obj->otyp].oc_oprop; 103. 			    u.uprops[p].extrinsic = 104. 					u.uprops[p].extrinsic | wp->w_mask; 105. 			    if ((p = w_blocks(obj, mask)) != 0) 106. 				u.uprops[p].blocked |= wp->w_mask; 107. 			}  108.  			if (obj->oartifact) 109. 			    set_artifact_intrinsic(obj, 1, mask); 110. 		    }  111.  		}  112.  	    }  113.  	}  114.  	update_inventory; 115. }  116.   117.  /* called e.g. when obj is destroyed */ 118. /* KMH, intrinsic patch. 119.  * Updated to use the extrinsic and blocked fields. 120.  */  121.  void 122. setnotworn(obj) 123. register struct obj *obj; 124. {  125.  	register const struct worn *wp; 126. 	register int p;  127. 128. 	if (!obj) return; 129. 	if (obj == uwep || obj == uswapwep) { 130. 	    if (uswapwep) 131. 		unwield(uswapwep, FALSE); 132. 	    u.twoweap = 0; 133. 	}  134.  	for(wp = worn; wp->w_mask; wp++) 135. 	    if(obj == *(wp->w_obj)) { 136. 		*(wp->w_obj) = 0; 137. 		p = objects[obj->otyp].oc_oprop; 138. 		u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask; 139. 		obj->owornmask &= ~wp->w_mask; 140. 		if (obj->oartifact) 141. 		    set_artifact_intrinsic(obj, 0, wp->w_mask); 142. 		if ((p = w_blocks(obj,wp->w_mask)) != 0) 143. 		    u.uprops[p].blocked &= ~wp->w_mask; 144. 	    }  145.  	update_inventory; 146. }  147.   148.  void 149. mon_set_minvis(mon) 150. struct monst *mon; 151. {  152.  	mon->perminvis = 1; 153. 	if (!mon->invis_blkd) { 154. 	    mon->minvis = 1; 155. 	    newsym(mon->mx, mon->my);		/* make it disappear */ 156. 	    if (mon->wormno) see_wsegs(mon);	/* and any tail too */ 157. 	}  158.  }  159.   160.  void 161. mon_adjust_speed(mon, adjust, obj) 162. struct monst *mon; 163. int adjust;	/* positive => increase speed, negative => decrease */ 164. struct obj *obj;	/* item to make known if effect can be seen */ 165. {  166.      struct obj *otmp; 167.     boolean give_msg = !in_mklev, petrify = FALSE; 168.     unsigned int oldspeed = mon->mspeed; 169.  170.      switch (adjust) { 171.      case  2: 172. 	mon->permspeed = MFAST; 173. 	give_msg = FALSE;	/* special case monster creation */ 174. 	break; 175.      case  1: 176. 	if (mon->permspeed == MSLOW) mon->permspeed = 0; 177. 	else mon->permspeed = MFAST; 178. 	break; 179.      case  0:			/* just check for worn speed boots */ 180. 	break; 181.      case -1: 182. 	if (mon->permspeed == MFAST) mon->permspeed = 0; 183. 	else mon->permspeed = MSLOW; 184. 	break; 185.      case -2: 186. 	mon->permspeed = MSLOW; 187. 	give_msg = FALSE;	/* (not currently used) */ 188. 	break; 189.      case -3:			/* petrification */ 190. 	/* take away intrinsic speed but don't reduce normal speed */ 191. 	if (mon->permspeed == MFAST) mon->permspeed = 0; 192. 	petrify = TRUE; 193. 	break; 194.     }  195.   196.      for (otmp = mon->minvent; otmp; otmp = otmp->nobj) 197. 	if (otmp->owornmask && objects[otmp->otyp].oc_oprop == FAST) 198. 	    break; 199.     if (otmp)		/* speed boots */ 200. 	mon->mspeed = MFAST; 201.     else 202. 	mon->mspeed = mon->permspeed; 203.  204.      if (give_msg && (mon->mspeed != oldspeed || petrify) && canseemon(mon)) { 205. 	/* fast to slow (skipping intermediate state) or vice versa */ 206. 	const char *howmuch = (mon->mspeed + oldspeed == MFAST + MSLOW) ? 207. 				"much " : ""; 208.  209.  	if (petrify) { 210. 	    /* mimic the player's petrification countdown; "slowing down" 211. 	       even if fast movement rate retained via worn speed boots */ 212. 	    if (flags.verbose) pline("%s is slowing down.", Monnam(mon)); 213. 	} else if (adjust > 0 || mon->mspeed == MFAST) 214. 	    pline("%s is suddenly moving %sfaster.", Monnam(mon), howmuch); 215. 	else 216. 	    pline("%s seems to be moving %sslower.", Monnam(mon), howmuch); 217.  218.  	/* might discover an object if we see the speed change happen, but 219. 	   avoid making possibly forgotten book known when casting its spell */ 220. 	if (obj != 0 && obj->dknown &&  221.  		objects[obj->otyp].oc_class != SPBOOK_CLASS) 222. 	    makeknown(obj->otyp); 223.     }  224.  }  225.   226.  /* armor put on or taken off; might be magical variety */ 227. void 228. update_mon_intrinsics(mon, obj, on, silently) 229. struct monst *mon; 230. struct obj *obj; 231. boolean on, silently; 232. {  233.      int unseen; 234.     unsigned long mask; 235.     struct obj *otmp; 236.     int which = (int) objects[obj->otyp].oc_oprop; 237.  238.      unseen = !canseemon(mon); 239.     if (!which) goto maybe_blocks; 240.  241.      if (on) { 242. 	switch (which) { 243. 	 case INVIS: 244. 	    mon->minvis = !mon->invis_blkd; 245. 	    break; 246. 	 case FAST: 247. 	  {  248.  	    boolean save_in_mklev = in_mklev; 249. 	    if (silently) in_mklev = TRUE; 250. 	    mon_adjust_speed(mon, 0, obj); 251. 	    in_mklev = save_in_mklev; 252. 	    break; 253. 	  }  254.  	/* properties handled elsewhere */ 255. 	 case ANTIMAGIC: 256. 	 case REFLECTING: 257. 	    break; 258. 	/* properties which have no effect for monsters */ 259. 	 case CLAIRVOYANT: 260. 	 case STEALTH: 261. 	 case TELEPAT: 262. 	    break; 263. 	/* properties which should have an effect but aren't implemented */ 264. 	 case LEVITATION: 265. 	 case WWALKING: 266. 	    break; 267. 	/* properties which maybe should have an effect but don't */ 268. 	 case DISPLACED: 269. 	 case FUMBLING: 270. 	 case JUMPING: 271. 	 case PROTECTION: 272. 	    break; 273. 	 case DRAIN_RES: 274. 	    mon->mintrinsics |= MR_DRAIN; 275. 	    break; 276. 	 default: 277. 	    if (which <= 8) {	/* 1 thru 8 correspond to MR_xxx mask values */ 278. 		/* FIRE,COLD,SLEEP,DISINT,SHOCK,POISON,ACID,STONE */ 279. 		mask = (uchar) (1 << (which - 1)); 280. 		mon->mintrinsics |= (unsigned short) mask; 281. 	    }  282.  	    break; 283. 	}  284.      } else {	    /* off */ 285. 	switch (which) { 286. 	 case INVIS: 287. 	    mon->minvis = mon->perminvis; 288. 	    break; 289. 	 case FAST: 290. 	  {  291.  	    boolean save_in_mklev = in_mklev; 292. 	    if (silently) in_mklev = TRUE; 293. 	    mon_adjust_speed(mon, 0, obj); 294. 	    in_mklev = save_in_mklev; 295. 	    break; 296. 	  }  297.  	 case DRAIN_RES: 298. 	    mask = MR_DRAIN; 299. 	    goto maybe_loose; 300. 	 case FIRE_RES: 301. 	 case COLD_RES: 302. 	 case SLEEP_RES: 303. 	 case DISINT_RES: 304. 	 case SHOCK_RES: 305. 	 case POISON_RES: 306. 	 case ACID_RES: 307. 	 case STONE_RES: 308. 	    mask = (uchar) (1 << (which - 1)); 309.  maybe_loose: 310. 	    /* If the monster doesn't have this resistance intrinsically, 311. 	       check whether any other worn item confers it. Note that 312. 	       we don't currently check for anything conferred via simply 313. 	       carrying an object. */ 314.  	    if (!(mon->data->mresists & mask)) { 315. 		for (otmp = mon->minvent; otmp; otmp = otmp->nobj) 316. 		    if (otmp->owornmask &&  317.  			    (int) objects[otmp->otyp].oc_oprop == which) 318. 			break; 319. 		if (!otmp) 320. 		    mon->mintrinsics &= ~mask; 321. 	    }  322.  	    break; 323. 	 default: 324. 	    break; 325. 	}  326.      }  327.   328.   maybe_blocks: 329.     /* obj->owornmask has been cleared by this point, so we can't use it. 330.        However, since monsters don't wield armor, we don't have to guard 331.        against that and can get away with a blanket worn-mask value. */ 332.      switch (w_blocks(obj,~0L)) { 333.      case INVIS: 334. 	mon->invis_blkd = on ? 1 : 0; 335.  	mon->minvis = on ? 0 : mon->perminvis; 336. 	break; 337.      default: 338. 	break; 339.     }  340.   341.  #ifdef STEED 342. 	if (!on && mon == u.usteed && obj->otyp == SADDLE) 343. 	    dismount_steed(DISMOUNT_FELL); 344. #endif 345.  346.      /* if couldn't see it but now can, or vice versa, update display */ 347.     if (!silently && (unseen ^ !canseemon(mon))) 348. 	newsym(mon->mx, mon->my); 349. }  350.   351.  int 352. find_mac(mon) 353. register struct monst *mon; 354. {  355.  	register struct obj *obj; 356. 	int base = mon->data->ac; 357. 	long mwflags = mon->misc_worn_check; 358.  359.  	for (obj = mon->minvent; obj; obj = obj->nobj) { 360. 	    if (obj->owornmask & mwflags) 361. 		base -= ARM_BONUS(obj); 362. 		/* since ARM_BONUS is positive, subtracting it increases AC */ 363. 	}  364.  	return base; 365. }  366.   367.  /* weapons are handled separately; rings and eyewear aren't used by monsters */ 368.  369.  /* Wear the best object of each type that the monster has. During creation, 370.  * the monster can put everything on at once; otherwise, wearing takes time. 371.  * This doesn't affect monster searching for objects--a monster may very well 372.  * search for objects it would not want to wear, because we don't want to  373. * check which_armor each round. 374.  *  375.   * We'll let monsters put on shirts and/or suits under worn cloaks, but 376.  * not shirts under worn suits. This is somewhat arbitrary, but it's 377. * too tedious to have them remove and later replace outer garments, 378.  * and preventing suits under cloaks makes it a little bit too easy for 379.  * players to influence what gets worn. Putting on a shirt underneath 380.  * already worn body armor is too obviously buggy...  381. */ 382.  void 383. m_dowear(mon, creation) 384. register struct monst *mon; 385. boolean creation; 386. {  387.  #define RACE_EXCEPTION TRUE 388. 	/* Note the restrictions here are the same as in dowear in do_wear.c  389. * except for the additional restriction on intelligence. (Players 390.  	 * are always intelligent, even if polymorphed). 391. 	 */  392.  	if (verysmall(mon->data) || nohands(mon->data) || is_animal(mon->data)) 393. 		return; 394. 	/* give mummies a chance to wear their wrappings 395. 	 * and let skeletons wear their initial armor */ 396. 	if (mindless(mon->data) && (!creation || 397. 	    (mon->data->mlet != S_MUMMY && mon->data != &mons[PM_SKELETON]))) 398. 		return; 399.  400.  	m_dowear_type(mon, W_AMUL, creation, FALSE); 401. #ifdef TOURIST 402. 	/* can't put on shirt if already wearing suit */ 403. 	if (!cantweararm(mon->data) || (mon->misc_worn_check & W_ARM)) 404. 	    m_dowear_type(mon, W_ARMU, creation, FALSE); 405. #endif 406. 	/* treating small as a special case allows 407. 	   hobbits, gnomes, and kobolds to wear cloaks */ 408. 	if (!cantweararm(mon->data) || mon->data->msize == MZ_SMALL) 409. 	    m_dowear_type(mon, W_ARMC, creation, FALSE); 410. 	m_dowear_type(mon, W_ARMH, creation, FALSE); 411. 	if (!MON_WEP(mon) || !bimanual(MON_WEP(mon))) 412. 	    m_dowear_type(mon, W_ARMS, creation, FALSE); 413. 	m_dowear_type(mon, W_ARMG, creation, FALSE); 414. 	if (!slithy(mon->data) && mon->data->mlet != S_CENTAUR) 415. 	    m_dowear_type(mon, W_ARMF, creation, FALSE); 416. 	if (!cantweararm(mon->data)) 417. 	    m_dowear_type(mon, W_ARM, creation, FALSE); 418. 	else 419. 	    m_dowear_type(mon, W_ARM, creation, RACE_EXCEPTION); 420. }  421.   422.  STATIC_OVL void 423. m_dowear_type(mon, flag, creation, racialexception) 424. struct monst *mon; 425. long flag; 426. boolean creation; 427. boolean racialexception; 428. {  429.  	struct obj *old, *best, *obj; 430. 	int m_delay = 0; 431. 	int unseen = !canseemon(mon); 432. 	char nambuf[BUFSZ]; 433.  434.  	if (mon->mfrozen) return; /* probably putting previous item on */ 435.  436.  	/* Get a copy of monster's name before altering its visibility */ 437. 	Strcpy(nambuf, See_invisible ? Monnam(mon) : mon_nam(mon)); 438.  439.  	old = which_armor(mon, flag); 440. 	if (old && old->cursed) return; 441. 	if (old && flag == W_AMUL) return; /* no such thing as better amulets */ 442. 	best = old; 443.  444.  	for(obj = mon->minvent; obj; obj = obj->nobj) { 445. 	    switch(flag) { 446. 		case W_AMUL: 447. 		    if (obj->oclass != AMULET_CLASS ||  448.  			    (obj->otyp != AMULET_OF_LIFE_SAVING && 449. 				obj->otyp != AMULET_OF_REFLECTION)) 450. 			continue; 451. 		    best = obj; 452. 		    goto outer_break; /* no such thing as better amulets */ 453. #ifdef TOURIST 454. 		case W_ARMU: 455. 		    if (!is_shirt(obj)) continue; 456. 		    break; 457. #endif 458. 		case W_ARMC: 459. 		    if (!is_cloak(obj)) continue; 460. 		    break; 461. 		case W_ARMH: 462. 		    if (!is_helmet(obj)) continue; 463. 		    /* (flimsy exception matches polyself handling) */ 464. 		    if (has_horns(mon->data) && !is_flimsy(obj)) continue; 465. 		    break; 466. 		case W_ARMS: 467. 		    if (!is_shield(obj)) continue; 468. 		    break; 469. 		case W_ARMG: 470. 		    if (!is_gloves(obj)) continue; 471. 		    break; 472. 		case W_ARMF: 473. 		    if (!is_boots(obj)) continue; 474. 		    break; 475. 		case W_ARM: 476. 		    if (!is_suit(obj)) continue; 477. 		    if (racialexception && (racial_exception(mon, obj) < 1)) continue; 478. 		    break; 479. 	    }  480.  	    if (obj->owornmask) continue; 481. 	    /* I'd like to define a VISIBLE_ARM_BONUS which doesn't assume the 482. 	     * monster knows obj->spe, but if I did that, a monster would keep 483. 	     * switching forever between two -2 caps since when it took off one 484. 	     * it would forget spe and once again think the object is better 485. 	     * than what it already has. 486. 	     */  487.  	    if (best && (ARM_BONUS(best) + extra_pref(mon,best) >= ARM_BONUS(obj) + extra_pref(mon,obj))) 488. 		continue; 489. 	    best = obj; 490. 	}  491.  outer_break: 492. 	if (!best || best == old) return; 493.  494.  	/* if wearing a cloak, account for the time spent removing 495. 	   and re-wearing it when putting on a suit or shirt */ 496. 	if ((flag == W_ARM 497. #ifdef TOURIST 498. 	  || flag == W_ARMU 499. #endif 500. 			  ) && (mon->misc_worn_check & W_ARMC)) 501. 	    m_delay += 2; 502. 	/* when upgrading a piece of armor, account for time spent 503. 	   taking off current one */ 504. 	if (old) 505. 	    m_delay += objects[old->otyp].oc_delay; 506.  507.  	if (old) /* do this first to avoid "(being worn)" */ 508. 	    old->owornmask = 0L; 509. 	if (!creation) { 510. 	    if (canseemon(mon)) { 511. 		char buf[BUFSZ]; 512.  513.  		if (old) 514. 		    Sprintf(buf, " removes %s and", distant_name(old, doname)); 515. 		else 516. 		    buf[0] = '\0'; 517. 		pline("%s%s puts on %s.", Monnam(mon),  518.  		      buf, distant_name(best,doname)); 519. 	    } /* can see it */ 520. 	    m_delay += objects[best->otyp].oc_delay; 521. 	    mon->mfrozen = m_delay; 522. 	    if (mon->mfrozen) mon->mcanmove = 0; 523. 	}  524.  	if (old) 525. 	    update_mon_intrinsics(mon, old, FALSE, creation); 526. 	mon->misc_worn_check |= flag; 527. 	best->owornmask |= flag; 528. 	update_mon_intrinsics(mon, best, TRUE, creation); 529. 	/* if couldn't see it but now can, or vice versa, */ 530. 	if (!creation && (unseen ^ !canseemon(mon))) { 531. 		if (mon->minvis && !See_invisible) { 532. 			pline("Suddenly you cannot see %s.", nambuf); 533. 			makeknown(best->otyp); 534. 		} /* else if (!mon->minvis) pline("%s suddenly appears!", Amonnam(mon)); */ 535. 	}  536.  }  537.  #undef RACE_EXCEPTION 538.  539.  struct obj * 540. which_armor(mon, flag) 541. struct monst *mon; 542. long flag; 543. {  544.  	register struct obj *obj; 545.  546.  	for(obj = mon->minvent; obj; obj = obj->nobj) 547. 		if (obj->owornmask & flag) return obj; 548. 	return((struct obj *)0); 549. }  550.   551.  /* remove an item of armor and then drop it */ 552. STATIC_OVL void 553. m_lose_armor(mon, obj) 554. struct monst *mon; 555. struct obj *obj; 556. {  557.  	mon->misc_worn_check &= ~obj->owornmask; 558. 	if (obj->owornmask) 559. 	    update_mon_intrinsics(mon, obj, FALSE, FALSE); 560. 	obj->owornmask = 0L; 561.  562.  	obj_extract_self(obj); 563. 	place_object(obj, mon->mx, mon->my); 564. 	/* call stackobj if we ever drop anything that can merge */ 565. 	newsym(mon->mx, mon->my); 566. }  567.   568.  /* all objects with their bypass bit set should now be reset to normal */ 569. void 570. clear_bypasses 571. {  572.  	struct obj *otmp, *nobj; 573. 	struct monst *mtmp; 574.  575.  	for (otmp = fobj; otmp; otmp = nobj) { 576. 	    nobj = otmp->nobj; 577. 	    if (otmp->bypass) { 578. 		otmp->bypass = 0; 579. 		/* bypass will have inhibited any stacking, but since it's  580. used for polymorph handling, the objects here probably 581. 		   have been transformed and won't be stacked in the usual 582. 		   manner afterwards; so don't bother with this */ 583. #if 0 584. 		if (objects[otmp->otyp].oc_merge) { 585. 		    xchar ox, oy; 586.  587.  		    (void) get_obj_location(otmp, &ox, &oy, 0); 588. 		    stack_object(otmp); 589. 		    newsym(ox, oy); 590. 		}  591.  #endif	/*0*/ 592. 	    }  593.  	}  594.  	/* invent and mydogs chains shouldn't matter here */ 595. 	for (otmp = migrating_objs; otmp; otmp = otmp->nobj) 596. 	    otmp->bypass = 0; 597. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 598. 	    if (DEADMONSTER(mtmp)) continue; 599. 	    for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 600. 		otmp->bypass = 0; 601. 	}  602.  	for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) { 603. 	    for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 604. 		otmp->bypass = 0; 605. 	}  606.  	flags.bypasses = FALSE; 607. }  608.   609.  void 610. bypass_obj(obj) 611. struct obj *obj; 612. {  613.  	obj->bypass = 1; 614. 	flags.bypasses = TRUE; 615. }  616.   617.  void 618. mon_break_armor(mon, polyspot) 619. struct monst *mon; 620. boolean polyspot; 621. {  622.  	register struct obj *otmp; 623. 	struct permonst *mdat = mon->data; 624. 	boolean vis = cansee(mon->mx, mon->my); 625. 	boolean handless_or_tiny = (nohands(mdat) || verysmall(mdat)); 626. 	const char *pronoun = mhim(mon), 627. 			*ppronoun = mhis(mon); 628.  629.  	if (breakarm(mdat)) { 630. 	    if ((otmp = which_armor(mon, W_ARM)) != 0) { 631. 		if ((Is_dragon_scales(otmp) && 632. 			mdat == Dragon_scales_to_pm(otmp)) ||  633.  		    (Is_dragon_mail(otmp) && mdat == Dragon_mail_to_pm(otmp))) 634. 		    ;	/* no message here; 635. 			   "the dragon merges with his scaly armor" is odd 636. 			   and the monster's previous form is already gone */ 637. 		else if (vis) 638. 		    pline("%s breaks out of %s armor!", Monnam(mon), ppronoun); 639. 		else 640. 		    You_hear("a cracking sound."); 641. 		m_useup(mon, otmp); 642. 	    }  643.  	    if ((otmp = which_armor(mon, W_ARMC)) != 0) { 644. 		if (otmp->oartifact) { 645. 		    if (vis) 646. 			pline("%s %s falls off!", s_suffix(Monnam(mon)),  647.  				cloak_simple_name(otmp)); 648. 		    if (polyspot) bypass_obj(otmp); 649. 		    m_lose_armor(mon, otmp); 650. 		} else { 651. 		    if (vis) 652. 			pline("%s %s tears apart!", s_suffix(Monnam(mon)),  653.  				cloak_simple_name(otmp)); 654. 		    else 655. 			You_hear("a ripping sound."); 656. 		    m_useup(mon, otmp); 657. 		}  658.  	    }  659.  #ifdef TOURIST 660. 	    if ((otmp = which_armor(mon, W_ARMU)) != 0) { 661. 		if (vis) 662. 		    pline("%s shirt rips to shreds!", s_suffix(Monnam(mon))); 663. 		else 664. 		    You_hear("a ripping sound."); 665. 		m_useup(mon, otmp); 666. 	    }  667.  #endif 668. 	} else if (sliparm(mdat)) { 669. 	    if ((otmp = which_armor(mon, W_ARM)) != 0) { 670. 		if (vis) 671. 		    pline("%s armor falls around %s!",  672.  				 s_suffix(Monnam(mon)), pronoun); 673. 		else 674. 		    You_hear("a thud."); 675. 		if (polyspot) bypass_obj(otmp); 676. 		m_lose_armor(mon, otmp); 677. 	    }  678.  	    if ((otmp = which_armor(mon, W_ARMC)) != 0) { 679. 		if (vis) { 680. 		    if (is_whirly(mon->data)) 681. 			pline("%s %s falls, unsupported!",  682.  				     s_suffix(Monnam(mon)), cloak_simple_name(otmp)); 683. 		    else 684. 			pline("%s shrinks out of %s %s!", Monnam(mon),  685.  						ppronoun, cloak_simple_name(otmp)); 686. 		}  687.  		if (polyspot) bypass_obj(otmp); 688. 		m_lose_armor(mon, otmp); 689. 	    }  690.  #ifdef TOURIST 691. 	    if ((otmp = which_armor(mon, W_ARMU)) != 0) { 692. 		if (vis) { 693. 		    if (sliparm(mon->data)) 694. 			pline("%s seeps right through %s shirt!",  695.  					Monnam(mon), ppronoun); 696. 		    else 697. 			pline("%s becomes much too small for %s shirt!",  698.  					Monnam(mon), ppronoun); 699. 		}  700.  		if (polyspot) bypass_obj(otmp); 701. 		m_lose_armor(mon, otmp); 702. 	    }  703.  #endif 704. 	}  705.  	if (handless_or_tiny) { 706. 	    /* [caller needs to handle weapon checks] */ 707. 	    if ((otmp = which_armor(mon, W_ARMG)) != 0) { 708. 		if (vis) 709. 		    pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,  710.  					MON_WEP(mon) ? " and weapon" : ""); 711. 		if (polyspot) bypass_obj(otmp); 712. 		m_lose_armor(mon, otmp); 713. 	    }  714.  	    if ((otmp = which_armor(mon, W_ARMS)) != 0) { 715. 		if (vis) 716. 		    pline("%s can no longer hold %s shield!", Monnam(mon),  717.  								ppronoun); 718. 		else 719. 		    You_hear("a clank."); 720. 		if (polyspot) bypass_obj(otmp); 721. 		m_lose_armor(mon, otmp); 722. 	    }  723.  	}  724.  	if (handless_or_tiny || has_horns(mdat)) { 725. 	    if ((otmp = which_armor(mon, W_ARMH)) != 0 &&  726.  		    /* flimsy test for horns matches polyself handling */  727.  		    (handless_or_tiny || !is_flimsy(otmp))) { 728. 		if (vis) 729. 		    pline("%s helmet falls to the %s!",  730.  			  s_suffix(Monnam(mon)), surface(mon->mx, mon->my)); 731. 		else 732. 		    You_hear("a clank."); 733. 		if (polyspot) bypass_obj(otmp); 734. 		m_lose_armor(mon, otmp); 735. 	    }  736.  	}  737.  	if (handless_or_tiny || slithy(mdat) || mdat->mlet == S_CENTAUR) { 738. 	    if ((otmp = which_armor(mon, W_ARMF)) != 0) { 739. 		if (vis) { 740. 		    if (is_whirly(mon->data)) 741. 			pline("%s boots fall away!",  742.  				       s_suffix(Monnam(mon))); 743. 		    else pline("%s boots %s off %s feet!",  744.  			s_suffix(Monnam(mon)),  745.  			verysmall(mdat) ? "slide" : "are pushed", ppronoun); 746. 		}  747.  		if (polyspot) bypass_obj(otmp); 748. 		m_lose_armor(mon, otmp); 749. 	    }  750.  	}  751.  #ifdef STEED 752. 	if (!can_saddle(mon)) { 753. 	    if ((otmp = which_armor(mon, W_SADDLE)) != 0) { 754. 		if (polyspot) bypass_obj(otmp); 755. 		m_lose_armor(mon, otmp); 756. 		if (vis) 757. 		    pline("%s saddle falls off.", s_suffix(Monnam(mon))); 758. 	    }  759.  	    if (mon == u.usteed) 760. 		goto noride; 761. 	} else if (mon == u.usteed && !can_ride(mon)) { 762. 	noride: 763. 	    You("can no longer ride %s.", mon_nam(mon)); 764. 	    if (touch_petrifies(u.usteed->data) &&  765.  			!Stone_resistance && rnl(3)) { 766. 		char buf[BUFSZ]; 767.  768.  		You("touch %s.", mon_nam(u.usteed)); 769. 		Sprintf(buf, "falling off %s",  770.  				an(u.usteed->data->mname)); 771. 		instapetrify(buf); 772. 	    }  773.  	    dismount_steed(DISMOUNT_FELL); 774. 	}  775.  #endif 776. 	return; 777. }  778.   779.  /* bias a monster's preferences towards armor that has special benefits. */ 780.  /* currently only does speed boots, but might be expanded if monsters get to  781. use more armor abilities */ 782. static int 783. extra_pref(mon, obj) 784. struct monst *mon; 785. struct obj *obj; 786. {  787.      if (obj) { 788. 	if (obj->otyp == SPEED_BOOTS && mon->permspeed != MFAST) 789. 	    return 20; 790.     }  791.      return 0; 792. }  793.   794.  /*  795.   * Exceptions to things based on race. Correctly checks polymorphed player race. 796.  * Returns: 797.  *	 0 No exception, normal rules apply. 798.  * 	 1 If the race/object combination is acceptable. 799.  *	-1 If the race/object combination is unacceptable. 800.  */  801.  int 802. racial_exception(mon, obj) 803. struct monst *mon; 804. struct obj *obj; 805. {  806.      const struct permonst *ptr = raceptr(mon); 807.  808.      /* Acceptable Exceptions: */ 809.     /* Allow hobbits to wear elven armor - LoTR */ 810.     if (ptr == &mons[PM_HOBBIT] && is_elven_armor(obj)) 811. 	return 1; 812.     /* Unacceptable Exceptions: */ 813.     /* Checks for object that certain races should never use go here */ 814.     /*	return -1; */ 815.  816.      return 0; 817. }  818.  /*worn.c*/