Source:Steal.c

Below is the full text to src/steal.c from NetHack 3.4.3. To link to a particular line, write [[steal.c#line123 ]], for example. 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.  241.  	if (objnambuf) *objnambuf = '\0'; 242. 	/* the following is true if successful on first of two attacks. */ 243.  	if(!monnear(mtmp, u.ux, u.uy)) return(0); 244.  245.  	/* food being eaten might already be used up but will not have 246. 	   been removed from inventory yet; we don't want to steal that, 247. 	   so this will cause it to be removed now */ 248. 	if (occupation) (void) maybe_finished_meal(FALSE); 249.  250.  	if (!invent || (inv_cnt == 1 && uskin)) { 251. nothing_to_steal: 252. 	    /* Not even a thousand men in armor can strip a naked man. */ 253.  	    if(Blind) 254. 	      pline("Somebody tries to rob you, but finds nothing to steal."); 255. 	    else 256. 	      pline("%s tries to rob you, but there is nothing to steal!",  257.  		Monnam(mtmp)); 258. 	    return(1);	/* let her flee */ 259. 	}  260.   261.  	monkey_business = is_animal(mtmp->data); 262. 	if (monkey_business) { 263. 	    ;	/* skip ring special cases */ 264. 	} else if (Adornment & LEFT_RING) { 265. 	    otmp = uleft; 266. 	    goto gotobj; 267. 	} else if (Adornment & RIGHT_RING) { 268. 	    otmp = uright; 269. 	    goto gotobj; 270. 	}  271.   272.  	tmp = 0; 273. 	for(otmp = invent; otmp; otmp = otmp->nobj) 274. 	    if ((!uarm || otmp != uarmc) && otmp != uskin  275.  #ifdef INVISIBLE_OBJECTS  276.  				&& (!otmp->oinvis || perceives(mtmp->data))  277.  #endif  278.  				) 279. 		tmp += ((otmp->owornmask & 280. 			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1); 281. 	if (!tmp) goto nothing_to_steal; 282. 	tmp = rn2(tmp); 283. 	for(otmp = invent; otmp; otmp = otmp->nobj) 284. 	    if ((!uarm || otmp != uarmc) && otmp != uskin  285.  #ifdef INVISIBLE_OBJECTS  286.  				&& (!otmp->oinvis || perceives(mtmp->data))  287.  #endif  288.  			) 289. 		if((tmp -= ((otmp->owornmask & 290. 			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0) 291. 			break; 292. 	if(!otmp) { 293. 		impossible("Steal fails!"); 294. 		return(0); 295. 	}  296.  	/* can't steal gloves while wielding - so steal the wielded item. */ 297.  	if (otmp == uarmg && uwep) 298. 	    otmp = uwep; 299. 	/* can't steal armor while wearing cloak - so steal the cloak. */ 300.  	else if(otmp == uarm && uarmc) otmp = uarmc; 301. #ifdef TOURIST 302. 	else if(otmp == uarmu && uarmc) otmp = uarmc; 303. 	else if(otmp == uarmu && uarm) otmp = uarm; 304. #endif 305. gotobj: 306. 	if(otmp->o_id == stealoid) return(0); 307.  308.  	/* animals can't overcome curse stickiness nor unlock chains */ 309. 	if (monkey_business) { 310. 	    boolean ostuck; 311. 	    /* is the player prevented from voluntarily giving up this item? 312. 	       (ignores loadstones; the !can_carry check will catch those) */ 313. 	    if (otmp == uball) 314. 		ostuck = TRUE;	/* effectively worn; curse is implicit */ 315. 	    else if (otmp == uquiver || (otmp == uswapwep && !u.twoweap)) 316. 		ostuck = FALSE;	/* not really worn; curse doesn't matter */ 317. 	    else 318. 		ostuck = (otmp->cursed && otmp->owornmask); 319.  320.  	    if (ostuck || !can_carry(mtmp, otmp)) { 321. 		static const char * const how[] = { "steal","snatch","grab","take" }; 322.  cant_take: 323. 		pline("%s tries to %s your %s but gives up.",  324.  		      Monnam(mtmp), how[rn2(SIZE(how))],  325.  		      (otmp->owornmask & W_ARMOR) ? equipname(otmp) :  326.  		       cxname(otmp)); 327. 		/* the fewer items you have, the less likely the thief 328. 		   is going to stick around to try again (0) instead of  329. running away (1) */ 330. 		return !rn2(inv_cnt / 5 + 2); 331. 	    }  332.  	}  333.   334.  	if (otmp->otyp == LEASH && otmp->leashmon) { 335. 	    if (monkey_business && otmp->cursed) goto cant_take; 336. 	    o_unleash(otmp); 337. 	}  338.   339.  	/* you're going to notice the theft... */ 340.  	stop_occupation; 341.  342.  	if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){ 343. 		switch(otmp->oclass) { 344. 		case TOOL_CLASS: 345. 		case AMULET_CLASS: 346. 		case RING_CLASS: 347. 		case FOOD_CLASS: /* meat ring */ 348. 		    remove_worn_item(otmp, TRUE); 349. 		    break; 350. 		case ARMOR_CLASS: 351. 		    armordelay = objects[otmp->otyp].oc_delay; 352. 		    /* Stop putting on armor which has been stolen. */ 353.  		    if (donning(otmp)) { 354. 			remove_worn_item(otmp, TRUE); 355. 			break; 356. 		    } else if (monkey_business) { 357. 			/* animals usually don't have enough patience 358. 			   to take off items which require extra time */ 359. 			if (armordelay >= 1 && rn2(10)) goto cant_take; 360. 			remove_worn_item(otmp, TRUE); 361. 			break; 362. 		    } else { 363. 			int curssv = otmp->cursed; 364. 			int slowly; 365. 			boolean seen = canspotmon(mtmp); 366.  367.  			otmp->cursed = 0; 368. 			/* can't charm you without first waking you */ 369. 			if (multi < 0 && is_fainted) unmul((char *)0); 370. 			slowly = (armordelay >= 1 || multi < 0); 371. 			if(flags.female) 372. 			    pline("%s charms you.  You gladly %s your %s.",  373.  				  !seen ? "She" : Monnam(mtmp),  374.  				  curssv ? "let her take" :  375.  				  slowly ? "start removing" : "hand over",  376.  				  equipname(otmp)); 377. 			else 378. 			    pline("%s seduces you and %s off your %s.",  379.  				  !seen ? "She" : Adjmonnam(mtmp, "beautiful"),  380.  				  curssv ? "helps you to take" :  381.  				  slowly ? "you start taking" : "you take",  382.  				  equipname(otmp)); 383. 			named++; 384. 			/* the following is to set multi for later on */ 385. 			nomul(-armordelay); 386. 			remove_worn_item(otmp, TRUE); 387. 			otmp->cursed = curssv; 388. 			if(multi < 0){ 389. 				/*  390.  				multi = 0; 391. 				nomovemsg = 0; 392. 				afternmv = 0; 393. 				*/  394.  				stealoid = otmp->o_id; 395. 				stealmid = mtmp->m_id; 396. 				afternmv = stealarm; 397. 				return(0); 398. 			}  399.  		    }  400.  		    break; 401. 		default: 402. 		    impossible("Tried to steal a strange worn thing. [%d]",  403.  			       otmp->oclass); 404. 		}  405.  	}  406.  	else if (otmp->owornmask) 407. 	    remove_worn_item(otmp, TRUE); 408.  409.  	/* do this before removing it from inventory */ 410. 	if (objnambuf) Strcpy(objnambuf, yname(otmp)); 411. 	/* set mavenge bit so knights won't suffer an  412. * alignment penalty during retaliation; 413. 	 */  414.  	mtmp->mavenge = 1; 415.  416.  	freeinv(otmp); 417. 	pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp)); 418. 	could_petrify = (otmp->otyp == CORPSE &&  419.  			 touch_petrifies(&mons[otmp->corpsenm])); 420. 	(void) mpickobj(mtmp,otmp);	/* may free otmp */ 421. 	if (could_petrify && !(mtmp->misc_worn_check & W_ARMG)) { 422. 	    minstapetrify(mtmp, TRUE); 423. 	    return -1; 424. 	}  425.  	return((multi < 0) ? 0 : 1); 426. }  427.   428.  #endif /* OVLB */ 429. #ifdef OVL1 430.  431.  /* Returns 1 if otmp is free'd, 0 otherwise. */ 432.  int 433. mpickobj(mtmp,otmp) 434. register struct monst *mtmp; 435. register struct obj *otmp; 436. {  437.      int freed_otmp; 438.  439.  #ifndef GOLDOBJ 440.     if (otmp->oclass == COIN_CLASS) { 441. 	mtmp->mgold += otmp->quan; 442. 	obfree(otmp, (struct obj *)0); 443. 	freed_otmp = 1; 444.     } else { 445. #endif 446.     boolean snuff_otmp = FALSE; 447.     /* don't want hidden light source inside the monster; assumes that 448.        engulfers won't have external inventories; whirly monsters cause 449.        the light to be extinguished rather than letting it shine thru */ 450.     if (otmp->lamplit &&  /* hack to avoid function calls for most objs */  451.        	obj_sheds_light(otmp) &&  452.  	attacktype(mtmp->data, AT_ENGL)) { 453. 	/* this is probably a burning object that you dropped or threw */ 454. 	if (u.uswallow && mtmp == u.ustuck && !Blind) 455. 	    pline("%s out.", Tobjnam(otmp, "go")); 456. 	snuff_otmp = TRUE; 457.     }  458.      /* Must do carrying effects on object prior to add_to_minv */ 459.     carry_obj_effects(otmp); 460.     /* add_to_minv might free otmp [if merged with something else], 461.        so we have to call it after doing the object checks */ 462.     freed_otmp = add_to_minv(mtmp, otmp); 463.     /* and we had to defer this until object is in mtmp's inventory */ 464.     if (snuff_otmp) snuff_light_source(mtmp->mx, mtmp->my); 465. #ifndef GOLDOBJ 466.     }  467.  #endif 468.     return freed_otmp; 469. }  470.   471.  #endif /* OVL1 */ 472. #ifdef OVLB 473.  474.  void 475. stealamulet(mtmp) 476. struct monst *mtmp; 477. {  478.      struct obj *otmp = (struct obj *)0; 479.     int real=0, fake=0; 480.  481.      /* select the artifact to steal */ 482.     if(u.uhave.amulet) { 483. 	real = AMULET_OF_YENDOR; 484. 	fake = FAKE_AMULET_OF_YENDOR; 485.     } else if(u.uhave.questart) { 486. 	for(otmp = invent; otmp; otmp = otmp->nobj) 487. 	    if(is_quest_artifact(otmp)) break; 488. 	if (!otmp) return;	/* should we panic instead? */ 489.      } else if(u.uhave.bell) { 490. 	real = BELL_OF_OPENING; 491. 	fake = BELL; 492.     } else if(u.uhave.book) { 493. 	real = SPE_BOOK_OF_THE_DEAD; 494.     } else if(u.uhave.menorah) { 495. 	real = CANDELABRUM_OF_INVOCATION; 496.     } else return;	/* you have nothing of special interest */ 497.  498.      if (!otmp) { 499. 	/* If we get here, real and fake have been set up. */ 500.  	for(otmp = invent; otmp; otmp = otmp->nobj) 501. 	    if(otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz)) 502. 		break; 503.     }  504.   505.      if (otmp) { /* we have something to snatch */ 506. 	if (otmp->owornmask) 507. 	    remove_worn_item(otmp, TRUE); 508. 	freeinv(otmp); 509. 	/* mpickobj wont merge otmp because none of the above things 510. 	   to steal are mergable */ 511. 	(void) mpickobj(mtmp,otmp);	/* may merge and free otmp */ 512. 	pline("%s stole %s!", Monnam(mtmp), doname(otmp)); 513. 	if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) 514. 	    (void) rloc(mtmp, FALSE); 515.     }  516.  }  517.   518.  #endif /* OVLB */ 519. #ifdef OVL0 520.  521.  /* drop one object taken from a (possibly dead) monster's inventory */ 522. STATIC_OVL void 523. mdrop_obj(mon, obj, verbosely) 524. struct monst *mon; 525. struct obj *obj; 526. boolean verbosely; 527. {  528.      int omx = mon->mx, omy = mon->my; 529.  530.      if (obj->owornmask) { 531. 	/* perform worn item handling if the monster is still alive */ 532. 	if (mon->mhp > 0) { 533. 	    mon->misc_worn_check &= ~obj->owornmask; 534. 	    update_mon_intrinsics(mon, obj, FALSE, TRUE); 535. 	 /* obj_no_longer_held(obj); -- done by place_object */ 536. 	    if (obj->owornmask & W_WEP) setmnotwielded(mon, obj); 537. #ifdef STEED 538. 	/* don't charge for an owned saddle on dead steed */ 539. 	} else if (mon->mtame && (obj->owornmask & W_SADDLE) &&  540.  		!obj->unpaid && costly_spot(omx, omy)) { 541. 	    obj->no_charge = 1; 542. #endif 543. 	}  544.  	obj->owornmask = 0L; 545.     }  546.      if (verbosely && cansee(omx, omy)) 547. 	pline("%s drops %s.", Monnam(mon), distant_name(obj, doname)); 548.     if (!flooreffects(obj, omx, omy, "fall")) { 549. 	place_object(obj, omx, omy); 550. 	stackobj(obj); 551.     }  552.  }  553.   554.  /* some monsters bypass the normal rules for moving between levels or  555. even leaving the game entirely; when that happens, prevent them from 556.    taking the Amulet or invocation tools with them */ 557. void 558. mdrop_special_objs(mon) 559. struct monst *mon; 560. {  561.      struct obj *obj, *otmp; 562.  563.      for (obj = mon->minvent; obj; obj = otmp) { 564. 	otmp = obj->nobj; 565. 	/* the Amulet, invocation tools, and Rider corpses resist even when 566. 	   artifacts and ordinary objects are given 0% resistance chance */ 567. 	if (obj_resists(obj, 0, 0)) { 568. 	    obj_extract_self(obj); 569. 	    mdrop_obj(mon, obj, FALSE); 570. 	}  571.      }  572.  }  573.   574.  /* release the objects the creature is carrying */ 575. void 576. relobj(mtmp,show,is_pet) 577. register struct monst *mtmp; 578. register int show; 579. boolean is_pet;		/* If true, pet should keep wielded/worn items */ 580. {  581.  	register struct obj *otmp; 582. 	register int omx = mtmp->mx, omy = mtmp->my; 583. 	struct obj *keepobj = 0; 584. 	struct obj *wep = MON_WEP(mtmp); 585. 	boolean item1 = FALSE, item2 = FALSE; 586.  587.  	if (!is_pet || mindless(mtmp->data) || is_animal(mtmp->data)) 588. 		item1 = item2 = TRUE; 589. 	if (!tunnels(mtmp->data) || !needspick(mtmp->data)) 590. 		item1 = TRUE; 591.  592.  	while ((otmp = mtmp->minvent) != 0) { 593. 		obj_extract_self(otmp); 594. 		/* special case: pick-axe and unicorn horn are non-worn */ 595. 		/* items that we also want pets to keep 1 of */ 596. 		/* (It is a coincidence that these can also be wielded.) */ 597. 		if (otmp->owornmask || otmp == wep ||  598.  		    ((!item1 && otmp->otyp == PICK_AXE) || 599. 		     (!item2 && otmp->otyp == UNICORN_HORN && !otmp->cursed))) { 600. 			if (is_pet) { /* dont drop worn/wielded item */ 601. 				if (otmp->otyp == PICK_AXE) 602. 					item1 = TRUE; 603. 				if (otmp->otyp == UNICORN_HORN && !otmp->cursed) 604. 					item2 = TRUE; 605. 				otmp->nobj = keepobj; 606. 				keepobj = otmp; 607. 				continue; 608. 			}  609.  		}  610.  		mdrop_obj(mtmp, otmp, is_pet && flags.verbose); 611. 	}  612.   613.  	/* put kept objects back */ 614. 	while ((otmp = keepobj) != (struct obj *)0) { 615. 	    keepobj = otmp->nobj; 616. 	    (void) add_to_minv(mtmp, otmp); 617. 	}  618.  #ifndef GOLDOBJ 619. 	if (mtmp->mgold) { 620. 		register long g = mtmp->mgold; 621. 		(void) mkgold(g, omx, omy); 622. 		if (is_pet && cansee(omx, omy) && flags.verbose) 623. 			pline("%s drops %ld gold piece%s.", Monnam(mtmp),  624.  				g, plur(g)); 625. 		mtmp->mgold = 0L; 626. 	}  627.  #endif 628. 	  629.  	if (show & cansee(omx, omy)) 630. 		newsym(omx, omy); 631. }  632.   633.  #endif /* OVL0 */ 634.  635.  /*steal.c*/