OSDN Git Service

update year to 2020
[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-2020            */
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 #if 0 /*JP:T*/
929                 pline("%s %s to %s %s!", Tobjnam(obj, "weld"),
930                       is_plural(obj) ? "themselves" : "itself",
931                       s_suffix(mon_nam(mon)), mbodypart(mon, HAND));
932 #else
933                 pline("%s\82Í\8f\9f\8eè\82É%s\82Ì%s\82É\91\95\94õ\82³\82ê\82½\81I",
934                       xname(obj),
935                       mon_nam(mon), mbodypart(mon, HAND));
936 #endif
937                 obj->bknown = 1;
938             }
939         }
940         if (artifact_light(obj) && !obj->lamplit) {
941             begin_burn(obj, FALSE);
942             if (canseemon(mon))
943 #if 0 /*JP:T*/
944                 pline("%s %s in %s %s!", Tobjnam(obj, "shine"),
945                       arti_light_description(obj), s_suffix(mon_nam(mon)),
946                       mbodypart(mon, HAND));
947 #else
948                 pline("%s\82Í%s\82Ì%s\82Ì\92\86\82Å%s\8bP\82¢\82½\81I",
949                       xname(obj), mon_nam(mon),
950                       mbodypart(mon, HAND), arti_light_description(obj));
951 #endif
952             /* 3.6.3: artifact might be getting wielded by invisible monst */
953             else if (cansee(mon->mx, mon->my))
954 #if 0 /*JP*/
955                 pline("Light begins shining %s.",
956                       (distu(mon->mx, mon->my) <= 5 * 5)
957                           ? "nearby"
958                           : "in the distance");
959 #else
960                 pline("\96¾\82©\82è\82ª%s\82Å\8bP\82«\82Í\82\82ß\82½\81D",
961                       (distu(mon->mx, mon->my) <= 5 * 5)
962                           ? "\8bß\82­"
963                           : "\89\93\82­");
964 #endif
965         }
966         obj->owornmask = W_WEP;
967         return 1;
968     }
969     mon->weapon_check = NEED_WEAPON;
970     return 0;
971 }
972
973 /* force monster to stop wielding current weapon, if any */
974 void
975 mwepgone(mon)
976 struct monst *mon;
977 {
978     struct obj *mwep = MON_WEP(mon);
979
980     if (mwep) {
981         setmnotwielded(mon, mwep);
982         mon->weapon_check = NEED_WEAPON;
983     }
984 }
985
986 /* attack bonus for strength & dexterity */
987 int
988 abon()
989 {
990     int sbon;
991     int str = ACURR(A_STR), dex = ACURR(A_DEX);
992
993     if (Upolyd)
994         return (adj_lev(&mons[u.umonnum]) - 3);
995     if (str < 6)
996         sbon = -2;
997     else if (str < 8)
998         sbon = -1;
999     else if (str < 17)
1000         sbon = 0;
1001     else if (str <= STR18(50))
1002         sbon = 1; /* up to 18/50 */
1003     else if (str < STR18(100))
1004         sbon = 2;
1005     else
1006         sbon = 3;
1007
1008     /* Game tuning kludge: make it a bit easier for a low level character to
1009      * hit */
1010     sbon += (u.ulevel < 3) ? 1 : 0;
1011
1012     if (dex < 4)
1013         return (sbon - 3);
1014     else if (dex < 6)
1015         return (sbon - 2);
1016     else if (dex < 8)
1017         return (sbon - 1);
1018     else if (dex < 14)
1019         return sbon;
1020     else
1021         return (sbon + dex - 14);
1022 }
1023
1024 /* damage bonus for strength */
1025 int
1026 dbon()
1027 {
1028     int str = ACURR(A_STR);
1029
1030     if (Upolyd)
1031         return 0;
1032
1033     if (str < 6)
1034         return -1;
1035     else if (str < 16)
1036         return 0;
1037     else if (str < 18)
1038         return 1;
1039     else if (str == 18)
1040         return 2; /* up to 18 */
1041     else if (str <= STR18(75))
1042         return 3; /* up to 18/75 */
1043     else if (str <= STR18(90))
1044         return 4; /* up to 18/90 */
1045     else if (str < STR18(100))
1046         return 5; /* up to 18/99 */
1047     else
1048         return 6;
1049 }
1050
1051 /* increase a towel's wetness */
1052 void
1053 wet_a_towel(obj, amt, verbose)
1054 struct obj *obj;
1055 int amt; /* positive: new value; negative: increment by -amt; zero: no-op */
1056 boolean verbose;
1057 {
1058     int newspe = (amt <= 0) ? obj->spe - amt : amt;
1059
1060     /* new state is only reported if it's an increase */
1061     if (newspe > obj->spe) {
1062         if (verbose) {
1063 #if 0 /*JP:T*/
1064             const char *wetness = (newspe < 3)
1065                                      ? (!obj->spe ? "damp" : "damper")
1066                                      : (!obj->spe ? "wet" : "wetter");
1067 #else
1068             const char *wetness = (newspe < 3)
1069                                      ? (!obj->spe ? "\8e¼\82Á\82½" : "\82³\82ç\82É\8e¼\82Á\82½")
1070                                      : (!obj->spe ? "\94G\82ê\82½" : "\82³\82ç\82É\94G\82ê\82½");
1071 #endif
1072
1073             if (carried(obj))
1074 #if 0 /*JP:T*/
1075                 pline("%s gets %s.", Yobjnam2(obj, (const char *) 0),
1076                       wetness);
1077 #else
1078                 pline("%s\82Í%s\81D", Yobjnam2(obj, (const char *) 0),
1079                       wetness);
1080 #endif
1081             else if (mcarried(obj) && canseemon(obj->ocarry))
1082 #if 0 /*JP:T*/
1083                 pline("%s %s gets %s.", s_suffix(Monnam(obj->ocarry)),
1084                       xname(obj), wetness);
1085 #else
1086                 pline("%s\82Ì%s\82Í%s\81D", Monnam(obj->ocarry),
1087                       xname(obj), wetness);
1088 #endif
1089         }
1090     }
1091     obj->spe = min(newspe, 7);
1092
1093     /* if hero is wielding this towel, don't give "you begin bashing
1094        with your wet towel" message on next attack with it */
1095     if (obj == uwep)
1096         unweapon = !is_wet_towel(obj);
1097 }
1098
1099 /* decrease a towel's wetness */
1100 void
1101 dry_a_towel(obj, amt, verbose)
1102 struct obj *obj;
1103 int amt; /* positive: new value; negative: decrement by -amt; zero: no-op */
1104 boolean verbose;
1105 {
1106     int newspe = (amt <= 0) ? obj->spe + amt : amt;
1107
1108     /* new state is only reported if it's a decrease */
1109     if (newspe < obj->spe) {
1110         if (verbose) {
1111             if (carried(obj))
1112 #if 0 /*JP:T*/
1113                 pline("%s dries%s.", Yobjnam2(obj, (const char *) 0),
1114                       !newspe ? " out" : "");
1115 #else
1116                 pline("%s\82Í%s\81D", Yobjnam2(obj, (const char *) 0),
1117                       !newspe ? "\8a£\82«\82«\82Á\82½" : "\8a£\82¢\82½");
1118 #endif
1119             else if (mcarried(obj) && canseemon(obj->ocarry))
1120 #if 0 /*JP:T*/
1121                 pline("%s %s drie%s.", s_suffix(Monnam(obj->ocarry)),
1122                       xname(obj), !newspe ? " out" : "");
1123 #else
1124                 pline("%s\82Ì%s\82Í%s\81D", Monnam(obj->ocarry),
1125                       xname(obj), !newspe ? "\8a£\82«\82«\82Á\82½" : "\8a£\82¢\82½");
1126 #endif
1127         }
1128     }
1129     newspe = min(newspe, 7);
1130     obj->spe = max(newspe, 0);
1131
1132     /* if hero is wielding this towel and it is now dry, give "you begin
1133        bashing with your towel" message on next attack with it */
1134     if (obj == uwep)
1135         unweapon = !is_wet_towel(obj);
1136 }
1137
1138 /* copy the skill level name into the given buffer */
1139 char *
1140 skill_level_name(skill, buf)
1141 int skill;
1142 char *buf;
1143 {
1144     const char *ptr;
1145
1146     switch (P_SKILL(skill)) {
1147     case P_UNSKILLED:
1148 /*JP
1149         ptr = "Unskilled";
1150 */
1151         ptr = "\8f\89\90S\8eÒ";
1152         break;
1153     case P_BASIC:
1154 /*JP
1155         ptr = "Basic";
1156 */
1157         ptr = "\93ü\96å\8eÒ";
1158         break;
1159     case P_SKILLED:
1160 /*JP
1161         ptr = "Skilled";
1162 */
1163         ptr = "\8fn\97û\8eÒ";
1164         break;
1165     case P_EXPERT:
1166 /*JP
1167         ptr = "Expert";
1168 */
1169         ptr = "\83G\83L\83X\83p\81[\83g";
1170         break;
1171     /* these are for unarmed combat/martial arts only */
1172     case P_MASTER:
1173 /*JP
1174         ptr = "Master";
1175 */
1176         ptr = "\83}\83X\83^\81[";
1177         break;
1178     case P_GRAND_MASTER:
1179 /*JP
1180         ptr = "Grand Master";
1181 */
1182         ptr = "\83O\83\89\83\93\83h\83}\83X\83^\81[";
1183         break;
1184     default:
1185 /*JP
1186         ptr = "Unknown";
1187 */
1188         ptr = "\95s\96¾";
1189         break;
1190     }
1191     Strcpy(buf, ptr);
1192     return buf;
1193 }
1194
1195 const char *
1196 skill_name(skill)
1197 int skill;
1198 {
1199     return P_NAME(skill);
1200 }
1201
1202 /* return the # of slots required to advance the skill */
1203 STATIC_OVL int
1204 slots_required(skill)
1205 int skill;
1206 {
1207     int tmp = P_SKILL(skill);
1208
1209     /* The more difficult the training, the more slots it takes.
1210      *  unskilled -> basic      1
1211      *  basic -> skilled        2
1212      *  skilled -> expert       3
1213      */
1214     if (skill <= P_LAST_WEAPON || skill == P_TWO_WEAPON_COMBAT)
1215         return tmp;
1216
1217     /* Fewer slots used up for unarmed or martial.
1218      *  unskilled -> basic      1
1219      *  basic -> skilled        1
1220      *  skilled -> expert       2
1221      *  expert -> master        2
1222      *  master -> grand master  3
1223      */
1224     return (tmp + 1) / 2;
1225 }
1226
1227 /* return true if this skill can be advanced */
1228 boolean
1229 can_advance(skill, speedy)
1230 int skill;
1231 boolean speedy;
1232 {
1233     if (P_RESTRICTED(skill)
1234         || P_SKILL(skill) >= P_MAX_SKILL(skill)
1235         || u.skills_advanced >= P_SKILL_LIMIT)
1236         return FALSE;
1237
1238     if (wizard && speedy)
1239         return TRUE;
1240
1241     return (boolean) ((int) P_ADVANCE(skill)
1242                       >= practice_needed_to_advance(P_SKILL(skill))
1243                       && u.weapon_slots >= slots_required(skill));
1244 }
1245
1246 /* return true if this skill could be advanced if more slots were available */
1247 STATIC_OVL boolean
1248 could_advance(skill)
1249 int skill;
1250 {
1251     if (P_RESTRICTED(skill)
1252         || P_SKILL(skill) >= P_MAX_SKILL(skill)
1253         || u.skills_advanced >= P_SKILL_LIMIT)
1254         return FALSE;
1255
1256     return (boolean) ((int) P_ADVANCE(skill)
1257                       >= practice_needed_to_advance(P_SKILL(skill)));
1258 }
1259
1260 /* return true if this skill has reached its maximum and there's been enough
1261    practice to become eligible for the next step if that had been possible */
1262 STATIC_OVL boolean
1263 peaked_skill(skill)
1264 int skill;
1265 {
1266     if (P_RESTRICTED(skill))
1267         return FALSE;
1268
1269     return (boolean) (P_SKILL(skill) >= P_MAX_SKILL(skill)
1270                       && ((int) P_ADVANCE(skill)
1271                           >= practice_needed_to_advance(P_SKILL(skill))));
1272 }
1273
1274 STATIC_OVL void
1275 skill_advance(skill)
1276 int skill;
1277 {
1278     u.weapon_slots -= slots_required(skill);
1279     P_SKILL(skill)++;
1280     u.skill_record[u.skills_advanced++] = skill;
1281     /* subtly change the advance message to indicate no more advancement */
1282 #if 0 /*JP:T*/
1283     You("are now %s skilled in %s.",
1284         P_SKILL(skill) >= P_MAX_SKILL(skill) ? "most" : "more",
1285         P_NAME(skill));
1286 #else
1287     Your("%s\82Ì\83X\83L\83\8b\82ð%s\8d\82\82ß\82½\81D", 
1288          P_NAME(skill),
1289          P_SKILL(skill) >= P_MAX_SKILL(skill) ? "\8dÅ\8d\82\82É" : "\82³\82ç\82É");
1290 #endif
1291 }
1292
1293 static const struct skill_range {
1294     short first, last;
1295     const char *name;
1296 } skill_ranges[] = {
1297 /*JP
1298     { P_FIRST_H_TO_H, P_LAST_H_TO_H, "Fighting Skills" },
1299 */
1300     { P_FIRST_H_TO_H, P_LAST_H_TO_H, "\90í\82¢\82Ì\83X\83L\83\8b" },
1301 /*JP
1302     { P_FIRST_WEAPON, P_LAST_WEAPON, "Weapon Skills" },
1303 */
1304     { P_FIRST_WEAPON, P_LAST_WEAPON, "\95\90\8aí\82Ì\83X\83L\83\8b" },
1305 /*JP
1306     { P_FIRST_SPELL, P_LAST_SPELL, "Spellcasting Skills" },
1307 */
1308     { P_FIRST_SPELL,  P_LAST_SPELL,  "\96\82\96@\82Ì\83X\83L\83\8b" },
1309 };
1310
1311 /*
1312  * The `#enhance' extended command.  What we _really_ would like is
1313  * to keep being able to pick things to advance until we couldn't any
1314  * more.  This is currently not possible -- the menu code has no way
1315  * to call us back for instant action.  Even if it did, we would also need
1316  * to be able to update the menu since selecting one item could make
1317  * others unselectable.
1318  */
1319 int
1320 enhance_weapon_skill()
1321 {
1322     int pass, i, n, len, longest, to_advance, eventually_advance, maxxed_cnt;
1323     char buf[BUFSZ], sklnambuf[BUFSZ];
1324     const char *prefix;
1325     menu_item *selected;
1326     anything any;
1327     winid win;
1328     boolean speedy = FALSE;
1329
1330     if (wizard && yn("Advance skills without practice?") == 'y')
1331         speedy = TRUE;
1332
1333     do {
1334         /* find longest available skill name, count those that can advance */
1335         to_advance = eventually_advance = maxxed_cnt = 0;
1336         for (longest = 0, i = 0; i < P_NUM_SKILLS; i++) {
1337             if (P_RESTRICTED(i))
1338                 continue;
1339             if ((len = strlen(P_NAME(i))) > longest)
1340                 longest = len;
1341             if (can_advance(i, speedy))
1342                 to_advance++;
1343             else if (could_advance(i))
1344                 eventually_advance++;
1345             else if (peaked_skill(i))
1346                 maxxed_cnt++;
1347         }
1348
1349         win = create_nhwindow(NHW_MENU);
1350         start_menu(win);
1351
1352         /* start with a legend if any entries will be annotated
1353            with "*" or "#" below */
1354         if (eventually_advance > 0 || maxxed_cnt > 0) {
1355             any = zeroany;
1356             if (eventually_advance > 0) {
1357 #if 0 /*JP:T*/
1358                 Sprintf(buf, "(Skill%s flagged by \"*\" may be enhanced %s.)",
1359                         plur(eventually_advance),
1360                         (u.ulevel < MAXULEV)
1361                             ? "when you're more experienced"
1362                             : "if skill slots become available");
1363 #else
1364                 Sprintf(buf, "(\"*\"\82ª\82Â\82¢\82Ä\82¢\82é\83X\83L\83\8b\82Í%s\8d\82\82ß\82ç\82ê\82é\81D)",
1365                         (u.ulevel < MAXULEV)
1366                             ? "\82à\82Á\82Æ\8co\8c±\82ð\82Â\82ß\82Î"
1367                             : "\83X\83L\83\8b\83X\83\8d\83b\83g\82ª\8eg\82¦\82é\82æ\82¤\82É\82È\82ê\82Î");
1368 #endif
1369                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1370                          MENU_UNSELECTED);
1371             }
1372             if (maxxed_cnt > 0) {
1373 #if 0 /*JP:T*/
1374                 Sprintf(buf,
1375                  "(Skill%s flagged by \"#\" cannot be enhanced any further.)",
1376                         plur(maxxed_cnt));
1377 #else
1378                 Sprintf(buf,
1379                         "(\"#\"\82ª\82Â\82¢\82Ä\82¢\82é\83X\83L\83\8b\82Í\82±\82ê\88È\8fã\8d\82\82ß\82ç\82ê\82È\82¢\81D)");
1380 #endif
1381                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1382                          MENU_UNSELECTED);
1383             }
1384             add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "",
1385                      MENU_UNSELECTED);
1386         }
1387
1388         /* List the skills, making ones that could be advanced
1389            selectable.  List the miscellaneous skills first.
1390            Possible future enhancement:  list spell skills before
1391            weapon skills for spellcaster roles. */
1392         for (pass = 0; pass < SIZE(skill_ranges); pass++)
1393             for (i = skill_ranges[pass].first; i <= skill_ranges[pass].last;
1394                  i++) {
1395                 /* Print headings for skill types */
1396                 any = zeroany;
1397                 if (i == skill_ranges[pass].first)
1398                     add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
1399                              skill_ranges[pass].name, MENU_UNSELECTED);
1400
1401                 if (P_RESTRICTED(i))
1402                     continue;
1403                 /*
1404                  * Sigh, this assumes a monospaced font unless
1405                  * iflags.menu_tab_sep is set in which case it puts
1406                  * tabs between columns.
1407                  * The 12 is the longest skill level name.
1408                  * The "    " is room for a selection letter and dash, "a - ".
1409                  */
1410                 if (can_advance(i, speedy))
1411                     prefix = ""; /* will be preceded by menu choice */
1412                 else if (could_advance(i))
1413                     prefix = "  * ";
1414                 else if (peaked_skill(i))
1415                     prefix = "  # ";
1416                 else
1417                     prefix =
1418                         (to_advance + eventually_advance + maxxed_cnt > 0)
1419                             ? "    "
1420                             : "";
1421                 (void) skill_level_name(i, sklnambuf);
1422                 if (wizard) {
1423                     if (!iflags.menu_tab_sep)
1424                         Sprintf(buf, " %s%-*s %-12s %5d(%4d)", prefix,
1425                                 longest, P_NAME(i), sklnambuf, P_ADVANCE(i),
1426                                 practice_needed_to_advance(P_SKILL(i)));
1427                     else
1428                         Sprintf(buf, " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i),
1429                                 sklnambuf, P_ADVANCE(i),
1430                                 practice_needed_to_advance(P_SKILL(i)));
1431                 } else {
1432                     if (!iflags.menu_tab_sep)
1433                         Sprintf(buf, " %s %-*s [%s]", prefix, longest,
1434                                 P_NAME(i), sklnambuf);
1435                     else
1436                         Sprintf(buf, " %s%s\t[%s]", prefix, P_NAME(i),
1437                                 sklnambuf);
1438                 }
1439                 any.a_int = can_advance(i, speedy) ? i + 1 : 0;
1440                 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1441                          MENU_UNSELECTED);
1442             }
1443
1444 #if 0 /*JP:T*/
1445         Strcpy(buf, (to_advance > 0) ? "Pick a skill to advance:"
1446                                      : "Current skills:");
1447 #else
1448         Strcpy(buf, (to_advance > 0) ? "\83X\83L\83\8b\82ð\91I\91ð\82µ\82Ä\82­\82¾\82³\82¢\81F"
1449                                      : "\8c»\8dÝ\82Ì\83X\83L\83\8b\81F");
1450 #endif
1451         if (wizard && !speedy)
1452             Sprintf(eos(buf), "  (%d slot%s available)", u.weapon_slots,
1453                     plur(u.weapon_slots));
1454         end_menu(win, buf);
1455         n = select_menu(win, to_advance ? PICK_ONE : PICK_NONE, &selected);
1456         destroy_nhwindow(win);
1457         if (n > 0) {
1458             n = selected[0].item.a_int - 1; /* get item selected */
1459             free((genericptr_t) selected);
1460             skill_advance(n);
1461             /* check for more skills able to advance, if so then .. */
1462             for (n = i = 0; i < P_NUM_SKILLS; i++) {
1463                 if (can_advance(i, speedy)) {
1464                     if (!speedy)
1465 /*JP
1466                         You_feel("you could be more dangerous!");
1467 */
1468                         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");
1469                     n++;
1470                     break;
1471                 }
1472             }
1473         }
1474     } while (speedy && n > 0);
1475     return 0;
1476 }
1477
1478 /*
1479  * Change from restricted to unrestricted, allowing P_BASIC as max.  This
1480  * function may be called with with P_NONE.  Used in pray.c as well as below.
1481  */
1482 void
1483 unrestrict_weapon_skill(skill)
1484 int skill;
1485 {
1486     if (skill < P_NUM_SKILLS && P_RESTRICTED(skill)) {
1487         P_SKILL(skill) = P_UNSKILLED;
1488         P_MAX_SKILL(skill) = P_BASIC;
1489         P_ADVANCE(skill) = 0;
1490     }
1491 }
1492
1493 void
1494 use_skill(skill, degree)
1495 int skill;
1496 int degree;
1497 {
1498     boolean advance_before;
1499
1500     if (skill != P_NONE && !P_RESTRICTED(skill)) {
1501         advance_before = can_advance(skill, FALSE);
1502         P_ADVANCE(skill) += degree;
1503         if (!advance_before && can_advance(skill, FALSE))
1504             give_may_advance_msg(skill);
1505     }
1506 }
1507
1508 void
1509 add_weapon_skill(n)
1510 int n; /* number of slots to gain; normally one */
1511 {
1512     int i, before, after;
1513
1514     for (i = 0, before = 0; i < P_NUM_SKILLS; i++)
1515         if (can_advance(i, FALSE))
1516             before++;
1517     u.weapon_slots += n;
1518     for (i = 0, after = 0; i < P_NUM_SKILLS; i++)
1519         if (can_advance(i, FALSE))
1520             after++;
1521     if (before < after)
1522         give_may_advance_msg(P_NONE);
1523 }
1524
1525 void
1526 lose_weapon_skill(n)
1527 int n; /* number of slots to lose; normally one */
1528 {
1529     int skill;
1530
1531     while (--n >= 0) {
1532         /* deduct first from unused slots then from last placed one, if any */
1533         if (u.weapon_slots) {
1534             u.weapon_slots--;
1535         } else if (u.skills_advanced) {
1536             skill = u.skill_record[--u.skills_advanced];
1537             if (P_SKILL(skill) <= P_UNSKILLED)
1538                 panic("lose_weapon_skill (%d)", skill);
1539             P_SKILL(skill)--; /* drop skill one level */
1540             /* Lost skill might have taken more than one slot; refund rest. */
1541             u.weapon_slots = slots_required(skill) - 1;
1542             /* It might now be possible to advance some other pending
1543                skill by using the refunded slots, but giving a message
1544                to that effect would seem pretty confusing.... */
1545         }
1546     }
1547 }
1548
1549 int
1550 weapon_type(obj)
1551 struct obj *obj;
1552 {
1553     /* KMH -- now uses the object table */
1554     int type;
1555
1556     if (!obj)
1557         return P_BARE_HANDED_COMBAT; /* Not using a weapon */
1558     if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS
1559         && obj->oclass != GEM_CLASS)
1560         return P_NONE; /* Not a weapon, weapon-tool, or ammo */
1561     type = objects[obj->otyp].oc_skill;
1562     return (type < 0) ? -type : type;
1563 }
1564
1565 int
1566 uwep_skill_type()
1567 {
1568     if (u.twoweap)
1569         return P_TWO_WEAPON_COMBAT;
1570     return weapon_type(uwep);
1571 }
1572
1573 /*
1574  * Return hit bonus/penalty based on skill of weapon.
1575  * Treat restricted weapons as unskilled.
1576  */
1577 int
1578 weapon_hit_bonus(weapon)
1579 struct obj *weapon;
1580 {
1581     int type, wep_type, skill, bonus = 0;
1582     static const char bad_skill[] = "weapon_hit_bonus: bad skill %d";
1583
1584     wep_type = weapon_type(weapon);
1585     /* use two weapon skill only if attacking with one of the wielded weapons
1586      */
1587     type = (u.twoweap && (weapon == uwep || weapon == uswapwep))
1588                ? P_TWO_WEAPON_COMBAT
1589                : wep_type;
1590     if (type == P_NONE) {
1591         bonus = 0;
1592     } else if (type <= P_LAST_WEAPON) {
1593         switch (P_SKILL(type)) {
1594         default:
1595             impossible(bad_skill, P_SKILL(type)); /* fall through */
1596         case P_ISRESTRICTED:
1597         case P_UNSKILLED:
1598             bonus = -4;
1599             break;
1600         case P_BASIC:
1601             bonus = 0;
1602             break;
1603         case P_SKILLED:
1604             bonus = 2;
1605             break;
1606         case P_EXPERT:
1607             bonus = 3;
1608             break;
1609         }
1610     } else if (type == P_TWO_WEAPON_COMBAT) {
1611         skill = P_SKILL(P_TWO_WEAPON_COMBAT);
1612         if (P_SKILL(wep_type) < skill)
1613             skill = P_SKILL(wep_type);
1614         switch (skill) {
1615         default:
1616             impossible(bad_skill, skill); /* fall through */
1617         case P_ISRESTRICTED:
1618         case P_UNSKILLED:
1619             bonus = -9;
1620             break;
1621         case P_BASIC:
1622             bonus = -7;
1623             break;
1624         case P_SKILLED:
1625             bonus = -5;
1626             break;
1627         case P_EXPERT:
1628             bonus = -3;
1629             break;
1630         }
1631     } else if (type == P_BARE_HANDED_COMBAT) {
1632         /*
1633          *        b.h. m.a.
1634          * unskl:  +1  n/a
1635          * basic:  +1   +3
1636          * skild:  +2   +4
1637          * exprt:  +2   +5
1638          * mastr:  +3   +6
1639          * grand:  +3   +7
1640          */
1641         bonus = P_SKILL(type);
1642         bonus = max(bonus, P_UNSKILLED) - 1; /* unskilled => 0 */
1643         bonus = ((bonus + 2) * (martial_bonus() ? 2 : 1)) / 2;
1644     }
1645
1646     /* KMH -- It's harder to hit while you are riding */
1647     if (u.usteed) {
1648         switch (P_SKILL(P_RIDING)) {
1649         case P_ISRESTRICTED:
1650         case P_UNSKILLED:
1651             bonus -= 2;
1652             break;
1653         case P_BASIC:
1654             bonus -= 1;
1655             break;
1656         case P_SKILLED:
1657             break;
1658         case P_EXPERT:
1659             break;
1660         }
1661         if (u.twoweap)
1662             bonus -= 2;
1663     }
1664
1665     return bonus;
1666 }
1667
1668 /*
1669  * Return damage bonus/penalty based on skill of weapon.
1670  * Treat restricted weapons as unskilled.
1671  */
1672 int
1673 weapon_dam_bonus(weapon)
1674 struct obj *weapon;
1675 {
1676     int type, wep_type, skill, bonus = 0;
1677
1678     wep_type = weapon_type(weapon);
1679     /* use two weapon skill only if attacking with one of the wielded weapons
1680      */
1681     type = (u.twoweap && (weapon == uwep || weapon == uswapwep))
1682                ? P_TWO_WEAPON_COMBAT
1683                : wep_type;
1684     if (type == P_NONE) {
1685         bonus = 0;
1686     } else if (type <= P_LAST_WEAPON) {
1687         switch (P_SKILL(type)) {
1688         default:
1689             impossible("weapon_dam_bonus: bad skill %d", P_SKILL(type));
1690         /* fall through */
1691         case P_ISRESTRICTED:
1692         case P_UNSKILLED:
1693             bonus = -2;
1694             break;
1695         case P_BASIC:
1696             bonus = 0;
1697             break;
1698         case P_SKILLED:
1699             bonus = 1;
1700             break;
1701         case P_EXPERT:
1702             bonus = 2;
1703             break;
1704         }
1705     } else if (type == P_TWO_WEAPON_COMBAT) {
1706         skill = P_SKILL(P_TWO_WEAPON_COMBAT);
1707         if (P_SKILL(wep_type) < skill)
1708             skill = P_SKILL(wep_type);
1709         switch (skill) {
1710         default:
1711         case P_ISRESTRICTED:
1712         case P_UNSKILLED:
1713             bonus = -3;
1714             break;
1715         case P_BASIC:
1716             bonus = -1;
1717             break;
1718         case P_SKILLED:
1719             bonus = 0;
1720             break;
1721         case P_EXPERT:
1722             bonus = 1;
1723             break;
1724         }
1725     } else if (type == P_BARE_HANDED_COMBAT) {
1726         /*
1727          *        b.h. m.a.
1728          * unskl:   0  n/a
1729          * basic:  +1   +3
1730          * skild:  +1   +4
1731          * exprt:  +2   +6
1732          * mastr:  +2   +7
1733          * grand:  +3   +9
1734          */
1735         bonus = P_SKILL(type);
1736         bonus = max(bonus, P_UNSKILLED) - 1; /* unskilled => 0 */
1737         bonus = ((bonus + 1) * (martial_bonus() ? 3 : 1)) / 2;
1738     }
1739
1740     /* KMH -- Riding gives some thrusting damage */
1741     if (u.usteed && type != P_TWO_WEAPON_COMBAT) {
1742         switch (P_SKILL(P_RIDING)) {
1743         case P_ISRESTRICTED:
1744         case P_UNSKILLED:
1745             break;
1746         case P_BASIC:
1747             break;
1748         case P_SKILLED:
1749             bonus += 1;
1750             break;
1751         case P_EXPERT:
1752             bonus += 2;
1753             break;
1754         }
1755     }
1756
1757     return bonus;
1758 }
1759
1760 /*
1761  * Initialize weapon skill array for the game.  Start by setting all
1762  * skills to restricted, then set the skill for every weapon the
1763  * hero is holding, finally reading the given array that sets
1764  * maximums.
1765  */
1766 void
1767 skill_init(class_skill)
1768 const struct def_skill *class_skill;
1769 {
1770     struct obj *obj;
1771     int skmax, skill;
1772
1773     /* initialize skill array; by default, everything is restricted */
1774     for (skill = 0; skill < P_NUM_SKILLS; skill++) {
1775         P_SKILL(skill) = P_ISRESTRICTED;
1776         P_MAX_SKILL(skill) = P_ISRESTRICTED;
1777         P_ADVANCE(skill) = 0;
1778     }
1779
1780     /* Set skill for all weapons in inventory to be basic */
1781     for (obj = invent; obj; obj = obj->nobj) {
1782         /* don't give skill just because of carried ammo, wait until
1783            we see the relevant launcher (prevents an archeologist's
1784            touchstone from inadvertently providing skill in sling) */
1785         if (is_ammo(obj))
1786             continue;
1787
1788         skill = weapon_type(obj);
1789         if (skill != P_NONE)
1790             P_SKILL(skill) = P_BASIC;
1791     }
1792
1793     /* set skills for magic */
1794     if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
1795         P_SKILL(P_HEALING_SPELL) = P_BASIC;
1796     } else if (Role_if(PM_PRIEST)) {
1797         P_SKILL(P_CLERIC_SPELL) = P_BASIC;
1798     } else if (Role_if(PM_WIZARD)) {
1799         P_SKILL(P_ATTACK_SPELL) = P_BASIC;
1800         P_SKILL(P_ENCHANTMENT_SPELL) = P_BASIC;
1801     }
1802
1803     /* walk through array to set skill maximums */
1804     for (; class_skill->skill != P_NONE; class_skill++) {
1805         skmax = class_skill->skmax;
1806         skill = class_skill->skill;
1807
1808         P_MAX_SKILL(skill) = skmax;
1809         if (P_SKILL(skill) == P_ISRESTRICTED) /* skill pre-set */
1810             P_SKILL(skill) = P_UNSKILLED;
1811     }
1812
1813     /* High potential fighters already know how to use their hands. */
1814     if (P_MAX_SKILL(P_BARE_HANDED_COMBAT) > P_EXPERT)
1815         P_SKILL(P_BARE_HANDED_COMBAT) = P_BASIC;
1816
1817     /* Roles that start with a horse know how to ride it */
1818     if (urole.petnum == PM_PONY)
1819         P_SKILL(P_RIDING) = P_BASIC;
1820
1821     /*
1822      * Make sure we haven't missed setting the max on a skill
1823      * & set advance
1824      */
1825     for (skill = 0; skill < P_NUM_SKILLS; skill++) {
1826         if (!P_RESTRICTED(skill)) {
1827             if (P_MAX_SKILL(skill) < P_SKILL(skill)) {
1828                 impossible("skill_init: curr > max: %s", P_NAME(skill));
1829                 P_MAX_SKILL(skill) = P_SKILL(skill);
1830             }
1831             P_ADVANCE(skill) = practice_needed_to_advance(P_SKILL(skill) - 1);
1832         }
1833     }
1834
1835     /* each role has a special spell; allow at least basic for its type
1836        (despite the function name, this works for spell skills too) */
1837     unrestrict_weapon_skill(spell_skilltype(urole.spelspec));
1838 }
1839
1840 void
1841 setmnotwielded(mon, obj)
1842 register struct monst *mon;
1843 register struct obj *obj;
1844 {
1845     if (!obj)
1846         return;
1847     if (artifact_light(obj) && obj->lamplit) {
1848         end_burn(obj, FALSE);
1849         if (canseemon(mon))
1850 #if 0 /*JP:T*/
1851             pline("%s in %s %s %s shining.", The(xname(obj)),
1852                   s_suffix(mon_nam(mon)), mbodypart(mon, HAND),
1853                   otense(obj, "stop"));
1854 #else
1855             pline("%s\82ª\8e\9d\82Â%s\82Ì\8bP\82«\82ª\8fÁ\82¦\82½\81D",
1856                   mon_nam(mon), xname(obj));
1857 #endif
1858     }
1859     if (MON_WEP(mon) == obj)
1860         MON_NOWEP(mon);
1861     obj->owornmask &= ~W_WEP;
1862 }
1863
1864 /*weapon.c*/