dumplog lint and formatting
[aNetHack.git] / src / wield.c
blob585e971c918a4aafa77eefef61d76ac98fa79dcd
1 /* NetHack 3.6 wield.c $NHDT-Date: 1461967849 2016/04/29 22:10:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
7 /* KMH -- Differences between the three weapon slots.
9 * The main weapon (uwep):
10 * 1. Is filled by the (w)ield command.
11 * 2. Can be filled with any type of item.
12 * 3. May be carried in one or both hands.
13 * 4. Is used as the melee weapon and as the launcher for
14 * ammunition.
15 * 5. Only conveys intrinsics when it is a weapon, weapon-tool,
16 * or artifact.
17 * 6. Certain cursed items will weld to the hand and cannot be
18 * unwielded or dropped. See erodeable_wep() and will_weld()
19 * below for the list of which items apply.
21 * The secondary weapon (uswapwep):
22 * 1. Is filled by the e(x)change command, which swaps this slot
23 * with the main weapon. If the "pushweapon" option is set,
24 * the (w)ield command will also store the old weapon in the
25 * secondary slot.
26 * 2. Can be filled with anything that will fit in the main weapon
27 * slot; that is, any type of item.
28 * 3. Is usually NOT considered to be carried in the hands.
29 * That would force too many checks among the main weapon,
30 * second weapon, shield, gloves, and rings; and it would
31 * further be complicated by bimanual weapons. A special
32 * exception is made for two-weapon combat.
33 * 4. Is used as the second weapon for two-weapon combat, and as
34 * a convenience to swap with the main weapon.
35 * 5. Never conveys intrinsics.
36 * 6. Cursed items never weld (see #3 for reasons), but they also
37 * prevent two-weapon combat.
39 * The quiver (uquiver):
40 * 1. Is filled by the (Q)uiver command.
41 * 2. Can be filled with any type of item.
42 * 3. Is considered to be carried in a special part of the pack.
43 * 4. Is used as the item to throw with the (f)ire command.
44 * This is a convenience over the normal (t)hrow command.
45 * 5. Never conveys intrinsics.
46 * 6. Cursed items never weld; their effect is handled by the normal
47 * throwing code.
48 * 7. The autoquiver option will fill it with something deemed
49 * suitable if (f)ire is used when it's empty.
51 * No item may be in more than one of these slots.
54 STATIC_DCL boolean FDECL(cant_wield_corpse, (struct obj *));
55 STATIC_DCL int FDECL(ready_weapon, (struct obj *));
57 /* used by will_weld() */
58 /* probably should be renamed */
59 #define erodeable_wep(optr) \
60 ((optr)->oclass == WEAPON_CLASS || is_weptool(optr) \
61 || (optr)->otyp == HEAVY_IRON_BALL || (optr)->otyp == IRON_CHAIN)
63 /* used by welded(), and also while wielding */
64 #define will_weld(optr) \
65 ((optr)->cursed && (erodeable_wep(optr) || (optr)->otyp == TIN_OPENER))
67 /*** Functions that place a given item in a slot ***/
68 /* Proper usage includes:
69 * 1. Initializing the slot during character generation or a
70 * restore.
71 * 2. Setting the slot due to a player's actions.
72 * 3. If one of the objects in the slot are split off, these
73 * functions can be used to put the remainder back in the slot.
74 * 4. Putting an item that was thrown and returned back into the slot.
75 * 5. Emptying the slot, by passing a null object. NEVER pass
76 * zeroobj!
78 * If the item is being moved from another slot, it is the caller's
79 * responsibility to handle that. It's also the caller's responsibility
80 * to print the appropriate messages.
82 void
83 setuwep(obj)
84 register struct obj *obj;
86 struct obj *olduwep = uwep;
88 if (obj == uwep)
89 return; /* necessary to not set unweapon */
90 /* This message isn't printed in the caller because it happens
91 * *whenever* Sunsword is unwielded, from whatever cause.
93 setworn(obj, W_WEP);
94 if (uwep == obj && artifact_light(olduwep) && olduwep->lamplit) {
95 end_burn(olduwep, FALSE);
96 if (!Blind)
97 pline("%s shining.", Tobjnam(olduwep, "stop"));
99 if (uwep == obj
100 && ((uwep && uwep->oartifact == ART_OGRESMASHER)
101 || (olduwep && olduwep->oartifact == ART_OGRESMASHER)))
102 context.botl = 1;
103 /* Note: Explicitly wielding a pick-axe will not give a "bashing"
104 * message. Wielding one via 'a'pplying it will.
105 * 3.2.2: Wielding arbitrary objects will give bashing message too.
107 if (obj) {
108 unweapon = (obj->oclass == WEAPON_CLASS)
109 ? is_launcher(obj) || is_ammo(obj) || is_missile(obj)
110 || (is_pole(obj) && !u.usteed)
111 : !is_weptool(obj) && !is_wet_towel(obj);
112 } else
113 unweapon = TRUE; /* for "bare hands" message */
114 update_inventory();
117 STATIC_OVL boolean
118 cant_wield_corpse(obj)
119 struct obj *obj;
121 char kbuf[BUFSZ];
123 if (uarmg || obj->otyp != CORPSE || !touch_petrifies(&mons[obj->corpsenm])
124 || Stone_resistance)
125 return FALSE;
127 /* Prevent wielding cockatrice when not wearing gloves --KAA */
128 You("wield %s in your bare %s.",
129 corpse_xname(obj, (const char *) 0, CXN_PFX_THE),
130 makeplural(body_part(HAND)));
131 Sprintf(kbuf, "wielding %s bare-handed", killer_xname(obj));
132 instapetrify(kbuf);
133 return TRUE;
136 STATIC_OVL int
137 ready_weapon(wep)
138 struct obj *wep;
140 /* Separated function so swapping works easily */
141 int res = 0;
143 if (!wep) {
144 /* No weapon */
145 if (uwep) {
146 You("are empty %s.", body_part(HANDED));
147 setuwep((struct obj *) 0);
148 res++;
149 } else
150 You("are already empty %s.", body_part(HANDED));
151 } else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) {
152 /* hero must have been life-saved to get here; use a turn */
153 res++; /* corpse won't be wielded */
154 } else if (uarms && bimanual(wep)) {
155 You("cannot wield a two-handed %s while wearing a shield.",
156 is_sword(wep) ? "sword" : wep->otyp == BATTLE_AXE ? "axe"
157 : "weapon");
158 } else if (!retouch_object(&wep, FALSE)) {
159 res++; /* takes a turn even though it doesn't get wielded */
160 } else {
161 /* Weapon WILL be wielded after this point */
162 res++;
163 if (will_weld(wep)) {
164 const char *tmp = xname(wep), *thestr = "The ";
166 if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
167 tmp = thestr;
168 else
169 tmp = "";
170 pline("%s%s %s to your %s!", tmp, aobjnam(wep, "weld"),
171 (wep->quan == 1L) ? "itself" : "themselves", /* a3 */
172 bimanual(wep) ? (const char *) makeplural(body_part(HAND))
173 : body_part(HAND));
174 wep->bknown = TRUE;
175 } else {
176 /* The message must be printed before setuwep (since
177 * you might die and be revived from changing weapons),
178 * and the message must be before the death message and
179 * Lifesaved rewielding. Yet we want the message to
180 * say "weapon in hand", thus this kludge.
181 * [That comment is obsolete. It dates from the days (3.0)
182 * when unwielding Firebrand could cause hero to be burned
183 * to death in Hell due to loss of fire resistance.
184 * "Lifesaved re-wielding or re-wearing" is ancient history.]
186 long dummy = wep->owornmask;
188 wep->owornmask |= W_WEP;
189 prinv((char *) 0, wep, 0L);
190 wep->owornmask = dummy;
192 setuwep(wep);
194 /* KMH -- Talking artifacts are finally implemented */
195 arti_speak(wep);
197 if (artifact_light(wep) && !wep->lamplit) {
198 begin_burn(wep, FALSE);
199 if (!Blind)
200 pline("%s to shine %s!", Tobjnam(wep, "begin"),
201 arti_light_description(wep));
203 #if 0
204 /* we'll get back to this someday, but it's not balanced yet */
205 if (Race_if(PM_ELF) && !wep->oartifact
206 && objects[wep->otyp].oc_material == IRON) {
207 /* Elves are averse to wielding cold iron */
208 You("have an uneasy feeling about wielding cold iron.");
209 change_luck(-1);
211 #endif
212 if (wep->unpaid) {
213 struct monst *this_shkp;
215 if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy)))
216 != (struct monst *) 0) {
217 pline("%s says \"You be careful with my %s!\"",
218 shkname(this_shkp), xname(wep));
222 return res;
225 void
226 setuqwep(obj)
227 register struct obj *obj;
229 setworn(obj, W_QUIVER);
230 update_inventory();
233 void
234 setuswapwep(obj)
235 register struct obj *obj;
237 setworn(obj, W_SWAPWEP);
238 update_inventory();
241 /*** Commands to change particular slot(s) ***/
243 static NEARDATA const char wield_objs[] = {
244 ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, TOOL_CLASS, 0
246 static NEARDATA const char ready_objs[] = {
247 ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, 0
249 static NEARDATA const char bullets[] = { /* (note: different from dothrow.c) */
250 ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, ALLOW_NONE,
251 GEM_CLASS, WEAPON_CLASS, 0
255 dowield()
257 register struct obj *wep, *oldwep;
258 int result;
260 /* May we attempt this? */
261 multi = 0;
262 if (cantwield(youmonst.data)) {
263 pline("Don't be ridiculous!");
264 return 0;
267 /* Prompt for a new weapon */
268 if (!(wep = getobj(wield_objs, "wield")))
269 /* Cancelled */
270 return 0;
271 else if (wep == uwep) {
272 You("are already wielding that!");
273 if (is_weptool(wep) || is_wet_towel(wep))
274 unweapon = FALSE; /* [see setuwep()] */
275 return 0;
276 } else if (welded(uwep)) {
277 weldmsg(uwep);
278 /* previously interrupted armor removal mustn't be resumed */
279 reset_remarm();
280 return 0;
283 /* Handle no object, or object in other slot */
284 if (wep == &zeroobj)
285 wep = (struct obj *) 0;
286 else if (wep == uswapwep)
287 return doswapweapon();
288 else if (wep == uquiver)
289 setuqwep((struct obj *) 0);
290 else if (wep->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE)) {
291 You("cannot wield that!");
292 return 0;
295 /* Set your new primary weapon */
296 oldwep = uwep;
297 result = ready_weapon(wep);
298 if (flags.pushweapon && oldwep && uwep != oldwep)
299 setuswapwep(oldwep);
300 untwoweapon();
302 return result;
306 doswapweapon()
308 register struct obj *oldwep, *oldswap;
309 int result = 0;
311 /* May we attempt this? */
312 multi = 0;
313 if (cantwield(youmonst.data)) {
314 pline("Don't be ridiculous!");
315 return 0;
317 if (welded(uwep)) {
318 weldmsg(uwep);
319 return 0;
322 /* Unwield your current secondary weapon */
323 oldwep = uwep;
324 oldswap = uswapwep;
325 setuswapwep((struct obj *) 0);
327 /* Set your new primary weapon */
328 result = ready_weapon(oldswap);
330 /* Set your new secondary weapon */
331 if (uwep == oldwep) {
332 /* Wield failed for some reason */
333 setuswapwep(oldswap);
334 } else {
335 setuswapwep(oldwep);
336 if (uswapwep)
337 prinv((char *) 0, uswapwep, 0L);
338 else
339 You("have no secondary weapon readied.");
342 if (u.twoweap && !can_twoweapon())
343 untwoweapon();
345 return result;
349 dowieldquiver()
351 char qbuf[QBUFSZ];
352 struct obj *newquiver;
353 const char *quivee_types;
354 int res;
355 boolean finish_splitting = FALSE,
356 was_uwep = FALSE, was_twoweap = u.twoweap;
358 /* Since the quiver isn't in your hands, don't check cantwield(), */
359 /* will_weld(), touch_petrifies(), etc. */
360 multi = 0;
361 /* forget last splitobj() before calling getobj() with ALLOW_COUNT */
362 context.objsplit.child_oid = context.objsplit.parent_oid = 0;
364 /* Prompt for a new quiver: "What do you want to ready?"
365 (Include gems/stones as likely candidates if either primary
366 or secondary weapon is a sling.) */
367 quivee_types = (uslinging()
368 || (uswapwep
369 && objects[uswapwep->otyp].oc_skill == P_SLING))
370 ? bullets
371 : ready_objs;
372 newquiver = getobj(quivee_types, "ready");
374 if (!newquiver) {
375 /* Cancelled */
376 return 0;
377 } else if (newquiver == &zeroobj) { /* no object */
378 /* Explicitly nothing */
379 if (uquiver) {
380 You("now have no ammunition readied.");
381 /* skip 'quivering: prinv()' */
382 setuqwep((struct obj *) 0);
383 } else {
384 You("already have no ammunition readied!");
386 return 0;
387 } else if (newquiver->o_id == context.objsplit.child_oid) {
388 /* if newquiver is the result of supplying a count to getobj()
389 we don't want to split something already in the quiver;
390 for any other item, we need to give it its own inventory slot */
391 if (uquiver && uquiver->o_id == context.objsplit.parent_oid) {
392 unsplitobj(newquiver);
393 goto already_quivered;
395 finish_splitting = TRUE;
396 } else if (newquiver == uquiver) {
397 already_quivered:
398 pline("That ammunition is already readied!");
399 return 0;
400 } else if (newquiver->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE)) {
401 You("cannot ready that!");
402 return 0;
403 } else if (newquiver == uwep) {
404 int weld_res = !uwep->bknown;
406 if (welded(uwep)) {
407 weldmsg(uwep);
408 reset_remarm(); /* same as dowield() */
409 return weld_res;
411 /* offer to split stack if wielding more than 1 */
412 if (uwep->quan > 1L && inv_cnt(FALSE) < 52 && splittable(uwep)) {
413 Sprintf(qbuf, "You are wielding %ld %s. Ready %ld of them?",
414 uwep->quan, simpleonames(uwep), uwep->quan - 1L);
415 switch (ynq(qbuf)) {
416 case 'q':
417 return 0;
418 case 'y':
419 /* leave 1 wielded, split rest off and put into quiver */
420 newquiver = splitobj(uwep, uwep->quan - 1L);
421 finish_splitting = TRUE;
422 goto quivering;
423 default:
424 break;
426 Strcpy(qbuf, "Ready all of them instead?");
427 } else {
428 boolean use_plural = (is_plural(uwep) || pair_of(uwep));
430 Sprintf(qbuf, "You are wielding %s. Ready %s instead?",
431 !use_plural ? "that" : "those",
432 !use_plural ? "it" : "them");
434 /* require confirmation to ready the main weapon */
435 if (ynq(qbuf) != 'y') {
436 (void) Shk_Your(qbuf, uwep); /* replace qbuf[] contents */
437 pline("%s%s %s wielded.", qbuf,
438 simpleonames(uwep), otense(uwep, "remain"));
439 return 0;
441 /* quivering main weapon, so no longer wielding it */
442 setuwep((struct obj *) 0);
443 untwoweapon();
444 was_uwep = TRUE;
445 } else if (newquiver == uswapwep) {
446 if (uswapwep->quan > 1L && inv_cnt(FALSE) < 52
447 && splittable(uswapwep)) {
448 Sprintf(qbuf, "%s %ld %s. Ready %ld of them?",
449 u.twoweap ? "You are dual wielding"
450 : "Your alternate weapon is",
451 uswapwep->quan, simpleonames(uswapwep),
452 uswapwep->quan - 1L);
453 switch (ynq(qbuf)) {
454 case 'q':
455 return 0;
456 case 'y':
457 /* leave 1 alt-wielded, split rest off and put into quiver */
458 newquiver = splitobj(uswapwep, uswapwep->quan - 1L);
459 finish_splitting = TRUE;
460 goto quivering;
461 default:
462 break;
464 Strcpy(qbuf, "Ready all of them instead?");
465 } else {
466 boolean use_plural = (is_plural(uswapwep) || pair_of(uswapwep));
468 Sprintf(qbuf, "%s your %s weapon. Ready %s instead?",
469 !use_plural ? "That is" : "Those are",
470 u.twoweap ? "second" : "alternate",
471 !use_plural ? "it" : "them");
473 /* require confirmation to ready the alternate weapon */
474 if (ynq(qbuf) != 'y') {
475 (void) Shk_Your(qbuf, uswapwep); /* replace qbuf[] contents */
476 pline("%s%s %s %s.", qbuf,
477 simpleonames(uswapwep), otense(uswapwep, "remain"),
478 u.twoweap ? "wielded" : "as secondary weapon");
479 return 0;
481 /* quivering alternate weapon, so no more uswapwep */
482 setuswapwep((struct obj *) 0);
483 untwoweapon();
486 quivering:
487 if (finish_splitting) {
488 freeinv(newquiver);
489 newquiver->nomerge = 1;
490 addinv(newquiver);
491 newquiver->nomerge = 0;
493 /* place item in quiver before printing so that inventory feedback
494 includes "(at the ready)" */
495 setuqwep(newquiver);
496 prinv((char *) 0, newquiver, 0L);
498 /* quiver is a convenience slot and manipulating it ordinarily
499 consumes no time, but unwielding primary or secondary weapon
500 should take time (perhaps we're adjacent to a rust monster
501 or disenchanter and want to hit it immediately, but not with
502 something we're wielding that's vulnerable to its damage) */
503 res = 0;
504 if (was_uwep) {
505 You("are now empty %s.", body_part(HANDED));
506 res = 1;
507 } else if (was_twoweap && !u.twoweap) {
508 You("are no longer wielding two weapons at once.");
509 res = 1;
511 return res;
514 /* used for #rub and for applying pick-axe, whip, grappling hook or polearm */
515 boolean
516 wield_tool(obj, verb)
517 struct obj *obj;
518 const char *verb; /* "rub",&c */
520 const char *what;
521 boolean more_than_1;
523 if (obj == uwep)
524 return TRUE; /* nothing to do if already wielding it */
526 if (!verb)
527 verb = "wield";
528 what = xname(obj);
529 more_than_1 = (obj->quan > 1L || strstri(what, "pair of ") != 0
530 || strstri(what, "s of ") != 0);
532 if (obj->owornmask & (W_ARMOR | W_ACCESSORY)) {
533 You_cant("%s %s while wearing %s.", verb, yname(obj),
534 more_than_1 ? "them" : "it");
535 return FALSE;
537 if (welded(uwep)) {
538 if (flags.verbose) {
539 const char *hand = body_part(HAND);
541 if (bimanual(uwep))
542 hand = makeplural(hand);
543 if (strstri(what, "pair of ") != 0)
544 more_than_1 = FALSE;
545 pline(
546 "Since your weapon is welded to your %s, you cannot %s %s %s.",
547 hand, verb, more_than_1 ? "those" : "that", xname(obj));
548 } else {
549 You_cant("do that.");
551 return FALSE;
553 if (cantwield(youmonst.data)) {
554 You_cant("hold %s strongly enough.", more_than_1 ? "them" : "it");
555 return FALSE;
557 /* check shield */
558 if (uarms && bimanual(obj)) {
559 You("cannot %s a two-handed %s while wearing a shield.", verb,
560 (obj->oclass == WEAPON_CLASS) ? "weapon" : "tool");
561 return FALSE;
564 if (uquiver == obj)
565 setuqwep((struct obj *) 0);
566 if (uswapwep == obj) {
567 (void) doswapweapon();
568 /* doswapweapon might fail */
569 if (uswapwep == obj)
570 return FALSE;
571 } else {
572 struct obj *oldwep = uwep;
574 You("now wield %s.", doname(obj));
575 setuwep(obj);
576 if (flags.pushweapon && oldwep && uwep != oldwep)
577 setuswapwep(oldwep);
579 if (uwep != obj)
580 return FALSE; /* rewielded old object after dying */
581 /* applying weapon or tool that gets wielded ends two-weapon combat */
582 if (u.twoweap)
583 untwoweapon();
584 if (obj->oclass != WEAPON_CLASS)
585 unweapon = TRUE;
586 return TRUE;
590 can_twoweapon()
592 struct obj *otmp;
594 #define NOT_WEAPON(obj) (!is_weptool(obj) && obj->oclass != WEAPON_CLASS)
595 if (!could_twoweap(youmonst.data)) {
596 if (Upolyd)
597 You_cant("use two weapons in your current form.");
598 else
599 pline("%s aren't able to use two weapons at once.",
600 makeplural((flags.female && urole.name.f) ? urole.name.f
601 : urole.name.m));
602 } else if (!uwep || !uswapwep)
603 Your("%s%s%s empty.", uwep ? "left " : uswapwep ? "right " : "",
604 body_part(HAND), (!uwep && !uswapwep) ? "s are" : " is");
605 else if (NOT_WEAPON(uwep) || NOT_WEAPON(uswapwep)) {
606 otmp = NOT_WEAPON(uwep) ? uwep : uswapwep;
607 pline("%s %s.", Yname2(otmp),
608 is_plural(otmp) ? "aren't weapons" : "isn't a weapon");
609 } else if (bimanual(uwep) || bimanual(uswapwep)) {
610 otmp = bimanual(uwep) ? uwep : uswapwep;
611 pline("%s isn't one-handed.", Yname2(otmp));
612 } else if (uarms)
613 You_cant("use two weapons while wearing a shield.");
614 else if (uswapwep->oartifact)
615 pline("%s being held second to another weapon!",
616 Yobjnam2(uswapwep, "resist"));
617 else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) {
618 /* [Note: NOT_WEAPON() check prevents ever getting here...] */
619 ; /* must be life-saved to reach here; return FALSE */
620 } else if (Glib || uswapwep->cursed) {
621 if (!Glib)
622 uswapwep->bknown = TRUE;
623 drop_uswapwep();
624 } else
625 return TRUE;
626 return FALSE;
629 void
630 drop_uswapwep()
632 char str[BUFSZ];
633 struct obj *obj = uswapwep;
635 /* Avoid trashing makeplural's static buffer */
636 Strcpy(str, makeplural(body_part(HAND)));
637 pline("%s from your %s!", Yobjnam2(obj, "slip"), str);
638 dropx(obj);
642 dotwoweapon()
644 /* You can always toggle it off */
645 if (u.twoweap) {
646 You("switch to your primary weapon.");
647 u.twoweap = 0;
648 update_inventory();
649 return 0;
652 /* May we use two weapons? */
653 if (can_twoweapon()) {
654 /* Success! */
655 You("begin two-weapon combat.");
656 u.twoweap = 1;
657 update_inventory();
658 return (rnd(20) > ACURR(A_DEX));
660 return 0;
663 /*** Functions to empty a given slot ***/
664 /* These should be used only when the item can't be put back in
665 * the slot by life saving. Proper usage includes:
666 * 1. The item has been eaten, stolen, burned away, or rotted away.
667 * 2. Making an item disappear for a bones pile.
669 void
670 uwepgone()
672 if (uwep) {
673 if (artifact_light(uwep) && uwep->lamplit) {
674 end_burn(uwep, FALSE);
675 if (!Blind)
676 pline("%s shining.", Tobjnam(uwep, "stop"));
678 setworn((struct obj *) 0, W_WEP);
679 unweapon = TRUE;
680 update_inventory();
684 void
685 uswapwepgone()
687 if (uswapwep) {
688 setworn((struct obj *) 0, W_SWAPWEP);
689 update_inventory();
693 void
694 uqwepgone()
696 if (uquiver) {
697 setworn((struct obj *) 0, W_QUIVER);
698 update_inventory();
702 void
703 untwoweapon()
705 if (u.twoweap) {
706 You("can no longer use two weapons at once.");
707 u.twoweap = FALSE;
708 update_inventory();
710 return;
714 chwepon(otmp, amount)
715 register struct obj *otmp;
716 register int amount;
718 const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE);
719 const char *xtime, *wepname = "";
720 boolean multiple;
721 int otyp = STRANGE_OBJECT;
723 if (!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) {
724 char buf[BUFSZ];
726 if (amount >= 0 && uwep && will_weld(uwep)) { /* cursed tin opener */
727 if (!Blind) {
728 Sprintf(buf, "%s with %s aura.",
729 Yobjnam2(uwep, "glow"), an(hcolor(NH_AMBER)));
730 uwep->bknown = !Hallucination;
731 } else {
732 /* cursed tin opener is wielded in right hand */
733 Sprintf(buf, "Your right %s tingles.", body_part(HAND));
735 uncurse(uwep);
736 update_inventory();
737 } else {
738 Sprintf(buf, "Your %s %s.", makeplural(body_part(HAND)),
739 (amount >= 0) ? "twitch" : "itch");
741 strange_feeling(otmp, buf); /* pline()+docall()+useup() */
742 exercise(A_DEX, (boolean) (amount >= 0));
743 return 0;
746 if (otmp && otmp->oclass == SCROLL_CLASS)
747 otyp = otmp->otyp;
749 if (uwep->otyp == WORM_TOOTH && amount >= 0) {
750 multiple = (uwep->quan > 1L);
751 /* order: message, transformation, shop handling */
752 Your("%s %s much sharper now.", simpleonames(uwep),
753 multiple ? "fuse, and become" : "is");
754 uwep->otyp = CRYSKNIFE;
755 uwep->oerodeproof = 0;
756 if (multiple) {
757 uwep->quan = 1L;
758 uwep->owt = weight(uwep);
760 if (uwep->cursed)
761 uncurse(uwep);
762 /* update shop bill to reflect new higher value */
763 if (uwep->unpaid)
764 alter_cost(uwep, 0L);
765 if (otyp != STRANGE_OBJECT)
766 makeknown(otyp);
767 if (multiple)
768 encumber_msg();
769 return 1;
770 } else if (uwep->otyp == CRYSKNIFE && amount < 0) {
771 multiple = (uwep->quan > 1L);
772 /* order matters: message, shop handling, transformation */
773 Your("%s %s much duller now.", simpleonames(uwep),
774 multiple ? "fuse, and become" : "is");
775 costly_alteration(uwep, COST_DEGRD); /* DECHNT? other? */
776 uwep->otyp = WORM_TOOTH;
777 uwep->oerodeproof = 0;
778 if (multiple) {
779 uwep->quan = 1L;
780 uwep->owt = weight(uwep);
782 if (otyp != STRANGE_OBJECT && otmp->bknown)
783 makeknown(otyp);
784 if (multiple)
785 encumber_msg();
786 return 1;
789 if (has_oname(uwep))
790 wepname = ONAME(uwep);
791 if (amount < 0 && uwep->oartifact && restrict_name(uwep, wepname)) {
792 if (!Blind)
793 pline("%s %s.", Yobjnam2(uwep, "faintly glow"), color);
794 return 1;
796 /* there is a (soft) upper and lower limit to uwep->spe */
797 if (((uwep->spe > 5 && amount >= 0) || (uwep->spe < -5 && amount < 0))
798 && rn2(3)) {
799 if (!Blind)
800 pline("%s %s for a while and then %s.",
801 Yobjnam2(uwep, "violently glow"), color,
802 otense(uwep, "evaporate"));
803 else
804 pline("%s.", Yobjnam2(uwep, "evaporate"));
806 useupall(uwep); /* let all of them disappear */
807 return 1;
809 if (!Blind) {
810 xtime = (amount * amount == 1) ? "moment" : "while";
811 pline("%s %s for a %s.",
812 Yobjnam2(uwep, amount == 0 ? "violently glow" : "glow"), color,
813 xtime);
814 if (otyp != STRANGE_OBJECT && uwep->known
815 && (amount > 0 || (amount < 0 && otmp->bknown)))
816 makeknown(otyp);
818 if (amount < 0)
819 costly_alteration(uwep, COST_DECHNT);
820 uwep->spe += amount;
821 if (amount > 0) {
822 if (uwep->cursed)
823 uncurse(uwep);
824 /* update shop bill to reflect new higher price */
825 if (uwep->unpaid)
826 alter_cost(uwep, 0L);
830 * Enchantment, which normally improves a weapon, has an
831 * addition adverse reaction on Magicbane whose effects are
832 * spe dependent. Give an obscure clue here.
834 if (uwep->oartifact == ART_MAGICBANE && uwep->spe >= 0) {
835 Your("right %s %sches!", body_part(HAND),
836 (((amount > 1) && (uwep->spe > 1)) ? "flin" : "it"));
839 /* an elven magic clue, cookie@keebler */
840 /* elven weapons vibrate warningly when enchanted beyond a limit */
841 if ((uwep->spe > 5)
842 && (is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)))
843 pline("%s unexpectedly.", Yobjnam2(uwep, "suddenly vibrate"));
845 return 1;
849 welded(obj)
850 register struct obj *obj;
852 if (obj && obj == uwep && will_weld(obj)) {
853 obj->bknown = TRUE;
854 return 1;
856 return 0;
859 void
860 weldmsg(obj)
861 register struct obj *obj;
863 long savewornmask;
865 savewornmask = obj->owornmask;
866 pline("%s welded to your %s!", Yobjnam2(obj, "are"),
867 bimanual(obj) ? (const char *) makeplural(body_part(HAND))
868 : body_part(HAND));
869 obj->owornmask = savewornmask;
872 /* test whether monster's wielded weapon is stuck to hand/paw/whatever */
873 boolean
874 mwelded(obj)
875 struct obj *obj;
877 /* caller is responsible for making sure this is a monster's item */
878 if (obj && (obj->owornmask & W_WEP) && will_weld(obj))
879 return TRUE;
880 return FALSE;
883 /*wield.c*/