OSDN Git Service

add translation
[jnethack/source.git] / src / attrib.c
1 /* NetHack 3.6  attrib.c        $NHDT-Date: 1449269911 2015/12/04 22:58:31 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.51 $ */
2 /*      Copyright 1988, 1989, 1990, 1992, M. Stephenson           */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10
11 /*  attribute modification routines. */
12
13 #include "hack.h"
14 #include <ctype.h>
15
16 /* part of the output on gain or loss of attribute */
17 static const char
18 #if 0 /*JP*/
19     *const plusattr[] = { "strong", "smart", "wise",
20                           "agile",  "tough", "charismatic" },
21 #else
22     *const plusattr[] = { "\8b­\82¢", "\8c«\96¾\82¾", "\8c«\82¢",
23                           "\8b@\95q\82¾", "\8aæ\8fä\82¾", "\96£\97Í\93I\82¾" },
24 #endif
25 #if 0 /*JP*/
26     *const minusattr[] = { "weak",    "stupid",
27                            "foolish", "clumsy",
28                            "fragile", "repulsive" };
29 #else
30     *const minusattr[] = { "\8eã\82¢", "\8bð\82©\82¾",
31                            "\8aÔ\94²\82¯\82¾", "\95s\8aí\97p\82¾",
32                            "\82Ð\8eã\82¾","\8fX\82¢" };
33 #endif
34
35 static const struct innate {
36     schar ulevel;
37     long *ability;
38     const char *gainstr, *losestr;
39 } arc_abil[] = { { 1, &(HStealth), "", "" },
40                  { 1, &(HFast), "", "" },
41 /*JP
42                  { 10, &(HSearching), "perceptive", "" },
43 */
44                  { 10, &(HSearching), "\92m\8ao\97Í\82ð\93¾\82½", "\92m\8ao\97Í\82ð\8e¸\82Á\82½" },
45                  { 0, 0, 0, 0 } },
46
47   bar_abil[] = { { 1, &(HPoison_resistance), "", "" },
48 /*JP
49                  { 7, &(HFast), "quick", "slow" },
50 */
51                  { 7, &(HFast), "\91f\91\81\82³\82ð\93¾\82½", "\92x\82­\82È\82Á\82½" },
52 /*JP
53                  { 15, &(HStealth), "stealthy", "" },
54 */
55                  { 15, &(HStealth), "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\93¾\82½", "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\8e¸\82Á\82½" },
56                  { 0, 0, 0, 0 } },
57
58 /*JP
59   cav_abil[] = { { 7, &(HFast), "quick", "slow" },
60 */
61   cav_abil[] = { { 7, &(HFast), "\91f\91\81\82³\82ð\93¾\82½", "\92x\82­\82È\82Á\82½" },
62 /*JP
63                  { 15, &(HWarning), "sensitive", "" },
64 */
65                  { 15, &(HWarning), "\95q\8a´\82É\82È\82Á\82½", "\93Ý\8a´\82É\82È\82Á\82½" },
66                  { 0, 0, 0, 0 } },
67
68   hea_abil[] = { { 1, &(HPoison_resistance), "", "" },
69 /*JP
70                  { 15, &(HWarning), "sensitive", "" },
71 */
72                  { 15, &(HWarning), "\95q\8a´\82É\82È\82Á\82½", "\93Ý\8a´\82É\82È\82Á\82½" },
73                  { 0, 0, 0, 0 } },
74
75 /*JP
76   kni_abil[] = { { 7, &(HFast), "quick", "slow" }, { 0, 0, 0, 0 } },
77 */
78   kni_abil[] = { { 7, &(HFast), "\91f\91\81\82³\82ð\93¾\82½", "\92x\82­\82È\82Á\82½" }, { 0, 0, 0, 0 } },
79
80   mon_abil[] = { { 1, &(HFast), "", "" },
81                  { 1, &(HSleep_resistance), "", "" },
82                  { 1, &(HSee_invisible), "", "" },
83 /*JP
84                  { 3, &(HPoison_resistance), "healthy", "" },
85 */
86                  { 3, &(HPoison_resistance), "\8c\92\8dN\82É\82È\82Á\82½", "\95s\8c\92\8dN\82É\82È\82Á\82½" },
87 /*JP
88                  { 5, &(HStealth), "stealthy", "" },
89 */
90                  { 5, &(HStealth), "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\93¾\82½", "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\8e¸\82Á\82½" },
91 /*JP
92                  { 7, &(HWarning), "sensitive", "" },
93 */
94                  { 7, &(HWarning), "\95q\8a´\82É\82È\82Á\82½", "\93Ý\8a´\82É\82È\82Á\82½" },
95 /*JP
96                  { 9, &(HSearching), "perceptive", "unaware" },
97 */
98                  { 9, &(HSearching), "\92m\8ao\97Í\82ð\93¾\82½", "\92m\8ao\97Í\82ð\8e¸\82Á\82½" },
99 /*JP
100                  { 11, &(HFire_resistance), "cool", "warmer" },
101 */
102                  { 11, &(HFire_resistance), "\97â\82½\82­\82È\82Á\82½", "\92g\82©\82­\82È\82Á\82½" },
103 /*JP
104                  { 13, &(HCold_resistance), "warm", "cooler" },
105 */
106                  { 13, &(HCold_resistance), "\92g\82©\82­\82È\82Á\82½", "\97â\82½\82­\82È\82Á\82½"},
107 /*JP
108                  { 15, &(HShock_resistance), "insulated", "conductive" },
109 */
110                  { 15, &(HShock_resistance), "\90â\89\8f\82³\82ê\82½", "\93±\93d\82³\82ê\82½" },
111 /*JP
112                  { 17, &(HTeleport_control), "controlled", "uncontrolled" },
113 */
114                  { 17, &(HTeleport_control), "\90§\8cä\97Í\82ð\93¾\82½","\90§\8cä\97Í\82ð\8e¸\82Á\82½" },
115                  { 0, 0, 0, 0 } },
116
117 /*JP
118   pri_abil[] = { { 15, &(HWarning), "sensitive", "" },
119 */
120   pri_abil[] = { { 15, &(HWarning), "\95q\8a´\82É\82È\82Á\82½", "\93Ý\8a´\82É\82È\82Á\82½" },
121 /*JP
122                  { 20, &(HFire_resistance), "cool", "warmer" },
123 */
124                  { 20, &(HFire_resistance), "\97â\82½\82­\82È\82Á\82½", "\92g\82©\82­\82È\82Á\82½" },
125                  { 0, 0, 0, 0 } },
126
127   ran_abil[] = { { 1, &(HSearching), "", "" },
128 /*JP
129                  { 7, &(HStealth), "stealthy", "" },
130 */
131                  { 7, &(HStealth), "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\93¾\82½", "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\8e¸\82Á\82½" },
132                  { 15, &(HSee_invisible), "", "" },
133                  { 0, 0, 0, 0 } },
134
135   rog_abil[] = { { 1, &(HStealth), "", "" },
136 /*JP
137                  { 10, &(HSearching), "perceptive", "" },
138 */
139                  { 10, &(HSearching), "\92m\8ao\97Í\82ð\93¾\82½", "\92m\8ao\97Í\82ð\8e¸\82Á\82½" },
140                  { 0, 0, 0, 0 } },
141
142   sam_abil[] = { { 1, &(HFast), "", "" },
143 /*JP
144                  { 15, &(HStealth), "stealthy", "" },
145 */
146                  { 15, &(HStealth), "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\93¾\82½", "\90l\96Ú\82ð\93\90\82Þ\97Í\82ð\8e¸\82Á\82½" },
147                  { 0, 0, 0, 0 } },
148
149 /*JP
150   tou_abil[] = { { 10, &(HSearching), "perceptive", "" },
151 */
152   tou_abil[] = { { 10, &(HSearching), "\92m\8ao\97Í\82ð\93¾\82½", "\92m\8ao\97Í\82ð\8e¸\82Á\82½" },
153 /*JP
154                  { 20, &(HPoison_resistance), "hardy", "" },
155 */
156                  { 20, &(HPoison_resistance), "\96Æ\89u\97Í\82ð\93¾\82½", "\96Æ\89u\97Í\82ð\8e¸\82Á\82½" },
157                  { 0, 0, 0, 0 } },
158
159   val_abil[] = { { 1, &(HCold_resistance), "", "" },
160                  { 1, &(HStealth), "", "" },
161 /*JP
162                  { 7, &(HFast), "quick", "slow" },
163 */
164                  { 7, &(HFast), "\91f\91\81\82³\82ð\93¾\82½", "\92x\82­\82È\82Á\82½" },
165                  { 0, 0, 0, 0 } },
166
167 /*JP
168   wiz_abil[] = { { 15, &(HWarning), "sensitive", "" },
169 */
170   wiz_abil[] = { { 15, &(HWarning), "\95q\8a´\82É\82È\82Á\82½", "\93Ý\8a´\82É\82È\82Á\82½" },
171 /*JP
172                  { 17, &(HTeleport_control), "controlled", "uncontrolled" },
173 */
174                  { 17, &(HTeleport_control), "\90§\8cä\97Í\82ð\93¾\82½","\90§\8cä\97Í\82ð\8e¸\82Á\82½" },
175                  { 0, 0, 0, 0 } },
176
177   /* Intrinsics conferred by race */
178 /*JP
179     elf_abil[] = { { 4, &(HSleep_resistance), "awake", "tired" },
180 */
181     elf_abil[] = { { 4, &(HSleep_resistance), "\96Ú\82ª\8ao\82ß\82½", "\96°\82­\82È\82Á\82½" },
182                    { 0, 0, 0, 0 } },
183
184   orc_abil[] = { { 1, &(HPoison_resistance), "", "" }, { 0, 0, 0, 0 } };
185
186 STATIC_DCL void NDECL(exerper);
187 STATIC_DCL void FDECL(postadjabil, (long *));
188 STATIC_DCL const struct innate *FDECL(check_innate_abil, (long *, long));
189 STATIC_DCL int FDECL(innately, (long *));
190
191 /* adjust an attribute; return TRUE if change is made, FALSE otherwise */
192 boolean
193 adjattrib(ndx, incr, msgflg)
194 int ndx, incr;
195 int msgflg; /* positive => no message, zero => message, and */
196 {           /* negative => conditional (msg if change made) */
197     int old_acurr;
198     boolean abonflg;
199     const char *attrstr;
200
201     if (Fixed_abil || !incr)
202         return FALSE;
203
204     if ((ndx == A_INT || ndx == A_WIS) && uarmh && uarmh->otyp == DUNCE_CAP) {
205         if (msgflg == 0)
206 /*JP
207             Your("cap constricts briefly, then relaxes again.");
208 */
209             Your("\96X\8eq\82ª\82µ\82Î\82ç\82­\82Ì\8aÔ\83L\83\85\82Á\82Æ\92÷\82ß\82Â\82¯\81C\82»\82µ\82Ä\82ä\82é\82ñ\82¾\81D");
210         return FALSE;
211     }
212
213     old_acurr = ACURR(ndx);
214     if (incr > 0) {
215         ABASE(ndx) += incr;
216         if (ABASE(ndx) > AMAX(ndx)) {
217             incr = ABASE(ndx) - AMAX(ndx);
218             AMAX(ndx) += incr;
219             if (AMAX(ndx) > ATTRMAX(ndx))
220                 AMAX(ndx) = ATTRMAX(ndx);
221             ABASE(ndx) = AMAX(ndx);
222         }
223         attrstr = plusattr[ndx];
224         abonflg = (ABON(ndx) < 0);
225     } else {
226         ABASE(ndx) += incr;
227         if (ABASE(ndx) < ATTRMIN(ndx)) {
228             incr = ABASE(ndx) - ATTRMIN(ndx);
229             ABASE(ndx) = ATTRMIN(ndx);
230             AMAX(ndx) += incr;
231             if (AMAX(ndx) < ATTRMIN(ndx))
232                 AMAX(ndx) = ATTRMIN(ndx);
233         }
234         attrstr = minusattr[ndx];
235         abonflg = (ABON(ndx) > 0);
236     }
237     if (ACURR(ndx) == old_acurr) {
238         if (msgflg == 0 && flags.verbose)
239 #if 0 /*JP*/
240             pline("You're %s as %s as you can get.",
241                   abonflg ? "currently" : "already", attrstr);
242 #else
243             You("%s\8f\\95ª\82É%s\81D",
244                   abonflg ? "\8d¡\82Ì\82Æ\82±\82ë" : "\8aù\82É", attrstr);
245 #endif
246         return FALSE;
247     }
248
249     if (msgflg <= 0)
250 /*JP
251         You_feel("%s%s!", (incr > 1 || incr < -1) ? "very " : "", attrstr);
252 */
253         You("%s%s\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I", (incr > 1 || incr < -1) ? "\82Æ\82Ä\82à" : "", jconj_adj(attrstr));
254     context.botl = 1;
255     if (moves > 1 && (ndx == A_STR || ndx == A_CON))
256         (void) encumber_msg();
257     return TRUE;
258 }
259
260 void
261 gainstr(otmp, incr, givemsg)
262 struct obj *otmp;
263 int incr;
264 boolean givemsg;
265 {
266     int num = incr;
267
268     if (!num) {
269         if (ABASE(A_STR) < 18)
270             num = (rn2(4) ? 1 : rnd(6));
271         else if (ABASE(A_STR) < STR18(85))
272             num = rnd(10);
273         else
274             num = 1;
275     }
276     (void) adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num,
277                      givemsg ? -1 : 1);
278 }
279
280 /* may kill you; cause may be poison or monster like 'a' */
281 void
282 losestr(num)
283 register int num;
284 {
285     int ustr = ABASE(A_STR) - num;
286
287     while (ustr < 3) {
288         ++ustr;
289         --num;
290         if (Upolyd) {
291             u.mh -= 6;
292             u.mhmax -= 6;
293         } else {
294             u.uhp -= 6;
295             u.uhpmax -= 6;
296         }
297     }
298     (void) adjattrib(A_STR, -num, 1);
299 }
300
301 static const struct poison_effect_message {
302     void VDECL((*delivery_func), (const char *, ...));
303     const char *effect_msg;
304 } poiseff[] = {
305 #if 0 /*JP*/
306     { You_feel, "weaker" },             /* A_STR */
307 #else
308     { You_feel, "\8eã\82­\82È\82Á\82½" },         /* A_STR */
309 #endif
310 #if 0 /*JP*/
311     { Your, "brain is on fire" },       /* A_INT */
312 #else
313     { You, "\93ª\82É\8c\8c\82ª\82Ì\82Ú\82Á\82½" },        /* A_INT */
314 #endif
315 #if 0 /*JP*/
316     { Your, "judgement is impaired" },  /* A_WIS */
317 #else
318     { You, "\94»\92f\97Í\82ð\8e¸\82Á\82½" },          /* A_WIS */
319 #endif
320 #if 0 /*JP*/
321     { Your, "muscles won't obey you" }, /* A_DEX */
322 #else
323     { You, "\8ev\82¤\82æ\82¤\82É\93®\82¯\82È\82¢" },      /* A_DEX */
324 #endif
325 #if 0 /*JP*/
326     { You_feel, "very sick" },          /* A_CON */
327 #else
328     { You_feel, "\82Æ\82Ä\82à\8bC\95ª\82ª\88«\82­\82È\82Á\82½" }, /* A_CON */
329 #endif
330 #if 0 /*JP*/
331     { You, "break out in hives" }       /* A_CHA */
332 #else
333     { You, "\82\82ñ\82Ü\82µ\82ñ\82ª\82 \82ç\82í\82ê\82½" }   /* A_CHA */
334 #endif
335 };
336
337 /* feedback for attribute loss due to poisoning */
338 void
339 poisontell(typ, exclaim)
340 int typ;         /* which attribute */
341 boolean exclaim; /* emphasis */
342 {
343     void VDECL((*func), (const char *, ...)) = poiseff[typ].delivery_func;
344
345 /*JP
346     (*func)("%s%c", poiseff[typ].effect_msg, exclaim ? '!' : '.');
347 */
348     (*func)("%s%s", poiseff[typ].effect_msg, exclaim ? "\81I" : "\81D");
349 }
350
351 /* called when an attack or trap has poisoned the hero (used to be in mon.c)
352  */
353 void
354 poisoned(reason, typ, pkiller, fatal, thrown_weapon)
355 const char *reason,    /* controls what messages we display */
356     *pkiller;          /* for score+log file if fatal */
357 int typ, fatal;        /* if fatal is 0, limit damage to adjattrib */
358 boolean thrown_weapon; /* thrown weapons are less deadly */
359 {
360     int i, loss, kprefix = KILLED_BY_AN;
361
362     /* inform player about being poisoned unless that's already been done;
363        "blast" has given a "blast of poison gas" message; "poison arrow",
364        "poison dart", etc have implicitly given poison messages too... */
365 #if 0 /*JP*/
366     if (strcmp(reason, "blast") && !strstri(reason, "poison")) {
367 #else
368     if (strcmp(reason, "\95\97") && strcmp(reason, "\91§") && !strstri(reason, "\93Å")) {
369 #endif
370 #if 0 /*JP*/
371         boolean plural = (reason[strlen(reason) - 1] == 's') ? 1 : 0;
372 #endif
373
374         /* avoid "The" Orcus's sting was poisoned... */
375 #if 0 /*JP*/
376         pline("%s%s %s poisoned!", isupper(*reason) ? "" : "The ", reason,
377               plural ? "were" : "was");
378 #else
379         pline("%s\82Í\93Å\82É\82¨\82©\82³\82ê\82Ä\82¢\82é\81I", reason);
380 #endif
381     }
382     if (Poison_resistance) {
383 #if 0 /*JP*/
384         if (!strcmp(reason, "blast"))
385 #else
386         if (!strcmp(reason, "\95\97") || !strcmp(reason, "\91§"))
387 #endif
388             shieldeff(u.ux, u.uy);
389 /*JP
390         pline_The("poison doesn't seem to affect you.");
391 */
392         pline("\93Å\82Í\8cø\82©\82È\82©\82Á\82½\82æ\82¤\82¾\81D");
393         return;
394     }
395
396 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\95s\97v*/
397     /* suppress killer prefix if it already has one */
398     i = name_to_mon(pkiller);
399     if (i >= LOW_PM && (mons[i].geno & G_UNIQ)) {
400         kprefix = KILLED_BY;
401         if (!type_is_pname(&mons[i]))
402             pkiller = the(pkiller);
403     } else if (!strncmpi(pkiller, "the ", 4) || !strncmpi(pkiller, "an ", 3)
404                || !strncmpi(pkiller, "a ", 2)) {
405         /*[ does this need a plural check too? ]*/
406         kprefix = KILLED_BY;
407     }
408 #endif
409
410     i = !fatal ? 1 : rn2(fatal + (thrown_weapon ? 20 : 0));
411     if (i == 0 && typ != A_CHA) {
412         /* instant kill */
413         u.uhp = -1;
414 /*JP
415         pline_The("poison was deadly...");
416 */
417         pline("\93Å\82Í\92v\8e\80\97Ê\82¾\82Á\82½\81D\81D\81D");
418     } else if (i > 5) {
419         /* HP damage; more likely--but less severe--with missiles */
420         loss = thrown_weapon ? rnd(6) : rn1(10, 6);
421         losehp(loss, pkiller, kprefix); /* poison damage */
422     } else {
423         /* attribute loss; if typ is A_STR, reduction in current and
424            maximum HP will occur once strength has dropped down to 3 */
425         loss = (thrown_weapon || !fatal) ? 1 : d(2, 2); /* was rn1(3,3) */
426         /* check that a stat change was made */
427         if (adjattrib(typ, -loss, 1))
428             poisontell(typ, TRUE);
429     }
430
431     if (u.uhp < 1) {
432         killer.format = kprefix;
433         Strcpy(killer.name, pkiller);
434 #if 0 /*JP*/
435         /* "Poisoned by a poisoned ___" is redundant */
436         done(strstri(pkiller, "poison") ? DIED : POISONING);
437 #else /*JP:\93ú\96{\8cê\82Å\82Í\8bæ\95Ê\82µ\82Ä\82¢\82È\82¢*/
438         done(POISONING);
439 #endif
440     }
441     (void) encumber_msg();
442 }
443
444 void
445 change_luck(n)
446 register schar n;
447 {
448     u.uluck += n;
449     if (u.uluck < 0 && u.uluck < LUCKMIN)
450         u.uluck = LUCKMIN;
451     if (u.uluck > 0 && u.uluck > LUCKMAX)
452         u.uluck = LUCKMAX;
453 }
454
455 int
456 stone_luck(parameter)
457 boolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
458 {
459     register struct obj *otmp;
460     register long bonchance = 0;
461
462     for (otmp = invent; otmp; otmp = otmp->nobj)
463         if (confers_luck(otmp)) {
464             if (otmp->cursed)
465                 bonchance -= otmp->quan;
466             else if (otmp->blessed)
467                 bonchance += otmp->quan;
468             else if (parameter)
469                 bonchance += otmp->quan;
470         }
471
472     return sgn((int) bonchance);
473 }
474
475 /* there has just been an inventory change affecting a luck-granting item */
476 void
477 set_moreluck()
478 {
479     int luckbon = stone_luck(TRUE);
480
481     if (!luckbon && !carrying(LUCKSTONE))
482         u.moreluck = 0;
483     else if (luckbon >= 0)
484         u.moreluck = LUCKADD;
485     else
486         u.moreluck = -LUCKADD;
487 }
488
489 void
490 restore_attrib()
491 {
492     int i;
493
494     for (i = 0; i < A_MAX; i++) { /* all temporary losses/gains */
495
496         if (ATEMP(i) && ATIME(i)) {
497             if (!(--(ATIME(i)))) { /* countdown for change */
498                 ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
499
500                 if (ATEMP(i)) /* reset timer */
501                     ATIME(i) = 100 / ACURR(A_CON);
502             }
503         }
504     }
505     (void) encumber_msg();
506 }
507
508 #define AVAL 50 /* tune value for exercise gains */
509
510 void
511 exercise(i, inc_or_dec)
512 int i;
513 boolean inc_or_dec;
514 {
515     debugpline0("Exercise:");
516     if (i == A_INT || i == A_CHA)
517         return; /* can't exercise these */
518
519     /* no physical exercise while polymorphed; the body's temporary */
520     if (Upolyd && i != A_WIS)
521         return;
522
523     if (abs(AEXE(i)) < AVAL) {
524         /*
525          *      Law of diminishing returns (Part I):
526          *
527          *      Gain is harder at higher attribute values.
528          *      79% at "3" --> 0% at "18"
529          *      Loss is even at all levels (50%).
530          *
531          *      Note: *YES* ACURR is the right one to use.
532          */
533         AEXE(i) += (inc_or_dec) ? (rn2(19) > ACURR(i)) : -rn2(2);
534         debugpline3("%s, %s AEXE = %d",
535                     (i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" : (i == A_DEX)
536                                                                       ? "Dex"
537                                                                       : "Con",
538                     (inc_or_dec) ? "inc" : "dec", AEXE(i));
539     }
540     if (moves > 0 && (i == A_STR || i == A_CON))
541         (void) encumber_msg();
542 }
543
544 STATIC_OVL void
545 exerper()
546 {
547     if (!(moves % 10)) {
548         /* Hunger Checks */
549
550         int hs = (u.uhunger > 1000) ? SATIATED : (u.uhunger > 150)
551                                                      ? NOT_HUNGRY
552                                                      : (u.uhunger > 50)
553                                                            ? HUNGRY
554                                                            : (u.uhunger > 0)
555                                                                  ? WEAK
556                                                                  : FAINTING;
557
558         debugpline0("exerper: Hunger checks");
559         switch (hs) {
560         case SATIATED:
561             exercise(A_DEX, FALSE);
562             if (Role_if(PM_MONK))
563                 exercise(A_WIS, FALSE);
564             break;
565         case NOT_HUNGRY:
566             exercise(A_CON, TRUE);
567             break;
568         case WEAK:
569             exercise(A_STR, FALSE);
570             if (Role_if(PM_MONK)) /* fasting */
571                 exercise(A_WIS, TRUE);
572             break;
573         case FAINTING:
574         case FAINTED:
575             exercise(A_CON, FALSE);
576             break;
577         }
578
579         /* Encumbrance Checks */
580         debugpline0("exerper: Encumber checks");
581         switch (near_capacity()) {
582         case MOD_ENCUMBER:
583             exercise(A_STR, TRUE);
584             break;
585         case HVY_ENCUMBER:
586             exercise(A_STR, TRUE);
587             exercise(A_DEX, FALSE);
588             break;
589         case EXT_ENCUMBER:
590             exercise(A_DEX, FALSE);
591             exercise(A_CON, FALSE);
592             break;
593         }
594     }
595
596     /* status checks */
597     if (!(moves % 5)) {
598         debugpline0("exerper: Status checks");
599         if ((HClairvoyant & (INTRINSIC | TIMEOUT)) && !BClairvoyant)
600             exercise(A_WIS, TRUE);
601         if (HRegeneration)
602             exercise(A_STR, TRUE);
603
604         if (Sick || Vomiting)
605             exercise(A_CON, FALSE);
606         if (Confusion || Hallucination)
607             exercise(A_WIS, FALSE);
608         if ((Wounded_legs && !u.usteed) || Fumbling || HStun)
609             exercise(A_DEX, FALSE);
610     }
611 }
612
613 /* exercise/abuse text (must be in attribute order, not botl order);
614    phrased as "You must have been [][0]." or "You haven't been [][1]." */
615 static NEARDATA const char *const exertext[A_MAX][2] = {
616 #if 0 /*JP*/
617     { "exercising diligently", "exercising properly" },           /* Str */
618     { 0, 0 },                                                     /* Int */
619     { "very observant", "paying attention" },                     /* Wis */
620     { "working on your reflexes", "working on reflexes lately" }, /* Dex */
621     { "leading a healthy life-style", "watching your health" },   /* Con */
622     { 0, 0 },                                                     /* Cha */
623 #else
624     { "\94O\93ü\82è\82É\89^\93®\82µ\82Ä\82¢\82½", "\93K\90Ø\82É\89^\93®\82µ\82Ä\82¢\82È\82©\82Á\82½" },       /* Str */
625     { 0, 0 },                                                     /* Int */
626     { "\90T\8fd\82É\8ds\93®\82µ\82Ä\82¢\82½", "\92\8d\88Ó\95s\91«\82¾\82Á\82½" },                   /* Wis */
627     { "\94½\8eË\90_\8co\82ð\8eg\82Á\82Ä\82¢\82½", "\8dÅ\8bß\94½\8eË\90_\8co\82ð\8eg\82Á\82Ä\82¢\82È\82©\82Á\82½" }, /* Dex */
628     { "\8c\92\8dN\93I\82È\90\8a\88\82ð\82µ\82Ä\82¢\82½", "\8c\92\8dN\8aÇ\97\9d\82ð\91Ó\82Á\82Ä\82¢\82½" },         /* Con */
629     { 0, 0 },                                                     /* Cha */
630 #endif
631 };
632
633 void
634 exerchk()
635 {
636     int i, ax, mod_val, lolim, hilim;
637
638     /*  Check out the periodic accumulations */
639     exerper();
640
641     if (moves >= context.next_attrib_check) {
642         debugpline1("exerchk: ready to test. multi = %d.", multi);
643     }
644     /*  Are we ready for a test? */
645     if (moves >= context.next_attrib_check && !multi) {
646         debugpline0("exerchk: testing.");
647         /*
648          *      Law of diminishing returns (Part II):
649          *
650          *      The effects of "exercise" and "abuse" wear
651          *      off over time.  Even if you *don't* get an
652          *      increase/decrease, you lose some of the
653          *      accumulated effects.
654          */
655         for (i = 0; i < A_MAX; ++i) {
656             ax = AEXE(i);
657             /* nothing to do here if no exercise or abuse has occurred
658                (Int and Cha always fall into this category) */
659             if (!ax)
660                 continue; /* ok to skip nextattrib */
661
662             mod_val = sgn(ax); /* +1 or -1; used below */
663             /* no further effect for exercise if at max or abuse if at min;
664                can't exceed 18 via exercise even if actual max is higher */
665             lolim = ATTRMIN(i); /* usually 3; might be higher */
666             hilim = ATTRMAX(i); /* usually 18; maybe lower or higher */
667             if (hilim > 18)
668                 hilim = 18;
669             if ((ax < 0) ? (ABASE(i) <= lolim) : (ABASE(i) >= hilim))
670                 goto nextattrib;
671             /* can't exercise non-Wisdom while polymorphed; previous
672                exercise/abuse gradually wears off without impact then */
673             if (Upolyd && i != A_WIS)
674                 goto nextattrib;
675
676             debugpline2("exerchk: testing %s (%d).",
677                         (i == A_STR)
678                             ? "Str"
679                             : (i == A_INT)
680                                   ? "Int?"
681                                   : (i == A_WIS)
682                                         ? "Wis"
683                                         : (i == A_DEX)
684                                               ? "Dex"
685                                               : (i == A_CON)
686                                                     ? "Con"
687                                                     : (i == A_CHA)
688                                                           ? "Cha?"
689                                                           : "???",
690                         ax);
691             /*
692              *  Law of diminishing returns (Part III):
693              *
694              *  You don't *always* gain by exercising.
695              *  [MRS 92/10/28 - Treat Wisdom specially for balance.]
696              */
697             if (rn2(AVAL) > ((i != A_WIS) ? (abs(ax) * 2 / 3) : abs(ax)))
698                 goto nextattrib;
699
700             debugpline1("exerchk: changing %d.", i);
701             if (adjattrib(i, mod_val, -1)) {
702                 debugpline1("exerchk: changed %d.", i);
703                 /* if you actually changed an attrib - zero accumulation */
704                 AEXE(i) = ax = 0;
705                 /* then print an explanation */
706 #if 0 /*JP*/
707                 You("%s %s.",
708                     (mod_val > 0) ? "must have been" : "haven't been",
709                     exertext[i][(mod_val > 0) ? 0 : 1]);
710 #else
711                 You("%s\82É\88á\82¢\82È\82¢\81D",
712                     exertext[i][(mod_val > 0) ? 0 : 1]);
713 #endif
714             }
715         nextattrib:
716             /* this used to be ``AEXE(i) /= 2'' but that would produce
717                platform-dependent rounding/truncation for negative vals */
718             AEXE(i) = (abs(ax) / 2) * mod_val;
719         }
720         context.next_attrib_check += rn1(200, 800);
721         debugpline1("exerchk: next check at %ld.", context.next_attrib_check);
722     }
723 }
724
725 void
726 init_attr(np)
727 register int np;
728 {
729     register int i, x, tryct;
730
731     for (i = 0; i < A_MAX; i++) {
732         ABASE(i) = AMAX(i) = urole.attrbase[i];
733         ATEMP(i) = ATIME(i) = 0;
734         np -= urole.attrbase[i];
735     }
736
737     tryct = 0;
738     while (np > 0 && tryct < 100) {
739         x = rn2(100);
740         for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++)
741             ;
742         if (i >= A_MAX)
743             continue; /* impossible */
744
745         if (ABASE(i) >= ATTRMAX(i)) {
746             tryct++;
747             continue;
748         }
749         tryct = 0;
750         ABASE(i)++;
751         AMAX(i)++;
752         np--;
753     }
754
755     tryct = 0;
756     while (np < 0 && tryct < 100) { /* for redistribution */
757
758         x = rn2(100);
759         for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++)
760             ;
761         if (i >= A_MAX)
762             continue; /* impossible */
763
764         if (ABASE(i) <= ATTRMIN(i)) {
765             tryct++;
766             continue;
767         }
768         tryct = 0;
769         ABASE(i)--;
770         AMAX(i)--;
771         np++;
772     }
773 }
774
775 void
776 redist_attr()
777 {
778     register int i, tmp;
779
780     for (i = 0; i < A_MAX; i++) {
781         if (i == A_INT || i == A_WIS)
782             continue;
783         /* Polymorphing doesn't change your mind */
784         tmp = AMAX(i);
785         AMAX(i) += (rn2(5) - 2);
786         if (AMAX(i) > ATTRMAX(i))
787             AMAX(i) = ATTRMAX(i);
788         if (AMAX(i) < ATTRMIN(i))
789             AMAX(i) = ATTRMIN(i);
790         ABASE(i) = ABASE(i) * AMAX(i) / tmp;
791         /* ABASE(i) > ATTRMAX(i) is impossible */
792         if (ABASE(i) < ATTRMIN(i))
793             ABASE(i) = ATTRMIN(i);
794     }
795     (void) encumber_msg();
796 }
797
798 STATIC_OVL
799 void
800 postadjabil(ability)
801 long *ability;
802 {
803     if (!ability)
804         return;
805     if (ability == &(HWarning) || ability == &(HSee_invisible))
806         see_monsters();
807 }
808
809 STATIC_OVL const struct innate *
810 check_innate_abil(ability, frommask)
811 long *ability;
812 long frommask;
813 {
814     const struct innate *abil = 0;
815
816     if (frommask == FROMEXPER)
817         switch (Role_switch) {
818         case PM_ARCHEOLOGIST:
819             abil = arc_abil;
820             break;
821         case PM_BARBARIAN:
822             abil = bar_abil;
823             break;
824         case PM_CAVEMAN:
825             abil = cav_abil;
826             break;
827         case PM_HEALER:
828             abil = hea_abil;
829             break;
830         case PM_KNIGHT:
831             abil = kni_abil;
832             break;
833         case PM_MONK:
834             abil = mon_abil;
835             break;
836         case PM_PRIEST:
837             abil = pri_abil;
838             break;
839         case PM_RANGER:
840             abil = ran_abil;
841             break;
842         case PM_ROGUE:
843             abil = rog_abil;
844             break;
845         case PM_SAMURAI:
846             abil = sam_abil;
847             break;
848         case PM_TOURIST:
849             abil = tou_abil;
850             break;
851         case PM_VALKYRIE:
852             abil = val_abil;
853             break;
854         case PM_WIZARD:
855             abil = wiz_abil;
856             break;
857         default:
858             break;
859         }
860     else if (frommask == FROMRACE)
861         switch (Race_switch) {
862         case PM_ELF:
863             abil = elf_abil;
864             break;
865         case PM_ORC:
866             abil = orc_abil;
867             break;
868         case PM_HUMAN:
869         case PM_DWARF:
870         case PM_GNOME:
871         default:
872             break;
873         }
874
875     while (abil && abil->ability) {
876         if ((abil->ability == ability) && (u.ulevel >= abil->ulevel))
877             return abil;
878         abil++;
879     }
880     return (struct innate *) 0;
881 }
882
883 /*
884  * returns 1 if FROMRACE or FROMEXPER and exper level == 1
885  * returns 2 if FROMEXPER and exper level > 1
886  * otherwise returns 0
887  */
888 STATIC_OVL int
889 innately(ability)
890 long *ability;
891 {
892     const struct innate *iptr;
893
894     if ((iptr = check_innate_abil(ability, FROMRACE)) != 0)
895         return 1;
896     else if ((iptr = check_innate_abil(ability, FROMEXPER)) != 0)
897         return (iptr->ulevel == 1) ? 1 : 2;
898     return 0;
899 }
900
901 int
902 is_innate(propidx)
903 int propidx;
904 {
905     if (propidx == BLINDED && !haseyes(youmonst.data))
906         return 1;
907     return innately(&u.uprops[propidx].intrinsic);
908 }
909
910 char *
911 from_what(propidx)
912 int propidx; /* special cases can have negative values */
913 {
914     static char buf[BUFSZ];
915
916     buf[0] = '\0';
917     /*
918      * Restrict the source of the attributes just to debug mode for now
919      */
920 /*JP:\81u\82 \82È\82½\82Í\82 \82È\82½\82Ì\81c\82É\82æ\82Á\82Ä\81v\82Æ\82È\82é\82Æ\95s\8e©\91R\82È\82Ì\82Åsimpleonames()\82ð\8eg\82¤*/
921 /*JP: \96{\97\88\82Íminimal_xname()\82ð\8eg\82¤\82×\82«\82¾\82ªstatic\82È\82Ì\82Å\91ã\97p*/
922     if (wizard) {
923 /*JP
924         static NEARDATA const char because_of[] = " because of %s";
925 */
926         static NEARDATA const char because_of[] = "%s\82É\82æ\82Á\82Ä";
927
928         if (propidx >= 0) {
929 #if 0 /*JP*/
930             char *p;
931 #endif
932             struct obj *obj = (struct obj *) 0;
933             int innate = is_innate(propidx);
934
935             if (innate == 2)
936 /*JP
937                 Strcpy(buf, " because of your experience");
938 */
939                 Strcpy(buf, "\8co\8c±\82É\82æ\82Á\82Ä");
940             else if (innate == 1)
941 /*JP
942                 Strcpy(buf, " innately");
943 */
944                 Strcpy(buf, "\90\82Ü\82ê\82È\82ª\82ç\82É");
945             else if (wizard
946                      && (obj = what_gives(&u.uprops[propidx].extrinsic)))
947                 Sprintf(buf, because_of, obj->oartifact
948                                              ? bare_artifactname(obj)
949 /*JP
950                                              : ysimple_name(obj));
951 */
952                                              : simpleonames(obj));
953             else if (propidx == BLINDED && u.uroleplay.blind)
954 /*JP
955                 Sprintf(buf, " from birth");
956 */
957                 Sprintf(buf, "\90\82Ü\82ê\82Ä\82©\82ç\82¸\82Á\82Æ");
958             else if (propidx == BLINDED && Blindfolded_only)
959 /*JP
960                 Sprintf(buf, because_of, ysimple_name(ublindf));
961 */
962                 Sprintf(buf, because_of, simpleonames(ublindf));
963
964 #if 0 /*JP*//*\95s\97v*/
965             /* remove some verbosity and/or redundancy */
966             if ((p = strstri(buf, " pair of ")) != 0)
967                 copynchars(p + 1, p + 9, BUFSZ); /* overlapping buffers ok */
968             else if (propidx == STRANGLED
969                      && (p = strstri(buf, " of strangulation")) != 0)
970                 *p = '\0';
971 #endif
972
973         } else { /* negative property index */
974             /* if more blocking capabilities get implemented we'll need to
975                replace this with what_blocks() comparable to what_gives() */
976             switch (-propidx) {
977             case BLINDED:
978                 if (ublindf
979                     && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)
980                     Sprintf(buf, because_of, bare_artifactname(ublindf));
981                 break;
982             case INVIS:
983                 if (u.uprops[INVIS].blocked & W_ARMC)
984                     Sprintf(buf, because_of,
985 #if 0 /*JP*/
986                             ysimple_name(uarmc)); /* mummy wrapping */
987 #else
988                             simpleonames(uarmc)); /* mummy wrapping */
989 #endif
990                 break;
991             case CLAIRVOYANT:
992                 if (wizard && (u.uprops[CLAIRVOYANT].blocked & W_ARMH))
993                     Sprintf(buf, because_of,
994 #if 0 /*JP*/
995                             ysimple_name(uarmh)); /* cornuthaum */
996 #else
997                             simpleonames(uarmh)); /* cornuthaum */
998 #endif
999                 break;
1000             }
1001         }
1002
1003     } /*wizard*/
1004     return buf;
1005 }
1006
1007 void
1008 adjabil(oldlevel, newlevel)
1009 int oldlevel, newlevel;
1010 {
1011     register const struct innate *abil, *rabil;
1012     long prevabil, mask = FROMEXPER;
1013
1014     switch (Role_switch) {
1015     case PM_ARCHEOLOGIST:
1016         abil = arc_abil;
1017         break;
1018     case PM_BARBARIAN:
1019         abil = bar_abil;
1020         break;
1021     case PM_CAVEMAN:
1022         abil = cav_abil;
1023         break;
1024     case PM_HEALER:
1025         abil = hea_abil;
1026         break;
1027     case PM_KNIGHT:
1028         abil = kni_abil;
1029         break;
1030     case PM_MONK:
1031         abil = mon_abil;
1032         break;
1033     case PM_PRIEST:
1034         abil = pri_abil;
1035         break;
1036     case PM_RANGER:
1037         abil = ran_abil;
1038         break;
1039     case PM_ROGUE:
1040         abil = rog_abil;
1041         break;
1042     case PM_SAMURAI:
1043         abil = sam_abil;
1044         break;
1045     case PM_TOURIST:
1046         abil = tou_abil;
1047         break;
1048     case PM_VALKYRIE:
1049         abil = val_abil;
1050         break;
1051     case PM_WIZARD:
1052         abil = wiz_abil;
1053         break;
1054     default:
1055         abil = 0;
1056         break;
1057     }
1058
1059     switch (Race_switch) {
1060     case PM_ELF:
1061         rabil = elf_abil;
1062         break;
1063     case PM_ORC:
1064         rabil = orc_abil;
1065         break;
1066     case PM_HUMAN:
1067     case PM_DWARF:
1068     case PM_GNOME:
1069     default:
1070         rabil = 0;
1071         break;
1072     }
1073
1074     while (abil || rabil) {
1075         /* Have we finished with the intrinsics list? */
1076         if (!abil || !abil->ability) {
1077             /* Try the race intrinsics */
1078             if (!rabil || !rabil->ability)
1079                 break;
1080             abil = rabil;
1081             rabil = 0;
1082             mask = FROMRACE;
1083         }
1084         prevabil = *(abil->ability);
1085         if (oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
1086             /* Abilities gained at level 1 can never be lost
1087              * via level loss, only via means that remove _any_
1088              * sort of ability.  A "gain" of such an ability from
1089              * an outside source is devoid of meaning, so we set
1090              * FROMOUTSIDE to avoid such gains.
1091              */
1092             if (abil->ulevel == 1)
1093                 *(abil->ability) |= (mask | FROMOUTSIDE);
1094             else
1095                 *(abil->ability) |= mask;
1096             if (!(*(abil->ability) & INTRINSIC & ~mask)) {
1097                 if (*(abil->gainstr))
1098 /*JP
1099                     You_feel("%s!", abil->gainstr);
1100 */
1101                     You("%s\82æ\82¤\82È\8bC\82ª\82µ\82½\81I", abil->gainstr);
1102             }
1103         } else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
1104             *(abil->ability) &= ~mask;
1105             if (!(*(abil->ability) & INTRINSIC)) {
1106                 if (*(abil->losestr))
1107 /*JP
1108                     You_feel("%s!", abil->losestr);
1109 */
1110                     You("%s\82æ\82¤\82È\8bC\82ª\82µ\82½\81I", abil->losestr);
1111 /*JP:\82±\82Ì\8fð\8c\8f\82Í\96\9e\82³\82È\82¢\82Í\82¸\81D*/
1112                 else if (*(abil->gainstr))
1113                     You_feel("less %s!", abil->gainstr);
1114             }
1115         }
1116         if (prevabil != *(abil->ability)) /* it changed */
1117             postadjabil(abil->ability);
1118         abil++;
1119     }
1120
1121     if (oldlevel > 0) {
1122         if (newlevel > oldlevel)
1123             add_weapon_skill(newlevel - oldlevel);
1124         else
1125             lose_weapon_skill(oldlevel - newlevel);
1126     }
1127 }
1128
1129 int
1130 newhp()
1131 {
1132     int hp, conplus;
1133
1134     if (u.ulevel == 0) {
1135         /* Initialize hit points */
1136         hp = urole.hpadv.infix + urace.hpadv.infix;
1137         if (urole.hpadv.inrnd > 0)
1138             hp += rnd(urole.hpadv.inrnd);
1139         if (urace.hpadv.inrnd > 0)
1140             hp += rnd(urace.hpadv.inrnd);
1141         if (moves <= 1L) { /* initial hero; skip for polyself to new man */
1142             /* Initialize alignment stuff */
1143             u.ualign.type = aligns[flags.initalign].value;
1144             u.ualign.record = urole.initrecord;
1145         }
1146         /* no Con adjustment for initial hit points */
1147     } else {
1148         if (u.ulevel < urole.xlev) {
1149             hp = urole.hpadv.lofix + urace.hpadv.lofix;
1150             if (urole.hpadv.lornd > 0)
1151                 hp += rnd(urole.hpadv.lornd);
1152             if (urace.hpadv.lornd > 0)
1153                 hp += rnd(urace.hpadv.lornd);
1154         } else {
1155             hp = urole.hpadv.hifix + urace.hpadv.hifix;
1156             if (urole.hpadv.hirnd > 0)
1157                 hp += rnd(urole.hpadv.hirnd);
1158             if (urace.hpadv.hirnd > 0)
1159                 hp += rnd(urace.hpadv.hirnd);
1160         }
1161         if (ACURR(A_CON) <= 3)
1162             conplus = -2;
1163         else if (ACURR(A_CON) <= 6)
1164             conplus = -1;
1165         else if (ACURR(A_CON) <= 14)
1166             conplus = 0;
1167         else if (ACURR(A_CON) <= 16)
1168             conplus = 1;
1169         else if (ACURR(A_CON) == 17)
1170             conplus = 2;
1171         else if (ACURR(A_CON) == 18)
1172             conplus = 3;
1173         else
1174             conplus = 4;
1175         hp += conplus;
1176     }
1177     if (hp <= 0)
1178         hp = 1;
1179     if (u.ulevel < MAXULEV)
1180         u.uhpinc[u.ulevel] = (xchar) hp;
1181     return hp;
1182 }
1183
1184 schar
1185 acurr(x)
1186 int x;
1187 {
1188     register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
1189
1190     if (x == A_STR) {
1191         if (tmp >= 125 || (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER))
1192             return (schar) 125;
1193         else
1194 #ifdef WIN32_BUG
1195             return (x = ((tmp <= 3) ? 3 : tmp));
1196 #else
1197         return (schar) ((tmp <= 3) ? 3 : tmp);
1198 #endif
1199     } else if (x == A_CHA) {
1200         if (tmp < 18
1201             && (youmonst.data->mlet == S_NYMPH || u.umonnum == PM_SUCCUBUS
1202                 || u.umonnum == PM_INCUBUS))
1203             return (schar) 18;
1204     } else if (x == A_INT || x == A_WIS) {
1205         /* yes, this may raise int/wis if player is sufficiently
1206          * stupid.  there are lower levels of cognition than "dunce".
1207          */
1208         if (uarmh && uarmh->otyp == DUNCE_CAP)
1209             return (schar) 6;
1210     }
1211 #ifdef WIN32_BUG
1212     return (x = ((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
1213 #else
1214     return (schar) ((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp);
1215 #endif
1216 }
1217
1218 /* condense clumsy ACURR(A_STR) value into value that fits into game formulas
1219  */
1220 schar
1221 acurrstr()
1222 {
1223     register int str = ACURR(A_STR);
1224
1225     if (str <= 18)
1226         return (schar) str;
1227     if (str <= 121)
1228         return (schar) (19 + str / 50); /* map to 19..21 */
1229     else
1230         return (schar) (min(str, 125) - 100); /* 22..25 */
1231 }
1232
1233 /* when wearing (or taking off) an unID'd item, this routine is used
1234    to distinguish between observable +0 result and no-visible-effect
1235    due to an attribute not being able to exceed maximum or minimum */
1236 boolean
1237 extremeattr(attrindx) /* does attrindx's value match its max or min? */
1238 int attrindx;
1239 {
1240     /* Fixed_abil and racial MINATTR/MAXATTR aren't relevant here */
1241     int lolimit = 3, hilimit = 25, curval = ACURR(attrindx);
1242
1243     /* upper limit for Str is 25 but its value is encoded differently */
1244     if (attrindx == A_STR) {
1245         hilimit = STR19(25); /* 125 */
1246         /* lower limit for Str can also be 25 */
1247         if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER)
1248             lolimit = hilimit;
1249     }
1250     /* this exception is hypothetical; the only other worn item affecting
1251        Int or Wis is another helmet so can't be in use at the same time */
1252     if (attrindx == A_INT || attrindx == A_WIS) {
1253         if (uarmh && uarmh->otyp == DUNCE_CAP)
1254             hilimit = lolimit = 6;
1255     }
1256
1257     /* are we currently at either limit? */
1258     return (curval == lolimit || curval == hilimit) ? TRUE : FALSE;
1259 }
1260
1261 /* avoid possible problems with alignment overflow, and provide a centralized
1262    location for any future alignment limits */
1263 void
1264 adjalign(n)
1265 int n;
1266 {
1267     int newalign = u.ualign.record + n;
1268
1269     if (n < 0) {
1270         if (newalign < u.ualign.record)
1271             u.ualign.record = newalign;
1272     } else if (newalign > u.ualign.record) {
1273         u.ualign.record = newalign;
1274         if (u.ualign.record > ALIGNLIM)
1275             u.ualign.record = ALIGNLIM;
1276     }
1277 }
1278
1279 /* change hero's alignment type, possibly losing use of artifacts */
1280 void
1281 uchangealign(newalign, reason)
1282 int newalign;
1283 int reason; /* 0==conversion, 1==helm-of-OA on, 2==helm-of-OA off */
1284 {
1285     aligntyp oldalign = u.ualign.type;
1286
1287     u.ublessed = 0;   /* lose divine protection */
1288     context.botl = 1; /* status line needs updating */
1289     if (reason == 0) {
1290         /* conversion via altar */
1291         u.ualignbase[A_CURRENT] = (aligntyp) newalign;
1292         /* worn helm of opposite alignment might block change */
1293         if (!uarmh || uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)
1294             u.ualign.type = u.ualignbase[A_CURRENT];
1295 #if 0 /*JP*/
1296         You("have a %ssense of a new direction.",
1297             (u.ualign.type != oldalign) ? "sudden " : "");
1298 #else
1299         You("%s\95Ê\82Ì\95û\8cü\90«\82É\82ß\82´\82ß\82½\81D",
1300             (u.ualign.type != oldalign) ? "\93Ë\91R" : "");
1301 #endif
1302     } else {
1303         /* putting on or taking off a helm of opposite alignment */
1304         u.ualign.type = (aligntyp) newalign;
1305         if (reason == 1)
1306 /*JP
1307             Your("mind oscillates %s.", Hallucination ? "wildly" : "briefly");
1308 */
1309             You("%s\90Q\95Ô\82Á\82½\81D", Hallucination ? "\8dr\82Á\82Û\82­" : "\82 \82Á\82³\82è\82Æ");
1310         else if (reason == 2)
1311 #if 0 /*JP*/
1312             Your("mind is %s.", Hallucination
1313                                     ? "much of a muchness"
1314                                     : "back in sync with your body");
1315 #else
1316             Your("\90S\82Í%s\81D", Hallucination
1317                                     ? "\8e\97\82½\82è\8añ\82Á\82½\82è\82É\82È\82Á\82½"
1318                                     : "\8dÄ\82Ñ\91Ì\82Æ\88ê\92v\82·\82é\82æ\82¤\82É\82È\82Á\82½");
1319 #endif
1320     }
1321
1322     if (u.ualign.type != oldalign) {
1323         u.ualign.record = 0; /* slate is wiped clean */
1324         retouch_equipment(0);
1325     }
1326 }
1327
1328 /*attrib.c*/