Source:Wield.c

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