OSDN Git Service

bcf4de343a127c058730f53fbfc77a85eea19e78
[jnethack/source.git] / src / weapon.c
1 /* NetHack 3.6  weapon.c        $NHDT-Date: 1559998716 2019/06/08 12:58:36 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.70 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2022            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 /*
12  *      This module contains code for calculation of "to hit" and damage
13  *      bonuses for any given weapon used, as well as weapons selection
14  *      code for monsters.
15  */
16
17 #include "hack.h"
18
19 STATIC_DCL void FDECL(give_may_advance_msg, (int));
20 STATIC_DCL boolean FDECL(could_advance, (int));
21 STATIC_DCL boolean FDECL(peaked_skill, (int));
22 STATIC_DCL int FDECL(slots_required, (int));
23 STATIC_DCL void FDECL(skill_advance, (int));
24
25 /* Categories whose names don't come from OBJ_NAME(objects[type])
26  */
27 #define PN_BARE_HANDED (-1) /* includes martial arts */
28 #define PN_TWO_WEAPONS (-2)
29 #define PN_RIDING (-3)
30 #define PN_POLEARMS (-4)
31 #define PN_SABER (-5)
32 #define PN_HAMMER (-6)
33 #define PN_WHIP (-7)
34 #define PN_ATTACK_SPELL (-8)
35 #define PN_HEALING_SPELL (-9)
36 #define PN_DIVINATION_SPELL (-10)
37 #define PN_ENCHANTMENT_SPELL (-11)
38 #define PN_CLERIC_SPELL (-12)
39 #define PN_ESCAPE_SPELL (-13)
40 #define PN_MATTER_SPELL (-14)
41
42 STATIC_VAR NEARDATA const short skill_names_indices[P_NUM_SKILLS] = {
43     0, DAGGER, KNIFE, AXE, PICK_AXE, SHORT_SWORD, BROADSWORD, LONG_SWORD,
44     TWO_HANDED_SWORD, SCIMITAR, PN_SABER, CLUB, MACE, MORNING_STAR, FLAIL,
45     PN_HAMMER, QUARTERSTAFF, PN_POLEARMS, SPEAR, TRIDENT, LANCE, BOW, SLING,
46     CROSSBOW, DART, SHURIKEN, BOOMERANG, PN_WHIP, UNICORN_HORN,
47     PN_ATTACK_SPELL, PN_HEALING_SPELL, PN_DIVINATION_SPELL,
48     PN_ENCHANTMENT_SPELL, PN_CLERIC_SPELL, PN_ESCAPE_SPELL, PN_MATTER_SPELL,
49     PN_BARE_HANDED, PN_TWO_WEAPONS, PN_RIDING
50 };
51
52 /* note: entry [0] isn't used */
53 STATIC_VAR NEARDATA const char *const odd_skill_names[] = {
54 #if 0 /*JP:T*/
55     "no skill", "bare hands", /* use barehands_or_martial[] instead */
56     "two weapon combat", "riding", "polearms", "saber", "hammer", "whip",
57     "attack spells", "healing spells", "divination spells",
58     "enchantment spells", "clerical spells", "escape spells", "matter spells",
59 #else
60     "no skill", "\91f\8eè", /* use barehands_or_martial[] instead */
61     "\93ñ\93\81\97¬", "\8bR\8fæ", "\92·\95\80", "\83T\81[\83x\83\8b", "\83n\83\93\83}\81[", "\95Ú",
62     "\8dU\8c\82", "\8e¡\96ü", "\97\\92m",
63     "\95â\8f\95", "\91m\97µ", "\92E\8fo", "\95¨\8e¿",
64 #endif
65 };
66 /* indexed vis `is_martial() */
67 STATIC_VAR NEARDATA const char *const barehands_or_martial[] = {
68 #if 0 /*JP:T*/
69     "bare handed combat", "martial arts"
70 #else
71     "\91f\8eè", "\91Ì\8fp"
72 #endif
73 };
74
75 #define P_NAME(type)                                    \
76     ((skill_names_indices[type] > 0)                    \
77          ? OBJ_NAME(objects[skill_names_indices[type]]) \
78          : (type == P_BARE_HANDED_COMBAT)               \
79                ? barehands_or_martial[martial_bonus()]  \
80                : odd_skill_names[-skill_names_indices[type]])
81
82 static NEARDATA const char kebabable[] = { S_XORN, S_DRAGON, S_JABBERWOCK,
83                                            S_NAGA, S_GIANT,  '\0' };
84
85 STATIC_OVL void
86 give_may_advance_msg(skill)
87 int skill;
88 {
89 #if 0 /*JP:T*/
90     You_feel("more confident in your %sskills.",
91              (skill == P_NONE) ? ""
92                  : (skill <= P_LAST_WEAPON) ? "weapon "
93                      : (skill <= P_LAST_SPELL) ? "spell casting "
94                          : "fighting ");
95 #else
96     You("%s\83X\83L\83\8b\82ð\8d\82\82ß\82é\8e©\90M\82ª\97N\82¢\82Ä\82«\82½\81D",
97         (skill == P_NONE) ? ""
98             : (skill <= P_LAST_WEAPON) ? "\95\90\8aí\82Ì"
99                 : (skill <= P_LAST_SPELL) ? "\96\82\96@\82Ì"
100                     : "\90í\82¢\82Ì");
101 #endif
102 }
103
104 /* weapon's skill category name for use as generalized description of weapon;
105    mostly used to shorten "you drop your <weapon>" messages when slippery
106    fingers or polymorph causes hero to involuntarily drop wielded weapon(s) */
107 const char *
108 weapon_descr(obj)
109 struct obj *obj;
110 {
111     int skill = weapon_type(obj);
112     const char *descr = P_NAME(skill);
113
114     /* assorted special cases */
115     switch (skill) {
116     case P_NONE:
117         /* not a weapon or weptool: use item class name;
118            override class name "food" for corpses, tins, and eggs,
119            "large rock" for statues and boulders, and "tool" for towels */
120         descr = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG
121                  || obj->otyp == STATUE || obj->otyp == BOULDER
122                  || obj->otyp == TOWEL)
123                     ? OBJ_NAME(objects[obj->otyp])
124                     : def_oc_syms[(int) obj->oclass].name;
125         break;
126     case P_SLING:
127         if (is_ammo(obj))
128             descr = (obj->otyp == ROCK || is_graystone(obj))
129 /*JP
130                         ? "stone"
131 */
132                         ? "\90Î"
133                         /* avoid "rock"; what about known glass? */
134                         : (obj->oclass == GEM_CLASS)
135 /*JP
136                             ? "gem"
137 */
138                             ? "\95ó\90Î"
139                             /* in case somebody adds odd sling ammo */
140                             : def_oc_syms[(int) obj->oclass].name;
141         break;
142     case P_BOW:
143         if (is_ammo(obj))
144 /*JP
145             descr = "arrow";
146 */
147             descr = "\96î";
148         break;
149     case P_CROSSBOW:
150         if (is_ammo(obj))
151 /*JP
152             descr = "bolt";
153 */
154             descr = "\83{\83\8b\83g";
155         break;
156     case P_FLAIL:
157         if (obj->otyp == GRAPPLING_HOOK)
158 /*JP
159             descr = "hook";
160 */
161             descr = "\83t\83b\83N";
162         break;
163     case P_PICK_AXE:
164         /* even if "dwarvish mattock" hasn't been discovered yet */
165         if (obj->otyp == DWARVISH_MATTOCK)
166 /*JP
167             descr = "mattock";
168 */
169             descr = "\82Â\82é\82Í\82µ";
170         break;
171     default:
172         break;
173     }
174     return makesingular(descr);
175 }
176
177 /*
178  *      hitval returns an integer representing the "to hit" bonuses
179  *      of "otmp" against the monster.
180  */
181 int
182 hitval(otmp, mon)
183 struct obj *otmp;
184 struct monst *mon;
185 {
186     int tmp = 0;
187     struct permonst *ptr = mon->data;
188     boolean Is_weapon = (otmp->oclass == WEAPON_CLASS || is_weptool(otmp));
189
190     if (Is_weapon)
191         tmp += otmp->spe;
192
193     /* Put weapon specific "to hit" bonuses in below: */
194     tmp += objects[otmp->otyp].oc_hitbon;
195
196     /* Put weapon vs. monster type "to hit" bonuses in below: */
197
198     /* Blessed weapons used against undead or demons */
199     if (Is_weapon && otmp->blessed
200         && (is_demon(ptr) || is_undead(ptr) || is_vampshifter(mon)))
201         tmp += 2;
202
203     if (is_spear(otmp) && index(kebabable, ptr->mlet))
204         tmp += 2;
205
206     /* trident is highly effective against swimmers */
207     if (otmp->otyp == TRIDENT && is_swimmer(ptr)) {
208         if (is_pool(mon->mx, mon->my))
209             tmp += 4;
210         else if (ptr->mlet == S_EEL || ptr->mlet == S_SNAKE)
211             tmp += 2;
212     }
213
214     /* Picks used against xorns and earth elementals */
215     if (is_pick(otmp) && (passes_walls(ptr) && thick_skinned(ptr)))
216         tmp += 2;
217
218     /* Check specially named weapon "to hit" bonuses */
219     if (otmp->oartifact)
220         tmp += spec_abon(otmp, mon);
221
222     return tmp;
223 }
224
225 /* Historical note: The original versions of Hack used a range of damage
226  * which was similar to, but not identical to the damage used in Advanced
227  * Dungeons and Dragons.  I figured that since it was so close, I may as well
228  * make it exactly the same as AD&D, adding some more weapons in the process.
229  * This has the advantage that it is at least possible that the player would
230  * already know the damage of at least some of the weapons.  This was circa
231  * 1987 and I used the table from Unearthed Arcana until I got tired of typing
232  * them in (leading to something of an imbalance towards weapons early in
233  * alphabetical order).  The data structure still doesn't include fields that
234  * fully allow the appropriate damage to be described (there's no way to say
235  * 3d6 or 1d6+1) so we add on the extra damage in dmgval() if the weapon
236  * doesn't do an exact die of damage.
237  *
238  * Of course new weapons were added later in the development of Nethack.  No
239  * AD&D consistency was kept, but most of these don't exist in AD&D anyway.
240  *
241  * Second edition AD&D came out a few years later; luckily it used the same
242  * table.  As of this writing (1999), third edition is in progress but not
243  * released.  Let's see if the weapon table stays the same.  --KAA
244  * October 2000: It didn't.  Oh, well.
245  */
246
247 /*
248  *      dmgval returns an integer representing the damage bonuses
249  *      of "otmp" against the monster.
250  */
251 int
252 dmgval(otmp, mon)
253 struct obj *otmp;
254 struct monst *mon;
255 {
256     int tmp = 0, otyp = otmp->otyp;
257     struct permonst *ptr = mon->data;
258     boolean Is_weapon = (otmp->oclass == WEAPON_CLASS || is_weptool(otmp));
259
260     if (otyp == CREAM_PIE)
261         return 0;
262
263     if (bigmonst(ptr)) {
264         if (objects[otyp].oc_wldam)
265             tmp = rnd(objects[otyp].oc_wldam);
266         switch (otyp) {
267         case IRON_CHAIN:
268         case CROSSBOW_BOLT:
269         case MORNING_STAR:
270         case PARTISAN:
271         case RUNESWORD:
272         case ELVEN_BROADSWORD:
273         case BROADSWORD:
274             tmp++;
275             break;
276
277         case FLAIL:
278         case RANSEUR:
279         case VOULGE:
280             tmp += rnd(4);
281             break;
282
283         case ACID_VENOM:
284         case HALBERD:
285         case SPETUM:
286             tmp += rnd(6);
287             break;
288
289         case BATTLE_AXE:
290         case BARDICHE:
291         case TRIDENT:
292             tmp += d(2, 4);
293             break;
294
295         case TSURUGI:
296         case DWARVISH_MATTOCK:
297         case TWO_HANDED_SWORD:
298             tmp += d(2, 6);
299             break;
300         }
301     } else {
302         if (objects[otyp].oc_wsdam)
303             tmp = rnd(objects[otyp].oc_wsdam);
304         switch (otyp) {
305         case IRON_CHAIN:
306         case CROSSBOW_BOLT:
307         case MACE:
308         case WAR_HAMMER:
309         case FLAIL:
310         case SPETUM:
311         case TRIDENT:
312             tmp++;
313             break;
314
315         case BATTLE_AXE:
316         case BARDICHE:
317         case BILL_GUISARME:
318         case GUISARME:
319         case LUCERN_HAMMER:
320         case MORNING_STAR:
321         case RANSEUR:
322         case BROADSWORD:
323         case ELVEN_BROADSWORD:
324         case RUNESWORD:
325         case VOULGE:
326             tmp += rnd(4);
327             break;
328
329         case ACID_VENOM:
330             tmp += rnd(6);
331             break;
332         }
333     }
334     if (Is_weapon) {
335         tmp += otmp->spe;
336         /* negative enchantment mustn't produce negative damage */
337         if (tmp < 0)
338             tmp = 0;
339     }
340
341     if (objects[otyp].oc_material <= LEATHER && thick_skinned(ptr))
342         /* thick skinned/scaled creatures don't feel it */
343         tmp = 0;
344     if (ptr == &mons[PM_SHADE] && !shade_glare(otmp))
345         tmp = 0;
346
347     /* "very heavy iron ball"; weight increase is in increments */
348     if (otyp == HEAVY_IRON_BALL && tmp > 0) {
349         int wt = (int) objects[HEAVY_IRON_BALL].oc_weight;
350
351         if ((int) otmp->owt > wt) {
352             wt = ((int) otmp->owt - wt) / IRON_BALL_W_INCR;
353             tmp += rnd(4 * wt);
354             if (tmp > 25)
355                 tmp = 25; /* objects[].oc_wldam */
356         }
357     }
358
359     /* Put weapon vs. monster type damage bonuses in below: */
360     if (Is_weapon || otmp->oclass == GEM_CLASS || otmp->oclass == BALL_CLASS
361         || otmp->oclass == CHAIN_CLASS) {
362         int bonus = 0;
363
364         if (otmp->blessed
365             && (is_undead(ptr) || is_demon(ptr) || is_vampshifter(mon)))
366             bonus += rnd(4);
367         if (is_axe(otmp) && is_wooden(ptr))
368             bonus += rnd(4);
369         if (objects[otyp].oc_material == SILVER && mon_hates_silver(mon))
370             bonus += rnd(20);
371         if (artifact_light(otmp) && otmp->lamplit && hates_light(ptr))
372             bonus += rnd(8);
373
374         /* if the weapon is going to get a double damage bonus, adjust
375            this bonus so that effectively it's added after the doubling */
376         if (bonus > 1 && otmp->oartifact && spec_dbon(otmp, mon, 25) >= 25)
377             bonus = (bonus + 1) / 2;
378
379         tmp += bonus;
380     }
381
382     if (tmp > 0) {
383         /* It's debatable whether a rusted blunt instrument
384            should do less damage than a pristine one, since
385            it will hit with essentially the same impact, but
386            there ought to some penalty for using damaged gear
387            so always subtract erosion even for blunt weapons. */
388         tmp -= greatest_erosion(otmp);
389         if (tmp < 1)
390             tmp = 1;
391     }
392
393     return  tmp;
394 }
395
396 /* check whether blessed and/or silver damage applies for *non-weapon* hit;
397    return value is the amount of the extra damage */
398 int
399 special_dmgval(magr, mdef, armask, silverhit_p)
400 struct monst *magr, *mdef;
401 long armask; /* armor mask, multiple bits accepted for W_ARMC|W_ARM|W_ARMU
402               * or W_ARMG|W_RINGL|W_RINGR only */
403 long *silverhit_p; /* output flag mask for silver bonus */
404 {
405     struct obj *obj;
406     struct permonst *ptr = mdef->data;
407     boolean left_ring = (armask & W_RINGL) ? TRUE : FALSE,
408             right_ring = (armask & W_RINGR) ? TRUE : FALSE;
409     long silverhit = 0L;
410     int bonus = 0;
411
412     obj = 0;
413     if (armask & (W_ARMC | W_ARM | W_ARMU)) {
414         if ((armask & W_ARMC) != 0L
415             && (obj = which_armor(magr, W_ARMC)) != 0)
416             armask = W_ARMC;
417         else if ((armask & W_ARM) != 0L
418                  && (obj = which_armor(magr, W_ARM)) != 0)
419             armask = W_ARM;
420         else if ((armask & W_ARMU) != 0L
421                  && (obj = which_armor(magr, W_ARMU)) != 0)
422             armask = W_ARMU;
423         else
424             armask = 0L;
425     } else if (armask & (W_ARMG | W_RINGL | W_RINGR)) {
426         armask = ((obj = which_armor(magr, W_ARMG)) != 0) ?  W_ARMG : 0L;
427     } else {
428         obj = which_armor(magr, armask);
429     }
430
431     if (obj) {
432         if (obj->blessed
433             && (is_undead(ptr) || is_demon(ptr) || is_vampshifter(mdef)))
434             bonus += rnd(4);
435         /* the only silver armor is shield of reflection (silver dragon
436            scales refer to color, not material) and the only way to hit
437            with one--aside from throwing--is to wield it and perform a
438            weapon hit, but we include a general check here */
439         if (objects[obj->otyp].oc_material == SILVER
440             && mon_hates_silver(mdef)) {
441             bonus += rnd(20);
442             silverhit |= armask;
443         }
444
445     /* when no gloves we check for silver rings (blessed rings ignored) */
446     } else if ((left_ring || right_ring) && magr == &youmonst) {
447         if (left_ring && uleft) {
448             if (objects[uleft->otyp].oc_material == SILVER
449                 && mon_hates_silver(mdef)) {
450                 bonus += rnd(20);
451                 silverhit |= W_RINGL;
452             }
453         }
454         if (right_ring && uright) {
455             if (objects[uright->otyp].oc_material == SILVER
456                 && mon_hates_silver(mdef)) {
457                 /* two silver rings don't give double silver damage
458                    but 'silverhit' messages might be adjusted for them */
459                 if (!(silverhit & W_RINGL))
460                     bonus += rnd(20);
461                 silverhit |= W_RINGR;
462             }
463         }
464     }
465
466     if (silverhit_p)
467         *silverhit_p = silverhit;
468     return bonus;
469 }
470
471 /* give a "silver <item> sears <target>" message;
472    not used for weapon hit, so we only handle rings */
473 void
474 silver_sears(magr, mdef, silverhit)
475 struct monst *magr UNUSED;
476 struct monst *mdef;
477 long silverhit;
478 {
479 #if 0 /*JP*/
480     char rings[20]; /* plenty of room for "rings" */
481 #endif
482     int ltyp = ((uleft && (silverhit & W_RINGL) != 0L)
483                 ? uleft->otyp : STRANGE_OBJECT),
484         rtyp = ((uright && (silverhit & W_RINGR) != 0L)
485                 ? uright->otyp : STRANGE_OBJECT);
486     boolean both,
487         l_ag = (objects[ltyp].oc_material == SILVER && uleft->dknown),
488         r_ag = (objects[rtyp].oc_material == SILVER && uright->dknown);
489
490     if ((silverhit & (W_RINGL | W_RINGR)) != 0L) {
491         /* plural if both the same type (so not multi_claw and both rings
492            are non-Null) and either both known or neither known, or both
493            silver (in case there is ever more than one type of silver ring)
494            and both known; singular if multi_claw (where one of ltyp or
495            rtyp will always be STRANGE_OBJECT) even if both rings are known
496            silver [see hmonas(uhitm.c) for explanation of 'multi_claw'] */
497         both = ((ltyp == rtyp && uleft->dknown == uright->dknown)
498                 || (l_ag && r_ag));
499 #if 0 /*JP*/
500         Sprintf(rings, "ring%s", both ? "s" : "");
501         Your("%s%s %s %s!",
502              (l_ag || r_ag) ? "silver "
503              : both ? ""
504                : ((silverhit & W_RINGL) != 0L) ? "left "
505                  : "right ",
506              rings, vtense(rings, "sear"), mon_nam(mdef));
507 #else
508         Your("%s\8ew\97Ö\82ª%s\82ð\8fÄ\82¢\82½\81I",
509              (l_ag || r_ag) ? "\8bâ\82Ì"
510              : both ? ""
511                : ((silverhit & W_RINGL) != 0L) ? "\8d\82Ì"
512                  : "\89E\82Ì",
513              mon_nam(mdef));
514 #endif
515     }
516 }
517
518 STATIC_DCL struct obj *FDECL(oselect, (struct monst *, int));
519 #define Oselect(x)                      \
520     if ((otmp = oselect(mtmp, x)) != 0) \
521         return otmp;
522
523 STATIC_OVL struct obj *
524 oselect(mtmp, x)
525 struct monst *mtmp;
526 int x;
527 {
528     struct obj *otmp;
529
530     for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
531         if (otmp->otyp == x
532             /* never select non-cockatrice corpses */
533             && !((x == CORPSE || x == EGG)
534                  && !touch_petrifies(&mons[otmp->corpsenm]))
535             && (!otmp->oartifact || touch_artifact(otmp, mtmp)))
536             return otmp;
537     }
538     return (struct obj *) 0;
539 }
540
541 /* TODO: have monsters use aklys' throw-and-return */
542 static NEARDATA const int rwep[] = {
543     DWARVISH_SPEAR, SILVER_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, JAVELIN,
544     SHURIKEN, YA, SILVER_ARROW, ELVEN_ARROW, ARROW, ORCISH_ARROW,
545     CROSSBOW_BOLT, SILVER_DAGGER, ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, KNIFE,
546     FLINT, ROCK, LOADSTONE, LUCKSTONE, DART,
547     /* BOOMERANG, */ CREAM_PIE
548 };
549
550 static NEARDATA const int pwep[] = { HALBERD,       BARDICHE, SPETUM,
551                                      BILL_GUISARME, VOULGE,   RANSEUR,
552                                      GUISARME,      GLAIVE,   LUCERN_HAMMER,
553                                      BEC_DE_CORBIN, FAUCHARD, PARTISAN,
554                                      LANCE };
555
556 static struct obj *propellor;
557
558 /* select a ranged weapon for the monster */
559 struct obj *
560 select_rwep(mtmp)
561 register struct monst *mtmp;
562 {
563     register struct obj *otmp;
564     struct obj *mwep;
565     boolean mweponly;
566     int i;
567
568     char mlet = mtmp->data->mlet;
569
570     propellor = (struct obj *) &zeroobj;
571     Oselect(EGG);      /* cockatrice egg */
572     if (mlet == S_KOP) /* pies are first choice for Kops */
573         Oselect(CREAM_PIE);
574     if (throws_rocks(mtmp->data)) /* ...boulders for giants */
575         Oselect(BOULDER);
576
577     /* Select polearms first; they do more damage and aren't expendable.
578        But don't pick one if monster's weapon is welded, because then
579        we'd never have a chance to throw non-wielding missiles. */
580     /* The limit of 13 here is based on the monster polearm range limit
581      * (defined as 5 in mthrowu.c).  5 corresponds to a distance of 2 in
582      * one direction and 1 in another; one space beyond that would be 3 in
583      * one direction and 2 in another; 3^2+2^2=13.
584      */
585     mwep = MON_WEP(mtmp);
586     /* NO_WEAPON_WANTED means we already tried to wield and failed */
587     mweponly = (mwelded(mwep) && mtmp->weapon_check == NO_WEAPON_WANTED);
588     if (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 13
589         && couldsee(mtmp->mx, mtmp->my)) {
590         for (i = 0; i < SIZE(pwep); i++) {
591             /* Only strong monsters can wield big (esp. long) weapons.
592              * Big weapon is basically the same as bimanual.
593              * All monsters can wield the remaining weapons.
594              */
595             if (((strongmonst(mtmp->data)
596                   && (mtmp->misc_worn_check & W_ARMS) == 0)
597                  || !objects[pwep[i]].oc_bimanual)
598                 && (objects[pwep[i]].oc_material != SILVER
599                     || !mon_hates_silver(mtmp))) {
600                 if ((otmp = oselect(mtmp, pwep[i])) != 0
601                     && (otmp == mwep || !mweponly)) {
602                     propellor = otmp; /* force the monster to wield it */
603                     return otmp;
604                 }
605             }
606         }
607     }
608
609     /*
610      * other than these two specific cases, always select the
611      * most potent ranged weapon to hand.
612      */
613     for (i = 0; i < SIZE(rwep); i++) {
614         int prop;
615
616         /* shooting gems from slings; this goes just before the darts */
617         /* (shooting rocks is already handled via the rwep[] ordering) */
618         if (rwep[i] == DART && !likes_gems(mtmp->data)
619             && m_carrying(mtmp, SLING)) { /* propellor */
620             for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
621                 if (otmp->oclass == GEM_CLASS
622                     && (otmp->otyp != LOADSTONE || !otmp->cursed)) {
623                     propellor = m_carrying(mtmp, SLING);
624                     return otmp;
625                 }
626         }
627
628         /* KMH -- This belongs here so darts will work */
629         propellor = (struct obj *) &zeroobj;
630
631         prop = objects[rwep[i]].oc_skill;
632         if (prop < 0) {
633             switch (-prop) {
634             case P_BOW:
635                 propellor = oselect(mtmp, YUMI);
636                 if (!propellor)
637                     propellor = oselect(mtmp, ELVEN_BOW);
638                 if (!propellor)
639                     propellor = oselect(mtmp, BOW);
640                 if (!propellor)
641                     propellor = oselect(mtmp, ORCISH_BOW);
642                 break;
643             case P_SLING:
644                 propellor = oselect(mtmp, SLING);
645                 break;
646             case P_CROSSBOW:
647                 propellor = oselect(mtmp, CROSSBOW);
648             }
649             if ((otmp = MON_WEP(mtmp)) && mwelded(otmp) && otmp != propellor
650                 && mtmp->weapon_check == NO_WEAPON_WANTED)
651                 propellor = 0;
652         }
653         /* propellor = obj, propellor to use
654          * propellor = &zeroobj, doesn't need a propellor
655          * propellor = 0, needed one and didn't have one
656          */
657         if (propellor != 0) {
658             /* Note: cannot use m_carrying for loadstones, since it will
659              * always select the first object of a type, and maybe the
660              * monster is carrying two but only the first is unthrowable.
661              */
662             if (rwep[i] != LOADSTONE) {
663                 /* Don't throw a cursed weapon-in-hand or an artifact */
664                 if ((otmp = oselect(mtmp, rwep[i])) && !otmp->oartifact
665                     && !(otmp == MON_WEP(mtmp) && mwelded(otmp)))
666                     return otmp;
667             } else
668                 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
669                     if (otmp->otyp == LOADSTONE && !otmp->cursed)
670                         return otmp;
671                 }
672         }
673     }
674
675     /* failure */
676     return (struct obj *) 0;
677 }
678
679 /* is 'obj' a type of weapon that any monster knows how to throw? */
680 boolean
681 monmightthrowwep(obj)
682 struct obj *obj;
683 {
684     short idx;
685
686     for (idx = 0; idx < SIZE(rwep); ++idx)
687         if (obj->otyp == rwep[idx])
688             return TRUE;
689     return FALSE;
690 }
691
692 /* Weapons in order of preference */
693 static const NEARDATA short hwep[] = {
694     CORPSE, /* cockatrice corpse */
695     TSURUGI, RUNESWORD, DWARVISH_MATTOCK, TWO_HANDED_SWORD, BATTLE_AXE,
696     KATANA, UNICORN_HORN, CRYSKNIFE, TRIDENT, LONG_SWORD, ELVEN_BROADSWORD,
697     BROADSWORD, SCIMITAR, SILVER_SABER, MORNING_STAR, ELVEN_SHORT_SWORD,
698     DWARVISH_SHORT_SWORD, SHORT_SWORD, ORCISH_SHORT_SWORD, MACE, AXE,
699     DWARVISH_SPEAR, SILVER_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, FLAIL,
700     BULLWHIP, QUARTERSTAFF, JAVELIN, AKLYS, CLUB, PICK_AXE, RUBBER_HOSE,
701     WAR_HAMMER, SILVER_DAGGER, ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, ATHAME,
702     SCALPEL, KNIFE, WORM_TOOTH
703 };
704
705 /* select a hand to hand weapon for the monster */
706 struct obj *
707 select_hwep(mtmp)
708 register struct monst *mtmp;
709 {
710     register struct obj *otmp;
711     register int i;
712     boolean strong = strongmonst(mtmp->data);
713     boolean wearing_shield = (mtmp->misc_worn_check & W_ARMS) != 0;
714
715     /* prefer artifacts to everything else */
716     for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
717         if (otmp->oclass == WEAPON_CLASS && otmp->oartifact
718             && touch_artifact(otmp, mtmp)
719             && ((strong && !wearing_shield)
720                 || !objects[otmp->otyp].oc_bimanual))
721             return otmp;
722     }
723
724     if (is_giant(mtmp->data)) /* giants just love to use clubs */
725         Oselect(CLUB);
726
727     /* only strong monsters can wield big (esp. long) weapons */
728     /* big weapon is basically the same as bimanual */
729     /* all monsters can wield the remaining weapons */
730     for (i = 0; i < SIZE(hwep); i++) {
731         if (hwep[i] == CORPSE && !(mtmp->misc_worn_check & W_ARMG)
732             && !resists_ston(mtmp))
733             continue;
734         if (((strong && !wearing_shield) || !objects[hwep[i]].oc_bimanual)
735             && (objects[hwep[i]].oc_material != SILVER
736                 || !mon_hates_silver(mtmp)))
737             Oselect(hwep[i]);
738     }
739
740     /* failure */
741     return (struct obj *) 0;
742 }
743
744 /* Called after polymorphing a monster, robbing it, etc....  Monsters
745  * otherwise never unwield stuff on their own.  Might print message.
746  */
747 void
748 possibly_unwield(mon, polyspot)
749 struct monst *mon;
750 boolean polyspot;
751 {
752     struct obj *obj, *mw_tmp;
753
754     if (!(mw_tmp = MON_WEP(mon)))
755         return;
756     for (obj = mon->minvent; obj; obj = obj->nobj)
757         if (obj == mw_tmp)
758             break;
759     if (!obj) { /* The weapon was stolen or destroyed */
760         MON_NOWEP(mon);
761         mon->weapon_check = NEED_WEAPON;
762         return;
763     }
764     if (!attacktype(mon->data, AT_WEAP)) {
765         setmnotwielded(mon, mw_tmp);
766         mon->weapon_check = NO_WEAPON_WANTED;
767         obj_extract_self(obj);
768         if (cansee(mon->mx, mon->my)) {
769 /*JP
770             pline("%s drops %s.", Monnam(mon), distant_name(obj, doname));
771 */
772             pline("%s\82Í%s\82ð\92u\82¢\82½\81D", Monnam(mon), distant_name(obj, doname));
773             newsym(mon->mx, mon->my);
774         }
775         /* might be dropping object into water or lava */
776 /*JP
777         if (!flooreffects(obj, mon->mx, mon->my, "drop")) {
778 */
779         if (!flooreffects(obj, mon->mx, mon->my, "\97\8e\82¿\82é")) {
780             if (polyspot)
781                 bypass_obj(obj);
782             place_object(obj, mon->mx, mon->my);
783             stackobj(obj);
784         }
785         return;
786     }
787     /* The remaining case where there is a change is where a monster
788      * is polymorphed into a stronger/weaker monster with a different
789      * choice of weapons.  This has no parallel for players.  It can
790      * be handled by waiting until mon_wield_item is actually called.
791      * Though the monster still wields the wrong weapon until then,
792      * this is OK since the player can't see it.  (FIXME: Not okay since
793      * probing can reveal it.)
794      * Note that if there is no change, setting the check to NEED_WEAPON
795      * is harmless.
796      * Possible problem: big monster with big cursed weapon gets
797      * polymorphed into little monster.  But it's not quite clear how to
798      * handle this anyway....
799      */
800     if (!(mwelded(mw_tmp) && mon->weapon_check == NO_WEAPON_WANTED))
801         mon->weapon_check = NEED_WEAPON;
802     return;
803 }
804
805 /* Let a monster try to wield a weapon, based on mon->weapon_check.
806  * Returns 1 if the monster took time to do it, 0 if it did not.
807  */
808 int
809 mon_wield_item(mon)
810 register struct monst *mon;
811 {
812     struct obj *obj;
813
814     /* This case actually should never happen */
815     if (mon->weapon_check == NO_WEAPON_WANTED)
816         return 0;
817     switch (mon->weapon_check) {
818     case NEED_HTH_WEAPON:
819         obj = select_hwep(mon);
820         break;
821     case NEED_RANGED_WEAPON:
822         (void) select_rwep(mon);
823         obj = propellor;
824         break;
825     case NEED_PICK_AXE:
826         obj = m_carrying(mon, PICK_AXE);
827         /* KMH -- allow other picks */
828         if (!obj && !which_armor(mon, W_ARMS))
829             obj = m_carrying(mon, DWARVISH_MATTOCK);
830         break;
831     case NEED_AXE:
832         /* currently, only 2 types of axe */
833         obj = m_carrying(mon, BATTLE_AXE);
834         if (!obj || which_armor(mon, W_ARMS))
835             obj = m_carrying(mon, AXE);
836         break;
837     case NEED_PICK_OR_AXE:
838         /* prefer pick for fewer switches on most levels */
839         obj = m_carrying(mon, DWARVISH_MATTOCK);
840         if (!obj)
841             obj = m_carrying(mon, BATTLE_AXE);
842         if (!obj || which_armor(mon, W_ARMS)) {
843             obj = m_carrying(mon, PICK_AXE);
844             if (!obj)
845                 obj = m_carrying(mon, AXE);
846         }
847         break;
848     default:
849         impossible("weapon_check %d for %s?", mon->weapon_check,
850                    mon_nam(mon));
851         return 0;
852     }
853     if (obj && obj != &zeroobj) {
854         struct obj *mw_tmp = MON_WEP(mon);
855
856         if (mw_tmp && mw_tmp->otyp == obj->otyp) {
857             /* already wielding it */
858             mon->weapon_check = NEED_WEAPON;
859             return 0;
860         }
861         /* Actually, this isn't necessary--as soon as the monster
862          * wields the weapon, the weapon welds itself, so the monster
863          * can know it's cursed and needn't even bother trying.
864          * Still....
865          */
866         if (mw_tmp && mwelded(mw_tmp)) {
867             if (canseemon(mon)) {
868 #if 0 /*JP*/
869                 char welded_buf[BUFSZ];
870 #endif
871                 const char *mon_hand = mbodypart(mon, HAND);
872
873                 if (bimanual(mw_tmp))
874                     mon_hand = makeplural(mon_hand);
875 #if 0 /*JP*/
876                 Sprintf(welded_buf, "%s welded to %s %s",
877                         otense(mw_tmp, "are"), mhis(mon), mon_hand);
878 #endif
879
880                 if (obj->otyp == PICK_AXE) {
881 #if 0 /*JP*/
882                     pline("Since %s weapon%s %s,", s_suffix(mon_nam(mon)),
883                           plur(mw_tmp->quan), welded_buf);
884 #else
885                     pline("%s\82Í\95\90\8aí\82ð\8eè\82É\82µ\82æ\82¤\82Æ\82µ\82½\82ª\81C", mon_nam(mon));
886 #endif
887 #if 0 /*JP:T*/
888                     pline("%s cannot wield that %s.", mon_nam(mon),
889                           xname(obj));
890 #else
891                     pline("%s\82Í%s\82ð\91\95\94õ\82Å\82«\82È\82©\82Á\82½\81D", mon_nam(mon),
892                           xname(obj));
893 #endif
894                 } else {
895 /*JP
896                     pline("%s tries to wield %s.", Monnam(mon), doname(obj));
897 */
898                     pline("%s\82Í%s\82ð\91\95\94õ\82µ\82æ\82¤\82Æ\82µ\82½\81D", Monnam(mon), doname(obj));
899 /*JP
900                     pline("%s %s!", Yname2(mw_tmp), welded_buf);
901 */
902                     pline("%s\82Í%s\82ð\8eè\82É\82µ\82½\81I", Monnam(mon), xname(mw_tmp));
903                 }
904                 mw_tmp->bknown = 1;
905             }
906             mon->weapon_check = NO_WEAPON_WANTED;
907             return 1;
908         }
909         mon->mw = obj; /* wield obj */
910         setmnotwielded(mon, mw_tmp);
911         mon->weapon_check = NEED_WEAPON;
912         if (canseemon(mon)) {
913             boolean newly_welded;
914
915 /*JP
916             pline("%s wields %s!", Monnam(mon), doname(obj));
917 */
918             pline("%s\82Í%s\82ð\91\95\94õ\82µ\82½\81I", Monnam(mon), doname(obj));
919             /* 3.6.3: mwelded() predicate expects the object to have its
920                W_WEP bit set in owormmask, but the pline here and for
921                artifact_light don't want that because they'd have '(weapon
922                in hand/claw)' appended; so we set it for the mwelded test
923                and then clear it, until finally setting it for good below */
924             obj->owornmask |= W_WEP;
925             newly_welded = mwelded(obj);
926             obj->owornmask &= ~W_WEP;
927             if (newly_welded) {
928                 const char *mon_hand = mbodypart(mon, HAND);
929
930                 if (bimanual(obj))
931                     mon_hand = makeplural(mon_hand);
932 #if 0 /*JP:T*/
933                 pline("%s %s to %s %s!", Tobjnam(obj, "weld"),
934                       is_plural(obj) ? "themselves" : "itself",
935                       s_suffix(mon_nam(mon)), mon_hand);
936 #else
937                 pline("%s\82Í\8f\9f\8eè\82É%s\82Ì%s\82É\91\95\94õ\82³\82ê\82½\81I",
938                       xname(obj),
939                       mon_nam(mon), mon_hand);
940 #endif
941                 obj->bknown = 1;
942             }
943         }
944         if (artifact_light(obj) && !obj->lamplit) {
945             begin_burn(obj, FALSE);
946             if (canseemon(mon))
947 #if 0 /*JP:T*/
948                 pline("%s %s in %s %s!", Tobjnam(obj, "shine"),
949                       arti_light_description(obj), s_suffix(mon_nam(mon)),
950                       mbodypart(mon, HAND));
951 #else
952                 pline("%s\82Í%s\82Ì%s\82Ì\92\86\82Å%s\8bP\82¢\82½\81I",
953                       xname(obj), mon_nam(mon),
954                       mbodypart(mon, HAND), arti_light_description(obj));
955 #endif
956             /* 3.6.3: artifact might be getting wielded by invisible monst */
957             else if (cansee(mon->mx, mon->my))
958 #if 0 /*JP*/
959                 pline("Light begins shining %s.",
960                       (distu(mon->mx, mon->my) <= 5 * 5)
961                           ? "nearby"
962                           : "in the distance");
963 #else
964                 pline("\96¾\82©\82è\82ª%s\82Å\8bP\82«\82Í\82\82ß\82½\81D",
965                       (distu(mon->mx, mon->my) <= 5 * 5)
966                           ? "\8bß\82­"
967                           : "\89\93\82­");
968 #endif
969         }
970         obj->owornmask = W_WEP;
971         return 1;
972     }
973     mon->weapon_check = NEED_WEAPON;
974     return 0;
975 }
976
977 /* force monster to stop wielding current weapon, if any */
978 void
979 mwepgone(mon)
980 struct monst *mon;
981 {
982     struct obj *mwep = MON_WEP(mon);
983
984     if (mwep) {
985         setmnotwielded(mon, mwep);
986         mon->weapon_check = NEED_WEAPON;
987     }
988 }
989
990 /* attack bonus for strength & dexterity */
991 int
992 abon()
993 {
994     int sbon;
995     int str = ACURR(A_STR), dex = ACURR(A_DEX);
996
997     if (Upolyd)
998         return (adj_lev(&mons[u.umonnum]) - 3);
999     if (str < 6)
1000         sbon = -2;
1001     else if (str < 8)
1002         sbon = -1;
1003     else if (str < 17)
1004         sbon = 0;
1005     else if (str <= STR18(50))
1006         sbon = 1; /* up to 18/50 */
1007     else if (str < STR18(100))
1008         sbon = 2;
1009     else
1010         sbon = 3;
1011
1012     /* Game tuning kludge: make it a bit easier for a low level character to
1013      * hit */
1014     sbon += (u.ulevel < 3) ? 1 : 0;
1015
1016     if (dex < 4)
1017         return (sbon - 3);
1018     else if (dex < 6)
1019         return (sbon - 2);
1020     else if (dex < 8)
1021         return (sbon - 1);
1022     else if (dex < 14)
1023         return sbon;
1024     else
1025         return (sbon + dex - 14);
1026 }
1027
1028 /* damage bonus for strength */
1029 int
1030 dbon()
1031 {
1032     int str = ACURR(A_STR);
1033
1034     if (Upolyd)
1035         return 0;
1036
1037     if (str < 6)
1038         return -1;
1039     else if (str < 16)
1040         return 0;
1041     else if (str < 18)
1042         return 1;
1043     else if (str == 18)
1044         return 2; /* up to 18 */
1045     else if (str <= STR18(75))
1046         return 3; /* up to 18/75 */
1047     else if (str <= STR18(90))
1048         return 4; /* up to 18/90 */
1049     else if (str < STR18(100))
1050         return 5; /* up to 18/99 */
1051     else
1052         return 6;
1053 }
1054
1055 /* increase a towel's wetness */
1056 void
1057 wet_a_towel(obj, amt, verbose)
1058 struct obj *obj;
1059 int amt; /* positive: new value; negative: increment by -amt; zero: no-op */
1060 boolean verbose;
1061 {
1062     int newspe = (amt <= 0) ? obj->spe - amt : amt;
1063
1064     /* new state is only reported if it's an increase */
1065     if (newspe > obj->spe) {
1066         if (verbose) {
1067 #if 0 /*JP:T*/
1068             const char *wetness = (newspe < 3)
1069                                      ? (!obj->spe ? "damp" : "damper")
1070                                      : (!obj->spe ? "wet" : "wetter");
1071 #else
1072             const char *wetness = (newspe < 3)
1073                                      ? (!obj->spe ? "\8e¼\82Á\82½" : "\82³\82ç\82É\8e¼\82Á\82½")
1074                                      : (!obj->spe ? "\94G\82ê\82½" : "\82³\82ç\82É\94G\82ê\82½");
1075 #endif
1076
1077             if (carried(obj))
1078 #if 0 /*JP:T*/
1079                 pline("%s gets %s.", Yobjnam2(obj, (const char *) 0),
1080                       wetness);
1081 #else
1082                 pline("%s\82Í%s\81D", Yobjnam2(obj, (const char *) 0),
1083                       wetness);
1084 #endif
1085             else if (mcarried(obj) && canseemon(obj->ocarry))
1086 #if 0 /*JP:T*/
1087                 pline("%s %s gets %s.", s_suffix(Monnam(obj->ocarry)),
1088                       xname(obj), wetness);
1089 #else
1090                 pline("%s\82Ì%s\82Í%s\81D", Monnam(obj->ocarry),
1091                       xname(obj), wetness);
1092 #endif
1093         }
1094     }
1095     obj->spe = min(newspe, 7);
1096
1097     /* if hero is wielding this towel, don't give "you begin bashing
1098        with your wet towel" message on next attack with it */
1099     if (obj == uwep)
1100         unweapon = !is_wet_towel(obj);
1101 }
1102
1103 /* decrease a towel's wetness */
1104 void
1105 dry_a_towel(obj, amt, verbose)
1106 struct obj *obj;
1107 int amt; /* positive: new value; negative: decrement by -amt; zero: no-op */
1108 boolean verbose;
1109 {
1110     int newspe = (amt <= 0) ? obj->spe + amt : amt;
1111
1112     /* new state is only reported if it's a decrease */
1113     if (newspe < obj->spe) {
1114         if (verbose) {
1115             if (carried(obj))
1116 #if 0 /*JP:T*/
1117                 pline("%s dries%s.", Yobjnam2(obj, (const char *) 0),
1118                       !newspe ? " out" : "");
1119 #else
1120                 pline("%s\82Í%s\81D", Yobjnam2(obj, (const char *) 0),
1121                       !newspe ? "\8a£\82«\82«\82Á\82½" : "\8a£\82¢\82½");
1122 #endif
1123             else if (mcarried(obj) && canseemon(obj->ocarry))
1124 #if 0 /*JP:T*/
1125                 pline("%s %s drie%s.", s_suffix(Monnam(obj->ocarry)),
1126                       xname(obj), !newspe ? " out" : "");
1127 #else
1128                 pline("%s\82Ì%s\82Í%s\81D", Monnam(obj->ocarry),
1129                       xname(obj), !newspe ? "\8a£\82«\82«\82Á\82½" : "\8a£\82¢\82½");
1130 #endif
1131         }
1132     }
1133     newspe = min(newspe, 7);
1134     obj->spe = max(newspe, 0);
1135
1136     /* if hero is wielding this towel and it is now dry, give "you begin
1137        bashing with your towel" message on next attack with it */
1138     if (obj == uwep)
1139         unweapon = !is_wet_towel(obj);
1140 }
1141
1142 /* copy the skill level name into the given buffer */
1143 char *
1144 skill_level_name(skill, buf)
1145 int skill;
1146 char *buf;
1147 {
1148     const char *ptr;
1149
1150     switch (P_SKILL(skill)) {
1151     case P_UNSKILLED:
1152 /*JP
1153         ptr = "Unskilled";
1154 */
1155         ptr = "\8f\89\90S\8eÒ";
1156         break;
1157     case P_BASIC:
1158 /*JP
1159         ptr = "Basic";
1160 */
1161         ptr = "\93ü\96å\8eÒ";
1162         break;
1163     case P_SKILLED:
1164 /*JP
1165         ptr = "Skilled";
1166 */
1167         ptr = "\8fn\97û\8eÒ";
1168         break;
1169     case P_EXPERT:
1170 /*JP
1171         ptr = "Expert";
1172 */
1173         ptr = "\83G\83L\83X\83p\81[\83g";
1174         break;
1175     /* these are for unarmed combat/martial arts only */
1176     case P_MASTER:
1177 /*JP
1178         ptr = "Master";
1179 */
1180         ptr = "\83}\83X\83^\81[";
1181         break;
1182     case P_GRAND_MASTER:
1183 /*JP
1184         ptr = "Grand Master";
1185 */
1186         ptr = "\83O\83\89\83\93\83h\83}\83X\83^\81[";
1187         break;
1188     default:
1189 /*JP
1190         ptr = "Unknown";
1191 */
1192         ptr = "\95s\96¾";
1193         break;
1194     }
1195     Strcpy(buf, ptr);
1196     return buf;
1197 }
1198
1199 const char *
1200 skill_name(skill)
1201 int skill;
1202 {
1203     return P_NAME(skill);
1204 }
1205
1206 /* return the # of slots required to advance the skill */
1207 STATIC_OVL int
1208 slots_required(skill)
1209 int skill;
1210 {
1211     int tmp = P_SKILL(skill);
1212
1213     /* The more difficult the training, the more slots it takes.
1214      *  unskilled -> basic      1
1215      *  basic -> skilled        2
1216      *  skilled -> expert       3
1217      */
1218     if (skill <= P_LAST_WEAPON || skill == P_TWO_WEAPON_COMBAT)
1219         return tmp;
1220
1221     /* Fewer slots used up for unarmed or martial.
1222      *  unskilled -> basic      1
1223      *  basic -> skilled        1
1224      *  skilled -> expert       2
1225      *  expert -> master        2
1226      *  master -> grand master  3
1227      */
1228     return (tmp + 1) / 2;
1229 }
1230
1231 /* return true if this skill can be advanced */
1232 boolean
1233 can_advance(skill, speedy)
1234 int skill;
1235 boolean speedy;
1236 {
1237     if (P_RESTRICTED(skill)
1238         || P_SKILL(skill) >= P_MAX_SKILL(skill)
1239         || u.skills_advanced >= P_SKILL_LIMIT)
1240         return FALSE;
1241
1242     if (wizard && speedy)
1243         return TRUE;
1244
1245     return (boolean) ((int) P_ADVANCE(skill)
1246                       >= practice_needed_to_advance(P_SKILL(skill))
1247                       && u.weapon_slots >= slots_required(skill));
1248 }
1249
1250 /* return true if this skill could be advanced if more slots were available */
1251 STATIC_OVL boolean
1252 could_advance(skill)
1253 int skill;
1254 {
1255     if (P_RESTRICTED(skill)
1256         || P_SKILL(skill) >= P_MAX_SKILL(skill)
1257         || u.skills_advanced >= P_SKILL_LIMIT)
1258         return FALSE;
1259
1260     return (boolean) ((int) P_ADVANCE(skill)
1261                       >= practice_needed_to_advance(P_SKILL(skill)));
1262 }
1263
1264 /* return true if this skill has reached its maximum and there's been enough
1265    practice to become eligible for the next step if that had been possible */
1266 STATIC_OVL boolean
1267 peaked_skill(skill)
1268 int skill;
1269 {
1270     if (P_RESTRICTED(skill))
1271         return FALSE;
1272
1273     return (boolean) (P_SKILL(skill) >= P_MAX_SKILL(skill)
1274                       && ((int) P_ADVANCE(skill)
1275                           >= practice_needed_to_advance(P_SKILL(skill))));
1276 }
1277
1278 STATIC_OVL void
1279 skill_advance(skill)
1280 int skill;
1281 {
1282     u.weapon_slots -= slots_required(skill);
1283     P_SKILL(skill)++;
1284     u.skill_record[u.skills_advanced++] = skill;
1285     /* subtly change the advance message to indicate no more advancement */
1286 #if 0 /*JP:T*/
1287     You("are now %s skilled in %s.",
1288         P_SKILL(skill) >= P_MAX_SKILL(skill) ? "most" : "more",
1289         P_NAME(skill));
1290 #else
1291     Your("%s\82Ì\83X\83L\83\8b\82ð%s\8d\82\82ß\82½\81D", 
1292          P_NAME(skill),
1293          P_SKILL(skill) >= P_MAX_SKILL(skill) ? "\8dÅ\8d\82\82É" : "\82³\82ç\82É");
1294 #endif
1295 }
1296
1297 static const struct skill_range {
1298     short first, last;
1299     const char *name;
1300 } skill_ranges[] = {
1301 /*JP
1302     { P_FIRST_H_TO_H, P_LAST_H_TO_H, "Fighting Skills" },
1303 */
1304     { P_FIRST_H_TO_H, P_LAST_H_TO_H, "\90í\82¢\82Ì\83X\83L\83\8b" },
1305 /*JP
1306     { P_FIRST_WEAPON, P_LAST_WEAPON, "Weapon Skills" },
1307 */
1308     { P_FIRST_WEAPON, P_LAST_WEAPON, "\95\90\8aí\82Ì\83X\83L\83\8b" },
1309 /*JP
1310     { P_FIRST_SPELL, P_LAST_SPELL, "Spellcasting Skills" },
1311 */
1312     { P_FIRST_SPELL,  P_LAST_SPELL,  "\96\82\96@\82Ì\83X\83L\83\8b" },
1313 };
1314
1315 /*
1316  * The `#enhance' extended command.  What we _really_ would like is
1317  * to keep being able to pick things to advance until we couldn't any
1318  * more.  This is currently not possible -- the menu code has no way
1319  * to call us back for instant action.  Even if it did, we would also need
1320  * to be able to update the menu since selecting one item could make
1321  * others unselectable.
1322  */
1323 int
1324 enhance_weapon_skill()
1325 {
1326     int pass, i, n, len, longest, to_advance, eventually_advance, maxxed_cnt;
1327     char buf[BUFSZ], sklnambuf[BUFSZ];
1328     const char *prefix;
1329     menu_item *selected;
1330     anything any;
1331     winid win;
1332     boolean speedy = FALSE;
1333
1334     if (wizard && yn("Advance skills without practice?") == 'y')
1335         speedy = TRUE;
1336
1337     do {
1338         /* find longest available skill name, count those that can advance */
1339         to_advance = eventually_advance = maxxed_cnt = 0;
1340         for (longest = 0, i = 0; i < P_NUM_SKILLS; i++) {
1341             if (P_RESTRICTED(i))
1342                 continue;
1343             if ((len = strlen(P_NAME(i))) > longest)
1344                 longest = len;
1345             if (can_advance(i, speedy))
1346                 to_advance++;
1347             else if (could_advance(i))
1348                 eventually_advance++;
1349             else if (peaked_skill(i))
1350                 maxxed_cnt++;
1351         }
1352
1353         win = create_nhwindow(NHW_MENU);
1354         start_menu(win);
1355
1356         /* start with a legend if any entries will be annotated
1357            with "*" or "#" below */
1358         if (eventually_advance > 0 || maxxed_cnt > 0) {
1359             any = zeroany;
1360             if (eventually_advance > 0) {
1361 #if 0 /*JP:T*/
1362                 Sprintf(buf, "(Skill%s flagged by \"*\" may be enhanced %s.)",
1363                         plur(eventually_advance),
1364                         (u.ulevel < MAXULEV)
1365                             ? "when you're more experienced"
1366                             : "if skill slots become available");
1367 #else
1368                 Sprintf(buf, "(\"*\"\82ª\82Â\82¢\82Ä\82¢\82é\83X\83L\83\8b\82Í%s\8d\82\82ß\82ç\82ê\82é\81D)",
1369                         (u.ulevel < MAXULEV)
1370                             ? "\82à\82Á\82Æ\8co\8c±\82ð\82Â\82ß\82Î"
1371                             : "\83X\83L\83\8b\83X\83\8d\83b\83g\82ª\8eg\82¦\82é\82æ\82¤\82É\82È\82ê\82Î");
1372 #endif
1373                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1374                          MENU_UNSELECTED);
1375             }
1376             if (maxxed_cnt > 0) {
1377 #if 0 /*JP:T*/
1378                 Sprintf(buf,
1379                  "(Skill%s flagged by \"#\" cannot be enhanced any further.)",
1380                         plur(maxxed_cnt));
1381 #else
1382                 Sprintf(buf,
1383                         "(\"#\"\82ª\82Â\82¢\82Ä\82¢\82é\83X\83L\83\8b\82Í\82±\82ê\88È\8fã\8d\82\82ß\82ç\82ê\82È\82¢\81D)");
1384 #endif
1385                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1386                          MENU_UNSELECTED);
1387             }
1388             add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "",
1389                      MENU_UNSELECTED);
1390         }
1391
1392         /* List the skills, making ones that could be advanced
1393            selectable.  List the miscellaneous skills first.
1394            Possible future enhancement:  list spell skills before
1395            weapon skills for spellcaster roles. */
1396         for (pass = 0; pass < SIZE(skill_ranges); pass++)
1397             for (i = skill_ranges[pass].first; i <= skill_ranges[pass].last;
1398                  i++) {
1399                 /* Print headings for skill types */
1400                 any = zeroany;
1401                 if (i == skill_ranges[pass].first)
1402                     add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
1403                              skill_ranges[pass].name, MENU_UNSELECTED);
1404
1405                 if (P_RESTRICTED(i))
1406                     continue;
1407                 /*
1408                  * Sigh, this assumes a monospaced font unless
1409                  * iflags.menu_tab_sep is set in which case it puts
1410                  * tabs between columns.
1411                  * The 12 is the longest skill level name.
1412                  * The "    " is room for a selection letter and dash, "a - ".
1413                  */
1414                 if (can_advance(i, speedy))
1415                     prefix = ""; /* will be preceded by menu choice */
1416                 else if (could_advance(i))
1417                     prefix = "  * ";
1418                 else if (peaked_skill(i))
1419                     prefix = "  # ";
1420                 else
1421                     prefix =
1422                         (to_advance + eventually_advance + maxxed_cnt > 0)
1423                             ? "    "
1424                             : "";
1425                 (void) skill_level_name(i, sklnambuf);
1426                 if (wizard) {
1427                     if (!iflags.menu_tab_sep)
1428                         Sprintf(buf, " %s%-*s %-12s %5d(%4d)", prefix,
1429                                 longest, P_NAME(i), sklnambuf, P_ADVANCE(i),
1430                                 practice_needed_to_advance(P_SKILL(i)));
1431                     else
1432                         Sprintf(buf, " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i),
1433                                 sklnambuf, P_ADVANCE(i),
1434                                 practice_needed_to_advance(P_SKILL(i)));
1435                 } else {
1436                     if (!iflags.menu_tab_sep)
1437                         Sprintf(buf, " %s %-*s [%s]", prefix, longest,
1438                                 P_NAME(i), sklnambuf);
1439                     else
1440                         Sprintf(buf, " %s%s\t[%s]", prefix, P_NAME(i),
1441                                 sklnambuf);
1442                 }
1443                 any.a_int = can_advance(i, speedy) ? i + 1 : 0;
1444                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1445                          MENU_UNSELECTED);
1446             }
1447
1448 #if 0 /*JP:T*/
1449         Strcpy(buf, (to_advance > 0) ? "Pick a skill to advance:"
1450                                      : "Current skills:");
1451 #else
1452         Strcpy(buf, (to_advance > 0) ? "\83X\83L\83\8b\82ð\91I\91ð\82µ\82Ä\82­\82¾\82³\82¢\81F"
1453                                      : "\8c»\8dÝ\82Ì\83X\83L\83\8b\81F");
1454 #endif
1455         if (wizard && !speedy)
1456             Sprintf(eos(buf), "  (%d slot%s available)", u.weapon_slots,
1457                     plur(u.weapon_slots));
1458         end_menu(win, buf);
1459         n = select_menu(win, to_advance ? PICK_ONE : PICK_NONE, &selected);
1460         destroy_nhwindow(win);
1461         if (n > 0) {
1462             n = selected[0].item.a_int - 1; /* get item selected */
1463             free((genericptr_t) selected);
1464             skill_advance(n);
1465             /* check for more skills able to advance, if so then .. */
1466             for (n = i = 0; i < P_NUM_SKILLS; i++) {
1467                 if (can_advance(i, speedy)) {
1468                     if (!speedy)
1469 /*JP
1470                         You_feel("you could be more dangerous!");
1471 */
1472                         You("\82³\82ç\82É\83X\83L\83\8b\82ð\8d\82\82ß\82é\82±\82Æ\82ª\82Å\82«\82»\82¤\82È\8bC\82ª\82µ\82½\81I");
1473                     n++;
1474                     break;
1475                 }
1476             }
1477         }
1478     } while (speedy && n > 0);
1479     return 0;
1480 }
1481
1482 /*
1483  * Change from restricted to unrestricted, allowing P_BASIC as max.  This
1484  * function may be called with with P_NONE.  Used in pray.c as well as below.
1485  */
1486 void
1487 unrestrict_weapon_skill(skill)
1488 int skill;
1489 {
1490     if (skill < P_NUM_SKILLS && P_RESTRICTED(skill)) {
1491         P_SKILL(skill) = P_UNSKILLED;
1492         P_MAX_SKILL(skill) = P_BASIC;
1493         P_ADVANCE(skill) = 0;
1494     }
1495 }
1496
1497 void
1498 use_skill(skill, degree)
1499 int skill;
1500 int degree;
1501 {
1502     boolean advance_before;
1503
1504     if (skill != P_NONE && !P_RESTRICTED(skill)) {
1505         advance_before = can_advance(skill, FALSE);
1506         P_ADVANCE(skill) += degree;
1507         if (!advance_before && can_advance(skill, FALSE))
1508             give_may_advance_msg(skill);
1509     }
1510 }
1511
1512 void
1513 add_weapon_skill(n)
1514 int n; /* number of slots to gain; normally one */
1515 {
1516     int i, before, after;
1517
1518     for (i = 0, before = 0; i < P_NUM_SKILLS; i++)
1519         if (can_advance(i, FALSE))
1520             before++;
1521     u.weapon_slots += n;
1522     for (i = 0, after = 0; i < P_NUM_SKILLS; i++)
1523         if (can_advance(i, FALSE))
1524             after++;
1525     if (before < after)
1526         give_may_advance_msg(P_NONE);
1527 }
1528
1529 void
1530 lose_weapon_skill(n)
1531 int n; /* number of slots to lose; normally one */
1532 {
1533     int skill;
1534
1535     while (--n >= 0) {
1536         /* deduct first from unused slots then from last placed one, if any */
1537         if (u.weapon_slots) {
1538             u.weapon_slots--;
1539         } else if (u.skills_advanced) {
1540             skill = u.skill_record[--u.skills_advanced];
1541             if (P_SKILL(skill) <= P_UNSKILLED)
1542                 panic("lose_weapon_skill (%d)", skill);
1543             P_SKILL(skill)--; /* drop skill one level */
1544             /* Lost skill might have taken more than one slot; refund rest. */
1545             u.weapon_slots = slots_required(skill) - 1;
1546             /* It might now be possible to advance some other pending
1547                skill by using the refunded slots, but giving a message
1548                to that effect would seem pretty confusing.... */
1549         }
1550     }
1551 }
1552
1553 int
1554 weapon_type(obj)
1555 struct obj *obj;
1556 {
1557     /* KMH -- now uses the object table */
1558     int type;
1559
1560     if (!obj)
1561         return P_BARE_HANDED_COMBAT; /* Not using a weapon */
1562     if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS
1563         && obj->oclass != GEM_CLASS)
1564         return P_NONE; /* Not a weapon, weapon-tool, or ammo */
1565     type = objects[obj->otyp].oc_skill;
1566     return (type < 0) ? -type : type;
1567 }
1568
1569 int
1570 uwep_skill_type()
1571 {
1572     if (u.twoweap)
1573         return P_TWO_WEAPON_COMBAT;
1574     return weapon_type(uwep);
1575 }
1576
1577 /*
1578  * Return hit bonus/penalty based on skill of weapon.
1579  * Treat restricted weapons as unskilled.
1580  */
1581 int
1582 weapon_hit_bonus(weapon)
1583 struct obj *weapon;
1584 {
1585     int type, wep_type, skill, bonus = 0;
1586     static const char bad_skill[] = "weapon_hit_bonus: bad skill %d";
1587
1588     wep_type = weapon_type(weapon);
1589     /* use two weapon skill only if attacking with one of the wielded weapons
1590      */
1591     type = (u.twoweap && (weapon == uwep || weapon == uswapwep))
1592                ? P_TWO_WEAPON_COMBAT
1593                : wep_type;
1594     if (type == P_NONE) {
1595         bonus = 0;
1596     } else if (type <= P_LAST_WEAPON) {
1597         switch (P_SKILL(type)) {
1598         default:
1599             impossible(bad_skill, P_SKILL(type)); /* fall through */
1600         case P_ISRESTRICTED:
1601         case P_UNSKILLED:
1602             bonus = -4;
1603             break;
1604         case P_BASIC:
1605             bonus = 0;
1606             break;
1607         case P_SKILLED:
1608             bonus = 2;
1609             break;
1610         case P_EXPERT:
1611             bonus = 3;
1612             break;
1613         }
1614     } else if (type == P_TWO_WEAPON_COMBAT) {
1615         skill = P_SKILL(P_TWO_WEAPON_COMBAT);
1616         if (P_SKILL(wep_type) < skill)
1617             skill = P_SKILL(wep_type);
1618         switch (skill) {
1619         default:
1620             impossible(bad_skill, skill); /* fall through */
1621         case P_ISRESTRICTED:
1622         case P_UNSKILLED:
1623             bonus = -9;
1624             break;
1625         case P_BASIC:
1626             bonus = -7;
1627             break;
1628         case P_SKILLED:
1629             bonus = -5;
1630             break;
1631         case P_EXPERT:
1632             bonus = -3;
1633             break;
1634         }
1635     } else if (type == P_BARE_HANDED_COMBAT) {
1636         /*
1637          *        b.h. m.a.
1638          * unskl:  +1  n/a
1639          * basic:  +1   +3
1640          * skild:  +2   +4
1641          * exprt:  +2   +5
1642          * mastr:  +3   +6
1643          * grand:  +3   +7
1644          */
1645         bonus = P_SKILL(type);
1646         bonus = max(bonus, P_UNSKILLED) - 1; /* unskilled => 0 */
1647         bonus = ((bonus + 2) * (martial_bonus() ? 2 : 1)) / 2;
1648     }
1649
1650     /* KMH -- It's harder to hit while you are riding */
1651     if (u.usteed) {
1652         switch (P_SKILL(P_RIDING)) {
1653         case P_ISRESTRICTED:
1654         case P_UNSKILLED:
1655             bonus -= 2;
1656             break;
1657         case P_BASIC:
1658             bonus -= 1;
1659             break;
1660         case P_SKILLED:
1661             break;
1662         case P_EXPERT:
1663             break;
1664         }
1665         if (u.twoweap)
1666             bonus -= 2;
1667     }
1668
1669     return bonus;
1670 }
1671
1672 /*
1673  * Return damage bonus/penalty based on skill of weapon.
1674  * Treat restricted weapons as unskilled.
1675  */
1676 int
1677 weapon_dam_bonus(weapon)
1678 struct obj *weapon;
1679 {
1680     int type, wep_type, skill, bonus = 0;
1681
1682     wep_type = weapon_type(weapon);
1683     /* use two weapon skill only if attacking with one of the wielded weapons
1684      */
1685     type = (u.twoweap && (weapon == uwep || weapon == uswapwep))
1686                ? P_TWO_WEAPON_COMBAT
1687                : wep_type;
1688     if (type == P_NONE) {
1689         bonus = 0;
1690     } else if (type <= P_LAST_WEAPON) {
1691         switch (P_SKILL(type)) {
1692         default:
1693             impossible("weapon_dam_bonus: bad skill %d", P_SKILL(type));
1694         /* fall through */
1695         case P_ISRESTRICTED:
1696         case P_UNSKILLED:
1697             bonus = -2;
1698             break;
1699         case P_BASIC:
1700             bonus = 0;
1701             break;
1702         case P_SKILLED:
1703             bonus = 1;
1704             break;
1705         case P_EXPERT:
1706             bonus = 2;
1707             break;
1708         }
1709     } else if (type == P_TWO_WEAPON_COMBAT) {
1710         skill = P_SKILL(P_TWO_WEAPON_COMBAT);
1711         if (P_SKILL(wep_type) < skill)
1712             skill = P_SKILL(wep_type);
1713         switch (skill) {
1714         default:
1715         case P_ISRESTRICTED:
1716         case P_UNSKILLED:
1717             bonus = -3;
1718             break;
1719         case P_BASIC:
1720             bonus = -1;
1721             break;
1722         case P_SKILLED:
1723             bonus = 0;
1724             break;
1725         case P_EXPERT:
1726             bonus = 1;
1727             break;
1728         }
1729     } else if (type == P_BARE_HANDED_COMBAT) {
1730         /*
1731          *        b.h. m.a.
1732          * unskl:   0  n/a
1733          * basic:  +1   +3
1734          * skild:  +1   +4
1735          * exprt:  +2   +6
1736          * mastr:  +2   +7
1737          * grand:  +3   +9
1738          */
1739         bonus = P_SKILL(type);
1740         bonus = max(bonus, P_UNSKILLED) - 1; /* unskilled => 0 */
1741         bonus = ((bonus + 1) * (martial_bonus() ? 3 : 1)) / 2;
1742     }
1743
1744     /* KMH -- Riding gives some thrusting damage */
1745     if (u.usteed && type != P_TWO_WEAPON_COMBAT) {
1746         switch (P_SKILL(P_RIDING)) {
1747         case P_ISRESTRICTED:
1748         case P_UNSKILLED:
1749             break;
1750         case P_BASIC:
1751             break;
1752         case P_SKILLED:
1753             bonus += 1;
1754             break;
1755         case P_EXPERT:
1756             bonus += 2;
1757             break;
1758         }
1759     }
1760
1761     return bonus;
1762 }
1763
1764 /*
1765  * Initialize weapon skill array for the game.  Start by setting all
1766  * skills to restricted, then set the skill for every weapon the
1767  * hero is holding, finally reading the given array that sets
1768  * maximums.
1769  */
1770 void
1771 skill_init(class_skill)
1772 const struct def_skill *class_skill;
1773 {
1774     struct obj *obj;
1775     int skmax, skill;
1776
1777     /* initialize skill array; by default, everything is restricted */
1778     for (skill = 0; skill < P_NUM_SKILLS; skill++) {
1779         P_SKILL(skill) = P_ISRESTRICTED;
1780         P_MAX_SKILL(skill) = P_ISRESTRICTED;
1781         P_ADVANCE(skill) = 0;
1782     }
1783
1784     /* Set skill for all weapons in inventory to be basic */
1785     for (obj = invent; obj; obj = obj->nobj) {
1786         /* don't give skill just because of carried ammo, wait until
1787            we see the relevant launcher (prevents an archeologist's
1788            touchstone from inadvertently providing skill in sling) */
1789         if (is_ammo(obj))
1790             continue;
1791
1792         skill = weapon_type(obj);
1793         if (skill != P_NONE)
1794             P_SKILL(skill) = P_BASIC;
1795     }
1796
1797     /* set skills for magic */
1798     if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
1799         P_SKILL(P_HEALING_SPELL) = P_BASIC;
1800     } else if (Role_if(PM_PRIEST)) {
1801         P_SKILL(P_CLERIC_SPELL) = P_BASIC;
1802     } else if (Role_if(PM_WIZARD)) {
1803         P_SKILL(P_ATTACK_SPELL) = P_BASIC;
1804         P_SKILL(P_ENCHANTMENT_SPELL) = P_BASIC;
1805     }
1806
1807     /* walk through array to set skill maximums */
1808     for (; class_skill->skill != P_NONE; class_skill++) {
1809         skmax = class_skill->skmax;
1810         skill = class_skill->skill;
1811
1812         P_MAX_SKILL(skill) = skmax;
1813         if (P_SKILL(skill) == P_ISRESTRICTED) /* skill pre-set */
1814             P_SKILL(skill) = P_UNSKILLED;
1815     }
1816
1817     /* High potential fighters already know how to use their hands. */
1818     if (P_MAX_SKILL(P_BARE_HANDED_COMBAT) > P_EXPERT)
1819         P_SKILL(P_BARE_HANDED_COMBAT) = P_BASIC;
1820
1821     /* Roles that start with a horse know how to ride it */
1822     if (urole.petnum == PM_PONY)
1823         P_SKILL(P_RIDING) = P_BASIC;
1824
1825     /*
1826      * Make sure we haven't missed setting the max on a skill
1827      * & set advance
1828      */
1829     for (skill = 0; skill < P_NUM_SKILLS; skill++) {
1830         if (!P_RESTRICTED(skill)) {
1831             if (P_MAX_SKILL(skill) < P_SKILL(skill)) {
1832                 impossible("skill_init: curr > max: %s", P_NAME(skill));
1833                 P_MAX_SKILL(skill) = P_SKILL(skill);
1834             }
1835             P_ADVANCE(skill) = practice_needed_to_advance(P_SKILL(skill) - 1);
1836         }
1837     }
1838
1839     /* each role has a special spell; allow at least basic for its type
1840        (despite the function name, this works for spell skills too) */
1841     unrestrict_weapon_skill(spell_skilltype(urole.spelspec));
1842 }
1843
1844 void
1845 setmnotwielded(mon, obj)
1846 register struct monst *mon;
1847 register struct obj *obj;
1848 {
1849     if (!obj)
1850         return;
1851     if (artifact_light(obj) && obj->lamplit) {
1852         end_burn(obj, FALSE);
1853         if (canseemon(mon))
1854 #if 0 /*JP:T*/
1855             pline("%s in %s %s %s shining.", The(xname(obj)),
1856                   s_suffix(mon_nam(mon)), mbodypart(mon, HAND),
1857                   otense(obj, "stop"));
1858 #else
1859             pline("%s\82ª\8e\9d\82Â%s\82Ì\8bP\82«\82ª\8fÁ\82¦\82½\81D",
1860                   mon_nam(mon), xname(obj));
1861 #endif
1862     }
1863     if (MON_WEP(mon) == obj)
1864         MON_NOWEP(mon);
1865     obj->owornmask &= ~W_WEP;
1866 }
1867
1868 /*weapon.c*/