OSDN Git Service

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