make rank() static again
[NetHack.git] / src / wield.c
blob9aaea38fccca0af33ab80af090bc7ce8ac3eda2b
1 /* NetHack 3.7 wield.c $NHDT-Date: 1707525193 2024/02/10 00:33:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */
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. */
6 #include "hack.h"
8 /* KMH -- Differences between the three weapon slots.
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.
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.
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.
52 * No item may be in more than one of these slots.
55 staticfn boolean cant_wield_corpse(struct obj *) NONNULLARG1;
56 staticfn int ready_weapon(struct obj *) NO_NNARGS;
57 staticfn int ready_ok(struct obj *) NO_NNARGS;
58 staticfn int wield_ok(struct obj *) NO_NNARGS;
59 staticfn void finish_splitting(struct obj *);
61 /* used by will_weld() */
62 /* probably should be renamed */
63 #define erodeable_wep(optr) \
64 ((optr)->oclass == WEAPON_CLASS || is_weptool(optr) \
65 || (optr)->otyp == HEAVY_IRON_BALL || (optr)->otyp == IRON_CHAIN)
67 /* used by welded(), and also while wielding */
68 #define will_weld(optr) \
69 ((optr)->cursed && (erodeable_wep(optr) || (optr)->otyp == TIN_OPENER))
71 /* to dual-wield, 'obj' must be a weapon or a weapon-tool, and not a bow
72 or arrow or missile (dart, shuriken, boomerang), so not matching the
73 one-handed weapons which yield "you begin bashing" if used for melee;
74 empty hands and two-handed weapons have to be handled separately */
75 #define TWOWEAPOK(obj) \
76 (((obj)->oclass == WEAPON_CLASS) \
77 ? !(is_launcher(obj) || is_ammo(obj) || is_missile(obj)) \
78 : is_weptool(obj))
80 static const char
81 are_no_longer_twoweap[] = "are no longer using two weapons at once",
82 can_no_longer_twoweap[] = "can no longer wield two weapons at once";
84 /*** Functions that place a given item in a slot ***/
85 /* Proper usage includes:
86 * 1. Initializing the slot during character generation or a
87 * restore.
88 * 2. Setting the slot due to a player's actions.
89 * 3. If one of the objects in the slot are split off, these
90 * functions can be used to put the remainder back in the slot.
91 * 4. Putting an item that was thrown and returned back into the slot.
92 * 5. Emptying the slot, by passing a null object. NEVER pass
93 * cg.zeroobj!
95 * If the item is being moved from another slot, it is the caller's
96 * responsibility to handle that. It's also the caller's responsibility
97 * to print the appropriate messages.
99 void
100 setuwep(struct obj *obj)
102 struct obj *olduwep = uwep;
104 if (obj == uwep)
105 return; /* necessary to not set gu.unweapon */
106 /* This message isn't printed in the caller because it happens
107 * *whenever* Sunsword is unwielded, from whatever cause.
109 setworn(obj, W_WEP);
110 if (uwep == obj && artifact_light(olduwep) && olduwep->lamplit) {
111 end_burn(olduwep, FALSE);
112 if (!Blind)
113 pline("%s shining.", Tobjnam(olduwep, "stop"));
115 if (uwep == obj
116 && (u_wield_art(ART_OGRESMASHER)
117 || is_art(olduwep, ART_OGRESMASHER)))
118 disp.botl = TRUE;
119 /* Note: Explicitly wielding a pick-axe will not give a "bashing"
120 * message. Wielding one via 'a'pplying it will.
121 * 3.2.2: Wielding arbitrary objects will give bashing message too.
123 if (obj) {
124 gu.unweapon = (obj->oclass == WEAPON_CLASS)
125 ? is_launcher(obj) || is_ammo(obj) || is_missile(obj)
126 || (is_pole(obj) && !u.usteed)
127 : !is_weptool(obj) && !is_wet_towel(obj);
128 } else
129 gu.unweapon = TRUE; /* for "bare hands" message */
132 staticfn boolean
133 cant_wield_corpse(struct obj *obj)
135 char kbuf[BUFSZ];
137 if (uarmg || obj->otyp != CORPSE || !touch_petrifies(&mons[obj->corpsenm])
138 || Stone_resistance)
139 return FALSE;
141 /* Prevent wielding cockatrice when not wearing gloves --KAA */
142 You("wield %s in your bare %s.",
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;
150 /* description of hands when not wielding anything; also used
151 by #seeweapon (')'), #attributes (^X), and #takeoffall ('A') */
152 const char *
153 empty_handed(void)
155 return uarmg ? "empty handed" /* gloves imply hands */
156 : humanoid(gy.youmonst.data)
157 /* hands but no weapon and no gloves */
158 ? "bare handed"
159 /* alternate phrasing for paws or lack of hands */
160 : "not wielding anything";
163 staticfn int
164 ready_weapon(struct obj *wep)
166 /* Separated function so swapping works easily */
167 int res = ECMD_OK;
168 boolean was_twoweap = u.twoweap, had_wep = (uwep != 0);
170 if (!wep) {
171 /* No weapon */
172 if (uwep) {
173 You("are %s.", empty_handed());
174 setuwep((struct obj *) 0);
175 res = ECMD_TIME;
176 } else
177 You("are already %s.", empty_handed());
178 } else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) {
179 /* hero must have been life-saved to get here; use a turn */
180 res = ECMD_TIME; /* corpse won't be wielded */
181 } else if (uarms && bimanual(wep)) {
182 You("cannot wield a two-handed %s while wearing a shield.",
183 is_sword(wep) ? "sword" : wep->otyp == BATTLE_AXE ? "axe"
184 : "weapon");
185 res = ECMD_FAIL;
186 } else if (!retouch_object(&wep, FALSE)) {
187 res = ECMD_TIME; /* takes a turn even though it doesn't get wielded */
188 } else {
189 /* Weapon WILL be wielded after this point */
190 res = ECMD_TIME;
191 if (will_weld(wep)) {
192 const char *tmp = xname(wep), *thestr = "The ";
194 if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
195 tmp = thestr;
196 else
197 tmp = "";
198 pline("%s%s %s to your %s%s!", tmp, aobjnam(wep, "weld"),
199 (wep->quan == 1L) ? "itself" : "themselves", /* a3 */
200 bimanual(wep) ? "" :
201 (URIGHTY ? "dominant right " : "dominant left "),
202 bimanual(wep) ? (const char *) makeplural(body_part(HAND))
203 : body_part(HAND));
204 set_bknown(wep, 1);
205 } else {
206 /* The message must be printed before setuwep (since
207 * you might die and be revived from changing weapons),
208 * and the message must be before the death message and
209 * Lifesaved rewielding. Yet we want the message to
210 * say "weapon in hand", thus this kludge.
211 * [That comment is obsolete. It dates from the days (3.0)
212 * when unwielding Firebrand could cause hero to be burned
213 * to death in Hell due to loss of fire resistance.
214 * "Lifesaved re-wielding or re-wearing" is ancient history.]
216 long dummy = wep->owornmask;
218 wep->owornmask |= W_WEP;
219 if (wep->otyp == AKLYS && (wep->owornmask & W_WEP) != 0)
220 You("secure the tether.");
221 prinv((char *) 0, wep, 0L);
222 wep->owornmask = dummy;
225 setuwep(wep);
226 if (was_twoweap && !u.twoweap && flags.verbose) {
227 /* skip this message if we already got "empty handed" one above;
228 also, Null is not safe for neither TWOWEAPOK() or bimanual() */
229 if (uwep)
230 You("%s.", ((TWOWEAPOK(uwep) && !bimanual(uwep))
231 ? are_no_longer_twoweap
232 : can_no_longer_twoweap));
235 /* KMH -- Talking artifacts are finally implemented */
236 if (wep->oartifact) {
237 res |= arti_speak(wep); /* sets ECMD_TIME bit if artifact speaks */
240 if (artifact_light(wep) && !wep->lamplit) {
241 begin_burn(wep, FALSE);
242 if (!Blind)
243 pline("%s to shine %s!", Tobjnam(wep, "begin"),
244 arti_light_description(wep));
246 #if 0
247 /* we'll get back to this someday, but it's not balanced yet */
248 if (Race_if(PM_ELF) && !wep->oartifact
249 && objects[wep->otyp].oc_material == IRON) {
250 /* Elves are averse to wielding cold iron */
251 You("have an uneasy feeling about wielding cold iron.");
252 change_luck(-1);
254 #endif
255 if (wep->unpaid) {
256 struct monst *this_shkp;
258 if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy)))
259 != (struct monst *) 0) {
260 pline("%s says \"You be careful with my %s!\"",
261 shkname(this_shkp), xname(wep));
265 if ((had_wep != (uwep != 0)) && condtests[bl_bareh].enabled)
266 disp.botl = TRUE;
267 return res;
270 void
271 setuqwep(struct obj *obj)
273 setworn(obj, W_QUIVER);
274 /* no extra handling needed; this used to include a call to
275 update_inventory() but that's already performed by setworn() */
276 return;
279 void
280 setuswapwep(struct obj *obj)
282 setworn(obj, W_SWAPWEP);
283 return;
286 /* getobj callback for object to ready for throwing/shooting;
287 this filter lets worn items through so that caller can reject them */
288 staticfn int
289 ready_ok(struct obj *obj)
291 if (!obj) /* '-', will empty quiver slot if chosen */
292 return uquiver ? GETOBJ_SUGGEST : GETOBJ_DOWNPLAY;
294 /* downplay when wielded, unless more than one */
295 if (obj == uwep || (obj == uswapwep && u.twoweap))
296 return (obj->quan == 1) ? GETOBJ_DOWNPLAY : GETOBJ_SUGGEST;
298 if (is_ammo(obj)) {
299 return ((uwep && ammo_and_launcher(obj, uwep))
300 || (uswapwep && ammo_and_launcher(obj, uswapwep)))
301 ? GETOBJ_SUGGEST
302 : GETOBJ_DOWNPLAY;
303 } else if (is_launcher(obj)) { /* part of 'possible extension' below */
304 return GETOBJ_DOWNPLAY;
305 } else {
306 if (obj->oclass == WEAPON_CLASS || obj->oclass == COIN_CLASS)
307 return GETOBJ_SUGGEST;
308 /* Possible extension: exclude weapons that make no sense to throw,
309 such as whips, bows, slings, rubber hoses. */
312 #if 0 /* superseded by ammo_and_launcher handling above */
313 /* Include gems/stones as likely candidates if either primary
314 or secondary weapon is a sling. */
315 if (obj->oclass == GEM_CLASS
316 && (uslinging()
317 || (uswapwep && objects[uswapwep->otyp].oc_skill == P_SLING)))
318 return GETOBJ_SUGGEST;
319 #endif
321 return GETOBJ_DOWNPLAY;
324 /* getobj callback for object to wield */
325 staticfn int
326 wield_ok(struct obj *obj)
328 if (!obj)
329 return GETOBJ_SUGGEST;
331 if (obj->oclass == COIN_CLASS)
332 return GETOBJ_EXCLUDE;
334 if (obj->oclass == WEAPON_CLASS || is_weptool(obj))
335 return GETOBJ_SUGGEST;
337 return GETOBJ_DOWNPLAY;
340 staticfn void
341 finish_splitting(struct obj *obj)
343 /* obj was split off from something; give it its own invlet */
344 freeinv(obj);
345 addinv_nomerge(obj);
348 /* the #wield command - wield a weapon */
350 dowield(void)
352 char qbuf[QBUFSZ];
353 struct obj *wep, *oldwep;
354 int result;
356 /* May we attempt this? */
357 gm.multi = 0;
358 if (cantwield(gy.youmonst.data)) {
359 pline("Don't be ridiculous!");
360 return ECMD_FAIL;
362 /* Keep going even if inventory is completely empty, since wielding '-'
363 to wield nothing can be construed as a positive act even when done
364 so redundantly. */
366 /* Prompt for a new weapon */
367 clear_splitobjs();
368 if (!(wep = getobj("wield", wield_ok, GETOBJ_PROMPT | GETOBJ_ALLOWCNT))) {
369 /* Cancelled */
370 return ECMD_CANCEL;
371 } else if (wep == uwep) {
372 already_wielded:
373 You("are already wielding that!");
374 if (is_weptool(wep) || is_wet_towel(wep))
375 gu.unweapon = FALSE; /* [see setuwep()] */
376 return ECMD_FAIL;
377 } else if (welded(uwep)) {
378 weldmsg(uwep);
379 /* previously interrupted armor removal mustn't be resumed */
380 reset_remarm();
381 /* if player chose a partial stack but can't wield it, undo split */
382 if (wep->o_id && wep->o_id == svc.context.objsplit.child_oid)
383 unsplitobj(wep);
384 return ECMD_FAIL;
385 } else if (wep->o_id && wep->o_id == svc.context.objsplit.child_oid) {
386 /* if wep is the result of supplying a count to getobj()
387 we don't want to split something already wielded; for
388 any other item, we need to give it its own inventory slot */
389 if (uwep && uwep->o_id == svc.context.objsplit.parent_oid) {
390 unsplitobj(wep);
391 /* wep was merged back to uwep, already_wielded uses wep */
392 wep = uwep;
393 goto already_wielded;
395 finish_splitting(wep);
396 goto wielding;
399 /* Handle no object, or object in other slot */
400 if (wep == &hands_obj) {
401 wep = (struct obj *) 0;
402 } else if (wep == uswapwep) {
403 return doswapweapon();
404 } else if (wep == uquiver) {
405 /* offer to split stack if multiple are quivered */
406 if (uquiver->quan > 1L && inv_cnt(FALSE) < invlet_basic
407 && splittable(uquiver)) {
408 Sprintf(qbuf, "You have %ld %s readied. Wield one?",
409 uquiver->quan, simpleonames(uquiver));
410 switch (ynq(qbuf)) {
411 case 'q':
412 return ECMD_OK;
413 case 'y':
414 /* leave N-1 quivered, split off 1 to wield */
415 wep = splitobj(uquiver, 1L);
416 finish_splitting(wep);
417 goto wielding;
418 default:
419 break;
421 Strcpy(qbuf, "Wield all of them instead?");
422 } else {
423 boolean use_plural = (is_plural(uquiver) || pair_of(uquiver));
425 Sprintf(qbuf, "You have %s readied. Wield %s instead?",
426 !use_plural ? "that" : "those",
427 !use_plural ? "it" : "them");
429 /* require confirmation to wield the quivered weapon */
430 if (ynq(qbuf) != 'y') {
431 (void) Shk_Your(qbuf, uquiver); /* replace qbuf[] contents */
432 pline("%s%s %s readied.", qbuf,
433 simpleonames(uquiver), otense(uquiver, "remain"));
434 return ECMD_OK;
436 /* wielding whole readied stack, so no longer quivered */
437 setuqwep((struct obj *) 0);
438 } else if (wep->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE)) {
439 You("cannot wield that!");
440 return ECMD_FAIL;
443 wielding:
444 /* Set your new primary weapon */
445 oldwep = uwep;
446 result = ready_weapon(wep);
447 if (flags.pushweapon && oldwep && uwep != oldwep)
448 setuswapwep(oldwep);
449 untwoweapon();
451 return result;
454 /* the #swap command - swap wielded and secondary weapons */
456 doswapweapon(void)
458 struct obj *oldwep, *oldswap;
459 int result = 0;
461 /* May we attempt this? */
462 gm.multi = 0;
463 if (cantwield(gy.youmonst.data)) {
464 pline("Don't be ridiculous!");
465 return ECMD_FAIL;
467 if (welded(uwep)) {
468 weldmsg(uwep);
469 return ECMD_FAIL;
472 /* Unwield your current secondary weapon */
473 oldwep = uwep;
474 oldswap = uswapwep;
475 setuswapwep((struct obj *) 0);
477 /* Set your new primary weapon */
478 result = ready_weapon(oldswap);
480 /* Set your new secondary weapon */
481 if (uwep == oldwep) {
482 /* Wield failed for some reason */
483 setuswapwep(oldswap);
484 } else {
485 setuswapwep(oldwep);
486 if (uswapwep)
487 prinv((char *) 0, uswapwep, 0L);
488 else
489 You("have no secondary weapon readied.");
492 if (u.twoweap && !can_twoweapon())
493 untwoweapon();
495 return result;
498 /* the #quiver command */
500 dowieldquiver(void)
502 return doquiver_core("ready");
505 /* guts of #quiver command; also used by #fire when refilling empty quiver */
507 doquiver_core(const char *verb) /* "ready" or "fire" */
509 char qbuf[QBUFSZ];
510 struct obj *newquiver;
511 int res;
512 boolean was_uwep = FALSE, was_twoweap = u.twoweap;
514 /* Since the quiver isn't in your hands, don't check cantwield(),
515 will_weld(), touch_petrifies(), etc. */
516 gm.multi = 0;
517 if (!gi.invent) {
518 /* could accept '-' to empty quiver, but there's no point since
519 inventory is empty so uquiver is already Null */
520 You("have nothing to ready for firing.");
521 return ECMD_OK;
524 /* forget last splitobj() before calling getobj() with GETOBJ_ALLOWCNT */
525 clear_splitobjs();
526 /* Prompt for a new quiver: "What do you want to {ready|fire}?" */
527 newquiver = getobj(verb, ready_ok, GETOBJ_PROMPT | GETOBJ_ALLOWCNT);
529 if (!newquiver) {
530 /* Cancelled */
531 return ECMD_CANCEL;
532 } else if (newquiver == &hands_obj) { /* no object */
533 /* Explicitly nothing */
534 if (uquiver) {
535 You("now have no ammunition readied.");
536 /* skip 'quivering: prinv()' */
537 setuqwep((struct obj *) 0);
538 } else {
539 You("already have no ammunition readied!");
541 return ECMD_OK;
542 } else if (newquiver->o_id == svc.context.objsplit.child_oid) {
543 /* if newquiver is the result of supplying a count to getobj()
544 we don't want to split something already in the quiver;
545 for any other item, we need to give it its own inventory slot */
546 if (uquiver && uquiver->o_id == svc.context.objsplit.parent_oid) {
547 unsplitobj(newquiver);
548 goto already_quivered;
549 } else if (newquiver->oclass == COIN_CLASS) {
550 /* don't allow splitting a stack of coins into quiver */
551 You("can't ready only part of your gold.");
552 unsplitobj(newquiver);
553 return ECMD_OK;
555 finish_splitting(newquiver);
556 } else if (newquiver == uquiver) {
557 already_quivered:
558 pline("That ammunition is already readied!");
559 return ECMD_OK;
560 } else if (newquiver->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE)) {
561 You("cannot %s that!", verb);
562 return ECMD_OK;
563 } else if (newquiver == uwep) {
564 int weld_res = !uwep->bknown;
566 if (welded(uwep)) {
567 weldmsg(uwep);
568 reset_remarm(); /* same as dowield() */
569 return weld_res ? ECMD_TIME : ECMD_OK;
571 /* offer to split stack if wielding more than 1 */
572 if (uwep->quan > 1L && inv_cnt(FALSE) < invlet_basic
573 && splittable(uwep)) {
574 Sprintf(qbuf, "You are wielding %ld %s. Ready %ld of them?",
575 uwep->quan, simpleonames(uwep), uwep->quan - 1L);
576 switch (ynq(qbuf)) {
577 case 'q':
578 return ECMD_OK;
579 case 'y':
580 /* leave 1 wielded, split rest off and put into quiver */
581 newquiver = splitobj(uwep, uwep->quan - 1L);
582 finish_splitting(newquiver);
583 goto quivering;
584 default:
585 break;
587 Strcpy(qbuf, "Ready all of them instead?");
588 } else {
589 boolean use_plural = (is_plural(uwep) || pair_of(uwep));
591 Sprintf(qbuf, "You are wielding %s. Ready %s instead?",
592 !use_plural ? "that" : "those",
593 !use_plural ? "it" : "them");
595 /* require confirmation to ready the main weapon */
596 if (ynq(qbuf) != 'y') {
597 (void) Shk_Your(qbuf, uwep); /* replace qbuf[] contents */
598 pline("%s%s %s wielded.", qbuf,
599 simpleonames(uwep), otense(uwep, "remain"));
600 return ECMD_OK;
602 /* quivering main weapon, so no longer wielding it */
603 setuwep((struct obj *) 0);
604 untwoweapon();
605 was_uwep = TRUE;
606 } else if (newquiver == uswapwep) {
607 if (uswapwep->quan > 1L && inv_cnt(FALSE) < invlet_basic
608 && splittable(uswapwep)) {
609 Sprintf(qbuf, "%s %ld %s. Ready %ld of them?",
610 u.twoweap ? "You are dual wielding"
611 : "Your alternate weapon is",
612 uswapwep->quan, simpleonames(uswapwep),
613 uswapwep->quan - 1L);
614 switch (ynq(qbuf)) {
615 case 'q':
616 return ECMD_OK;
617 case 'y':
618 /* leave 1 alt-wielded, split rest off and put into quiver */
619 newquiver = splitobj(uswapwep, uswapwep->quan - 1L);
620 finish_splitting(newquiver);
621 goto quivering;
622 default:
623 break;
625 Strcpy(qbuf, "Ready all of them instead?");
626 } else {
627 boolean use_plural = (is_plural(uswapwep) || pair_of(uswapwep));
629 Sprintf(qbuf, "%s your %s weapon. Ready %s instead?",
630 !use_plural ? "That is" : "Those are",
631 u.twoweap ? "second" : "alternate",
632 !use_plural ? "it" : "them");
634 /* require confirmation to ready the alternate weapon */
635 if (ynq(qbuf) != 'y') {
636 (void) Shk_Your(qbuf, uswapwep); /* replace qbuf[] contents */
637 pline("%s%s %s %s.", qbuf,
638 simpleonames(uswapwep), otense(uswapwep, "remain"),
639 u.twoweap ? "wielded" : "as secondary weapon");
640 return ECMD_OK;
642 /* quivering alternate weapon, so no more uswapwep */
643 setuswapwep((struct obj *) 0);
644 untwoweapon();
647 quivering:
648 if (!strcmp(verb, "ready")) {
649 /* place item in quiver before printing so that inventory feedback
650 includes "(at the ready)" */
651 setuqwep(newquiver);
652 prinv((char *) 0, newquiver, 0L);
653 } else { /* verb=="fire", manually refilling quiver during 'f'ire */
654 /* prefix item with description of action, so don't want that to
655 include "(at the ready)" */
656 prinv("You ready:", newquiver, 0L);
657 setuqwep(newquiver);
660 /* quiver is a convenience slot and manipulating it ordinarily
661 consumes no time, but unwielding primary or secondary weapon
662 should take time (perhaps we're adjacent to a rust monster
663 or disenchanter and want to hit it immediately, but not with
664 something we're wielding that's vulnerable to its damage) */
665 res = 0;
666 if (was_uwep) {
667 You("are now %s.", empty_handed());
668 res = 1;
669 } else if (was_twoweap && !u.twoweap) {
670 You("%s.", are_no_longer_twoweap);
671 res = 1;
673 return res ? ECMD_TIME : ECMD_OK;
676 /* used for #rub and for applying pick-axe, whip, grappling hook or polearm */
677 boolean
678 wield_tool(struct obj *obj,
679 const char *verb) /* "rub",&c */
681 const char *what;
682 boolean more_than_1;
684 if (uwep && obj == uwep)
685 return TRUE; /* nothing to do if already wielding it */
687 if (!verb)
688 verb = "wield";
689 what = xname(obj);
690 more_than_1 = (obj->quan > 1L || strstri(what, "pair of ") != 0
691 || strstri(what, "s of ") != 0);
693 if (obj->owornmask & (W_ARMOR | W_ACCESSORY)) {
694 You_cant("%s %s while wearing %s.", verb, yname(obj),
695 more_than_1 ? "them" : "it");
696 return FALSE;
698 if (uwep && welded(uwep)) {
699 if (flags.verbose) {
700 const char *hand = body_part(HAND);
702 if (bimanual(uwep))
703 hand = makeplural(hand);
704 if (strstri(what, "pair of ") != 0)
705 more_than_1 = FALSE;
706 pline(
707 "Since your weapon is welded to your %s, you cannot %s %s %s.",
708 hand, verb, more_than_1 ? "those" : "that", xname(obj));
709 } else {
710 You_cant("do that.");
712 return FALSE;
714 if (cantwield(gy.youmonst.data)) {
715 You_cant("hold %s strongly enough.", more_than_1 ? "them" : "it");
716 return FALSE;
718 /* check shield */
719 if (uarms && bimanual(obj)) {
720 You("cannot %s a two-handed %s while wearing a shield.", verb,
721 (obj->oclass == WEAPON_CLASS) ? "weapon" : "tool");
722 return FALSE;
725 if (uquiver == obj)
726 setuqwep((struct obj *) 0);
727 if (uswapwep == obj) {
728 (void) doswapweapon();
729 /* doswapweapon might fail */
730 if (uswapwep == obj)
731 return FALSE;
732 } else {
733 struct obj *oldwep = uwep;
735 if (will_weld(obj)) {
736 /* hope none of ready_weapon()'s early returns apply here... */
737 (void) ready_weapon(obj);
738 } else {
739 You("now wield %s.", doname(obj));
740 setuwep(obj);
742 if (flags.pushweapon && oldwep && uwep != oldwep)
743 setuswapwep(oldwep);
745 if (uwep && uwep != obj)
746 return FALSE; /* rewielded old object after dying */
747 /* applying weapon or tool that gets wielded ends two-weapon combat */
748 if (u.twoweap)
749 untwoweapon();
750 if (obj->oclass != WEAPON_CLASS)
751 gu.unweapon = TRUE;
752 return TRUE;
756 can_twoweapon(void)
758 struct obj *otmp;
760 if (!could_twoweap(gy.youmonst.data)) {
761 if (Upolyd)
762 You_cant("use two weapons in your current form.");
763 else
764 pline("%s aren't able to use two weapons at once.",
765 makeplural((flags.female && gu.urole.name.f)
766 ? gu.urole.name.f : gu.urole.name.m));
767 } else if (!uwep || !uswapwep) {
768 const char *hand_s = body_part(HAND);
770 if (!uwep && !uswapwep)
771 hand_s = makeplural(hand_s);
772 /* "your hands are empty" or "your {left|right} hand is empty" */
773 Your("%s%s %s empty.", uwep ? "left " : uswapwep ? "right " : "",
774 hand_s, vtense(hand_s, "are"));
775 } else if (!TWOWEAPOK(uwep) || !TWOWEAPOK(uswapwep)) {
776 otmp = !TWOWEAPOK(uwep) ? uwep : uswapwep;
777 pline("%s %s suitable %s weapon%s.", Yname2(otmp),
778 is_plural(otmp) ? "aren't" : "isn't a",
779 (otmp == uwep) ? "primary" : "secondary",
780 plur(otmp->quan));
781 } else if (bimanual(uwep) || bimanual(uswapwep)) {
782 otmp = bimanual(uwep) ? uwep : uswapwep;
783 pline("%s isn't one-handed.", Yname2(otmp));
784 } else if (uarms) {
785 You_cant("use two weapons while wearing a shield.");
786 } else if (uswapwep->oartifact) {
787 pline("%s being held second to another weapon!",
788 Yobjnam2(uswapwep, "resist"));
789 } else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) {
790 /* [Note: !TWOWEAPOK() check prevents ever getting here...] */
791 ; /* must be life-saved to reach here; return FALSE */
792 } else if (Glib || uswapwep->cursed) {
793 if (!Glib)
794 set_bknown(uswapwep, 1);
795 drop_uswapwep();
796 } else
797 return TRUE;
798 return FALSE;
801 /* uswapwep has become cursed while in two-weapon combat mode or hero is
802 attempting to dual-wield when it is already cursed or hands are slippery */
803 void
804 drop_uswapwep(void)
806 char left_hand[QBUFSZ];
807 struct obj *obj = uswapwep;
809 /* this used to use makeplural(body_part(HAND)) but in order to be
810 dual-wielded, or to get this far attempting to achieve that,
811 uswapwep must be one-handed; since it's secondary, the hand must
812 be the left one */
813 Sprintf(left_hand, "left %s", body_part(HAND));
814 if (!obj->cursed)
815 /* attempting to two-weapon while Glib */
816 pline("%s from your %s!", Yobjnam2(obj, "slip"), left_hand);
817 else if (!u.twoweap)
818 /* attempting to two-weapon when uswapwep is cursed */
819 pline("%s your grasp and %s from your %s!",
820 Yobjnam2(obj, "evade"), otense(obj, "drop"), left_hand);
821 else
822 /* already two-weaponing but can't anymore because uswapwep has
823 become cursed */
824 Your("%s spasms and drops %s!", left_hand, yobjnam(obj, (char *) 0));
825 dropx(obj);
828 void
829 set_twoweap(boolean on_off)
831 u.twoweap = on_off;
834 /* the #twoweapon command */
836 dotwoweapon(void)
838 /* You can always toggle it off */
839 if (u.twoweap) {
840 You("switch to your primary weapon.");
841 set_twoweap(FALSE); /* u.twoweap = FALSE */
842 update_inventory();
843 return ECMD_OK;
846 /* May we use two weapons? */
847 if (can_twoweapon()) {
848 /* Success! */
849 You("begin two-weapon combat.");
850 set_twoweap(TRUE); /* u.twoweap = TRUE */
851 update_inventory();
852 return (rnd(20) > ACURR(A_DEX)) ? ECMD_TIME : ECMD_OK;
854 return ECMD_OK;
857 /*** Functions to empty a given slot ***/
858 /* These should be used only when the item can't be put back in
859 * the slot by life saving. Proper usage includes:
860 * 1. The item has been eaten, stolen, burned away, or rotted away.
861 * 2. Making an item disappear for a bones pile.
863 void
864 uwepgone(void)
866 if (uwep) {
867 if (artifact_light(uwep) && uwep->lamplit) {
868 end_burn(uwep, FALSE);
869 if (!Blind)
870 pline("%s shining.", Tobjnam(uwep, "stop"));
872 setworn((struct obj *) 0, W_WEP);
873 gu.unweapon = TRUE;
874 update_inventory();
878 void
879 uswapwepgone(void)
881 if (uswapwep) {
882 setworn((struct obj *) 0, W_SWAPWEP);
883 update_inventory();
887 void
888 uqwepgone(void)
890 if (uquiver) {
891 setworn((struct obj *) 0, W_QUIVER);
892 update_inventory();
896 void
897 untwoweapon(void)
899 if (u.twoweap) {
900 You("%s.", can_no_longer_twoweap);
901 set_twoweap(FALSE); /* u.twoweap = FALSE */
902 update_inventory();
904 return;
907 /* enchant wielded weapon */
909 chwepon(struct obj *otmp, int amount)
911 const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE);
912 const char *xtime, *wepname = "";
913 boolean multiple;
914 int otyp = STRANGE_OBJECT;
916 if (!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) {
917 char buf[BUFSZ];
919 if (amount >= 0 && uwep && will_weld(uwep)) { /* cursed tin opener */
920 if (!Blind) {
921 Sprintf(buf, "%s with %s aura.",
922 Yobjnam2(uwep, "glow"), an(hcolor(NH_AMBER)));
923 uwep->bknown = !Hallucination; /* ok to bypass set_bknown() */
924 } else {
925 /* cursed tin opener is wielded in right hand */
926 Sprintf(buf, "Your right %s tingles.", body_part(HAND));
928 uncurse(uwep);
929 update_inventory();
930 } else {
931 Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),
932 (amount >= 0) ? "twitch" : "itch");
934 strange_feeling(otmp, buf); /* pline()+docall()+useup() */
935 exercise(A_DEX, (boolean) (amount >= 0));
936 return 0;
939 if (otmp && otmp->oclass == SCROLL_CLASS)
940 otyp = otmp->otyp;
942 if (uwep->otyp == WORM_TOOTH && amount >= 0) {
943 multiple = (uwep->quan > 1L);
944 /* order: message, transformation, shop handling */
945 Your("%s %s much sharper now.", simpleonames(uwep),
946 multiple ? "fuse, and become" : "is");
947 uwep->otyp = CRYSKNIFE;
948 uwep->oerodeproof = 0;
949 if (multiple) {
950 uwep->quan = 1L;
951 uwep->owt = weight(uwep);
953 if (uwep->cursed)
954 uncurse(uwep);
955 /* update shop bill to reflect new higher value */
956 if (uwep->unpaid)
957 alter_cost(uwep, 0L);
958 if (otyp != STRANGE_OBJECT)
959 makeknown(otyp);
960 if (multiple)
961 (void) encumber_msg();
962 return 1;
963 } else if (uwep->otyp == CRYSKNIFE && amount < 0) {
964 multiple = (uwep->quan > 1L);
965 /* order matters: message, shop handling, transformation */
966 Your("%s %s much duller now.", simpleonames(uwep),
967 multiple ? "fuse, and become" : "is");
968 costly_alteration(uwep, COST_DEGRD); /* DECHNT? other? */
969 uwep->otyp = WORM_TOOTH;
970 uwep->oerodeproof = 0;
971 if (multiple) {
972 uwep->quan = 1L;
973 uwep->owt = weight(uwep);
975 if (otyp != STRANGE_OBJECT && otmp->bknown)
976 makeknown(otyp);
977 if (multiple)
978 (void) encumber_msg();
979 return 1;
982 if (has_oname(uwep))
983 wepname = ONAME(uwep);
984 if (amount < 0 && uwep->oartifact && restrict_name(uwep, wepname)) {
985 if (!Blind)
986 pline("%s %s.", Yobjnam2(uwep, "faintly glow"), color);
987 return 1;
989 /* there is a (soft) upper and lower limit to uwep->spe */
990 if (((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
991 && rn2(3)) {
992 if (!Blind)
993 pline("%s %s for a while and then %s.",
994 Yobjnam2(uwep, "violently glow"), color,
995 otense(uwep, "evaporate"));
996 else
997 pline("%s.", Yobjnam2(uwep, "evaporate"));
999 useupall(uwep); /* let all of them disappear */
1000 return 1;
1002 if (!Blind) {
1003 xtime = (amount * amount == 1) ? "moment" : "while";
1004 pline("%s %s for a %s.",
1005 Yobjnam2(uwep, amount == 0 ? "violently glow" : "glow"), color,
1006 xtime);
1007 if (otyp != STRANGE_OBJECT && uwep->known
1008 && (amount > 0 || (amount < 0 && otmp->bknown)))
1009 makeknown(otyp);
1011 if (amount < 0)
1012 costly_alteration(uwep, COST_DECHNT);
1013 uwep->spe += amount;
1014 if (amount > 0) {
1015 if (uwep->cursed)
1016 uncurse(uwep);
1017 /* update shop bill to reflect new higher price */
1018 if (uwep->unpaid)
1019 alter_cost(uwep, 0L);
1023 * Enchantment, which normally improves a weapon, has an
1024 * addition adverse reaction on Magicbane whose effects are
1025 * spe dependent. Give an obscure clue here.
1027 if (u_wield_art(ART_MAGICBANE) && uwep->spe >= 0) {
1028 Your("right %s %sches!", body_part(HAND),
1029 (((amount > 1) && (uwep->spe > 1)) ? "flin" : "it"));
1032 /* an elven magic clue, cookie@keebler */
1033 /* elven weapons vibrate warningly when enchanted beyond a limit */
1034 if ((uwep->spe > 5)
1035 && (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
1036 pline("%s unexpectedly.", Yobjnam2(uwep, "suddenly vibrate"));
1038 return 1;
1042 welded(struct obj *obj)
1044 if (obj && obj == uwep && will_weld(obj)) {
1045 set_bknown(obj, 1);
1046 return 1;
1048 return 0;
1051 void
1052 weldmsg(struct obj *obj)
1054 long savewornmask;
1055 const char *hand = body_part(HAND);
1057 if (bimanual(obj))
1058 hand = makeplural(hand);
1059 savewornmask = obj->owornmask;
1060 obj->owornmask = 0L; /* suppress doname()'s "(weapon in hand)";
1061 * Yobjnam2() doesn't actually need this because
1062 * it is based on xname() rather than doname() */
1063 pline("%s welded to your %s!", Yobjnam2(obj, "are"), hand);
1064 obj->owornmask = savewornmask;
1067 /* test whether monster's wielded weapon is stuck to hand/paw/whatever */
1068 boolean
1069 mwelded(struct obj *obj)
1071 /* caller is responsible for making sure this is a monster's item */
1072 if (obj && (obj->owornmask & W_WEP) && will_weld(obj))
1073 return TRUE;
1074 return FALSE;
1077 /*wield.c*/