コード例 #1
0
ファイル: teleport.c プロジェクト: eatnumber1/bingehack4
void
domagicportal(struct trap *ttmp)
{
    struct d_level target_level;

    if (!next_to_u()) {
        pline("You shudder for a moment.");
        return;
    }

    /* if landed from another portal, do nothing */
    /* problem: level teleport landing escapes the check */
    if (!on_level(&u.uz, &u.uz0))
        return;

    pline("You activated a magic portal!");

    /* prevent the poor shnook, whose amulet was stolen while in the endgame,
       from accidently triggering the portal to the next level, and thus losing 
       the game */
    if (In_endgame(&u.uz) && !u.uhave.amulet) {
        pline("You feel dizzy for a moment, but nothing happens...");
        return;
    }

    target_level = ttmp->dst;
    schedule_goto(&target_level, FALSE, FALSE, 1,
                  "You feel dizzy for a moment, but the sensation passes.",
                  NULL);
}
コード例 #2
0
ファイル: priest.c プロジェクト: FredrIQ/nhfourk
static boolean
histemple_at(struct monst *priest, xchar x, xchar y)
{
    return ((boolean)
            ((CONST_EPRI(priest)->shroom == *in_rooms(level, x, y, TEMPLE)) &&
             on_level(&(CONST_EPRI(priest)->shrlevel), &u.uz)));
}
コード例 #3
0
ファイル: vault.c プロジェクト: thejoshwolfe/nethack
static struct monst * findgd(void) {
    struct monst *mtmp;

    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
        if (mtmp->isgd && !DEADMONSTER(mtmp) && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
            return (mtmp);
    return ((struct monst *)0);
}
コード例 #4
0
static struct monst *
findgd(void)
{
    struct monst *mtmp;

    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon)
        if (mtmp->isgd && !DEADMONSTER(mtmp) &&
            on_level(&(EGD(mtmp)->gdlevel), &u.uz))
            return mtmp;
    return NULL;
}
コード例 #5
0
ファイル: priest.c プロジェクト: FredrIQ/nhfourk
/*
 * When saving bones, find priests that aren't on their shrine level,
 * and remove them.   This avoids big problems when restoring bones.
 */
void
clearpriests(void)
{
    struct monst *mtmp, *mtmp2;

    for (mtmp = level->monlist; mtmp; mtmp = mtmp2) {
        mtmp2 = mtmp->nmon;
        if (!DEADMONSTER(mtmp) && mtmp->ispriest &&
            !on_level(&(CONST_EPRI(mtmp)->shrlevel), &u.uz))
            mongone(mtmp);
    }
}
コード例 #6
0
ファイル: quest.c プロジェクト: FredrIQ/nhfourk
void
onquest(const d_level * orig_lev)
{
    if (u.uevent.qcompleted || on_level(orig_lev, &u.uz))
        return;
    if (!Is_special(&u.uz))
        return;

    if (Is_qstart(&u.uz))
        on_start(orig_lev);
    else if (Is_qlocate(&u.uz))
        on_locate(orig_lev);
    else if (Is_nemesis(&u.uz))
        on_goal();
    return;
}
コード例 #7
0
ファイル: quest.c プロジェクト: FredrIQ/nhfourk
void
leader_speaks(struct monst *mtmp)
{
    /* maybe you attacked leader? */
    if (!mtmp->mpeaceful) {
        Qstat(pissed_off) = TRUE;
        mtmp->mstrategy &= ~STRAT_WAITMASK;     /* end the inaction */
    }
    /* the quest leader might have passed through the portal into the regular
       dungeon; if so, mustn't perform "backwards expulsion" */
    if (!on_level(&u.uz, &qstart_level))
        return;

    if (Qstat(pissed_off)) {
        qt_pager(QT_LASTLEADER);
        expulsion(TRUE);
    } else
        chat_with_leader();
}
コード例 #8
0
ファイル: vault.c プロジェクト: thejoshwolfe/nethack
static bool clear_fcorr(struct monst *grd, bool forceshow) {
    int fcx, fcy, fcbeg;
    struct monst *mtmp;

    if (!on_level(&(EGD(grd)->gdlevel), &u.uz))
        return true;

    while ((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
        fcx = EGD(grd)->fakecorr[fcbeg].fx;
        fcy = EGD(grd)->fakecorr[fcbeg].fy;
        if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
        EGD(grd)->gddone)
            forceshow = true;
        if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0) || (!forceshow && couldsee(fcx, fcy)) || (Punished && !carried(uball) && uball->ox == fcx && uball->oy == fcy))
            return false;

        if ((mtmp = m_at(fcx, fcy)) != 0) {
            if (mtmp->isgd)
                return (false);
            else if (!in_fcorridor(grd, u.ux, u.uy)) {
                if (mtmp->mtame)
                    yelp(mtmp);
                (void)rloc(mtmp, false);
            }
        }
        levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
        map_location(fcx, fcy, 1); /* bypass vision */
        if (!ACCESSIBLE(levl[fcx][fcy].typ))
            block_point(fcx, fcy);
        EGD(grd)->fcbeg++;
    }
    if (grd->mhp <= 0) {
        pline_The("corridor disappears.");
        if (IS_ROCK(levl[u.ux][u.uy].typ))
            You("are encased in rock.");
    }
    return (true);
}
コード例 #9
0
ファイル: priest.c プロジェクト: FredrIQ/nhfourk
/* exclusively for mktemple(); uses level creation RNG */
void
priestini(struct level *lev, struct mkroom *sroom, int sx, int sy,
          boolean sanctum)
{       /* is it the seat of the high priest? */
    struct monst *priest = NULL;
    struct obj *otmp;
    int cnt;

    coord *priest_pos, pos_array[] = {
        { sx + 1, sy },
        { sx - 1, sy },
        { sx, sy + 1 },
        { sx, sy - 1 },
        { sx, sy },
        { COLNO, ROWNO },
    };

    /* Search for a good position for the priest. The -1 in the array bound is
     * to ensure that we stop on the { COLNO, ROWNO } entry which is not ok. Do
     * not pass a monster to goodpos(), because we will move any monster later.
     */
    for (priest_pos = pos_array;
         !goodpos(lev, priest_pos->x, priest_pos->y, NULL, 0) &&
         (priest_pos < pos_array + ARRAY_SIZE(pos_array) - 1);
         ++priest_pos)
         {}
    
    if (!isok(priest_pos->x, priest_pos->y)) {
        impossible("Unable to find location for priest in shrine");
    } else {
        if (MON_AT(lev, priest_pos->x, priest_pos->y))
            rloc(m_at(lev, priest_pos->x, priest_pos->y), FALSE);

        priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
                         lev, priest_pos->x, priest_pos->y, MM_ALLLEVRNG);
    }

    if (priest) {
        EPRI(priest)->shroom = (sroom - lev->rooms) + ROOMOFFSET;
        EPRI(priest)->shralign = Amask2align(lev->locations[sx][sy].altarmask);
        EPRI(priest)->shrpos.x = sx;
        EPRI(priest)->shrpos.y = sy;
        assign_level(&(EPRI(priest)->shrlevel), &lev->z);
        priest->mtrapseen = ~0; /* traps are known */
        priest->mpeaceful = 1;
        priest->ispriest = 1;
        priest->msleeping = 0;
        set_malign(priest);     /* mpeaceful may have changed */

        /* now his/her goodies... */
        if (sanctum && CONST_EPRI(priest)->shralign == A_NONE &&
            on_level(&sanctum_level, &lev->z)) {
            mongets(priest, AMULET_OF_YENDOR, rng_for_level(&lev->z));
        }
        /* 2 to 4 spellbooks */
        for (cnt = rn1(3, 2); cnt > 0; --cnt) {
            mpickobj(priest, mkobj(level, SPBOOK_CLASS, FALSE,
                                   rng_for_level(&lev->z)));
        }
        /* robe [via makemon()] */
        if (mklev_rn2(2, lev) && (otmp = which_armor(priest, os_armc)) != 0) {
            if (p_coaligned(priest))
                uncurse(otmp);
            else
                curse(otmp);
        }
    }
}
コード例 #10
0
ファイル: quest.c プロジェクト: FredrIQ/nhfourk
static void
chat_with_leader(void)
{
/* Rule 0: Cheater checks.                                 */
    if (Uhave_questart && !Qstat(met_nemesis))
        Qstat(cheater) = TRUE;

/* It is possible for you to get the amulet without completing
 * the quest.  If so, try to induce the player to quest.
 */
    if (Qstat(got_thanks)) {
/* Rule 1: You've gone back with/without the amulet.       */
        if (Uhave_amulet)
            finish_quest(NULL);

/* Rule 2: You've gone back before going for the amulet.   */
        else
            qt_pager(QT_POSTHANKS);
    }

/* Rule 3: You've got the artifact and are back to return it. */
    else if (Uhave_questart) {
        struct obj *otmp;

        for (otmp = invent; otmp; otmp = otmp->nobj)
            if (is_quest_artifact(otmp))
                break;

        finish_quest(otmp);

/* Rule 4: You haven't got the artifact yet.       */
    } else if (Qstat(got_quest)) {
        qt_pager(rn1(10, QT_ENCOURAGE));

/* Rule 5: You aren't yet acceptable - or are you? */
    } else {
        if (!Qstat(met_leader)) {
            qt_pager(QT_FIRSTLEADER);
            Qstat(met_leader) = TRUE;
            Qstat(not_ready) = 0;
        } else
            qt_pager(QT_NEXTLEADER);
        /* the quest leader might have passed through the portal into the
           regular dungeon; none of the remaining make sense there */
        if (!on_level(&u.uz, &qstart_level))
            return;

        if ((is_pure(FALSE) > 0) && (u.ulevelmax < 2) &&
            ((!challengemode) || !(u.uconduct[conduct_killer]))) {
            qt_pager(QT_LOWLEVEL);
            if (yn_function("Confirm your readiness and start the quest?",
                            "yn", 'n') == 'y') {
                pline("\"Go on then.\"");
                Qstat(got_quest) = TRUE;
                /* TODO: levelport the player straight to Quest 2? */
                historic_event(FALSE, FALSE, "embarked upon an epic quest.");
            } else {
                qt_pager(QT_BADLEVEL);
                expulsion(FALSE);
            }
            return;
        }
        if (not_capable()) {
            qt_pager(QT_BADLEVEL);
            expulsion(FALSE);
        } else if (is_pure(TRUE) < 0) {
            com_pager(QT_BANISHED);
            expulsion(TRUE);
        } else if (is_pure(FALSE) == 0) {
            qt_pager(QT_BADALIGN);
            if (Qstat(not_ready) == MAX_QUEST_TRIES) {
                qt_pager(QT_LASTLEADER);
                expulsion(TRUE);
            } else {
                Qstat(not_ready)++;
                expulsion(FALSE);
            }
        } else {        /* You are worthy! */
            qt_pager(QT_ASSIGNQUEST);
            Qstat(got_quest) = TRUE;
            historic_event(FALSE, FALSE, "embarked upon an epic quest.");
        }
    }
}
コード例 #11
0
ファイル: vault.c プロジェクト: thejoshwolfe/nethack
/*
 * 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, gy, fci;
    unsigned char typ;
    struct fakecorridor *fcp;
    struct egd *egrd = EGD(grd);
    struct rm *crm;
    bool goldincorridor = false, u_in_vault = vault_occupied(u.urooms) ? true : false, grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ?
    true :
                                                                                                                                           false;
    bool disappear_msg_seen = false, semi_dead = (grd->mhp <= 0);
    bool u_carry_gold = ((u.ugold + hidden_gold()) > 0L);
    bool 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)))) {
            (void)rloc(grd, false);
            wallify_vault(grd);
            (void)clear_fcorr(grd, true);
            goto letknow;
        }
        if (!in_fcorridor(grd, grd->mx, grd->my))
            (void)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 ? (!u.ugold ? "drop that hidden gold and " : "drop that gold and ") : "");
            if (egrd->warncnt == 7) {
                m = grd->mx;
                n = grd->my;
                verbalize("You've been warned, knave!");
                mnexto(grd);
                levl[m][n].typ = egrd->fakecorr[0].ftyp;
                newsym(m, n);
                grd->mpeaceful = 0;
                return (-1);
            }
            /* not fair to get mad when (s)he's fainted or paralyzed */
            if (!is_fainted() && multi >= 0)
                egrd->warncnt++;
            return (0);
        }

        if (!u_in_vault) {
            if (u_carry_gold) { /* player teleported */
                m = grd->mx;
                n = grd->my;
                (void)rloc(grd, false);
                levl[m][n].typ = egrd->fakecorr[0].ftyp;
                newsym(m, n);
                grd->mpeaceful = 0;
                letknow: if (!cansee(grd->mx, grd->my) || !mon_visible(grd)) {
                    You_hear("the shrill sound of a guard's whistle.");
                } else {
                    const char * fmt = um_dist(grd->mx, grd->my, 2) ? "see an angry %s approaching." : "are confronted by an angry %s.";
                    char name[BUFSZ];
                    g_monnam(name, BUFSZ, grd);
                    You(fmt, name);
                }
                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) &&
        levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ == egrd->fakecorr[0].ftyp) {
            char name[BUFSZ];
            g_monnam(name, BUFSZ, grd);
            pline_The("%s, confused, disappears.", name);
            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!");
                grd->mpeaceful = 0;
                return (-1);
            }
        }
    }
    for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
        if (g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
            m = egrd->fakecorr[fci].fx;
            n = egrd->fakecorr[fci].fy;
            goldincorridor = true;
        }
    if (goldincorridor && !egrd->gddone) {
        x = grd->mx;
        y = grd->my;
        if (m == u.ux && n == u.uy) {
            struct obj *gold = g_at(m, n);
            /* Grab the gold from between the hero's feet.  */
            grd->mgold += gold->quan;
            delobj(gold);
            newsym(m, n);
        } else if (m == x && n == y) {
            mpickgold(grd); /* does a newsym */
        } else {
            /* just for insurance... */
            if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
                verbalize("Out of my way, scum!");
                (void)rloc(m_at(m, n), false);
            }
            remove_monster(grd->mx, grd->my);
            newsym(grd->mx, grd->my);
            place_monster(grd, m, n);
            mpickgold(grd); /* does a newsym */
        }
        if (cansee(m, n)) {
            char name[BUFSZ];
            Monnam(name, BUFSZ, grd);
            pline("%s%s picks up the gold.", name, grd->mpeaceful ? " calms down and" : "");
        }
        if (x != grd->mx || y != grd->my) {
            remove_monster(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 = &levl[nx][ny])->typ;
                if (!IS_STWALL(typ) && !IS_POOL(typ)) {

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

                    if (*in_rooms(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->flags = 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 = &levl[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(levl[nx+nx-x][ny+ny-y].typ)) {
            crm->typ = DOOR;
            crm->flags = 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->flags = D_NODOOR;
            goto proceed;
        }
        break;
    }
    crm->typ = CORR;
    proceed: unblock_point(nx, ny); /* doesn't block light */
    if (cansee(nx, ny))
        newsym(nx, ny);

    fcp = &(egrd->fakecorr[egrd->fcend]);
    if (egrd->fcend++ == FCSIZ)
        impossible("fakecorr overflow");
    fcp->fx = nx;
    fcp->fy = ny;
    fcp->ftyp = typ;
    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(grd->mx, grd->my);
        newsym(grd->mx, grd->my);
        place_monster(grd, 0, 0);
        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) {
                char name[BUFSZ];
                g_monnam(name, BUFSZ, grd);
                pline("Suddenly, the %s disappears.", name);
            }
            return (1);
        }
        return (-2);
    }
    egrd->ogx = grd->mx; /* update old positions */
    egrd->ogy = grd->my;
    remove_monster(grd->mx, grd->my);
    place_monster(grd, nx, ny);
    newsym(grd->mx, grd->my);
    restfakecorr(grd);
    return (1);
}
コード例 #12
0
ファイル: quest.c プロジェクト: clockfort/bingehack4
static void
chat_with_leader(void)
{
/* Rule 0: Cheater checks.                                 */
    if (u.uhave.questart && !Qstat(met_nemesis))
        Qstat(cheater) = TRUE;

/* It is possible for you to get the amulet without completing
 * the quest.  If so, try to induce the player to quest.
 */
    if (Qstat(got_thanks)) {
/* Rule 1: You've gone back with/without the amulet.       */
        if (u.uhave.amulet)
            finish_quest(NULL);

/* Rule 2: You've gone back before going for the amulet.   */
        else
            qt_pager(QT_POSTHANKS);
    }

/* Rule 3: You've got the artifact and are back to return it. */
    else if (u.uhave.questart) {
        struct obj *otmp;

        for (otmp = invent; otmp; otmp = otmp->nobj)
            if (is_quest_artifact(otmp))
                break;

        finish_quest(otmp);

/* Rule 4: You haven't got the artifact yet.       */
    } else if (Qstat(got_quest)) {
        qt_pager(rn1(10, QT_ENCOURAGE));

/* Rule 5: You aren't yet acceptable - or are you? */
    } else {
        if (!Qstat(met_leader)) {
            qt_pager(QT_FIRSTLEADER);
            Qstat(met_leader) = TRUE;
            Qstat(not_ready) = 0;
        } else
            qt_pager(QT_NEXTLEADER);
        /* the quest leader might have passed through the portal into the
           regular dungeon; none of the remaining make sense there */
        if (!on_level(&u.uz, &qstart_level))
            return;

        if (not_capable()) {
            qt_pager(QT_BADLEVEL);
            exercise(A_WIS, TRUE);
            expulsion(FALSE);
        } else if (is_pure(TRUE) < 0) {
            com_pager(QT_BANISHED);
            expulsion(TRUE);
        } else if (is_pure(TRUE) == 0) {
            qt_pager(QT_BADALIGN);
            if (Qstat(not_ready) == MAX_QUEST_TRIES) {
                qt_pager(QT_LASTLEADER);
                expulsion(TRUE);
            } else {
                Qstat(not_ready)++;
                exercise(A_WIS, TRUE);
                expulsion(FALSE);
            }
        } else {        /* You are worthy! */
            qt_pager(QT_ASSIGNQUEST);
            exercise(A_WIS, TRUE);
            Qstat(got_quest) = TRUE;
            historic_event(FALSE, "embarked upon an epic quest.");
        }
    }
}
コード例 #13
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;
}
コード例 #14
0
static boolean
clear_fcorr(struct monst *grd, boolean forceshow)
{
    int fcx, fcy, fcbeg, oldtyp;
    struct monst *mtmp;
    boolean showmsg = FALSE;

    if (!on_level(&(EGD(grd)->gdlevel), &u.uz))
        return TRUE;

    while ((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
        fcx = EGD(grd)->fakecorr[fcbeg].fx;
        fcy = EGD(grd)->fakecorr[fcbeg].fy;
        if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
            EGD(grd)->gddone)
            forceshow = TRUE;
        if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
            || (!forceshow && couldsee(fcx, fcy)))
            return FALSE;

        if ((Punished && !carried(uball)
             && uball->ox == fcx && uball->oy == fcy)) {
            unplacebc();
            placebc();
        }

        if ((mtmp = m_at(level, fcx, fcy)) != 0) {
            if (mtmp->isgd)
                return FALSE;
            else if (!in_fcorridor(grd, u.ux, u.uy)) {
                if (mtmp->mtame)
                    yelp(mtmp);
                rloc(mtmp, FALSE);
            }
        }
        oldtyp = level->locations[fcx][fcy].typ;
        level->locations[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
        if (!ACCESSIBLE(level->locations[fcx][fcy].typ) && ACCESSIBLE(oldtyp)) {
            struct trap *t = t_at(level, fcx, fcy);

            if (couldsee(fcx, fcy))
                showmsg = TRUE;
            if (t)
                deltrap(level, t);
            level->locations[fcx][fcy].lit = FALSE;
            block_point(fcx, fcy);
        }
        map_location(fcx, fcy, 1, FALSE);      /* bypass vision */
        EGD(grd)->fcbeg++;
    }
    if (grd->mhp <= 0) {
        if (showmsg) {
            if (!Blind)
                pline("The corridor disappears.");
            else
                pline("You feel claustrophobic.");
        }
        if (IS_ROCK(level->locations[u.ux][u.uy].typ))
            pline("You are encased in rock.");
    }
    return TRUE;
}