void init_attr(int np) { int i, x, tryct; for (i = 0; i < A_MAX; i++) { ABASE(i) = AMAX(i) = urole.attrbase[i]; ATEMP(i) = ATIME(i) = 0; np -= urole.attrbase[i]; } /* The starting ability distribution has changed slightly since 3.4.3 so that players with different races but the same role will have the same stats, as far as is possible. Instead of capping scores at the racial maximum, we cap them at STR18(100) for Strength, or 20 for other stats. Then, if any stats end up over the racial cap, we reduce them to the cap and redistribute them on rng_main. The result is that the number of seeds consumed from rng_charstats_role depends purely on role. Note: there were previously two loops here, one to top up to np points, one to cut down to np points. The latter was dead code, and has been removed. */ int pass; for (pass = 1; pass < 3; pass++) { tryct = 0; while (np > 0 && tryct < 100) { x = rn2_on_rng(100, pass == 1 ? rng_charstats_role : rng_main); for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ; if (i >= A_MAX) continue; /* impossible */ int current_max = (pass == 1 ? ATTRMAX(i) : i == A_STR ? STR18(100) : 20); if (ABASE(i) >= current_max) { tryct++; continue; } tryct = 0; ABASE(i)++; AMAX(i)++; np--; } for (i = 0; i < A_MAX; i++) { if (ABASE(i) > ATTRMAX(i)) { np += ABASE(i) - ATTRMAX(i); AMAX(i) -= ABASE(i) - ATTRMAX(i); ABASE(i) = ATTRMAX(i); } } } }
/* adjust an attribute; return true if change is made, false otherwise */ // int msgflg; /* positive => no message, zero => message, and */ // /* negative => conditional (msg if change made) */ bool adjattrib(int ndx, int incr, int msgflg) { if (Fixed_abil || !incr) return false; if ((ndx == A_INT || ndx == A_WIS) && uarmh && uarmh->otyp == DUNCE_CAP) { if (msgflg == 0) Your("cap constricts briefly, then relaxes again."); return false; } if (incr > 0) { if ((AMAX(ndx) >= ATTRMAX(ndx)) && (ACURR(ndx) >= AMAX(ndx))) { if (msgflg == 0 && flags.verbose) pline("You're already as %s as you can get.", plusattr[ndx]); ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx); /* just in case */ return false; } ABASE(ndx) += incr; if(ABASE(ndx) > AMAX(ndx)) { incr = ABASE(ndx) - AMAX(ndx); AMAX(ndx) += incr; if(AMAX(ndx) > ATTRMAX(ndx)) AMAX(ndx) = ATTRMAX(ndx); ABASE(ndx) = AMAX(ndx); } } else { if (ABASE(ndx) <= ATTRMIN(ndx)) { if (msgflg == 0 && flags.verbose) pline("You're already as %s as you can get.", minusattr[ndx]); ABASE(ndx) = ATTRMIN(ndx); /* just in case */ return false; } ABASE(ndx) += incr; if(ABASE(ndx) < ATTRMIN(ndx)) { incr = ABASE(ndx) - ATTRMIN(ndx); ABASE(ndx) = ATTRMIN(ndx); AMAX(ndx) += incr; if(AMAX(ndx) < ATTRMIN(ndx)) AMAX(ndx) = ATTRMIN(ndx); } } if (msgflg <= 0) You_feel("%s%s!", (incr > 1 || incr < -1) ? "very ": "", (incr > 0) ? plusattr[ndx] : minusattr[ndx]); if (moves > 1 && (ndx == A_STR || ndx == A_CON)) (void)encumber_msg(); return true; }
void redist_attr (void) { int i, tmp; for(i = 0; i < A_MAX; i++) { if (i==A_INT || i==A_WIS) continue; /* Polymorphing doesn't change your mind */ tmp = AMAX(i); AMAX(i) += (rn2(5)-2); if (AMAX(i) > ATTRMAX(i)) AMAX(i) = ATTRMAX(i); if (AMAX(i) < ATTRMIN(i)) AMAX(i) = ATTRMIN(i); ABASE(i) = ABASE(i) * AMAX(i) / tmp; /* ABASE(i) > ATTRMAX(i) is impossible */ if (ABASE(i) < ATTRMIN(i)) ABASE(i) = ATTRMIN(i); } (void)encumber_msg(); }
void init_attr (int np) { int i, x, tryct; for(i = 0; i < A_MAX; i++) { ABASE(i) = AMAX(i) = urole.attrbase[i]; ATEMP(i) = ATIME(i) = 0; np -= urole.attrbase[i]; } tryct = 0; while(np > 0 && tryct < 100) { x = rn2(100); for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ; if(i >= A_MAX) continue; /* impossible */ if(ABASE(i) >= ATTRMAX(i)) { tryct++; continue; } tryct = 0; ABASE(i)++; AMAX(i)++; np--; } tryct = 0; while(np < 0 && tryct < 100) { /* for redistribution */ x = rn2(100); for (i = 0; (i < A_MAX) && ((x -= urole.attrdist[i]) > 0); i++) ; if(i >= A_MAX) continue; /* impossible */ if(ABASE(i) <= ATTRMIN(i)) { tryct++; continue; } tryct = 0; ABASE(i)--; AMAX(i)--; np++; } }