Source:NetHack 3.3.0/wield.c

Below is the full text to wield.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/wield.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)wield.c	3.3	1999/08/16	*/ 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.    53.   static int FDECL(ready_weapon, (struct obj *)); 54.   55.   /* elven weapons vibrate warningly when enchanted beyond a limit */ 56.  #define is_elven_weapon(optr)	((optr)->otyp == ELVEN_ARROW\  57.   				|| (optr)->otyp == ELVEN_SPEAR\  58.   				|| (optr)->otyp == ELVEN_DAGGER\  59.   				|| (optr)->otyp == ELVEN_SHORT_SWORD\  60.   				|| (optr)->otyp == ELVEN_BROADSWORD\  61.   				|| (optr)->otyp == ELVEN_BOW) 62.   63.   /* used by will_weld */ 64.  /* probably should be renamed */ 65.  #define erodeable_wep(optr)	((optr)->oclass == WEAPON_CLASS \  66.   				|| is_weptool(optr) \  67.   				|| (optr)->otyp == HEAVY_IRON_BALL \  68.   				|| (optr)->otyp == IRON_CHAIN) 69.   70.   /* used by welded, and also while wielding */ 71.  #define will_weld(optr)		((optr)->cursed \  72.   				&& (erodeable_wep(optr) \ 73.  				   || (optr)->otyp == TIN_OPENER)) 74.   75.    76.   /*** Functions that place a given item in a slot ***/ 77.  /* Proper usage includes: 78.   * 1.  Initializing the slot during character generation or a  79. *    restore. 80.   * 2.  Setting the slot due to a player's actions. 81.   * 3.  If one of the objects in the slot are split off, these 82.   *     functions can be used to put the remainder back in the slot. 83.   * 4.  Putting an item that was thrown and returned back into the slot. 84.   * 5.  Emptying the slot, by passing a null object. NEVER pass 85.   *     zeroobj! 86.   *  87.    * Note: setuwep with a null obj, and uwepgone, are NOT the same! 88.   * Sometimes unwielding a weapon can kill you, and lifesaving will then 89.   * put it back into your hand. If lifesaving is permitted to do this, 90.   * use setwuep((struct obj *)0); otherwise use uwepgone. 91.   *  92.    * If the item is being moved from another slot, it is the caller's  93. * responsibility to handle that. It's also the caller's responsibility 94.   * to print the appropriate messages. 95.   */  96.   void 97.  setuwep(obj) 98.  register struct obj *obj; 99.  {  100.  	if (obj == uwep) return; /* necessary to not set unweapon */ 101. 	setworn(obj, W_WEP); 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. 			   !is_weptool(obj); 111. 	} else 112. 		unweapon = TRUE;	/* for "bare hands" message */ 113. 	update_inventory; 114. }  115.   116.  static int 117. ready_weapon(wep) 118. struct obj *wep; 119. {  120.  	/* Separated function so swapping works easily */ 121. 	int res = 0; 122.  123.  	if (!wep) { 124. 	    /* No weapon */ 125. 	    if (uwep) { 126. 		You("are empty %s.", body_part(HANDED)); 127. 		setuwep((struct obj *) 0); 128. 		res++; 129. 	    } else 130. 		You("are already empty %s.", body_part(HANDED)); 131. 	} else if (!uarmg && !Stone_resistance && wep->otyp == CORPSE  132.  				&& touch_petrifies(&mons[wep->corpsenm])) { 133. 	    /* Prevent wielding cockatrice when not wearing gloves --KAA */ 134.             char kbuf[BUFSZ]; 135.  136.              You("wield the %s corpse in your bare %s.",  137.                  mons[wep->corpsenm].mname, makeplural(body_part(HAND))); 138.             Sprintf(kbuf, "%s corpse", an(mons[wep->corpsenm].mname)); 139.             instapetrify(kbuf); 140. 	} else if (uarms && bimanual(wep)) 141. 	    You("cannot wield a two-handed %s while wearing a shield.",  142.  		is_sword(wep) ? "sword" :  143.  		    wep->otyp == BATTLE_AXE ? "axe" : "weapon"); 144. 	else if (wep->oartifact && !touch_artifact(wep, &youmonst)) { 145. 	    res++;	/* takes a turn even though it doesn't get wielded */ 146. 	} else { 147. 	    /* Weapon WILL be wielded after this point */ 148. 	    res++; 149. 	    if (will_weld(wep)) { 150. 		const char *tmp = xname(wep), *thestr = "The "; 151. 		if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp),thestr,4)) 152. 		    tmp = thestr; 153. 		else tmp = ""; 154. 		pline("%s%s %s to your %s!", tmp, aobjnam(wep, "weld"),  155.  			(wep->quan == 1L) ? "itself" : "themselves", /* a3 */  156.  			bimanual(wep) ?  157.  				(const char *)makeplural(body_part(HAND))  158.  				: body_part(HAND)); 159. 		wep->bknown = TRUE; 160. 	    } else { 161. 		/* The message must be printed before setuwep (since  162.  		 * you might die and be revived from changing weapons), 163. 		 * and the message must be before the death message and 164. 		 * Lifesaved rewielding. Yet we want the message to 165. * say "weapon in hand", thus this kludge. 166. 		 */  167.  		long dummy = wep->owornmask; 168. 		wep->owornmask |= W_WEP; 169. 		prinv((char *)0, wep, 0L); 170. 		wep->owornmask = dummy; 171. 	    }  172.  	    setuwep(wep); 173.  174.  	    /* KMH -- Talking artifacts are finally implemented */ 175. 	    arti_speak(wep); 176.  177.  #if 0 178. 	    /* we'll get back to this someday, but it's not balanced yet */ 179. 	    if (Race_if(PM_ELF) && !wep->oartifact &&  180.  			    objects[wep->otyp].oc_material == IRON) { 181. 		/* Elves are averse to wielding cold iron */ 182. 		You("have an uneasy feeling about wielding cold iron."); 183. 		change_luck(-1); 184. 	    }  185.  #endif 186.  187.  	    if (wep->unpaid) { 188. 		struct monst *this_shkp; 189.  190.  		if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy))) !=  191.  		    (struct monst *)0) { 192. 		    pline("%s says \"You be careful with my %s!\"",  193.  			  shkname(this_shkp),  194.  			  xname(wep)); 195. 		}  196.  	    }  197.  	}  198.  	return(res); 199. 	/* Take no time if we are dextrous enough */ 200. /*	return ((rnd(20) > ACURR(A_DEX)) ? res : 0);*/ 201. }  202.   203.  void 204. setuqwep(obj) 205. register struct obj *obj; 206. {  207.  	setworn(obj, W_QUIVER); 208. 	update_inventory; 209. }  210.   211.  void 212. setuswapwep(obj) 213. register struct obj *obj; 214. {  215.  	setworn(obj, W_SWAPWEP); 216. 	update_inventory; 217. }  218.   219.   220.  /*** Commands to change particular slot(s) ***/ 221.  222.  static NEARDATA const char wield_objs[] = 223. 	{ ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, TOOL_CLASS, 0 }; 224.  225.  int 226. dowield 227. {  228.  	register struct obj *wep; 229. 	int result; 230.  231.  	/* May we attempt this? */ 232.  	multi = 0; 233. 	if (cantwield(youmonst.data)) { 234. 		pline("Don't be ridiculous!"); 235. 		return(0); 236. 	}  237.   238.  	/* Prompt for a new weapon */ 239. 	if (!(wep = getobj(wield_objs, "wield"))) 240. 		/* Cancelled */ 241. 		return (0); 242. 	else if (wep == uwep) { 243. 	    You("are already wielding that!"); 244. 	    if (is_weptool(wep)) unweapon = FALSE;	/* [see setuwep] */ 245. 		return (0); 246. 	} else if (welded(uwep)) { 247. 		weldmsg(uwep); 248. 		return (0); 249. 	}  250.   251.  	/* Handle no object, or object in other slot */ 252. 	if (wep == &zeroobj) 253. 		wep = (struct obj *) 0; 254. 	else if (wep == uswapwep) 255. 		return (doswapweapon); 256. 	else if (wep == uquiver) 257. 		setuqwep((struct obj *) 0); 258. 	else if (wep->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL 259. #ifdef STEED 260. 			| W_SADDLE 261. #endif 262. 			)) {  263.  		You("cannot wield that!"); 264. 		return (0); 265. 	}  266.   267.  	/* Set your new primary weapon */ 268. 	if (flags.pushweapon && uwep) 269. 		setuswapwep(uwep); 270. 	result = ready_weapon(wep); 271. 	untwoweapon; 272.  273.  	return (result); 274. }  275.   276.  int 277. doswapweapon 278. {  279.  	register struct obj *oldwep, *oldswap; 280. 	int result = 0; 281.  282.   283.  	/* May we attempt this? */ 284.  	multi = 0; 285. 	if (cantwield(youmonst.data)) { 286. 		pline("Don't be ridiculous!"); 287. 		return(0); 288. 	}  289.  	if (welded(uwep)) { 290. 		weldmsg(uwep); 291. 		return (0); 292. 	}  293.   294.  	/* Unwield your current secondary weapon */ 295. 	oldwep = uwep; 296. 	oldswap = uswapwep; 297. 	setuswapwep((struct obj *) 0); 298.  299.  	/* Set your new primary weapon */ 300. 	result = ready_weapon(oldswap); 301.  302.  	/* Set your new secondary weapon */ 303. 	if (uwep == oldwep) 304. 		/* Wield failed for some reason */ 305. 		setuswapwep(oldswap); 306. 	else { 307. 		setuswapwep(oldwep); 308. 		if (uswapwep) 309. 			prinv((char *)0, uswapwep, 0L); 310. 		else 311. 			You("have no secondary weapon readied."); 312. 	}  313.   314.  	if (u.twoweap && !can_twoweapon) 315. 		untwoweapon; 316.  317.  	return (result); 318. }  319.   320.  int 321. dowieldquiver 322. {  323.  	register struct obj *newquiver; 324.  325.   326.  	/* Since the quiver isn't in your hands, don't check cantwield, */ 327. 	/* will_weld, touch_petrifies, etc. */ 328. 	multi = 0; 329.  330.  	/* Because 'Q' used to be quit... */ 331.  	if (!flags.suppress_alert || flags.suppress_alert < FEATURE_NOTICE_VER(3,3,0)) 332. 		pline("Note: Please use #quit if you wish to exit the game."); 333.  334.  	/* Prompt for a new quiver */ 335. 	if (!(newquiver = getobj(wield_objs, "ready"))) 336. 		/* Cancelled */ 337. 		return (0); 338.  339.  	/* Handle no object, or object in other slot */ 340. 	/* Any type is okay, since we give no intrinsics anyways */ 341. 	if (newquiver == &zeroobj) { 342. 		/* Explicitly nothing */ 343. 		if (uquiver) { 344. 			pline("You now have no ammunition readied."); 345. 			setuqwep(newquiver = (struct obj *) 0); 346. 		} else { 347. 			pline("You already have no ammunition readied!"); 348. 			return(0); 349. 		}  350.  	} else if (newquiver == uquiver) { 351. 		pline("That ammunition is already readied!"); 352. 		return(0); 353. 	} else if (newquiver == uwep) { 354. 		/* Prevent accidentally readying the main weapon */ 355. 		pline("That is already being used as a weapon!"); 356. 		return(0); 357. 	} else if (newquiver->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL 358. #ifdef STEED 359. 			| W_SADDLE 360. #endif 361. 			)) {  362.  		You("cannot ready that!"); 363. 		return (0); 364. 	} else { 365. 		long dummy; 366.  367.   368.  		/* Check if it's the secondary weapon */ 369. 		if (newquiver == uswapwep) { 370. 			setuswapwep((struct obj *) 0); 371. 			untwoweapon; 372. 		}  373.   374.  		/* Okay to put in quiver; print it */ 375. 		dummy = newquiver->owornmask; 376. 		newquiver->owornmask |= W_QUIVER; 377. 		prinv((char *)0, newquiver, 0L); 378. 		newquiver->owornmask = dummy; 379. 	}  380.   381.  	/* Finally, place it in the quiver */ 382. 	setuqwep(newquiver); 383. 	/* Take no time if we are dextrous enough */ 384. 	return (rnd(20) > ACURR(A_DEX)); 385. }  386.   387.  int 388. can_twoweapon 389. {  390.  #define NOT_WEAPON(obj) (!is_weptool(obj) && obj->oclass != WEAPON_CLASS) 391. 	if (Upolyd) 392. 		You("can only use two weapons in your normal form."); 393. 	else if (!uwep || !uswapwep) 394. 		Your("%s%s%s empty.", uwep ? "left " : uswapwep ? "right " : "",  395.  			body_part(HAND), (!uwep && !uswapwep) ? "s are" : " is"); 396. 	else if (NOT_WEAPON(uwep) || bimanual(uwep)) 397. 		pline("%s isn't %s%s%s.", Yname2(uwep),  398.  			NOT_WEAPON(uwep) ? "a ": "",  399.  			bimanual(uwep) ? "one-handed": "",  400.  			NOT_WEAPON(uwep) ? "weapon": ""); 401. 	else if (NOT_WEAPON(uswapwep) || bimanual(uswapwep)) 402. 		pline("%s isn't %s%s%s.", Yname2(uswapwep),  403.  			NOT_WEAPON(uswapwep) ? "a ": "",  404.  			bimanual(uswapwep) ? "one-handed": "",  405.  			NOT_WEAPON(uswapwep) ? "weapon": ""); 406. 	else if (uarms) 407. 		You("can't use two weapons while wearing a shield."); 408. 	else if (uswapwep->oartifact) 409. 		pline("%s resists being held second to another weapon!",  410.  			Yname2(uswapwep)); 411. 	else if (!uarmg && !Stone_resistance && (uswapwep->otyp == CORPSE && 412.                   (touch_petrifies(&mons[uswapwep->corpsenm])))) { 413. 		char kbuf[BUFSZ]; 414.  415.  		You("wield the %s corpse with your bare %s.",  416.  		    mons[uswapwep->corpsenm].mname, body_part(HAND)); 417. 		Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); 418. 		instapetrify(kbuf); 419. 	} else if (Glib || uswapwep->cursed) { 420. 		struct obj *obj = uswapwep; 421.  422.  		Your("%s from your %s!",  aobjnam(obj, "slip"),  423.  				makeplural(body_part(HAND))); 424. 		if (!Glib) 425. 			obj->bknown = TRUE; 426. 		setuswapwep((struct obj *) 0); 427. 		dropx(obj); 428. 	} else 429. 		return (TRUE); 430. 	return (FALSE); 431. }  432.   433.  int 434. dotwoweapon 435. {  436.  	/* You can always toggle it off */ 437. 	if (u.twoweap) { 438. 		You("switch to your primary weapon."); 439. 		u.twoweap = 0; 440. 		return (0); 441. 	}  442.   443.  	/* May we use two weapons? */ 444.  	if (can_twoweapon) { 445. 		/* Success! */ 446.  		You("begin two-weapon combat."); 447. 		u.twoweap = 1; 448. 		return (rnd(20) > ACURR(A_DEX)); 449. 	}  450.  	return (0); 451. }  452.   453.  /*** Functions to empty a given slot ***/ 454. /* These should be used only when the item can't be put back in  455. * the slot by life saving. Proper usage includes: 456.  * 1.  The item has been eaten, stolen, burned away, or rotted away. 457.  * 2.  Making an item disappear for a bones pile. 458.  */  459.  void 460. uwepgone 461. {  462.  	if (uwep) { 463. 		setworn((struct obj *)0, W_WEP); 464. 		unweapon = TRUE; 465. 		update_inventory; 466. 	}  467.  }  468.   469.  void 470. uswapwepgone 471. {  472.  	if (uswapwep) { 473. 		setworn((struct obj *)0, W_SWAPWEP); 474. 		update_inventory; 475. 	}  476.  }  477.   478.  void 479. uqwepgone 480. {  481.  	if (uquiver) { 482. 		setworn((struct obj *)0, W_QUIVER); 483. 		update_inventory; 484. 	}  485.  }  486.   487.  void 488. untwoweapon 489. {  490.  	if (u.twoweap) { 491. 		You("can no longer use two weapons at once."); 492. 		u.twoweap = FALSE; 493. 	}  494.  	return; 495. }  496.   497.  /* Maybe rust weapon, or corrode it if acid damage is called for */ 498. void 499. erode_weapon(victim, acid_dmg) 500. struct monst *victim; 501. boolean acid_dmg; 502. {  503.  	int erosion; 504. 	struct obj *target; 505. 	boolean vismon = (victim != &youmonst) && canseemon(victim); 506.  507.  	target = (victim == &youmonst) ? uwep : MON_WEP(victim); 508. 	if (!target) 509. 	    return; 510.  511.  	erosion = acid_dmg ? target->oeroded2 : target->oeroded; 512.  513.  	if (target->greased) { 514. 	    grease_protect(target,(char *)0,FALSE,victim); 515. 	} else if (target->oerodeproof ||  516.  		(acid_dmg ? !is_corrodeable(target) : !is_rustprone(target))) { 517. 	    if (flags.verbose || !(target->oerodeproof && target->rknown)) { 518. 		if (victim == &youmonst) 519. 		    Your("%s not affected.", aobjnam(target, "are")); 520. 		else if (vismon) 521. 		    pline("%s's %s not affected.", Monnam(victim),  522.  			aobjnam(target, "are")); 523. 	    }  524.  	    if (target->oerodeproof) target->rknown = TRUE; 525. 	} else if (erosion < MAX_ERODE) { 526. 	    if (victim == &youmonst) 527. 		Your("%s%s!", aobjnam(target, acid_dmg ? "corrode" : "rust"), 528.  		    erosion+1 == MAX_ERODE ? " completely" :  529.  		    erosion ? " further" : ""); 530. 	    else if (vismon) 531. 		pline("%s's %s%s!", Monnam(victim),  532.  		    aobjnam(target, acid_dmg ? "corrode" : "rust"), 533.  		    erosion+1 == MAX_ERODE ? " completely" :  534.  		    erosion ? " further" : ""); 535. 	    if (acid_dmg) 536. 		target->oeroded2++; 537. 	    else 538. 		target->oeroded++; 539. 	} else { 540. 	    if (flags.verbose) { 541. 		if (victim == &youmonst) 542. 		    Your("%s completely %s.",  543.  			aobjnam(target, Blind ? "feel" : "look"), 544.  			acid_dmg ? "corroded" : "rusty"); 545. 		else if (vismon) 546. 		    pline("%s's %s completely %s.", Monnam(victim),  547.  			aobjnam(target, "look"),  548.  			acid_dmg ? "corroded" : "rusty"); 549. 	    }  550.  	}  551.  }  552.   553.  int 554. chwepon(otmp, amount) 555. register struct obj *otmp; 556. register int amount; 557. {  558.  	register const char *color = hcolor((amount < 0) ? Black : blue); 559. 	register const char *xtime; 560.  561.  	if(!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) { 562. 		char buf[BUFSZ]; 563.  564.  		Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),  565.  			(amount >= 0) ? "twitch" : "itch"); 566. 		strange_feeling(otmp, buf); 567. 		exercise(A_DEX, (boolean) (amount >= 0)); 568. 		return(0); 569. 	}  570.   571.  	if(uwep->otyp == WORM_TOOTH && amount >= 0) { 572. 		uwep->otyp = CRYSKNIFE; 573. 		uwep->oerodeproof = 0; 574. 		Your("weapon seems sharper now."); 575. 		uwep->cursed = 0; 576. 		return(1); 577. 	}  578.   579.  	if(uwep->otyp == CRYSKNIFE && amount < 0) { 580. 		uwep->otyp = WORM_TOOTH; 581. 		uwep->oerodeproof = 0; 582. 		Your("weapon seems duller now."); 583. 		return(1); 584. 	}  585.   586.  	if (amount < 0 && uwep->oartifact && restrict_name(uwep, ONAME(uwep))) { 587. 	    if (!Blind) 588. 		Your("%s %s.", aobjnam(uwep, "faintly glow"), color); 589. 	    return(1); 590. 	}  591.  	/* there is a (soft) upper and lower limit to uwep->spe */ 592. 	if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))  593.  								&& rn2(3)) { 594. 	    if (!Blind) 595. 	    Your("%s %s for a while and then evaporate%s.",  596.  		 aobjnam(uwep, "violently glow"), color,  597.  		 uwep->quan == 1L ? "s" : ""); 598. 	    else 599. 		Your("%s.", aobjnam(uwep, "evaporate")); 600.  601.  	    while(uwep)		/* let all of them disappear */ 602. 				/* note: uwep->quan = 1 is nogood if unpaid */ 603. 		useup(uwep); 604. 	    return(1); 605. 	}  606.  	if (!Blind) { 607. 	    xtime = (amount*amount == 1) ? "moment" : "while"; 608. 	    Your("%s %s for a %s.",  609.  		 aobjnam(uwep, amount == 0 ? "violently glow" : "glow"), 610.  		 color, xtime); 611. 	}  612.  	uwep->spe += amount; 613. 	if(amount > 0) uwep->cursed = 0; 614.  615.  	/*  616.  	 * Enchantment, which normally improves a weapon, has an  617. * addition adverse reaction on Magicbane whose effects are 618. 	 * spe dependent. Give an obscure clue here. 619. 	 */  620.  	if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) { 621. 		Your("right %s %sches!",  622.  			body_part(HAND),  623.  			(((amount > 1) && (uwep->spe > 1)) ? "flin" : "it")); 624. 	}  625.   626.  	/* an elven magic clue, cookie@keebler */ 627. 	if ((uwep->spe > 5)  628.  		&& (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7))) 629. 	    Your("%s unexpectedly.",  630.  		aobjnam(uwep, "suddenly vibrate")); 631.  632.  	return(1); 633. }  634.   635.  int 636. welded(obj) 637. register struct obj *obj; 638. {  639.  	if (obj && obj == uwep && will_weld(obj)) { 640. 		obj->bknown = TRUE; 641. 		return 1; 642. 	}  643.  	return 0; 644. }  645.   646.  void 647. weldmsg(obj) 648. register struct obj *obj; 649. {  650.  	long savewornmask; 651.  652.  	savewornmask = obj->owornmask; 653. 	Your("%s %s welded to your %s!",  654.  		xname(obj), (obj->quan == 1L) ? "is" : "are",  655.  		bimanual(obj) ? (const char *)makeplural(body_part(HAND))  656.  				: body_part(HAND)); 657. 	obj->owornmask = savewornmask; 658. }  659.   660.  /*wield.c*/