Wikihack
Register
Advertisement

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.

Top of File[]

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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.   

equipname[]

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.   

somegold without GOLDOBJ[]

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.   

stealgold without GOLDOBJ[]

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.   

somegold with GOLDOBJ[]

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.   

findgold[]

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.   

stealgold with GOLDOBJ[]

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.  

stealarm[]

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.  

remove_worn_item[]

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.  

steal[]

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 */

mpickobj[]

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 */

stealamulet[]

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 */

mdrop_obj[]

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.  

mdrop_special_objs[]

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.  

relobj[]

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*/
Advertisement