OSDN Git Service

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