Source:SLASH'EM 0.0.7E7F2/steal.c

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

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

1.   /*	SCCS Id: @(#)steal.c	3.4	2003/12/04	*/ 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_PTR int NDECL(stealarm); 8.    9.    #ifdef OVLB 10.  STATIC_DCL const char *FDECL(equipname, (struct obj *)); 11.  STATIC_DCL void FDECL(mdrop_obj, (struct monst *,struct obj *,BOOLEAN_P)); 12.   13.   STATIC_OVL const char * 14.  equipname(otmp) 15.  register struct obj *otmp; 16.  {  17.   	return (  18.   #ifdef TOURIST  19.   		(otmp == uarmu) ? "shirt" :  20.   #endif  21.   		(otmp == uarmf) ? "boots" :  22.   		(otmp == uarms) ? "shield" :  23.   		(otmp == uarmg) ? "gloves" :  24.   		(otmp == uarmc) ? cloak_simple_name(otmp) :  25.   		(otmp == uarmh) ? "helmet" : "armor"); 26.  }  27.    28.   #ifndef GOLDOBJ 29.  long		/* actually returns something that fits in an int */ 30.  somegold 31.  {  32.   #ifdef LINT	/* long conv. ok */ 33.  	return(0L); 34.  #else 35.  	return (long)( (u.ugold < 100) ? u.ugold :  36.   		(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) ); 37.  #endif 38.  }  39.    40.   void 41.  stealgold(mtmp) 42.  register struct monst *mtmp; 43.  {  44.   	register struct obj *gold = g_at(u.ux, u.uy); 45.  	register long tmp; 46.   47.   	if (gold && ( !u.ugold || gold->quan > u.ugold || !rn2(5))) { 48.  	    mtmp->mgold += gold->quan; 49.  	    delobj(gold); 50.  	    newsym(u.ux, u.uy); 51.  	    pline("%s quickly snatches some gold from between your %s!",  52.   		    Monnam(mtmp), makeplural(body_part(FOOT))); 53.  	    if(!u.ugold || !rn2(5)) { 54.  		if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 55.  		/* do not set mtmp->mavenge here; gold on the floor is fair game */ 56.  		monflee(mtmp, 0, FALSE, FALSE); 57.  	    }  58.   	} else if(u.ugold) { 59.  	    u.ugold -= (tmp = somegold); 60.  	    Your("purse feels lighter."); 61.  	    mtmp->mgold += tmp; 62.  	if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 63.  	    mtmp->mavenge = 1; 64.  	    monflee(mtmp, 0, FALSE, FALSE); 65.  	    flags.botl = 1; 66.  	}  67.   }  68.    69.   #else /* !GOLDOBJ */ 70.   71.   long		/* actually returns something that fits in an int */ 72.  somegold(umoney) 73.  long umoney; 74.  {  75.   #ifdef LINT	/* long conv. ok */ 76.  	return(0L); 77.  #else 78.  	return (long)( (umoney < 100) ? umoney :  79.   		(umoney > 10000) ? rnd(10000) : rnd((int) umoney) ); 80.  #endif 81.  }  82.    83.   /*  84.   Find the first (and hopefully only) gold object in a chain. 85.  Used when leprechaun (or you as leprechaun) looks for 86.  someone else's gold. Returns a pointer so the gold may 87.  be seized without further searching. 88.  May search containers too. 89.  Deals in gold only, as leprechauns don't care for lesser coins. 90.  */  91.   struct obj * 92.  findgold(chain) 93.  register struct obj *chain; 94.  {  95.           while (chain && chain->otyp != GOLD_PIECE) chain = chain->nobj; 96.          return chain; 97.  }  98.    99.   /*  100.  Steal gold coins only. Leprechauns don't care for lesser coins. 101. */  102.  void 103. stealgold(mtmp) 104. register struct monst *mtmp; 105. {  106.  	register struct obj *fgold = g_at(u.ux, u.uy); 107. 	register struct obj *ygold; 108. 	register long tmp; 109.  110.          /* skip lesser coins on the floor */ 111.         while (fgold && fgold->otyp != GOLD_PIECE) fgold = fgold->nexthere; 112.  113.          /* Do you have real gold? */ 114.          ygold = findgold(invent); 115.  116.  	if (fgold && ( !ygold || fgold->quan > ygold->quan || !rn2(5))) { 117.             obj_extract_self(fgold); 118. 	    add_to_minv(mtmp, fgold); 119. 	    newsym(u.ux, u.uy); 120. 	    pline("%s quickly snatches some gold from between your %s!",  121.  		    Monnam(mtmp), makeplural(body_part(FOOT))); 122. 	    if(!ygold || !rn2(5)) { 123. 		if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 124. 		monflee(mtmp, 0, FALSE, FALSE); 125. 	    }  126.  	} else if(ygold) { 127.             const int gold_price = objects[GOLD_PIECE].oc_cost; 128. 	    tmp = (somegold(money_cnt(invent)) + gold_price - 1) / gold_price; 129. 	    tmp = min(tmp, ygold->quan); 130.             if (tmp < ygold->quan) ygold = splitobj(ygold, tmp); 131.             freeinv(ygold); 132.             add_to_minv(mtmp, ygold); 133. 	    Your("purse feels lighter."); 134. 	    if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 135. 	    monflee(mtmp, 0, FALSE, FALSE); 136. 	    flags.botl = 1; 137. 	}  138.  }  139.  #endif /* GOLDOBJ */ 140.  141.  /* steal armor after you finish taking it off */ 142. unsigned int stealoid;		/* object to be stolen */ 143. unsigned int stealmid;		/* monster doing the stealing */ 144.  145.  STATIC_PTR int 146. stealarm 147. {  148.  	register struct monst *mtmp; 149. 	register struct obj *otmp; 150.  151.  	for(otmp = invent; otmp; otmp = otmp->nobj) { 152. 	    if(otmp->o_id == stealoid) { 153. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 154. 		    if(mtmp->m_id == stealmid) { 155. 			if(DEADMONSTER(mtmp)) impossible("stealarm: dead monster stealing"); 156. 			if(!dmgtype(mtmp->data, AD_SITM)) /* polymorphed */ 157. 			    goto botm; 158. 			if(otmp->unpaid) 159. 			    subfrombill(otmp, shop_keeper(*u.ushops)); 160. 			freeinv(otmp); 161. 			pline("%s steals %s!", Monnam(mtmp), doname(otmp)); 162. 			(void) mpickobj(mtmp,otmp);	/* may free otmp */ 163. 			/* Implies seduction, "you gladly hand over ..." 164. 			   so we don't set mavenge bit here. */ 165.  			monflee(mtmp, 0, FALSE, FALSE); 166. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 167. 		        break; 168. 		    }  169.  		}  170.  		break; 171. 	    }  172.  	}  173.  botm:   stealoid = 0; 174. 	return 0; 175. }  176.   177.  /* An object you're wearing has been taken off by a monster (theft or  178.     seduction). Also used if a worn item gets transformed (stone to flesh). */ 179.  void 180. remove_worn_item(obj, unchain_ball) 181. struct obj *obj; 182. boolean unchain_ball;	/* whether to unpunish or just unwield */ 183. {  184.  	if (donning(obj)) 185. 	    cancel_don; 186. 	if (!obj->owornmask) 187. 	    return; 188.  189.  	if (obj->owornmask & W_ARMOR) { 190. 	    if (obj == uskin) { 191. 		impossible("Removing embedded scales?"); 192. 		skinback(TRUE);		/* uarm = uskin; uskin = 0; */ 193. 	    }  194.  	    if (obj == uarm) (void) Armor_off; 195. 	    else if (obj == uarmc) (void) Cloak_off; 196. 	    else if (obj == uarmf) (void) Boots_off; 197. 	    else if (obj == uarmg) (void) Gloves_off; 198. 	    else if (obj == uarmh) (void) Helmet_off; 199. 	    else if (obj == uarms) (void) Shield_off; 200. #ifdef TOURIST 201. 	    else if (obj == uarmu) (void) Shirt_off; 202. #endif 203. 	    /* catchall -- should never happen */ 204. 	    else setworn((struct obj *)0, obj->owornmask & W_ARMOR); 205. 	} else if (obj->owornmask & W_AMUL) { 206. 	    Amulet_off; 207. 	} else if (obj->owornmask & W_RING) { 208. 	    Ring_gone(obj); 209. 	} else if (obj->owornmask & W_TOOL) { 210. 	    Blindf_off(obj); 211. 	} else if (obj->owornmask & (W_WEP|W_SWAPWEP|W_QUIVER)) { 212. 	    if (obj == uwep) 213. 		uwepgone; 214. 	    if (obj == uswapwep) 215. 		uswapwepgone; 216. 	    if (obj == uquiver) 217. 		uqwepgone; 218. 	}  219.   220.  	if (obj->owornmask & (W_BALL|W_CHAIN)) { 221. 	    if (unchain_ball) unpunish; 222. 	} else if (obj->owornmask) { 223. 	/* catchall */ 224. 	    setnotworn(obj); 225. 	}  226.  }  227.   228.  /* Returns 1 when something was stolen (or at least, when N should flee now) 229.  * Returns -1 if the monster died in the attempt 230.  * Avoid stealing the object stealoid 231.  */  232.  int 233. steal(mtmp, objnambuf) 234. struct monst *mtmp; 235. char *objnambuf; 236. {  237.  	struct obj *otmp; 238. 	int tmp, could_petrify, named = 0, armordelay; 239. 	boolean monkey_business; /* true iff an animal is doing the thievery */ 240. 	int do_charm = is_neuter(mtmp->data) || flags.female == mtmp->female; 241.  242.  	if (objnambuf) *objnambuf = '\0'; 243. 	/* the following is true if successful on first of two attacks. */ 244.  	if(!monnear(mtmp, u.ux, u.uy)) return(0); 245.  246.  	/* food being eaten might already be used up but will not have 247. 	   been removed from inventory yet; we don't want to steal that, 248. 	   so this will cause it to be removed now */ 249. 	if (occupation) (void) maybe_finished_meal(FALSE); 250.  251.  	if (!invent || (inv_cnt == 1 && uskin)) { 252. nothing_to_steal: 253. 	    /* Not even a thousand men in armor can strip a naked man. */ 254.  	    if(Blind) 255. 	      pline("Somebody tries to rob you, but finds nothing to steal."); 256. 	    else 257. 	      pline("%s tries to rob you, but there is nothing to steal!",  258.  		Monnam(mtmp)); 259. 	    return(1);  /* let thief flee */ 260. 	}  261.   262.  	monkey_business = is_animal(mtmp->data); 263. 	if (monkey_business) { 264. 	    ;	/* skip ring special cases */ 265. 	} else if (Adornment & LEFT_RING) { 266. 	    otmp = uleft; 267. 	    goto gotobj; 268. 	} else if (Adornment & RIGHT_RING) { 269. 	    otmp = uright; 270. 	    goto gotobj; 271. 	}  272.   273.  	tmp = 0; 274. 	for(otmp = invent; otmp; otmp = otmp->nobj) 275. 	    if ((!uarm || otmp != uarmc) && otmp != uskin  276.  #ifdef INVISIBLE_OBJECTS  277.  				&& (!otmp->oinvis || perceives(mtmp->data))  278.  #endif  279.  				) 280. 		tmp += ((otmp->owornmask & 281. 			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1); 282. 	if (!tmp) goto nothing_to_steal; 283. 	tmp = rn2(tmp); 284. 	for(otmp = invent; otmp; otmp = otmp->nobj) 285. 	    if ((!uarm || otmp != uarmc) && otmp != uskin  286.  #ifdef INVISIBLE_OBJECTS  287.  				&& (!otmp->oinvis || perceives(mtmp->data))  288.  #endif  289.  			) 290. 		if((tmp -= ((otmp->owornmask & 291. 			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0) 292. 			break; 293. 	if(!otmp) { 294. 		impossible("Steal fails!"); 295. 		return(0); 296. 	}  297.  	/* can't steal gloves while wielding - so steal the wielded item. */ 298.  	if (otmp == uarmg && uwep) 299. 	    otmp = uwep; 300. 	/* can't steal armor while wearing cloak - so steal the cloak. */ 301.  	else if(otmp == uarm && uarmc) otmp = uarmc; 302. #ifdef TOURIST 303. 	else if(otmp == uarmu && uarmc) otmp = uarmc; 304. 	else if(otmp == uarmu && uarm) otmp = uarm; 305. #endif 306. gotobj: 307. 	if(otmp->o_id == stealoid) return(0); 308.  309.  #ifdef STEED 310. 	if (otmp == usaddle) dismount_steed(DISMOUNT_FELL); 311. #endif 312.  313.  	/* animals can't overcome curse stickiness nor unlock chains */ 314. 	if (monkey_business) { 315. 	    boolean ostuck; 316. 	    /* is the player prevented from voluntarily giving up this item? 317. 	       (ignores loadstones; the !can_carry check will catch those) */ 318. 	    if (otmp == uball) 319. 		ostuck = TRUE;	/* effectively worn; curse is implicit */ 320. 	    else if (otmp == uquiver || (otmp == uswapwep && !u.twoweap)) 321. 		ostuck = FALSE;	/* not really worn; curse doesn't matter */ 322. 	    else 323. 		ostuck = (otmp->cursed && otmp->owornmask); 324.  325.  	    if (ostuck || !can_carry(mtmp, otmp)) { 326. 		static const char * const how[] = { "steal","snatch","grab","take" }; 327.  cant_take: 328. 		pline("%s tries to %s your %s but gives up.",  329.  		      Monnam(mtmp), how[rn2(SIZE(how))],  330.  		      (otmp->owornmask & W_ARMOR) ? equipname(otmp) :  331.  		       cxname(otmp)); 332. 		/* the fewer items you have, the less likely the thief 333. 		   is going to stick around to try again (0) instead of  334. running away (1) */ 335. 		return !rn2(inv_cnt / 5 + 2); 336. 	    }  337.  	}  338.   339.  	if (otmp->otyp == LEASH && otmp->leashmon) { 340. 	    if (monkey_business && otmp->cursed) goto cant_take; 341. 	    o_unleash(otmp); 342. 	}  343.   344.  	/* you're going to notice the theft... */ 345.  	stop_occupation; 346.  347.  	if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){ 348. 		switch(otmp->oclass) { 349. 		case TOOL_CLASS: 350. 		case AMULET_CLASS: 351. 		case RING_CLASS: 352. 		case FOOD_CLASS: /* meat ring */ 353. 		    remove_worn_item(otmp, TRUE); 354. 		    break; 355. 		case ARMOR_CLASS: 356. 		    armordelay = objects[otmp->otyp].oc_delay; 357. 		    /* Stop putting on armor which has been stolen. */ 358.  		    if (donning(otmp) || is_animal(mtmp->data)) { 359. 			remove_worn_item(otmp, TRUE); 360. 			break; 361. 		    } else if (monkey_business) { 362. 			/* animals usually don't have enough patience 363. 			   to take off items which require extra time */ 364. 			if (armordelay >= 1 && rn2(10)) goto cant_take; 365. 			remove_worn_item(otmp, TRUE); 366. 			break; 367. 		    } else { 368. 			int curssv = otmp->cursed; 369. 			int slowly; 370. 			boolean seen = canspotmon(mtmp); 371. 			char pronoun[4]; 372.  373.  			if (!seen) { 374. 			    strcpy(pronoun, mhe(mtmp)); 375. 			    pronoun[0] = highc(pronoun[0]); 376. 			}  377.  			otmp->cursed = 0; 378. 			/* can't charm you without first waking you */ 379. 			if (multi < 0 && is_fainted) unmul((char *)0); 380. 			slowly = (armordelay >= 1 || multi < 0); 381. 			if (do_charm) { 382. 			    char action[15]; 383. 			    if (curssv) 384. 				sprintf(action, "let %s take",  385.  					mhis(mtmp)); 386. 			    else 387. 				strcpy(action, slowly ?  388.  					"start removing" : "hand over"); 389. 			    pline("%s charms you.  You gladly %s your %s.",  390.  				  !seen ? pronoun : Monnam(mtmp), action,  391.  				  equipname(otmp)); 392. 			}  393.  			else 394. 			    pline("%s seduces you and %s off your %s.",  395.  				  !seen ? pronoun : Adjmonnam(mtmp, 396. 				  mtmp->female ? "beautiful" : "handsome"), 397.  				  curssv ? "helps you to take" :  398.  				  slowly ? "you start taking" : "you take",  399.  				  equipname(otmp)); 400. 			named++; 401. 			/* the following is to set multi for later on */ 402. 			nomul(-armordelay); 403. 			nomovemsg = 0; 404. 			remove_worn_item(otmp, TRUE); 405. 			otmp->cursed = curssv; 406. 			if(multi < 0){ 407. 				/*  408.  				multi = 0; 409. 				nomovemsg = 0; 410. 				afternmv = 0; 411. 				*/  412.  				stealoid = otmp->o_id; 413. 				stealmid = mtmp->m_id; 414. 				afternmv = stealarm; 415. 				return(0); 416. 			}  417.  		    }  418.  		    break; 419. 		default: 420. 		    impossible("Tried to steal a strange worn thing. [%d]",  421.  			       otmp->oclass); 422. 		}  423.  	}  424.  	else if (otmp->owornmask) 425. 	    remove_worn_item(otmp, TRUE); 426.  427.  	/* do this before removing it from inventory */ 428. 	if (objnambuf) Strcpy(objnambuf, yname(otmp)); 429. 	/* set mavenge bit so knights won't suffer an  430. * alignment penalty during retaliation; 431. 	 */  432.  	mtmp->mavenge = 1; 433.  434.  	freeinv(otmp); 435. 	pline("%s stole %s.", named ? "It" : Monnam(mtmp), doname(otmp)); 436. 	could_petrify = (otmp->otyp == CORPSE &&  437.  			 touch_petrifies(&mons[otmp->corpsenm])); 438. 	(void) mpickobj(mtmp,otmp);	/* may free otmp */ 439. 	if (could_petrify && !(mtmp->misc_worn_check & W_ARMG)) { 440. 	    minstapetrify(mtmp, TRUE); 441. 	    return -1; 442. 	}  443.  	return((multi < 0) ? 0 : 1); 444. }  445.   446.  #endif /* OVLB */ 447. #ifdef OVL1 448.  449.  /* Returns 1 if otmp is free'd, 0 otherwise. */ 450.  int 451. mpickobj(mtmp,otmp) 452. register struct monst *mtmp; 453. register struct obj *otmp; 454. {  455.      int freed_otmp; 456.  457.  #ifndef GOLDOBJ 458.     if (otmp->oclass == COIN_CLASS) { 459. 	mtmp->mgold += otmp->quan; 460. 	obfree(otmp, (struct obj *)0); 461. 	freed_otmp = 1; 462.     } else { 463. #endif 464.     boolean snuff_otmp = FALSE; 465.     /* don't want hidden light source inside the monster; assumes that 466.        engulfers won't have external inventories; whirly monsters cause 467.        the light to be extinguished rather than letting it shine thru */ 468.     if (otmp->lamplit &&  /* hack to avoid function calls for most objs */  469.        	obj_sheds_light(otmp) &&  470.  	attacktype(mtmp->data, AT_ENGL)) { 471. 	/* this is probably a burning object that you dropped or threw */ 472. 	if (u.uswallow && mtmp == u.ustuck && !Blind) 473. 	    pline("%s out.", Tobjnam(otmp, "go")); 474. 	snuff_otmp = TRUE; 475.     }  476.      /* Must do carrying effects on object prior to add_to_minv */ 477.     carry_obj_effects(mtmp, otmp); 478.     /* add_to_minv might free otmp [if merged with something else], 479.        so we have to call it after doing the object checks */ 480.     freed_otmp = add_to_minv(mtmp, otmp); 481.     /* and we had to defer this until object is in mtmp's inventory */ 482.     if (snuff_otmp) snuff_light_source(mtmp->mx, mtmp->my); 483. #ifndef GOLDOBJ 484.     }  485.  #endif 486.     return freed_otmp; 487. }  488.   489.  #endif /* OVL1 */ 490. #ifdef OVLB 491.  492.  void 493. stealamulet(mtmp) 494. struct monst *mtmp; 495. {  496.      struct obj *otmp = (struct obj *)0; 497.     int real=0, fake=0; 498.  499.      /* select the artifact to steal */ 500.     if(u.uhave.amulet) { 501. 	real = AMULET_OF_YENDOR; 502. 	fake = FAKE_AMULET_OF_YENDOR; 503.     } else if(u.uhave.questart) { 504. 	for(otmp = invent; otmp; otmp = otmp->nobj) 505. 	    if(is_quest_artifact(otmp)) break; 506. 	if (!otmp) return;	/* should we panic instead? */ 507.      } else if(u.uhave.bell) { 508. 	real = BELL_OF_OPENING; 509. 	fake = BELL; 510.     } else if(u.uhave.book) { 511. 	real = SPE_BOOK_OF_THE_DEAD; 512.     } else if(u.uhave.menorah) { 513. 	real = CANDELABRUM_OF_INVOCATION; 514.     } else return;	/* you have nothing of special interest */ 515.  516.      if (!otmp) { 517. 	/* If we get here, real and fake have been set up. */ 518.  	for(otmp = invent; otmp; otmp = otmp->nobj) 519. 	    if(otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz)) 520. 		break; 521.     }  522.   523.      if (otmp) { /* we have something to snatch */ 524. 	if (otmp->owornmask) 525. 	    remove_worn_item(otmp, TRUE); 526. 	freeinv(otmp); 527. 	/* mpickobj wont merge otmp because none of the above things 528. 	   to steal are mergable */ 529. 	(void) mpickobj(mtmp,otmp);	/* may merge and free otmp */ 530. 	pline("%s stole %s!", Monnam(mtmp), doname(otmp)); 531. 	if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) 532. 	    (void) rloc(mtmp, FALSE); 533.     }  534.  }  535.   536.  #endif /* OVLB */ 537. #ifdef OVL0 538.  539.  /* drop one object taken from a (possibly dead) monster's inventory */ 540. STATIC_OVL void 541. mdrop_obj(mon, obj, verbosely) 542. struct monst *mon; 543. struct obj *obj; 544. boolean verbosely; 545. {  546.      int omx = mon->mx, omy = mon->my; 547.  548.      if (obj->owornmask) { 549. 	/* perform worn item handling if the monster is still alive */ 550. 	if (mon->mhp > 0) { 551. 	    mon->misc_worn_check &= ~obj->owornmask; 552. 	    update_mon_intrinsics(mon, obj, FALSE, TRUE); 553. 	 /* obj_no_longer_held(obj); -- done by place_object */ 554. 	    if (obj->owornmask & W_WEP) setmnotwielded(mon, obj); 555. #ifdef STEED 556. 	/* don't charge for an owned saddle on dead steed */ 557. 	} else if (mon->mtame && (obj->owornmask & W_SADDLE) &&  558.  		!obj->unpaid && costly_spot(omx, omy)) { 559. 	    obj->no_charge = 1; 560. #endif 561. 	}  562.  	obj->owornmask = 0L; 563.     }  564.      if (verbosely && cansee(omx, omy)) 565. 	pline("%s drops %s.", Monnam(mon), distant_name(obj, doname)); 566.     if (!flooreffects(obj, omx, omy, "fall")) { 567. 	place_object(obj, omx, omy); 568. 	stackobj(obj); 569.     }  570.  }  571.   572.  /* some monsters bypass the normal rules for moving between levels or  573. even leaving the game entirely; when that happens, prevent them from 574.    taking the Amulet or invocation tools with them */ 575. void 576. mdrop_special_objs(mon) 577. struct monst *mon; 578. {  579.      struct obj *obj, *otmp; 580.  581.      for (obj = mon->minvent; obj; obj = otmp) { 582. 	otmp = obj->nobj; 583. 	/* the Amulet, invocation tools, and Rider corpses resist even when 584. 	   artifacts and ordinary objects are given 0% resistance chance */ 585. 	if (obj_resists(obj, 0, 0)) { 586. 	    obj_extract_self(obj); 587. 	    mdrop_obj(mon, obj, FALSE); 588. 	}  589.      }  590.  }  591.   592.  /* release the objects the creature is carrying */ 593. void 594. relobj(mtmp,show,is_pet) 595. register struct monst *mtmp; 596. register int show; 597. boolean is_pet;		/* If true, pet should keep wielded/worn items */ 598. {  599.  	register struct obj *otmp; 600. 	register int omx = mtmp->mx, omy = mtmp->my; 601. 	struct obj *keepobj = 0; 602. 	struct obj *wep = MON_WEP(mtmp); 603. 	boolean item1 = FALSE, item2 = FALSE; 604.  605.  	if (!is_pet || mindless(mtmp->data) || is_animal(mtmp->data)) 606. 		item1 = item2 = TRUE; 607. 	if (!tunnels(mtmp->data) || !needspick(mtmp->data)) 608. 		item1 = TRUE; 609.  610.  	while ((otmp = mtmp->minvent) != 0) { 611. 		obj_extract_self(otmp); 612. 		/* special case: pick-axe and unicorn horn are non-worn */ 613. 		/* items that we also want pets to keep 1 of */ 614. 		/* (It is a coincidence that these can also be wielded.) */ 615. 		if (otmp->owornmask || otmp == wep ||  616.  		    ((!item1 && otmp->otyp == PICK_AXE) || 617. 		     (!item2 && otmp->otyp == UNICORN_HORN && !otmp->cursed))) { 618. 			if (is_pet) { /* dont drop worn/wielded item */ 619. 				if (otmp->otyp == PICK_AXE) 620. 					item1 = TRUE; 621. 				if (otmp->otyp == UNICORN_HORN && !otmp->cursed) 622. 					item2 = TRUE; 623. 				otmp->nobj = keepobj; 624. 				keepobj = otmp; 625. 				continue; 626. 			}  627.  		}  628.  		mdrop_obj(mtmp, otmp, is_pet && flags.verbose); 629. 	}  630.   631.  	/* put kept objects back */ 632. 	while ((otmp = keepobj) != (struct obj *)0) { 633. 	    keepobj = otmp->nobj; 634. 	    (void) add_to_minv(mtmp, otmp); 635. 	}  636.  #ifndef GOLDOBJ 637. 	if (mtmp->mgold) { 638. 		register long g = mtmp->mgold; 639. 		(void) mkgold(g, omx, omy); 640. 		if (is_pet && cansee(omx, omy) && flags.verbose) 641. 			pline("%s drops %ld gold piece%s.", Monnam(mtmp),  642.  				g, plur(g)); 643. 		mtmp->mgold = 0L; 644. 	}  645.  #endif 646. 	  647.  	if (show & cansee(omx, omy)) 648. 		newsym(omx, omy); 649. }  650.   651.  #endif /* OVL0 */ 652.  653.  /*steal.c*/