Source:NetHack 3.2.0/steal.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to steal.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/steal.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)steal.c	3.2	96/04/08	*/
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 const char * FDECL(equipname, (struct obj *));
11.   static void FDECL(lose_worn_item, (struct obj *));
12.   
13.   static 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" :
25.   		(otmp == uarmh) ? "helmet" : "armor");
26.   }
27.   
28.   long		/* actually returns something that fits in an int */
29.   somegold()
30.   {
31.   #ifdef LINT	/* long conv. ok */
32.   	return(0L);
33.   #else
34.   	return (long)( (u.ugold < 100) ? u.ugold :
35.   		(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
36.   #endif
37.   }
38.   
39.   void
40.   stealgold(mtmp)
41.   register struct monst *mtmp;
42.   {
43.   	register struct obj *gold = g_at(u.ux, u.uy);
44.   	register long tmp;
45.   
46.   	if (gold && ( !u.ugold || gold->quan > u.ugold || !rn2(5))) {
47.   	    mtmp->mgold += gold->quan;
48.   	    delobj(gold);
49.   	    newsym(u.ux, u.uy);
50.   	    pline("%s quickly snatches some gold from between your %s!",
51.   		    Monnam(mtmp), makeplural(body_part(FOOT)));
52.   	    if(!u.ugold || !rn2(5)) {
53.   		if (!tele_restrict(mtmp)) rloc(mtmp);
54.   		mtmp->mflee = 1;
55.   	    }
56.   	} else if(u.ugold) {
57.   	    u.ugold -= (tmp = somegold());
58.   	    Your("purse feels lighter.");
59.   	    mtmp->mgold += tmp;
60.   	    if (!tele_restrict(mtmp)) rloc(mtmp);
61.   	    mtmp->mflee = 1;
62.   	    flags.botl = 1;
63.   	}
64.   }
65.   
66.   /* steal armor after you finish taking it off */
67.   unsigned int stealoid;		/* object to be stolen */
68.   unsigned int stealmid;		/* monster doing the stealing */
69.   
70.   STATIC_PTR int
71.   stealarm()
72.   {
73.   	register struct monst *mtmp;
74.   	register struct obj *otmp;
75.   
76.   	for(otmp = invent; otmp; otmp = otmp->nobj) {
77.   	    if(otmp->o_id == stealoid) {
78.   		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
79.   		    if(mtmp->m_id == stealmid) {
80.   			if(!dmgtype(mtmp->data, AD_SITM)) /* polymorphed */
81.   			    goto botm;
82.   			if(otmp->unpaid)
83.   			    subfrombill(otmp, shop_keeper(*u.ushops));
84.   			freeinv(otmp);
85.   			pline("%s steals %s!", Monnam(mtmp), doname(otmp));
86.   			mpickobj(mtmp,otmp);
87.   			mtmp->mflee = 1;
88.   			if (!tele_restrict(mtmp)) rloc(mtmp);
89.   		        break;
90.   		    }
91.   		}
92.   		break;
93.   	    }
94.   	}
95.   botm:   stealoid = 0;
96.   	return 0;
97.   }
98.   
99.   /* an object you're wearing has been stolen */
100.  static void
101.  lose_worn_item(obj)
102.  struct obj *obj;
103.  {
104.  	if (donning(obj))
105.  	    cancel_don();
106.  	if (!obj->owornmask)
107.  	    return;
108.  
109.  	switch (obj->oclass) {
110.  	 case TOOL_CLASS:
111.  	    Blindf_off(obj);
112.  	    break;
113.  	 case AMULET_CLASS:
114.  	    Amulet_off();
115.  	    break;
116.  	 case RING_CLASS:
117.  	    Ring_gone(obj);
118.  	    break;
119.  	 case ARMOR_CLASS:
120.  	    if (obj == uarm) (void) Armor_off();
121.  	    else if (obj == uarmc) (void) Cloak_off();
122.  	    else if (obj == uarmf) (void) Boots_off();
123.  	    else if (obj == uarmg) (void) Gloves_off();
124.  	    else if (obj == uarmh) (void) Helmet_off();
125.  	    else if (obj == uarms) (void) Shield_off();
126.  	    else setworn((struct obj *)0, obj->owornmask & W_ARMOR);
127.  	    break;
128.  	 default:
129.  	    /* shouldn't reach here, but just in case... */
130.  	    setnotworn(obj);
131.  	    break;
132.  	}
133.  }
134.  
135.  /* Returns 1 when something was stolen (or at least, when N should flee now)
136.   * Returns -1 if the monster died in the attempt
137.   * Avoid stealing the object stealoid
138.   */
139.  int
140.  steal(mtmp)
141.  struct monst *mtmp;
142.  {
143.  	register struct obj *otmp;
144.  	register int tmp;
145.  	register int named = 0;
146.  
147.  	/* the following is true if successful on first of two attacks. */
148.  	if(!monnear(mtmp, u.ux, u.uy)) return(0);
149.  
150.  	if (!invent || (inv_cnt() == 1 && uskin)) {
151.  	    /* Not even a thousand men in armor can strip a naked man. */
152.  	    if(Blind)
153.  	      pline("Somebody tries to rob you, but finds nothing to steal.");
154.  	    else
155.  	      pline("%s tries to rob you, but she finds nothing to steal!",
156.  		Monnam(mtmp));
157.  	    return(1);	/* let her flee */
158.  	}
159.  
160.  	if(Adornment & LEFT_RING) {
161.  	    otmp = uleft;
162.  	    goto gotobj;
163.  	} else if(Adornment & RIGHT_RING) {
164.  	    otmp = uright;
165.  	    goto gotobj;
166.  	}
167.  
168.  	tmp = 0;
169.  	for(otmp = invent; otmp; otmp = otmp->nobj)
170.  	    if ((!uarm || otmp != uarmc) && otmp != uskin)
171.  		tmp += ((otmp->owornmask &
172.  			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1);
173.  	tmp = rn2(tmp);
174.  	for(otmp = invent; otmp; otmp = otmp->nobj)
175.  	    if ((!uarm || otmp != uarmc) && otmp != uskin)
176.  		if((tmp -= ((otmp->owornmask &
177.  			(W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1)) < 0)
178.  			break;
179.  	if(!otmp) {
180.  		impossible("Steal fails!");
181.  		return(0);
182.  	}
183.  	/* can't steal gloves while wielding - so steal the wielded item. */
184.  	if (otmp == uarmg && uwep)
185.  	    otmp = uwep;
186.  	/* can't steal armor while wearing cloak - so steal the cloak. */
187.  	else if(otmp == uarm && uarmc) otmp = uarmc;
188.  #ifdef TOURIST
189.  	else if(otmp == uarmu && uarmc) otmp = uarmc;
190.  	else if(otmp == uarmu && uarm) otmp = uarm;
191.  #endif
192.  gotobj:
193.  	if(otmp->o_id == stealoid) return(0);
194.  
195.  	if(otmp->otyp == LEASH && otmp->leashmon) o_unleash(otmp);
196.  
197.  	if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){
198.  		switch(otmp->oclass) {
199.  		case TOOL_CLASS:
200.  		case AMULET_CLASS:
201.  		case RING_CLASS:
202.  			lose_worn_item(otmp);
203.  			break;
204.  		case ARMOR_CLASS:
205.  			/* Stop putting on armor which has been stolen. */
206.  			if (donning(otmp)) {
207.  			    lose_worn_item(otmp);
208.  			    break;
209.  			}
210.  		    {	int curssv = otmp->cursed;
211.  			otmp->cursed = 0;
212.  			stop_occupation();
213.  			if(flags.female)
214.  			    pline("%s charms you.  You gladly %s your %s.",
215.  				  Blind ? "She" : Monnam(mtmp),
216.  				  curssv ? "let her take" : "hand over",
217.  				  equipname(otmp));
218.  			else
219.  			    pline("%s seduces you and %s off your %s.",
220.  				  Blind ? "It" : Adjmonnam(mtmp, "beautiful"),
221.  				  curssv ? "helps you to take" :
222.  	(objects[otmp->otyp].oc_delay > 1) ? "you start taking" : "you take",
223.  				  equipname(otmp));
224.  			named++;
225.  			/* the following is to set multi for later on */
226.  			nomul(-objects[otmp->otyp].oc_delay);
227.  			lose_worn_item(otmp);
228.  			otmp->cursed = curssv;
229.  			if(multi < 0){
230.  				/*
231.  				multi = 0;
232.  				nomovemsg = 0;
233.  				afternmv = 0;
234.  				*/
235.  				stealoid = otmp->o_id;
236.  				stealmid = mtmp->m_id;
237.  				afternmv = stealarm;
238.  				return(0);
239.  			}
240.  			break;
241.  		    }
242.  		default:
243.  			impossible("Tried to steal a strange worn thing.");
244.  		}
245.  	}
246.  	else if(otmp == uwep) uwepgone();
247.  
248.  	if(otmp == uball) unpunish();
249.  
250.  	freeinv(otmp);
251.  	pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
252.  	mpickobj(mtmp,otmp);
253.  	if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE &&
254.  		!(mtmp->misc_worn_check & W_ARMG)) {
255.  	    minstapetrify(mtmp, TRUE);
256.  	    return -1;
257.  	}
258.  	return((multi < 0) ? 0 : 1);
259.  }
260.  
261.  #endif /* OVLB */
262.  #ifdef OVL1
263.  
264.  void
265.  mpickobj(mtmp,otmp)
266.  register struct monst *mtmp;
267.  register struct obj *otmp;
268.  {
269.      if (otmp->oclass == GOLD_CLASS) {
270.  	mtmp->mgold += otmp->quan;
271.  	obfree(otmp, (struct obj *)0);
272.      } else {
273.  	boolean snuff_otmp = FALSE;
274.  	/* don't want hidden light source inside the monster; assumes that
275.  	   engulfers won't have external inventories; whirly monsters cause
276.  	   the light to be extinguished rather than letting it shine thru */
277.  	if (otmp->lamplit &&  /* hack to avoid function calls for most objs */
278.  		obj_sheds_light(otmp) &&
279.  		attacktype(mtmp->data, AT_ENGL)) {
280.  	    /* this is probably a burning object that you dropped or threw */
281.  	    if (u.uswallow && mtmp == u.ustuck && !Blind)
282.  		pline("%s go%s out.", The(xname(otmp)),
283.  		      otmp->quan == 1L ? "es" : "");
284.  	    snuff_otmp = TRUE;
285.  	}
286.  	/* add_to_minv() might free otmp [if merged with something else],
287.  	   so we have to call it after doing the object checks */
288.  	add_to_minv(mtmp, otmp);
289.  	/* and we had to defer this until object is in mtmp's inventory */
290.  	if (snuff_otmp) snuff_light_source(mtmp->mx, mtmp->my);
291.      }
292.  }
293.  
294.  #endif /* OVL1 */
295.  #ifdef OVLB
296.  
297.  void
298.  stealamulet(mtmp)
299.  register struct monst *mtmp;
300.  {
301.  	register struct obj *otmp;
302.  	register int	real, fake;
303.  
304.  	/* select the artifact to steal */
305.  	if(u.uhave.amulet) {
306.  		real = AMULET_OF_YENDOR ;
307.  		fake = FAKE_AMULET_OF_YENDOR ;
308.  	} else if(u.uhave.questart) {
309.  	    real = fake = 0;		/* gcc -Wall lint */
310.  	    for(otmp = invent; otmp; otmp = otmp->nobj)
311.  	        if(is_quest_artifact(otmp)) goto snatch_it;
312.  	} else if(u.uhave.bell) {
313.  		real = BELL_OF_OPENING;
314.  		fake = BELL;
315.  	} else if(u.uhave.book) {
316.  		real = SPE_BOOK_OF_THE_DEAD;
317.  		fake = 0;
318.  	} else if(u.uhave.menorah) {
319.  		real = CANDELABRUM_OF_INVOCATION;
320.  		fake = 0;
321.  	} else return;	/* you have nothing of special interest */
322.  
323.  /*	If we get here, real and fake have been set up. */
324.  	for(otmp = invent; otmp; otmp = otmp->nobj) {
325.  	    if(otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz)) {
326.  		/* might be an imitation one */
327.  snatch_it:
328.  		if (otmp->owornmask)
329.  		    lose_worn_item(otmp);
330.  		freeinv(otmp);
331.  		mpickobj(mtmp,otmp);
332.  		pline("%s stole %s!", Monnam(mtmp), doname(otmp));
333.  		if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
334.  			rloc(mtmp);
335.  		return;
336.  	    }
337.  	}
338.  }
339.  
340.  #endif /* OVLB */
341.  #ifdef OVL0
342.  
343.  /* release the objects the creature is carrying */
344.  void
345.  relobj(mtmp,show,is_pet)
346.  register struct monst *mtmp;
347.  register int show;
348.  boolean is_pet;		/* If true, pet should keep wielded/worn items */
349.  {
350.  	register struct obj *otmp;
351.  	register int omx = mtmp->mx, omy = mtmp->my;
352.  	struct obj *keepobj = 0;
353.  	struct obj *wep = MON_WEP(mtmp);
354.  
355.  	while ((otmp = mtmp->minvent) != 0) {
356.  		obj_extract_self(otmp);
357.  		if (otmp->owornmask || otmp == wep) {
358.  			if (is_pet) { /* dont drop worn/wielded item */
359.  				otmp->nobj = keepobj;
360.  				keepobj = otmp;
361.  				continue;
362.  			}
363.  			mtmp->misc_worn_check &= ~(otmp->owornmask);
364.  			otmp->owornmask = 0L;
365.  		}
366.  		if (is_pet && cansee(omx, omy) && flags.verbose)
367.  			pline("%s drops %s.", Monnam(mtmp),
368.  					distant_name(otmp, doname));
369.  		if (flooreffects(otmp, omx, omy, "fall")) continue;
370.  		place_object(otmp, omx, omy);
371.  		stackobj(otmp);
372.  	}
373.  	/* put kept objects back */
374.  	while ((otmp = keepobj) != (struct obj *)0) {
375.  	    keepobj = otmp->nobj;
376.  	    add_to_minv(mtmp, otmp);
377.  	}
378.  
379.  	if (mtmp->mgold) {
380.  		register long g = mtmp->mgold;
381.  		mkgold(g, omx, omy);
382.  		if (is_pet && cansee(omx, omy) && flags.verbose)
383.  			pline("%s drops %ld gold piece%s.", Monnam(mtmp),
384.  				g, plur(g));
385.  		mtmp->mgold = 0L;
386.  	}
387.  	if (show & cansee(omx, omy))
388.  		newsym(omx, omy);
389.  }
390.  
391.  #endif /* OVL0 */
392.  
393.  /*steal.c*/