abstract
| - Below is the full text to wield.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/wield.c#line123]], for example. The latest source code for vanilla NetHack is at Source code. 1. /* SCCS Id: @(#)wield.c 3.4 2003/01/29 */ 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. /* KMH -- Differences between the three weapon slots. 8. * 9. * The main weapon (uwep): 10. * 1. Is filled by the (w)ield command. 11. * 2. Can be filled with any type of item. 12. * 3. May be carried in one or both hands. 13. * 4. Is used as the melee weapon and as the launcher for 14. * ammunition. 15. * 5. Only conveys intrinsics when it is a weapon, weapon-tool, 16. * or artifact. 17. * 6. Certain cursed items will weld to the hand and cannot be 18. * unwielded or dropped. See erodeable_wep() and will_weld() 19. * below for the list of which items apply. 20. * 21. * The secondary weapon (uswapwep): 22. * 1. Is filled by the e(x)change command, which swaps this slot 23. * with the main weapon. If the "pushweapon" option is set, 24. * the (w)ield command will also store the old weapon in the 25. * secondary slot. 26. * 2. Can be field with anything that will fit in the main weapon 27. * slot; that is, any type of item. 28. * 3. Is usually NOT considered to be carried in the hands. 29. * That would force too many checks among the main weapon, 30. * second weapon, shield, gloves, and rings; and it would 31. * further be complicated by bimanual weapons. A special 32. * exception is made for two-weapon combat. 33. * 4. Is used as the second weapon for two-weapon combat, and as 34. * a convenience to swap with the main weapon. 35. * 5. Never conveys intrinsics. 36. * 6. Cursed items never weld (see #3 for reasons), but they also 37. * prevent two-weapon combat. 38. * 39. * The quiver (uquiver): 40. * 1. Is filled by the (Q)uiver command. 41. * 2. Can be filled with any type of item. 42. * 3. Is considered to be carried in a special part of the pack. 43. * 4. Is used as the item to throw with the (f)ire command. 44. * This is a convenience over the normal (t)hrow command. 45. * 5. Never conveys intrinsics. 46. * 6. Cursed items never weld; their effect is handled by the normal 47. * throwing code. 48. * 49. * No item may be in more than one of these slots. 50. */ 51. 52. STATIC_DCL int FDECL(ready_weapon, (struct obj *, BOOLEAN_P)); 53. 54. /* used by will_weld() */ 55. /* probably should be renamed */ 56. #define erodeable_wep(optr) ((optr)->oclass == WEAPON_CLASS \ 57. || is_weptool(optr) \ 58. || (optr)->otyp == HEAVY_IRON_BALL \ 59. || (optr)->otyp == IRON_CHAIN) 60. 61. /* used by welded(), and also while wielding */ 62. #define will_weld(optr) ((optr)->cursed \ 63. && (erodeable_wep(optr) \ 64. || (optr)->otyp == TIN_OPENER)) 65. 66. 67. /*** Functions that place a given item in a slot ***/ 68. /* Proper usage includes: 69. * 1. Initializing the slot during character generation or a 70. * restore. 71. * 2. Setting the slot due to a player's actions. 72. * 3. If one of the objects in the slot are split off, these 73. * functions can be used to put the remainder back in the slot. 74. * 4. Putting an item that was thrown and returned back into the slot. 75. * 5. Emptying the slot, by passing a null object. NEVER pass 76. * zeroobj! 77. * 78. * If the item is being moved from another slot, it is the caller's 79. * responsibility to handle that. It's also the caller's responsibility 80. * to print the appropriate messages. 81. * 82. * MRKR: It now takes an extra flag put_away which is true if the 83. * unwielded weapon is being put back into the inventory 84. * (rather than dropped, destroyed, etc) 85. */ 86. void 87. setuwep(obj, put_away) 88. register struct obj *obj; 89. boolean put_away; 90. { 91. struct obj *olduwep = uwep; 92. 93. if (obj == uwep) return; /* necessary to not set unweapon */ 94. /* This message isn't printed in the caller because it happens 95. * *whenever* Sunsword is unwielded, from whatever cause. 96. */ 97. setworn(obj, W_WEP); 98. if (uwep == obj && artifact_light(olduwep) && olduwep->lamplit) { 99. end_burn(olduwep, FALSE); 100. if (!Blind) pline("%s glowing.", Tobjnam(olduwep, "stop")); 101. } 102. /* Note: Explicitly wielding a pick-axe will not give a "bashing" 103. * message. Wielding one via 'a'pplying it will. 104. * 3.2.2: Wielding arbitrary objects will give bashing message too. 105. */ 106. if (obj) { 107. unweapon = (obj->oclass == WEAPON_CLASS) ? 108. is_launcher(obj) || is_ammo(obj) || 109. is_missile(obj) || (is_pole(obj) 110. #ifdef STEED 111. && !u.usteed 112. #endif 113. ) : !is_weptool(obj); 114. } else 115. unweapon = TRUE; /* for "bare hands" message */ 116. 117. 118. /* MRKR: Handle any special effects of unwielding a weapon */ 119. if (olduwep && olduwep != uwep) 120. unwield(olduwep, put_away); 121. 122. update_inventory(); 123. } 124. 125. STATIC_OVL int 126. ready_weapon(wep, put_away) 127. struct obj *wep; 128. boolean put_away; 129. { 130. /* Separated function so swapping works easily */ 131. int res = 0; 132. 133. if (!wep) { 134. /* No weapon */ 135. if (uwep) { 136. You("are empty %s.", body_part(HANDED)); 137. setuwep((struct obj *) 0, put_away); 138. res++; 139. } else 140. You("are already empty %s.", body_part(HANDED)); 141. } else if (!uarmg && !Stone_resistance && wep->otyp == CORPSE 142. && touch_petrifies(&mons[wep->corpsenm])) { 143. /* Prevent wielding cockatrice when not wearing gloves --KAA */ 144. char kbuf[BUFSZ]; 145. 146. You("wield the %s corpse in your bare %s.", 147. mons[wep->corpsenm].mname, makeplural(body_part(HAND))); 148. Sprintf(kbuf, "%s corpse", an(mons[wep->corpsenm].mname)); 149. instapetrify(kbuf); 150. } else if (uarms && bimanual(wep)) 151. You("cannot wield a two-handed %s while wearing a shield.", 152. is_sword(wep) ? "sword" : 153. wep->otyp == BATTLE_AXE ? "axe" : "weapon"); 154. else if (wep->oartifact && !touch_artifact(wep, &youmonst)) { 155. res++; /* takes a turn even though it doesn't get wielded */ 156. } else if (tech_inuse(T_EVISCERATE)) { 157. /* WAC - if you have 'L' has claws out and wields weapon, 158. * can't retract claws 159. */ 160. You("can't retract your claws!"); 161. } else { 162. /* Weapon WILL be wielded after this point */ 163. res++; 164. if (will_weld(wep)) { 165. const char *tmp = xname(wep), *thestr = "The "; 166. if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp),thestr,4)) 167. tmp = thestr; 168. else tmp = ""; 169. pline("%s%s %s to your %s!", tmp, aobjnam(wep, "weld"), 170. (wep->quan == 1L) ? "itself" : "themselves", /* a3 */ 171. bimanual(wep) ? 172. (const char *)makeplural(body_part(HAND)) 173. : body_part(HAND)); 174. wep->bknown = TRUE; 175. } else { 176. /* The message must be printed before setuwep (since 177. * you might die and be revived from changing weapons), 178. * and the message must be before the death message and 179. * Lifesaved rewielding. Yet we want the message to 180. * say "weapon in hand", thus this kludge. 181. */ 182. long dummy = wep->owornmask; 183. wep->owornmask |= W_WEP; 184. prinv((char *)0, wep, 0L); 185. wep->owornmask = dummy; 186. } 187. setuwep(wep, put_away); 188. 189. /* KMH -- Talking artifacts are finally implemented */ 190. arti_speak(wep); 191. 192. if (artifact_light(wep) && !wep->lamplit) { 193. begin_burn(wep, FALSE); 194. if (!Blind) 195. pline("%s to glow brilliantly!", Tobjnam(wep, "begin")); 196. } 197. 198. #if 0 199. /* we'll get back to this someday, but it's not balanced yet */ 200. if (Race_if(PM_ELF) && !wep->oartifact && 201. objects[wep->otyp].oc_material == IRON) { 202. /* Elves are averse to wielding cold iron */ 203. You("have an uneasy feeling about wielding cold iron."); 204. change_luck(-1); 205. } 206. #endif 207. 208. if (wep->unpaid) { 209. struct monst *this_shkp; 210. 211. if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy))) != 212. (struct monst *)0) { 213. pline("%s says \"You be careful with my %s!\"", 214. shkname(this_shkp), 215. xname(wep)); 216. } 217. } 218. } 219. return(res); 220. } 221. 222. void 223. setuqwep(obj) 224. register struct obj *obj; 225. { 226. setworn(obj, W_QUIVER); 227. update_inventory(); 228. } 229. 230. void 231. setuswapwep(obj, put_away) 232. register struct obj *obj; 233. boolean put_away; 234. { 235. struct obj *oldswapwep = uswapwep; 236. setworn(obj, W_SWAPWEP); 237. 238. if (oldswapwep && oldswapwep != uswapwep) 239. unwield(oldswapwep, put_away); 240. update_inventory(); 241. } 242. 243. 244. /*** Commands to change particular slot(s) ***/ 245. 246. static NEARDATA const char wield_objs[] = 247. { ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, TOOL_CLASS, 0 }; 248. static NEARDATA const char ready_objs[] = 249. { ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, 0 }; 250. static NEARDATA const char bullets[] = /* (note: different from dothrow.c) */ 251. { ALL_CLASSES, ALLOW_NONE, GEM_CLASS, WEAPON_CLASS, 0 }; 252. 253. int 254. dowield() 255. { 256. register struct obj *wep, *oldwep; 257. int result; 258. 259. /* May we attempt this? */ 260. multi = 0; 261. if (cantwield(youmonst.data)) { 262. pline("Don't be ridiculous!"); 263. return(0); 264. } 265. 266. /* Prompt for a new weapon */ 267. if (!(wep = getobj(wield_objs, "wield"))) 268. /* Cancelled */ 269. return (0); 270. else if (wep == uwep) { 271. You("are already wielding that!"); 272. if (is_weptool(wep)) unweapon = FALSE; /* [see setuwep()] */ 273. return (0); 274. } else if (welded(uwep)) { 275. weldmsg(uwep); 276. /* previously interrupted armor removal mustn't be resumed */ 277. reset_remarm(); 278. return (0); 279. } 280. 281. /* Handle no object, or object in other slot */ 282. if (wep == &zeroobj) 283. wep = (struct obj *) 0; 284. else if (wep == uswapwep) 285. return (doswapweapon()); 286. else if (wep == uquiver) 287. setuqwep((struct obj *) 0); 288. else if (wep->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL 289. #ifdef STEED 290. | W_SADDLE 291. #endif 292. )) { 293. You("cannot wield that!"); 294. return (0); 295. } 296. 297. /* Set your new primary weapon */ 298. oldwep = uwep; 299. result = ready_weapon(wep, TRUE); 300. if (flags.pushweapon && oldwep && uwep != oldwep) 301. setuswapwep(oldwep, TRUE); 302. untwoweapon(); 303. 304. return (result); 305. } 306. 307. int 308. doswapweapon() 309. { 310. register struct obj *oldwep, *oldswap; 311. int result = 0; 312. 313. 314. /* May we attempt this? */ 315. multi = 0; 316. if (cantwield(youmonst.data)) { 317. pline("Don't be ridiculous!"); 318. return(0); 319. } 320. if (welded(uwep)) { 321. weldmsg(uwep); 322. return (0); 323. } 324. 325. /* Unwield your current secondary weapon */ 326. oldwep = uwep; 327. oldswap = uswapwep; 328. if (uswapwep) 329. unwield(uswapwep, FALSE); 330. u.twoweap = 0; 331. setuswapwep((struct obj *) 0, FALSE); 332. 333. /* Set your new primary weapon */ 334. result = ready_weapon(oldswap, TRUE); 335. 336. /* Set your new secondary weapon */ 337. if (uwep == oldwep) 338. /* Wield failed for some reason */ 339. setuswapwep(oldswap, FALSE); 340. else { 341. setuswapwep(oldwep, FALSE); 342. if (uswapwep) 343. prinv((char *)0, uswapwep, 0L); 344. else 345. You("have no secondary weapon readied."); 346. } 347. 348. if (u.twoweap && !can_twoweapon()) 349. untwoweapon(); 350. 351. return (result); 352. } 353. 354. int 355. dowieldquiver() 356. { 357. register struct obj *newquiver; 358. const char *quivee_types = (uslinging() || 359. (uswapwep && objects[uswapwep->otyp].oc_skill == P_SLING)) ? 360. bullets : ready_objs; 361. 362. /* Since the quiver isn't in your hands, don't check cantwield(), */ 363. /* will_weld(), touch_petrifies(), etc. */ 364. multi = 0; 365. 366. /* Slash'EM has used Q for quiver since it started */ 367. /* Because 'Q' used to be quit... */ 368. if (flags.suppress_alert < FEATURE_NOTICE_VER(0,0,0)) 369. pline("Note: Please use #quit if you wish to exit the game."); 370. 371. /* Prompt for a new quiver */ 372. if (!(newquiver = getobj(quivee_types, "ready"))) 373. /* Cancelled */ 374. return (0); 375. 376. /* Handle no object, or object in other slot */ 377. /* Any type is okay, since we give no intrinsics anyways */ 378. if (newquiver == &zeroobj) { 379. /* Explicitly nothing */ 380. if (uquiver) { 381. You("now have no ammunition readied."); 382. setuqwep(newquiver = (struct obj *) 0); 383. } else { 384. You("already have no ammunition readied!"); 385. return(0); 386. } 387. } else if (newquiver == uquiver) { 388. pline("That ammunition is already readied!"); 389. return(0); 390. } else if (newquiver == uwep) { 391. /* Prevent accidentally readying the main weapon */ 392. pline("%s already being used as a weapon!", 393. !is_plural(uwep) ? "That is" : "They are"); 394. return(0); 395. } else if (newquiver->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL 396. #ifdef STEED 397. | W_SADDLE 398. #endif 399. )) { 400. You("cannot ready that!"); 401. return (0); 402. } else { 403. long dummy; 404. 405. 406. /* Check if it's the secondary weapon */ 407. if (newquiver == uswapwep) { 408. setuswapwep((struct obj *) 0, TRUE); 409. untwoweapon(); 410. } 411. 412. /* Okay to put in quiver; print it */ 413. dummy = newquiver->owornmask; 414. newquiver->owornmask |= W_QUIVER; 415. prinv((char *)0, newquiver, 0L); 416. newquiver->owornmask = dummy; 417. } 418. 419. /* Finally, place it in the quiver */ 420. setuqwep(newquiver); 421. /* Take no time since this is a convenience slot */ 422. return (0); 423. } 424. 425. /* used for #rub and for applying pick-axe, whip, grappling hook, or polearm */ 426. /* (moved from apply.c) */ 427. boolean 428. wield_tool(obj, verb) 429. struct obj *obj; 430. const char *verb; /* "rub",&c */ 431. { 432. const char *what; 433. boolean more_than_1; 434. 435. if (obj == uwep) return TRUE; /* nothing to do if already wielding it */ 436. 437. if (!verb) verb = "wield"; 438. what = xname(obj); 439. more_than_1 = (obj->quan > 1L || 440. strstri(what, "pair of ") != 0 || 441. strstri(what, "s of ") != 0); 442. 443. if (obj->owornmask & (W_ARMOR|W_RING|W_AMUL|W_TOOL)) { 444. char yourbuf[BUFSZ]; 445. 446. You_cant("%s %s %s while wearing %s.", 447. verb, shk_your(yourbuf, obj), what, 448. more_than_1 ? "them" : "it"); 449. return FALSE; 450. } 451. if (welded(uwep)) { 452. if (flags.verbose) { 453. const char *hand = body_part(HAND); 454. 455. if (bimanual(uwep)) hand = makeplural(hand); 456. if (strstri(what, "pair of ") != 0) more_than_1 = FALSE; 457. pline( 458. "Since your weapon is welded to your %s, you cannot %s %s %s.", 459. hand, verb, more_than_1 ? "those" : "that", xname(obj)); 460. } else { 461. You_cant("do that."); 462. } 463. return FALSE; 464. } 465. if (cantwield(youmonst.data)) { 466. You_cant("hold %s strongly enough.", more_than_1 ? "them" : "it"); 467. return FALSE; 468. } 469. /* check shield */ 470. if (uarms && bimanual(obj)) { 471. You("cannot %s a two-handed %s while wearing a shield.", 472. verb, (obj->oclass == WEAPON_CLASS) ? "weapon" : "tool"); 473. return FALSE; 474. } 475. if (uquiver == obj) setuqwep((struct obj *)0); 476. if (uswapwep == obj) { 477. (void) doswapweapon(); 478. /* doswapweapon might fail */ 479. if (uswapwep == obj) return FALSE; 480. } else { 481. You("now wield %s.", doname(obj)); 482. setuwep(obj, TRUE); 483. } 484. if (uwep != obj) return FALSE; /* rewielded old object after dying */ 485. /* applying weapon or tool that gets wielded ends two-weapon combat */ 486. if (u.twoweap) 487. untwoweapon(); 488. if (obj->oclass != WEAPON_CLASS && !is_weptool(obj)) 489. unweapon = TRUE; 490. return TRUE; 491. } 492. 493. /* WAC 494. * For the purposes of SLASH'EM, artifacts should be wieldable in either hand 495. */ 496. int 497. can_twoweapon() 498. { 499. char buf[BUFSZ]; 500. const char *what; 501. boolean disallowed_by_race; 502. boolean disallowed_by_role; 503. struct obj *otmp; 504. 505. #define NOT_WEAPON(obj) (obj && !is_weptool(obj) && obj->oclass != WEAPON_CLASS) 506. if (!could_twoweap(youmonst.data) && (uwep || uswapwep)) { 507. what = uwep && uswapwep ? "two weapons" : "more than one weapon"; 508. if (cantwield(youmonst.data)) 509. pline("Don't be ridiculous!"); 510. else if (Upolyd) 511. You_cant("use %s in your current form.", what); 512. else { 513. disallowed_by_role = P_MAX_SKILL(P_TWO_WEAPON_COMBAT) < P_BASIC; 514. disallowed_by_race = youmonst.data->mattk[1].aatyp != AT_WEAP; 515. *buf = '\0'; 516. if (!disallowed_by_role) 517. Strcpy(buf, disallowed_by_race ? urace.noun : urace.adj); 518. if (disallowed_by_role || !disallowed_by_race) { 519. if (!disallowed_by_role) 520. Strcat(buf, " "); 521. Strcat(buf, (flags.female && urole.name.f) ? 522. urole.name.f : urole.name.m); 523. } 524. pline("%s aren't able to use %s at once.", 525. makeplural(upstart(buf)), what); 526. } 527. } else if (cantwield(youmonst.data)) 528. pline("Don't be ridiculous!"); 529. else if (youmonst.data->mattk[1].aatyp != AT_WEAP && 530. youmonst.data->mattk[1].aatyp != AT_CLAW) { 531. if (Upolyd) 532. You_cant("fight with two %s in your current form.", 533. makeplural(body_part(HAND))); 534. else 535. pline("%s aren't able to fight two-handed.", 536. upstart(makeplural(urace.noun))); 537. } else if (NOT_WEAPON(uwep) || NOT_WEAPON(uswapwep)) { 538. otmp = NOT_WEAPON(uwep) ? uwep : uswapwep; 539. pline("%s %s.", Yname2(otmp), 540. is_plural(otmp) ? "aren't weapons" : "isn't a weapon"); 541. } else if ((uwep && bimanual(uwep)) || (uswapwep && bimanual(uswapwep))) { 542. otmp = (uwep && bimanual(uwep)) ? uwep : uswapwep; 543. pline("%s isn't one-handed.", Yname2(otmp)); 544. } else if (uarms) { 545. if (uwep || uswapwep) 546. what = uwep && uswapwep ? "use two weapons" : 547. "use more than one weapon"; 548. else { 549. sprintf(buf, "fight with two %s", makeplural(body_part(HAND))); 550. what = buf; 551. } 552. You_cant("%s while wearing a shield.", what); 553. } 554. /* WAC: TODO: cannot wield conflicting alignment artifacts*/ 555. #if 0 556. else if (uswapwep->oartifact && ...) 557. pline("%s resists being held second to another weapon!", 558. Yname2(uswapwep)); 559. #endif 560. else if (!uarmg && !Stone_resistance && 561. (uswapwep && uswapwep->otyp == CORPSE && 562. (touch_petrifies(&mons[uswapwep->corpsenm])))) { 563. char kbuf[BUFSZ]; 564. 565. You("wield the %s corpse with your bare %s.", 566. mons[uswapwep->corpsenm].mname, body_part(HAND)); 567. Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); 568. instapetrify(kbuf); 569. } else if (uswapwep && (Glib || uswapwep->cursed)) { 570. if (!Glib) 571. uswapwep->bknown = TRUE; 572. drop_uswapwep(); 573. } else 574. return (TRUE); /* Passes all the checks */ 575. 576. /* Otherwise */ 577. return (FALSE); 578. } 579. 580. void 581. drop_uswapwep() 582. { 583. char str[BUFSZ]; 584. struct obj *obj = uswapwep; 585. 586. /* Avoid trashing makeplural's static buffer */ 587. Strcpy(str, makeplural(body_part(HAND))); 588. Your("%s from your %s!", aobjnam(obj, "slip"), str); 589. setuswapwep((struct obj *) 0, FALSE); 590. dropx(obj); 591. } 592. 593. int 594. dotwoweapon() 595. { 596. /* You can always toggle it off */ 597. if (u.twoweap) { 598. if (uwep) 599. You("switch to your primary weapon."); 600. else if (uswapwep) { 601. You("are empty %s.", body_part(HANDED)); 602. unweapon = TRUE; 603. } else 604. You("switch to your right %s.", body_part(HAND)); 605. if (uswapwep) 606. unwield(uswapwep, TRUE); 607. u.twoweap = 0; 608. update_inventory(); 609. return (0); 610. } 611. 612. /* May we use two weapons? */ 613. if (can_twoweapon()) { 614. /* Success! */ 615. if (uwep && uswapwep) 616. You("begin two-weapon combat."); 617. else if (uwep || uswapwep) { 618. You("begin fighting with a weapon and your %s %s.", 619. uwep ? "left" : "right", body_part(HAND)); 620. unweapon = FALSE; 621. } else if (Upolyd) 622. You("begin fighting with two %s.", 623. makeplural(body_part(HAND))); 624. else 625. You("begin two-handed combat."); 626. u.twoweap = 1; 627. update_inventory(); 628. return (rnd(20) > ACURR(A_DEX)); 629. } 630. return (0); 631. } 632. 633. /*** Functions to empty a given slot ***/ 634. /* These should be used only when the item can't be put back in 635. * the slot by life saving. Proper usage includes: 636. * 1. The item has been eaten, stolen, burned away, or rotted away. 637. * 2. Making an item disappear for a bones pile. 638. */ 639. void 640. uwepgone() 641. { 642. if (uwep) { 643. if (artifact_light(uwep) && uwep->lamplit) { 644. end_burn(uwep, FALSE); 645. if (!Blind) pline("%s glowing.", Tobjnam(uwep, "stop")); 646. } 647. unwield(uwep, FALSE); 648. setworn((struct obj *)0, W_WEP); 649. unweapon = TRUE; 650. update_inventory(); 651. } 652. } 653. 654. void 655. uswapwepgone() 656. { 657. if (uswapwep) { 658. setworn((struct obj *)0, W_SWAPWEP); 659. update_inventory(); 660. } 661. } 662. 663. void 664. uqwepgone() 665. { 666. if (uquiver) { 667. setworn((struct obj *)0, W_QUIVER); 668. update_inventory(); 669. } 670. } 671. 672. void 673. untwoweapon() 674. { 675. if (u.twoweap) { 676. if (uwep && uswapwep) 677. You("can no longer use two weapons at once."); 678. else if (cantwield(youmonst.data)) 679. You("can no longer control which %s to fight with.", 680. body_part(HAND)); 681. else 682. You("can no longer use two %s to fight.", 683. makeplural(body_part(HAND))); 684. if (uswapwep) 685. unwield(uswapwep, TRUE); 686. u.twoweap = FALSE; 687. update_inventory(); 688. } 689. return; 690. } 691. 692. /* Maybe rust object, or corrode it if acid damage is called for */ 693. void 694. erode_obj(target, acid_dmg, fade_scrolls) 695. struct obj *target; /* object (e.g. weapon or armor) to erode */ 696. boolean acid_dmg; 697. boolean fade_scrolls; 698. { 699. int erosion; 700. struct monst *victim; 701. boolean vismon; 702. boolean visobj; 703. 704. if (!target) 705. return; 706. victim = carried(target) ? &youmonst : 707. mcarried(target) ? target->ocarry : (struct monst *)0; 708. vismon = victim && (victim != &youmonst) && canseemon(victim); 709. visobj = !victim && cansee(bhitpos.x, bhitpos.y); /* assume thrown */ 710. 711. erosion = acid_dmg ? target->oeroded2 : target->oeroded; 712. 713. if (target->greased) { 714. grease_protect(target,(char *)0,victim); 715. } else if (target->oclass == SCROLL_CLASS) { 716. if(fade_scrolls && target->otyp != SCR_BLANK_PAPER 717. #ifdef MAIL 718. && target->otyp != SCR_MAIL 719. #endif 720. ) 721. { 722. if (!Blind) { 723. if (victim == &youmonst) 724. Your("%s.", aobjnam(target, "fade")); 725. else if (vismon) 726. pline("%s's %s.", Monnam(victim), 727. aobjnam(target, "fade")); 728. else if (visobj) 729. pline_The("%s.", aobjnam(target, "fade")); 730. } 731. target->otyp = SCR_BLANK_PAPER; 732. target->spe = 0; 733. } 734. } else if (target->oerodeproof || 735. (acid_dmg ? !is_corrodeable(target) : !is_rustprone(target))) { 736. if (flags.verbose || !(target->oerodeproof && target->rknown)) { 737. if (victim == &youmonst) 738. Your("%s not affected.", aobjnam(target, "are")); 739. else if (vismon) 740. pline("%s's %s not affected.", Monnam(victim), 741. aobjnam(target, "are")); 742. /* no message if not carried */ 743. } 744. if (target->oerodeproof) target->rknown = TRUE; 745. } else if (erosion < MAX_ERODE) { 746. if (victim == &youmonst) 747. Your("%s%s!", aobjnam(target, acid_dmg ? "corrode" : "rust"), 748. erosion+1 == MAX_ERODE ? " completely" : 749. erosion ? " further" : ""); 750. else if (vismon) 751. pline("%s's %s%s!", Monnam(victim), 752. aobjnam(target, acid_dmg ? "corrode" : "rust"), 753. erosion+1 == MAX_ERODE ? " completely" : 754. erosion ? " further" : ""); 755. else if (visobj) 756. pline_The("%s%s!", 757. aobjnam(target, acid_dmg ? "corrode" : "rust"), 758. erosion+1 == MAX_ERODE ? " completely" : 759. erosion ? " further" : ""); 760. if (acid_dmg) 761. target->oeroded2++; 762. else 763. target->oeroded++; 764. } else { 765. if (flags.verbose) { 766. if (victim == &youmonst) 767. Your("%s completely %s.", 768. aobjnam(target, Blind ? "feel" : "look"), 769. acid_dmg ? "corroded" : "rusty"); 770. else if (vismon) 771. pline("%s's %s completely %s.", Monnam(victim), 772. aobjnam(target, "look"), 773. acid_dmg ? "corroded" : "rusty"); 774. else if (visobj) 775. pline_The("%s completely %s.", 776. aobjnam(target, "look"), 777. acid_dmg ? "corroded" : "rusty"); 778. } 779. } 780. } 781. 782. int 783. chwepon(otmp, amount) 784. register struct obj *otmp; 785. register int amount; 786. { 787. const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE); 788. const char *xtime; 789. int otyp = STRANGE_OBJECT; 790. 791. if(!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) { 792. char buf[BUFSZ]; 793. 794. Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)), 795. (amount >= 0) ? "twitch" : "itch"); 796. strange_feeling(otmp, buf); 797. exercise(A_DEX, (boolean) (amount >= 0)); 798. return(0); 799. } 800. 801. if (otmp && otmp->oclass == SCROLL_CLASS) otyp = otmp->otyp; 802. 803. if(uwep->otyp == WORM_TOOTH && amount >= 0) { 804. uwep->otyp = CRYSKNIFE; 805. uwep->oerodeproof = 0; 806. Your("weapon seems sharper now."); 807. uwep->cursed = 0; 808. if (otyp != STRANGE_OBJECT) makeknown(otyp); 809. return(1); 810. } 811. 812. if(uwep->otyp == CRYSKNIFE && amount < 0) { 813. uwep->otyp = WORM_TOOTH; 814. uwep->oerodeproof = 0; 815. Your("weapon seems duller now."); 816. if (otyp != STRANGE_OBJECT && otmp->bknown) makeknown(otyp); 817. return(1); 818. } 819. 820. if (amount < 0 && uwep->oartifact && restrict_name(uwep, ONAME(uwep))) { 821. if (!Blind) 822. Your("%s %s.", aobjnam(uwep, "faintly glow"), color); 823. return(1); 824. } 825. /* there is a (soft) upper and lower limit to uwep->spe */ 826. if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0)) 827. && rn2(3)) { 828. if (!Blind) 829. Your("%s %s for a while and then %s.", 830. aobjnam(uwep, "violently glow"), color, 831. otense(uwep, "evaporate")); 832. else 833. Your("%s.", aobjnam(uwep, "evaporate")); 834. 835. useupall(uwep); /* let all of them disappear */ 836. return(1); 837. } 838. if (!Blind) { 839. xtime = (amount*amount == 1) ? "moment" : "while"; 840. Your("%s %s for a %s.", 841. aobjnam(uwep, amount == 0 ? "violently glow" : "glow"), 842. color, xtime); 843. if (otyp != STRANGE_OBJECT && uwep->known && 844. (amount > 0 || (amount < 0 && otmp->bknown))) 845. makeknown(otyp); 846. } 847. uwep->spe += amount; 848. if(amount > 0) uwep->cursed = 0; 849. 850. /* 851. * Enchantment, which normally improves a weapon, has an 852. * addition adverse reaction on Magicbane whose effects are 853. * spe dependent. Give an obscure clue here. 854. */ 855. if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) { 856. Your("right %s %sches!", 857. body_part(HAND), 858. (((amount > 1) && (uwep->spe > 1)) ? "flin" : "it")); 859. } 860. 861. /* an elven magic clue, cookie@keebler */ 862. /* elven weapons vibrate warningly when enchanted beyond a limit */ 863. if ((uwep->spe > 5) 864. && (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7))) 865. Your("%s unexpectedly.", 866. aobjnam(uwep, "suddenly vibrate")); 867. 868. return(1); 869. } 870. 871. int 872. welded(obj) 873. register struct obj *obj; 874. { 875. if (obj && obj == uwep && will_weld(obj)) { 876. obj->bknown = TRUE; 877. return 1; 878. } 879. return 0; 880. } 881. 882. void 883. weldmsg(obj) 884. register struct obj *obj; 885. { 886. long savewornmask; 887. 888. savewornmask = obj->owornmask; 889. Your("%s %s welded to your %s!", 890. xname(obj), otense(obj, "are"), 891. bimanual(obj) ? (const char *)makeplural(body_part(HAND)) 892. : body_part(HAND)); 893. obj->owornmask = savewornmask; 894. } 895. 896. void 897. unwield(obj, put_away) 898. register struct obj *obj; 899. boolean put_away; 900. { 901. /* MRKR: Extinguish torches when they are put away */ 902. if (put_away && obj->otyp == TORCH && obj->lamplit) { 903. You("extinguish %s before putting it away.", yname(obj)); 904. end_burn(obj, TRUE); 905. } 906. } 907. 908. /*wield.c*/
|