Source:SLASH'EM 0.0.7E7F2/wield.c

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