Source:NetHack 3.3.0/steal.c
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)
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*/