예제 #1
0
/* the sounds of distressed pets */
void
whimper(struct monst *mtmp)
{
    const char *whimper_verb = 0;

    if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound ||
        !canhear())
        return;

    /* presumably nearness checks have already been made */
    if (Hallucination)
        whimper_verb = h_sounds[rn2(SIZE(h_sounds))];
    else
        switch (mtmp->data->msound) {
        case MS_MEW:
        case MS_GROWL:
            whimper_verb = "whimper";
            break;
        case MS_BARK:
            whimper_verb = "whine";
            break;
        case MS_SQEEK:
            whimper_verb = "squeal";
            break;
        }
    if (whimper_verb) {
        pline("%s %s.", Monnam(mtmp), vtense(NULL, whimper_verb));
        action_interrupted();
        wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 6);
    }
}
예제 #2
0
파일: dbridge.c 프로젝트: FredrIQ/nhfourk
/*
 * Close the drawbridge located at x,y
 */
void
close_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    int x2, y2;

    loc1 = &level->locations[x][y];
    if (loc1->typ != DRAWBRIDGE_DOWN)
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    if (cansee(x, y) || cansee(x2, y2))
        pline("You see a drawbridge %s up!",
              (((u.ux == x || u.uy == y) && !Underwater) ||
               distu(x2, y2) < distu(x, y)) ? "coming" : "going");
    else if (canhear())
        pline("You hear chains rattling and gears turning.");
    loc1->typ = DRAWBRIDGE_UP;
    loc2 = &level->locations[x2][y2];
    loc2->typ = DBWALL;
    switch (loc1->drawbridgemask & DB_DIR) {
    case DB_NORTH:
    case DB_SOUTH:
        loc2->horizontal = TRUE;
        break;
    case DB_WEST:
    case DB_EAST:
        loc2->horizontal = FALSE;
        break;
    }
    loc2->wall_info = W_NONDIGGABLE;
    set_entity(x, y, &(occupants[0]));
    set_entity(x2, y2, &(occupants[1]));
    do_entity(&(occupants[0])); /* Do set_entity after first */
    set_entity(x2, y2, &(occupants[1]));        /* do_entity for worm tail */
    do_entity(&(occupants[1]));
    if (OBJ_AT(x, y))
        You_hear("smashing and crushing.");
    revive_nasty(x, y, NULL);
    revive_nasty(x2, y2, NULL);
    delallobj(x, y);
    delallobj(x2, y2);
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    del_engr_at(level, x, y);
    del_engr_at(level, x2, y2);
    newsym(x, y);
    newsym(x2, y2);
    block_point(x2, y2);        /* vision */
}
예제 #3
0
/*VARARGS1*/
void
verbalize(const char *line, ...)
{
    va_list the_args;

    if (!canhear())
        return;

    va_start(the_args, line);
    vpline(FALSE, FALSE, msgcat_many("\"", line, "\"", NULL), the_args);
    va_end(the_args);
}
예제 #4
0
/*VARARGS1*/
void
You_hear(const char *line, ...)
{
    /* You can't hear while unconscious. */
    if (!canhear())
        return;

    va_list the_args;

    va_start(the_args, line);
    vpline(FALSE, FALSE, msgcat_many("You ", Underwater ? "barely " : "",
                                     "hear ", line, NULL), the_args);
    va_end(the_args);
}
예제 #5
0
파일: mthrowu.c 프로젝트: FredrIQ/nhfourk
int
breamq(struct monst *mtmp, int xdef, int ydef, const struct attack *mattk)
{
    /* if new breath types are added, change AD_ACID to max type */
    int typ = (mattk->adtyp == AD_RBRE) ? rnd(AD_ACID) : mattk->adtyp;

    boolean youdef = u.ux == xdef && u.uy == ydef;

    if (!youdef && distmin(mtmp->mx, mtmp->my, xdef, ydef) < 3)
        return 0;

    boolean linedup = qlined_up(mtmp, xdef, ydef, TRUE, FALSE);

    if (linedup) {
        if (mtmp->mcan) {
            if (canhear()) {
                if (mon_visible(mtmp))
                    pline("%s coughs.", Monnam(mtmp));
                else
                    You_hear("a cough.");
            }
            return 0;
        }
        if (!mtmp->mspec_used && rn2(3)) {
            if ((typ >= AD_MAGM) && (typ <= AD_ACID)) {
                if (mon_visible(mtmp)) {
                    pline("%s breathes %s!", Monnam(mtmp), breathwep[typ - 1]);
                    action_interrupted();
                }
                buzz((int)(-20 - (typ - 1)), (int)mattk->damn, mtmp->mx,
                     mtmp->my, sgn(tbx), sgn(tby), 0);
                /* breath runs out sometimes. Also, give monster some cunning;
                   don't breath if the target fell asleep. */
                if (!rn2(3))
                    mtmp->mspec_used = 10 + rn2(20);
                boolean sleeping = youdef ? u_helpless(hm_asleep) :
                    MON_AT(level, xdef, ydef) ?
                    m_at(level, xdef, ydef)->msleeping : FALSE;
                if (typ == AD_SLEE && sleeping)
                    mtmp->mspec_used += rnd(20);
            } else
                impossible("Breath weapon %d used", typ - 1);
        }
    }
    return 1;
}
예제 #6
0
/* the sounds of a seriously abused pet, including player attacking it */
void
growl(struct monst *mtmp)
{
    const char *growl_verb = 0;

    if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound ||
        !canhear())
        return;

    /* presumably nearness checks have already been made */
    if (Hallucination)
        growl_verb = h_sounds[rn2(SIZE(h_sounds))];
    else
        growl_verb = growl_sound(mtmp);
    if (growl_verb) {
        pline("%s %s!", Monnam(mtmp), vtense(NULL, growl_verb));
        action_interrupted();
        wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 18);
    }
}
예제 #7
0
파일: dbridge.c 프로젝트: FredrIQ/nhfourk
/*
 * Open the drawbridge located at x,y
 */
void
open_drawbridge(int x, int y)
{
    struct rm *loc1, *loc2;
    struct trap *t;
    int x2, y2;

    loc1 = &level->locations[x][y];
    if (loc1->typ != DRAWBRIDGE_UP)
        return;
    x2 = x;
    y2 = y;
    get_wall_for_db(&x2, &y2);
    if (cansee(x, y) || cansee(x2, y2))
        pline("You see a drawbridge %s down!",
              (distu(x2, y2) < distu(x, y)) ? "going" : "coming");
    else if (canhear())
        pline("You hear chains rattling and gears turning.");
    loc1->typ = DRAWBRIDGE_DOWN;
    loc2 = &level->locations[x2][y2];
    loc2->typ = DOOR;
    loc2->doormask = D_NODOOR;
    set_entity(x, y, &(occupants[0]));
    set_entity(x2, y2, &(occupants[1]));
    do_entity(&(occupants[0])); /* do set_entity after first */
    set_entity(x2, y2, &(occupants[1]));        /* do_entity for worm tails */
    do_entity(&(occupants[1]));
    revive_nasty(x, y, NULL);
    delallobj(x, y);
    if ((t = t_at(level, x, y)) != 0)
        deltrap(level, t);
    if ((t = t_at(level, x2, y2)) != 0)
        deltrap(level, t);
    del_engr_at(level, x, y);
    del_engr_at(level, x2, y2);
    newsym(x, y);
    newsym(x2, y2);
    unblock_point(x2, y2);      /* vision */
    if (Is_stronghold(&u.uz))
        u.uevent.uopened_dbridge = TRUE;
}
예제 #8
0
파일: mthrowu.c 프로젝트: FredrIQ/nhfourk
int
spitmq(struct monst *mtmp, int xdef, int ydef, const struct attack *mattk)
{
    struct obj *otmp;

    if (mtmp->mcan) {
        if (canhear())
            pline("A dry rattle comes from %s throat.",
                  s_suffix(mon_nam(mtmp)));
        return 0;
    }
    boolean linedup = qlined_up(mtmp, xdef, ydef, FALSE, FALSE);
    if (linedup && ai_use_at_range(
            BOLT_LIM - distmin(mtmp->mx, mtmp->my, xdef, ydef))) {
        switch (mattk->adtyp) {
        case AD_BLND:
        case AD_DRST:
            otmp = mktemp_sobj(level, BLINDING_VENOM);
            break;
        case AD_DRLI:
            otmp = mktemp_sobj(level, VAMPIRE_BLOOD);
            break;
        default:
            impossible("bad attack type in spitm");
            /* fall through */
        case AD_ACID:
            otmp = mktemp_sobj(level, ACID_VENOM);
            break;
        }

        if (mon_visible(mtmp)) {
            pline("%s spits venom!", Monnam(mtmp));
            action_interrupted();
        }
        m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
                distmin(mtmp->mx, mtmp->my, xdef, ydef), otmp,
                FALSE);
        return 1;
    }
    return 0;
}
예제 #9
0
/* the sounds of mistreated pets */
void
yelp(struct monst *mtmp)
{
    const char *yelp_verb = 0;

    if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound ||
        !canhear())
        return;

    /* presumably nearness checks have already been made */
    if (Hallucination)
        yelp_verb = h_sounds[rn2(SIZE(h_sounds))];
    else
        switch (mtmp->data->msound) {
        case MS_MEW:
            yelp_verb = "yowl";
            break;
        case MS_BARK:
        case MS_GROWL:
            yelp_verb = "yelp";
            break;
        case MS_ROAR:
            yelp_verb = "snarl";
            break;
        case MS_SQEEK:
            yelp_verb = "squeal";
            break;
        case MS_SQAWK:
            yelp_verb = "screak";
            break;
        case MS_WAIL:
            yelp_verb = "wail";
            break;
        }
    if (yelp_verb) {
        pline("%s %s!", Monnam(mtmp), vtense(NULL, yelp_verb));
        action_interrupted();
        wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 12);
    }
}
예제 #10
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;
}
예제 #11
0
void
dosounds(void)
{
    struct mkroom *sroom;
    int hallu, vx, vy;
    struct monst *mtmp;

    if (!canhear() || Engulfed || Underwater)
        return;

    hallu = Hallucination ? 1 : 0;

    if (has_terrain(level, FOUNTAIN) && !rn2(400)) {
        static const char *const fountain_msg[4] = {
            "bubbling water.",
            "water falling on coins.",
            "the splashing of a naiad.",
            "a soda fountain!",
        };
        You_hear("%s", fountain_msg[rn2(3) + hallu]);
    }

    if (has_terrain(level, SINK) && !rn2(300)) {
        static const char *const sink_msg[3] = {
            "a slow drip.",
            "a gurgling noise.",
            "dishes being washed!",
        };
        You_hear("%s", sink_msg[rn2(2) + hallu]);
    }

    if (search_special(level, COURT) && !rn2(200)) {
        static const char *const throne_msg[4] = {
            "the tones of courtly conversation.",
            "a sceptre pounded in judgment.",
            "Someone shouts \"Off with %s head!\"",
            "Queen Beruthiel's cats!",
        };
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if ((mtmp->msleeping || is_lord(mtmp->data) ||
                 is_prince(mtmp->data)) && !is_animal(mtmp->data) &&
                mon_in_room(mtmp, COURT)) {
                /* finding one is enough, at least for now */
                int which = rn2(3) + hallu;

                if (which != 2)
                    You_hear("%s", throne_msg[which]);
                else
                    pline(throne_msg[2], uhis());
                return;
            }
        }
    }
    if (search_special(level, SWAMP) && !rn2(200)) {
        static const char *const swamp_msg[3] = {
            "You hear mosquitoes!",
            "You smell marsh gas!",     /* so it's a smell... */
            "You hear Donald Duck!",
        };
        pline("%s", swamp_msg[rn2(2) + hallu]);
        return;
    }
    if ((sroom = search_special(level, VAULT)) && !rn2(200)) {
        if (gd_sound())
            switch (rn2(2) + hallu) {
            case 1:{
                    boolean gold_in_vault = FALSE;

                    for (vx = sroom->lx; vx <= sroom->hx; vx++)
                        for (vy = sroom->ly; vy <= sroom->hy; vy++)
                            if (gold_at(level, vx, vy))
                                gold_in_vault = TRUE;
                    if (vault_occupied(u.urooms) !=
                        (ROOM_INDEX(sroom) + ROOMOFFSET)) {
                        if (gold_in_vault)
                            You_hear(!hallu ? "someone counting money." :
                                     "the quarterback calling the play.");
                        else
                            You_hear("someone searching.");
                        break;
                    }
                    /* fall into... (yes, even for hallucination) */
                }
            case 0:
                You_hear("the footsteps of a guard on patrol.");
                break;
            case 2:
                You_hear("Ebenezer Scrooge!");
                break;
            }
        return;
    }
    if (search_special(level, BEEHIVE) && !rn2(200)) {
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if ((mtmp->data->mlet == S_ANT && is_flyer(mtmp->data)) &&
                mon_in_room(mtmp, BEEHIVE)) {
                switch (rn2(2) + hallu) {
                case 0:
                    You_hear("a low buzzing.");
                    break;
                case 1:
                    You_hear("an angry drone.");
                    break;
                case 2:
                    You_hear("bees in your %sbonnet!",
                             uarmh ? "" : "(nonexistent) ");
                    break;
                }
                return;
            }
        }
    }
    if (search_special(level, MORGUE) && !rn2(200)) {
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if (is_undead(mtmp->data) && mon_in_room(mtmp, MORGUE)) {
                switch (rn2(2) + hallu) {
                case 1:
                    if (!strcmp(body_part(HAIR), "hair")) {
                        pline("The %s on the back of your %s stands up.",
                              body_part(HAIR), body_part(NECK));
                        break;
                    }
                    /* fall through */
                case 2:
                    if (!strcmp(body_part(HAIR), "hair")) {
                        pline("The %s on your %s seems to stand up.",
                              body_part(HAIR), body_part(HEAD));
                        break;
                    }
                    /* fall through */
                case 0:
                    pline("You suddenly realize it is unnaturally quiet.");
                    break;
                }
                return;
            }
        }
    }
    if (search_special(level, BARRACKS) && !rn2(200)) {
        static const char *const barracks_msg[4] = {
            "blades being honed.",
            "loud snoring.",
            "dice being thrown.",
            "General MacArthur!",
        };
        int count = 0;

        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if (is_mercenary(mtmp->data) && mon_in_room(mtmp, BARRACKS) &&
                /* sleeping implies not-yet-disturbed (usually) */
                (mtmp->msleeping || ++count > 5)) {
                You_hear("%s", barracks_msg[rn2(3) + hallu]);
                return;
            }
        }
    }
    if (search_special(level, ZOO) && !rn2(200)) {
        static const char *const zoo_msg[3] = {
            "a sound reminiscent of an elephant stepping on a peanut.",
            "a sound reminiscent of a seal barking.",
            "Doctor Dolittle!",
        };
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp))
                continue;
            if ((mtmp->msleeping || is_animal(mtmp->data)) &&
                mon_in_room(mtmp, ZOO)) {
                You_hear("%s", zoo_msg[rn2(2) + hallu]);
                return;
            }
        }
    }
    if ((sroom = search_special(level, ANY_SHOP)) && !rn2(200)) {
        if (tended_shop(sroom) &&
            !strchr(u.ushops, ROOM_INDEX(sroom) + ROOMOFFSET)) {
            static const char *const shop_msg[3] = {
                "someone cursing shoplifters.",
                "the chime of a cash register.",
                "Neiman and Marcus arguing!",
            };
            You_hear("%s", shop_msg[rn2(2) + hallu]);
        }
        return;
    }
    if (search_special(level, DELPHI) && !rn2(400)) {
        /* make sure the Oracle is still here */
        for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon)
            if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_POTTER])
                break;
        /* and don't produce silly effects when he's clearly visible */
        if (mtmp && (hallu || !canseemon(mtmp))) {
            static const char *const ora_msg[5] = {
                "political commentary.",
                "convulsive ravings about WLAN controllers.",
                "an Adirondack woodsman.",
                "someone ask you for your punchcards.", /* if(hallucinating) */
                "loud praise for Netgear devices." /* if(hallucinating) */
            };
            You_hear("%s", ora_msg[rn2(3) + hallu * 2]);
        }
        return;
    }
}
예제 #12
0
파일: priest.c 프로젝트: FredrIQ/nhfourk
/* called from check_special_room() when the player enters the temple room */
void
intemple(int roomno)
{
    struct monst *priest = findpriest((char)roomno);
    boolean tended = (priest != NULL);
    boolean sanctum, can_speak;
    xchar shrined;
    const char *msg1, *msg2;

    if (In_mines(&u.uz) && !historysearch("entered the Minetown temple", TRUE))
        historic_event(FALSE, TRUE, "entered the Minetown temple");

    if (!temple_occupied(u.urooms0)) {
        if (tended) {
            shrined = has_shrine(priest);
            sanctum = (priest->data == &mons[PM_HIGH_PRIEST] &&
                       (shrined & AM_SANCTUM));
            can_speak = (priest->mcanmove && !priest->msleeping &&
                         canhear());
            if (can_speak) {
                unsigned save_priest = priest->ispriest;

                /* don't reveal the altar's owner upon temple entry in the
                   endgame; for the Sanctum, the next message names Moloch so
                   suppress the "of Moloch" for him here too */
                if (sanctum && !Hallucination)
                    priest->ispriest = 0;
                pline("%s intones:",
                      canseemon(priest) ? Monnam(priest) : "A nearby voice");
                priest->ispriest = save_priest;
            }
            msg2 = 0;
            if (sanctum && CONST_EPRI(priest)->shralign == A_NONE) {
                if (priest->mpeaceful) {
                    msg1 = "Infidel, you have entered Moloch's Sanctum!";
                    msg2 = "Be gone!";
                    msethostility(priest, TRUE, TRUE);
                } else
                    msg1 = "You desecrate this place by your presence!";
            } else {
                msg1 = msgprintf("Pilgrim, you enter a %s place!",
                                 !shrined ? "desecrated" : "sacred");
            }
            if (can_speak) {
                verbalize("%s", msg1);
                if (msg2)
                    verbalize("%s", msg2);
            }
            if (!sanctum) {
                /* !tended -> !shrined */
                if (!shrined || !p_coaligned(priest) ||
                    u.ualign.record <= ALGN_SINNED)
                    pline("You have a%s forbidding feeling...",
                          (!shrined) ? "" : " strange");
                else
                    pline("You experience a strange sense of peace.");
            }
        } else {
            switch (rn2(3)) {
            case 0:
                pline("You have an eerie feeling...");
                break;
            case 1:
                pline("You feel like you are being watched.");
                break;
            default:
                pline("A shiver runs down your %s.", body_part(SPINE));
                break;
            }
            if (!rn2(5)) {
                struct monst *mtmp;

                if (!((mtmp = makemon(&mons[PM_GHOST], level, 
                                      u.ux, u.uy, NO_MM_FLAGS))))
                    return;
                if (!Blind || sensemon(mtmp))
                    pline("An enormous ghost appears next to you!");
                else
                    pline("You sense a presence close by!");
                msethostility(mtmp, TRUE, TRUE);
                if (flags.verbose)
                    pline("You are frightened to death, and unable to move.");
                helpless(3, hr_afraid, "frightened to death",
                         "You regain your composure.");
            }
        }
    }
}
예제 #13
0
파일: music.c 프로젝트: FredrIQ/fiqhack
/* So you want music... */
int
do_play_instrument(struct obj *instr, const struct nh_cmd_arg *arg)
{
    char c = 'y';
    const char *buf;
    int x, y;
    boolean ok;

    if (Underwater) {
        pline(msgc_cancelled, "You can't play music underwater!");
        return 0;
    }
    if (Upolyd && !can_blow_instrument(youmonst.data) &&
        (instr->otyp == BUGLE || instr->otyp == WOODEN_FLUTE ||
         instr->otyp == MAGIC_FLUTE || instr->otyp == TOOLED_HORN ||
         instr->otyp == FIRE_HORN || instr->otyp == FROST_HORN)) {
        pline(msgc_cancelled,
              "You are incapable of playing %s in your current form!",
              the(xname(instr)));
        return 0;
    }
    if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
        c = yn("Improvise?");
    }
    if (c == 'n') {
        if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y') {
            buf = msg_from_string(gamestate.castle_tune);
        } else {
            /* Note: This is explicitly not getarglin(); we don't want
               command repeat to repeat the tune. */
            buf = getlin("What tune are you playing? [5 notes, A-G]", FALSE);
            if (*buf == '\033')
                buf = "";
            buf = msgmungspaces(buf);
            /* convert to uppercase and change any "H" to the expected "B" */
            buf = msgcaseconv(buf, highc_htob, highc_htob, highc_htob);
        }
        pline(msgc_occstart, "You extract a strange sound from %s!",
              the(xname(instr)));

        /* Check if there was the Stronghold drawbridge near and if the tune
           conforms to what we're waiting for. */
        if (Is_stronghold(&u.uz)) {
            exercise(A_WIS, TRUE);      /* just for trying */
            if (!strcmp(buf, gamestate.castle_tune)) {
                /* Search for the drawbridge */
                for (y = youmonst.my - 1; y <= youmonst.my + 1; y++)
                    for (x = youmonst.mx - 1; x <= youmonst.mx + 1; x++)
                        if (isok(x, y))
                            if (find_drawbridge(&x, &y)) {
                                /* tune now fully known */
                                u.uevent.uheard_tune = 2;
                                if (level->locations[x][y].typ ==
                                    DRAWBRIDGE_DOWN)
                                    close_drawbridge(x, y);
                                else
                                    open_drawbridge(x, y);
                                return 1;
                            }
            } else if (canhear()) {
                if (u.uevent.uheard_tune < 1)
                    u.uevent.uheard_tune = 1;
                /* Okay, it wasn't the right tune, but perhaps we can give the
                   player some hints like in the Mastermind game */
                ok = FALSE;
                for (y = youmonst.my - 1; y <= youmonst.my + 1 && !ok; y++)
                    for (x = youmonst.mx - 1; x <= youmonst.mx + 1 && !ok; x++)
                        if (isok(x, y))
                            if (IS_DRAWBRIDGE(level->locations[x][y].typ) ||
                                is_drawbridge_wall(x, y) >= 0)
                                ok = TRUE;
                if (ok) {       /* There is a drawbridge near */
                    int tumblers, gears;
                    boolean matched[5];

                    tumblers = gears = 0;
                    for (x = 0; x < 5; x++)
                        matched[x] = FALSE;

                    for (x = 0; x < (int)strlen(buf); x++)
                        if (x < 5) {
                            if (buf[x] == gamestate.castle_tune[x]) {
                                gears++;
                                matched[x] = TRUE;
                            } else
                                for (y = 0; y < 5; y++)
                                    if (!matched[y] &&
                                        buf[x] == gamestate.castle_tune[y] &&
                                        buf[y] != gamestate.castle_tune[y]) {
                                        tumblers++;
                                        matched[y] = TRUE;
                                        break;
                                    }
                        }
                    if (tumblers)
                        if (gears)
                            You_hear(msgc_hint,
                                     "%d tumbler%s click and %d gear%s turn.",
                                     tumblers, plur(tumblers), gears,
                                     plur(gears));
                        else
                            You_hear(msgc_hint, "%d tumbler%s click.", tumblers,
                                     plur(tumblers));
                    else if (gears) {
                        You_hear(msgc_hint, "%d gear%s turn.", gears,
                                 plur(gears));
                        /* could only get `gears == 5' by playing five correct
                           notes followed by excess; otherwise, tune would have 
                           matched above */
                        if (gears == 5)
                            u.uevent.uheard_tune = 2;
                    }
                }
            }
        }
        return 1;
    } else
        return do_improvisation(instr, arg);
}
예제 #14
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;
    }
}