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