1 /* NetHack 3.6 weapon.c $NHDT-Date: 1454660575 2016/02/05 08:22:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.57 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed. See license for details. */
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. */
12 * This module contains code for calculation of "to hit" and damage
13 * bonuses for any given weapon used, as well as weapons selection
19 /* Categories whose names don't come from OBJ_NAME(objects[type])
21 #define PN_BARE_HANDED (-1) /* includes martial arts */
22 #define PN_TWO_WEAPONS (-2)
23 #define PN_RIDING (-3)
24 #define PN_POLEARMS (-4)
26 #define PN_HAMMER (-6)
28 #define PN_ATTACK_SPELL (-8)
29 #define PN_HEALING_SPELL (-9)
30 #define PN_DIVINATION_SPELL (-10)
31 #define PN_ENCHANTMENT_SPELL (-11)
32 #define PN_CLERIC_SPELL (-12)
33 #define PN_ESCAPE_SPELL (-13)
34 #define PN_MATTER_SPELL (-14)
36 STATIC_DCL void FDECL(give_may_advance_msg, (int));
38 STATIC_VAR NEARDATA const short skill_names_indices[P_NUM_SKILLS] = {
39 0, DAGGER, KNIFE, AXE, PICK_AXE, SHORT_SWORD, BROADSWORD, LONG_SWORD,
40 TWO_HANDED_SWORD, SCIMITAR, PN_SABER, CLUB, MACE, MORNING_STAR, FLAIL,
41 PN_HAMMER, QUARTERSTAFF, PN_POLEARMS, SPEAR, TRIDENT, LANCE, BOW, SLING,
42 CROSSBOW, DART, SHURIKEN, BOOMERANG, PN_WHIP, UNICORN_HORN,
43 PN_ATTACK_SPELL, PN_HEALING_SPELL, PN_DIVINATION_SPELL,
44 PN_ENCHANTMENT_SPELL, PN_CLERIC_SPELL, PN_ESCAPE_SPELL, PN_MATTER_SPELL,
45 PN_BARE_HANDED, PN_TWO_WEAPONS, PN_RIDING
48 /* note: entry [0] isn't used */
49 STATIC_VAR NEARDATA const char *const odd_skill_names[] = {
51 "no skill", "bare hands", /* use barehands_or_martial[] instead */
52 "two weapon combat", "riding", "polearms", "saber", "hammer", "whip",
53 "attack spells", "healing spells", "divination spells",
54 "enchantment spells", "clerical spells", "escape spells", "matter spells",
56 "no skill", "
\91f
\8eè", /* use barehands_or_martial[] instead */
57 "
\93ñ
\93\81\97¬", "
\8bR
\8fæ", "
\92·
\95\80", "
\83T
\81[
\83x
\83\8b", "
\83n
\83\93\83}
\81[", "
\95Ú",
58 "
\8dU
\8c\82", "
\8e¡
\96ü", "
\97\
\92m",
59 "
\95â
\8f\95", "
\91m
\97µ", "
\92E
\8fo", "
\95¨
\8e¿",
62 /* indexed vis `is_martial() */
63 STATIC_VAR NEARDATA const char *const barehands_or_martial[] = {
65 "bare handed combat", "martial arts"
67 "
\91f
\8eè", "
\91Ì
\8fp"
72 give_may_advance_msg(skill)
76 You_feel("more confident in your %sskills.",
77 skill == P_NONE ? "" : skill <= P_LAST_WEAPON
79 : skill <= P_LAST_SPELL
83 You("%s
\83X
\83L
\83\8b\82ð
\8d\82\82ß
\82é
\8e©
\90M
\82ª
\97N
\82¢
\82Ä
\82«
\82½
\81D",
84 skill == P_NONE ? "" : skill <= P_LAST_WEAPON
86 : skill <= P_LAST_SPELL
92 STATIC_DCL boolean FDECL(can_advance, (int, BOOLEAN_P));
93 STATIC_DCL boolean FDECL(could_advance, (int));
94 STATIC_DCL boolean FDECL(peaked_skill, (int));
95 STATIC_DCL int FDECL(slots_required, (int));
96 STATIC_DCL char *FDECL(skill_level_name, (int, char *));
97 STATIC_DCL void FDECL(skill_advance, (int));
99 #define P_NAME(type) \
100 ((skill_names_indices[type] > 0) \
101 ? OBJ_NAME(objects[skill_names_indices[type]]) \
102 : (type == P_BARE_HANDED_COMBAT) \
103 ? barehands_or_martial[martial_bonus()] \
104 : odd_skill_names[-skill_names_indices[type]])
106 static NEARDATA const char kebabable[] = { S_XORN, S_DRAGON, S_JABBERWOCK,
107 S_NAGA, S_GIANT, '\0' };
109 /* weapon's skill category name for use as generalized description of weapon;
110 mostly used to shorten "you drop your <weapon>" messages when slippery
111 fingers or polymorph causes hero to involuntarily drop wielded weapon(s) */
116 int skill = weapon_type(obj);
117 const char *descr = P_NAME(skill);
119 /* assorted special cases */
122 /* not a weapon or weptool: use item class name;
123 override class name "food" for corpses, tins, and eggs,
124 "large rock" for statues and boulders, and "tool" for towels */
125 descr = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG
126 || obj->otyp == STATUE || obj->otyp == BOULDER
127 || obj->otyp == TOWEL)
128 ? OBJ_NAME(objects[obj->otyp])
129 : def_oc_syms[(int) obj->oclass].name;
133 descr = (obj->otyp == ROCK || is_graystone(obj))
138 /* avoid "rock"; what about known glass? */
139 : (obj->oclass == GEM_CLASS)
144 /* in case somebody adds odd sling ammo */
145 : def_oc_syms[(int) obj->oclass].name;
159 descr = "
\83{
\83\8b\83g";
162 if (obj->otyp == GRAPPLING_HOOK)
166 descr = "
\83t
\83b
\83N";
169 /* even if "dwarvish mattock" hasn't been discovered yet */
170 if (obj->otyp == DWARVISH_MATTOCK)
174 descr = "
\82Â
\82é
\82Í
\82µ";
179 return makesingular(descr);
183 * hitval returns an integer representing the "to hit" bonuses
184 * of "otmp" against the monster.
192 struct permonst *ptr = mon->data;
193 boolean Is_weapon = (otmp->oclass == WEAPON_CLASS || is_weptool(otmp));
198 /* Put weapon specific "to hit" bonuses in below: */
199 tmp += objects[otmp->otyp].oc_hitbon;
201 /* Put weapon vs. monster type "to hit" bonuses in below: */
203 /* Blessed weapons used against undead or demons */
204 if (Is_weapon && otmp->blessed
205 && (is_demon(ptr) || is_undead(ptr) || is_vampshifter(mon)))
208 if (is_spear(otmp) && index(kebabable, ptr->mlet))
211 /* trident is highly effective against swimmers */
212 if (otmp->otyp == TRIDENT && is_swimmer(ptr)) {
213 if (is_pool(mon->mx, mon->my))
215 else if (ptr->mlet == S_EEL || ptr->mlet == S_SNAKE)
219 /* Picks used against xorns and earth elementals */
220 if (is_pick(otmp) && (passes_walls(ptr) && thick_skinned(ptr)))
223 /* Check specially named weapon "to hit" bonuses */
225 tmp += spec_abon(otmp, mon);
230 /* Historical note: The original versions of Hack used a range of damage
231 * which was similar to, but not identical to the damage used in Advanced
232 * Dungeons and Dragons. I figured that since it was so close, I may as well
233 * make it exactly the same as AD&D, adding some more weapons in the process.
234 * This has the advantage that it is at least possible that the player would
235 * already know the damage of at least some of the weapons. This was circa
236 * 1987 and I used the table from Unearthed Arcana until I got tired of typing
237 * them in (leading to something of an imbalance towards weapons early in
238 * alphabetical order). The data structure still doesn't include fields that
239 * fully allow the appropriate damage to be described (there's no way to say
240 * 3d6 or 1d6+1) so we add on the extra damage in dmgval() if the weapon
241 * doesn't do an exact die of damage.
243 * Of course new weapons were added later in the development of Nethack. No
244 * AD&D consistency was kept, but most of these don't exist in AD&D anyway.
246 * Second edition AD&D came out a few years later; luckily it used the same
247 * table. As of this writing (1999), third edition is in progress but not
248 * released. Let's see if the weapon table stays the same. --KAA
249 * October 2000: It didn't. Oh, well.
253 * dmgval returns an integer representing the damage bonuses
254 * of "otmp" against the monster.
261 int tmp = 0, otyp = otmp->otyp;
262 struct permonst *ptr = mon->data;
263 boolean Is_weapon = (otmp->oclass == WEAPON_CLASS || is_weptool(otmp));
265 if (otyp == CREAM_PIE)
269 if (objects[otyp].oc_wldam)
270 tmp = rnd(objects[otyp].oc_wldam);
277 case ELVEN_BROADSWORD:
301 case DWARVISH_MATTOCK:
302 case TWO_HANDED_SWORD:
307 if (objects[otyp].oc_wsdam)
308 tmp = rnd(objects[otyp].oc_wsdam);
328 case ELVEN_BROADSWORD:
341 /* negative enchantment mustn't produce negative damage */
346 if (objects[otyp].oc_material <= LEATHER && thick_skinned(ptr))
347 /* thick skinned/scaled creatures don't feel it */
349 if (ptr == &mons[PM_SHADE] && !shade_glare(otmp))
352 /* "very heavy iron ball"; weight increase is in increments */
353 if (otyp == HEAVY_IRON_BALL && tmp > 0) {
354 int wt = (int) objects[HEAVY_IRON_BALL].oc_weight;
356 if ((int) otmp->owt > wt) {
357 wt = ((int) otmp->owt - wt) / IRON_BALL_W_INCR;
360 tmp = 25; /* objects[].oc_wldam */
364 /* Put weapon vs. monster type damage bonuses in below: */
365 if (Is_weapon || otmp->oclass == GEM_CLASS || otmp->oclass == BALL_CLASS
366 || otmp->oclass == CHAIN_CLASS) {
370 && (is_undead(ptr) || is_demon(ptr) || is_vampshifter(mon)))
372 if (is_axe(otmp) && is_wooden(ptr))
374 if (objects[otyp].oc_material == SILVER && mon_hates_silver(mon))
377 /* if the weapon is going to get a double damage bonus, adjust
378 this bonus so that effectively it's added after the doubling */
379 if (bonus > 1 && otmp->oartifact && spec_dbon(otmp, mon, 25) >= 25)
380 bonus = (bonus + 1) / 2;
386 /* It's debatable whether a rusted blunt instrument
387 should do less damage than a pristine one, since
388 it will hit with essentially the same impact, but
389 there ought to some penalty for using damaged gear
390 so always subtract erosion even for blunt weapons. */
391 tmp -= greatest_erosion(otmp);
399 STATIC_DCL struct obj *FDECL(oselect, (struct monst *, int));
401 if ((otmp = oselect(mtmp, x)) != 0) \
404 STATIC_OVL struct obj *
411 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
413 /* never select non-cockatrice corpses */
414 && !((x == CORPSE || x == EGG)
415 && !touch_petrifies(&mons[otmp->corpsenm]))
416 && (!otmp->oartifact || touch_artifact(otmp, mtmp)))
419 return (struct obj *) 0;
422 static NEARDATA const int rwep[] = {
423 DWARVISH_SPEAR, SILVER_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, JAVELIN,
424 SHURIKEN, YA, SILVER_ARROW, ELVEN_ARROW, ARROW, ORCISH_ARROW,
425 CROSSBOW_BOLT, SILVER_DAGGER, ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, KNIFE,
426 FLINT, ROCK, LOADSTONE, LUCKSTONE, DART,
427 /* BOOMERANG, */ CREAM_PIE
430 static NEARDATA const int pwep[] = { HALBERD, BARDICHE, SPETUM,
431 BILL_GUISARME, VOULGE, RANSEUR,
432 GUISARME, GLAIVE, LUCERN_HAMMER,
433 BEC_DE_CORBIN, FAUCHARD, PARTISAN,
436 static struct obj *propellor;
438 /* select a ranged weapon for the monster */
441 register struct monst *mtmp;
443 register struct obj *otmp;
448 char mlet = mtmp->data->mlet;
450 propellor = &zeroobj;
451 Oselect(EGG); /* cockatrice egg */
452 if (mlet == S_KOP) /* pies are first choice for Kops */
454 if (throws_rocks(mtmp->data)) /* ...boulders for giants */
457 /* Select polearms first; they do more damage and aren't expendable.
458 But don't pick one if monster's weapon is welded, because then
459 we'd never have a chance to throw non-wielding missiles. */
460 /* The limit of 13 here is based on the monster polearm range limit
461 * (defined as 5 in mthrowu.c). 5 corresponds to a distance of 2 in
462 * one direction and 1 in another; one space beyond that would be 3 in
463 * one direction and 2 in another; 3^2+2^2=13.
465 mwep = MON_WEP(mtmp);
466 /* NO_WEAPON_WANTED means we already tried to wield and failed */
467 mweponly = (mwelded(mwep) && mtmp->weapon_check == NO_WEAPON_WANTED);
468 if (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 13
469 && couldsee(mtmp->mx, mtmp->my)) {
470 for (i = 0; i < SIZE(pwep); i++) {
471 /* Only strong monsters can wield big (esp. long) weapons.
472 * Big weapon is basically the same as bimanual.
473 * All monsters can wield the remaining weapons.
475 if (((strongmonst(mtmp->data)
476 && (mtmp->misc_worn_check & W_ARMS) == 0)
477 || !objects[pwep[i]].oc_bimanual)
478 && (objects[pwep[i]].oc_material != SILVER
479 || !mon_hates_silver(mtmp))) {
480 if ((otmp = oselect(mtmp, pwep[i])) != 0
481 && (otmp == mwep || !mweponly)) {
482 propellor = otmp; /* force the monster to wield it */
490 * other than these two specific cases, always select the
491 * most potent ranged weapon to hand.
493 for (i = 0; i < SIZE(rwep); i++) {
496 /* shooting gems from slings; this goes just before the darts */
497 /* (shooting rocks is already handled via the rwep[] ordering) */
498 if (rwep[i] == DART && !likes_gems(mtmp->data)
499 && m_carrying(mtmp, SLING)) { /* propellor */
500 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
501 if (otmp->oclass == GEM_CLASS
502 && (otmp->otyp != LOADSTONE || !otmp->cursed)) {
503 propellor = m_carrying(mtmp, SLING);
508 /* KMH -- This belongs here so darts will work */
509 propellor = &zeroobj;
511 prop = (objects[rwep[i]]).oc_skill;
515 propellor = (oselect(mtmp, YUMI));
517 propellor = (oselect(mtmp, ELVEN_BOW));
519 propellor = (oselect(mtmp, BOW));
521 propellor = (oselect(mtmp, ORCISH_BOW));
524 propellor = (oselect(mtmp, SLING));
527 propellor = (oselect(mtmp, CROSSBOW));
529 if ((otmp = MON_WEP(mtmp)) && mwelded(otmp) && otmp != propellor
530 && mtmp->weapon_check == NO_WEAPON_WANTED)
533 /* propellor = obj, propellor to use
534 * propellor = &zeroobj, doesn't need a propellor
535 * propellor = 0, needed one and didn't have one
537 if (propellor != 0) {
538 /* Note: cannot use m_carrying for loadstones, since it will
539 * always select the first object of a type, and maybe the
540 * monster is carrying two but only the first is unthrowable.
542 if (rwep[i] != LOADSTONE) {
543 /* Don't throw a cursed weapon-in-hand or an artifact */
544 if ((otmp = oselect(mtmp, rwep[i])) && !otmp->oartifact
545 && !(otmp == MON_WEP(mtmp) && mwelded(otmp)))
548 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
549 if (otmp->otyp == LOADSTONE && !otmp->cursed)
556 return (struct obj *) 0;
559 /* Weapons in order of preference */
560 static const NEARDATA short hwep[] = {
561 CORPSE, /* cockatrice corpse */
562 TSURUGI, RUNESWORD, DWARVISH_MATTOCK, TWO_HANDED_SWORD, BATTLE_AXE,
563 KATANA, UNICORN_HORN, CRYSKNIFE, TRIDENT, LONG_SWORD, ELVEN_BROADSWORD,
564 BROADSWORD, SCIMITAR, SILVER_SABER, MORNING_STAR, ELVEN_SHORT_SWORD,
565 DWARVISH_SHORT_SWORD, SHORT_SWORD, ORCISH_SHORT_SWORD, MACE, AXE,
566 DWARVISH_SPEAR, SILVER_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, FLAIL,
567 BULLWHIP, QUARTERSTAFF, JAVELIN, AKLYS, CLUB, PICK_AXE, RUBBER_HOSE,
568 WAR_HAMMER, SILVER_DAGGER, ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, ATHAME,
569 SCALPEL, KNIFE, WORM_TOOTH
572 /* select a hand to hand weapon for the monster */
575 register struct monst *mtmp;
577 register struct obj *otmp;
579 boolean strong = strongmonst(mtmp->data);
580 boolean wearing_shield = (mtmp->misc_worn_check & W_ARMS) != 0;
582 /* prefer artifacts to everything else */
583 for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) {
584 if (otmp->oclass == WEAPON_CLASS && otmp->oartifact
585 && touch_artifact(otmp, mtmp)
586 && ((strong && !wearing_shield)
587 || !objects[otmp->otyp].oc_bimanual))
591 if (is_giant(mtmp->data)) /* giants just love to use clubs */
594 /* only strong monsters can wield big (esp. long) weapons */
595 /* big weapon is basically the same as bimanual */
596 /* all monsters can wield the remaining weapons */
597 for (i = 0; i < SIZE(hwep); i++) {
598 if (hwep[i] == CORPSE && !(mtmp->misc_worn_check & W_ARMG)
599 && !resists_ston(mtmp))
601 if (((strong && !wearing_shield) || !objects[hwep[i]].oc_bimanual)
602 && (objects[hwep[i]].oc_material != SILVER
603 || !mon_hates_silver(mtmp)))
608 return (struct obj *) 0;
611 /* Called after polymorphing a monster, robbing it, etc.... Monsters
612 * otherwise never unwield stuff on their own. Might print message.
615 possibly_unwield(mon, polyspot)
619 struct obj *obj, *mw_tmp;
621 if (!(mw_tmp = MON_WEP(mon)))
623 for (obj = mon->minvent; obj; obj = obj->nobj)
626 if (!obj) { /* The weapon was stolen or destroyed */
628 mon->weapon_check = NEED_WEAPON;
631 if (!attacktype(mon->data, AT_WEAP)) {
632 setmnotwielded(mon, mw_tmp);
633 mon->weapon_check = NO_WEAPON_WANTED;
634 obj_extract_self(obj);
635 if (cansee(mon->mx, mon->my)) {
637 pline("%s drops %s.", Monnam(mon), distant_name(obj, doname));
639 pline("%s
\82Í%s
\82ð
\92u
\82¢
\82½
\81D", Monnam(mon), distant_name(obj, doname));
640 newsym(mon->mx, mon->my);
642 /* might be dropping object into water or lava */
644 if (!flooreffects(obj, mon->mx, mon->my, "drop")) {
646 if (!flooreffects(obj, mon->mx, mon->my, "
\97\8e\82¿
\82é")) {
649 place_object(obj, mon->mx, mon->my);
654 /* The remaining case where there is a change is where a monster
655 * is polymorphed into a stronger/weaker monster with a different
656 * choice of weapons. This has no parallel for players. It can
657 * be handled by waiting until mon_wield_item is actually called.
658 * Though the monster still wields the wrong weapon until then,
659 * this is OK since the player can't see it. (FIXME: Not okay since
660 * probing can reveal it.)
661 * Note that if there is no change, setting the check to NEED_WEAPON
663 * Possible problem: big monster with big cursed weapon gets
664 * polymorphed into little monster. But it's not quite clear how to
665 * handle this anyway....
667 if (!(mwelded(mw_tmp) && mon->weapon_check == NO_WEAPON_WANTED))
668 mon->weapon_check = NEED_WEAPON;
672 /* Let a monster try to wield a weapon, based on mon->weapon_check.
673 * Returns 1 if the monster took time to do it, 0 if it did not.
677 register struct monst *mon;
681 /* This case actually should never happen */
682 if (mon->weapon_check == NO_WEAPON_WANTED)
684 switch (mon->weapon_check) {
685 case NEED_HTH_WEAPON:
686 obj = select_hwep(mon);
688 case NEED_RANGED_WEAPON:
689 (void) select_rwep(mon);
693 obj = m_carrying(mon, PICK_AXE);
694 /* KMH -- allow other picks */
695 if (!obj && !which_armor(mon, W_ARMS))
696 obj = m_carrying(mon, DWARVISH_MATTOCK);
699 /* currently, only 2 types of axe */
700 obj = m_carrying(mon, BATTLE_AXE);
701 if (!obj || which_armor(mon, W_ARMS))
702 obj = m_carrying(mon, AXE);
704 case NEED_PICK_OR_AXE:
705 /* prefer pick for fewer switches on most levels */
706 obj = m_carrying(mon, DWARVISH_MATTOCK);
708 obj = m_carrying(mon, BATTLE_AXE);
709 if (!obj || which_armor(mon, W_ARMS)) {
710 obj = m_carrying(mon, PICK_AXE);
712 obj = m_carrying(mon, AXE);
716 impossible("weapon_check %d for %s?", mon->weapon_check,
720 if (obj && obj != &zeroobj) {
721 struct obj *mw_tmp = MON_WEP(mon);
722 if (mw_tmp && mw_tmp->otyp == obj->otyp) {
723 /* already wielding it */
724 mon->weapon_check = NEED_WEAPON;
727 /* Actually, this isn't necessary--as soon as the monster
728 * wields the weapon, the weapon welds itself, so the monster
729 * can know it's cursed and needn't even bother trying.
732 if (mw_tmp && mwelded(mw_tmp)) {
733 if (canseemon(mon)) {
735 char welded_buf[BUFSZ];
737 const char *mon_hand = mbodypart(mon, HAND);
739 if (bimanual(mw_tmp))
740 mon_hand = makeplural(mon_hand);
742 Sprintf(welded_buf, "%s welded to %s %s",
743 otense(mw_tmp, "are"), mhis(mon), mon_hand);
746 if (obj->otyp == PICK_AXE) {
748 pline("Since %s weapon%s %s,", s_suffix(mon_nam(mon)),
749 plur(mw_tmp->quan), welded_buf);
751 pline("%s
\82Í
\95\90\8aí
\82ð
\8eè
\82É
\82µ
\82æ
\82¤
\82Æ
\82µ
\82½
\82ª
\81C", mon_nam(mon));
754 pline("%s cannot wield that %s.", mon_nam(mon),
757 pline("%s
\82Í%s
\82ð
\91\95\94õ
\82Å
\82«
\82È
\82©
\82Á
\82½
\81D", mon_nam(mon),
762 pline("%s tries to wield %s.", Monnam(mon), doname(obj));
764 pline("%s
\82Í%s
\82ð
\91\95\94õ
\82µ
\82æ
\82¤
\82Æ
\82µ
\82½
\81D", Monnam(mon), doname(obj));
766 pline("%s %s!", Yname2(mw_tmp), welded_buf);
768 pline("%s
\82Í%s
\82ð
\8eè
\82É
\82µ
\82½
\81I", Monnam(mon), xname(mw_tmp));
772 mon->weapon_check = NO_WEAPON_WANTED;
775 mon->mw = obj; /* wield obj */
776 setmnotwielded(mon, mw_tmp);
777 mon->weapon_check = NEED_WEAPON;
778 if (canseemon(mon)) {
780 pline("%s wields %s!", Monnam(mon), doname(obj));
782 pline("%s
\82Í%s
\82ð
\91\95\94õ
\82µ
\82½
\81I", Monnam(mon), doname(obj));
783 if (mwelded(mw_tmp)) {
785 pline("%s %s to %s %s!", Tobjnam(obj, "weld"),
786 is_plural(obj) ? "themselves" : "itself",
787 s_suffix(mon_nam(mon)), mbodypart(mon, HAND));
789 pline("%s
\82Í
\8f\9f\8eè
\82É%s
\82Ì%s
\82É
\91\95\94õ
\82³
\82ê
\82½
\81I",
791 mon_nam(mon), mbodypart(mon, HAND));
796 if (artifact_light(obj) && !obj->lamplit) {
797 begin_burn(obj, FALSE);
800 pline("%s %s in %s %s!", Tobjnam(obj, "shine"),
801 arti_light_description(obj), s_suffix(mon_nam(mon)),
802 mbodypart(mon, HAND));
804 pline("%s
\82Í%s
\82Ì%s
\82Ì
\92\86\82Å%s
\8bP
\82¢
\82½
\81I",
805 xname(obj), mon_nam(mon),
806 mbodypart(mon, HAND), arti_light_description(obj));
809 obj->owornmask = W_WEP;
812 mon->weapon_check = NEED_WEAPON;
816 /* force monster to stop wielding current weapon, if any */
821 struct obj *mwep = MON_WEP(mon);
824 setmnotwielded(mon, mwep);
825 mon->weapon_check = NEED_WEAPON;
829 /* attack bonus for strength & dexterity */
834 int str = ACURR(A_STR), dex = ACURR(A_DEX);
837 return (adj_lev(&mons[u.umonnum]) - 3);
844 else if (str <= STR18(50))
845 sbon = 1; /* up to 18/50 */
846 else if (str < STR18(100))
851 /* Game tuning kludge: make it a bit easier for a low level character to
853 sbon += (u.ulevel < 3) ? 1 : 0;
864 return (sbon + dex - 14);
867 /* damage bonus for strength */
871 int str = ACURR(A_STR);
883 return 2; /* up to 18 */
884 else if (str <= STR18(75))
885 return 3; /* up to 18/75 */
886 else if (str <= STR18(90))
887 return 4; /* up to 18/90 */
888 else if (str < STR18(100))
889 return 5; /* up to 18/99 */
894 /* increase a towel's wetness */
896 wet_a_towel(obj, amt, verbose)
898 int amt; /* positive: new value; negative: increment by -amt; zero: no-op */
901 int newspe = (amt <= 0) ? obj->spe - amt : amt;
903 /* new state is only reported if it's an increase */
904 if (newspe > obj->spe) {
907 const char *wetness = (newspe < 3)
908 ? (!obj->spe ? "damp" : "damper")
909 : (!obj->spe ? "wet" : "wetter");
911 const char *wetness = (newspe < 3)
912 ? (!obj->spe ? "
\8e¼
\82Á
\82½" : "
\82³
\82ç
\82É
\8e¼
\82Á
\82½")
913 : (!obj->spe ? "
\94G
\82ê
\82½" : "
\82³
\82ç
\82É
\94G
\82ê
\82½");
918 pline("%s gets %s.", Yobjnam2(obj, (const char *) 0),
921 pline("%s
\82Í%s
\81D", Yobjnam2(obj, (const char *) 0),
924 else if (mcarried(obj) && canseemon(obj->ocarry))
926 pline("%s %s gets %s.", s_suffix(Monnam(obj->ocarry)),
927 xname(obj), wetness);
929 pline("%s
\82Ì%s
\82Í%s
\81D", Monnam(obj->ocarry),
930 xname(obj), wetness);
934 obj->spe = min(newspe, 7);
936 /* if hero is wielding this towel, don't give "you begin bashing
937 with your wet towel" message on next attack with it */
939 unweapon = !is_wet_towel(obj);
942 /* decrease a towel's wetness */
944 dry_a_towel(obj, amt, verbose)
946 int amt; /* positive: new value; negative: decrement by -amt; zero: no-op */
949 int newspe = (amt <= 0) ? obj->spe + amt : amt;
951 /* new state is only reported if it's a decrease */
952 if (newspe < obj->spe) {
956 pline("%s dries%s.", Yobjnam2(obj, (const char *) 0),
957 !newspe ? " out" : "");
959 pline("%s
\82Í%s
\81D", Yobjnam2(obj, (const char *) 0),
960 !newspe ? "
\8a£
\82«
\82«
\82Á
\82½" : "
\8a£
\82¢
\82½");
962 else if (mcarried(obj) && canseemon(obj->ocarry))
964 pline("%s %s drie%s.", s_suffix(Monnam(obj->ocarry)),
965 xname(obj), !newspe ? " out" : "");
967 pline("%s
\82Ì%s
\82Í%s
\81D", Monnam(obj->ocarry),
968 xname(obj), !newspe ? "
\8a£
\82«
\82«
\82Á
\82½" : "
\8a£
\82¢
\82½");
972 newspe = min(newspe, 7);
973 obj->spe = max(newspe, 0);
975 /* if hero is wielding this towel and it is now dry, give "you begin
976 bashing with your towel" message on next attack with it */
978 unweapon = !is_wet_towel(obj);
981 /* copy the skill level name into the given buffer */
983 skill_level_name(skill, buf)
989 switch (P_SKILL(skill)) {
994 ptr = "
\8f\89\90S
\8eÒ";
1000 ptr = "
\93ü
\96å
\8eÒ";
1006 ptr = "
\8fn
\97û
\8eÒ";
1012 ptr = "
\83G
\83L
\83X
\83p
\81[
\83g";
1014 /* these are for unarmed combat/martial arts only */
1019 ptr = "
\83}
\83X
\83^
\81[";
1021 case P_GRAND_MASTER:
1023 ptr = "Grand Master";
1025 ptr = "
\83O
\83\89\83\93\83h
\83}
\83X
\83^
\81[";
1038 /* return the # of slots required to advance the skill */
1040 slots_required(skill)
1043 int tmp = P_SKILL(skill);
1045 /* The more difficult the training, the more slots it takes.
1046 * unskilled -> basic 1
1047 * basic -> skilled 2
1048 * skilled -> expert 3
1050 if (skill <= P_LAST_WEAPON || skill == P_TWO_WEAPON_COMBAT)
1053 /* Fewer slots used up for unarmed or martial.
1054 * unskilled -> basic 1
1055 * basic -> skilled 1
1056 * skilled -> expert 2
1057 * expert -> master 2
1058 * master -> grand master 3
1060 return (tmp + 1) / 2;
1063 /* return true if this skill can be advanced */
1066 can_advance(skill, speedy)
1070 if (P_RESTRICTED(skill)
1071 || P_SKILL(skill) >= P_MAX_SKILL(skill)
1072 || u.skills_advanced >= P_SKILL_LIMIT)
1075 if (wizard && speedy)
1078 return (boolean) ((int) P_ADVANCE(skill)
1079 >= practice_needed_to_advance(P_SKILL(skill))
1080 && u.weapon_slots >= slots_required(skill));
1083 /* return true if this skill could be advanced if more slots were available */
1085 could_advance(skill)
1088 if (P_RESTRICTED(skill)
1089 || P_SKILL(skill) >= P_MAX_SKILL(skill)
1090 || u.skills_advanced >= P_SKILL_LIMIT)
1093 return (boolean) ((int) P_ADVANCE(skill)
1094 >= practice_needed_to_advance(P_SKILL(skill)));
1097 /* return true if this skill has reached its maximum and there's been enough
1098 practice to become eligible for the next step if that had been possible */
1103 if (P_RESTRICTED(skill))
1106 return (boolean) (P_SKILL(skill) >= P_MAX_SKILL(skill)
1107 && ((int) P_ADVANCE(skill)
1108 >= practice_needed_to_advance(P_SKILL(skill))));
1112 skill_advance(skill)
1115 u.weapon_slots -= slots_required(skill);
1117 u.skill_record[u.skills_advanced++] = skill;
1118 /* subtly change the advance message to indicate no more advancement */
1120 You("are now %s skilled in %s.",
1121 P_SKILL(skill) >= P_MAX_SKILL(skill) ? "most" : "more",
1124 Your("%s
\82Ì
\83X
\83L
\83\8b\82ð%s
\8d\82\82ß
\82½
\81D",
1126 P_SKILL(skill) >= P_MAX_SKILL(skill) ? "
\8dÅ
\8d\82\82É" : "
\82³
\82ç
\82É");
1130 static const struct skill_range {
1133 } skill_ranges[] = {
1135 { P_FIRST_H_TO_H, P_LAST_H_TO_H, "Fighting Skills" },
1137 { P_FIRST_H_TO_H, P_LAST_H_TO_H, "
\90í
\82¢
\82Ì
\83X
\83L
\83\8b" },
1139 { P_FIRST_WEAPON, P_LAST_WEAPON, "Weapon Skills" },
1141 { P_FIRST_WEAPON, P_LAST_WEAPON, "
\95\90\8aí
\82Ì
\83X
\83L
\83\8b" },
1143 { P_FIRST_SPELL, P_LAST_SPELL, "Spellcasting Skills" },
1145 { P_FIRST_SPELL, P_LAST_SPELL, "
\96\82\96@
\82Ì
\83X
\83L
\83\8b" },
1149 * The `#enhance' extended command. What we _really_ would like is
1150 * to keep being able to pick things to advance until we couldn't any
1151 * more. This is currently not possible -- the menu code has no way
1152 * to call us back for instant action. Even if it did, we would also need
1153 * to be able to update the menu since selecting one item could make
1154 * others unselectable.
1157 enhance_weapon_skill()
1159 int pass, i, n, len, longest, to_advance, eventually_advance, maxxed_cnt;
1160 char buf[BUFSZ], sklnambuf[BUFSZ];
1162 menu_item *selected;
1165 boolean speedy = FALSE;
1167 if (wizard && yn("Advance skills without practice?") == 'y')
1171 /* find longest available skill name, count those that can advance */
1172 to_advance = eventually_advance = maxxed_cnt = 0;
1173 for (longest = 0, i = 0; i < P_NUM_SKILLS; i++) {
1174 if (P_RESTRICTED(i))
1176 if ((len = strlen(P_NAME(i))) > longest)
1178 if (can_advance(i, speedy))
1180 else if (could_advance(i))
1181 eventually_advance++;
1182 else if (peaked_skill(i))
1186 win = create_nhwindow(NHW_MENU);
1189 /* start with a legend if any entries will be annotated
1190 with "*" or "#" below */
1191 if (eventually_advance > 0 || maxxed_cnt > 0) {
1193 if (eventually_advance > 0) {
1195 Sprintf(buf, "(Skill%s flagged by \"*\" may be enhanced %s.)",
1196 plur(eventually_advance),
1197 (u.ulevel < MAXULEV)
1198 ? "when you're more experienced"
1199 : "if skill slots become available");
1201 Sprintf(buf, "(\"*\"
\82ª
\82Â
\82¢
\82Ä
\82¢
\82é
\83X
\83L
\83\8b\82Í%s
\8d\82\82ß
\82ç
\82ê
\82é
\81D)",
1202 (u.ulevel < MAXULEV)
1203 ? "
\82à
\82Á
\82Æ
\8co
\8c±
\82ð
\82Â
\82ß
\82Î"
1204 : "
\83X
\83L
\83\8b\83X
\83\8d\83b
\83g
\82ª
\8eg
\82¦
\82é
\82æ
\82¤
\82É
\82È
\82ê
\82Î");
1206 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1209 if (maxxed_cnt > 0) {
1212 "(Skill%s flagged by \"#\" cannot be enhanced any further.)",
1216 "(\"#\"
\82ª
\82Â
\82¢
\82Ä
\82¢
\82é
\83X
\83L
\83\8b\82Í
\82±
\82ê
\88È
\8fã
\8d\82\82ß
\82ç
\82ê
\82È
\82¢
\81D)");
1218 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1221 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "",
1225 /* List the skills, making ones that could be advanced
1226 selectable. List the miscellaneous skills first.
1227 Possible future enhancement: list spell skills before
1228 weapon skills for spellcaster roles. */
1229 for (pass = 0; pass < SIZE(skill_ranges); pass++)
1230 for (i = skill_ranges[pass].first; i <= skill_ranges[pass].last;
1232 /* Print headings for skill types */
1234 if (i == skill_ranges[pass].first)
1235 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
1236 skill_ranges[pass].name, MENU_UNSELECTED);
1238 if (P_RESTRICTED(i))
1241 * Sigh, this assumes a monospaced font unless
1242 * iflags.menu_tab_sep is set in which case it puts
1243 * tabs between columns.
1244 * The 12 is the longest skill level name.
1245 * The " " is room for a selection letter and dash, "a - ".
1247 if (can_advance(i, speedy))
1248 prefix = ""; /* will be preceded by menu choice */
1249 else if (could_advance(i))
1251 else if (peaked_skill(i))
1255 (to_advance + eventually_advance + maxxed_cnt > 0)
1258 (void) skill_level_name(i, sklnambuf);
1260 if (!iflags.menu_tab_sep)
1261 Sprintf(buf, " %s%-*s %-12s %5d(%4d)", prefix,
1262 longest, P_NAME(i), sklnambuf, P_ADVANCE(i),
1263 practice_needed_to_advance(P_SKILL(i)));
1265 Sprintf(buf, " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i),
1266 sklnambuf, P_ADVANCE(i),
1267 practice_needed_to_advance(P_SKILL(i)));
1269 if (!iflags.menu_tab_sep)
1270 Sprintf(buf, " %s %-*s [%s]", prefix, longest,
1271 P_NAME(i), sklnambuf);
1273 Sprintf(buf, " %s%s\t[%s]", prefix, P_NAME(i),
1276 any.a_int = can_advance(i, speedy) ? i + 1 : 0;
1277 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
1282 Strcpy(buf, (to_advance > 0) ? "Pick a skill to advance:"
1283 : "Current skills:");
1285 Strcpy(buf, (to_advance > 0) ? "
\83X
\83L
\83\8b\82ð
\91I
\91ð
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81F"
1286 : "
\8c»
\8dÝ
\82Ì
\83X
\83L
\83\8b\81F");
1288 if (wizard && !speedy)
1289 Sprintf(eos(buf), " (%d slot%s available)", u.weapon_slots,
1290 plur(u.weapon_slots));
1292 n = select_menu(win, to_advance ? PICK_ONE : PICK_NONE, &selected);
1293 destroy_nhwindow(win);
1295 n = selected[0].item.a_int - 1; /* get item selected */
1296 free((genericptr_t) selected);
1298 /* check for more skills able to advance, if so then .. */
1299 for (n = i = 0; i < P_NUM_SKILLS; i++) {
1300 if (can_advance(i, speedy)) {
1303 You_feel("you could be more dangerous!");
1305 You("
\82³
\82ç
\82É
\83X
\83L
\83\8b\82ð
\8d\82\82ß
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82»
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81I");
1311 } while (speedy && n > 0);
1316 * Change from restricted to unrestricted, allowing P_BASIC as max. This
1317 * function may be called with with P_NONE. Used in pray.c as well as below.
1320 unrestrict_weapon_skill(skill)
1323 if (skill < P_NUM_SKILLS && P_RESTRICTED(skill)) {
1324 P_SKILL(skill) = P_UNSKILLED;
1325 P_MAX_SKILL(skill) = P_BASIC;
1326 P_ADVANCE(skill) = 0;
1331 use_skill(skill, degree)
1335 boolean advance_before;
1337 if (skill != P_NONE && !P_RESTRICTED(skill)) {
1338 advance_before = can_advance(skill, FALSE);
1339 P_ADVANCE(skill) += degree;
1340 if (!advance_before && can_advance(skill, FALSE))
1341 give_may_advance_msg(skill);
1347 int n; /* number of slots to gain; normally one */
1349 int i, before, after;
1351 for (i = 0, before = 0; i < P_NUM_SKILLS; i++)
1352 if (can_advance(i, FALSE))
1354 u.weapon_slots += n;
1355 for (i = 0, after = 0; i < P_NUM_SKILLS; i++)
1356 if (can_advance(i, FALSE))
1359 give_may_advance_msg(P_NONE);
1363 lose_weapon_skill(n)
1364 int n; /* number of slots to lose; normally one */
1369 /* deduct first from unused slots then from last placed one, if any */
1370 if (u.weapon_slots) {
1372 } else if (u.skills_advanced) {
1373 skill = u.skill_record[--u.skills_advanced];
1374 if (P_SKILL(skill) <= P_UNSKILLED)
1375 panic("lose_weapon_skill (%d)", skill);
1376 P_SKILL(skill)--; /* drop skill one level */
1377 /* Lost skill might have taken more than one slot; refund rest. */
1378 u.weapon_slots = slots_required(skill) - 1;
1379 /* It might now be possible to advance some other pending
1380 skill by using the refunded slots, but giving a message
1381 to that effect would seem pretty confusing.... */
1390 /* KMH -- now uses the object table */
1394 return P_BARE_HANDED_COMBAT; /* Not using a weapon */
1395 if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS
1396 && obj->oclass != GEM_CLASS)
1397 return P_NONE; /* Not a weapon, weapon-tool, or ammo */
1398 type = objects[obj->otyp].oc_skill;
1399 return (type < 0) ? -type : type;
1406 return P_TWO_WEAPON_COMBAT;
1407 return weapon_type(uwep);
1411 * Return hit bonus/penalty based on skill of weapon.
1412 * Treat restricted weapons as unskilled.
1415 weapon_hit_bonus(weapon)
1418 int type, wep_type, skill, bonus = 0;
1419 static const char bad_skill[] = "weapon_hit_bonus: bad skill %d";
1421 wep_type = weapon_type(weapon);
1422 /* use two weapon skill only if attacking with one of the wielded weapons
1424 type = (u.twoweap && (weapon == uwep || weapon == uswapwep))
1425 ? P_TWO_WEAPON_COMBAT
1427 if (type == P_NONE) {
1429 } else if (type <= P_LAST_WEAPON) {
1430 switch (P_SKILL(type)) {
1432 impossible(bad_skill, P_SKILL(type)); /* fall through */
1433 case P_ISRESTRICTED:
1447 } else if (type == P_TWO_WEAPON_COMBAT) {
1448 skill = P_SKILL(P_TWO_WEAPON_COMBAT);
1449 if (P_SKILL(wep_type) < skill)
1450 skill = P_SKILL(wep_type);
1453 impossible(bad_skill, skill); /* fall through */
1454 case P_ISRESTRICTED:
1468 } else if (type == P_BARE_HANDED_COMBAT) {
1478 bonus = P_SKILL(type);
1479 bonus = max(bonus, P_UNSKILLED) - 1; /* unskilled => 0 */
1480 bonus = ((bonus + 2) * (martial_bonus() ? 2 : 1)) / 2;
1483 /* KMH -- It's harder to hit while you are riding */
1485 switch (P_SKILL(P_RIDING)) {
1486 case P_ISRESTRICTED:
1506 * Return damage bonus/penalty based on skill of weapon.
1507 * Treat restricted weapons as unskilled.
1510 weapon_dam_bonus(weapon)
1513 int type, wep_type, skill, bonus = 0;
1515 wep_type = weapon_type(weapon);
1516 /* use two weapon skill only if attacking with one of the wielded weapons
1518 type = (u.twoweap && (weapon == uwep || weapon == uswapwep))
1519 ? P_TWO_WEAPON_COMBAT
1521 if (type == P_NONE) {
1523 } else if (type <= P_LAST_WEAPON) {
1524 switch (P_SKILL(type)) {
1526 impossible("weapon_dam_bonus: bad skill %d", P_SKILL(type));
1528 case P_ISRESTRICTED:
1542 } else if (type == P_TWO_WEAPON_COMBAT) {
1543 skill = P_SKILL(P_TWO_WEAPON_COMBAT);
1544 if (P_SKILL(wep_type) < skill)
1545 skill = P_SKILL(wep_type);
1548 case P_ISRESTRICTED:
1562 } else if (type == P_BARE_HANDED_COMBAT) {
1572 bonus = P_SKILL(type);
1573 bonus = max(bonus, P_UNSKILLED) - 1; /* unskilled => 0 */
1574 bonus = ((bonus + 1) * (martial_bonus() ? 3 : 1)) / 2;
1577 /* KMH -- Riding gives some thrusting damage */
1578 if (u.usteed && type != P_TWO_WEAPON_COMBAT) {
1579 switch (P_SKILL(P_RIDING)) {
1580 case P_ISRESTRICTED:
1598 * Initialize weapon skill array for the game. Start by setting all
1599 * skills to restricted, then set the skill for every weapon the
1600 * hero is holding, finally reading the given array that sets
1604 skill_init(class_skill)
1605 const struct def_skill *class_skill;
1610 /* initialize skill array; by default, everything is restricted */
1611 for (skill = 0; skill < P_NUM_SKILLS; skill++) {
1612 P_SKILL(skill) = P_ISRESTRICTED;
1613 P_MAX_SKILL(skill) = P_ISRESTRICTED;
1614 P_ADVANCE(skill) = 0;
1617 /* Set skill for all weapons in inventory to be basic */
1618 for (obj = invent; obj; obj = obj->nobj) {
1619 /* don't give skill just because of carried ammo, wait until
1620 we see the relevant launcher (prevents an archeologist's
1621 touchstone from inadvertently providing skill in sling) */
1625 skill = weapon_type(obj);
1626 if (skill != P_NONE)
1627 P_SKILL(skill) = P_BASIC;
1630 /* set skills for magic */
1631 if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
1632 P_SKILL(P_HEALING_SPELL) = P_BASIC;
1633 } else if (Role_if(PM_PRIEST)) {
1634 P_SKILL(P_CLERIC_SPELL) = P_BASIC;
1635 } else if (Role_if(PM_WIZARD)) {
1636 P_SKILL(P_ATTACK_SPELL) = P_BASIC;
1637 P_SKILL(P_ENCHANTMENT_SPELL) = P_BASIC;
1640 /* walk through array to set skill maximums */
1641 for (; class_skill->skill != P_NONE; class_skill++) {
1642 skmax = class_skill->skmax;
1643 skill = class_skill->skill;
1645 P_MAX_SKILL(skill) = skmax;
1646 if (P_SKILL(skill) == P_ISRESTRICTED) /* skill pre-set */
1647 P_SKILL(skill) = P_UNSKILLED;
1650 /* High potential fighters already know how to use their hands. */
1651 if (P_MAX_SKILL(P_BARE_HANDED_COMBAT) > P_EXPERT)
1652 P_SKILL(P_BARE_HANDED_COMBAT) = P_BASIC;
1654 /* Roles that start with a horse know how to ride it */
1655 if (urole.petnum == PM_PONY)
1656 P_SKILL(P_RIDING) = P_BASIC;
1659 * Make sure we haven't missed setting the max on a skill
1662 for (skill = 0; skill < P_NUM_SKILLS; skill++) {
1663 if (!P_RESTRICTED(skill)) {
1664 if (P_MAX_SKILL(skill) < P_SKILL(skill)) {
1665 impossible("skill_init: curr > max: %s", P_NAME(skill));
1666 P_MAX_SKILL(skill) = P_SKILL(skill);
1668 P_ADVANCE(skill) = practice_needed_to_advance(P_SKILL(skill) - 1);
1672 /* each role has a special spell; allow at least basic for its type
1673 (despite the function name, this works for spell skills too) */
1674 unrestrict_weapon_skill(spell_skilltype(urole.spelspec));
1678 setmnotwielded(mon, obj)
1679 register struct monst *mon;
1680 register struct obj *obj;
1684 if (artifact_light(obj) && obj->lamplit) {
1685 end_burn(obj, FALSE);
1688 pline("%s in %s %s %s shining.", The(xname(obj)),
1689 s_suffix(mon_nam(mon)), mbodypart(mon, HAND),
1690 otense(obj, "stop"));
1692 pline("%s
\82ª
\8e\9d\82Â%s
\82Ì
\8bP
\82«
\82ª
\8fÁ
\82¦
\82½
\81D",
1693 mon_nam(mon), xname(obj));
1696 if (MON_WEP(mon) == obj)
1698 obj->owornmask &= ~W_WEP;