Source:NetHack 3.1.0/weapon.c
Revision as of 07:49, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.1.0/weapon.c moved to Source:NetHack 3.1.0/weapon.c: Robot: moved page)
Below is the full text to weapon.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/weapon.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: @(#)weapon.c 3.1 93/01/15 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* 6. * This module contains code for calculation of "to hit" and damage 7. * bonuses for any given weapon used, as well as weapons selection 8. * code for monsters. 9. */ 10. #include "hack.h" 11. 12. #ifdef OVLB 13. 14. static const char NEARDATA kebabable[] = { S_XORN, S_DRAGON, S_NAGA, S_GIANT, 0 }; 15. 16. /* 17. * hitval returns an integer representing the "to hit" bonuses 18. * of "otmp" against the monster type "ptr". 19. */ 20. int 21. hitval(otmp, ptr) 22. struct obj *otmp; 23. struct permonst *ptr; 24. { 25. int tmp = 0; 26. 27. if (otmp->oclass == WEAPON_CLASS || 28. otmp->otyp == PICK_AXE || otmp->otyp == UNICORN_HORN) 29. tmp += otmp->spe; 30. 31. /* Put weapon specific "to hit" bonuses in below: */ 32. tmp += objects[otmp->otyp].oc_hitbon; 33. 34. /* Put weapon vs. monster type "to hit" bonuses in below: */ 35. 36. /* Blessed weapons used against undead or demons */ 37. if(otmp->oclass == WEAPON_CLASS && otmp->blessed && 38. (is_demon(ptr) || is_undead(ptr))) tmp += 2; 39. 40. if(otmp->otyp >= SPEAR && otmp->otyp <= JAVELIN && 41. index(kebabable, ptr->mlet)) tmp += 2; 42. 43. /* Check specially named weapon "to hit" bonuses */ 44. if (otmp->oartifact) tmp += spec_abon(otmp, ptr); 45. return tmp; 46. } 47. 48. /* 49. * dmgval returns an integer representing the damage bonuses 50. * of "otmp" against the monster type "ptr". 51. */ 52. int 53. dmgval(otmp, ptr) 54. struct obj *otmp; 55. struct permonst *ptr; 56. { 57. int tmp = 0; 58. 59. if(otmp->otyp == CREAM_PIE) return(0); 60. 61. if(ptr->msize >= MZ_HUMAN) { 62. if(objects[otmp->otyp].oc_wldam) 63. tmp = rnd(objects[otmp->otyp].oc_wldam); 64. switch (otmp->otyp) { 65. case CROSSBOW_BOLT: 66. case MORNING_STAR: 67. case PARTISAN: 68. case ELVEN_BROADSWORD: 69. case BROADSWORD: tmp++; break; 70. 71. case FLAIL: 72. case RANSEUR: 73. case VOULGE: tmp += rnd(4); break; 74. 75. case ACID_VENOM: 76. case HALBERD: 77. case SPETUM: tmp += rnd(6); break; 78. 79. case BATTLE_AXE: 80. case BARDICHE: 81. case TRIDENT: tmp += d(2,4); break; 82. 83. case TSURUGI: 84. case DWARVISH_MATTOCK: 85. case TWO_HANDED_SWORD: tmp += d(2,6); break; 86. } 87. } else { 88. if(objects[otmp->otyp].oc_wsdam) 89. tmp = rnd(objects[otmp->otyp].oc_wsdam); 90. switch (otmp->otyp) { 91. case CROSSBOW_BOLT: 92. case MACE: 93. case WAR_HAMMER: 94. case FLAIL: 95. case SPETUM: 96. case TRIDENT: tmp++; break; 97. 98. case BATTLE_AXE: 99. case BARDICHE: 100. case BILL_GUISARME: 101. case GUISARME: 102. case LUCERN_HAMMER: 103. case MORNING_STAR: 104. case RANSEUR: 105. case BROADSWORD: 106. case ELVEN_BROADSWORD: 107. case VOULGE: tmp += rnd(4); break; 108. 109. case ACID_VENOM: tmp += rnd(6); break; 110. } 111. } 112. if (otmp->oclass == WEAPON_CLASS || otmp->otyp == PICK_AXE 113. || otmp->otyp == UNICORN_HORN) 114. tmp += otmp->spe; 115. 116. tmp -= otmp->oeroded; 117. 118. if (objects[otmp->otyp].oc_material <= LEATHER && thick_skinned(ptr)) 119. /* thick skinned/scaled creatures don't feel it */ 120. tmp = 0; 121. if (ptr == &mons[PM_SHADE] && objects[otmp->otyp].oc_material != SILVER) 122. tmp = 0; 123. 124. /* Put weapon vs. monster type damage bonuses in below: */ 125. if(otmp->oclass == WEAPON_CLASS) { 126. if (otmp->blessed && (is_undead(ptr) || is_demon(ptr))) 127. tmp += rnd(4); 128. if ((otmp->otyp == AXE || otmp->otyp == BATTLE_AXE) 129. && is_wooden(ptr)) 130. tmp += rnd(4); 131. if (objects[otmp->otyp].oc_material == SILVER && hates_silver(ptr)) 132. tmp += rnd(20); 133. } 134. 135. return(tmp); 136. } 137. 138. void 139. set_uasmon() /* update the "uasmon" structure */ 140. { 141. #ifdef POLYSELF 142. if(u.umonnum >= 0) uasmon = &mons[u.umonnum]; 143. else { 144. #endif 145. 146. uasmon = &playermon; 147. playermon.mlevel = u.ulevel; 148. playermon.ac = u.uac; 149. playermon.mr = (u.ulevel > 8) ? 5 * (u.ulevel-7) : u.ulevel; 150. #ifdef POLYSELF 151. } 152. #endif 153. return; 154. } 155. 156. #endif /* OVLB */ 157. #ifdef OVL0 158. 159. #define Oselect(x) if((otmp = oselect(mtmp, x))) return(otmp); 160. 161. static struct obj * FDECL(oselect, (struct monst *,int)); 162. 163. static struct obj * 164. oselect(mtmp, x) 165. struct monst *mtmp; 166. int x; 167. { 168. struct obj *otmp; 169. 170. for(otmp=mtmp->minvent; otmp; otmp = otmp->nobj) { 171. if (otmp->otyp == x && touch_artifact(otmp,mtmp)) 172. return otmp; 173. } 174. return (struct obj *)0; 175. } 176. 177. static const int NEARDATA rwep[] = 178. { DWARVISH_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, JAVELIN, 179. SHURIKEN, SILVER_ARROW, ELVEN_ARROW, ARROW, ORCISH_ARROW, 180. CROSSBOW_BOLT, ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, KNIFE, ROCK, 181. LOADSTONE, LUCKSTONE, DART, /* BOOMERANG, */ CREAM_PIE 182. /* note: CREAM_PIE should NOT be #ifdef KOPS */ 183. }; 184. 185. static struct obj *propellor; 186. 187. struct obj * 188. select_rwep(mtmp) /* select a ranged weapon for the monster */ 189. register struct monst *mtmp; 190. { 191. register struct obj *otmp; 192. int i; 193. 194. #ifdef KOPS 195. char mlet = mtmp->data->mlet; 196. #endif 197. 198. propellor = &zeroobj; 199. #ifdef KOPS 200. if(mlet == S_KOP) /* pies are first choice for Kops */ 201. Oselect(CREAM_PIE); 202. #endif 203. if(throws_rocks(mtmp->data)) /* ...boulders for giants */ 204. Oselect(BOULDER); 205. /* 206. * other than these two specific cases, always select the 207. * most potent ranged weapon to hand. 208. */ 209. for (i = 0; i < SIZE(rwep); i++) { 210. int prop; 211. 212. propellor = &zeroobj; 213. /* shooting gems from slings; this goes just before the darts */ 214. if (rwep[i]==DART && !likes_gems(mtmp->data) 215. && (propellor = m_carrying(mtmp, SLING))) { 216. for(otmp=mtmp->minvent; otmp; otmp=otmp->nobj) { 217. if(otmp->oclass==GEM_CLASS && 218. (otmp->otyp != LOADSTONE || !otmp->cursed)) 219. return(otmp); 220. } 221. } 222. prop = (objects[rwep[i]]).w_propellor; 223. if (prop > 0) { 224. switch (prop) { 225. case WP_BOW: 226. propellor = (oselect(mtmp, ELVEN_BOW)); 227. if (!propellor) propellor = (oselect(mtmp, BOW)); 228. if (!propellor) propellor = (oselect(mtmp, ORCISH_BOW)); 229. break; 230. case WP_SLING: 231. propellor = (oselect(mtmp, SLING)); 232. break; 233. case WP_CROSSBOW: 234. propellor = (oselect(mtmp, CROSSBOW)); 235. } 236. #ifdef MUSE 237. if ((otmp = MON_WEP(mtmp)) && otmp->cursed && otmp != propellor 238. && mtmp->weapon_check == NO_WEAPON_WANTED) 239. propellor = 0; 240. #endif 241. } 242. /* propellor = obj, propellor to use 243. * propellor = &zeroobj, doesn't need a propellor 244. * propellor = 0, needed one and didn't have one 245. */ 246. if (propellor != 0) { 247. /* Note: cannot use m_carrying for loadstones, since it will 248. * always select the first object of a type, and maybe the 249. * monster is carrying two but only the first is unthrowable. 250. */ 251. if (rwep[i] != LOADSTONE) { 252. #ifdef MUSE 253. /* Don't throw a cursed weapon-in-hand */ 254. if ((otmp = oselect(mtmp, rwep[i])) 255. && (!otmp->cursed || otmp != MON_WEP(mtmp))) 256. return(otmp); 257. #else 258. Oselect(rwep[i]); 259. #endif 260. } else for(otmp=mtmp->minvent; otmp; otmp=otmp->nobj) { 261. if (otmp->otyp == LOADSTONE && !otmp->cursed) 262. return otmp; 263. } 264. } 265. } 266. 267. /* failure */ 268. return (struct obj *)0; 269. } 270. 271. /* 0 = used by any monster; 1 = only used by strong monsters */ 272. static const struct hwep { short otyp, big; } NEARDATA hwep[] = { 273. {TSURUGI,1}, {RUNESWORD,0}, 274. {DWARVISH_MATTOCK,1}, {TWO_HANDED_SWORD,1}, {BATTLE_AXE,1}, 275. {KATANA,0}, {UNICORN_HORN,1}, {CRYSKNIFE,0}, 276. {TRIDENT,0}, {LONG_SWORD,0}, {ELVEN_BROADSWORD,0}, {BROADSWORD,0}, 277. {LUCERN_HAMMER,1}, {SCIMITAR,1}, {SILVER_SABER,0}, {HALBERD,1}, 278. {PARTISAN,1}, {LANCE,1}, {FAUCHARD,1}, {BILL_GUISARME,1}, 279. {BEC_DE_CORBIN,1}, {GUISARME,1}, {RANSEUR,1}, {SPETUM,1}, 280. {VOULGE,1}, {BARDICHE,0}, {MORNING_STAR,0}, {GLAIVE,0}, 281. {ELVEN_SHORT_SWORD,0}, {DWARVISH_SHORT_SWORD,0}, {SHORT_SWORD,0}, 282. {ORCISH_SHORT_SWORD,0}, {MACE,0}, {AXE,0}, {DWARVISH_SPEAR,0}, 283. {ELVEN_SPEAR,0}, {SPEAR,0}, {ORCISH_SPEAR,0}, {FLAIL,0}, 284. {QUARTERSTAFF,1}, {JAVELIN,0}, {AKLYS,0}, {CLUB,0}, {PICK_AXE,0}, 285. #ifdef KOPS 286. {RUBBER_HOSE,0}, 287. #endif /* KOPS */ 288. {WAR_HAMMER,0}, {ELVEN_DAGGER,0}, {DAGGER,0}, {ORCISH_DAGGER,0}, 289. {ATHAME,0}, {SCALPEL,0}, {KNIFE,0}, {WORM_TOOTH,0}, {BULLWHIP,0} 290. }; 291. 292. struct obj * 293. select_hwep(mtmp) /* select a hand to hand weapon for the monster */ 294. register struct monst *mtmp; 295. { 296. register struct obj *otmp; 297. register int i; 298. register const struct hwep *hw; 299. boolean strong = strongmonst(mtmp->data); 300. 301. if(is_giant(mtmp->data)) /* giants just love to use clubs */ 302. Oselect(CLUB); 303. 304. /* only strong monsters can wield big (esp. long) weapons */ 305. /* all monsters can wield the remaining weapons */ 306. for (i = 0, hw = hwep; i < SIZE(hwep); i++, hw++) 307. if ((strong || !hw->big) && 308. #ifdef MUSE 309. (!objects[hw->otyp].oc_bimanual || !which_armor(mtmp, W_ARMS)) && 310. #endif 311. (objects[hw->otyp].oc_material != SILVER || !hates_silver(mtmp->data))) 312. Oselect(hw->otyp); 313. 314. /* failure */ 315. return (struct obj *)0; 316. } 317. 318. #ifdef MUSE 319. /* Called after polymorphing a monster, robbing it, etc.... Monsters 320. * otherwise never unwield stuff on their own. Shouldn't print messages. 321. */ 322. void 323. possibly_unwield(mon) 324. register struct monst *mon; 325. { 326. register struct obj *obj; 327. struct obj *otmp, *backobj, *mw_tmp; 328. 329. if (!(mw_tmp = MON_WEP(mon))) 330. return; 331. for(obj=mon->minvent; obj; obj=obj->nobj) 332. if (obj == mw_tmp) break; 333. if (!obj) { /* The weapon was stolen or destroyed */ 334. MON_NOWEP(mon); 335. mon->weapon_check = NEED_WEAPON; 336. return; 337. } 338. if (!attacktype(mon->data, AT_WEAP)) { 339. MON_NOWEP(mon); 340. mon->weapon_check = NO_WEAPON_WANTED; 341. if (cansee(mon->mx, mon->my)) { 342. pline("%s drops %s.", Monnam(mon), 343. distant_name(obj, doname)); 344. } 345. backobj = 0; 346. for(otmp = mon->minvent; otmp; otmp = otmp->nobj) { 347. /* flooreffects unnecessary, can't wield boulders */ 348. if (otmp == obj) { 349. if (!backobj) mon->minvent = otmp->nobj; 350. else backobj->nobj = otmp->nobj; 351. place_object(otmp, mon->mx, mon->my); 352. otmp->nobj = fobj; 353. fobj = otmp; 354. stackobj(fobj); 355. if(cansee(mon->mx,mon->my)) 356. newsym(mon->mx, mon->my); 357. break; 358. } 359. backobj = otmp; 360. } 361. return; 362. } 363. /* The remaining case where there is a change is where a monster 364. * is polymorphed into a stronger/weaker monster with a different 365. * choice of weapons. This has no parallel for players. It can 366. * be handled by waiting until mon_wield_item is actually called. 367. * Though the monster still wields the wrong weapon until then, 368. * this is OK since the player can't see it. 369. * Possible problem: big monster with big cursed weapon gets 370. * polymorphed into little monster. But it's not quite clear how to 371. * handle this anyway.... 372. */ 373. mon->weapon_check = NEED_WEAPON; 374. return; 375. } 376. 377. /* Let a monster try to wield a weapon, based on mon->weapon_check. 378. * Returns 1 if the monster took time to do it, 0 if it did not. 379. */ 380. int 381. mon_wield_item(mon) 382. register struct monst *mon; 383. { 384. struct obj *obj; 385. 386. /* This case actually should never happen */ 387. if (mon->weapon_check == NO_WEAPON_WANTED) return 0; 388. 389. switch(mon->weapon_check) { 390. case NEED_HTH_WEAPON: 391. obj = select_hwep(mon); 392. break; 393. case NEED_RANGED_WEAPON: 394. (void)select_rwep(mon); 395. obj = propellor; 396. break; 397. case NEED_PICK_AXE: 398. obj = m_carrying(mon, PICK_AXE); 399. break; 400. default: impossible("weapon_check %d for %s?", 401. mon->weapon_check, mon_nam(mon)); 402. return 0; 403. } 404. if (obj && obj != &zeroobj) { 405. struct obj *mw_tmp = MON_WEP(mon); 406. if (mw_tmp == obj) { /* already wielding it */ 407. mon->weapon_check = NEED_WEAPON; 408. return 0; 409. } 410. /* Actually, this isn't necessary--as soon as the monster 411. * wields the weapon, the weapon welds itself, so the monster 412. * can know it's cursed and needn't even bother trying. 413. * Still.... 414. */ 415. if (mw_tmp && mw_tmp->cursed) { 416. if (obj->otyp == PICK_AXE) { 417. if (canseemon(mon)) { 418. pline("Since %s weapon %s welded to %s hand,", 419. s_suffix(mon_nam(mon)), 420. (mw_tmp->quan == 1L) ? "is" : "are", 421. humanoid(mon->data) 422. ? (mon->female ? "her" : "his") 423. : "its"); 424. pline("%s cannot wield that %s.", 425. mon_nam(mon), xname(obj)); 426. mw_tmp->bknown = 1; 427. } 428. } else { 429. if (canseemon(mon)) { 430. pline("%s tries to wield %s.", Monnam(mon), 431. doname(obj)); 432. pline("%s %s %s welded to %s hand!", 433. s_suffix(Monnam(mon)), xname(mw_tmp), 434. (mw_tmp->quan == 1L) ? "is" : "are", 435. humanoid(mon->data) 436. ? (mon->female ? "her" : "his") 437. : "its"); 438. mw_tmp->bknown = 1; 439. } 440. } 441. mon->weapon_check = NO_WEAPON_WANTED; 442. return 1; 443. } 444. mon->mw = obj; /* wield obj */ 445. mon->weapon_check = NEED_WEAPON; 446. if (canseemon(mon)) { 447. pline("%s wields %s!", Monnam(mon), doname(obj)); 448. if (obj->cursed) { 449. pline("%s %s to %s hand!", 450. The(xname(obj)), 451. (obj->quan == 1L) ? "welds itself" 452. : "weld themselves", 453. s_suffix(mon_nam(mon))); 454. obj->bknown = 1; 455. } 456. } 457. return 1; 458. } 459. mon->weapon_check = NEED_WEAPON; 460. return 0; 461. } 462. 463. /* rearrange a monster's inventory so that wielded weapon is first */ 464. void 465. sort_mwep(mon) 466. struct monst *mon; 467. { 468. struct obj *otmp, *prev, *mw_tmp = MON_WEP(mon); 469. 470. if (!mw_tmp) return; 471. for (otmp = mon->minvent, prev = 0; otmp; otmp = otmp->nobj) { 472. if (otmp == mw_tmp) break; 473. prev = otmp; 474. } 475. if (!otmp) { 476. MON_NOWEP(mon); 477. } else if (prev) { 478. prev->nobj = otmp->nobj; 479. otmp->nobj = mon->minvent; 480. mon->minvent = otmp; 481. } 482. } 483. #endif 484. 485. int 486. abon() { /* attack bonus for strength & dexterity */ 487. int sbon; 488. register int str = ACURR(A_STR), dex = ACURR(A_DEX); 489. 490. #ifdef POLYSELF 491. if (u.umonnum >= 0) return(adj_lev(&mons[u.umonnum])-3); 492. #endif 493. if (str < 6) sbon = -2; 494. else if (str < 8) sbon = -1; 495. else if (str < 17) sbon = 0; 496. else if (str < 69) sbon = 1; /* up to 18/50 */ 497. else if (str < 118) sbon = 2; 498. else sbon = 3; 499. /* 500. * Temporary kludge - make it a bit easier for a low level character 501. * to hit until we tune the game a little better. 502. */ 503. sbon += (u.ulevel < 3) ? 1 : 0; 504. 505. if (dex < 4) return(sbon-3); 506. else if (dex < 6) return(sbon-2); 507. else if (dex < 8) return(sbon-1); 508. else if (dex < 14) return(sbon); 509. else return(sbon + dex-14); 510. } 511. 512. #endif /* OVL0 */ 513. #ifdef OVL1 514. 515. int 516. dbon() { /* damage bonus for strength */ 517. register int str = ACURR(A_STR); 518. 519. #ifdef POLYSELF 520. if (u.umonnum >= 0) return(0); 521. #endif 522. 523. if (str < 6) return(-1); 524. else if (str < 16) return(0); 525. else if (str < 18) return(1); 526. else if (str == 18) return(2); /* up to 18 */ 527. else if (str < 94) return(3); /* up to 18/75 */ 528. else if (str < 109) return(4); /* up to 18/90 */ 529. else if (str < 118) return(5); /* up to 18/99 */ 530. else return(6); 531. } 532. 533. #endif /* OVL1 */ 534. 535. /*weapon.c*/