예제 #1
0
long
bribe(struct monst *mtmp)
{
    const char *buf;
    long offer;
    long umoney = money_cnt(invent);

    buf = getlin("How much will you offer?", FALSE);
    if (sscanf(buf, "%ld", &offer) != 1)
        offer = 0L;

    /* Michael Paddon -- fix for negative offer to monster */
    /* JAR880815 - */
    if (offer < 0L) {
        pline("You try to shortchange %s, but fumble.", mon_nam(mtmp));
        return 0L;
    } else if (offer == 0L) {
        pline("You refuse.");
        return 0L;
    } else if (umoney == 0L) {
        pline("You open your purse, but realize you have no gold.");
        return 0L;
    } else if (offer >= umoney) {
        pline("You give %s all your gold.", mon_nam(mtmp));
        offer = umoney;
    } else {
        pline("You give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
    }
    money2mon(mtmp, offer);

    return offer;
}
예제 #2
0
long
bribe(struct monst *mtmp)
{
    char buf[BUFSZ];
    long offer;
    long umoney = money_cnt(invent);

    getlin("How much will you offer?", buf);
    if (sscanf(buf, "%ld", &offer) != 1)
        offer = 0L;

    /* Michael Paddon -- fix for negative offer to monster */
    /* JAR880815 - */
    if (offer < 0L) {
        pline("You try to shortchange %s, but fumble.", mon_nam(mtmp));
        return 0L;
    } else if (offer == 0L) {
        pline("You refuse.");
        return 0L;
    } else if (offer >= umoney) {
        pline("You give %s all your gold.", mon_nam(mtmp));
        offer = umoney;
    } else {
        pline("You give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
    }
    money2mon(mtmp, offer);

    iflags.botl = 1;
    return offer;
}
예제 #3
0
파일: botl.c 프로젝트: FredrIQ/fiqhack
static long
botl_score(void)
{
    long umoney = money_cnt(invent) + hidden_gold();

    return calc_score(DIED, FALSE, umoney);
}
예제 #4
0
/* 
 * Steal gold coins only.  Leprechauns don't care for lesser coins.
 */
void stealgold(struct monst *mtmp)
{
	struct obj *fgold = gold_at(level, u.ux, u.uy);
	struct obj *ygold;
	long tmp;

        /* skip lesser coins on the floor */        
        while (fgold && fgold->otyp != GOLD_PIECE) fgold = fgold->nexthere; 

        /* Do you have real gold? */
        ygold = findgold(invent);

	if (fgold && ( !ygold || fgold->quan > ygold->quan || !rn2(5))) {
            obj_extract_self(fgold);
	    add_to_minv(mtmp, fgold);
	    newsym(u.ux, u.uy);
	    pline("%s quickly snatches some gold from between your %s!",
		    Monnam(mtmp), makeplural(body_part(FOOT)));
	    if (!ygold || !rn2(5)) {
		if (!tele_restrict(mtmp)) rloc(level, mtmp, FALSE);
		monflee(mtmp, 0, FALSE, FALSE);
	    }
	} else if (ygold) {
            const int gold_price = objects[GOLD_PIECE].oc_cost;
	    tmp = (somegold(money_cnt(invent)) + gold_price - 1) / gold_price;
	    tmp = min(tmp, ygold->quan);
            if (tmp < ygold->quan) ygold = splitobj(ygold, tmp);
            freeinv(ygold);
            add_to_minv(mtmp, ygold);
	    pline("Your purse feels lighter.");
	    if (!tele_restrict(mtmp)) rloc(level, mtmp, FALSE);
	    monflee(mtmp, 0, FALSE, FALSE);
	    iflags.botl = 1;
	}
}
예제 #5
0
/* returns 1 if it won't attack. */
int
demon_talk(struct monst *mtmp)
{
    long cash, demand, offer;

    if (uwep && uwep->oartifact == ART_EXCALIBUR) {
        pline("%s looks very angry.", Amonnam(mtmp));
        msethostility(mtmp, TRUE, TRUE);
        return 0;
    }

    /* Slight advantage given. */
    if (is_dprince(mtmp->data) && mtmp->minvis) {
        mtmp->minvis = mtmp->perminvis = 0;
        if (!Blind)
            pline("%s appears before you.", Amonnam(mtmp));
        newsym(mtmp->mx, mtmp->my);
    }
    if (youmonst.data->mlet == S_DEMON) {       /* Won't blackmail their own. */
        pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
              u.ufemale ? "Sister" : "Brother");
        if (!tele_restrict(mtmp))
            rloc(mtmp, TRUE);
        return 1;
    }
    cash = money_cnt(invent);
    /* don't bother with a custom RNG here, too much unpredictability is
       involved */
    demand = (cash * (rnd(80) + 20 * Athome)) /
        (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));

    if (!demand) {      /* you have no gold */
        msethostility(mtmp, TRUE, TRUE);
        return 0;
    } else {
        /* make sure that the demand is unmeetable if the monster has the
           Amulet, preventing monster from being satisified and removed from
           the game (along with said Amulet...) */
        if (mon_has_amulet(mtmp))
            demand = cash + (long)rn1(1000, 40);

        pline("%s demands %ld %s for safe passage.", Amonnam(mtmp), demand,
              currency(demand));

        if ((offer = bribe(mtmp)) >= demand) {
            pline("%s vanishes, laughing about cowardly %s.", Amonnam(mtmp),
                  makeplural(mortal_or_creature(youmonst.data, FALSE)));
        } else if (offer > 0L && (long)rnd(40) > (demand - offer)) {
            pline("%s scowls at you menacingly, then vanishes.", Amonnam(mtmp));
        } else {
            pline("%s gets angry...", Amonnam(mtmp));
            msethostility(mtmp, TRUE, TRUE);
            return 0;
        }
    }
    mongone(mtmp);
    return 1;
}
예제 #6
0
static void
fill_topten_entry(struct toptenentry *newtt, int how)
{
    int uid = getuid();

    memset(newtt, 0, sizeof (struct toptenentry));

    /* deepest_lev_reached() is in terms of depth(), and reporting the deepest
       level reached in the dungeon death occurred in doesn't seem right, so we 
       have to report the death level in depth() terms as well (which also
       seems reasonable since that's all the player sees on the screen anyway) */
    newtt->ver_major = VERSION_MAJOR;
    newtt->ver_minor = VERSION_MINOR;
    newtt->patchlevel = PATCHLEVEL;
    newtt->points = u.urexp > -1 ?      /* u.urexp stores score once invent is
                                           invalid */
        u.urexp : calc_score(how, FALSE, money_cnt(invent) + hidden_gold());
    newtt->deathdnum = u.uz.dnum;
    newtt->deathlev = depth(&u.uz);
    newtt->maxlvl = deepest_lev_reached(TRUE);
    newtt->hp = u.uhp;
    newtt->maxhp = u.uhpmax;
    newtt->deaths = u.umortality;
    newtt->uid = uid;
    newtt->moves = moves;
    newtt->how = how;
    strncpy(newtt->plrole, urole.filecode, ROLESZ);
    newtt->plrole[ROLESZ] = '\0';
    strncpy(newtt->plrace, urace.filecode, ROLESZ);
    newtt->plrace[ROLESZ] = '\0';
    strncpy(newtt->plgend, genders[flags.female].filecode, ROLESZ);
    newtt->plgend[ROLESZ] = '\0';
    strncpy(newtt->plalign, aligns[1 - u.ualign.type].filecode, ROLESZ);
    newtt->plalign[ROLESZ] = '\0';
    strncpy(newtt->name, plname, NAMSZ);
    newtt->name[NAMSZ] = '\0';
    newtt->death[0] = '\0';
    switch (killer_format) {
    default:
        impossible("bad killer format?");
    case KILLED_BY_AN:
        strcat(newtt->death, killed_by_prefix[how]);
        strncat(newtt->death, an(killer), DTHSZ - strlen(newtt->death));
        break;
    case KILLED_BY:
        strcat(newtt->death, killed_by_prefix[how]);
        strncat(newtt->death, killer, DTHSZ - strlen(newtt->death));
        break;
    case NO_KILLER_PREFIX:
        strncat(newtt->death, killer, DTHSZ);
        break;
    }
    newtt->birthdate = yyyymmdd(u.ubirthday);
    newtt->deathdate = yyyymmdd((time_t) 0L);
    time(&deathtime_internal);
}
예제 #7
0
/* Routine when dying or quitting with a vault guard around */
void
paygd(void)
{
    struct monst *grd = findgd();
    long umoney = money_cnt(invent);
    struct obj *coins, *nextcoins;
    int gx, gy;

    if (!umoney || !grd)
        return;

    if (u.uinvault) {
        pline("Your %ld %s goes into the Magic Memory Vault.", umoney,
              currency(umoney));
        gx = u.ux;
        gy = u.uy;
    } else {
        if (grd->mpeaceful) {   /* guard has no "right" to your gold */
            mongone(grd);
            return;
        }
        mnexto(grd);
        pline("%s remits your gold to the vault.", Monnam(grd));
        gx = level->rooms[EGD(grd)->vroom].lx + rn2(2);
        gy = level->rooms[EGD(grd)->vroom].ly + rn2(2);
        make_grave(level, gx, gy,
                   msgprintf(
                       "To Croesus: here's the gold recovered from %s the %s.",
                       u.uplname, mons[u.umonster].mname));
    }
    
    for (coins = invent; coins; coins = nextcoins) {
        nextcoins = coins->nobj;
        if (objects[coins->otyp].oc_class == COIN_CLASS) {
            unwield_silently(coins);
            freeinv(coins);
            place_object(coins, level, gx, gy);
            stackobj(coins);
        }
    }
    mongone(grd);
}
예제 #8
0
파일: dump.c 프로젝트: FredrIQ/nhfourk
static void
dump_status(void)
{
    int hp;
    char rngseedbuf[RNG_SEED_SIZE_BASE64];

    fprintf(dumpfp, "%s the %s\n", u.uplname,
            rank_of(u.ulevel, Role_switch, u.ufemale));
    fprintf(dumpfp, "  Experience level: %d\n", u.ulevel);

    if (ACURR(A_STR) > 18) {
        if (ACURR(A_STR) < 118)
            fprintf(dumpfp, "  Strength: 18/%02d\n", ACURR(A_STR) - 18);
        else if (ACURR(A_STR) == 118)
            fprintf(dumpfp, "  Strength: 18/**\n");
        else
            fprintf(dumpfp, "  Strength: %-1d\n", ACURR(A_STR) - 100);
    } else
        fprintf(dumpfp, "  Strength: %-1d\n", ACURR(A_STR));

    fprintf(dumpfp, "  Dexterity: %-1d\n  Constitution: %-1d\n", ACURR(A_DEX),
            ACURR(A_CON));
    fprintf(dumpfp, "  Intelligence: %-1d\n  Wisdom: %-1d\n  Charisma: %-1d\n",
            ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));

    hp = Upolyd ? u.mh : u.uhp;
    fprintf(dumpfp, "  Health: %d(%d)\n", hp < 0 ? 0 : hp,
            Upolyd ? u.mhmax : u.uhpmax);
    fprintf(dumpfp, "  Energy: %d(%d)\n", u.uen, u.uenmax);
    fprintf(dumpfp, "  Def: %d\n", 10 - get_player_ac());
    fprintf(dumpfp, "  Gold: %ld\n", money_cnt(invent));
    fprintf(dumpfp, "  Moves: %u\n\n", moves);

    get_initial_rng_seed(rngseedbuf);

    fprintf(dumpfp, "Dungeon seed: %.*s\n", RNG_SEED_SIZE_BASE64, rngseedbuf);
    fprintf(dumpfp, "Game ID: %s_%" PRIdLEAST64 "\n\n", u.uplname,
            (int_least64_t)u.ubirthday / 1000000L);
}
예제 #9
0
int
doconsult(struct monst *oracl)
{
    int umoney = money_cnt(invent);
    int u_pay, minor_cost = 50, major_cost = 500 + 50 * u.ulevel;
    int add_xpts;
    const char *qbuf;

    /* TODO: Do we want this? The purpose seems to be specifically to prevent
       repeating an Oracle donation. */
    action_completed();

    if (!oracl) {
        pline("There is no one here to consult.");
        return 0;
    } else if (!oracl->mpeaceful) {
        pline("%s is not in the mood for conversation (believe it or not...)", Monnam(oracl));
        return 0;
    } else if (!umoney) {
        pline("You have no money.  There's no free lunch in wireless... and in being an oracle!");
        return 0;
    }

    qbuf = msgprintf("\"Would you mind talking for a little bit?\" (%d %s)",
                     minor_cost, currency(minor_cost));
    switch (ynq(qbuf)) {
    default:
    case 'q':
        return 0;
    case 'y':
        if (umoney < minor_cost) {
            pline("You don't even have enough money for that! There's no free lunch in wireless... and in being an oracle!");
            return 0;
        }
        u_pay = minor_cost;
        break;
    case 'n':
        if (umoney <= minor_cost ||     /* don't even ask */
            (oracle_cnt == 1 || oracle_flg < 0))
            return 0;
        qbuf = msgprintf("\"Oh! You'd like to sit and talk for a _long_ while?\" (%d %s)",
                         major_cost, currency(major_cost));
        if (yn(qbuf) != 'y')
            return 0;
        u_pay = (umoney < major_cost ? umoney : major_cost);

        break;
    }

    money2mon(oracl, u_pay);
    add_xpts = 0;       /* first oracle of each type gives experience points */
    if (u_pay == minor_cost) {
        outrumor(1, BY_ORACLE);
        if (!u.uevent.minor_oracle)
            add_xpts = u_pay / (u.uevent.major_oracle ? 25 : 10);
        /* 5 pts if very 1st, or 2 pts if major already done */
        u.uevent.minor_oracle = TRUE;
    } else {
        boolean cheapskate = u_pay < major_cost;

        outoracle(cheapskate, TRUE);
        if (!cheapskate && !u.uevent.major_oracle)
            add_xpts = u_pay / (u.uevent.minor_oracle ? 25 : 10);
        /* ~100 pts if very 1st, ~40 pts if minor already done */
        u.uevent.major_oracle = TRUE;
        historic_event(FALSE, "received advice from The Oracle.");
        exercise(A_WIS, !cheapskate);
    }
    if (add_xpts) {
        more_experienced(add_xpts, u_pay / 50);
        newexplevel();
    }
    return 1;
}
예제 #10
0
파일: detect.c 프로젝트: DanielT/NitroHack
/* look for gold, on the floor or in monsters' possession */
int gold_detect(struct obj *sobj, boolean *scr_known)
{
    struct obj *obj;
    struct monst *mtmp;
    int uw = u.uinwater;
    struct obj *temp;
    boolean stale;

    *scr_known = stale = clear_stale_map(COIN_CLASS, sobj->blessed ? GOLD : 0);

    /* look for gold carried by monsters (might be in a container) */
    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
    	if (DEADMONSTER(mtmp)) continue;	/* probably not needed in this case but... */
	if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
	    *scr_known = TRUE;
	    goto outgoldmap;	/* skip further searching */
	} else for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (sobj->blessed && o_material(obj, GOLD)) {
	    	*scr_known = TRUE;
	    	goto outgoldmap;
	    } else if (o_in(obj, COIN_CLASS)) {
		*scr_known = TRUE;
		goto outgoldmap;	/* skip further searching */
	    }
    }
    
    /* look for gold objects */
    for (obj = level->objlist; obj; obj = obj->nobj) {
	if (sobj->blessed && o_material(obj, GOLD)) {
	    *scr_known = TRUE;
	    if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
	} else if (o_in(obj, COIN_CLASS)) {
	    *scr_known = TRUE;
	    if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
	}
    }

    if (!*scr_known) {
	/* no gold found on floor or monster's inventory.
	   adjust message if you have gold in your inventory */
	char buf[BUFSZ];
	if (youmonst.data == &mons[PM_GOLD_GOLEM]) {
		sprintf(buf, "You feel like a million %s!", currency(2L));
	} else if (hidden_gold() || money_cnt(invent))
		strcpy(buf, "You feel worried about your future financial situation.");
	else
		strcpy(buf, "You feel materially poor.");
	strange_feeling(sobj, buf);
	return 1;
    }
    /* only under me - no separate display required */
    if (stale) doredraw();
    pline("You notice some gold between your %s.", makeplural(body_part(FOOT)));
    return 0;

outgoldmap:
    cls();

    u.uinwater = 0;
    /* Discover gold locations. */
    for (obj = level->objlist; obj; obj = obj->nobj) {
    	if (sobj->blessed && (temp = o_material(obj, GOLD))) {
	    if (temp != obj) {
		temp->ox = obj->ox;
		temp->oy = obj->oy;
	    }
	    map_object(temp,1);
	} else if ((temp = o_in(obj, COIN_CLASS))) {
	    if (temp != obj) {
		temp->ox = obj->ox;
		temp->oy = obj->oy;
	    }
	    map_object(temp,1);
	}
    }
    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
    	if (DEADMONSTER(mtmp)) continue;	/* probably overkill here */
	if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
	    struct obj gold;

	    gold.otyp = GOLD_PIECE;
	    gold.ox = mtmp->mx;
	    gold.oy = mtmp->my;
	    map_object(&gold,1);
	} else for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (sobj->blessed && (temp = o_material(obj, GOLD))) {
		temp->ox = mtmp->mx;
		temp->oy = mtmp->my;
		map_object(temp,1);
		break;
	    } else if ((temp = o_in(obj, COIN_CLASS))) {
		temp->ox = mtmp->mx;
		temp->oy = mtmp->my;
		map_object(temp,1);
		break;
	    }
    }
    
    newsym(u.ux,u.uy);
    pline("You feel very greedy, and sense gold!");
    exercise(A_WIS, TRUE);
    win_pause_output(P_MAP);
    doredraw();
    u.uinwater = uw;
    if (Underwater) under_water(2);
    if (u.uburied) under_ground(2);
    return 0;
}
예제 #11
0
파일: priest.c 프로젝트: FredrIQ/nhfourk
void
priest_talk(struct monst *priest)
{
    boolean coaligned = p_coaligned(priest);
    boolean strayed = (u.ualign.record < 0);

    /* KMH, conduct */
    break_conduct(conduct_gnostic);

    if (priest->mflee || (!priest->ispriest && coaligned && strayed)) {
        pline("%s doesn't want anything to do with you!", Monnam(priest));
        msethostility(priest, TRUE, FALSE);
        return;
    }

    /* priests don't chat unless peaceful and in their own temple */
    if (!histemple_at(priest, priest->mx, priest->my) || !priest->mpeaceful ||
        !priest->mcanmove || priest->msleeping) {
        static const char *const cranky_msg[3] = {
            "Thou wouldst have words, eh?  I'll give thee a word or two!",
            "Talk?  Here is what I have to say!",
            "Pilgrim, I would speak no longer with thee."
        };

        if (!priest->mcanmove || priest->msleeping) {
            pline("%s breaks out of %s reverie!", Monnam(priest), mhis(priest));
            priest->mfrozen = priest->msleeping = 0;
            priest->mcanmove = 1;
        }
        msethostility(priest, TRUE, FALSE);
        verbalize("%s", cranky_msg[rn2(3)]);
        return;
    }

    /* you desecrated the temple and now you want to chat? */
    if (priest->mpeaceful && *in_rooms(level, priest->mx, priest->my, TEMPLE) &&
        !has_shrine(priest)) {
        verbalize
            ("Begone!  Thou desecratest this holy place with thy presence.");
        msethostility(priest, TRUE, FALSE);
        return;
    }
    if (!money_cnt(invent)) {
        if (coaligned && !strayed) {
            long pmoney = money_cnt(priest->minvent);

            if (pmoney > 0L) {
                /* Note: two bits is actually 25 cents.  Hmm. */
                pline("%s gives you %s for an ale.", Monnam(priest),
                      (pmoney == 1L) ? "one bit" : "two bits");
                money2u(priest, pmoney > 1L ? 2 : 1);
            } else
                pline("%s preaches the virtues of poverty.", Monnam(priest));
        } else
            pline("%s is not interested.", Monnam(priest));
        return;
    } else {
        long offer;

        pline("%s asks you for a contribution for the temple.", Monnam(priest));
        if ((offer = bribe(priest)) == 0) {
            verbalize("Thou shalt regret thine action!");
            if (coaligned)
                adjalign(-1);
        } else if (offer < (u.ulevel * 200)) {
            if (money_cnt(invent) > (offer * 2L))
                verbalize("Cheapskate.");
            else {
                verbalize("I thank thee for thy contribution.");
            }
        } else if (offer < (u.ulevel * 400)) {
            verbalize("Thou art indeed a pious individual.");
            if (money_cnt(invent) < (offer * 2L)) {
                if (coaligned && u.ualign.record <= ALGN_SINNED)
                    adjalign(1);
                verbalize("I bestow upon thee a blessing.");
                incr_itimeout(&HClairvoyant, rn1(500, 500));
            }
        } else if (offer < (u.ulevel * 600) && u.ublessed < 20 &&
                   (u.ublessed < 9 || !rn2(u.ublessed))) {
            verbalize("Thy devotion has been rewarded.");
            if (!(HProtection & INTRINSIC)) {
                HProtection |= FROMOUTSIDE;
                if (!u.ublessed)
                    u.ublessed = rn1(3, 2);
            } else
                u.ublessed++;
        } else {
            verbalize("Thy selfless generosity is deeply appreciated.");
            if (money_cnt(invent) < (offer * 2L) && coaligned) {
                if (strayed && (moves - u.ucleansed) > 5000L) {
                    u.ualign.record = 0;        /* cleanse thee */
                    u.ucleansed = moves;
                } else {
                    adjalign(2);
                }
            }
        }
    }
}
예제 #12
0
파일: end.c 프로젝트: FredrIQ/fiqhack
    /* make sure the inventory is fully identified, even if DYWYPI = n */
    for (obj = invent; obj; obj = obj->nobj) {
        discover_object(obj->otyp, TRUE, FALSE, TRUE);
        obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
    }
    display_inventory(NULL, TRUE);
    container_contents(invent, TRUE, TRUE);
    dump_spells();
    dump_skills();
    enlighten_mon(&youmonst, how > LAST_KILLER ? 1 : 2, 1);     /* final */
    list_vanquished('y', FALSE);
    list_genocided('y', FALSE);
    show_conduct(how > LAST_KILLER ? 1 : 2);
    dooverview(&(struct nh_cmd_arg){.argtype = 0});
    dohistory(&(struct nh_cmd_arg){.argtype = 0});
    calc_score(how, TRUE, money_cnt(invent) + hidden_gold());

    /* make menus work normally again */
    dump_catch_menus(FALSE);
}


/* try to get the player back in a viable state after being killed */
static void
savelife(int how)
{
    /* just swallow any --More--s that were waiting until we died; if the player
       has a force-more on msgc_fatalavoid, they'll get a --More-- anyway, and
       if they don't, they probably don't want one */
    turnstate.force_more_pending_until_done = FALSE;
    u.uswldtim = 0;
예제 #13
0
파일: cursstat.c 프로젝트: bhaak/sporkhack
void curses_update_stats()
{
    char buf[BUFSZ];
    int count, enc, orient, sx_start;
    WINDOW *win = curses_get_nhwin(STATUS_WIN);
    static boolean first = TRUE;
    boolean horiz;
    int sx = 0;
    int sy = 0;
    boolean border = curses_window_has_border(STATUS_WIN);
    
    if (border)
    {
        sx++;
        sy++;
    }
    
    sx_start = sx;
        
    if (first)
    {
        init_stats();
        first = FALSE;
    }
    
    orient = curses_get_window_orientation(STATUS_WIN);

    if ((orient == ALIGN_RIGHT) || (orient == ALIGN_LEFT))
    {
        horiz = FALSE;
    }
    else
    {
        horiz = TRUE;
    }

    curses_clear_nhwin(STATUS_WIN);
    
    /* Line 1 */
    
    /* Player name and title */
    strcpy(buf, plname);
    if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
    strcat(buf, " the ");
    if (u.mtimedone) {
        char mname[BUFSZ];
        int k = 0;

        strcpy(mname, mons[u.umonnum].mname);
        while(mname[k] != 0) {
            if ((k == 0 || (k > 0 && mname[k-1] == ' '))
             && 'a' <= mname[k] && mname[k] <= 'z')
            {
                mname[k] += 'A' - 'a';
            }
            k++;
        }
        strcat(buf, mname);
    } else {
        strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
    }
    
    if (strcmp(buf, prevname.txt) != 0) /* Title changed */
    {
        prevname.highlight_turns = 5;
        prevname.highlight_color = HIGHLIGHT_COLOR;
        free(prevname.txt);
        prevname.txt = curses_copy_of(buf);
    }
    
    if (prevname.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevname.label);
        sx += strlen(prevname.label);
    }
    
    if (prevname.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevname.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevname.txt);
        curses_toggle_color_attr(win, prevname.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevname.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevname.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }
    
    /* Strength */
    if (ACURR(A_STR) != prevstr.value)  /* Strength changed */
    {
        
        if (ACURR(A_STR) > prevstr.value)
        {
            prevstr.highlight_color = STAT_UP_COLOR;
        }
        else
        {
            prevstr.highlight_color = STAT_DOWN_COLOR;
        }
        prevstr.value = ACURR(A_STR);
        if (ACURR(A_STR) > 118)
        {
            sprintf(buf, "%d", ACURR(A_STR) - 100);
        }
        else if (ACURR(A_STR)==118)
        {
            sprintf(buf, "18/**");
        }
        else if(ACURR(A_STR) > 18)
        {
            sprintf(buf, "18/%02d", ACURR(A_STR) - 18);
        }
        else
        {
            sprintf(buf, "%d", ACURR(A_STR));
        }
        free(prevstr.txt);
        prevstr.txt = curses_copy_of(buf);
        prevstr.highlight_turns = 5;
    }

    if (prevstr.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevstr.label);
        sx += strlen(prevstr.label);
    }
    
    if (prevstr.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevstr.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevstr.txt);
        curses_toggle_color_attr(win, prevstr.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevstr.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevstr.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Intelligence */
    if (ACURR(A_INT) != prevint.value)  /* Intelligence changed */
    {
        
        if (ACURR(A_INT) > prevint.value)
        {
            prevint.highlight_color = STAT_UP_COLOR;
        }
        else
        {
            prevint.highlight_color = STAT_DOWN_COLOR;
        }
        prevint.value = ACURR(A_INT);
        sprintf(buf, "%d", ACURR(A_INT)); 
        free(prevint.txt);
        prevint.txt = curses_copy_of(buf);
        prevint.highlight_turns = 5;
    }

    if (prevint.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevint.label);
        sx += strlen(prevint.label);
    }
    
    if (prevint.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevint.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevint.txt);
        curses_toggle_color_attr(win, prevint.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevint.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevint.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Wisdom */
    if (ACURR(A_WIS) != prevwis.value)  /* Wisdom changed */
    {
        
        if (ACURR(A_WIS) > prevwis.value)
        {
            prevwis.highlight_color = STAT_UP_COLOR;
        }
        else
        {
            prevwis.highlight_color = STAT_DOWN_COLOR;
        }
        prevwis.value = ACURR(A_WIS);
        sprintf(buf, "%d", ACURR(A_WIS)); 
        free(prevwis.txt);
        prevwis.txt = curses_copy_of(buf);
        prevwis.highlight_turns = 5;
    }

    if (prevwis.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevwis.label);
        sx += strlen(prevwis.label);
    }
    
    if (prevwis.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevwis.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevwis.txt);
        curses_toggle_color_attr(win, prevwis.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevwis.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevwis.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Dexterity */
    if (ACURR(A_DEX) != prevdex.value)  /* Dexterity changed */
    {
        
        if (ACURR(A_DEX) > prevdex.value)
        {
            prevdex.highlight_color = STAT_UP_COLOR;
        }
        else
        {
            prevdex.highlight_color = STAT_DOWN_COLOR;
        }
        prevdex.value = ACURR(A_DEX);
        sprintf(buf, "%d", ACURR(A_DEX));
        free(prevdex.txt);
        prevdex.txt = curses_copy_of(buf);
        prevdex.highlight_turns = 5;
    }

    if (prevdex.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevdex.label);
        sx += strlen(prevdex.label);
    }
    
    if (prevdex.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevdex.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevdex.txt);
        curses_toggle_color_attr(win, prevdex.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevdex.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevdex.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Constitution */
    if (ACURR(A_CON) != prevcon.value)  /* Constitution changed */
    {
        
        if (ACURR(A_CON) > prevcon.value)
        {
            prevcon.highlight_color = STAT_UP_COLOR;
        }
        else
        {
            prevcon.highlight_color = STAT_DOWN_COLOR;
        }
        prevcon.value = ACURR(A_CON);
        sprintf(buf, "%d", ACURR(A_CON));
        free(prevcon.txt);
        prevcon.txt = curses_copy_of(buf);
        prevcon.highlight_turns = 5;
    }

    if (prevcon.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevcon.label);
        sx += strlen(prevcon.label);
    }
    
    if (prevcon.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevcon.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevcon.txt);
        curses_toggle_color_attr(win, prevcon.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevcon.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevcon.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Charisma */
    if (ACURR(A_CHA) != prevcha.value)  /* Charisma changed */
    {
        if (ACURR(A_CHA) > prevcha.value)
        {
            prevcha.highlight_color = STAT_UP_COLOR;
        }
        else
        {
            prevcha.highlight_color = STAT_DOWN_COLOR;
        }
        prevcha.value = ACURR(A_CHA);
        sprintf(buf, "%d", ACURR(A_CHA));
        free(prevcha.txt);
        prevcha.txt = curses_copy_of(buf);
        prevcha.highlight_turns = 5;
    }

    if (prevcha.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevcha.label);
        sx += strlen(prevcha.label);
    }
    
    if (prevcha.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevcha.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevcha.txt);
        curses_toggle_color_attr(win, prevcha.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevcha.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevcha.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }
    
    /* Alignment */
    if (prevalign.alignment != u.ualign.type)   /* Alignment changed */
    {
        prevalign.highlight_color = HIGHLIGHT_COLOR;
        prevalign.highlight_turns = 10; /* This is a major change! */
        prevalign.alignment = u.ualign.type;
        free(prevalign.txt);
        switch (u.ualign.type)
        {
            case A_LAWFUL:
            {
                prevalign.txt = curses_copy_of("Lawful");
                break;
            }
            case A_NEUTRAL:
            {
                prevalign.txt = curses_copy_of("Neutral");
                break;
            }
            case A_CHAOTIC:
            {
                prevalign.txt = curses_copy_of("Chaotic");
                break;
            }
        }
    }

    if (prevalign.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevalign.label);
        sx += strlen(prevalign.label);
    }
    
    if (prevalign.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevalign.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevalign.txt);
        curses_toggle_color_attr(win, prevalign.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevalign.txt);
    }
    
    /* Line 2 */
    
    sx = sx_start;
    sy++;
    
    /* Dungeon Level */
    if (depth(&u.uz) != prevdepth.value)    /* Dungeon level changed */
    {
        prevdepth.highlight_color = HIGHLIGHT_COLOR;
        prevdepth.highlight_turns = 5;
        prevdepth.value = depth(&u.uz);
        free(prevdepth.txt);
        if (In_endgame(&u.uz))
        {
            strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game"));
        }
        else
        {
            sprintf(buf, "%d", depth(&u.uz));
        }
        prevdepth.txt = curses_copy_of(buf);
    }
    
    if (prevdepth.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevdepth.label);
        sx += strlen(prevdepth.label);
    }
    
    if (prevdepth.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevdepth.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevdepth.txt);
        curses_toggle_color_attr(win, prevdepth.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevdepth.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevdepth.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }
    
    /* Gold */
#ifndef GOLDOBJ
    if (prevau.value != u.ugold)    /* Gold changed */
    {
        if (u.ugold > prevau.value)
        {
#else
    if (prevau.value != money_cnt(invent))  /* Gold changed */
    {
        if (money_cnt(invent) > prevau.value)
        {
#endif
            prevau.highlight_color = HI_GOLD;
        }
        else
        {
            prevau.highlight_color = STAT_DOWN_COLOR;
        }
#ifndef GOLDOBJ
        prevau.value = u.ugold;
        sprintf(buf,"%ld", u.ugold);
#else
        prevau.value = money_cnt(invent);
        sprintf(buf,"%ld", money_cnt(invent));
#endif
        free(prevau.txt);
        prevau.txt = curses_copy_of(buf);
        prevau.highlight_turns = 5;
    }
    
    if (prevau.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevau.label);
        sx += strlen(prevau.label);
    }
    
    if (prevau.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevau.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevau.txt);
        curses_toggle_color_attr(win, prevau.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevau.txt);
    }

    if (horiz)
    {
        sx += strlen(prevau.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }
    
    /* Hit Points */
    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
    {
	    if (u.mh != prevhp.value)
	    {
	        if (u.mh > prevhp.value)
	        {
	            prevhp.highlight_color = STAT_UP_COLOR;
	        }
	        else
	        {
	            prevhp.highlight_color = STAT_DOWN_COLOR;
	        }
            prevhp.highlight_turns = 3;
            prevhp.value = u.mh;
            sprintf(buf, "%d", u.mh);
            free(prevhp.txt);
            prevhp.txt = curses_copy_of(buf);
	    }
	}
	else if (u.uhp != prevhp.value)  /* Not polymorphed */
	{
	    if (u.uhp > prevhp.value)
	    {
	        prevhp.highlight_color = STAT_UP_COLOR;
	    }
	    else
	    {
            prevhp.highlight_color = STAT_DOWN_COLOR;
	    }
        prevhp.value = u.uhp;
        sprintf(buf, "%d", u.uhp);
        free(prevhp.txt);
        prevhp.txt = curses_copy_of(buf);
        prevhp.highlight_turns = 3;
	}

    if (prevhp.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevhp.label);
        sx += strlen(prevhp.label);
    }

    if (prevhp.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevhp.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevhp.txt);
        curses_toggle_color_attr(win, prevhp.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevhp.txt);
    }
    
    sx += strlen(prevhp.txt);

    /* Max Hit Points */
    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
    {
	    if (u.mhmax != prevmhp.value)
	    {
	        if (u.mhmax > prevmhp.value)
	        {
	            prevmhp.highlight_color = STAT_UP_COLOR;
	        }
	        else
	        {
	            prevmhp.highlight_color = STAT_DOWN_COLOR;
	        }
            prevmhp.value = u.mhmax;
            sprintf(buf, "%d", u.mhmax);
            free(prevmhp.txt);
            prevmhp.txt = curses_copy_of(buf);
            prevmhp.highlight_turns = 3;
	    }
	}
	else if (u.uhpmax != prevmhp.value)  /* Not polymorphed */
	{
	    if (u.uhpmax > prevmhp.value)
	    {
	        prevmhp.highlight_color = STAT_UP_COLOR;
	    }
	    else
	    {
            prevmhp.highlight_color = STAT_DOWN_COLOR;
	    }
        prevmhp.value = u.uhpmax;
        sprintf(buf, "%d", u.uhpmax);
        free(prevmhp.txt);
        prevmhp.txt = curses_copy_of(buf);
        prevmhp.highlight_turns = 3;
	}

    if (prevmhp.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevmhp.label);
        sx += strlen(prevmhp.label);
    }

    if (prevmhp.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevmhp.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevmhp.txt);
        curses_toggle_color_attr(win, prevmhp.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevmhp.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevmhp.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Power */
    if (u.uen != prevpow.value)
	{
	    if (u.uen > prevpow.value)
	    {
	        prevpow.highlight_color = STAT_UP_COLOR;
	    }
	    else
	    {
            prevpow.highlight_color = STAT_DOWN_COLOR;
	    }
        prevpow.value = u.uen;
        sprintf(buf, "%d", u.uen);
        free(prevpow.txt);
        prevpow.txt = curses_copy_of(buf);
        prevpow.highlight_turns = 3;
	}

    if (prevpow.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevpow.label);
        sx += strlen(prevpow.label);
    }

    if (prevpow.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevpow.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevpow.txt);
        curses_toggle_color_attr(win, prevpow.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevpow.txt);
    }
    
    sx += strlen(prevpow.txt);

    /* Max Power */
    if (u.uenmax != prevmpow.value)
	{
	    if (u.uenmax > prevmpow.value)
	    {
	        prevmpow.highlight_color = STAT_UP_COLOR;
	    }
	    else
	    {
            prevmpow.highlight_color = STAT_DOWN_COLOR;
	    }
        prevmpow.value = u.uenmax;
        sprintf(buf, "%d", u.uenmax);
        free(prevmpow.txt);
        prevmpow.txt = curses_copy_of(buf);
        prevmpow.highlight_turns = 3;
	}

    if (prevmpow.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevmpow.label);
        sx += strlen(prevmpow.label);
    }

    if (prevmpow.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevmpow.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevmpow.txt);
        curses_toggle_color_attr(win, prevmpow.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevmpow.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevmpow.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }


    /* Armor Class */
    if (u.uac != prevac.value)
	{
	    if (u.uac > prevac.value)   /* Lower is better for AC */
	    {
	        prevac.highlight_color = STAT_DOWN_COLOR;
	    }
	    else
	    {
            prevac.highlight_color = STAT_UP_COLOR;
	    }
        prevac.value = u.uac;
        sprintf(buf, "%d", u.uac);
        free(prevac.txt);
        prevac.txt = curses_copy_of(buf);
        prevac.highlight_turns = 5;
	}

    if (prevac.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevac.label);
        sx += strlen(prevac.label);
    }

    if (prevac.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevac.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevac.txt);
        curses_toggle_color_attr(win, prevac.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevac.txt);
    }
    
    if (horiz)
    {
        sx += strlen(prevac.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Experience */
#ifdef EXP_ON_BOTL
    if (prevexp.display != flags.showexp)   /* Setting has changed */
    {
        prevexp.display = flags.showexp;
        free(prevlevel.label);
        if (prevexp.display)
        {
            prevlevel.label = curses_copy_of("/");
        }
        else
        {
            prevlevel.label = curses_copy_of("Lvl:");
        }
    }

    if (prevexp.display && !u.mtimedone)
    {
        if (u.uexp != prevexp.value)
	    {
	        if (u.uexp > prevexp.value)
	        {
	            prevexp.highlight_color = STAT_UP_COLOR;
	        }
	        else
	        {
                prevexp.highlight_color = STAT_DOWN_COLOR;
	        }
            sprintf(buf, "%d", u.uexp);
            free(prevexp.txt);
            prevexp.txt = curses_copy_of(buf);
            prevexp.highlight_turns = 3;
	    }

        if (prevexp.label != NULL)
        {
            mvwaddstr(win, sy, sx, prevexp.label);
            sx += strlen(prevexp.label);
        }

        if (prevexp.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevexp.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevexp.txt);
            curses_toggle_color_attr(win, prevexp.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevexp.txt);
        }

        sx += strlen(prevexp.txt);
    }
    
    prevexp.value = u.uexp; /* Track it even when it's not displayed */
#endif  /* EXP_ON_BOTL */

    /* Level */
    if (u.mtimedone)    /* Currently polymorphed - show monster HD */
    {
        if (strncmp(prevlevel.label, "HD:", 3) != 0)
        {
            free(prevlevel.label);
            prevlevel.label = curses_copy_of("HD:");
        }
        if (mons[u.umonnum].mlevel != prevlevel.value)
        {
            if (mons[u.umonnum].mlevel > prevlevel.value)
            {
                prevlevel.highlight_color = STAT_UP_COLOR;
            }
            else
            {
                prevlevel.highlight_color = STAT_DOWN_COLOR;
            }
            prevlevel.highlight_turns = 5;
        }
        prevlevel.value = mons[u.umonnum].mlevel;
        sprintf(buf, "%d", mons[u.umonnum].mlevel);
        free(prevlevel.txt);
        prevlevel.txt = curses_copy_of(buf);
    }
    else    /* Not polymorphed */
    {
        if (strncmp(prevlevel.label, "HD:", 3) == 0)
        {
            free(prevlevel.label);
            if (prevexp.display)
            {
                prevlevel.label = curses_copy_of("/");
            }
            else
            {
                prevlevel.label = curses_copy_of("Lvl:");
            }
        }
        if (u.ulevel > prevlevel.value)
        {
            prevlevel.highlight_color = STAT_UP_COLOR;
            prevlevel.highlight_turns = 5;
        }
        else if (u.ulevel < prevlevel.value)
        {
            prevlevel.highlight_color = STAT_DOWN_COLOR;
            prevlevel.highlight_turns = 5;
        }
        prevlevel.value = u.ulevel;
        sprintf(buf, "%d", u.ulevel);
        free(prevlevel.txt);
        prevlevel.txt = curses_copy_of(buf);
    }

    if (prevlevel.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevlevel.label);
        sx += strlen(prevlevel.label);
    }

    if (prevlevel.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevlevel.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevlevel.txt);
        curses_toggle_color_attr(win, prevlevel.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevlevel.txt);
    }

    if (horiz)
    {
        sx += strlen(prevlevel.txt) + 1;
    }
    else
    {
        sx = sx_start;
        sy++;
    }

    /* Time */
    if (prevtime.display != flags.time)   /* Setting has changed */
    {
        prevtime.display = flags.time;
    }
    if (prevtime.display)
    {
        if (moves != prevtime.value)
	    {
            sprintf(buf, "%ld", moves);
            free(prevtime.txt);
            prevtime.txt = curses_copy_of(buf);
	    }

        if (prevtime.label != NULL)
        {
            mvwaddstr(win, sy, sx, prevtime.label);
            sx += strlen(prevtime.label);
        }

        mvwaddstr(win, sy, sx, prevtime.txt);

        if (horiz)
        {
            sx += strlen(prevtime.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }
    
    /* Score */
#ifdef SCORE_ON_BOTL
    if (prevscore.display != flags.showscore)   /* Setting has changed */
    {
        prevscore.display = flags.showscore;
    }
    if (prevscore.display)
    {
        if (botl_score() != prevscore.value)
	    {
	        if (botl_score() > prevscore.value)
	        {
	            prevscore.highlight_color = STAT_UP_COLOR;
	        }
	        else    /* Not sure this is possible */
	        {
                prevscore.highlight_color = STAT_DOWN_COLOR;
	        }
            sprintf(buf, "%ld", botl_score());
            free(prevscore.txt);
            prevscore.txt = curses_copy_of(buf);
            prevscore.highlight_turns = 3;
	    }

        if (prevscore.label != NULL)
        {
            mvwaddstr(win, sy, sx, prevscore.label);
            sx += strlen(prevscore.label);
        }

        if (prevscore.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevscore.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevscore.txt);
            curses_toggle_color_attr(win, prevscore.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevscore.txt);
        }

        if (horiz)
        {
            sx += strlen(prevscore.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }
    
    prevscore.value = botl_score(); /* Track it even when it's not displayed */
#endif  /* SCORE_ON_BOTL */

    /* Hunger */
    if (u.uhs != prevhunger.value)
	{
	    if ((u.uhs > prevhunger.value) || (u.uhs > 3))
	    {
	        prevhunger.highlight_color = STAT_DOWN_COLOR;
	    }
	    else
	    {
            prevhunger.highlight_color = STAT_UP_COLOR;
	    }
        prevhunger.value = u.uhs;
        for (count = 0; count < strlen(hu_stat[u.uhs]); count++)
        {
            if ((hu_stat[u.uhs][count]) == ' ')
            {
                break;
            }
            buf[count] = hu_stat[u.uhs][count];
        }

        buf[count] = '\0';
        free(prevhunger.txt);
        prevhunger.txt = curses_copy_of(buf);
        prevhunger.highlight_turns = 5;
	}

    if (prevhunger.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevhunger.label);
        sx += strlen(prevhunger.label);
    }

    if (prevhunger.highlight_turns > 0)
    {
        curses_toggle_color_attr(win, prevhunger.highlight_color, NONE, ON);
        mvwaddstr(win, sy, sx, prevhunger.txt);
        curses_toggle_color_attr(win, prevhunger.highlight_color, NONE, OFF);
    }
    else
    {
        mvwaddstr(win, sy, sx, prevhunger.txt);
    }
    
    if (strlen(prevhunger.txt) > 0)
    {
        if (horiz)
        {
            sx += strlen(prevhunger.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Confusion */
    if (Confusion != prevconf.value)
	{
	    prevconf.highlight_color = STAT_DOWN_COLOR;
        if (prevconf.txt != NULL)
        {
            free(prevconf.txt);
        }
        if (Confusion)
        {
            prevconf.txt = curses_copy_of("Conf");
        }
        else
        {
            prevconf.txt = NULL;
        }
        if (prevconf.value == 0)
        {
            prevconf.highlight_turns = 5;
	    }
        prevconf.value = Confusion;
	}

    if (prevconf.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevconf.label);
        sx += strlen(prevconf.label);
    }

    if (prevconf.txt != NULL)
    {
        if (prevconf.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevconf.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevconf.txt);
            curses_toggle_color_attr(win, prevconf.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevconf.txt);
        }
    }

    if (prevconf.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevconf.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Blindness */
    if (Blind != prevblind.value)
	{
	    prevblind.highlight_color = STAT_DOWN_COLOR;
        if (prevblind.txt != NULL)
        {
            free(prevblind.txt);
        }
        if (Blind)
        {
            prevblind.txt = curses_copy_of("Blind");
        }
        else
        {
            prevblind.txt = NULL;
        }
        if (prevblind.value == 0)
        {
            prevblind.highlight_turns = 5;
	    }
        prevblind.value = Blind;
	}

    if (prevblind.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevblind.label);
        sx += strlen(prevblind.label);
    }

    if (prevblind.txt != NULL)
    {
        if (prevblind.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevblind.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevblind.txt);
            curses_toggle_color_attr(win, prevblind.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevblind.txt);
        }
    }

    if (prevblind.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevblind.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Stun */
    if (Stunned != prevstun.value)
	{
	    prevstun.highlight_color = STAT_DOWN_COLOR;
        if (prevstun.txt != NULL)
        {
            free(prevstun.txt);
        }
        if (Stunned)
        {
            prevstun.txt = curses_copy_of("Stun");
        }
        else
        {
            prevstun.txt = NULL;
        }
        if (prevstun.value == 0)
        {
            prevstun.highlight_turns = 5;
	    }
        prevstun.value = Stunned;
	}

    if (prevstun.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevstun.label);
        sx += strlen(prevstun.label);
    }

    if (prevstun.txt != NULL)
    {
        if (prevstun.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevstun.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevstun.txt);
            curses_toggle_color_attr(win, prevstun.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevstun.txt);
        }
    }

    if (prevstun.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevstun.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Hallucination */
    if (Hallucination != prevhallu.value)
	{
	    prevhallu.highlight_color = STAT_DOWN_COLOR;
        if (prevhallu.txt != NULL)
        {
            free(prevhallu.txt);
        }
        if (Hallucination)
        {
            prevhallu.txt = curses_copy_of("Hallu");
        }
        else
        {
            prevhallu.txt = NULL;
        }
        if (prevhallu.value == 0)
        {
            prevhallu.highlight_turns = 5;
	    }
        prevhallu.value = Hallucination;
	}

    if (prevhallu.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevhallu.label);
        sx += strlen(prevhallu.label);
    }

    if (prevhallu.txt != NULL)
    {
        if (prevhallu.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevhallu.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevhallu.txt);
            curses_toggle_color_attr(win, prevhallu.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevhallu.txt);
        }
    }

    if (prevhallu.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevhallu.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Sick */
    if (Sick != prevsick.value)
	{
	    prevsick.highlight_color = STAT_DOWN_COLOR;
        if (prevsick.txt != NULL)
        {
            free(prevsick.txt);
        }
        if (Sick)
        {
            if (u.usick_type & SICK_VOMITABLE)
            {
                prevsick.txt = curses_copy_of("FoodPois");
            }
            else      
            {
                prevsick.txt = curses_copy_of("Ill");
            }
        }
        else
        {
            prevsick.txt = NULL;
        }
        if (prevsick.value == 0)
        {
            prevsick.highlight_turns = 5;
	    }
        prevsick.value = Sick;
	}

    if (prevsick.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevsick.label);
        sx += strlen(prevsick.label);
    }

    if (prevsick.txt != NULL)
    {
        if (prevsick.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevsick.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevsick.txt);
            curses_toggle_color_attr(win, prevsick.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevsick.txt);
        }
    }

    if (prevsick.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevsick.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Slime */
    if (Slimed != prevslime.value)
	{
	    prevslime.highlight_color = STAT_DOWN_COLOR;
        if (prevslime.txt != NULL)
        {
            free(prevslime.txt);
        }
        if (Slimed)
        {
            prevslime.txt = curses_copy_of("Slime");
        }
        else
        {
            prevslime.txt = NULL;
        }
        if (prevslime.value == 0)
        {
            prevslime.highlight_turns = 5;
	    }
        prevslime.value = Slimed;
	}

    if (prevslime.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevslime.label);
        sx += strlen(prevslime.label);
    }

    if (prevslime.txt != NULL)
    {
        if (prevslime.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevslime.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevslime.txt);
            curses_toggle_color_attr(win, prevslime.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevslime.txt);
        }
    }

    if (prevslime.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevslime.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    /* Encumberance */
    enc = near_capacity();
    
    if (enc != prevencumb.value)
	{
	    if (enc < prevencumb.value)
	    {
	        prevencumb.highlight_color = STAT_UP_COLOR;
	    }
	    else
	    {
	        prevencumb.highlight_color = STAT_DOWN_COLOR;
        }
        if (prevencumb.txt != NULL)
        {
            free(prevencumb.txt);
        }
        if (enc > UNENCUMBERED)
        {
            sprintf(buf, "%s", enc_stat[enc]);
            prevencumb.txt = curses_copy_of(buf);
            prevencumb.highlight_turns = 5;
        }
        else
        {
            prevencumb.txt = NULL;
        }
        prevencumb.value = enc;
	}

    if (prevencumb.label != NULL)
    {
        mvwaddstr(win, sy, sx, prevencumb.label);
        sx += strlen(prevencumb.label);
    }

    if (prevencumb.txt != NULL)
    {
        if (prevencumb.highlight_turns > 0)
        {
            curses_toggle_color_attr(win, prevencumb.highlight_color, NONE, ON);
            mvwaddstr(win, sy, sx, prevencumb.txt);
            curses_toggle_color_attr(win, prevencumb.highlight_color, NONE, OFF);
        }
        else
        {
            mvwaddstr(win, sy, sx, prevencumb.txt);
        }
    }

    if (prevencumb.txt != NULL)
    {
        if (horiz)
        {
            sx += strlen(prevencumb.txt) + 1;
        }
        else
        {
            sx = sx_start;
            sy++;
        }
    }

    wrefresh(win);
}


/* Decrement the highlight_turns for all stats.  Call curses_update_stats
if needed to unhighlight a stat */

void curses_decrement_highlight()
{
    boolean unhighlight = FALSE;
    
    if (prevname.highlight_turns > 0)
    {
        prevname.highlight_turns--;
        if (prevname.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevdepth.highlight_turns > 0)
    {
        prevdepth.highlight_turns--;
        if (prevdepth.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevstr.highlight_turns > 0)
    {
        prevstr.highlight_turns--;
        if (prevstr.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevint.highlight_turns > 0)
    {
        prevint.highlight_turns--;
        if (prevint.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevwis.highlight_turns > 0)
    {
        prevwis.highlight_turns--;
        if (prevwis.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevdex.highlight_turns > 0)
    {
        prevdex.highlight_turns--;
        if (prevdex.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevcon.highlight_turns > 0)
    {
        prevcon.highlight_turns--;
        if (prevcon.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevcha.highlight_turns > 0)
    {
        prevcha.highlight_turns--;
        if (prevcha.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevalign.highlight_turns > 0)
    {
        prevalign.highlight_turns--;
        if (prevalign.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevau.highlight_turns > 0)
    {
        prevau.highlight_turns--;
        if (prevau.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevhp.highlight_turns > 0)
    {
        prevhp.highlight_turns--;
        if (prevhp.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevmhp.highlight_turns > 0)
    {
        prevmhp.highlight_turns--;
        if (prevmhp.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevlevel.highlight_turns > 0)
    {
        prevlevel.highlight_turns--;
        if (prevlevel.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevpow.highlight_turns > 0)
    {
        prevpow.highlight_turns--;
        if (prevpow.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevmpow.highlight_turns > 0)
    {
        prevmpow.highlight_turns--;
        if (prevmpow.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevac.highlight_turns > 0)
    {
        prevac.highlight_turns--;
        if (prevac.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
#ifdef EXP_ON_BOTL
    if (prevexp.highlight_turns > 0)
    {
        prevexp.highlight_turns--;
        if (prevexp.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
#endif
    if (prevtime.highlight_turns > 0)
    {
        prevtime.highlight_turns--;
        if (prevtime.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
#ifdef SCORE_ON_BOTL
    if (prevscore.highlight_turns > 0)
    {
        prevscore.highlight_turns--;
        if (prevscore.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
#endif
    if (prevhunger.highlight_turns > 0)
    {
        prevhunger.highlight_turns--;
        if (prevhunger.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevconf.highlight_turns > 0)
    {
        prevconf.highlight_turns--;
        if (prevconf.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevblind.highlight_turns > 0)
    {
        prevblind.highlight_turns--;
        if (prevblind.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevstun.highlight_turns > 0)
    {
        prevstun.highlight_turns--;
        if (prevstun.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevhallu.highlight_turns > 0)
    {
        prevhallu.highlight_turns--;
        if (prevhallu.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevsick.highlight_turns > 0)
    {
        prevsick.highlight_turns--;
        if (prevsick.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevslime.highlight_turns > 0)
    {
        prevslime.highlight_turns--;
        if (prevslime.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    if (prevencumb.highlight_turns > 0)
    {
        prevencumb.highlight_turns--;
        if (prevencumb.highlight_turns == 0)
        {
            unhighlight = TRUE;
        }
    }
    
    if (unhighlight)
    {
        curses_update_stats();
    }
}


/* Initialize the stats with beginning values. */

static void init_stats()
{
    char buf[BUFSZ];
    int count;

    /* Player name and title */
    strcpy(buf, plname);
    if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
    strcat(buf, " the ");
    if (u.mtimedone) {
        char mname[BUFSZ];
        int k = 0;

        strcpy(mname, mons[u.umonnum].mname);
        while(mname[k] != 0) {
            if ((k == 0 || (k > 0 && mname[k-1] == ' '))
             && 'a' <= mname[k] && mname[k] <= 'z')
            {
                mname[k] += 'A' - 'a';
            }
            k++;
        }
        strcat(buf, mname);
    } else {
        strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
    }

    prevname.txt = curses_copy_of(buf);
    prevname.display = TRUE;
    prevname.highlight_turns = 0;
    prevname.label = NULL;
    
    /* Strength */
    if (ACURR(A_STR) > 118)
    {
        sprintf(buf, "%d", ACURR(A_STR) - 100);
    }
    else if (ACURR(A_STR)==118)
    {
        sprintf(buf, "18/**");
    }
    else if(ACURR(A_STR) > 18)
    {
        sprintf(buf, "18/%02d", ACURR(A_STR) - 18);
    }
    else
    {
        sprintf(buf, "%d", ACURR(A_STR));
    }

    prevstr.value = ACURR(A_STR);
    prevstr.txt = curses_copy_of(buf);
    prevstr.display = TRUE;
    prevstr.highlight_turns = 0;
    prevstr.label = curses_copy_of("Str:");

    /* Intelligence */
    sprintf(buf, "%d", ACURR(A_INT));
    prevint.value = ACURR(A_INT);
    prevint.txt = curses_copy_of(buf);
    prevint.display = TRUE;
    prevint.highlight_turns = 0;
    prevint.label = curses_copy_of("Int:");

    /* Wisdom */
    sprintf(buf, "%d", ACURR(A_WIS));
    prevwis.value = ACURR(A_WIS);
    prevwis.txt = curses_copy_of(buf);
    prevwis.display = TRUE;
    prevwis.highlight_turns = 0;
    prevwis.label = curses_copy_of("Wis:");

    /* Dexterity */
    sprintf(buf, "%d", ACURR(A_DEX));
    prevdex.value = ACURR(A_DEX);
    prevdex.txt = curses_copy_of(buf);
    prevdex.display = TRUE;
    prevdex.highlight_turns = 0;
    prevdex.label = curses_copy_of("Dex:");

    /* Constitution */
    sprintf(buf, "%d", ACURR(A_CON));
    prevcon.value = ACURR(A_CON);
    prevcon.txt = curses_copy_of(buf);
    prevcon.display = TRUE;
    prevcon.highlight_turns = 0;
    prevcon.label = curses_copy_of("Con:");

    /* Charisma */
    sprintf(buf, "%d", ACURR(A_CHA));
    prevcha.value = ACURR(A_CHA);
    prevcha.txt = curses_copy_of(buf);
    prevcha.display = TRUE;
    prevcha.highlight_turns = 0;
    prevcha.label = curses_copy_of("Cha:");

    /* Alignment */
    switch (u.ualign.type)
    {
        case A_LAWFUL:
        {
            prevalign.txt = curses_copy_of("Lawful");
            break;
        }
        case A_NEUTRAL:
        {
            prevalign.txt = curses_copy_of("Neutral");
            break;
        }
        case A_CHAOTIC:
        {
            prevalign.txt = curses_copy_of("Chaotic");
            break;
        }
    }
    
    prevalign.alignment = u.ualign.type;
    prevalign.display = TRUE;
    prevalign.highlight_turns = 0;
    prevalign.label = NULL;
    
    /* Dungeon level */
    if (In_endgame(&u.uz))
    {
        strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game"));
    }
    else
    {
        sprintf(buf, "%d", depth(&u.uz));
    }

    prevdepth.value = depth(&u.uz);
    prevdepth.txt = curses_copy_of(buf);
    prevdepth.display = TRUE;
    prevdepth.highlight_turns = 0;
    prevdepth.label = curses_copy_of("Dlvl:");
    
    /* Gold */
#ifndef GOLDOBJ
    sprintf(buf,"%ld", u.ugold);
    prevau.value = u.ugold;
#else
    sprintf(buf,"%ld", money_cnt(invent));
    prevau.value = money_cnt(invent);
#endif
    prevau.txt = curses_copy_of(buf);
    prevau.display = TRUE;
    prevau.highlight_turns = 0;
    sprintf(buf, "%c:", GOLD_SYM);
    prevau.label = curses_copy_of(buf);

    /* Hit Points */
    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
    {
        prevhp.value = u.mh;
        sprintf(buf, "%d", u.mh);
        prevhp.txt = curses_copy_of(buf);
	}
	else if (u.uhp != prevhp.value)  /* Not polymorphed */
	{
	    prevhp.value = u.uhp;
        sprintf(buf, "%d", u.uhp);
        prevhp.txt = curses_copy_of(buf);
	}
	prevhp.display = TRUE;
	prevhp.highlight_turns = 0;
    prevhp.label = curses_copy_of("HP:");

    /* Max Hit Points */
    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
    {
        prevmhp.value = u.mhmax;
        sprintf(buf, "%d", u.mhmax);
        prevmhp.txt = curses_copy_of(buf);
	}
	else    /* Not polymorphed */
	{
	    prevmhp.value = u.uhpmax;
        sprintf(buf, "%d", u.uhpmax);
        prevmhp.txt = curses_copy_of(buf);
	}
	prevmhp.display = TRUE;
	prevmhp.highlight_turns = 0;
    prevmhp.label = curses_copy_of("/");

    /* Power */
    prevpow.value = u.uen;
    sprintf(buf, "%d", u.uen);
    prevpow.txt = curses_copy_of(buf);
	prevpow.display = TRUE;
	prevpow.highlight_turns = 0;
    prevpow.label = curses_copy_of("Pw:");

    /* Max Power */
    prevmpow.value = u.uenmax;
    sprintf(buf, "%d", u.uenmax);
    prevmpow.txt = curses_copy_of(buf);
	prevmpow.display = TRUE;
	prevmpow.highlight_turns = 0;
    prevmpow.label = curses_copy_of("/");

    /* Armor Class */
    prevac.value = u.uac;
    sprintf(buf, "%d", u.uac);
    prevac.txt = curses_copy_of(buf);
	prevac.display = TRUE;
	prevac.highlight_turns = 0;
    prevac.label = curses_copy_of("AC:");

    /* Experience */
#ifdef EXP_ON_BOTL
    prevexp.value = u.uexp;
    sprintf(buf, "%ld", u.uexp);
    prevexp.txt = curses_copy_of(buf);
	prevexp.display = flags.showexp;
	prevexp.highlight_turns = 0;
    prevexp.label = curses_copy_of("Xp:");
#endif

    /* Level */
    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
    {
        prevlevel.value = mons[u.umonnum].mlevel;
        sprintf(buf, "%d", mons[u.umonnum].mlevel);
        prevlevel.txt = curses_copy_of(buf);
        prevlevel.label = curses_copy_of("HD:");
	}
	else if (u.ulevel != prevlevel.value)  /* Not polymorphed */
	{
	    prevlevel.value = u.ulevel;
        sprintf(buf, "%d", u.ulevel);
        prevlevel.txt = curses_copy_of(buf);
        if (prevexp.display)
        {
            prevlevel.label = curses_copy_of("/");
        }
        else
        {    
            prevlevel.label = curses_copy_of("Lvl:");
        }
	}
	prevlevel.display = TRUE;
	prevlevel.highlight_turns = 0;

    /* Time */
    prevtime.value = moves;
    sprintf(buf, "%ld", moves);
    prevtime.txt = curses_copy_of(buf);
	prevtime.display = flags.time;
	prevtime.highlight_turns = 0;
    prevtime.label = curses_copy_of("T:");

    /* Score */
#ifdef SCORE_ON_BOTL
    prevscore.value = botl_score();
    sprintf(buf, "%ld", botl_score());
    prevscore.txt = curses_copy_of(buf);
	prevscore.display = flags.showscore;
	prevscore.highlight_turns = 0;
    prevscore.label = curses_copy_of("S:");
#endif

    /* Hunger */
    prevhunger.value = u.uhs;
    for (count = 0; count < strlen(hu_stat[u.uhs]); count++)
    {
        if ((hu_stat[u.uhs][count]) == ' ')
        {
            break;
        }
        buf[count] = hu_stat[u.uhs][count];
    }

    buf[count] = '\0';
    prevhunger.txt = curses_copy_of(buf);
    prevhunger.display = TRUE;
    prevhunger.highlight_turns = 0;
    prevhunger.label = NULL;

    /* Confusion */
    prevconf.value = Confusion;
    if (Confusion)
    {
        prevconf.txt = curses_copy_of("Conf");
    }
    else
    {
        prevconf.txt = NULL;
    }
    prevconf.display = TRUE;
    prevconf.highlight_turns = 0;
    prevconf.label = NULL;

    /* Blindness */
    prevblind.value = Blind;
    if (Blind)
    {
        prevblind.txt = curses_copy_of("Blind");
    }
    else
    {
        prevblind.txt = NULL;
    }
    prevblind.display = TRUE;
    prevblind.highlight_turns = 0;
    prevblind.label = NULL;

    /* Stun */
    prevstun.value = Stunned;
    if (Stunned)
    {
        prevstun.txt = curses_copy_of("Stun");
    }
    else
    {
        prevstun.txt = NULL;
    }
    prevstun.display = TRUE;
    prevstun.highlight_turns = 0;
    prevstun.label = NULL;

    /* Hallucination */
    prevhallu.value = Hallucination;
    if (Hallucination)
    {
        prevhallu.txt = curses_copy_of("Hallu");
    }
    else
    {
        prevhallu.txt = NULL;
    }
    prevhallu.display = TRUE;
    prevhallu.highlight_turns = 0;
    prevhallu.label = NULL;

    /* Sick */
    prevsick.value = Sick;
    if (Sick)
    {
        if (u.usick_type & SICK_VOMITABLE)
        {
            prevsick.txt = curses_copy_of("Sick");
        }
        else     
        {
            prevsick.txt = curses_copy_of("Ill");
        }
    }
    else
    {
        prevsick.txt = NULL;
    }
    prevsick.display = TRUE;
    prevsick.highlight_turns = 0;
    prevsick.label = NULL;

    /* Slimed */
    prevslime.value = Slimed;
    if (Slimed)
    {
        prevslime.txt = curses_copy_of("Slime");
    }
    else
    {
        prevslime.txt = NULL;
    }
    prevslime.display = TRUE;
    prevslime.highlight_turns = 0;
    prevslime.label = NULL;

    /* Encumberance */
    prevencumb.value = near_capacity();
    if (prevencumb.value > UNENCUMBERED)
    {
        sprintf(buf, "%s", enc_stat[prevencumb.value]);
        prevencumb.txt = curses_copy_of(buf);
    }
    else
    {
        prevencumb.txt = NULL;
    }
    prevencumb.display = TRUE;
    prevencumb.highlight_turns = 0;
    prevencumb.label = NULL;
}
예제 #14
0
/* #sit command */
int
dosit()
{
    static const char sit_message[] = "sit on the %s.";
    register struct trap *trap = t_at(u.ux, u.uy);
    register int typ = levl[u.ux][u.uy].typ;

    if (u.usteed) {
        You("are already sitting on %s.", mon_nam(u.usteed));
        return 0;
    }
    if (u.uundetected && is_hider(youmonst.data) && u.umonnum != PM_TRAPPER)
        u.uundetected = 0; /* no longer on the ceiling */

    if (!can_reach_floor(FALSE)) {
        if (u.uswallow)
            There("are no seats in here!");
        else if (Levitation)
            You("tumble in place.");
        else
            You("are sitting on air.");
        return 0;
    } else if (u.ustuck && !sticks(youmonst.data)) {
        /* holding monster is next to hero rather than beneath, but
           hero is in no condition to actually sit at has/her own spot */
        if (humanoid(u.ustuck->data))
            pline("%s won't offer %s lap.", Monnam(u.ustuck), mhis(u.ustuck));
        else
            pline("%s has no lap.", Monnam(u.ustuck));
        return 0;
    } else if (is_pool(u.ux, u.uy) && !Underwater) { /* water walking */
        goto in_water;
    }

    if (OBJ_AT(u.ux, u.uy)
        /* ensure we're not standing on the precipice */
        && !uteetering_at_seen_pit(trap)) {
        register struct obj *obj;

        obj = level.objects[u.ux][u.uy];
        if (youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) {
            You("coil up around your %shoard.",
                (obj->quan + money_cnt(invent) < u.ulevel * 1000) ? "meager "
                                                                  : "");
        } else {
            You("sit on %s.", the(xname(obj)));
            if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH))
                pline("It's not very comfortable...");
        }
    } else if (trap != 0 || (u.utrap && (u.utraptype >= TT_LAVA))) {
        if (u.utrap) {
            exercise(A_WIS, FALSE); /* you're getting stuck longer */
            if (u.utraptype == TT_BEARTRAP) {
                You_cant("sit down with your %s in the bear trap.",
                         body_part(FOOT));
                u.utrap++;
            } else if (u.utraptype == TT_PIT) {
                if (trap && trap->ttyp == SPIKED_PIT) {
                    You("sit down on a spike.  Ouch!");
                    losehp(Half_physical_damage ? rn2(2) : 1,
                           "sitting on an iron spike", KILLED_BY);
                    exercise(A_STR, FALSE);
                } else
                    You("sit down in the pit.");
                u.utrap += rn2(5);
            } else if (u.utraptype == TT_WEB) {
                You("sit in the spider web and get entangled further!");
                u.utrap += rn1(10, 5);
            } else if (u.utraptype == TT_LAVA) {
                /* Must have fire resistance or they'd be dead already */
                You("sit in the lava!");
                if (Slimed)
                    burn_away_slime();
                u.utrap += rnd(4);
                losehp(d(2, 10), "sitting in lava",
                       KILLED_BY); /* lava damage */
            } else if (u.utraptype == TT_INFLOOR
                       || u.utraptype == TT_BURIEDBALL) {
                You_cant("maneuver to sit!");
                u.utrap++;
            }
        } else {
            You("sit down.");
            dotrap(trap, 0);
        }
    } else if (Underwater || Is_waterlevel(&u.uz)) {
        if (Is_waterlevel(&u.uz))
            There("are no cushions floating nearby.");
        else
            You("sit down on the muddy bottom.");
    } else if (is_pool(u.ux, u.uy)) {
    in_water:
        You("sit in the water.");
        if (!rn2(10) && uarm)
            (void) water_damage(uarm, "armor", TRUE);
        if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
            (void) water_damage(uarm, "armor", TRUE);
    } else if (IS_SINK(typ)) {
        You(sit_message, defsyms[S_sink].explanation);
        Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside");
    } else if (IS_ALTAR(typ)) {
        You(sit_message, defsyms[S_altar].explanation);
        altar_wrath(u.ux, u.uy);
    } else if (IS_GRAVE(typ)) {
        You(sit_message, defsyms[S_grave].explanation);
    } else if (typ == STAIRS) {
        You(sit_message, "stairs");
    } else if (typ == LADDER) {
        You(sit_message, "ladder");
    } else if (is_lava(u.ux, u.uy)) {
        /* must be WWalking */
        You(sit_message, "lava");
        burn_away_slime();
        if (likes_lava(youmonst.data)) {
            pline_The("lava feels warm.");
            return 1;
        }
        pline_The("lava burns you!");
        losehp(d((Fire_resistance ? 2 : 10), 10), /* lava damage */
               "sitting on lava", KILLED_BY);
    } else if (is_ice(u.ux, u.uy)) {
        You(sit_message, defsyms[S_ice].explanation);
        if (!Cold_resistance)
            pline_The("ice feels cold.");
    } else if (typ == DRAWBRIDGE_DOWN) {
        You(sit_message, "drawbridge");
    } else if (IS_THRONE(typ)) {
        You(sit_message, defsyms[S_throne].explanation);
        if (rnd(6) > 4) {
            switch (rnd(13)) {
            case 1:
                (void) adjattrib(rn2(A_MAX), -rn1(4, 3), FALSE);
                losehp(rnd(10), "cursed throne", KILLED_BY_AN);
                break;
            case 2:
                (void) adjattrib(rn2(A_MAX), 1, FALSE);
                break;
            case 3:
                pline("A%s electric shock shoots through your body!",
                      (Shock_resistance) ? "n" : " massive");
                losehp(Shock_resistance ? rnd(6) : rnd(30), "electric chair",
                       KILLED_BY_AN);
                exercise(A_CON, FALSE);
                break;
            case 4:
                You_feel("much, much better!");
                if (Upolyd) {
                    if (u.mh >= (u.mhmax - 5))
                        u.mhmax += 4;
                    u.mh = u.mhmax;
                }
                if (u.uhp >= (u.uhpmax - 5))
                    u.uhpmax += 4;
                u.uhp = u.uhpmax;
                make_blinded(0L, TRUE);
                make_sick(0L, (char *) 0, FALSE, SICK_ALL);
                heal_legs();
                context.botl = 1;
                break;
            case 5:
                take_gold();
                break;
            case 6:
                if (u.uluck + rn2(5) < 0) {
                    You_feel("your luck is changing.");
                    change_luck(1);
                } else
                    makewish();
                break;
            case 7:
              {
                int cnt = rnd(10);

                /* Magical voice not affected by deafness */
                pline("A voice echoes:");
                verbalize("Thy audience hath been summoned, %s!",
                          flags.female ? "Dame" : "Sire");
                while (cnt--)
                    (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
                break;
              }
            case 8:
                /* Magical voice not affected by deafness */
                pline("A voice echoes:");
                verbalize("By thine Imperious order, %s...",
                          flags.female ? "Dame" : "Sire");
                do_genocide(5); /* REALLY|ONTHRONE, see do_genocide() */
                break;
            case 9:
                /* Magical voice not affected by deafness */
                pline("A voice echoes:");
                verbalize(
                 "A curse upon thee for sitting upon this most holy throne!");
                if (Luck > 0) {
                    make_blinded(Blinded + rn1(100, 250), TRUE);
                } else
                    rndcurse();
                break;
            case 10:
                if (Luck < 0 || (HSee_invisible & INTRINSIC)) {
                    if (level.flags.nommap) {
                        pline("A terrible drone fills your head!");
                        make_confused((HConfusion & TIMEOUT) + (long) rnd(30),
                                      FALSE);
                    } else {
                        pline("An image forms in your mind.");
                        do_mapping();
                    }
                } else {
                    Your("vision becomes clear.");
                    HSee_invisible |= FROMOUTSIDE;
                    newsym(u.ux, u.uy);
                }
                break;
            case 11:
                if (Luck < 0) {
                    You_feel("threatened.");
                    aggravate();
                } else {
                    You_feel("a wrenching sensation.");
                    tele(); /* teleport him */
                }
                break;
            case 12:
                You("are granted an insight!");
                if (invent) {
                    /* rn2(5) agrees w/seffects() */
                    identify_pack(rn2(5), FALSE);
                }
                break;
            case 13:
                Your("mind turns into a pretzel!");
                make_confused((HConfusion & TIMEOUT) + (long) rn1(7, 16),
                              FALSE);
                break;
            default:
                impossible("throne effect");
                break;
            }
        } else {
            if (is_prince(youmonst.data))
                You_feel("very comfortable here.");
            else
                You_feel("somehow out of place...");
        }

        if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
            /* may have teleported */
            levl[u.ux][u.uy].typ = ROOM;
            pline_The("throne vanishes in a puff of logic.");
            newsym(u.ux, u.uy);
        }
    } else if (lays_eggs(youmonst.data)) {
        struct obj *uegg;

        if (!flags.female) {
            pline("%s can't lay eggs!",
                  Hallucination
                      ? "You may think you are a platypus, but a male still"
                      : "Males");
            return 0;
        } else if (u.uhunger < (int) objects[EGG].oc_nutrition) {
            You("don't have enough energy to lay an egg.");
            return 0;
        }

        uegg = mksobj(EGG, FALSE, FALSE);
        uegg->spe = 1;
        uegg->quan = 1L;
        uegg->owt = weight(uegg);
        /* this sets hatch timers if appropriate */
        set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE));
        uegg->known = uegg->dknown = 1;
        You("lay an egg.");
        dropy(uegg);
        stackobj(uegg);
        morehungry((int) objects[EGG].oc_nutrition);
    } else {
        pline("Having fun sitting on the %s?", surface(u.ux, u.uy));
    }
    return 1;
}
예제 #15
0
void statuswin::parse_statusline(std::string str)
{
	int hp, hpmax, nconds;
	long val;
  std::string txt;
	int cap = near_capacity();
	size_t pos;
	char buf[64];

	/* get player name + title */
	pos = str.find("St:", 0);
	if (pos != std::string::npos)
		tokenarray[0][0]->caption = str.substr(0, pos);

	/* strength needs special treatment */
	if (ACURR(A_STR) > 18) 
	{
		if (ACURR(A_STR) > STR18(100))
			sprintf(buf,"St:%2d", ACURR(A_STR)-100);
		else if (ACURR(A_STR) < STR18(100))
			sprintf(buf, "St:18/%02d", ACURR(A_STR)-18);
		else
			sprintf(buf,"St:18/**");
	}
	else
		sprintf(buf, "St:%-1d", ACURR(A_STR));
	tokenarray[0][1]->caption = buf;

	/* the other stats */
	sprintf(buf, "Dx:%-1d", ACURR(A_DEX));
	tokenarray[0][2]->caption = buf;
	
	sprintf(buf, "Co:%-1d", ACURR(A_CON));
	tokenarray[0][3]->caption = buf;
	
	sprintf(buf, "In:%-1d", ACURR(A_INT));
	tokenarray[1][1]->caption = buf;
	
	sprintf(buf, "Wi:%-1d", ACURR(A_WIS));
	tokenarray[1][2]->caption = buf;
	
	sprintf(buf, "Ch:%-1d", ACURR(A_CHA));
	tokenarray[1][3]->caption = buf;

	/* alignment */
	tokenarray[4][0]->visible = 1;
	tokenarray[4][0]->caption = (u.ualign.type == A_CHAOTIC) ? "Chaotic" :
			(u.ualign.type == A_NEUTRAL) ? "Neutral" : "Lawful";

	/* score */
#ifdef SCORE_ON_BOTL
	if (flags.showscore) {
		sprintf(buf, "S:%ld", botl_score());
		tokenarray[3][4]->caption = buf;
	} else
		tokenarray[3][4]->caption.clear();
#endif

	/* money */
#ifndef GOLDOBJ
		val = u.ugold;
#else
		val = money_cnt(invent);
#endif
	if (val >= 100000) {
		sprintf(buf, "%c:%-2ldk", oc_syms[COIN_CLASS], val / 1000);
		tokenarray[3][2]->caption = buf;
	} else {
		sprintf(buf, "%c:%-2ld", oc_syms[COIN_CLASS], val);
		tokenarray[3][2]->caption = buf;
	}

	/* Experience */
	if (Upolyd) {
		sprintf(buf, "HD:%d", mons[u.umonnum].mlevel);
		tokenarray[3][0]->caption = buf;
	}
#ifdef EXP_ON_BOTL
	else if(flags.showexp)
	{
		Sprintf(buf, "Xp:%u/%-1ld", u.ulevel,u.uexp);
		tokenarray[3][0]->caption = buf;
		/* if the exp gets too long, suppress displaying the alignment */
		if (tokenarray[3][0]->caption.length() > 10)
			tokenarray[4][0]->visible = 0;
	}
#endif
	else {
		Sprintf(buf, "Exp:%u", u.ulevel);
		tokenarray[3][0]->caption = buf;
	}

	/* HP, energy, armor */
	hp = Upolyd ? u.mh : u.uhp;
	hpmax = Upolyd ? u.mhmax : u.uhpmax;
	sprintf(buf, "HP:%d(%d)", hp, hpmax);
	tokenarray[2][1]->caption = buf;
	if (hp >= ((hpmax * 90) / 100))
		tokenarray[2][1]->textcolor = warn_colors[V_WARN_NONE];
	else if (hp >= ((hpmax * 70) / 100))
		tokenarray[2][1]->textcolor = warn_colors[V_WARN_NORMAL];
	else if (hp >= ((hpmax * 50) / 100))
		tokenarray[2][1]->textcolor = warn_colors[V_WARN_MORE];
	else if (hp >= ((hpmax * 25) / 100))
		tokenarray[2][1]->textcolor = warn_colors[V_WARN_ALERT];
	else
		tokenarray[2][1]->textcolor = warn_colors[V_WARN_CRITICAL];
	sprintf(buf, "Pw:%d(%d)", u.uen, u.uenmax);
	tokenarray[2][2]->caption = buf;
	sprintf(buf, "AC:%-2d", u.uac);
	tokenarray[2][3]->caption = buf;

	/* time */
	if(flags.time) {
		sprintf(buf, "T:%ld", moves);
		tokenarray[3][3]->caption = buf;
	} else
		tokenarray[3][3]->caption.clear();

	/* depth again (numeric) */
	sprintf(buf, "Dlvl:%-2d ", depth(&u.uz));
	tokenarray[3][1]->caption = buf;

	/* conditions (hunger, confusion, etc) */
	nconds = 0;

	if (u.uhs > 1) /* hunger */
		add_cond(hu_stat[u.uhs], nconds++, u.uhs-1);
	else if (u.uhs < 1) /* satiated */
		add_cond(hu_stat[u.uhs], nconds++, 0);

	if(Confusion)
		add_cond("Conf", nconds++, V_WARN_MORE);

	if(Sick)
	{
		if (u.usick_type & SICK_VOMITABLE)
			add_cond("FoodPois", nconds++, V_WARN_ALERT);
		if (u.usick_type & SICK_NONVOMITABLE)
			add_cond("Ill", nconds++, V_WARN_ALERT);
	}

	if(Blind)          add_cond("Blind", nconds++, V_WARN_MORE);
	if(Stunned)        add_cond("Stun",  nconds++, V_WARN_MORE);
	if(Hallucination)  add_cond("Hallu", nconds++, V_WARN_MORE);
	if(Slimed)         add_cond("Slime", nconds++, V_WARN_ALERT);

	if(cap > UNENCUMBERED)
		add_cond(enc_stat[cap], nconds++, cap);

	/* reset the empty positions */
	for ( ;nconds < 8; nconds++)
		add_cond("", nconds, 0);

#ifdef SHOW_WEIGHT
	if (flags.showweight && !tokenarray[0][4]->caption[0])
  {
    std::stringstream stream;
    stream << "Wt:" << static_cast<long>((inv_weight()+weight_cap())) << "/" << static_cast<long>(weight_cap()) ;
    tokenarray[0][4]->caption = stream.str();
  }
#endif

}
예제 #16
0
void
ghack_status_window_update_stats()
{
    char buf[BUFSZ];
    gchar *buf1;
    const char *hung;
    const char *enc;
    static int firstTime = TRUE;
    long umoney;

    /* First, fill in the player name and the dungeon level */
    strcpy(buf, plname);
    if ('a' <= buf[0] && buf[0] <= 'z')
        buf[0] += 'A' - 'a';
    strcat(buf, " the ");
    if (u.mtimedone) {
        char mname[BUFSZ];
        int k = 0;

        strcpy(mname, mons[u.umonnum].mname);
        while (mname[k] != 0) {
            if ((k == 0 || (k > 0 && mname[k - 1] == ' ')) && 'a' <= mname[k]
                && mname[k] <= 'z') {
                mname[k] += 'A' - 'a';
            }
            k++;
        }
        strcat(buf, mname);
    } else {
        strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
    }
    gtk_label_get(GTK_LABEL(titleLabel), &buf1);
    if (strcmp(buf1, buf) != 0 && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(titleLabel, bigStyle, bigGreenStyle);
    }
    gtk_label_set(GTK_LABEL(titleLabel), buf);

    if (In_endgame(&u.uz)) {
        strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane" : "End Game"));
    } else {
        sprintf(buf, "%s, level %d", dungeons[u.uz.dnum].dname, depth(&u.uz));
    }
    if (lastDepth > depth(&u.uz) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(dgnLevelLabel, bigStyle, bigRedStyle);
    } else if (lastDepth < depth(&u.uz) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(dgnLevelLabel, bigStyle, bigGreenStyle);
    }
    lastDepth = depth(&u.uz);
    gtk_label_set(GTK_LABEL(dgnLevelLabel), buf);

    /* Next, fill in the player's stats */
    if (ACURR(A_STR) > 118) {
        sprintf(buf, "STR:%d", ACURR(A_STR) - 100);
    } else if (ACURR(A_STR) == 118) {
        sprintf(buf, "STR:18/**");
    } else if (ACURR(A_STR) > 18) {
        sprintf(buf, "STR:18/%02d", ACURR(A_STR) - 18);
    } else {
        sprintf(buf, "STR:%d", ACURR(A_STR));
    }
    if (lastStr < ACURR(A_STR) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(strLabel, normalStyle, greenStyle);
    } else if (lastStr > ACURR(A_STR) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(strLabel, normalStyle, redStyle);
    }
    lastStr = ACURR(A_STR);
    gtk_label_set(GTK_LABEL(strLabel), buf);

    sprintf(buf, "INT:%d", ACURR(A_INT));
    if (lastInt < ACURR(A_INT) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(intLabel, normalStyle, greenStyle);
    } else if (lastInt > ACURR(A_INT) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(intLabel, normalStyle, redStyle);
    }
    lastInt = ACURR(A_INT);
    gtk_label_set(GTK_LABEL(intLabel), buf);

    sprintf(buf, "WIS:%d", ACURR(A_WIS));
    if (lastWis < ACURR(A_WIS) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(wisLabel, normalStyle, greenStyle);
    } else if (lastWis > ACURR(A_WIS) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(wisLabel, normalStyle, redStyle);
    }
    lastWis = ACURR(A_WIS);
    gtk_label_set(GTK_LABEL(wisLabel), buf);

    sprintf(buf, "DEX:%d", ACURR(A_DEX));
    if (lastDex < ACURR(A_DEX) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(dexLabel, normalStyle, greenStyle);
    } else if (lastDex > ACURR(A_DEX) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(dexLabel, normalStyle, redStyle);
    }
    lastDex = ACURR(A_DEX);
    gtk_label_set(GTK_LABEL(dexLabel), buf);

    sprintf(buf, "CON:%d", ACURR(A_CON));
    if (lastCon < ACURR(A_CON) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(conLabel, normalStyle, greenStyle);
    } else if (lastCon > ACURR(A_CON) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(conLabel, normalStyle, redStyle);
    }
    lastCon = ACURR(A_CON);
    gtk_label_set(GTK_LABEL(conLabel), buf);

    sprintf(buf, "CHA:%d", ACURR(A_CHA));
    if (lastCha < ACURR(A_CHA) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(chaLabel, normalStyle, greenStyle);
    } else if (lastCha > ACURR(A_CHA) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(chaLabel, normalStyle, redStyle);
    }
    lastCha = ACURR(A_CHA);
    gtk_label_set(GTK_LABEL(chaLabel), buf);

    /* Now do the non-pixmaped stats (gold and such) */
    umoney = money_cnt(invent);
    sprintf(buf, "Au:%ld", umoney);
    if (lastAu < umoney && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(goldLabel, normalStyle, greenStyle);
    } else if (lastAu > umoney && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(goldLabel, normalStyle, redStyle);
    }
    lastAu = umoney;
    gtk_label_set(GTK_LABEL(goldLabel), buf);

    if (u.mtimedone) {
        /* special case: when polymorphed, show "HD", disable exp */
        sprintf(buf, "HP:%d/%d", ((u.mh > 0) ? u.mh : 0), u.mhmax);
        if ((lastHP < u.mh || lastMHP < u.mhmax) && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(hpLabel, normalStyle, greenStyle);
        } else if ((lastHP > u.mh || lastMHP > u.mhmax)
                   && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(hpLabel, normalStyle, redStyle);
        }
        lastHP = u.mh;
        lastMHP = u.mhmax;
    } else {
        sprintf(buf, "HP:%d/%d", ((u.uhp > 0) ? u.uhp : 0), u.uhpmax);
        if ((lastHP < u.uhp || lastMHP < u.uhpmax) && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(hpLabel, normalStyle, greenStyle);
        } else if ((lastHP > u.uhp || lastMHP > u.uhpmax)
                   && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(hpLabel, normalStyle, redStyle);
        }
        lastHP = u.uhp;
        lastMHP = u.uhpmax;
    }
    gtk_label_set(GTK_LABEL(hpLabel), buf);

    if (u.mtimedone) {
        /* special case: when polymorphed, show "HD", disable exp */
        sprintf(buf, "HD:%d", mons[u.umonnum].mlevel);
        if (lastLevel < mons[u.umonnum].mlevel && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(levlLabel, normalStyle, greenStyle);
        } else if (lastLevel > mons[u.umonnum].mlevel && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(levlLabel, normalStyle, redStyle);
        }
        lastLevel = mons[u.umonnum].mlevel;
    } else {
        sprintf(buf, "Level:%d", u.ulevel);
        if (lastLevel < u.ulevel && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(levlLabel, normalStyle, greenStyle);
        } else if (lastLevel > u.ulevel && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(levlLabel, normalStyle, redStyle);
        }
        lastLevel = u.ulevel;
    }
    gtk_label_set(GTK_LABEL(levlLabel), buf);

    sprintf(buf, "Power:%d/%d", u.uen, u.uenmax);
    if ((lastPOW < u.uen || lastMPOW < u.uenmax) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(powLabel, normalStyle, greenStyle);
    }
    if ((lastPOW > u.uen || lastMPOW > u.uenmax) && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(powLabel, normalStyle, redStyle);
    }
    lastPOW = u.uen;
    lastMPOW = u.uenmax;
    gtk_label_set(GTK_LABEL(powLabel), buf);

    sprintf(buf, "AC:%d", u.uac);
    if (lastAC > u.uac && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(acLabel, normalStyle, greenStyle);
    } else if (lastAC < u.uac && firstTime == FALSE) {
        /* Ok, this changed so add it to the highlighing list */
        ghack_highlight_widget(acLabel, normalStyle, redStyle);
    }
    lastAC = u.uac;
    gtk_label_set(GTK_LABEL(acLabel), buf);

    if (flags.showexp) {
        sprintf(buf, "Exp:%ld", u.uexp);
        if (lastExp < u.uexp && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(expLabel, normalStyle, greenStyle);
        } else if (lastExp > u.uexp && firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(expLabel, normalStyle, redStyle);
        }
        lastExp = u.uexp;
        gtk_label_set(GTK_LABEL(expLabel), buf);
    } else {
        gtk_label_set(GTK_LABEL(expLabel), "");
    }

    if (flags.time) {
        sprintf(buf, "Time:%ld", moves);
        gtk_label_set(GTK_LABEL(timeLabel), buf);
    } else
        gtk_label_set(GTK_LABEL(timeLabel), "");
#ifdef SCORE_ON_BOTL
    if (flags.showscore) {
        sprintf(buf, "Score:%ld", botl_score());
        gtk_label_set(GTK_LABEL(scoreLabel), buf);
    } else
        gtk_label_set(GTK_LABEL(scoreLabel), "");
#else
    {
        gtk_label_set(GTK_LABEL(scoreLabel), "");
    }
#endif

    /* See if their alignment has changed */
    if (lastAlignment != u.ualign.type) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(alignLabel, normalStyle, redStyle);
        }

        lastAlignment = u.ualign.type;
        /* looks like their alignment has changed -- change out the icon */
        if (u.ualign.type == A_CHAOTIC) {
            gtk_label_set(GTK_LABEL(alignLabel), "Chaotic");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(alignPix), chaotic_xpm);
        } else if (u.ualign.type == A_NEUTRAL) {
            gtk_label_set(GTK_LABEL(alignLabel), "Neutral");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(alignPix), neutral_xpm);
        } else {
            gtk_label_set(GTK_LABEL(alignLabel), "Lawful");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(alignPix), lawful_xpm);
        }
    }

    hung = hu_stat[u.uhs];
    if (lastHungr != u.uhs) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(hungerLabel, normalStyle, redStyle);
        }

        lastHungr = u.uhs;
        if (hung[0] == ' ') {
            gtk_label_set(GTK_LABEL(hungerLabel), "      ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(hungerPix), nothing_xpm);
        } else if (u.uhs == 0 /* SATIATED */) {
            gtk_label_set(GTK_LABEL(hungerLabel), hung);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(hungerPix), satiated_xpm);
        } else {
            gtk_label_set(GTK_LABEL(hungerLabel), hung);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(hungerPix), hungry_xpm);
        }
    }

    if (lastConf != Confusion) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(confuLabel, normalStyle, redStyle);
        }

        lastConf = Confusion;
        if (Confusion) {
            gtk_label_set(GTK_LABEL(confuLabel), "Confused");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(confuPix), confused_xpm);
        } else {
            gtk_label_set(GTK_LABEL(confuLabel), "        ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(confuPix), nothing_xpm);
        }
    }

    if (lastBlind != Blind) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(blindLabel, normalStyle, redStyle);
        }

        lastBlind = Blind;
        if (Blind) {
            gtk_label_set(GTK_LABEL(blindLabel), "Blind");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(blindPix), blind_xpm);
        } else {
            gtk_label_set(GTK_LABEL(blindLabel), "     ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(blindPix), nothing_xpm);
        }
    }
    if (lastStun != Stunned) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(stunLabel, normalStyle, redStyle);
        }

        lastStun = Stunned;
        if (Stunned) {
            gtk_label_set(GTK_LABEL(stunLabel), "Stun");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(stunPix), stunned_xpm);
        } else {
            gtk_label_set(GTK_LABEL(stunLabel), "    ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(stunPix), nothing_xpm);
        }
    }

    if (lastHalu != Hallucination) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(halluLabel, normalStyle, redStyle);
        }

        lastHalu = Hallucination;
        if (Hallucination) {
            gtk_label_set(GTK_LABEL(halluLabel), "Hallu");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(halluPix), hallu_xpm);
        } else {
            gtk_label_set(GTK_LABEL(halluLabel), "     ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(halluPix), nothing_xpm);
        }
    }

    if (lastSick != Sick) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(sickLabel, normalStyle, redStyle);
        }

        lastSick = Sick;
        if (Sick) {
            if (u.usick_type & SICK_VOMITABLE) {
                gtk_label_set(GTK_LABEL(sickLabel), "FoodPois");
                gnome_pixmap_load_xpm_d(GNOME_PIXMAP(sickPix), sick_fp_xpm);
            } else if (u.usick_type & SICK_NONVOMITABLE) {
                gtk_label_set(GTK_LABEL(sickLabel), "Ill");
                gnome_pixmap_load_xpm_d(GNOME_PIXMAP(sickPix), sick_il_xpm);
            } else {
                gtk_label_set(GTK_LABEL(sickLabel), "FoodPois");
                gnome_pixmap_load_xpm_d(GNOME_PIXMAP(sickPix), sick_fp_xpm);
            }
        } else {
            gtk_label_set(GTK_LABEL(sickLabel), "        ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(sickPix), nothing_xpm);
        }
    }

    enc = enc_stat[near_capacity()];
    if (lastEncumb != near_capacity()) {
        if (firstTime == FALSE) {
            /* Ok, this changed so add it to the highlighing list */
            ghack_highlight_widget(encumbLabel, normalStyle, redStyle);
        }

        lastEncumb = near_capacity();
        switch (lastEncumb) {
        case 0:
            gtk_label_set(GTK_LABEL(encumbLabel), "        ");
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(encumbPix), nothing_xpm);
            break;
        case 1:
            gtk_label_set(GTK_LABEL(encumbLabel), enc);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(encumbPix), slt_enc_xpm);
            break;
        case 2:
            gtk_label_set(GTK_LABEL(encumbLabel), enc);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(encumbPix), mod_enc_xpm);
            break;
        case 3:
            gtk_label_set(GTK_LABEL(encumbLabel), enc);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(encumbPix), hvy_enc_xpm);
            break;
        case 4:
            gtk_label_set(GTK_LABEL(encumbLabel), enc);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(encumbPix), ext_enc_xpm);
            break;
        case 5:
            gtk_label_set(GTK_LABEL(encumbLabel), enc);
            gnome_pixmap_load_xpm_d(GNOME_PIXMAP(encumbPix), ovr_enc_xpm);
        }
    }
    firstTime = FALSE;
}
예제 #17
0
파일: botl.c 프로젝트: FredrIQ/fiqhack
static void
make_player_info(struct nh_player_info *pi)
{
    int cap, advskills, i;

    memset(pi, 0, sizeof (struct nh_player_info));

    pi->moves = moves;
    strncpy(pi->plname, u.uplname, sizeof (pi->plname));
    pi->align = u.ualign.type;

    /* This function could be called before the game is fully inited. Test
       youmonst.data as it is required for near_capacity().
       program_state.game_running is no good, as we need this data before
       game_running is set.

       TODO: Wow this is hacky. */
    if (!youmonst.data)
        return;
    API_ENTRY_CHECKPOINT_RETURN_VOID_ON_ERROR();

    pi->x = youmonst.mx;
    pi->y = youmonst.my;
    pi->z = u.uz.dlevel;

    if (Upolyd) {
        strncpy(pi->rank, msgtitlecase(mons[u.umonnum].mname),
                sizeof (pi->rank));
    } else
        strncpy(pi->rank, rank(), sizeof (pi->rank));

    strncpy(pi->rolename, (u.ufemale && urole.name.f) ?
            urole.name.f : urole.name.m, sizeof (pi->rolename));
    strncpy(pi->racename, urace.noun, sizeof (pi->racename));
    strncpy(pi->gendername, genders[u.ufemale].adj,
            sizeof(pi->gendername));

    pi->max_rank_sz = mrank_sz;

    /* abilities */
    pi->st = ACURR(A_STR);
    pi->st_extra = 0;
    if (pi->st > 118) {
        pi->st = pi->st - 100;
        pi->st_extra = 0;
    } else if (pi->st > 18) {
        pi->st_extra = pi->st - 18;
        pi->st = 18;
    }

    pi->dx = ACURR(A_DEX);
    pi->co = ACURR(A_CON);
    pi->in = ACURR(A_INT);
    pi->wi = ACURR(A_WIS);
    pi->ch = ACURR(A_CHA);

    pi->score = botl_score();

    /* hp and energy */
    pi->hp = Upolyd ? u.mh : u.uhp;
    pi->hpmax = Upolyd ? u.mhmax : u.uhpmax;
    if (pi->hp < 0)
        pi->hp = 0;

    pi->en = u.uen;
    pi->enmax = u.uenmax;
    pi->ac = find_mac(&youmonst);

    pi->gold = money_cnt(invent);
    pi->coinsym = def_oc_syms[COIN_CLASS];
    describe_level(pi->level_desc);

    pi->monnum = u.umonster;
    pi->cur_monnum = u.umonnum;

    /* level and exp points */
    if (Upolyd)
        pi->level = mons[u.umonnum].mlevel;
    else
        pi->level = youmonst.m_lev;
    pi->xp = youmonst.exp;

    cap = near_capacity();

    /* check if any skills could be anhanced */
    advskills = 0;
    for (i = 0; i < P_NUM_SKILLS; i++) {
        if (P_RESTRICTED(i))
            continue;
        if (can_advance(i, FALSE))
            advskills++;
    }
    pi->can_enhance = advskills > 0;

    /* add status items for various problems there can be at most 24 items here 
       at any one time or we overflow the buffer */
    if (hu_stat[u.uhs]) /* 1 */
        strncpy(pi->statusitems[pi->nr_items++], hu_stat[u.uhs], ITEMLEN);

    if (Confusion)      /* 2 */
        strncpy(pi->statusitems[pi->nr_items++], "Conf", ITEMLEN);

    if (sick(&youmonst)) { /* 3 */
        if (u.usick_type & SICK_VOMITABLE)
            strncpy(pi->statusitems[pi->nr_items++], "FoodPois", ITEMLEN);
        if (u.usick_type & SICK_NONVOMITABLE)
            strncpy(pi->statusitems[pi->nr_items++], "Ill", ITEMLEN);
    }
    if (Blind)  /* 4 */
        strncpy(pi->statusitems[pi->nr_items++], "Blind", ITEMLEN);
    if (slippery_fingers(&youmonst))   /* 5 */
        strncpy(pi->statusitems[pi->nr_items++], "Greasy", ITEMLEN);
    if (leg_hurt(&youmonst))       /* 6 */
        strncpy(pi->statusitems[pi->nr_items++], "Lame", ITEMLEN);
    if (stunned(&youmonst))        /* 7 */
        strncpy(pi->statusitems[pi->nr_items++], "Stun", ITEMLEN);
    if (hallucinating(&youmonst))  /* 8 */
        strncpy(pi->statusitems[pi->nr_items++], "Hallu", ITEMLEN);
    if (strangled(&youmonst))      /* 9 */
        strncpy(pi->statusitems[pi->nr_items++], "Strangle", ITEMLEN);
    if (sliming(&youmonst))        /* 10 */
        strncpy(pi->statusitems[pi->nr_items++], "Slime", ITEMLEN);
    if (petrifying(&youmonst))     /* 11 */
        strncpy(pi->statusitems[pi->nr_items++], "Petrify", ITEMLEN);
    if (u.ustuck && !Engulfed && !sticks(youmonst.data))      /* 12 */
        strncpy(pi->statusitems[pi->nr_items++], "Held", ITEMLEN);
    if (enc_stat[cap]           )  /* 13 */
        strncpy(pi->statusitems[pi->nr_items++], enc_stat[cap], ITEMLEN);
    if (cancelled(&youmonst))
        strncpy(pi->statusitems[pi->nr_items++], "Cancelled", ITEMLEN);
    if (slow(&youmonst))
        strncpy(pi->statusitems[pi->nr_items++], "Slow", ITEMLEN);
    if (Levitation)     /* 14 */
        strncpy(pi->statusitems[pi->nr_items++], "Lev", ITEMLEN);
    else if (Flying)
        strncpy(pi->statusitems[pi->nr_items++], "Fly", ITEMLEN);
    if (uwep && is_pick(uwep)) /* 15 (first case) */
        strncpy(pi->statusitems[pi->nr_items++], "Dig", ITEMLEN);
    else if (uwep && is_launcher(uwep))
        strncpy(pi->statusitems[pi->nr_items++], "Ranged", ITEMLEN);
    else if (uwep && (uwep->otyp == CORPSE) && (touch_petrifies(&mons[uwep->corpsenm])))
        strncpy(pi->statusitems[pi->nr_items++], "cWielded", ITEMLEN);
    else if (!uwep)
        strncpy(pi->statusitems[pi->nr_items++], "Unarmed", ITEMLEN);
    else if (!is_wep(uwep))
        strncpy(pi->statusitems[pi->nr_items++], "NonWeap", ITEMLEN);
    else {
        /* strncpy(pi->statusitems[pi->nr_items++], "Melee", ITEMLEN); */
        /* Don't show the default Melee status light, as that's the most common case. */
        /* 15 (last case) */
    }
    if (u.utrap)        /* 16 */
        strncpy(pi->statusitems[pi->nr_items++], trap_stat[u.utraptype],
                ITEMLEN);

    API_EXIT();
}
예제 #18
0
/* Locks the live log file and writes 'buffer' */
void livelog_write_string(char* buffer)
{
    FILE* livelogfile;
#ifdef FILE_AREAS
    if (lock_file_area(LOGAREA, LIVELOGFILE, 10)) {
#else
    if (lock_file(LIVELOGFILE, SCOREPREFIX, 10)) {
#endif
        if(!(livelogfile = fopen_datafile_area(LOGAREA, LIVELOGFILE, "a", SCOREPREFIX))) {
            pline("Cannot open live log file!");
        } else {
            fprintf(livelogfile, "%s", buffer);
            (void) fclose(livelogfile);
        }
        unlock_file_area(LOGAREA, LIVELOGFILE);
    }
}

static
char *livelog_prefix()
{
    s_level *lev = Is_special(&u.uz);
    snprintf(prefixbuf, STRBUF_LEN,
             "version=%s-%d.%d.%d:"
             "player=%s:turns=%ld:starttime=%ld:"
             "currenttime=%ld:"
             "dnum=%d:dname=%s:dlev=%d:maxlvl=%d:"
             "dlev_name=%s:"
             "hp=%d:maxhp=%d:deaths=%d:"
#ifdef RECORD_REALTIME
             "realtime=%ld:"
#endif
             "conduct=0x%lx:"
             "role=%s:race=%s:"
             "gender=%s:align=%s:"
             "gender0=%s:align0=%s:"
             "explvl=%d:exp=%ld:"
             "elbereths=%ld:"
             "xplevel=%d:" /* XP level */
             "exp=%ld:" /* Experience points */
             "mode=%s:"
             "gold=%ld",
             GAME_SHORT_NAME, VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
             plname,
             moves,
             (long)u.ubirthday,
             (long)current_epoch(),
             u.uz.dnum, dungeons[u.uz.dnum].dname, depth(&u.uz), deepest_lev_reached(TRUE),
             lev ? lev->proto : "", /* proto level name if special level */
             u.uhp, u.uhpmax, u.umortality,
#ifdef RECORD_REALTIME
             (long)realtime_data.realtime,
#endif
             encodeconduct(),
             urole.filecode, urace.filecode,
             genders[flags.female].filecode, aligns[1-u.ualign.type].filecode,
             genders[flags.initgend].filecode, aligns[1-u.ualignbase[A_ORIGINAL]].filecode,
             u.ulevel,u.uexp,
             u.uconduct.elbereths,
             u.ulevel, /* XP level */
             (long)u.uexp, /* Experience points */
             (flags.debug ? "debug" : /* mode */
              flags.explore ? "explore" :
              hell_and_hell_mode ? "hah" :
              heaven_or_hell_mode ? "hoh" :
              "normal"),
#ifndef GOLDOBJ
             (u.ugold + hidden_gold())
#else
             (money_cnt(invent) + hidden_gold())
#endif
            );
    return prefixbuf;
}
예제 #19
0
파일: prop.c 프로젝트: FredrIQ/nethack4
/* Returns the bitwise OR of all MSENSE_ values that explain how "viewer" can
   see "viewee". &youmonst is accepted as either argument. If both arguments
   are the same, this tests if/how a monster/player can detect itself. */
unsigned
msensem(const struct monst *viewer, const struct monst *viewee)
{
    unsigned sensemethod = 0;

    /* sanity checks, so the caller doesn't have to */
    if (viewer != &youmonst)
        if (!onmap(viewer) || DEADMONSTER(viewer))
            return 0;
    if (viewee != &youmonst)
        if (!onmap(viewee) || DEADMONSTER(viewee))
            return 0;
    if (!level) {
        impossible("vision calculations during level creation");
        return 0;
    }

    /* TODO: once levels rewrite is done, this code can be simplified (and won't
       work in its present form). */
    d_level *sz = m_mz(viewer), *tz = m_mz(viewee);
    if (sz->dnum != tz->dnum || sz->dlevel != tz->dlevel)
        return 0;
    struct level *lev = level;
    if (viewer != &youmonst)
        lev = viewer->dlevel;

    int sx = m_mx(viewer), sy = m_my(viewer),
        tx = m_mx(viewee), ty = m_my(viewee);

    int distance = dist2(sx, sy, tx, ty);

    /* Special case: if either endpoint is an engulfing monster, then we want
       LOE to the square specifically, ignoring players on that square (because
       the edge of an engulfing monster blocks LOE to the player). */
    char **msensem_vizarray =
        (Engulfed && (viewer == u.ustuck || viewee == u.ustuck)) ?
        NULL : viz_array;

    /* Line of effect. clear_path is like couldsee(), but doesn't require the
       player to be at either endpoint. (If the player happens to be at one of
       the endpoints, it just calls couldsee() directly.) */
    boolean loe = clear_path(sx, sy, tx, ty, msensem_vizarray);

    /* A special case for many vision methods: water or the ground blocking
       vision. A hiding target is also included in these, because hiding is
       often a case of using an object, part of the floor, a cranny in the
       ceiling, etc., to block vision (and even when it isn't, it should block
       vision in the same cases). */
    boolean vertical_loe =
        !(m_mburied(viewer) || m_mburied(viewee) ||
          ((!!m_underwater(viewee)) ^ (!!m_underwater(viewer))) ||
          m_mundetected(viewee));

    boolean invisible = !!m_has_property(viewee, INVIS, ANY_PROPERTY, 0);

    /* For normal vision, one necessary condition is that the target must be
       adjacent or on a lit square (we assume there's just enough light in the
       dungeon that even in dark areas, adjacent squares are visible to normal
       vision). We test "lit" by testing that the square is either temporarily
       lit, or permanently lit. (We can't use the normal cansee() check because
       that doesn't work for squares outside the player's LOE, and it's possible
       that neither the viewer nor the viewee is the player.)

       TODO: templit off-level. That's very hard to implement because we don't
       run lighting calculations off-level. */
    boolean target_lit = distance <= 2 || (lev == level && templit(tx, ty)) ||
        lev->locations[tx][ty].lit;

    /* TODO: Maybe infravision (and perhaps even infravisibility) should be
       properties? */
    boolean infravision_ok = infravision(viewer->data) &&
        infravisible(viewee->data);

    boolean blinded = !!m_has_property(viewer, BLINDED, ANY_PROPERTY, 0);
    boolean see_invisible =
        !!m_has_property(viewer, SEE_INVIS, ANY_PROPERTY, 0);

    if (loe && vertical_loe && !blinded) {
        if (!invisible && target_lit)
            sensemethod |= MSENSE_VISION;
        if (!invisible && infravision_ok)
            sensemethod |= MSENSE_INFRAVISION;
        if (invisible && (target_lit || infravision_ok) && see_invisible)
            sensemethod |= MSENSE_SEEINVIS | MSENSEF_KNOWNINVIS;
    }

    /* Telepathy. The viewee needs a mind; the viewer needs either to be blind,
       or for the telepathy to be extrinsic and the viewer within BOLT_LIM. */
    if (!mindless(viewee->data) && !m_helpless(viewer, hm_unconscious)) {
        unsigned telepathy_reason =
            m_has_property(viewer, TELEPAT, ANY_PROPERTY, 0);
        if ((telepathy_reason && blinded) ||
            (telepathy_reason & (W_EQUIP | W_ARTIFACT) &&
             distance <= BOLT_LIM * BOLT_LIM))
            sensemethod |= MSENSE_TELEPATHY;
    }

    /* Astral vision. Like regular vision, but has a distance check rather than
       an LOE check. It's unclear whether this pierces blindness, because the
       only item that gives astral vision also gives blindness immunity; this
       code assumes not. */
    boolean xray = m_has_property(viewer, XRAY_VISION, ANY_PROPERTY, 0) &&
        (!invisible || see_invisible);
    if (vertical_loe && distance <= XRAY_RANGE * XRAY_RANGE && xray &&
        (target_lit || infravision_ok)) {
        sensemethod |= MSENSE_XRAY;
        if (invisible && see_invisible)
            sensemethod |= MSENSEF_KNOWNINVIS;
    }

    /* Ideally scent should work around corners, but not through walls. That's
       awkward to write, though, because it'd require pathfinding. */
    if (vertical_loe && loe && distance <= 5 && has_scent(viewer->data))
        sensemethod |= MSENSE_SCENT;

    /* Monster detection. All that is needed (apart from same-level, which was
       checked earlier) is the property itself. */
    if (m_has_property(viewer, DETECT_MONSTERS, ANY_PROPERTY, 0))
        sensemethod |= MSENSE_MONDETECT;

    /* Warning versus monster class. (Actually implemented as monster
       /race/.) */
    if (mworn_warntype(viewer) & viewee->data->mflags2)
        sensemethod |= MSENSE_WARNOFMON;

    /* Covetous sense. Note that the player can benefit from this too, e.g. a
       player in master lich form will be able to detect the Wizard of Yendor
       holding the Book of the Dead. */
    if (covetous_sense(viewer, viewee))
        sensemethod |= MSENSE_COVETOUS;

    /* Smell of gold, approximating 3.4.3 behaviour (which was previously in
       set_apparxy in monmove.c). Xorns can sense any monster with gold in their
       inventory. */
    if (viewer->data == &mons[PM_XORN] && money_cnt(m_minvent(viewee)))
        sensemethod |= MSENSE_GOLDSMELL;

    /* Warning. This partial-senses monsters that are hostile to the viewer, and
       have a level of 4 or greater, and a distance of 100 or less. */
    if (distance <= 100 && m_mlev(viewee) >= 4 &&
        m_has_property(viewer, WARNING, ANY_PROPERTY, 0) &&
        mm_aggression(viewee, viewer) & ALLOW_M)
        sensemethod |= MSENSE_WARNING;

    /* Deducing the existence of a long worm via seeing a segment.

       Based on the code that was formerly worm_known in worm.c, but expanded to
       handle monster viewing.

       Note: assumes that normal vision, possibly modified by astral vision and
       see invisible, is the only way to see a long worm tail. Infravision
       doesn't work (they're cold-blooded), and currently no other types of
       vision are implemented. Detection would find the head. */
    if (viewee->wormno && (!invisible || see_invisible) &&
        vertical_loe && !blinded) {
        struct wseg *curr = viewee->dlevel->wtails[viewee->wormno];

        while (curr) {
            boolean seg_dist = dist2(sx, sy, curr->wx, curr->wy);
            boolean seg_loe =
                clear_path(sx, sy, curr->wx, curr->wy, msensem_vizarray) ||
                (xray && seg_dist <= XRAY_RANGE * XRAY_RANGE);
            boolean seg_lit = seg_dist <= 2 ||
                (lev == level && templit(curr->wx, curr->wy)) ||
                lev->locations[curr->wx][curr->wy].lit;

            if (seg_loe && seg_lit)
                sensemethod |= MSENSE_WORM;

            curr = curr->nseg;
        }
    }

    /* Calculate known invisibility, because we have all the information to
       hand, and it's a complex calculation without it. We need to be able to
       see the monster's location with normal vision, but not the monster
       itself. Also don't include warning in this (because then, we can't match
       the monster to the message). */
    if (loe && vertical_loe && !blinded && sensemethod && target_lit &&
        !(sensemethod & (MSENSE_ANYVISION | MSENSE_WARNING)))
        sensemethod |= MSENSEF_KNOWNINVIS;

    /* If the target is in item form, it's not being seen properly. Any
       vision-style detection of the target is going to not see it as a
       monster. */
    if (m_helpless(viewee, 1 << hr_mimicking) &&
        (lev != level || !Protection_from_shape_changers) &&
        (sensemethod & MSENSE_ANYVISION)) {
        sensemethod &= ~MSENSE_ANYVISION;
        sensemethod |= MSENSE_ITEMMIMIC;
    }

    return sensemethod;
}
예제 #20
0
static int
domonnoise(struct monst *mtmp)
{
    const char *pline_msg = 0,  /* Monnam(mtmp) will be prepended */
        *verbl_msg = 0; /* verbalize() */
    const struct permonst *ptr = mtmp->data;

    /* presumably nearness checks have already been made */
    if (!canhear())
        return 0;
    if (is_silent(ptr))
        return 0;

    /* Make sure its your role's quest quardian; adjust if not */
    if (ptr->msound == MS_GUARDIAN && ptr != &pm_guardian) {
        int mndx = monsndx(ptr);

        ptr = &mons[genus(mndx, 1)];
    }

    /* be sure to do this before talking; the monster might teleport away, in
       which case we want to check its pre-teleport position */
    if (!canspotmon(mtmp))
        map_invisible(mtmp->mx, mtmp->my);

    switch (ptr->msound) {
    case MS_ORACLE:
        return doconsult(mtmp);
    case MS_PRIEST:
        priest_talk(mtmp);
        break;
    case MS_LEADER:
    case MS_NEMESIS:
    case MS_GUARDIAN:
        quest_chat(mtmp);
        break;
    case MS_SELL:      /* pitch, pay, total */
        shk_chat(mtmp);
        break;
    case MS_VAMPIRE:
        {
            /* vampire messages are varied by tameness, peacefulness, and time
               of night */
            boolean isnight = night();
            boolean kindred = (Upolyd &&
                               (u.umonnum == PM_VAMPIRE ||
                                u.umonnum == PM_VAMPIRE_LORD));
            boolean nightchild = (Upolyd &&
                                  (u.umonnum == PM_WOLF ||
                                   u.umonnum == PM_WINTER_WOLF ||
                                   u.umonnum == PM_WINTER_WOLF_CUB));
            const char *racenoun = (u.ufemale &&
                                    urace.individual.f) ? urace.
                individual.f : (urace.individual.m) ? urace.individual.
                m : urace.noun;

            if (mtmp->mtame) {
                if (kindred)
                    verbl_msg = msgprintf("Good %s to you Master%s",
                                          isnight ? "evening" : "day",
                                          isnight ? "!" :
                                          ".  Why do we not rest?");
                else
                    verbl_msg = msgcat(
                        nightchild ? "Child of the night, " : "",
                        midnight()? "I can stand this craving no longer!" :
                        isnight ?
                        "I beg you, help me satisfy this growing craving!" :
                        "I find myself growing a little weary.");
            } else if (mtmp->mpeaceful) {
                if (kindred && isnight)
                    verbl_msg = msgprintf("Good feeding %s!",
                                          u.ufemale ? "sister" : "brother");
                else if (nightchild && isnight)
                    verbl_msg = "How nice to hear you, child of the night!";
                else
                    verbl_msg = "I only drink... potions.";
            } else {
                int vampindex;

                static const char *const vampmsg[] = {
                    /* These first two (0 and 1) are specially handled below */
                    "I vant to suck your %s!",
                    "I vill come after %s without regret!",
                    /* other famous vampire quotes can follow here if desired */
                };
                if (kindred)
                    verbl_msg =
                        "This is my hunting ground that you dare to prowl!";
                else if (youmonst.data == &mons[PM_SILVER_DRAGON] ||
                         youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) {
                    /* Silver dragons are silver in color, not made of silver */
                    verbl_msg = msgprintf(
                        "%s! Your silver sheen does not frighten me!",
                        youmonst.data ==
                        &mons[PM_SILVER_DRAGON] ? "Fool" : "Young Fool");
                } else {
                    vampindex = rn2(SIZE(vampmsg));
                    if (vampindex == 0) {
                        verbl_msg = msgprintf(
                            vampmsg[vampindex], body_part(BLOOD));
                    } else if (vampindex == 1) {
                        verbl_msg = msgprintf(
                            vampmsg[vampindex],
                            Upolyd ? an(mons[u.umonnum].mname) : an(racenoun));
                    } else
                        verbl_msg = vampmsg[vampindex];
                }
            }
        }
        break;
    case MS_WERE:
        if (flags.moonphase == FULL_MOON && (night() ^ !rn2(13))) {
            pline("%s throws back %s head and lets out a blood curdling %s!",
                  Monnam(mtmp), mhis(mtmp),
                  ptr == &mons[PM_HUMAN_WERERAT] ? "shriek" : "howl");
            wake_nearto(mtmp->mx, mtmp->my, 11 * 11);
        } else
            pline_msg =
                "whispers inaudibly.  All you can make out is \"moon\".";
        break;
    case MS_BARK:
        if (flags.moonphase == FULL_MOON && night()) {
            pline_msg = "howls.";
        } else if (mtmp->mpeaceful) {
            if (mtmp->mtame &&
                (mtmp->mconf || mtmp->mflee || mtmp->mtrapped ||
                 moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5))
                pline_msg = "whines.";
            else if (mtmp->mtame && EDOG(mtmp)->hungrytime > moves + 1000)
                pline_msg = "yips.";
            else {
                if (mtmp->data == &mons[PM_FOX])
                    pline_msg = whatthefoxsays();
                else if (mtmp->data != &mons[PM_DINGO])  /* dingos do not
                                                           actually bark */
                    pline_msg = "barks.";
            }
        } else {
            if (mtmp->data == &mons[PM_FOX])
                pline_msg = whatthefoxsays();
            else
                pline_msg = "growls.";
        }
        break;
    case MS_MEW:
        if (mtmp->mtame) {
            if (mtmp->mconf || mtmp->mflee || mtmp->mtrapped || mtmp->mtame < 5)
                pline_msg = "yowls.";
            else if (moves > EDOG(mtmp)->hungrytime)
                pline_msg = "meows.";
            else if (EDOG(mtmp)->hungrytime > moves + 1000)
                pline_msg = "purrs.";
            else
                pline_msg = "mews.";
            break;
        }       /* else FALLTHRU */
    case MS_GROWL:
        pline_msg = mtmp->mpeaceful ? "snarls." : "growls!";
        break;
    case MS_ROAR:
        pline_msg = mtmp->mpeaceful ? "snarls." : "roars!";
        break;
    case MS_SQEEK:
        pline_msg = "squeaks.";
        break;
    case MS_SQAWK:
        if (ptr == &mons[PM_RAVEN] && !mtmp->mpeaceful)
            verbl_msg = "Nevermore!";
        else
            pline_msg = "squawks.";
        break;
    case MS_HISS:
        if (!mtmp->mpeaceful)
            pline_msg = "hisses!";
        else
            return 0;   /* no sound */
        break;
    case MS_BUZZ:
        pline_msg = mtmp->mpeaceful ? "drones." : "buzzes angrily.";
        break;
    case MS_GRUNT:
        pline_msg = "grunts.";
        break;
    case MS_NEIGH:
        if (mtmp->mtame < 5)
            pline_msg = "neighs.";
        else if (moves > EDOG(mtmp)->hungrytime)
            pline_msg = "whinnies.";
        else
            pline_msg = "whickers.";
        break;
    case MS_WAIL:
        pline_msg = "wails mournfully.";
        break;
    case MS_GURGLE:
        pline_msg = "gurgles.";
        break;
    case MS_BURBLE:
        pline_msg = "burbles.";
        break;
    case MS_SHRIEK:
        pline_msg = "shrieks.";
        aggravate();
        break;
    case MS_IMITATE:
        pline_msg = "imitates you.";
        break;
    case MS_BONES:
        pline("%s rattles noisily.", Monnam(mtmp));
        pline("You freeze for a moment.");
        helpless(2, hr_afraid, "scared by rattling", NULL);
        break;
    case MS_LAUGH:
        {
            static const char *const laugh_msg[4] = {
                "giggles.", "chuckles.", "snickers.", "laughs.",
            };
            pline_msg = laugh_msg[rn2(4)];
        }
        break;
    case MS_MUMBLE:
        pline_msg = "mumbles incomprehensibly.";
        break;
    case MS_WISHGIVER:
        if (mtmp->mtame) {
            verbl_msg = "Sorry, I'm all out of wishes.";
        } else if (mtmp->mpeaceful) {
            if (ptr == &mons[PM_WATER_DEMON])
                pline_msg = "gurgles.";
            else
                verbl_msg = "I'm free!";
        } else
            verbl_msg = "This will teach you not to disturb me!";
        break;
    case MS_BOAST:     /* giants */
        if (!mtmp->mpeaceful) {
            switch (rn2(4)) {
            case 0:
                pline("%s boasts about %s gem collection.", Monnam(mtmp),
                      mhis(mtmp));
                break;
            case 1:
                pline_msg = "complains about a diet of mutton.";
                break;
            default:
                pline_msg = "shouts \"Fee Fie Foe Foo!\" and guffaws.";
                wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
                break;
            }
            break;
        }
        /* else FALLTHRU */
    case MS_HUMANOID:
        if (!mtmp->mpeaceful) {
            if (In_endgame(&u.uz) && is_mplayer(ptr)) {
                mplayer_talk(mtmp);
                break;
            } else
                return 0;       /* no sound */
        }
        /* Generic peaceful humanoid behaviour. */
        if (mtmp->mflee)
            pline_msg = "wants nothing to do with you.";
        else if (mtmp->mhp < mtmp->mhpmax / 4)
            pline_msg = "moans.";
        else if (mtmp->mconf || mtmp->mstun)
            verbl_msg = !rn2(3) ? "Huh?" : rn2(2) ? "What?" : "Eh?";
        else if (!mtmp->mcansee)
            verbl_msg = "I can't see!";
        else if (mtmp->mtrapped) {
            struct trap *t = t_at(level, mtmp->mx, mtmp->my);

            if (t)
                t->tseen = 1;
            verbl_msg = "I'm trapped!";
        } else if (mtmp->mhp < mtmp->mhpmax / 2)
            pline_msg = "asks for a potion of healing.";
        else if (mtmp->mtame && !mtmp->isminion &&
                 moves > EDOG(mtmp)->hungrytime)
            verbl_msg = "I'm hungry.";
        /* Specific monsters' interests */
        else if (is_elf(ptr))
            pline_msg = "curses orcs.";
        else if (is_dwarf(ptr))
            pline_msg = "talks about mining.";
        else if (likes_magic(ptr))
            pline_msg = "talks about spellcraft.";
        else if (ptr->mlet == S_CENTAUR)
            pline_msg = "discusses hunting.";
        else
            switch (monsndx(ptr)) {
            case PM_HOBBIT:
                pline_msg =
                    (mtmp->mhpmax - mtmp->mhp >=
                     10) ? "complains about unpleasant dungeon conditions." :
                    "asks you about the One Ring.";
                break;
            case PM_ARCHEOLOGIST:
                pline_msg =
                    "describes a recent article in \"Spelunker Today\" "
                    "magazine.";
                break;
            case PM_TOURIST:
                verbl_msg = "Aloha.";
                break;
            case PM_PRISONER:
                verbl_msg = "Thank you for freeing me!";
                break;
            default:
                pline_msg = "discusses dungeon exploration.";
                break;
            }
        break;
    case MS_SEDUCE:
        if (ptr->mlet != S_NYMPH && flags.seduce_enabled &&
            could_seduce(mtmp, &youmonst, NULL) == 1) {
            doseduce(mtmp);
            break;
        }

        switch ((poly_gender() != (int)mtmp->female) ? rn2(3) : 0) {
        case 2:
            verbl_msg = "Hello, sailor.";
            break;
        case 1:
            pline_msg = "comes on to you.";
            break;
        default:
            pline_msg = "cajoles you.";
        }
        break;
    case MS_ARREST:
        if (mtmp->mpeaceful)
            verbalize("Just the facts, %s.", u.ufemale ? "Ma'am" : "Sir");
        else {
            static const char *const arrest_msg[3] = {
                "Anything you say can be used against you.",
                "You're under arrest!",
                "Stop in the name of the Law!",
            };
            verbl_msg = arrest_msg[rn2(3)];
        }
        break;
    case MS_BRIBE:
        if (mtmp->mpeaceful && !mtmp->mtame) {
            demon_talk(mtmp);
            break;
        }
        /* fall through */
    case MS_CUSS:
        if (!mtmp->mpeaceful)
            cuss(mtmp);
        break;
    case MS_SPELL:
        /* deliberately vague, since it's not actually casting any spell */
        pline_msg = "seems to mutter a cantrip.";
        break;
    case MS_NURSE:
        if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)))
            verbl_msg = "Put that weapon away before you hurt someone!";
        else if (uarmc || (uarm && !uskin()) ||
                 uarmh || uarms || uarmg || uarmf)
            verbl_msg =
                Role_if(PM_HEALER) ?
                "Doc, I can't help you unless you cooperate." :
                "Please undress so I can examine you.";
        else if (uarmu)
            verbl_msg = "Take off your shirt, please.";
        else
            verbl_msg = "Relax, this won't hurt a bit.";
        break;
    case MS_GUARD:
        if (money_cnt(invent))
            verbl_msg = "Please drop that gold and follow me.";
        else
            verbl_msg = "Please follow me.";
        break;
    case MS_SOLDIER:
        {
            static const char *const soldier_foe_msg[3] = {
                "Resistance is useless!",
                "You're dog meat!",
                "Surrender!",
            }, *const soldier_pax_msg[3] = {
                "What lousy pay we're getting here!",
                "The food's not fit for Orcs!",
                "My feet hurt, I've been on them all day!",
            };
            verbl_msg = mtmp->mpeaceful ? soldier_pax_msg[rn2(3)]
                : soldier_foe_msg[rn2(3)];
        }
        break;
    case MS_RIDER:
        if (ptr == &mons[PM_DEATH] && !rn2(10))
            pline_msg = "is busy reading a copy of Sandman #8.";
        else
            verbl_msg = "Who do you think you are, War?";
        break;
    }

    if (pline_msg)
        pline("%s %s", Monnam(mtmp), pline_msg);
    else if (verbl_msg)
        verbalize("%s", verbl_msg);
    return 1;
}
예제 #21
0
int
doconsult(struct monst *oracl)
{
    int umoney = money_cnt(invent);
    int u_pay, minor_cost = 50, major_cost = 500 + 50 * u.ulevel;
    int add_xpts;
    char qbuf[QBUFSZ];

    multi = 0;

    if (!oracl) {
        pline("There is no one here to consult.");
        return 0;
    } else if (!oracl->mpeaceful) {
        pline("%s is in no mood for consultations.", Monnam(oracl));
        return 0;
    } else if (!umoney) {
        pline("You have no money.");
        return 0;
    }

    sprintf(qbuf, "\"Wilt thou settle for a minor consultation?\" (%d %s)",
            minor_cost, currency(minor_cost));
    switch (ynq(qbuf)) {
    default:
    case 'q':
        return 0;
    case 'y':
        if (umoney < minor_cost) {
            pline("You don't even have enough money for that!");
            return 0;
        }
        u_pay = minor_cost;
        break;
    case 'n':
        if (umoney <= minor_cost ||     /* don't even ask */
            (oracle_cnt == 1 || oracle_flg < 0))
            return 0;
        sprintf(qbuf, "\"Then dost thou desire a major one?\" (%d %s)",
                major_cost, currency(major_cost));
        if (yn(qbuf) != 'y')
            return 0;
        u_pay = (umoney < major_cost ? umoney : major_cost);

        break;
    }

    money2mon(oracl, u_pay);
    iflags.botl = 1;
    add_xpts = 0;       /* first oracle of each type gives experience points */
    if (u_pay == minor_cost) {
        outrumor(1, BY_ORACLE);
        if (!u.uevent.minor_oracle)
            add_xpts = u_pay / (u.uevent.major_oracle ? 25 : 10);
        /* 5 pts if very 1st, or 2 pts if major already done */
        u.uevent.minor_oracle = TRUE;
    } else {
        boolean cheapskate = u_pay < major_cost;

        outoracle(cheapskate, TRUE);
        if (!cheapskate && !u.uevent.major_oracle)
            add_xpts = u_pay / (u.uevent.minor_oracle ? 25 : 10);
        /* ~100 pts if very 1st, ~40 pts if minor already done */
        u.uevent.major_oracle = TRUE;
        historic_event(FALSE, "received advice from The Oracle.");
        exercise(A_WIS, !cheapskate);
    }
    if (add_xpts) {
        more_experienced(add_xpts, u_pay / 50);
        newexplevel();
    }
    return 1;
}
예제 #22
0
        /* set height of the status box */
        sz->cy = tm.tmHeight * data->nhstat_format;

        SelectObject(hdc, saveFont);
        ReleaseDC(hWnd, hdc);
    }
}
extern const char *hu_stat[];  /* defined in eat.c */
extern const char *enc_stat[]; /* define in botl.c */
void
FormatStatusString(char *text, int format)
{
    register char *nb;
    int hp, hpmax;
    int cap = near_capacity();

    Strcpy(text, plname);
    if ('a' <= text[0] && text[0] <= 'z')
        text[0] += 'A' - 'a';
    text[10] = 0;
    Sprintf(nb = eos(text), " the ");

    if (Upolyd) {
        char mbot[BUFSZ];
        int k = 0;

        Strcpy(mbot, mons[u.umonnum].mname);
        while (mbot[k] != 0) {
            if ((k == 0 || (k > 0 && mbot[k - 1] == ' ')) && 'a' <= mbot[k]
                && mbot[k] <= 'z')
                mbot[k] += 'A' - 'a';
            k++;
        }
        Sprintf(nb = eos(nb), mbot);
    } else
        Sprintf(nb = eos(nb), rank_of(u.ulevel, Role_switch, flags.female));

    if (format == NHSTAT_LINES_4)
        Sprintf(nb = eos(nb), "\r\n");

    if (ACURR(A_STR) > 18) {
        if (ACURR(A_STR) > STR18(100))
            Sprintf(nb = eos(nb), "St:%2d ", ACURR(A_STR) - 100);
        else if (ACURR(A_STR) < STR18(100))
            Sprintf(nb = eos(nb), "St:18/%02d ", ACURR(A_STR) - 18);
        else
            Sprintf(nb = eos(nb), "St:18/** ");
    } else
        Sprintf(nb = eos(nb), "St:%-1d ", ACURR(A_STR));
    Sprintf(nb = eos(nb), "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
            ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS),
            ACURR(A_CHA));
    Sprintf(nb = eos(nb),
            (u.ualign.type == A_CHAOTIC)
                ? "  Chaotic"
                : (u.ualign.type == A_NEUTRAL) ? "  Neutral" : "  Lawful");
#ifdef SCORE_ON_BOTL
    if (flags.showscore)
        Sprintf(nb = eos(nb), " S:%ld", botl_score());
#endif
    if (format == NHSTAT_LINES_4 || format == NHSTAT_LINES_2)
        strcat(text, "\r\n");

    /* third line */
    hp = Upolyd ? u.mh : u.uhp;
    hpmax = Upolyd ? u.mhmax : u.uhpmax;

    if (hp < 0)
        hp = 0;
    (void) describe_level(nb = eos(nb));
    Sprintf(nb = eos(nb), "%c:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d",
            showsyms[COIN_CLASS + SYM_OFF_O], money_cnt(invent), hp, hpmax,
            u.uen, u.uenmax, u.uac);

    if (Upolyd)
        Sprintf(nb = eos(nb), " HD:%d", mons[u.umonnum].mlevel);
    else if (flags.showexp)
        Sprintf(nb = eos(nb), " Xp:%u/%-1ld", u.ulevel, u.uexp);
    else
        Sprintf(nb = eos(nb), " Exp:%u", u.ulevel);
    if (format == NHSTAT_LINES_4)
        strcat(text, "\r\n");
    else
        strcat(text, " ");

    /* forth line */
    if (flags.time)
        Sprintf(nb = eos(nb), "T:%ld ", moves);

    if (strcmp(hu_stat[u.uhs], "        ")) {
        Strcat(text, hu_stat[u.uhs]);
        Sprintf(nb = eos(nb), " ");
    }
    if (Confusion)
        Sprintf(nb = eos(nb), "Conf");
    if (Sick) {
        if (u.usick_type & SICK_VOMITABLE)
            Sprintf(nb = eos(nb), " FoodPois");
        if (u.usick_type & SICK_NONVOMITABLE)
            Sprintf(nb = eos(nb), " Ill");
    }
    if (Blind)
        Sprintf(nb = eos(nb), " Blind");
    if (Stunned)
        Sprintf(nb = eos(nb), " Stun");
    if (Hallucination)
        Sprintf(nb = eos(nb), " Hallu");
    if (Slimed)
        Sprintf(nb = eos(nb), " Slime");
    if (cap > UNENCUMBERED)
        Sprintf(nb = eos(nb), " %s", enc_stat[cap]);
}
예제 #23
0
/*
 * return  1: guard moved,  0: guard didn't,  -1: let m_move do it,  -2: died
 */
int
gd_move(struct monst *grd)
{
    int x, y, nx, ny, m, n;
    int dx, dy, gx = 0, gy = 0, fci;
    uchar typ;
    struct fakecorridor *fcp;
    struct egd *egrd = EGD(grd);
    struct rm *crm;
    boolean goldincorridor = FALSE, u_in_vault =
        vault_occupied(u.urooms) ? TRUE : FALSE, grd_in_vault =
        *in_rooms(level, grd->mx, grd->my, VAULT) ? TRUE : FALSE;
    boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
    long umoney = money_cnt(invent);
    boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
    boolean see_guard;

    if (!on_level(&(egrd->gdlevel), &u.uz))
        return -1;
    nx = ny = m = n = 0;
    if (!u_in_vault && !grd_in_vault)
        wallify_vault(grd);
    if (!grd->mpeaceful) {
        if (semi_dead) {
            egrd->gddone = 1;
            goto newpos;
        }
        if (!u_in_vault &&
            (grd_in_vault ||
             (in_fcorridor(grd, grd->mx, grd->my) &&
              !in_fcorridor(grd, u.ux, u.uy)))) {
            rloc(grd, FALSE);
            wallify_vault(grd);
            clear_fcorr(grd, TRUE);
            goto letknow;
        }
        if (!in_fcorridor(grd, grd->mx, grd->my))
            clear_fcorr(grd, TRUE);
        return -1;
    }
    if (abs(egrd->ogx - grd->mx) > 1 || abs(egrd->ogy - grd->my) > 1)
        return -1;      /* teleported guard - treat as monster */
    if (egrd->fcend == 1) {
        if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
            if (egrd->warncnt == 3)
                verbalize("I repeat, %sfollow me!",
                          u_carry_gold ? (!umoney ?
                                          "drop that hidden money and " :
                                          "drop that money and ") : "");
            if (egrd->warncnt == 7) {
                m = grd->mx;
                n = grd->my;
                verbalize("You've been warned, knave!");
                mnexto(grd);
                level->locations[m][n].typ = egrd->fakecorr[0].ftyp;
                newsym(m, n);
                msethostility(grd, TRUE, FALSE);
                return -1;
            }
            /* not fair to get mad when (s)he's fainted or paralyzed */
            if (!u_helpless(hm_all))
                egrd->warncnt++;
            return 0;
        }

        if (!u_in_vault) {
            if (u_carry_gold) { /* player teleported */
                m = grd->mx;
                n = grd->my;
                rloc(grd, FALSE);
                level->locations[m][n].typ = egrd->fakecorr[0].ftyp;
                newsym(m, n);
                msethostility(grd, TRUE, FALSE);
            letknow:
                if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
                    You_hear("the shrill sound of a guard's whistle.");
                else
                    pline(um_dist(grd->mx, grd->my, 2) ?
                          "You see an angry guard approaching." :
                          "You are confronted by an angry guard.");
                return -1;
            } else {
                verbalize("Well, begone.");
                wallify_vault(grd);
                egrd->gddone = 1;
                goto cleanup;
            }
        }
    }

    if (egrd->fcend > 1) {
        if (egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
            !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
            level->locations[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ ==
            egrd->fakecorr[0].ftyp) {
            if (canseemon(grd)) {
                pline("%s, confused, disappears.", Monnam(grd));
                disappear_msg_seen = TRUE;
            }
            goto cleanup;
        }
        if (u_carry_gold && (in_fcorridor(grd, u.ux, u.uy) ||
                             /* cover a 'blind' spot */
                             (egrd->fcend > 1 && u_in_vault))) {
            if (!grd->mx) {
                restfakecorr(grd);
                return -2;
            }
            if (egrd->warncnt < 6) {
                egrd->warncnt = 6;
                verbalize("Drop all your gold, scoundrel!");
                return 0;
            } else {
                verbalize("So be it, rogue!");
                msethostility(grd, TRUE, FALSE);
                return -1;
            }
        }
    }
    for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
        if (gold_at(level, egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
            m = egrd->fakecorr[fci].fx;
            n = egrd->fakecorr[fci].fy;
            goldincorridor = TRUE;
        }
    if (goldincorridor && !egrd->gddone) {
        boolean yours = FALSE;

        x = grd->mx;
        y = grd->my;
        if (m == u.ux && n == u.uy) {
            struct obj *gold = gold_at(level, m, n);

            yours = TRUE;
            /* Grab the gold from between the hero's feet.  */
            obj_extract_self(gold);
            add_to_minv(grd, gold);
            newsym(m, n);
        } else if (m == x && n == y) {
            mpickgold(grd);     /* does a newsym */
        } else {
            /* just for insurance... */
            if (MON_AT(level, m, n) && m != grd->mx && n != grd->my) {
                verbalize("Out of my way, scum!");
                rloc(m_at(level, m, n), FALSE);
            }
            remove_monster(level, grd->mx, grd->my);
            newsym(grd->mx, grd->my);
            place_monster(grd, m, n);
            mpickgold(grd);     /* does a newsym */
        }
        if (cansee(m, n)) {
            if (yours) {
                pline("%s%s picks up the gold.", Monnam(grd),
                      grd->mpeaceful ? " calms down and" : "");
            } else {
                pline("%s picks up some gold.", Monnam(grd));
            }
        }
        if (x != grd->mx || y != grd->my) {
            remove_monster(level, grd->mx, grd->my);
            newsym(grd->mx, grd->my);
            place_monster(grd, x, y);
            newsym(x, y);
        }
        if (!grd->mpeaceful)
            return -1;
        else {
            egrd->warncnt = 5;
            return 0;
        }
    }
    if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
        if (!egrd->gddone && !rn2(10))
            verbalize("Move along!");
        restfakecorr(grd);
        return 0;       /* didn't move */
    }
    x = grd->mx;
    y = grd->my;

    if (u_in_vault)
        goto nextpos;

    /* look around (hor & vert only) for accessible places */
    for (nx = x - 1; nx <= x + 1; nx++)
        for (ny = y - 1; ny <= y + 1; ny++) {
            if ((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {

                typ = (crm = &level->locations[nx][ny])->typ;
                if (!IS_STWALL(typ) && !IS_POOL(typ)) {

                    if (in_fcorridor(grd, nx, ny))
                        goto nextnxy;

                    if (*in_rooms(level, nx, ny, VAULT))
                        continue;

                    /* seems we found a good place to leave him alone */
                    egrd->gddone = 1;
                    if (ACCESSIBLE(typ))
                        goto newpos;
                    crm->typ = (typ == SCORR) ? CORR : DOOR;
                    if (crm->typ == DOOR)
                        crm->doormask = D_NODOOR;
                    goto proceed;
                }
            }
        nextnxy:;
        }
nextpos:
    nx = x;
    ny = y;
    gx = egrd->gdx;
    gy = egrd->gdy;
    dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
    dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
    if (abs(gx - x) >= abs(gy - y))
        nx += dx;
    else
        ny += dy;

    while ((typ = (crm = &level->locations[nx][ny])->typ) != 0) {
        /* in view of the above we must have IS_WALL(typ) or typ == POOL */
        /* must be a wall here */
        if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ) &&
            IS_ROOM(level->locations[nx + nx - x][ny + ny - y].typ)) {
            crm->typ = DOOR;
            crm->doormask = D_NODOOR;
            goto proceed;
        }
        if (dy && nx != x) {
            nx = x;
            ny = y + dy;
            continue;
        }
        if (dx && ny != y) {
            ny = y;
            nx = x + dx;
            dy = 0;
            continue;
        }
        /* I don't like this, but ... */
        if (IS_ROOM(typ)) {
            crm->typ = DOOR;
            crm->doormask = D_NODOOR;
            goto proceed;
        }
        break;
    }
    crm->typ = CORR;
proceed:
    unblock_point(nx, ny);      /* doesn't block light */
    if (cansee(nx, ny))
        newsym(nx, ny);

    if ((nx != gx || ny != gy) || (grd->mx != gx || grd->my != gy)) {
        fcp = &(egrd->fakecorr[egrd->fcend]);
        if (egrd->fcend++ == FCSIZ)
            panic("fakecorr overflow");
        fcp->fx = nx;
        fcp->fy = ny;
        fcp->ftyp = typ;
    } else if (!egrd->gddone) {
        /* We're stuck, so try to find a new destination. */
        if (!find_guard_dest(grd, &egrd->gdx, &egrd->gdy) ||
            (egrd->gdx == gx && egrd->gdy == gy)) {
            pline("%s, confused, disappears.", Monnam(grd));
            disappear_msg_seen = TRUE;
            goto cleanup;
        } else
            goto nextpos;
    }
newpos:
    if (egrd->gddone) {
        /* The following is a kludge.  We need to keep the guard around in order
           to be able to make the fake corridor disappear as the player moves
           out of it, but we also need the guard out of the way.  We send the
           guard to never-never land.  We set ogx ogy to mx my in order to avoid
           a check at the top of this function.  At the end of the process, the
           guard is killed in restfakecorr().  */
    cleanup:
        x = grd->mx;
        y = grd->my;

        see_guard = canspotmon(grd);
        wallify_vault(grd);
        remove_monster(level, grd->mx, grd->my);
        newsym(grd->mx, grd->my);
        grd->mx = COLNO;
        grd->my = ROWNO;
        egrd->ogx = grd->mx;
        egrd->ogy = grd->my;
        restfakecorr(grd);
        if (!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || cansee(x, y))) {
            if (!disappear_msg_seen && see_guard)
                pline("Suddenly, %s disappears.", noit_mon_nam(grd));
            return 1;
        }
        return -2;
    }
    egrd->ogx = grd->mx;        /* update old positions */
    egrd->ogy = grd->my;
    remove_monster(level, grd->mx, grd->my);
    place_monster(grd, nx, ny);
    newsym(grd->mx, grd->my);
    restfakecorr(grd);
    return 1;
}
예제 #24
0
/* #sit command */
int
dosit()
{
/*JP
    static const char sit_message[] = "sit on the %s.";
*/
    static const char sit_message[] = "%sに座った.";
    register struct trap *trap = t_at(u.ux, u.uy);
    register int typ = levl[u.ux][u.uy].typ;

    if (u.usteed) {
/*JP
        You("are already sitting on %s.", mon_nam(u.usteed));
*/
        You("もう%sに座っている.", mon_nam(u.usteed));
        return 0;
    }
    if (u.uundetected && is_hider(youmonst.data) && u.umonnum != PM_TRAPPER)
        u.uundetected = 0; /* no longer on the ceiling */

    if (!can_reach_floor(FALSE)) {
        if (u.uswallow)
/*JP
            There("are no seats in here!");
*/
            pline("ここには椅子がない!");
        else if (Levitation)
/*JP
            You("tumble in place.");
*/
            You("その場で宙返りした.");
        else
/*JP
            You("are sitting on air.");
*/
            You("空中に座った.");
        return 0;
    } else if (u.ustuck && !sticks(youmonst.data)) {
        /* holding monster is next to hero rather than beneath, but
           hero is in no condition to actually sit at has/her own spot */
        if (humanoid(u.ustuck->data))
/*JP
            pline("%s won't offer %s lap.", Monnam(u.ustuck), mhis(u.ustuck));
*/
            pline("%sはひざを出さなかった.", Monnam(u.ustuck));
        else
/*JP
            pline("%s has no lap.", Monnam(u.ustuck));
*/
            pline("%sにはひざがない.", Monnam(u.ustuck));
        return 0;
    } else if (is_pool(u.ux, u.uy) && !Underwater) { /* water walking */
        goto in_water;
    }

    if (OBJ_AT(u.ux, u.uy)
        /* ensure we're not standing on the precipice */
        && !uteetering_at_seen_pit(trap)) {
        register struct obj *obj;

        obj = level.objects[u.ux][u.uy];
        if (youmonst.data->mlet == S_DRAGON && obj->oclass == COIN_CLASS) {
#if 0 /*JP*/
            You("coil up around your %shoard.",
                (obj->quan + money_cnt(invent) < u.ulevel * 1000) ? "meager "
                                                                  : "");
#else
            You("%sお宝のまわりでとぐろを巻いた.",
                (obj->quan + money_cnt(invent) < u.ulevel * 1000) ? "わずかな"
                                                                  : "");
#endif
        } else {
/*JP
            You("sit on %s.", the(xname(obj)));
*/
            You("%sに座った.", the(xname(obj)));
            if (!(Is_box(obj) || objects[obj->otyp].oc_material == CLOTH))
/*JP
                pline("It's not very comfortable...");
*/
                pline("あまり座りごこちがよくない...");
        }
    } else if (trap != 0 || (u.utrap && (u.utraptype >= TT_LAVA))) {
        if (u.utrap) {
            exercise(A_WIS, FALSE); /* you're getting stuck longer */
            if (u.utraptype == TT_BEARTRAP) {
/*JP
                You_cant("sit down with your %s in the bear trap.",
*/
                pline("%sが熊の罠にはさまっているので座れない.",
                         body_part(FOOT));
                u.utrap++;
            } else if (u.utraptype == TT_PIT) {
                if (trap && trap->ttyp == SPIKED_PIT) {
/*JP
                    You("sit down on a spike.  Ouch!");
*/
                    You("トゲの上に座った.いてっ!");
                    losehp(Half_physical_damage ? rn2(2) : 1,
/*JP
                           "sitting on an iron spike", KILLED_BY);
*/
                           "鉄のトゲの上に座って", KILLED_BY);
                    exercise(A_STR, FALSE);
                } else
/*JP
                    You("sit down in the pit.");
*/
                    You("落し穴の中で座った.");
                u.utrap += rn2(5);
            } else if (u.utraptype == TT_WEB) {
/*JP
                You("sit in the spider web and get entangled further!");
*/
                You("くもの巣の中で座ったら,ますます絡まった!");
                u.utrap += rn1(10, 5);
            } else if (u.utraptype == TT_LAVA) {
                /* Must have fire resistance or they'd be dead already */
/*JP
                You("sit in the lava!");
*/
                You("溶岩の中に座った!");
                if (Slimed)
                    burn_away_slime();
                u.utrap += rnd(4);
/*JP
                losehp(d(2, 10), "sitting in lava",
*/
                losehp(d(2, 10), "溶岩の中に座って",
                       KILLED_BY); /* lava damage */
            } else if (u.utraptype == TT_INFLOOR
                       || u.utraptype == TT_BURIEDBALL) {
/*JP
                You_cant("maneuver to sit!");
*/
                You("座るような動作ができない!");
                u.utrap++;
            }
        } else {
/*JP
            You("sit down.");
*/
            You("座った.");
            dotrap(trap, 0);
        }
    } else if (Underwater || Is_waterlevel(&u.uz)) {
        if (Is_waterlevel(&u.uz))
/*JP
            There("are no cushions floating nearby.");
*/
            pline("近くに浮いているクッションはない.");
        else
/*JP
            You("sit down on the muddy bottom.");
*/
            You("どろどろした底に座った.");
    } else if (is_pool(u.ux, u.uy)) {
    in_water:
/*JP
        You("sit in the water.");
*/
        You("水の中で座った.");
        if (!rn2(10) && uarm)
/*JP
            (void) water_damage(uarm, "armor", TRUE);
*/
            (void) water_damage(uarm, "鎧", TRUE);
        if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
/*JP
            (void) water_damage(uarm, "armor", TRUE);
*/
            (void) water_damage(uarm, "鎧", TRUE);
    } else if (IS_SINK(typ)) {
        You(sit_message, defsyms[S_sink].explanation);
/*JP
        Your("%s gets wet.", humanoid(youmonst.data) ? "rump" : "underside");
*/
        Your("%sは濡れた.", humanoid(youmonst.data) ? "尻" : "下部");
    } else if (IS_ALTAR(typ)) {
        You(sit_message, defsyms[S_altar].explanation);
        altar_wrath(u.ux, u.uy);
    } else if (IS_GRAVE(typ)) {
        You(sit_message, defsyms[S_grave].explanation);
    } else if (typ == STAIRS) {
/*JP
        You(sit_message, "stairs");
*/
        You(sit_message, "階段");
    } else if (typ == LADDER) {
/*JP
        You(sit_message, "ladder");
*/
        You(sit_message, "はしご");
    } else if (is_lava(u.ux, u.uy)) {
        /* must be WWalking */
/*JP
        You(sit_message, "lava");
*/
        You(sit_message, "溶岩");
        burn_away_slime();
        if (likes_lava(youmonst.data)) {
/*JP
            pline_The("lava feels warm.");
*/
            pline("溶岩は暖かい.");
            return 1;
        }
/*JP
        pline_The("lava burns you!");
*/
        You("溶岩で燃えた!");
        losehp(d((Fire_resistance ? 2 : 10), 10), /* lava damage */
/*JP
               "sitting on lava", KILLED_BY);
*/
               "溶岩に座って", KILLED_BY);
    } else if (is_ice(u.ux, u.uy)) {
        You(sit_message, defsyms[S_ice].explanation);
        if (!Cold_resistance)
/*JP
            pline_The("ice feels cold.");
*/
            pline("氷は冷たく感じた.");
    } else if (typ == DRAWBRIDGE_DOWN) {
/*JP
        You(sit_message, "drawbridge");
*/
        You(sit_message, "跳ね橋");
    } else if (IS_THRONE(typ)) {
        You(sit_message, defsyms[S_throne].explanation);
        if (rnd(6) > 4) {
            switch (rnd(13)) {
            case 1:
                (void) adjattrib(rn2(A_MAX), -rn1(4, 3), FALSE);
/*JP
                losehp(rnd(10), "cursed throne", KILLED_BY_AN);
*/
                losehp(rnd(10), "呪われた玉座で", KILLED_BY_AN);
                break;
            case 2:
                (void) adjattrib(rn2(A_MAX), 1, FALSE);
                break;
            case 3:
#if 0 /*JP*/
                pline("A%s electric shock shoots through your body!",
                      (Shock_resistance) ? "n" : " massive");
#else
                pline("%s電気があなたの体を走り抜けた!",
                      (Shock_resistance) ? "" : "激しい");
#endif
/*JP
                losehp(Shock_resistance ? rnd(6) : rnd(30), "electric chair",
*/
                losehp(Shock_resistance ? rnd(6) : rnd(30), "電気椅子で",
                       KILLED_BY_AN);
                exercise(A_CON, FALSE);
                break;
            case 4:
/*JP
                You_feel("much, much better!");
*/
                You_feel("とても,とても元気になったような気がした!");
                if (Upolyd) {
                    if (u.mh >= (u.mhmax - 5))
                        u.mhmax += 4;
                    u.mh = u.mhmax;
                }
                if (u.uhp >= (u.uhpmax - 5))
                    u.uhpmax += 4;
                u.uhp = u.uhpmax;
                make_blinded(0L, TRUE);
                make_sick(0L, (char *) 0, FALSE, SICK_ALL);
                heal_legs();
                context.botl = 1;
                break;
            case 5:
                take_gold();
                break;
            case 6:
                if (u.uluck + rn2(5) < 0) {
/*JP
                    You_feel("your luck is changing.");
*/
                    pline("運が向いてきた気がする.");
                    change_luck(1);
                } else
                    makewish();
                break;
            case 7:
              {
                int cnt = rnd(10);

                /* Magical voice not affected by deafness */
/*JP
                pline("A voice echoes:");
*/
                pline("声が響いた:");
#if 0 /*JP*/
                verbalize("Thy audience hath been summoned, %s!",
                          flags.female ? "Dame" : "Sire");
#else
                verbalize("%sよ!汝の聴衆召喚されし.",
                          flags.female ? "女" : "男");
#endif
                while (cnt--)
                    (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
                break;
              }
            case 8:
                /* Magical voice not affected by deafness */
/*JP
                pline("A voice echoes:");
*/
                pline("声が響いた:");
#if 0 /*JP*/
                verbalize("By thine Imperious order, %s...",
                          flags.female ? "Dame" : "Sire");
#else
                verbalize("%sよ!汝の傲慢聞きいれようぞ.",
                          flags.female ? "女" : "男");
#endif
                do_genocide(5); /* REALLY|ONTHRONE, see do_genocide() */
                break;
            case 9:
                /* Magical voice not affected by deafness */
/*JP
                pline("A voice echoes:");
*/
                pline("声が響いた:");
                verbalize(
/*JP
                 "A curse upon thee for sitting upon this most holy throne!");
*/
                 "聖なる玉座に座りし汝に呪いあれ!");
                if (Luck > 0) {
                    make_blinded(Blinded + rn1(100, 250), TRUE);
                } else
                    rndcurse();
                break;
            case 10:
                if (Luck < 0 || (HSee_invisible & INTRINSIC)) {
                    if (level.flags.nommap) {
/*JP
                        pline("A terrible drone fills your head!");
*/
                        pline("恐しいブンブンという音が頭に響いた!");
                        make_confused((HConfusion & TIMEOUT) + (long) rnd(30),
                                      FALSE);
                    } else {
/*JP
                        pline("An image forms in your mind.");
*/
                        pline("あるイメージが頭に浮んだ.");
                        do_mapping();
                    }
                } else {
/*JP
                    Your("vision becomes clear.");
*/
                    Your("視界は冴え渡った.");
                    HSee_invisible |= FROMOUTSIDE;
                    newsym(u.ux, u.uy);
                }
                break;
            case 11:
                if (Luck < 0) {
/*JP
                    You_feel("threatened.");
*/
                    You("脅迫されているような気がした.");
                    aggravate();
                } else {
/*JP
                    You_feel("a wrenching sensation.");
*/
                    You("ねじられたような感覚を感じた.");
                    tele(); /* teleport him */
                }
                break;
            case 12:
/*JP
                You("are granted an insight!");
*/
                You("洞察力を得た!");
                if (invent) {
                    /* rn2(5) agrees w/seffects() */
                    identify_pack(rn2(5), FALSE);
                }
                break;
            case 13:
/*JP
                Your("mind turns into a pretzel!");
*/
                Your("心はクネクネになった!");
                make_confused((HConfusion & TIMEOUT) + (long) rn1(7, 16),
                              FALSE);
                break;
            default:
                impossible("throne effect");
                break;
            }
        } else {
            if (is_prince(youmonst.data))
/*JP
                You_feel("very comfortable here.");
*/
                You("ここはとても落ち着く.");
            else
/*JP
                You_feel("somehow out of place...");
*/
                You("何か場違いの気がした...");
        }

        if (!rn2(3) && IS_THRONE(levl[u.ux][u.uy].typ)) {
            /* may have teleported */
            levl[u.ux][u.uy].typ = ROOM;
/*JP
            pline_The("throne vanishes in a puff of logic.");
*/
            pline("玉座はふっと消えた.");
            newsym(u.ux, u.uy);
        }
    } else if (lays_eggs(youmonst.data)) {
        struct obj *uegg;

        if (!flags.female) {
#if 0 /*JP*/
            pline("%s can't lay eggs!",
                  Hallucination
                      ? "You may think you are a platypus, but a male still"
                      : "Males");
#else
            pline("%s雄は卵を産めない!",
                  Hallucination
                      ? "あなたは自分がカモノハシだと思っているかもしれないが,やっぱり"
                      : "");
#endif
            return 0;
        } else if (u.uhunger < (int) objects[EGG].oc_nutrition) {
/*JP
            You("don't have enough energy to lay an egg.");
*/
            You("卵を産むだけのエネルギーがない.");
            return 0;
        }

        uegg = mksobj(EGG, FALSE, FALSE);
        uegg->spe = 1;
        uegg->quan = 1L;
        uegg->owt = weight(uegg);
        /* this sets hatch timers if appropriate */
        set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE));
        uegg->known = uegg->dknown = 1;
/*JP
        You("lay an egg.");
*/
        You("卵を産んだ.");
        dropy(uegg);
        stackobj(uegg);
        morehungry((int) objects[EGG].oc_nutrition);
    } else {
/*JP
        pline("Having fun sitting on the %s?", surface(u.ux, u.uy));
*/
        pline("%sに座って楽しいかい?", surface(u.ux,u.uy));
    }
    return 1;
}
예제 #25
0
void
invault(void)
{
    struct monst *guard;
    int trycount, vaultroom = (int)vault_occupied(u.urooms);
    boolean messages = TRUE;

    if (!vaultroom) {
        u.uinvault = 0;
        return;
    }

    vaultroom -= ROOMOFFSET;

    guard = findgd();
    if (++u.uinvault % 30 == 0 && !guard) {  /* if time ok and no guard now. */
        int x, y, gx, gy;
        xchar rx, ry;
        long umoney;
        const char *buf;

        /* first find the goal for the guard */
        if (!find_guard_dest(NULL, &rx, &ry))
            return;
        gx = rx;
        gy = ry;

        /* next find a good place for a door in the wall */
        x = u.ux;
        y = u.uy;
        if (level->locations[x][y].typ != ROOM) {       /* player dug a door
                                                           and is in it */
            if (level->locations[x + 1][y].typ == ROOM)
                x = x + 1;
            else if (level->locations[x][y + 1].typ == ROOM)
                y = y + 1;
            else if (level->locations[x - 1][y].typ == ROOM)
                x = x - 1;
            else if (level->locations[x][y - 1].typ == ROOM)
                y = y - 1;
            else if (level->locations[x + 1][y + 1].typ == ROOM) {
                x = x + 1;
                y = y + 1;
            } else if (level->locations[x - 1][y - 1].typ == ROOM) {
                x = x - 1;
                y = y - 1;
            } else if (level->locations[x + 1][y - 1].typ == ROOM) {
                x = x + 1;
                y = y - 1;
            } else if (level->locations[x - 1][y + 1].typ == ROOM) {
                x = x - 1;
                y = y + 1;
            }
        }
        while (level->locations[x][y].typ == ROOM) {
            int dx, dy;

            dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
            dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
            if (abs(gx - x) >= abs(gy - y))
                x += dx;
            else
                y += dy;
        }
        if (x == u.ux && y == u.uy) {
            if (level->locations[x + 1][y].typ == HWALL ||
                level->locations[x + 1][y].typ == DOOR)
                x = x + 1;
            else if (level->locations[x - 1][y].typ == HWALL ||
                     level->locations[x - 1][y].typ == DOOR)
                x = x - 1;
            else if (level->locations[x][y + 1].typ == VWALL ||
                     level->locations[x][y + 1].typ == DOOR)
                y = y + 1;
            else if (level->locations[x][y - 1].typ == VWALL ||
                     level->locations[x][y - 1].typ == DOOR)
                y = y - 1;
            else
                return;
        }

        /* make something interesting happen */
        if (!(guard = makemon(&mons[PM_GUARD], level, x, y, NO_MM_FLAGS)))
            return;
        guard->isgd = 1;
        msethostility(guard, FALSE, TRUE);
        EGD(guard)->gddone = 0;
        EGD(guard)->ogx = x;
        EGD(guard)->ogy = y;
        assign_level(&(EGD(guard)->gdlevel), &u.uz);
        EGD(guard)->vroom = vaultroom;
        EGD(guard)->warncnt = 0;

        /* We used to reset fainted status here, but that doesn't really make
           sense; instead, that's treated like normal helplessness */
        if (canspotmon(guard))
            pline("Suddenly one of the Vault's guards enters!");
        else if (canhear())
            You_hear("someone else enter the Vault.");
        else
            messages = FALSE;

        newsym(guard->mx, guard->my);
        if (youmonst.m_ap_type == M_AP_OBJECT || u.uundetected || u.uburied) {
            if (youmonst.m_ap_type == M_AP_OBJECT &&
                youmonst.mappearance != GOLD_PIECE)
                verbalize("Hey! Who left that %s in here?",
                          mimic_obj_name(&youmonst));
            /* You're mimicking some object or you're hidden. */
            if (messages)
                pline("Puzzled, %s turns around and leaves.", mhe(guard));
            mongone(guard);
            return;
        }
        if (Engulfed) {
            if ((!u.ustuck->minvis || perceives(guard->data)))
                verbalize("How did that %s get in here?", m_monnam(u.ustuck));
            if (messages)
                pline("Puzzled, %s turns around and leaves.", mhe(guard));
            mongone(guard);
            return;
        }
        if (Strangled || is_silent(youmonst.data) || u_helpless(hm_all)) {
            /* [we ought to record whether this this message has already been
               given in order to vary it upon repeat visits, but discarding the 
               monster and its egd data renders that hard] */
            verbalize("I'll be back when you're ready to speak to me!");
            mongone(guard);
            return;
        }

        action_interrupted();

        trycount = 5;
        do {
            buf = getlin("\"Hello stranger, who are you?\" -", FALSE);
            buf = msgmungspaces(buf);
        } while (!letter(buf[0]) && --trycount > 0);

        if (u.ualign.type == A_LAWFUL &&
            /* ignore trailing text, in case player includes character's rank */
            strncmpi(buf, u.uplname, (int)strlen(u.uplname)) != 0) {
            adjalign(-1);       /* Liar! */
        }

        if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos") ||
            !strcmpi(buf, "Creosote")) {
            if (!mvitals[PM_CROESUS].died) {
                verbalize("Oh, yes, of course.  Sorry to have disturbed you.");
                mongone(guard);
            } else {
                setmangry(guard);
                verbalize("Back from the dead, are you?  I'll remedy that!");
                /* don't want guard to waste next turn wielding a weapon */
                if (!MON_WEP(guard)) {
                    guard->weapon_check = NEED_HTH_WEAPON;
                    mon_wield_item(guard);
                }
            }
            return;
        }
        verbalize("I don't know you.");
        umoney = money_cnt(invent);
        if (!umoney && !hidden_gold())
            verbalize("Please follow me.");
        else {
            if (!umoney)
                verbalize("You have hidden money.");
            verbalize("Most likely all your money was stolen from this vault.");
            verbalize("Please drop that money and follow me.");
        }

        EGD(guard)->gdx = gx;
        EGD(guard)->gdy = gy;
        EGD(guard)->fcbeg = 0;
        EGD(guard)->fakecorr[0].fx = x;
        EGD(guard)->fakecorr[0].fy = y;
        if (IS_WALL(level->locations[x][y].typ))
            EGD(guard)->fakecorr[0].ftyp = level->locations[x][y].typ;
        else {  /* the initial guard location is a dug door */
            int vlt = EGD(guard)->vroom;
            xchar lowx = level->rooms[vlt].lx, hix = level->rooms[vlt].hx;
            xchar lowy = level->rooms[vlt].ly, hiy = level->rooms[vlt].hy;

            if (x == lowx - 1 && y == lowy - 1)
                EGD(guard)->fakecorr[0].ftyp = TLCORNER;
            else if (x == hix + 1 && y == lowy - 1)
                EGD(guard)->fakecorr[0].ftyp = TRCORNER;
            else if (x == lowx - 1 && y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = BLCORNER;
            else if (x == hix + 1 && y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = BRCORNER;
            else if (y == lowy - 1 || y == hiy + 1)
                EGD(guard)->fakecorr[0].ftyp = HWALL;
            else if (x == lowx - 1 || x == hix + 1)
                EGD(guard)->fakecorr[0].ftyp = VWALL;
        }
        level->locations[x][y].typ = DOOR;
        level->locations[x][y].doormask = D_NODOOR;
        unblock_point(x, y);    /* doesn't block light */
        EGD(guard)->fcend = 1;
        EGD(guard)->warncnt = 1;
    }
}