1 /* NetHack 3.7	wield.c	$NHDT-Date: 1607200367 2020/12/05 20:32:47 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2009. */
4 /* NetHack may be freely redistributed.  See license for details. */
5 
6 #include "hack.h"
7 
8 /* KMH -- Differences between the three weapon slots.
9  *
10  * The main weapon (uwep):
11  * 1.  Is filled by the (w)ield command.
12  * 2.  Can be filled with any type of item.
13  * 3.  May be carried in one or both hands.
14  * 4.  Is used as the melee weapon and as the launcher for
15  *     ammunition.
16  * 5.  Only conveys intrinsics when it is a weapon, weapon-tool,
17  *     or artifact.
18  * 6.  Certain cursed items will weld to the hand and cannot be
19  *     unwielded or dropped.  See erodeable_wep() and will_weld()
20  *     below for the list of which items apply.
21  *
22  * The secondary weapon (uswapwep):
23  * 1.  Is filled by the e(x)change command, which swaps this slot
24  *     with the main weapon.  If the "pushweapon" option is set,
25  *     the (w)ield command will also store the old weapon in the
26  *     secondary slot.
27  * 2.  Can be filled with anything that will fit in the main weapon
28  *     slot; that is, any type of item.
29  * 3.  Is usually NOT considered to be carried in the hands.
30  *     That would force too many checks among the main weapon,
31  *     second weapon, shield, gloves, and rings; and it would
32  *     further be complicated by bimanual weapons.  A special
33  *     exception is made for two-weapon combat.
34  * 4.  Is used as the second weapon for two-weapon combat, and as
35  *     a convenience to swap with the main weapon.
36  * 5.  Never conveys intrinsics.
37  * 6.  Cursed items never weld (see #3 for reasons), but they also
38  *     prevent two-weapon combat.
39  *
40  * The quiver (uquiver):
41  * 1.  Is filled by the (Q)uiver command.
42  * 2.  Can be filled with any type of item.
43  * 3.  Is considered to be carried in a special part of the pack.
44  * 4.  Is used as the item to throw with the (f)ire command.
45  *     This is a convenience over the normal (t)hrow command.
46  * 5.  Never conveys intrinsics.
47  * 6.  Cursed items never weld; their effect is handled by the normal
48  *     throwing code.
49  * 7.  The autoquiver option will fill it with something deemed
50  *     suitable if (f)ire is used when it's empty.
51  *
52  * No item may be in more than one of these slots.
53  */
54 
55 static int ready_weapon(struct obj *);
56 static int ready_ok(struct obj *);
57 static int wield_ok(struct obj *);
58 
59 /* to dual-wield, 'obj' must be a weapon or a weapon-tool, and not a bow
60    or arrow or missile (dart, shuriken, boomerang), so not matching the
61    one-handed weapons which yield "you begin bashing" if used for melee;
62    empty hands and two-handed weapons have to be handled separately */
63 #define TWOWEAPOK(obj) \
64     (((obj)->oclass == WEAPON_CLASS)                            \
65      ? !(is_launcher(obj) ||is_ammo(obj) || is_missile(obj))    \
66      : is_weptool(obj))
67 
68 static const char
69     are_no_longer_twoweap[] = "are no longer using two weapons at once",
70     can_no_longer_twoweap[] = "can no longer wield two weapons at once";
71 
72 /*** Functions that place a given item in a slot ***/
73 /* Proper usage includes:
74  * 1.  Initializing the slot during character generation or a
75  *     restore.
76  * 2.  Setting the slot due to a player's actions.
77  * 3.  If one of the objects in the slot are split off, these
78  *     functions can be used to put the remainder back in the slot.
79  * 4.  Putting an item that was thrown and returned back into the slot.
80  * 5.  Emptying the slot, by passing a null object.  NEVER pass
81  *     cg.zeroobj!
82  *
83  * If the item is being moved from another slot, it is the caller's
84  * responsibility to handle that.  It's also the caller's responsibility
85  * to print the appropriate messages.
86  */
87 void
setuwep(struct obj * obj)88 setuwep(struct obj *obj)
89 {
90     struct obj *olduwep = uwep;
91 
92     if (obj == uwep)
93         return; /* necessary to not set g.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)
101             pline("%s shining.", Tobjnam(olduwep, "stop"));
102     }
103     if (uwep == obj
104         && ((uwep && uwep->oartifact == ART_OGRESMASHER)
105             || (olduwep && olduwep->oartifact == ART_OGRESMASHER)))
106         g.context.botl = 1;
107     /* Note: Explicitly wielding a pick-axe will not give a "bashing"
108      * message.  Wielding one via 'a'pplying it will.
109      * 3.2.2:  Wielding arbitrary objects will give bashing message too.
110      */
111     if (obj) {
112         int skill = weapon_type(obj); /* non-weapons => P_NONE */
113         g.unweapon = (obj->oclass == WEAPON_CLASS)
114                        ? is_launcher(obj) || is_ammo(obj) || is_missile(obj)
115                              || (is_pole(obj) && !u.usteed)
116                        : !is_weptool(obj) && !is_wet_towel(obj);
117         if (skill != P_NONE && P_SKILL(skill) < P_BASIC
118             && g.moves > 1) {
119             /* check moves because starting weapon is wielded before skills are
120              * initialized */
121             g.unweapon = TRUE;
122         }
123     } else
124         g.unweapon = TRUE; /* for "bare hands" message */
125 }
126 
127 boolean
cant_wield_corpse(struct obj * obj)128 cant_wield_corpse(struct obj *obj)
129 {
130     char kbuf[BUFSZ];
131 
132     if (uarmg || obj->otyp != CORPSE || !touch_petrifies(&mons[obj->corpsenm])
133         || Stone_resistance)
134         /* no Hallucination check here; instapetrify() takes care of that */
135         return FALSE;
136 
137     /* Prevent wielding cockatrice when not wearing gloves --KAA */
138     /* note that hallucination wearing off while wielding cockatrice can trigger
139      * this function - that should be the only case for which obj is already
140      * uwep, since we otherwise check this before actually wielding it. */
141     You("%s %s in your bare %s.",
142         obj == uwep ? "are still wielding" : "wield",
143         corpse_xname(obj, (const char *) 0, CXN_PFX_THE),
144         makeplural(body_part(HAND)));
145     Sprintf(kbuf, "wielding %s bare-handed", killer_xname(obj));
146     instapetrify(kbuf);
147     return TRUE;
148 }
149 
150 static int
ready_weapon(struct obj * wep)151 ready_weapon(struct obj *wep)
152 {
153     /* Separated function so swapping works easily */
154     int res = 0;
155     boolean was_twoweap = u.twoweap, had_wep = (uwep != 0);
156 
157     if (!wep) {
158         /* No weapon */
159         if (uwep) {
160             You("are empty %s.", body_part(HANDED));
161             setuwep((struct obj *) 0);
162             res++;
163         } else
164             You("are already empty %s.", body_part(HANDED));
165     } else if (wep->otyp == CORPSE && cant_wield_corpse(wep)
166                && !Hallucination) {
167         /* hero must have been life-saved to get here; use a turn */
168         res++; /* corpse won't be wielded */
169     } else if (uarms && bimanual(wep)) {
170         You("cannot wield a two-handed %s while wearing a shield.",
171             is_sword(wep) ? "sword" : wep->otyp == BATTLE_AXE ? "axe"
172                                                               : "weapon");
173     } else if (!retouch_object(&wep, FALSE, !will_touch_skin(W_WEP))) {
174         /* don't retouch and take material damage if it's a non-artifact object
175          * and you're wearing gloves */
176         res++; /* takes a turn even though it doesn't get wielded */
177     } else {
178         /* Weapon WILL be wielded after this point */
179         res++;
180         if (will_weld(wep)) {
181             const char *tmp = xname(wep), *thestr = "The ";
182 
183             if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
184                 tmp = thestr;
185             else
186                 tmp = "";
187             pline("%s%s %s to your %s!", tmp, aobjnam(wep, "weld"),
188                   (wep->quan == 1L) ? "itself" : "themselves", /* a3 */
189                   bimanual(wep) ? (const char *) makeplural(body_part(HAND))
190                                 : body_part(HAND));
191             set_bknown(wep, 1);
192         } else {
193             /* The message must be printed before setuwep (since
194              * you might die and be revived from changing weapons),
195              * and the message must be before the death message and
196              * Lifesaved rewielding.  Yet we want the message to
197              * say "weapon in hand", thus this kludge.
198              * [That comment is obsolete.  It dates from the days (3.0)
199              * when unwielding Firebrand could cause hero to be burned
200              * to death in Hell due to loss of fire resistance.
201              * "Lifesaved re-wielding or re-wearing" is ancient history.]
202              */
203             long dummy = wep->owornmask;
204 
205             wep->owornmask |= W_WEP;
206             if (wep->otyp == AKLYS && (wep->owornmask & W_WEP) != 0)
207                 You("secure the tether.");
208             prinv((char *) 0, wep, 0L);
209             wep->owornmask = dummy;
210         }
211 
212         setuwep(wep);
213         if (was_twoweap && !u.twoweap && flags.verbose) {
214             /* skip this message if we already got "empty handed" one above;
215                also, Null is not safe for neither TWOWEAPOK() or bimanual() */
216             if (uwep)
217                 You("%s.", ((TWOWEAPOK(uwep) && !bimanual(uwep))
218                             ? are_no_longer_twoweap
219                             : can_no_longer_twoweap));
220         }
221 
222         /* KMH -- Talking artifacts are finally implemented */
223         arti_speak(wep);
224 
225         if (artifact_light(wep) && !wep->lamplit) {
226             begin_burn(wep, FALSE);
227             if (!Blind)
228                 pline("%s to shine %s!", Tobjnam(wep, "begin"),
229                       arti_light_description(wep));
230         }
231 #if 0
232         /* we'll get back to this someday, but it's not balanced yet */
233         if (Race_if(PM_ELF) && !wep->oartifact
234             && wep->material == IRON) {
235             /* Elves are averse to wielding cold iron */
236             You("have an uneasy feeling about wielding cold iron.");
237             change_luck(-1);
238         }
239 #endif
240         if (wep->unpaid) {
241             struct monst *this_shkp;
242 
243             if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy)))
244                 != (struct monst *) 0) {
245                 pline("%s says \"You be careful with my %s!\"",
246                       shkname(this_shkp), xname(wep));
247             }
248         }
249     }
250     if ((had_wep != (uwep != 0)) && condtests[bl_bareh].enabled)
251         g.context.botl = 1;
252     return res;
253 }
254 
255 void
setuqwep(struct obj * obj)256 setuqwep(struct obj *obj)
257 {
258     setworn(obj, W_QUIVER);
259     /* no extra handling needed; this used to include a call to
260        update_inventory() but that's already performed by setworn() */
261     return;
262 }
263 
264 void
setuswapwep(struct obj * obj)265 setuswapwep(struct obj *obj)
266 {
267     setworn(obj, W_SWAPWEP);
268     return;
269 }
270 
271 /* getobj callback for object to ready for throwing/shooting */
272 static int
ready_ok(struct obj * obj)273 ready_ok(struct obj *obj)
274 {
275     if (!obj)
276         return GETOBJ_SUGGEST;
277 
278     /* exclude when wielded... */
279     if ((obj == uwep || (obj == uswapwep && u.twoweap))
280         && obj->quan == 1) /* ...unless more than one */
281         return GETOBJ_EXCLUDE_INACCESS;
282 
283     if (obj->oclass == WEAPON_CLASS || obj->oclass == COIN_CLASS)
284         return GETOBJ_SUGGEST;
285     /* Possible extension: exclude weapons that make no sense to throw, such as
286      * whips, bows, slings, rubber hoses. */
287 
288     /* Include gems/stones as likely candidates if either primary
289        or secondary weapon is a sling. */
290     if (obj->oclass == GEM_CLASS
291         && (uslinging()
292             || (uswapwep && objects[uswapwep->otyp].oc_skill == P_SLING)))
293         return GETOBJ_SUGGEST;
294 
295     return GETOBJ_DOWNPLAY;
296 }
297 
298 /* getobj callback for object to wield */
299 static int
wield_ok(struct obj * obj)300 wield_ok(struct obj *obj)
301 {
302     if (!obj)
303         return GETOBJ_SUGGEST;
304 
305     if (obj->oclass == COIN_CLASS)
306         return GETOBJ_EXCLUDE;
307 
308     if (obj->oclass == WEAPON_CLASS
309         || (obj->oclass == TOOL_CLASS && is_weptool(obj)))
310         return GETOBJ_SUGGEST;
311 
312     return GETOBJ_DOWNPLAY;
313 }
314 
315 int
dowield(void)316 dowield(void)
317 {
318     char qbuf[QBUFSZ];
319     struct obj *wep, *oldwep;
320     boolean finish_splitting = FALSE;
321     int result;
322 
323     /* May we attempt this? */
324     g.multi = 0;
325     if (cantwield(g.youmonst.data)) {
326         pline("Don't be ridiculous!");
327         return 0;
328     }
329 
330     /* Prompt for a new weapon */
331     clear_splitobjs();
332     if (!(wep = getobj("wield", wield_ok, GETOBJ_PROMPT | GETOBJ_ALLOWCNT))) {
333         /* Cancelled */
334         return 0;
335     } else if (wep == uwep) {
336  already_wielded:
337         You("are already wielding that!");
338         if (is_weptool(wep) || is_wet_towel(wep))
339             g.unweapon = FALSE; /* [see setuwep()] */
340         return 0;
341     } else if (welded(uwep)) {
342         weldmsg(uwep);
343         /* previously interrupted armor removal mustn't be resumed */
344         reset_remarm();
345         /* if player chose a partial stack but can't wield it, undo split */
346         if (wep->o_id && wep->o_id == g.context.objsplit.child_oid)
347             unsplitobj(wep);
348         return 0;
349     } else if (wep->o_id && wep->o_id == g.context.objsplit.child_oid) {
350         /* if wep is the result of supplying a count to getobj()
351            we don't want to split something already wielded; for
352            any other item, we need to give it its own inventory slot */
353         if (uwep && uwep->o_id == g.context.objsplit.parent_oid) {
354             unsplitobj(wep);
355             /* wep was merged back to uwep, already_wielded uses wep */
356             wep = uwep;
357             goto already_wielded;
358         }
359         finish_splitting = TRUE;
360         goto wielding;
361     }
362 
363     /* Handle no object, or object in other slot */
364     if (wep == &cg.zeroobj) {
365         wep = (struct obj *) 0;
366     } else if (wep == uswapwep) {
367         return doswapweapon();
368     } else if (wep == uquiver) {
369         /* offer to split stack if multiple are quivered */
370         if (uquiver->quan > 1L && inv_cnt(FALSE) < 52 && splittable(uquiver)) {
371             Sprintf(qbuf, "You have %ld %s readied.  Wield one?",
372                     uquiver->quan, simpleonames(uquiver));
373             switch (ynq(qbuf)) {
374             case 'q':
375                 return 0;
376             case 'y':
377                 /* leave N-1 quivered, split off 1 to wield */
378                 wep = splitobj(uquiver, 1L);
379                 finish_splitting = TRUE;
380                 goto wielding;
381             default:
382                 break;
383             }
384             Strcpy(qbuf, "Wield all of them instead?");
385         } else {
386             boolean use_plural = (is_plural(uquiver) || pair_of(uquiver));
387 
388             Sprintf(qbuf, "You have %s readied.  Wield %s instead?",
389                     !use_plural ? "that" : "those",
390                     !use_plural ? "it" : "them");
391         }
392         /* require confirmation to wield the quivered weapon */
393         if (ynq(qbuf) != 'y') {
394             (void) Shk_Your(qbuf, uquiver); /* replace qbuf[] contents */
395             pline("%s%s %s readied.", qbuf,
396                   simpleonames(uquiver), otense(uquiver, "remain"));
397             return 0;
398         }
399         /* wielding whole readied stack, so no longer quivered */
400         setuqwep((struct obj *) 0);
401     } else if (wep->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE)) {
402         You("cannot wield that!");
403         return 0;
404     }
405 
406  wielding:
407     if (finish_splitting) {
408         /* wep was split off from something; give it its own invlet */
409         freeinv(wep);
410         wep->nomerge = 1;
411         addinv(wep);
412         wep->nomerge = 0;
413     }
414 
415     /* Set your new primary weapon */
416     oldwep = uwep;
417     result = ready_weapon(wep);
418     if (flags.pushweapon && oldwep && uwep != oldwep)
419         setuswapwep(oldwep);
420     untwoweapon();
421 
422     return result;
423 }
424 
425 int
doswapweapon(void)426 doswapweapon(void)
427 {
428     register struct obj *oldwep, *oldswap;
429     int result = 0;
430 
431     /* May we attempt this? */
432     g.multi = 0;
433     if (cantwield(g.youmonst.data)) {
434         pline("Don't be ridiculous!");
435         return 0;
436     }
437     if (welded(uwep)) {
438         weldmsg(uwep);
439         return 0;
440     }
441 
442     /* Unwield your current secondary weapon */
443     oldwep = uwep;
444     oldswap = uswapwep;
445     setuswapwep((struct obj *) 0);
446 
447     /* Set your new primary weapon */
448     result = ready_weapon(oldswap);
449 
450     /* Set your new secondary weapon */
451     if (uwep == oldwep) {
452         /* Wield failed for some reason */
453         setuswapwep(oldswap);
454     } else {
455         setuswapwep(oldwep);
456         if (uswapwep)
457             prinv((char *) 0, uswapwep, 0L);
458         else
459             You("have no secondary weapon readied.");
460     }
461 
462     if (u.twoweap && !can_twoweapon())
463         untwoweapon();
464 
465     return result;
466 }
467 
468 int
dowieldquiver(void)469 dowieldquiver(void)
470 {
471     char qbuf[QBUFSZ];
472     struct obj *newquiver;
473     int res;
474     boolean finish_splitting = FALSE,
475             was_uwep = FALSE, was_twoweap = u.twoweap;
476 
477     /* Since the quiver isn't in your hands, don't check cantwield(), */
478     /* will_weld(), touch_petrifies(), etc. */
479     g.multi = 0;
480     /* forget last splitobj() before calling getobj() with GETOBJ_ALLOWCNT */
481     clear_splitobjs();
482 
483     /* Prompt for a new quiver: "What do you want to ready?" */
484     newquiver = getobj("ready", ready_ok, GETOBJ_PROMPT | GETOBJ_ALLOWCNT);
485 
486     if (!newquiver) {
487         /* Cancelled */
488         return 0;
489     } else if (newquiver == &cg.zeroobj) { /* no object */
490         /* Explicitly nothing */
491         if (uquiver) {
492             You("now have no ammunition readied.");
493             /* skip 'quivering: prinv()' */
494             setuqwep((struct obj *) 0);
495         } else {
496             You("already have no ammunition readied!");
497         }
498         return 0;
499     } else if (newquiver->o_id == g.context.objsplit.child_oid) {
500         /* if newquiver is the result of supplying a count to getobj()
501            we don't want to split something already in the quiver;
502            for any other item, we need to give it its own inventory slot */
503         if (uquiver && uquiver->o_id == g.context.objsplit.parent_oid) {
504             unsplitobj(newquiver);
505             goto already_quivered;
506         } else if (newquiver->oclass == COIN_CLASS) {
507             /* don't allow splitting a stack of coins into quiver */
508             You("can't ready only part of your gold.");
509             unsplitobj(newquiver);
510             return 0;
511         }
512         else if (newquiver->oclass == COIN_CLASS) {
513             /* don't allow splitting a stack of coins into quiver */
514             You("can't ready only part of your gold.");
515             unsplitobj(newquiver);
516             return 0;
517         }
518         finish_splitting = TRUE;
519     } else if (newquiver == uquiver) {
520  already_quivered:
521         pline("That ammunition is already readied!");
522         return 0;
523     } else if (newquiver->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE)) {
524         You("cannot ready that!");
525         return 0;
526     } else if (newquiver == uwep) {
527         int weld_res = !uwep->bknown;
528 
529         if (welded(uwep)) {
530             weldmsg(uwep);
531             reset_remarm(); /* same as dowield() */
532             return weld_res;
533         }
534         /* offer to split stack if wielding more than 1 */
535         if (uwep->quan > 1L && inv_cnt(FALSE) < 52 && splittable(uwep)) {
536             Sprintf(qbuf, "You are wielding %ld %s.  Ready %ld of them?",
537                     uwep->quan, simpleonames(uwep), uwep->quan - 1L);
538             switch (ynq(qbuf)) {
539             case 'q':
540                 return 0;
541             case 'y':
542                 /* leave 1 wielded, split rest off and put into quiver */
543                 newquiver = splitobj(uwep, uwep->quan - 1L);
544                 finish_splitting = TRUE;
545                 goto quivering;
546             default:
547                 break;
548             }
549             Strcpy(qbuf, "Ready all of them instead?");
550         } else {
551             boolean use_plural = (is_plural(uwep) || pair_of(uwep));
552 
553             Sprintf(qbuf, "You are wielding %s.  Ready %s instead?",
554                     !use_plural ? "that" : "those",
555                     !use_plural ? "it" : "them");
556         }
557         /* require confirmation to ready the main weapon */
558         if (ynq(qbuf) != 'y') {
559             (void) Shk_Your(qbuf, uwep); /* replace qbuf[] contents */
560             pline("%s%s %s wielded.", qbuf,
561                   simpleonames(uwep), otense(uwep, "remain"));
562             return 0;
563         }
564         /* quivering main weapon, so no longer wielding it */
565         setuwep((struct obj *) 0);
566         untwoweapon();
567         was_uwep = TRUE;
568     } else if (newquiver == uswapwep) {
569         if (uswapwep->quan > 1L && inv_cnt(FALSE) < 52
570             && splittable(uswapwep)) {
571             Sprintf(qbuf, "%s %ld %s.  Ready %ld of them?",
572                     u.twoweap ? "You are dual wielding"
573                               : "Your alternate weapon is",
574                     uswapwep->quan, simpleonames(uswapwep),
575                     uswapwep->quan - 1L);
576             switch (ynq(qbuf)) {
577             case 'q':
578                 return 0;
579             case 'y':
580                 /* leave 1 alt-wielded, split rest off and put into quiver */
581                 newquiver = splitobj(uswapwep, uswapwep->quan - 1L);
582                 finish_splitting = TRUE;
583                 goto quivering;
584             default:
585                 break;
586             }
587             Strcpy(qbuf, "Ready all of them instead?");
588         } else {
589             boolean use_plural = (is_plural(uswapwep) || pair_of(uswapwep));
590 
591             Sprintf(qbuf, "%s your %s weapon.  Ready %s instead?",
592                     !use_plural ? "That is" : "Those are",
593                     u.twoweap ? "second" : "alternate",
594                     !use_plural ? "it" : "them");
595         }
596         /* require confirmation to ready the alternate weapon */
597         if (ynq(qbuf) != 'y') {
598             (void) Shk_Your(qbuf, uswapwep); /* replace qbuf[] contents */
599             pline("%s%s %s %s.", qbuf,
600                   simpleonames(uswapwep), otense(uswapwep, "remain"),
601                   u.twoweap ? "wielded" : "as secondary weapon");
602             return 0;
603         }
604         /* quivering alternate weapon, so no more uswapwep */
605         setuswapwep((struct obj *) 0);
606         untwoweapon();
607     }
608 
609  quivering:
610     if (finish_splitting) {
611         freeinv(newquiver);
612         newquiver->nomerge = 1;
613         addinv(newquiver);
614         newquiver->nomerge = 0;
615     }
616     /* place item in quiver before printing so that inventory feedback
617        includes "(at the ready)" */
618     setuqwep(newquiver);
619     prinv((char *) 0, newquiver, 0L);
620 
621     /* quiver is a convenience slot and manipulating it ordinarily
622        consumes no time, but unwielding primary or secondary weapon
623        should take time (perhaps we're adjacent to a rust monster
624        or disenchanter and want to hit it immediately, but not with
625        something we're wielding that's vulnerable to its damage) */
626     res = 0;
627     if (was_uwep) {
628         You("are now empty %s.", body_part(HANDED));
629         res = 1;
630     } else if (was_twoweap && !u.twoweap) {
631         You("%s.", are_no_longer_twoweap);
632         res = 1;
633     }
634     return res;
635 }
636 
637 /* used for #rub and for applying pick-axe, whip, grappling hook or polearm */
638 boolean
wield_tool(struct obj * obj,const char * verb)639 wield_tool(struct obj *obj,
640            const char *verb) /* "rub",&c */
641 {
642     const char *what;
643     boolean more_than_1;
644 
645     if (obj == uwep)
646         return TRUE; /* nothing to do if already wielding it */
647 
648     if (!verb)
649         verb = "wield";
650     what = xname(obj);
651     more_than_1 = (obj->quan > 1L || strstri(what, "pair of ") != 0
652                    || strstri(what, "s of ") != 0);
653 
654     if (obj->owornmask & (W_ARMOR | W_ACCESSORY)) {
655         You_cant("%s %s while wearing %s.", verb, yname(obj),
656                  more_than_1 ? "them" : "it");
657         return FALSE;
658     }
659     if (welded(uwep)) {
660         if (flags.verbose) {
661             const char *hand = body_part(HAND);
662 
663             if (bimanual(uwep))
664                 hand = makeplural(hand);
665             if (strstri(what, "pair of ") != 0)
666                 more_than_1 = FALSE;
667             pline(
668                "Since your weapon is welded to your %s, you cannot %s %s %s.",
669                   hand, verb, more_than_1 ? "those" : "that", xname(obj));
670         } else {
671             You_cant("do that.");
672         }
673         return FALSE;
674     }
675     if (cantwield(g.youmonst.data)) {
676         You_cant("hold %s strongly enough.", more_than_1 ? "them" : "it");
677         return FALSE;
678     }
679     /* check shield */
680     if (uarms && bimanual(obj)) {
681         You("cannot %s a two-handed %s while wearing a shield.", verb,
682             (obj->oclass == WEAPON_CLASS) ? "weapon" : "tool");
683         return FALSE;
684     }
685 
686     if (uquiver == obj)
687         setuqwep((struct obj *) 0);
688     if (uswapwep == obj) {
689         (void) doswapweapon();
690         /* doswapweapon might fail */
691         if (uswapwep == obj)
692             return FALSE;
693     } else {
694         struct obj *oldwep = uwep;
695 
696         if (will_weld(obj)) {
697             /* hope none of ready_weapon()'s early returns apply here... */
698             (void) ready_weapon(obj);
699         } else {
700             You("now wield %s.", doname(obj));
701             setuwep(obj);
702         }
703         if (flags.pushweapon && oldwep && uwep != oldwep)
704             setuswapwep(oldwep);
705     }
706     if (uwep != obj)
707         return FALSE; /* rewielded old object after dying */
708     /* applying weapon or tool that gets wielded ends two-weapon combat */
709     if (u.twoweap)
710         untwoweapon();
711     if (obj->oclass != WEAPON_CLASS)
712         g.unweapon = TRUE;
713     return TRUE;
714 }
715 
716 int
can_twoweapon(void)717 can_twoweapon(void)
718 {
719     struct obj *otmp;
720 
721     if (!could_twoweap(g.youmonst.data)) {
722         if (Upolyd)
723             You_cant("use two weapons in your current form.");
724         else
725             pline("%s aren't able to use two weapons at once.",
726                   makeplural((flags.female && g.urole.name.f)
727                              ? g.urole.name.f : g.urole.name.m));
728     } else if (!uwep || !uswapwep) {
729         const char *hand_s = body_part(HAND);
730 
731         if (!uwep && !uswapwep)
732             hand_s = makeplural(hand_s);
733         /* "your hands are empty" or "your {left|right} hand is empty" */
734         Your("%s%s %s empty.", uwep ? "left " : uswapwep ? "right " : "",
735              hand_s, vtense(hand_s, "are"));
736     } else if (!TWOWEAPOK(uwep) || !TWOWEAPOK(uswapwep)) {
737         otmp = !TWOWEAPOK(uwep) ? uwep : uswapwep;
738         pline("%s %s suitable %s weapon%s.", Yname2(otmp),
739               is_plural(otmp) ? "aren't" : "isn't a",
740               (otmp == uwep) ? "primary" : "secondary",
741               plur(otmp->quan));
742     } else if (bimanual(uwep) || bimanual(uswapwep)) {
743         otmp = bimanual(uwep) ? uwep : uswapwep;
744         pline("%s isn't one-handed.", Yname2(otmp));
745     } else if (uarms) {
746         You_cant("use two weapons while wearing a shield.");
747     } else if (uswapwep->oartifact
748             /* From NetHack Fourk: allow only Fire Brand and Frost Brand to be
749              * dual-wielded. */
750              && !(uswapwep->oartifact == ART_FIRE_BRAND
751                   && uwep->oartifact == ART_FROST_BRAND)
752              && !(uswapwep->oartifact == ART_FROST_BRAND
753                   && uwep->oartifact == ART_FIRE_BRAND)) {
754         pline("%s being held second to another weapon!",
755               Yobjnam2(uswapwep, "resist"));
756     } else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) {
757         /* [Note: !TWOWEAPOK() check prevents ever getting here...] */
758         ; /* must be life-saved to reach here; return FALSE */
759     } else if (Glib || uswapwep->cursed) {
760         if (!Glib)
761             set_bknown(uswapwep, 1);
762         drop_uswapwep();
763     } else
764         return TRUE;
765     return FALSE;
766 }
767 
768 void
drop_uswapwep(void)769 drop_uswapwep(void)
770 {
771     char str[BUFSZ];
772     struct obj *obj = uswapwep;
773 
774     /* Avoid trashing makeplural's static buffer */
775     Strcpy(str, makeplural(body_part(HAND)));
776     pline("%s from your %s!", Yobjnam2(obj, "slip"), str);
777     dropx(obj);
778 }
779 
780 void
set_twoweap(boolean on_off)781 set_twoweap(boolean on_off)
782 {
783     u.twoweap = on_off;
784 }
785 
786 int
dotwoweapon(void)787 dotwoweapon(void)
788 {
789     /* You can always toggle it off */
790     if (u.twoweap) {
791         You("switch to your primary weapon.");
792         set_twoweap(FALSE); /* u.twoweap = FALSE */
793         update_inventory();
794         return 0;
795     }
796 
797     /* May we use two weapons? */
798     if (can_twoweapon()) {
799         /* Success! */
800         You("begin two-weapon combat.");
801         set_twoweap(TRUE); /* u.twoweap = TRUE */
802         update_inventory();
803         return (rnd(20) > ACURR(A_DEX));
804     }
805     return 0;
806 }
807 
808 /*** Functions to empty a given slot ***/
809 /* These should be used only when the item can't be put back in
810  * the slot by life saving.  Proper usage includes:
811  * 1.  The item has been eaten, stolen, burned away, or rotted away.
812  * 2.  Making an item disappear for a bones pile.
813  */
814 void
uwepgone(void)815 uwepgone(void)
816 {
817     if (uwep) {
818         if (artifact_light(uwep) && uwep->lamplit) {
819             end_burn(uwep, FALSE);
820             if (!Blind)
821                 pline("%s shining.", Tobjnam(uwep, "stop"));
822         }
823         setworn((struct obj *) 0, W_WEP);
824         g.unweapon = TRUE;
825         update_inventory();
826     }
827 }
828 
829 void
uswapwepgone(void)830 uswapwepgone(void)
831 {
832     if (uswapwep) {
833         setworn((struct obj *) 0, W_SWAPWEP);
834         update_inventory();
835     }
836 }
837 
838 void
uqwepgone(void)839 uqwepgone(void)
840 {
841     if (uquiver) {
842         setworn((struct obj *) 0, W_QUIVER);
843         update_inventory();
844     }
845 }
846 
847 void
untwoweapon(void)848 untwoweapon(void)
849 {
850     if (u.twoweap) {
851         You("%s.", can_no_longer_twoweap);
852         set_twoweap(FALSE); /* u.twoweap = FALSE */
853         update_inventory();
854     }
855     return;
856 }
857 
858 int
chwepon(struct obj * otmp,int amount)859 chwepon(struct obj *otmp, int amount)
860 {
861     const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE);
862     const char *xtime, *wepname = "";
863     boolean multiple;
864     int otyp = STRANGE_OBJECT;
865 
866     if (!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep)
867                   && uwep->oclass != TOOL_CLASS
868                   && !(uwep->oclass == RING_CLASS
869                        && objects[uwep->otyp].oc_charged))) {
870         char buf[BUFSZ];
871 
872         if (amount >= 0 && uwep && will_weld(uwep)) { /* cursed tin opener */
873             if (!Blind) {
874                 Sprintf(buf, "%s with %s aura.",
875                         Yobjnam2(uwep, "glow"), an(hcolor(NH_AMBER)));
876                 uwep->bknown = !Hallucination; /* ok to bypass set_bknown() */
877             } else {
878                 /* cursed tin opener is wielded in right hand */
879                 Sprintf(buf, "Your right %s tingles.", body_part(HAND));
880             }
881             uncurse(uwep);
882             update_inventory();
883         } else {
884             Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),
885                     (amount >= 0) ? "twitch" : "itch");
886         }
887         strange_feeling(otmp, buf); /* pline()+docall()+useup() */
888         exercise(A_DEX, (boolean) (amount >= 0));
889         return 0;
890     }
891 
892     if (otmp && otmp->oclass == SCROLL_CLASS)
893         otyp = otmp->otyp;
894 
895     if (uwep->otyp == WORM_TOOTH && amount >= 0) {
896         multiple = (uwep->quan > 1L);
897         /* order: message, transformation, shop handling */
898         Your("%s %s much sharper now.", simpleonames(uwep),
899              multiple ? "fuse, and become" : "is");
900         uwep->otyp = CRYSKNIFE;
901         uwep->oerodeproof = 0;
902         set_material(uwep, objects[CRYSKNIFE].oc_material);
903         if (multiple) {
904             uwep->quan = 1L;
905             uwep->owt = weight(uwep);
906         }
907         if (uwep->cursed)
908             uncurse(uwep);
909         /* update shop bill to reflect new higher value */
910         if (uwep->unpaid)
911             alter_cost(uwep, 0L);
912         if (otyp != STRANGE_OBJECT)
913             makeknown(otyp);
914         if (multiple)
915             encumber_msg();
916         return 1;
917     } else if (uwep->otyp == CRYSKNIFE && amount < 0) {
918         multiple = (uwep->quan > 1L);
919         /* order matters: message, shop handling, transformation */
920         Your("%s %s much duller now.", simpleonames(uwep),
921              multiple ? "fuse, and become" : "is");
922         costly_alteration(uwep, COST_DEGRD); /* DECHNT? other? */
923         uwep->otyp = WORM_TOOTH;
924         uwep->oerodeproof = 0;
925         set_material(uwep, objects[WORM_TOOTH].oc_material);
926         if (multiple) {
927             uwep->quan = 1L;
928             uwep->owt = weight(uwep);
929         }
930         if (otyp != STRANGE_OBJECT && otmp->bknown)
931             makeknown(otyp);
932         if (multiple)
933             encumber_msg();
934         return 1;
935     }
936 
937     if (uwep->oclass == RING_CLASS) {
938         /* charge the ring; this shouldn't print "feeling of loss" message for
939          * failing to charge because we've ruled out non-chargeable rings above
940          */
941         recharge(uwep, bcsign(otmp));
942         return 1;
943     }
944     else if (uwep->oclass == TOOL_CLASS && !is_weptool(uwep) && !otmp->cursed) {
945         /* enchant a non-magical tool into a magical counterpart; not all tools
946          * have such a counterpart, however */
947         short old_otyp = uwep->otyp;
948         char *old_yname = Yname2(uwep);
949         if (uwep->otyp == HARP) {
950             /* may not get any charges; blessed guarantees at least 1 charge */
951             uwep->otyp = MAGIC_HARP;
952             uwep->recharged = 0;
953             uwep->spe = rn2(2) + (otmp->blessed ? 1 : 0);
954         }
955         else if (uwep->otyp == TOOLED_HORN && rn2(3)) {
956             /* can't become a horn of plenty; it only turns into "instrumental"
957              * type horns */
958             uwep->otyp = rnd_class(FROST_HORN, FIRE_HORN);
959             uwep->recharged = 0;
960             uwep->spe = rn2(2) + (otmp->blessed ? 1 : 0);
961         }
962         else if (uwep->otyp == FLUTE) {
963             uwep->otyp = MAGIC_FLUTE;
964             uwep->recharged = 0;
965             uwep->spe = rn2(1) + (otmp->blessed ? 1 : 0);
966         }
967         else if (uwep->otyp == PEA_WHISTLE && !rn2(3)) {
968             uwep->otyp = MAGIC_WHISTLE;
969         }
970         else if (uwep->otyp == SACK && !rn2(6)) {
971             uwep->otyp = rnd_class(BAG_OF_HOLDING, BAG_OF_TRICKS);
972             if (uwep->otyp == BAG_OF_TRICKS) {
973                 uwep->recharged = 0;
974                 uwep->spe = rn2(2) + (otmp->blessed ? 1 : 0);
975             }
976         }
977         else if (uwep->otyp == LEATHER_DRUM) {
978             uwep->otyp = DRUM_OF_EARTHQUAKE;
979             uwep->recharged = 0;
980             uwep->spe = rn2(2) + (otmp->blessed ? 1 : 0);
981         }
982 
983         if (uwep->otyp != old_otyp) {
984             if (!valid_obj_material(uwep, uwep->material)) {
985                 impossible("tool enchanted into incompatible material");
986                 uwep->material = objects[uwep->otyp].oc_material;
987             }
988             pline("%s glitters and warps in your %s!", old_yname,
989                   body_part(HAND));
990             uwep->owt = weight(uwep);
991             makeknown(otyp);
992             return 1;
993         }
994         else { /* failed to enchant, or non-enchantable tool */
995             strange_feeling(otmp, "Nothing seems to happen.");
996                 /* pline()+docall()+useup() */
997             return 0;
998         }
999     }
1000 
1001     if (has_oname(uwep))
1002         wepname = ONAME(uwep);
1003     if (amount < 0 && uwep->oartifact && restrict_name(uwep, wepname)) {
1004         if (!Blind)
1005             pline("%s %s.", Yobjnam2(uwep, "faintly glow"), color);
1006         return 1;
1007     }
1008     /* there is a (soft) upper and lower limit to uwep->spe */
1009     if (((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
1010         && rn2(3)) {
1011         if (!Blind)
1012             pline("%s %s for a while and then %s.",
1013                   Yobjnam2(uwep, "violently glow"), color,
1014                   otense(uwep, "evaporate"));
1015         else
1016             pline("%s.", Yobjnam2(uwep, "evaporate"));
1017 
1018         useupall(uwep); /* let all of them disappear */
1019         return 1;
1020     }
1021     if (!Blind) {
1022         xtime = (amount * amount == 1) ? "moment" : "while";
1023         pline("%s %s for a %s.",
1024               Yobjnam2(uwep, amount == 0 ? "violently glow" : "glow"), color,
1025               xtime);
1026         if (otyp != STRANGE_OBJECT && uwep->known
1027             && (amount > 0 || (amount < 0 && otmp->bknown)))
1028             makeknown(otyp);
1029     }
1030     if (amount < 0)
1031         costly_alteration(uwep, COST_DECHNT);
1032     uwep->spe += amount;
1033     if (amount > 0) {
1034         if (uwep->cursed)
1035             uncurse(uwep);
1036         /* update shop bill to reflect new higher price */
1037         if (uwep->unpaid)
1038             alter_cost(uwep, 0L);
1039     }
1040 
1041     /*
1042      * Enchantment, which normally improves a weapon, has an
1043      * addition adverse reaction on Magicbane whose effects are
1044      * spe dependent.  Give an obscure clue here.
1045      */
1046     if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) {
1047         Your("right %s %sches!", body_part(HAND),
1048              (((amount > 1) && (uwep->spe > 1)) ? "flin" : "it"));
1049     }
1050 
1051     /* an elven magic clue, cookie@keebler */
1052     /* elven weapons vibrate warningly when enchanted beyond a limit */
1053     if ((uwep->spe > 5)
1054         && (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
1055         pline("%s unexpectedly.", Yobjnam2(uwep, "suddenly vibrate"));
1056 
1057     return 1;
1058 }
1059 
1060 int
welded(struct obj * obj)1061 welded(struct obj *obj)
1062 {
1063     if (obj && obj == uwep && will_weld(obj)) {
1064         set_bknown(obj, 1);
1065         return 1;
1066     }
1067     return 0;
1068 }
1069 
1070 void
weldmsg(struct obj * obj)1071 weldmsg(struct obj *obj)
1072 {
1073     long savewornmask;
1074 
1075     savewornmask = obj->owornmask;
1076     pline("%s welded to your %s!", Yobjnam2(obj, "are"),
1077           bimanual(obj) ? (const char *) makeplural(body_part(HAND))
1078                         : body_part(HAND));
1079     obj->owornmask = savewornmask;
1080 }
1081 
1082 /* test whether monster's wielded weapon is stuck to hand/paw/whatever */
1083 boolean
mwelded(struct obj * obj)1084 mwelded(struct obj *obj)
1085 {
1086     /* caller is responsible for making sure this is a monster's item */
1087     if (obj && (obj->owornmask & W_WEP) && will_weld(obj))
1088         return TRUE;
1089     return FALSE;
1090 }
1091 
1092 /*wield.c*/
1093