Wikihack
Advertisement

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.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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*/
Advertisement