1 /* SCCS Id: @(#)attrib.c 3.3 2000/05/17 */
2 /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 /* attribute modification routines. */
6
7 #include "hack.h"
8 #include "artifact.h"
9
10 /* #define DEBUG */ /* uncomment for debugging info */
11
12 #ifdef OVLB
13
14 /* part of the output on gain or loss of attribute */
15 static
16 const char *plusattr[] = {
17 "strong", "smart", "wise", "agile", "tough", "charismatic"
18 },
19 *minusattr[] = {
20 "weak", "stupid", "foolish", "clumsy", "fragile", "repulsive"
21 };
22
23
24 static
25 const struct innate {
26 schar ulevel;
27 long *ability;
28 const char *gainstr, *losestr;
29 } arc_abil[] = { { 1, &(HStealth), "", "" },
30 { 1, &(HFast), "", "" },
31 { 10, &(HSearching), "perceptive", "" },
32 { 0, 0, 0, 0 } },
33
34 bar_abil[] = { { 1, &(HPoison_resistance), "", "" },
35 { 7, &(HFast), "quick", "slow" },
36 { 15, &(HStealth), "stealthy", "" },
37 { 0, 0, 0, 0 } },
38
39 cav_abil[] = { { 7, &(HFast), "quick", "slow" },
40 { 15, &(HWarning), "sensitive", "" },
41 { 0, 0, 0, 0 } },
42
43 hea_abil[] = { { 1, &(HPoison_resistance), "", "" },
44 { 15, &(HWarning), "sensitive", "" },
45 { 0, 0, 0, 0 } },
46
47 kni_abil[] = { { 7, &(HFast), "quick", "slow" },
48 { 0, 0, 0, 0 } },
49
50 mon_abil[] = { { 1, &(HFast), "", "" },
51 { 1, &(HSleep_resistance), "", "" },
52 { 1, &(HSee_invisible), "", "" },
53 { 3, &(HPoison_resistance), "healthy", "" },
54 { 5, &(HStealth), "stealthy", "" },
55 { 7, &(HWarning), "sensitive", "" },
56 { 9, &(HSearching), "perceptive", "unaware" },
57 { 11, &(HFire_resistance), "cool", "warmer" },
58 { 13, &(HCold_resistance), "warm", "cooler" },
59 { 15, &(HShock_resistance), "insulated", "conductive" },
60 { 17, &(HTeleport_control), "controlled","uncontrolled" },
61 { 0, 0, 0, 0 } },
62
63 pri_abil[] = { { 15, &(HWarning), "sensitive", "" },
64 { 20, &(HFire_resistance), "cool", "warmer" },
65 { 0, 0, 0, 0 } },
66
67 ran_abil[] = { { 1, &(HSearching), "", "" },
68 { 7, &(HStealth), "stealthy", "" },
69 { 15, &(HSee_invisible), "", "" },
70 { 0, 0, 0, 0 } },
71
72 rog_abil[] = { { 1, &(HStealth), "", "" },
73 { 10, &(HSearching), "perceptive", "" },
74 { 0, 0, 0, 0 } },
75
76 sam_abil[] = { { 1, &(HFast), "", "" },
77 { 15, &(HStealth), "stealthy", "" },
78 { 0, 0, 0, 0 } },
79
80 tou_abil[] = { { 10, &(HSearching), "perceptive", "" },
81 { 20, &(HPoison_resistance), "hardy", "" },
82 { 0, 0, 0, 0 } },
83
84 val_abil[] = { { 1, &(HCold_resistance), "", "" },
85 { 1, &(HStealth), "", "" },
86 { 7, &(HFast), "quick", "slow" },
87 { 0, 0, 0, 0 } },
88
89 wiz_abil[] = { { 15, &(HWarning), "sensitive", "" },
90 { 17, &(HTeleport_control), "controlled","uncontrolled" },
91 { 0, 0, 0, 0 } },
92
93 /* Intrinsics conferred by race */
94 elf_abil[] = { { 4, &(HSleep_resistance), "awake", "tired" },
95 { 0, 0, 0, 0 } },
96
97 orc_abil[] = { { 1, &(HPoison_resistance), "", "" },
98 { 0, 0, 0, 0 } };
99
100 static long next_check = 600L; /* arbitrary first setting */
101 STATIC_DCL void NDECL(exerper);
102
103 /* adjust an attribute; return TRUE if change is made, FALSE otherwise */
104 boolean
adjattrib(ndx,incr,msgflg)105 adjattrib(ndx, incr, msgflg)
106 int ndx, incr;
107 int msgflg; /* positive => no message, zero => message, and */
108 { /* negative => conditional (msg if change made) */
109 if (Fixed_abil || !incr) return FALSE;
110
111 if ((ndx == A_INT || ndx == A_WIS)
112 && uarmh && uarmh->otyp == DUNCE_CAP) {
113 if (msgflg == 0)
114 Your("cap constricts briefly, then relaxes again.");
115 return FALSE;
116 }
117
118 if (incr > 0) {
119 if ((AMAX(ndx) >= ATTRMAX(ndx)) && (ACURR(ndx) >= AMAX(ndx))) {
120 if (msgflg == 0 && flags.verbose)
121 pline("You're already as %s as you can get.",
122 plusattr[ndx]);
123 ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); /* just in case */
124 return FALSE;
125 }
126
127 ABASE(ndx) += incr;
128 if(ABASE(ndx) > AMAX(ndx)) {
129 incr = ABASE(ndx) - AMAX(ndx);
130 AMAX(ndx) += incr;
131 if(AMAX(ndx) > ATTRMAX(ndx))
132 AMAX(ndx) = ATTRMAX(ndx);
133 ABASE(ndx) = AMAX(ndx);
134 }
135 } else {
136 if (ABASE(ndx) <= ATTRMIN(ndx)) {
137 if (msgflg == 0 && flags.verbose)
138 pline("You're already as %s as you can get.",
139 minusattr[ndx]);
140 ABASE(ndx) = ATTRMIN(ndx); /* just in case */
141 return FALSE;
142 }
143
144 ABASE(ndx) += incr;
145 if(ABASE(ndx) < ATTRMIN(ndx)) {
146 incr = ABASE(ndx) - ATTRMIN(ndx);
147 ABASE(ndx) = ATTRMIN(ndx);
148 AMAX(ndx) += incr;
149 if(AMAX(ndx) < ATTRMIN(ndx))
150 AMAX(ndx) = ATTRMIN(ndx);
151 }
152 }
153 if (msgflg <= 0)
154 You_feel("%s%s!",
155 (incr > 1 || incr < -1) ? "very ": "",
156 (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
157 flags.botl = 1;
158 if (moves > 0 && (ndx == A_STR || ndx == A_CON))
159 (void)encumber_msg();
160 return TRUE;
161 }
162
163 void
gainstr(otmp,incr)164 gainstr(otmp, incr)
165 register struct obj *otmp;
166 register int incr;
167 {
168 int num = 1;
169
170 if(incr) num = incr;
171 else {
172 if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
173 else if (ABASE(A_STR) < STR18(85)) num = rnd(10);
174 }
175 (void) adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
176 }
177
178 void
losestr(num)179 losestr(num) /* may kill you; cause may be poison or monster like 'a' */
180 register int num;
181 {
182 int ustr = ABASE(A_STR) - num;
183
184 while(ustr < 3) {
185 ++ustr;
186 --num;
187 if (Upolyd) {
188 u.mh -= 6;
189 u.mhmax -= 6;
190 } else {
191 u.uhp -= 6;
192 u.uhpmax -= 6;
193 }
194 }
195 (void) adjattrib(A_STR, -num, TRUE);
196 }
197
198 void
change_luck(n)199 change_luck(n)
200 register schar n;
201 {
202 u.uluck += n;
203 if (u.uluck < 0 && u.uluck < LUCKMIN) u.uluck = LUCKMIN;
204 if (u.uluck > 0 && u.uluck > LUCKMAX) u.uluck = LUCKMAX;
205 }
206
207 int
stone_luck(parameter)208 stone_luck(parameter)
209 boolean parameter; /* So I can't think up of a good name. So sue me. --KAA */
210 {
211 register struct obj *otmp;
212 register long bonchance = 0;
213
214 for(otmp = invent; otmp; otmp=otmp->nobj)
215 if (otmp->otyp == LUCKSTONE
216 || (otmp->oartifact && spec_ability(otmp, SPFX_LUCK))) {
217 if (otmp->cursed) bonchance -= otmp->quan;
218 else if (otmp->blessed) bonchance += otmp->quan;
219 else if (parameter) bonchance += otmp->quan;
220 }
221
222 return sgn((int)bonchance);
223 }
224
225 /* there has just been an inventory change affecting a luck-granting item */
226 void
set_moreluck()227 set_moreluck()
228 {
229 int luckbon = stone_luck(TRUE);
230
231 if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0;
232 else if (luckbon >= 0) u.moreluck = LUCKADD;
233 else u.moreluck = -LUCKADD;
234 }
235
236 #endif /* OVLB */
237 #ifdef OVL1
238
239 void
restore_attrib()240 restore_attrib()
241 {
242 int i;
243
244 for(i = 0; i < A_MAX; i++) { /* all temporary losses/gains */
245
246 if(ATEMP(i) && ATIME(i)) {
247 if(!(--(ATIME(i)))) { /* countdown for change */
248 ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
249
250 if(ATEMP(i)) /* reset timer */
251 ATIME(i) = 100 / ACURR(A_CON);
252 }
253 }
254 }
255 (void)encumber_msg();
256 }
257
258 #endif /* OVL1 */
259 #ifdef OVLB
260
261 #define AVAL 50 /* tune value for exercise gains */
262
263 void
exercise(i,inc_or_dec)264 exercise(i, inc_or_dec)
265 int i;
266 boolean inc_or_dec;
267 {
268 #ifdef DEBUG
269 pline("Exercise:");
270 #endif
271 if (i == A_INT || i == A_CHA) return; /* can't exercise these */
272
273 /* no physical exercise while polymorphed; the body's temporary */
274 if (Upolyd && i != A_WIS) return;
275
276 if(abs(AEXE(i)) < AVAL) {
277 /*
278 * Law of diminishing returns (Part I):
279 *
280 * Gain is harder at higher attribute values.
281 * 79% at "3" --> 0% at "18"
282 * Loss is even at all levels (50%).
283 *
284 * Note: *YES* ACURR is the right one to use.
285 */
286 AEXE(i) += (inc_or_dec) ? (rn2(19) > ACURR(i)) : -rn2(2);
287 #ifdef DEBUG
288 pline("%s, %s AEXE = %d",
289 (i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
290 (i == A_DEX) ? "Dex" : "Con",
291 (inc_or_dec) ? "inc" : "dec", AEXE(i));
292 #endif
293 }
294 if (moves > 0 && (i == A_STR || i == A_CON)) (void)encumber_msg();
295 }
296
297 /* hunger values - from eat.c */
298 #define SATIATED 0
299 #define NOT_HUNGRY 1
300 #define HUNGRY 2
301 #define WEAK 3
302 #define FAINTING 4
303 #define FAINTED 5
304 #define STARVED 6
305
306 STATIC_OVL void
exerper()307 exerper()
308 {
309 if(!(moves % 10)) {
310 /* Hunger Checks */
311
312 int hs = (u.uhunger > 1000) ? SATIATED :
313 (u.uhunger > 150) ? NOT_HUNGRY :
314 (u.uhunger > 50) ? HUNGRY :
315 (u.uhunger > 0) ? WEAK : FAINTING;
316
317 #ifdef DEBUG
318 pline("exerper: Hunger checks");
319 #endif
320 switch (hs) {
321 case SATIATED: exercise(A_DEX, FALSE); break;
322 case NOT_HUNGRY: exercise(A_CON, TRUE); break;
323 case WEAK: exercise(A_STR, FALSE); break;
324 case FAINTING:
325 case FAINTED: exercise(A_CON, FALSE); break;
326 }
327
328 /* Encumberance Checks */
329 #ifdef DEBUG
330 pline("exerper: Encumber checks");
331 #endif
332 switch (near_capacity()) {
333 case MOD_ENCUMBER: exercise(A_STR, TRUE); break;
334 case HVY_ENCUMBER: exercise(A_STR, TRUE);
335 exercise(A_DEX, FALSE); break;
336 case EXT_ENCUMBER: exercise(A_DEX, FALSE);
337 exercise(A_CON, FALSE); break;
338 }
339
340 }
341
342 /* status checks */
343 if(!(moves % 5)) {
344 #ifdef DEBUG
345 pline("exerper: Status checks");
346 #endif
347 if ((HClairvoyant & (INTRINSIC|TIMEOUT)) &&
348 !BClairvoyant) exercise(A_WIS, TRUE);
349 if (HRegeneration) exercise(A_STR, TRUE);
350
351 if(Sick || Vomiting) exercise(A_CON, FALSE);
352 if(Confusion || Hallucination) exercise(A_WIS, FALSE);
353 if(Wounded_legs || Fumbling || HStun) exercise(A_DEX, FALSE);
354 }
355 }
356
357 void
exerchk()358 exerchk()
359 {
360 int i, mod_val;
361
362 /* Check out the periodic accumulations */
363 exerper();
364
365 #ifdef DEBUG
366 if(moves >= next_check)
367 pline("exerchk: ready to test. multi = %d.", multi);
368 #endif
369 /* Are we ready for a test? */
370 if(moves >= next_check && !multi) {
371 #ifdef DEBUG
372 pline("exerchk: testing.");
373 #endif
374 /*
375 * Law of diminishing returns (Part II):
376 *
377 * The effects of "exercise" and "abuse" wear
378 * off over time. Even if you *don't* get an
379 * increase/decrease, you lose some of the
380 * accumulated effects.
381 */
382 for(i = 0; i < A_MAX; AEXE(i++) /= 2) {
383
384 if(ABASE(i) >= 18 || !AEXE(i)) continue;
385 if(i == A_INT || i == A_CHA) continue;/* can't exercise these */
386
387 #ifdef DEBUG
388 pline("exerchk: testing %s (%d).",
389 (i == A_STR) ? "Str" : (i == A_WIS) ? "Wis" :
390 (i == A_DEX) ? "Dex" : "Con", AEXE(i));
391 #endif
392 /*
393 * Law of diminishing returns (Part III):
394 *
395 * You don't *always* gain by exercising.
396 * [MRS 92/10/28 - Treat Wisdom specially for balance.]
397 */
398 if(rn2(AVAL) > ((i != A_WIS) ? abs(AEXE(i)*2/3) : abs(AEXE(i))))
399 continue;
400 mod_val = sgn(AEXE(i));
401
402 #ifdef DEBUG
403 pline("exerchk: changing %d.", i);
404 #endif
405 if(adjattrib(i, mod_val, -1)) {
406 #ifdef DEBUG
407 pline("exerchk: changed %d.", i);
408 #endif
409 /* if you actually changed an attrib - zero accumulation */
410 AEXE(i) = 0;
411 /* then print an explanation */
412 switch(i) {
413 case A_STR: You((mod_val >0) ?
414 "must have been exercising." :
415 "must have been abusing your body.");
416 break;
417 case A_WIS: You((mod_val >0) ?
418 "must have been very observant." :
419 "haven't been paying attention.");
420 break;
421 case A_DEX: You((mod_val >0) ?
422 "must have been working on your reflexes." :
423 "haven't been working on reflexes lately.");
424 break;
425 case A_CON: You((mod_val >0) ?
426 "must be leading a healthy life-style." :
427 "haven't been watching your health.");
428 break;
429 }
430 }
431 }
432 next_check += rn1(200,800);
433 #ifdef DEBUG
434 pline("exerchk: next check at %ld.", next_check);
435 #endif
436 }
437 }
438
439 /* next_check will otherwise have its initial 600L after a game restore */
440 void
reset_attribute_clock()441 reset_attribute_clock()
442 {
443 if (moves > 600L) next_check = moves + rn1(50,800);
444 }
445
446
447 void
init_attr(np)448 init_attr(np)
449 register int np;
450 {
451 register int i, x, tryct;
452
453
454 for(i = 0; i < A_MAX; i++) {
455 ABASE(i) = AMAX(i) = urole.attrbase[i];
456 ATEMP(i) = ATIME(i) = 0;
457 np -= urole.attrbase[i];
458 }
459
460 tryct = 0;
461 while(np > 0 && tryct < 100) {
462
463 x = rn2(100);
464 for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ;
465 if(i >= A_MAX) continue; /* impossible */
466
467 if(ABASE(i) >= ATTRMAX(i)) {
468
469 tryct++;
470 continue;
471 }
472 tryct = 0;
473 ABASE(i)++;
474 AMAX(i)++;
475 np--;
476 }
477
478 tryct = 0;
479 while(np < 0 && tryct < 100) { /* for redistribution */
480
481 x = rn2(100);
482 for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ;
483 if(i >= A_MAX) continue; /* impossible */
484
485 if(ABASE(i) <= ATTRMIN(i)) {
486
487 tryct++;
488 continue;
489 }
490 tryct = 0;
491 ABASE(i)--;
492 AMAX(i)--;
493 np++;
494 }
495 }
496
497 void
redist_attr()498 redist_attr()
499 {
500 register int i, tmp;
501
502 for(i = 0; i < A_MAX; i++) {
503 if (i==A_INT || i==A_WIS) continue;
504 /* Polymorphing doesn't change your mind */
505 tmp = AMAX(i);
506 AMAX(i) += (rn2(5)-2);
507 if (AMAX(i) > ATTRMAX(i)) AMAX(i) = ATTRMAX(i);
508 if (AMAX(i) < ATTRMIN(i)) AMAX(i) = ATTRMIN(i);
509 ABASE(i) = ABASE(i) * AMAX(i) / tmp;
510 /* ABASE(i) > ATTRMAX(i) is impossible */
511 if (ABASE(i) < ATTRMIN(i)) ABASE(i) = ATTRMIN(i);
512 }
513 (void)encumber_msg();
514 }
515
516 void
adjabil(oldlevel,newlevel)517 adjabil(oldlevel,newlevel)
518 int oldlevel, newlevel;
519 {
520 register const struct innate *abil, *rabil;
521 long mask = FROMEXPER;
522
523
524 switch (Role_switch) {
525 case PM_ARCHEOLOGIST: abil = arc_abil; break;
526 case PM_BARBARIAN: abil = bar_abil; break;
527 case PM_CAVEMAN: abil = cav_abil; break;
528 case PM_HEALER: abil = hea_abil; break;
529 case PM_KNIGHT: abil = kni_abil; break;
530 case PM_MONK: abil = mon_abil; break;
531 case PM_PRIEST: abil = pri_abil; break;
532 case PM_RANGER: abil = ran_abil; break;
533 case PM_ROGUE: abil = rog_abil; break;
534 case PM_SAMURAI: abil = sam_abil; break;
535 #ifdef TOURIST
536 case PM_TOURIST: abil = tou_abil; break;
537 #endif
538 case PM_VALKYRIE: abil = val_abil; break;
539 case PM_WIZARD: abil = wiz_abil; break;
540 default: abil = 0; break;
541 }
542
543 switch (Race_switch) {
544 case PM_ELF: rabil = elf_abil; break;
545 case PM_ORC: rabil = orc_abil; break;
546 case PM_HUMAN:
547 case PM_DWARF:
548 case PM_GNOME:
549 default: rabil = 0; break;
550 }
551
552 while (abil || rabil) {
553 /* Have we finished with the intrinsics list? */
554 if (!abil || !abil->ability) {
555 /* Try the race intrinsics */
556 if (!rabil || !rabil->ability) break;
557 abil = rabil;
558 rabil = 0;
559 mask = FROMRACE;
560 }
561
562 if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
563 /* Abilities gained at level 1 can never be lost
564 * via level loss, only via means that remove _any_
565 * sort of ability. A "gain" of such an ability from
566 * an outside source is devoid of meaning, so we set
567 * FROMOUTSIDE to avoid such gains.
568 */
569 if (abil->ulevel == 1)
570 *(abil->ability) |= (mask|FROMOUTSIDE);
571 else
572 *(abil->ability) |= mask;
573 if(!(*(abil->ability) & INTRINSIC & ~mask)) {
574 if(*(abil->gainstr))
575 You_feel("%s!", abil->gainstr);
576 }
577 } else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
578 *(abil->ability) &= ~mask;
579 if(!(*(abil->ability) & INTRINSIC)) {
580 if(*(abil->losestr))
581 You_feel("%s!", abil->losestr);
582 else if(*(abil->gainstr))
583 You_feel("less %s!", abil->gainstr);
584 }
585 }
586 abil++;
587 }
588
589 if (oldlevel > 0) {
590 if (newlevel > oldlevel)
591 add_weapon_skill(newlevel - oldlevel);
592 else
593 lose_weapon_skill(oldlevel - newlevel);
594 }
595 }
596
597
598 int
newhp()599 newhp()
600 {
601 int hp, conplus;
602
603
604 if (u.ulevel == 0) {
605 /* Initialize hit points */
606 hp = urole.hpadv.infix + urace.hpadv.infix;
607 if (urole.hpadv.inrnd > 0) hp += rnd(urole.hpadv.inrnd);
608 if (urace.hpadv.inrnd > 0) hp += rnd(urace.hpadv.inrnd);
609
610 /* Initialize alignment stuff */
611 u.ualign.type = aligns[flags.initalign].value;
612 u.ualign.record = urole.initrecord;
613
614 return hp;
615 } else {
616 if (u.ulevel < urole.xlev) {
617 hp = urole.hpadv.lofix + urace.hpadv.lofix;
618 if (urole.hpadv.lornd > 0) hp += rnd(urole.hpadv.lornd);
619 if (urace.hpadv.lornd > 0) hp += rnd(urace.hpadv.lornd);
620 } else {
621 hp = urole.hpadv.hifix + urace.hpadv.hifix;
622 if (urole.hpadv.hirnd > 0) hp += rnd(urole.hpadv.hirnd);
623 if (urace.hpadv.hirnd > 0) hp += rnd(urace.hpadv.hirnd);
624 }
625 }
626
627 if (ACURR(A_CON) <= 3) conplus = -2;
628 else if (ACURR(A_CON) <= 6) conplus = -1;
629 else if (ACURR(A_CON) <= 14) conplus = 0;
630 else if (ACURR(A_CON) <= 16) conplus = 1;
631 else if (ACURR(A_CON) == 17) conplus = 2;
632 else if (ACURR(A_CON) == 18) conplus = 3;
633 else conplus = 4;
634
635 hp += conplus;
636 return((hp <= 0) ? 1 : hp);
637 }
638
639 #endif /* OVLB */
640 #ifdef OVL0
641
642 schar
acurr(x)643 acurr(x)
644 int x;
645 {
646 register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
647
648 if (x == A_STR) {
649 if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
650 #ifdef WIN32_BUG
651 else return(x=((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp));
652 #else
653 else return((schar)((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp));
654 #endif
655 } else if (x == A_CHA) {
656 if (tmp < 18 && (youmonst.data->mlet == S_NYMPH ||
657 u.umonnum==PM_SUCCUBUS || u.umonnum == PM_INCUBUS))
658 return 18;
659 } else if (x == A_INT || x == A_WIS) {
660 /* yes, this may raise int/wis if player is sufficiently
661 * stupid. there are lower levels of cognition than "dunce".
662 */
663 if (uarmh && uarmh->otyp == DUNCE_CAP) return(6);
664 }
665 #ifdef WIN32_BUG
666 return(x=((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
667 #else
668 return((schar)((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp));
669 #endif
670 }
671
672 /* condense clumsy ACURR(A_STR) value into value that fits into game formulas
673 */
674 schar
acurrstr()675 acurrstr()
676 {
677 register int str = ACURR(A_STR);
678
679 if (str <= 18) return((schar)str);
680 if (str <= 121) return((schar)(19 + str / 50)); /* map to 19-21 */
681 else return((schar)(str - 100));
682 }
683
684 #endif /* OVL0 */
685 #ifdef OVL2
686
687 /* avoid possible problems with alignment overflow, and provide a centralized
688 * location for any future alignment limits
689 */
690 void
adjalign(n)691 adjalign(n)
692 register int n;
693 {
694 register int newalign = u.ualign.record + n;
695
696 if(n < 0) {
697 if(newalign < u.ualign.record)
698 u.ualign.record = newalign;
699 } else
700 if(newalign > u.ualign.record) {
701 u.ualign.record = newalign;
702 if(u.ualign.record > ALIGNLIM)
703 u.ualign.record = ALIGNLIM;
704 }
705 }
706
707 #endif /* OVL2 */
708
709 /*attrib.c*/
710