Example #1
0
static void
describe_mon(int x, int y, int monnum, char *buf)
{
    char race[QBUFSZ];
    const char *name;
    boolean accurate = !Hallucination;
    char steedbuf[BUFSZ];
    struct monst *mtmp;
    char visionbuf[BUFSZ], temp_buf[BUFSZ];

    static const int maximum_output_len = 78;

    if (monnum == -1)
        return;

    if (u.ux == x && u.uy == y && senseself()) {
        /* if not polymorphed, show both the role and the race */
        race[0] = 0;
        if (!Upolyd)
            snprintf(race, SIZE(race), "%s ", urace.adj);

        sprintf(buf, "%s%s%s called %s", Invis ? "invisible " : "", race,
                mons[u.umonnum].mname, u.uplname);

        if (u.usteed) {
            snprintf(steedbuf, SIZE(steedbuf), ", mounted on %s", y_monnam(u.usteed));
            /* assert((sizeof buf >= strlen(buf)+strlen(steedbuf)+1); */
            strcat(buf, steedbuf);
        }
        /* When you see yourself normally, no explanation is appended (even if
           you could also see yourself via other means). Sensing self while
           blind or swallowed is treated as if it were by normal vision (cf
           canseeself()). */
        if ((Invisible || u.uundetected) && !Blind && !Engulfed) {
            unsigned how = 0;

            if (Infravision)
                how |= 1;
            if (Unblind_telepat)
                how |= 2;
            if (Detect_monsters)
                how |= 4;

            if (how)
                sprintf(buf + strlen(buf), " [seen: %s%s%s%s%s]",
                        (how & 1) ? "infravision" : "",
                        /* add comma if telep and infrav */
                        ((how & 3) > 2) ? ", " : "",
                        (how & 2) ? "telepathy" : "",
                        /* add comma if detect and (infrav or telep or both) */
                        ((how & 7) > 4) ? ", " : "",
                        (how & 4) ? "monster detection" : "");
        }

    } else if (monnum >= NUMMONS) {
        monnum -= NUMMONS;
        if (monnum < WARNCOUNT)
            strcat(buf, warnexplain[monnum]);

    } else if ((mtmp = m_at(level, x, y))) {
        bhitpos.x = x;
        bhitpos.y = y;

        if (mtmp->data == &mons[PM_COYOTE] && accurate && !mtmp->mpeaceful)
            name = an(coyotename(mtmp));
        else
            name = distant_monnam(
                mtmp, (mtmp->mtame && accurate) ? "tame" :
                (mtmp->mpeaceful && accurate) ? "peaceful" : NULL,
                ARTICLE_A);

        boolean spotted = canspotmon(mtmp);

        if (!spotted && (mtmp->mx != x || mtmp->my != y))
            name = "an unseen long worm";
        else if (!spotted)
            /* we can't safely impossible/panic from this point in the code;
               well, we /could/, but as it's called on every mouse movement,
               it'd quickly get very confusing and possibly lead to recursive
               panics; just put up an obvious message instead */
            name = "a <BUG: monster both seen and unseen>";

        snprintf(buf, BUFSZ-1, "%s%s",
                (mtmp->mx != x || mtmp->my != y) ? "tail of " : "", name);
        buf[BUFSZ-1] = '\0';
        if (u.ustuck == mtmp)
            strcat(buf,
                   (Upolyd &&
                    sticks(youmonst.data)) ? ", being held" : ", holding you");
        if (mtmp->mleashed)
            strcat(buf, ", leashed to you");

        if (mtmp->mtrapped && cansee(mtmp->mx, mtmp->my)) {
            struct trap *t = t_at(level, mtmp->mx, mtmp->my);
            int tt = t ? t->ttyp : NO_TRAP;

            /* newsym lets you know of the trap, so mention it here */
            if (tt == BEAR_TRAP || tt == PIT || tt == SPIKED_PIT || tt == WEB)
                sprintf(buf + strlen(buf),
                        ", trapped in %s", an(trapexplain[tt - 1]));
        }

#ifdef DEBUG_STRATEGY
        if (wizard) {
            snprintf(temp_buf, SIZE(temp_buf),
                     ", strategy %08lx, muxy %02x%02x",
                     (unsigned long)mtmp->mstrategy,
                     (int)mtmp->mux, (int)mtmp->muy);
            strncat(buf, temp_buf, maximum_output_len - strlen(buf) - 1);
        }
#endif

        /* Don't mention how a long worm tail is seen; msensem() only works on
           monster heads. (Probably, the only unusual way to see a long worm
           tail is see invisible, anyway.) */
        if (mtmp->mx == x && mtmp->my == y) {
            mon_vision_summary(mtmp, visionbuf);
            if (visionbuf[0]) {
                snprintf(temp_buf, SIZE(temp_buf), " [seen: %s]", visionbuf);
                strncat(buf, temp_buf, maximum_output_len - strlen(buf) - 1);
            }
        }
    }
}
Example #2
0
static void describe_mon(int x, int y, int monnum, char *buf)
{
    char race[QBUFSZ];
    char *name, monnambuf[BUFSZ];
    boolean accurate = !Hallucination;
    char steedbuf[BUFSZ];
    struct monst *mtmp;
    char visionbuf[BUFSZ], temp_buf[BUFSZ];
    
    if (monnum == -1)
	return;
    
    if (u.ux == x && u.uy == y && senseself()) {
	/* if not polymorphed, show both the role and the race */
	race[0] = 0;
	if (!Upolyd)
	    sprintf(race, "%s ", urace.adj);

	sprintf(buf, "%s%s%s called %s",
		Invis ? "invisible " : "",
		race,
		mons[u.umonnum].mname,
		plname);
	
	if (u.usteed) {
	    sprintf(steedbuf, ", mounted on %s", y_monnam(u.usteed));
	    /* assert((sizeof buf >= strlen(buf)+strlen(steedbuf)+1); */
	    strcat(buf, steedbuf);
	}
	/* When you see yourself normally, no explanation is appended
	(even if you could also see yourself via other means).
	Sensing self while blind or swallowed is treated as if it
	were by normal vision (cf canseeself()). */
	if ((Invisible || u.uundetected) && !Blind && !u.uswallow) {
	    unsigned how = 0;

	    if (Infravision)	 how |= 1;
	    if (Unblind_telepat) how |= 2;
	    if (Detect_monsters) how |= 4;

	    if (how)
		sprintf(eos(buf), " [seen: %s%s%s%s%s]",
			(how & 1) ? "infravision" : "",
			/* add comma if telep and infrav */
			((how & 3) > 2) ? ", " : "",
			(how & 2) ? "telepathy" : "",
			/* add comma if detect and (infrav or telep or both) */
			((how & 7) > 4) ? ", " : "",
			(how & 4) ? "monster detection" : "");
	}
	
    } else if (monnum >= NUMMONS) {
	monnum -= NUMMONS;
	if (monnum < WARNCOUNT)
	    strcat(buf, warnexplain[monnum]);
	
    } else if ( (mtmp = m_at(level, x,y)) ) {
	bhitpos.x = x;
	bhitpos.y = y;

	if (mtmp->data == &mons[PM_COYOTE] && accurate)
	    name = coyotename(mtmp, monnambuf);
	else
	    name = distant_monnam(mtmp, ARTICLE_NONE, monnambuf);

	sprintf(buf, "%s%s%s",
		(mtmp->mx != x || mtmp->my != y) ?
		    ((mtmp->isshk && accurate)
			    ? "tail of " : "tail of a ") : "",
		(mtmp->mtame && accurate) ? "tame " :
		(mtmp->mpeaceful && accurate) ? "peaceful " : "",
		name);
	if (u.ustuck == mtmp)
	    strcat(buf, (Upolyd && sticks(youmonst.data)) ?
		    ", being held" : ", holding you");
	if (mtmp->mleashed)
	    strcat(buf, ", leashed to you");

	if (mtmp->mtrapped && cansee(mtmp->mx, mtmp->my)) {
	    struct trap *t = t_at(level, mtmp->mx, mtmp->my);
	    int tt = t ? t->ttyp : NO_TRAP;

	    /* newsym lets you know of the trap, so mention it here */
	    if (tt == BEAR_TRAP || tt == PIT ||
		    tt == SPIKED_PIT || tt == WEB)
		sprintf(eos(buf), ", trapped in %s", an(trapexplain[tt]));
	}

	mon_vision_summary(mtmp, visionbuf);
	if (visionbuf[0]) {
	    sprintf(temp_buf, " [seen: %s]", visionbuf);
	    strncat(buf, temp_buf, BUFSZ-strlen(buf)-1);
	}
    }
}