OSDN Git Service

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