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