Source:NetHack 3.3.0/steal.c

From NetHackWiki
Revision as of 11:50, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.3.0/steal.c moved to Source:NetHack 3.3.0/steal.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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