Source:NetHack 3.2.0/wield.c

From NetHackWiki
(Redirected from NetHack 3.2.0/wield.c)
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)wield.c	3.2	96/01/24	*/
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.    /* elven weapons vibrate warningly when enchanted beyond a limit */
8.    #define is_elven_weapon(optr)	((optr)->otyp == ELVEN_ARROW\
9.    				|| (optr)->otyp == ELVEN_SPEAR\
10.   				|| (optr)->otyp == ELVEN_DAGGER\
11.   				|| (optr)->otyp == ELVEN_SHORT_SWORD\
12.   				|| (optr)->otyp == ELVEN_BROADSWORD\
13.   				|| (optr)->otyp == ELVEN_BOW)
14.   
15.   /* used by welded(), and also while wielding */
16.   #define will_weld(optr)		((optr)->cursed \
17.   				&& ((optr)->oclass == WEAPON_CLASS \
18.   				   || is_weptool(optr) \
19.   				   || (optr)->otyp == HEAVY_IRON_BALL \
20.   				   || (optr)->otyp == TIN_OPENER))
21.   
22.   /* Note: setuwep() with a null obj, and uwepgone(), are NOT the same!
23.    * Sometimes unwielding a weapon can kill you, and lifesaving will then
24.    * put it back into your hand.  If lifesaving is permitted to do this,
25.    * use setwuep((struct obj *)0); otherwise use uwepgone().
26.    */
27.   void
28.   setuwep(obj)
29.   register struct obj *obj;
30.   {
31.   	if (obj == uwep) return; /* necessary to not set unweapon */
32.   	setworn(obj, W_WEP);
33.   	/* Note: Explicitly wielding a pick-axe will not give a "bashing"
34.   	 * message.  Wielding one via 'a'pplying it will.
35.   	 */
36.   	if (obj)
37.   		unweapon = ((obj->oclass == WEAPON_CLASS &&
38.   			     (objects[obj->otyp].oc_wepcat == WEP_BOW ||
39.   			      objects[obj->otyp].oc_wepcat == WEP_AMMO ||
40.   			      objects[obj->otyp].oc_wepcat == WEP_MISSILE)) ||
41.   			    (obj->oclass == TOOL_CLASS && !is_weptool(obj)));
42.   	else
43.   		unweapon = TRUE;	/* for "bare hands" message */
44.   	update_inventory();
45.   }
46.   
47.   void
48.   uwepgone()
49.   {
50.   	if (uwep) {
51.   		setworn((struct obj *)0, W_WEP);
52.   		unweapon = TRUE;
53.   		update_inventory();
54.   	}
55.   }
56.   
57.   static NEARDATA const char wield_objs[] =
58.   	{ ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, TOOL_CLASS, 0 };
59.   
60.   int
61.   dowield()
62.   {
63.   	register struct obj *wep;
64.   	register int res = 0;
65.   
66.   	multi = 0;
67.   	if (cantwield(uasmon)) {
68.   	    pline("Don't be ridiculous!");
69.   	    return(0);
70.   	}
71.   	if (!(wep = getobj(wield_objs, "wield"))) {
72.   	    ;	/* nothing */
73.   	} else if (uwep == wep) {
74.   	    You("are already wielding that!");
75.   	    if (is_weptool(wep)) unweapon = FALSE;	/* [see setuwep()] */
76.   	} else if (welded(uwep)) {
77.   	    weldmsg(uwep, TRUE);
78.   	} else if (wep == &zeroobj) {
79.   	    if (uwep == 0)
80.   		You("are already empty %s.", body_part(HANDED));
81.   	    else  {
82.   		You("are empty %s.", body_part(HANDED));
83.   		setuwep((struct obj *) 0);
84.   		res++;
85.   	    }
86.   	} else if (!uarmg && !resists_ston(&youmonst) &&
87.   		   (wep->otyp == CORPSE && wep->corpsenm == PM_COCKATRICE)) {
88.   	    /* Prevent wielding cockatrice when not wearing gloves --KAA */
89.   	    You("wield the cockatrice corpse in your bare %s.",
90.   			makeplural(body_part(HAND)));
91.   	    instapetrify("cockatrice corpse");
92.   	} else if (uarms && bimanual(wep))
93.   	    You("cannot wield a two-handed %s while wearing a shield.",
94.   		is_sword(wep) ? "sword" :
95.   		    wep->otyp == BATTLE_AXE ? "axe" : "weapon");
96.   	else if (wep->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))
97.   	    You("cannot wield that!");
98.   	else if (wep->oartifact && !touch_artifact(wep, &youmonst))
99.   	    res++;	/* takes a turn even though it doesn't get wielded */
100.  	else {
101.  	    res++;
102.  	    if (will_weld(wep)) {
103.  		const char *tmp = xname(wep), *thestr = "The ";
104.  		if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp),thestr,4))
105.  		    tmp = thestr;
106.  		else tmp = "";
107.  		pline("%s%s %s to your %s!",
108.  		      tmp, aobjnam(wep, "weld"),
109.  		      (wep->quan == 1L) ? "itself" : "themselves", /* a3 */
110.  		      body_part(HAND));
111.  		wep->bknown = TRUE;
112.  	    } else {
113.  		/* The message must be printed before setuwep (since
114.  		 * you might die and be revived from changing weapons),
115.  		 * and the message must be before the death message and
116.  		 * Lifesaved rewielding.  Yet we want the message to
117.  		 * say "weapon in hand", thus this kludge.
118.  		 */
119.  		long dummy = wep->owornmask;
120.  		wep->owornmask |= W_WEP;
121.  		prinv((char *)0, wep, 0L);
122.  		wep->owornmask = dummy;
123.  	    }
124.  	    setuwep(wep);
125.  	    if (wep->unpaid) {
126.  		struct monst *this_shkp;
127.  
128.  		if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy))) !=
129.  		    (struct monst *)0) {
130.  		    pline("%s says \"You be careful with my %s!\"",
131.  			  shkname(this_shkp),
132.  			  xname(wep));
133.  		}
134.  	    }
135.  	}
136.  	return(res);
137.  }
138.  
139.  void
140.  erode_weapon(acid_dmg)
141.  boolean acid_dmg;
142.  /* Rust weapon, or corrode it if acid damage is called for */
143.  {
144.  	if(!uwep || uwep->oclass != WEAPON_CLASS) return;	/* %% */
145.  	if (uwep->greased) {
146.  		grease_protect(uwep,(char *)0,FALSE);
147.  	} else if(uwep->oerodeproof ||
148.  	   (acid_dmg ? !is_corrodeable(uwep) : !is_rustprone(uwep))) {
149.  		if (flags.verbose || !(uwep->oerodeproof && uwep->rknown))
150.  		    Your("%s not affected.", aobjnam(uwep, "are"));
151.  		if (uwep->oerodeproof) uwep->rknown = TRUE;
152.  	} else if (uwep->oeroded < MAX_ERODE) {
153.  		Your("%s%s!", aobjnam(uwep, acid_dmg ? "corrode" : "rust"),
154.  		     uwep->oeroded+1 == MAX_ERODE ? " completely" :
155.  		     uwep->oeroded ? " further" : "");
156.  		uwep->oeroded++;
157.  	} else
158.  		if (flags.verbose)
159.  		    Your("%s completely %s.",
160.  			 aobjnam(uwep, Blind ? "feel" : "look"),
161.  			 acid_dmg ? "corroded" : "rusty");
162.  }
163.  
164.  int
165.  chwepon(otmp, amount)
166.  register struct obj *otmp;
167.  register int amount;
168.  {
169.  	register const char *color = hcolor((amount < 0) ? Black : blue);
170.  	register const char *xtime;
171.  
172.  	if(!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) {
173.  		char buf[BUFSZ];
174.  
175.  		Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),
176.  			(amount >= 0) ? "twitch" : "itch");
177.  		strange_feeling(otmp, buf);
178.  		exercise(A_DEX, (boolean) (amount >= 0));
179.  		return(0);
180.  	}
181.  
182.  	if(uwep->otyp == WORM_TOOTH && amount >= 0) {
183.  		uwep->otyp = CRYSKNIFE;
184.  		Your("weapon seems sharper now.");
185.  		uwep->cursed = 0;
186.  		return(1);
187.  	}
188.  
189.  	if(uwep->otyp == CRYSKNIFE && amount < 0) {
190.  		uwep->otyp = WORM_TOOTH;
191.  		Your("weapon seems duller now.");
192.  		return(1);
193.  	}
194.  
195.  	if (amount < 0 && uwep->oartifact && restrict_name(uwep, ONAME(uwep))) {
196.  	    if (!Blind)
197.  		Your("%s %s.", aobjnam(uwep, "faintly glow"), color);
198.  	    return(1);
199.  	}
200.  	/* there is a (soft) upper and lower limit to uwep->spe */
201.  	if(((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
202.  								&& rn2(3)) {
203.  	    if (!Blind)
204.  	    Your("%s %s for a while and then evaporate%s.",
205.  		 aobjnam(uwep, "violently glow"), color,
206.  		 uwep->quan == 1L ? "s" : "");
207.  	    else
208.  		Your("%s.", aobjnam(uwep, "evaporate"));
209.  
210.  	    while(uwep)		/* let all of them disappear */
211.  				/* note: uwep->quan = 1 is nogood if unpaid */
212.  		useup(uwep);
213.  	    return(1);
214.  	}
215.  	if (!Blind) {
216.  	    xtime = (amount*amount == 1) ? "moment" : "while";
217.  	    Your("%s %s for a %s.",
218.  		 aobjnam(uwep, amount == 0 ? "violently glow" : "glow"),
219.  		 color, xtime);
220.  	}
221.  	uwep->spe += amount;
222.  	if(amount > 0) uwep->cursed = 0;
223.  
224.  	/*
225.  	 * Enchantment, which normally improves a weapon, has an
226.  	 * addition adverse reaction on Magicbane whose effects are
227.  	 * spe dependent.  Give an obscure clue here.
228.  	 */
229.  	if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) {
230.  		Your("right %s %sches!",
231.  			body_part(HAND),
232.  			(((amount > 1) && (uwep->spe > 1)) ? "flin" : "it"));
233.  	}
234.  
235.  	/* an elven magic clue, cookie@keebler */
236.  	if ((uwep->spe > 5)
237.  		&& (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
238.  	    Your("%s unexpectedly.",
239.  		aobjnam(uwep, "suddenly vibrate"));
240.  
241.  	return(1);
242.  }
243.  
244.  int
245.  welded(obj)
246.  register struct obj *obj;
247.  {
248.  	if (obj && obj == uwep && will_weld(obj)) {
249.  		obj->bknown = TRUE;
250.  		return 1;
251.  	}
252.  	return 0;
253.  }
254.  
255.  /* The reason for "specific" is historical; some parts of the code used
256.   * the object name and others just used "weapon"/"sword".  This function
257.   * replaced all of those.  Which one we use is really arbitrary.
258.   */
259.  void
260.  weldmsg(obj, specific)
261.  register struct obj *obj;
262.  boolean specific;
263.  {
264.  	char buf[BUFSZ];
265.  
266.  	if (specific) {
267.  		long savewornmask = obj->owornmask;
268.  		obj->owornmask &= ~W_WEP;
269.  		Strcpy(buf, Doname2(obj));
270.  		obj->owornmask = savewornmask;
271.  	} else
272.  		Sprintf(buf, "Your %s%s",
273.  			is_sword(obj) ? "sword" : "weapon",
274.  			plur(obj->quan));
275.  	Strcat(buf, (obj->quan == 1L) ? " is" : " are");
276.  	Sprintf(eos(buf), " welded to your %s!",
277.  		bimanual(obj) ? (const char *)makeplural(body_part(HAND))
278.  				: body_part(HAND));
279.  	pline(buf);
280.  }
281.  
282.  /*wield.c*/