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