Source:NetHack 3.2.0/steal.c

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

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