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); }
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))); }
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); }
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; }
/* * 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); } }
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; }
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(); }
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); }
/* 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); } } }
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."); } } }
/* * 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); }
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."); } } }
/* * 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; }
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; }