FANDOM


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.


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

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.