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 *
equipname(otmp)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 */
somegold()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
stealgold(mtmp)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 */
somegold(umoney)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 *
findgold(chain)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
stealgold(mtmp)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
stealarm()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
remove_worn_item(obj,unchain_ball)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
steal(mtmp,objnambuf)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
mpickobj(mtmp,otmp)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
stealamulet(mtmp)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
mdrop_obj(mon,obj,verbosely)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
mdrop_special_objs(mon)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
relobj(mtmp,show,is_pet)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*/
636