OSDN Git Service

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