Пример #1
0
char *Adjmonnam(const struct monst *mtmp, const char *adj)
{
	char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
		mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE);

	*bp = highc(*bp);
	return bp;
}
Пример #2
0
char *coyotename(const struct monst *mtmp, char *buf)
{
    if (mtmp && buf) {
	sprintf(buf, "%s - %s",
	    x_monnam(mtmp, ARTICLE_NONE, NULL, 0, TRUE),
	    mtmp->mcan ? coynames[SIZE(coynames)-1] : coynames[display_rng(SIZE(coynames)-1)]);
    }
    return buf;
}
Пример #3
0
/* pet name: "your little dog" */
char *y_monnam(const struct monst *mtmp)
{
	int prefix, suppression_flag;

	prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
	/* "saddled" is redundant when mounted */
	suppression_flag = (mtmp->mnamelth || mtmp == u.usteed) ? SUPPRESS_SADDLE : 0;

	return x_monnam(mtmp, prefix, NULL, suppression_flag, FALSE);
}
Пример #4
0
/* article: only ARTICLE_NONE and ARTICLE_THE are handled here */
char *distant_monnam(const struct monst *mon, int article, char *outbuf)
{
    /* high priest(ess)'s identity is concealed on the Astral Plane,
       unless you're adjacent (overridden for hallucination which does
       its own obfuscation) */
    if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination &&
	    Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
	strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
	strcat(outbuf, mon->female ? "high priestess" : "high priest");
    } else {
	strcpy(outbuf, x_monnam(mon, article, NULL, 0, TRUE));
    }
    return outbuf;
}
Пример #5
0
static size_t g_monnam(char *out_buf, int buf_size, struct monst * mtmp) {
    return x_monnam(out_buf, buf_size, mtmp, ARTICLE_NONE, (char *)0, SUPPRESS_IT, false);
}
Пример #6
0
/* Generate earthquake :-) of desired force. That is: create random chasms
   (pits). Currently assumes that the player created it (you'll need to change
   at least messages, angering, and kill credit if you generalize it). */
static void
do_earthquake(int force)
{
    int x, y;
    struct monst *mtmp;
    struct obj *otmp;
    struct trap *chasm, *oldtrap;
    int start_x, start_y, end_x, end_y;

    start_x = youmonst.mx - (force * 2);
    start_y = youmonst.my - (force * 2);
    end_x = youmonst.mx + (force * 2);
    end_y = youmonst.my + (force * 2);
    if (start_x < 0)
        start_x = 0;
    if (start_y < 0)
        start_y = 0;
    if (end_x >= COLNO)
        end_x = COLNO - 1;
    if (end_y >= ROWNO)
        end_y = ROWNO - 1;
    for (x = start_x; x <= end_x; x++)
        for (y = start_y; y <= end_y; y++) {
            if ((mtmp = m_at(level, x, y)) != 0) {
                wakeup(mtmp, FALSE);  /* peaceful monster will become hostile */
                if (mtmp->mundetected && is_hider(mtmp->data)) {
                    mtmp->mundetected = 0;
                    if (cansee(x, y))
                        pline(msgc_youdiscover, "%s is shaken loose from %s!",
                              Amonnam(mtmp), mtmp->data == &mons[PM_TRAPPER] ?
                              "its hiding place" : the(ceiling(youmonst.mx, youmonst.my)));
                    else
                        You_hear(msgc_levelsound, "a thumping sound.");
                    if (x == youmonst.mx && y == youmonst.my &&
                        mtmp->data != &mons[PM_TRAPPER])
                        pline(msgc_moncombatgood,
                              "You easily dodge the falling %s.",
                              mon_nam(mtmp));
                    newsym(x, y);
                }
            }
            if (!rn2(14 - force))
                switch (level->locations[x][y].typ) {
                case FOUNTAIN: /* Make the fountain disappear */
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The fountain falls into a chasm.");
                    goto do_pit;
                case SINK:
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The kitchen sink falls into a chasm.");
                    goto do_pit;
                case ALTAR:
                    if (level->locations[x][y].altarmask & AM_SANCTUM)
                        break;

                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The altar falls into a chasm.");
                    goto do_pit;
                case GRAVE:
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The headstone topples into a chasm.");
                    goto do_pit;
                case THRONE:
                    if (cansee(x, y))
                        pline(msgc_consequence,
                              "The throne falls into a chasm.");
                    /* Falls into next case */
                case ROOM:
                case CORR:     /* Try to make a pit */
                    /* Pits, spiked pits, holes, trapdoors, vibrating squares,
                       magic portals are immune.  A bear trap will leave the
                       trap in the pit.  It would be kind of cool to make
                       landmines detonate, but that's more trouble than it's
                       worth. */
                    if ((oldtrap = t_at(level, x, y))) {
                        if (oldtrap->ttyp == PIT || oldtrap->ttyp == SPIKED_PIT
                            || oldtrap->ttyp == HOLE ||
                            oldtrap->ttyp == TRAPDOOR ||
                            oldtrap->ttyp == VIBRATING_SQUARE ||
                            oldtrap->ttyp == MAGIC_PORTAL)
                            break;

                        if (oldtrap->ttyp == BEAR_TRAP) {
                            if (mtmp)
                                mtmp->mtrapped = 0;
                            cnv_trap_obj(level, BEARTRAP, 1, oldtrap);
                        }
                    }

                do_pit:
                    chasm = maketrap(level, x, y, PIT, rng_main);
                    if (!chasm)
                        break;  /* no pit if portal at that location */
                    chasm->tseen = 1;

                    level->locations[x][y].doormask = 0;

                    mtmp = m_at(level, x, y);

                    if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) {
                        if (cansee(x, y))
                            pline(msgc_consequence,
                                  "KADOOM! The boulder falls into a chasm%s!",
                                  ((x == youmonst.mx) &&
                                   (y == youmonst.my)) ? " below you" : "");
                        if (mtmp)
                            mtmp->mtrapped = 0;
                        obj_extract_self(otmp);
                        flooreffects(otmp, x, y, "");
                        break;
                    }

                    /* We have to check whether monsters or player falls in a
                       chasm... */

                    if (mtmp) {
                        if (!flying(mtmp) && !levitates(mtmp) &&
                            !is_clinger(mtmp->data)) {
                            mtmp->mtrapped = 1;
                            if (cansee(x, y))
                                pline(combat_msgc(&youmonst, mtmp, cr_hit),
                                      "%s falls into a chasm!", Monnam(mtmp));
                            else if (humanoid(mtmp->data))
                                You_hear(msgc_levelsound, "a scream!");
                            mselftouch(mtmp, "Falling, ", &youmonst);
                            if (!DEADMONSTER(mtmp))
                                if ((mtmp->mhp -= rnd(6)) <= 0) {
                                    if (!cansee(x, y))
                                        pline(msgc_kill, "It is destroyed!");
                                    else {
                                        pline(msgc_petfatal, "You destroy %s!",
                                              mtmp->mtame ?
                                              x_monnam(mtmp, ARTICLE_THE,
                                                       "poor", mx_name(mtmp) ?
                                                       SUPPRESS_SADDLE : 0,
                                                       FALSE) : mon_nam(mtmp));
                                    }
                                    xkilled(mtmp, 0);
                                }
                        }
                    } else if (!u.utrap && x == youmonst.mx && y == youmonst.my) {
                        if (Levitation || Flying || is_clinger(youmonst.data)) {
                            pline(msgc_noconsequence,
                                  "A chasm opens up under you!");
                            pline(msgc_noconsequence, "You don't fall in!");
                        } else {
                            pline(msgc_badidea, "You fall into a chasm!");
                            u.utrap = rn1(6, 2);
                            u.utraptype = TT_PIT;
                            turnstate.vision_full_recalc = TRUE;
                            losehp(rnd(6), "fell into a chasm");
                            selftouch("Falling, you",
                                      "falling into a chasm while wielding");
                        }
                    } else
                        newsym(x, y);
                    break;
                case DOOR:     /* Make the door collapse */
                    if (level->locations[x][y].doormask == D_NODOOR)
                        goto do_pit;
                    if (cansee(x, y))
                        pline(msgc_consequence, "The door collapses.");
                    if (*in_rooms(level, x, y, SHOPBASE))
                        add_damage(x, y, 0L);
                    level->locations[x][y].doormask = D_NODOOR;
                    unblock_point(x, y);
                    newsym(x, y);
                    break;
                }
        }
}
Пример #7
0
void
mstatusline(struct monst *mtmp)
{
    aligntyp alignment;
    const char *info, *monnambuf;

    if (mtmp->ispriest || (mtmp->isminion && roamer_type(mtmp->data)))
        alignment = CONST_EPRI(mtmp)->shralign;
    else if (mtmp->isminion)
        alignment = EMIN(mtmp)->min_align;
    else {
        alignment = mtmp->data->maligntyp;
        alignment =
            (alignment > 0) ? A_LAWFUL :
            (alignment == A_NONE) ? A_NONE :
            (alignment < 0) ? A_CHAOTIC : A_NEUTRAL;
    }

    info = "";
    if (mtmp->mtame) {
        info = msgcat(info, ", tame");
        if (wizard) {
            info = msgprintf("%s (%d", info, mtmp->mtame);
            if (!mtmp->isminion)
                info = msgprintf("%s; hungry %u; apport %d", info,
                                 EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
            info = msgcat(info, ")");
        }
    } else if (mtmp->mpeaceful)
        info = msgcat(info, ", peaceful");
    if (mtmp->meating)
        info = msgcat(info, ", eating");
    if (mtmp->mcan)
        info = msgcat(info, ", cancelled");
    if (mtmp->mconf)
        info = msgcat(info, ", confused");
    if (mtmp->mblinded || !mtmp->mcansee)
        info = msgcat(info, ", blind");
    if (mtmp->mstun)
        info = msgcat(info, ", stunned");
    if (mtmp->msleeping)
        info = msgcat(info, ", asleep");
    else if (mtmp->mfrozen || !mtmp->mcanmove)
        info = msgcat(info, ", can't move");
    /* [arbitrary reason why it isn't moving] */
    else if (mtmp->mstrategy & STRAT_WAITMASK)
        info = msgcat(info, ", meditating");
    else if (mtmp->mflee)
        info = msgcat(info, ", scared");
    if (mtmp->mtrapped)
        info = msgcat(info, ", trapped");
    if (mtmp->mspeed)
        info = msgcat(info,
                      mtmp->mspeed == MFAST ? ", fast" :
                      mtmp->mspeed == MSLOW ? ", slow" : ", ???? speed");
    if (mtmp->mundetected)
        info = msgcat(info, ", concealed");
    if (mtmp->minvis)
        info = msgcat(info, ", invisible");
    if (mtmp == u.ustuck)
        info = msgcat(info,
                      (sticks(youmonst.data)) ? ", held by you" : Engulfed
                      ? (is_animal(u.ustuck->data) ? ", swallowed you" :
                         ", engulfed you") : ", holding you");
    if (mtmp == u.usteed)
        info = msgcat(info, ", carrying you");

    /* avoid "Status of the invisible newt ..., invisible" */
    /* and unlike a normal mon_nam, use "saddled" even if it has a name */
    monnambuf = x_monnam(mtmp, ARTICLE_THE, NULL,
                         (SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE);

    pline("Status of %s (%s):  Level %d  HP %d(%d)  Def %d%s.", monnambuf,
          align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax,
          10 - find_mac(mtmp), info);
}
Пример #8
0
/* Start riding, with the given monster */
boolean
mount_steed(struct monst * mtmp,        /* The animal */
            boolean force)
{   /* Quietly force this animal */
    struct obj *otmp;
    const struct permonst *ptr;

    /* Sanity checks */
    if (u.usteed) {
        pline("You are already riding %s.", mon_nam(u.usteed));
        return FALSE;
    }

    /* Is the player in the right form? */
    if (Hallucination && !force) {
        pline("Maybe you should find a designated driver.");
        return FALSE;
    }
    /* While riding Wounded_legs refers to the steed's, not the hero's legs.
       That opens up a potential abuse where the player can mount a steed, then
       dismount immediately to heal leg damage, because leg damage is always
       healed upon dismount (Wounded_legs context switch). By preventing a hero
       with Wounded_legs from mounting a steed, the potential for abuse is
       minimized, if not eliminated altogether. */
    if (Wounded_legs) {
        pline("Your %s are in no shape for riding.",
              makeplural(body_part(LEG)));
        if (force && wizard && yn("Heal your legs?") == 'y')
            LWounded_legs = RWounded_legs = 0;
        else
            return FALSE;
    }

    if (Upolyd &&
            (!humanoid(youmonst.data) || verysmall(youmonst.data) ||
             bigmonst(youmonst.data) || slithy(youmonst.data))) {
        pline("You won't fit on a saddle.");
        return FALSE;
    }
    if (!force && (near_capacity() > SLT_ENCUMBER)) {
        pline("You can't do that while carrying so much stuff.");
        return FALSE;
    }

    /* Can the player reach and see the monster? */
    if (!mtmp ||
            (!force &&
             ((Blind && !Blind_telepat) || mtmp->mundetected ||
              mtmp->m_ap_type == M_AP_FURNITURE ||
              mtmp->m_ap_type == M_AP_OBJECT))) {
        pline("I see nobody there.");
        return FALSE;
    }

    struct test_move_cache cache;
    init_test_move_cache(&cache);

    if (Engulfed || u.ustuck || u.utrap || Punished ||
            !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy, 0,
                       TEST_MOVE, &cache)) {
        if (Punished || !(Engulfed || u.ustuck || u.utrap))
            pline("You are unable to swing your %s over.", body_part(LEG));
        else
            pline("You are stuck here for now.");
        return FALSE;
    }

    /* Is this a valid monster? */
    otmp = which_armor(mtmp, os_saddle);
    if (!otmp) {
        pline("%s is not saddled.", Monnam(mtmp));
        return FALSE;
    }
    ptr = mtmp->data;
    if (touch_petrifies(ptr) && !Stone_resistance) {
        pline("You touch %s.", mon_nam(mtmp));
        instapetrify(killer_msg(STONING,
                                msgcat("attempting to ride ", an(mtmp->data->mname))));
    }
    if (!mtmp->mtame || mtmp->isminion) {
        pline("I think %s would mind.", mon_nam(mtmp));
        return FALSE;
    }
    if (mtmp->mtrapped) {
        struct trap *t = t_at(level, mtmp->mx, mtmp->my);

        pline("You can't mount %s while %s's trapped in %s.", mon_nam(mtmp),
              mhe(mtmp), t ? an(trapexplain[t->ttyp - 1]) : "ice");
        return FALSE;
    }

    if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) {
        /* no longer tame */
        newsym(mtmp->mx, mtmp->my);
        pline("%s resists%s!", Monnam(mtmp),
              mtmp->mleashed ? " and its leash comes off" : "");
        if (mtmp->mleashed)
            m_unleash(mtmp, FALSE);
        return FALSE;
    }
    if (!force && Underwater && !is_swimmer(ptr)) {
        pline("You can't ride that creature while under water.");
        return FALSE;
    }
    if (!can_saddle(mtmp) || !can_ride(mtmp)) {
        pline("You can't ride such a creature.");
        return 0;
    }

    /* Is the player impaired? */
    if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation &&
            !Lev_at_will) {
        pline("You cannot reach %s.", mon_nam(mtmp));
        return FALSE;
    }
    if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) {
        pline("Your %s armor is too stiff to be able to mount %s.",
              uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp));
        return FALSE;
    }
    if (!force &&
            (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed ||
             ((u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)) &&
              (!Role_if(PM_KNIGHT))))) {
        if (Levitation) {
            pline("%s slips away from you.", Monnam(mtmp));
            return FALSE;
        }
        pline("You slip while trying to get on %s.", mon_nam(mtmp));

        const char *buf = msgcat(
                              "slipped while mounting ",
                              /* "a saddled mumak" or "a saddled pony called Dobbin" */
                              x_monnam(mtmp, ARTICLE_A, NULL,
                                       SUPPRESS_IT | SUPPRESS_INVISIBLE |
                                       SUPPRESS_HALLUCINATION, TRUE));
        losehp(rn1(5, 10), buf);
        return FALSE;
    }

    /* Success */
    maybewakesteed(mtmp);
    if (!force) {
        if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
            /* Must have Lev_at_will at this point */
            pline("%s magically floats up!", Monnam(mtmp));
        pline("You mount %s.", mon_nam(mtmp));
    }
    /* setuwep handles polearms differently when you're mounted */
    if (uwep && is_pole(uwep))
        u.bashmsg = TRUE;
    u.usteed = mtmp;
    remove_monster(level, mtmp->mx, mtmp->my);
    teleds(mtmp->mx, mtmp->my, TRUE);
    return TRUE;
}
Пример #9
0
char *a_monnam(const struct monst *mtmp)
{
	return x_monnam(mtmp, ARTICLE_A, NULL,
		mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE);
}
Пример #10
0
/* monster's own name */
char *m_monnam(const struct monst *mtmp)
{
	return x_monnam(mtmp, ARTICLE_NONE, NULL, EXACT_NAME, FALSE);
}
Пример #11
0
/* print the name as if mon_nam() was called, but assume that the player
 * can always see the monster--used for probing and for monsters aggravating
 * the player with a cursed potion of invisibility
 */
char *noit_mon_nam(const struct monst *mtmp)
{
	return(x_monnam(mtmp, ARTICLE_THE, NULL,
		mtmp->mnamelth ? (SUPPRESS_SADDLE|SUPPRESS_IT) :
		    SUPPRESS_IT, FALSE));
}
Пример #12
0
char *mon_nam(const struct monst *mtmp)
{
	return(x_monnam(mtmp, ARTICLE_THE, NULL,
		mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE));
}
Пример #13
0
char *l_monnam(const struct monst *mtmp)
{
	return(x_monnam(mtmp, ARTICLE_NONE, NULL, 
		mtmp->mnamelth ? SUPPRESS_SADDLE : 0, TRUE));
}