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);
            }
        }
    }
}
Exemple #2
0
/* 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;
}
Exemple #3
0
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();
}
Exemple #4
0
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++;
    }
}