/* create a new shopkeeper in the given room */ static int shkinit ( const struct shclass *shp, struct mkroom *sroom) { int sh, sx, sy; struct monst *shk; /* place the shopkeeper in the given room */ sh = sroom->fdoor; sx = doors[sh].x; sy = doors[sh].y; /* check that the shopkeeper placement is sane */ if(sroom->irregular) { int rmno = (sroom - rooms) + ROOMOFFSET; if (isok(sx-1,sy) && !levl[sx-1][sy].edge && (int) levl[sx-1][sy].roomno == rmno) sx--; else if (isok(sx+1,sy) && !levl[sx+1][sy].edge && (int) levl[sx+1][sy].roomno == rmno) sx++; else if (isok(sx,sy-1) && !levl[sx][sy-1].edge && (int) levl[sx][sy-1].roomno == rmno) sy--; else if (isok(sx,sy+1) && !levl[sx][sy+1].edge && (int) levl[sx][sy+1].roomno == rmno) sx++; else goto shk_failed; } else if(sx == sroom->lx-1) sx++; else if(sx == sroom->hx+1) sx--; else if(sy == sroom->ly-1) sy++; else if(sy == sroom->hy+1) sy--; else { shk_failed: return(-1); } if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), false); /* insurance */ /* now initialize the shopkeeper monster structure */ if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS))) return(-1); shk->isshk = shk->mpeaceful = 1; set_malign(shk); shk->msleeping = 0; shk->mtrapseen = ~0; /* we know all the traps already */ ESHK(shk)->shoproom = (sroom - rooms) + ROOMOFFSET; sroom->resident = shk; ESHK(shk)->shoptype = sroom->rtype; assign_level(&(ESHK(shk)->shoplevel), &u.uz); ESHK(shk)->shd = doors[sh]; ESHK(shk)->shk.x = sx; ESHK(shk)->shk.y = sy; ESHK(shk)->robbed = 0L; ESHK(shk)->credit = 0L; ESHK(shk)->debit = 0L; ESHK(shk)->loan = 0L; ESHK(shk)->visitct = 0; ESHK(shk)->following = 0; ESHK(shk)->billct = 0; shk->mgold = 1000L + 30L*(long)rnd(100); /* initial capital */ if (shp->shknms == shkrings) (void) mongets(shk, TOUCHSTONE); nameshk(shk, shp->shknms); return(sh); }
/* munge priest-specific structure when restoring -dlc */ void restpriest(struct monst *mtmp, boolean ghostly) { if (u.uz.dlevel) { if (ghostly) assign_level(&(EPRI(mtmp)->shrlevel), &u.uz); } }
STATIC_OVL boolean uz_no_bones_level() { extern d_level save_dlevel; /* in do.c */ s_level *sptr; if (ledger_no(&save_dlevel)) assign_level(&u.uz, &save_dlevel); return (boolean) (((sptr = uz_is_special()) != 0 && !sptr->boneid) || !dungeons[u.uz.dnum].boneid /* no bones on the last or multiway branch levels in any dungeon (level 1 isn't multiway) */ || uz_is_botlevel() || (uz_is_branchlev() && u.uz.dlevel > 1) /* no bones in the invocation level */ || (uz_in_hell() && u.uz.dlevel == dunlevs_in_uz_dungeon() - 1)); }
void level_tele_impl(boolean wizard_tele) { int newlev; d_level newlevel; const char *escape_by_flying = 0; /* when surviving dest of -N */ boolean force_dest = FALSE; const char *buf, *killer = NULL; if ((Uhave_amulet || In_endgame(&u.uz) || In_sokoban(&u.uz)) && !wizard_tele) { pline("You feel very disoriented for a moment."); return; } if ((Teleport_control && !Stunned) || wizard_tele) { int trycnt = 0; const char *qbuf = "To what level do you want to teleport?"; do { if (++trycnt == 2) { if (wizard_tele) qbuf = msgcat(qbuf, " [type a number or ? for a menu]"); else qbuf = msgcat(qbuf, " [type a number]"); } buf = getlin(qbuf, FALSE); if (!strcmp(buf, "\033")) { /* cancelled */ if (Confusion && rnl(5)) { pline("Oops..."); goto random_levtport; } return; } else if (!strcmp(buf, "*")) { goto random_levtport; } else if (Confusion && rnl(5)) { pline("Oops..."); goto random_levtport; } if (wizard_tele && !strcmp(buf, "?")) { schar destlev = 0; xchar destdnum = 0; if ((newlev = (int)print_dungeon(TRUE, &destlev, &destdnum))) { newlevel.dnum = destdnum; newlevel.dlevel = destlev; if (In_endgame(&newlevel) && !In_endgame(&u.uz)) { const char *dest = "Destination is earth level"; if (!Uhave_amulet) { struct obj *obj; obj = mksobj(level, AMULET_OF_YENDOR, TRUE, FALSE, rng_main); if (obj) { addinv(obj); dest = msgcat(dest, " with the amulet"); } } assign_level(&newlevel, &earth_level); pline("%s.", dest); } force_dest = TRUE; } else return; } else if ((newlev = lev_by_name(buf)) == 0) newlev = atoi(buf); } while (!newlev && !digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10); /* no dungeon escape via this route */ if (newlev == 0) { if (trycnt >= 10) goto random_levtport; if (ynq("Go to Nowhere. Are you sure?") != 'y') return; pline("You %s in agony as your body begins to warp...", is_silent(youmonst.data) ? "writhe" : "scream"); win_pause_output(P_MESSAGE); pline("You cease to exist."); if (invent) pline("Your possessions land on the %s with a thud.", surface(u.ux, u.uy)); done(DIED, "committed suicide"); pline("An energized cloud of dust begins to coalesce."); pline("Your body rematerializes%s.", invent ? ", and you gather up all your possessions" : ""); return; } /* if in Knox and the requested level > 0, stay put. we let negative values requests fall into the "heaven" loop. */ if (Is_knox(&u.uz) && newlev > 0) { pline("You shudder for a moment."); return; } /* if in Quest, the player sees "Home 1", etc., on the status line, instead of the logical depth of the level. controlled level teleport request is likely to be relativized to the status line, and consequently it should be incremented to the value of the logical depth of the target level. we let negative values requests fall into the "heaven" loop. */ if (In_quest(&u.uz) && newlev > 0) newlev = newlev + find_dungeon(&u.uz).depth_start - 1; } else { /* involuntary level tele */ random_levtport: newlev = random_teleport_level(); if (newlev == depth(&u.uz)) { pline("You shudder for a moment."); return; } } if (!next_to_u()) { pline("You shudder for a moment."); return; } if (In_endgame(&u.uz)) { /* must already be wizard */ int llimit = dunlevs_in_dungeon(&u.uz); if (newlev >= 0 || newlev <= -llimit) { pline("You can't get there from here."); return; } newlevel.dnum = u.uz.dnum; newlevel.dlevel = llimit + newlev; schedule_goto(&newlevel, FALSE, FALSE, 0, NULL, NULL); return; } if (newlev < 0 && !force_dest) { if (*u.ushops0) { /* take unpaid inventory items off of shop bills */ in_mklev = TRUE; /* suppress map update */ u_left_shop(u.ushops0, TRUE); /* you're now effectively out of the shop */ *u.ushops0 = *u.ushops = '\0'; in_mklev = FALSE; } if (newlev <= -10) { pline("You arrive in heaven."); verbalize("Thou art early, but we'll admit thee."); killer = "went to heaven prematurely"; } else if (newlev == -9) { pline("You feel deliriously happy. "); pline("(In fact, you're on Cloud 9!) "); win_pause_output(P_MESSAGE); } else pline("You are now high above the clouds..."); if (killer) { ; /* arrival in heaven is pending */ } else if (Levitation) { escape_by_flying = "float gently down to earth"; } else if (Flying) { escape_by_flying = "fly down to the ground"; } else { pline("Unfortunately, you don't know how to fly."); pline("You plummet a few thousand feet to your death."); killer = msgcat_many("teleported out of the dungeon and fell to ", uhis(), " death", NULL); } } if (killer) { /* the chosen destination was not survivable */ d_level lsav; /* set specific death location; this also suppresses bones */ lsav = u.uz; /* save current level, see below */ u.uz.dnum = 0; /* main dungeon */ u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */ done(DIED, killer); /* can only get here via life-saving (or declining to die in explore|debug mode); the hero has now left the dungeon... */ escape_by_flying = "find yourself back on the surface"; u.uz = lsav; /* restore u.uz so escape code works */ } /* calls done(ESCAPED) if newlevel==0 */ if (escape_by_flying) { pline("You %s.", escape_by_flying); done(ESCAPED, "teleported to safety"); } else if (u.uz.dnum == medusa_level.dnum && newlev >= (find_dungeon(&u.uz).depth_start + dunlevs_in_dungeon(&u.uz))) { if (!(wizard_tele && force_dest)) find_hell(&newlevel); } else { /* if invocation did not yet occur, teleporting into the last level of Gehennom is forbidden. */ if (!wizard_tele) if (Inhell && !u.uevent.invoked && newlev >= (find_dungeon(&u.uz).depth_start + dunlevs_in_dungeon(&u.uz) - 1)) { newlev = (find_dungeon(&u.uz).depth_start + dunlevs_in_dungeon(&u.uz) - 2); pline("Sorry..."); } /* no teleporting out of quest dungeon */ if (In_quest(&u.uz) && newlev < depth(&qstart_level)) newlev = depth(&qstart_level); /* the player thinks of levels purely in logical terms, so we must translate newlev to a number relative to the current dungeon. */ if (!(wizard_tele && force_dest)) get_level(&newlevel, newlev); } schedule_goto(&newlevel, FALSE, FALSE, 0, NULL, NULL); /* in case player just read a scroll and is about to be asked to call it something, we can't defer until the end of the turn */ if (!flags.mon_moving) deferred_goto(); }
/* return 0 if still on level, 3 if not */ int mlevel_tele_trap(struct monst *mtmp, struct trap *trap, boolean force_it, int in_sight) { int tt = trap->ttyp; const struct permonst *mptr = mtmp->data; if (mtmp == u.ustuck) /* probably a vortex */ return 0; /* temporary? kludge */ if (teleport_pet(mtmp, force_it)) { d_level tolevel; int migrate_typ = MIGR_RANDOM; if ((tt == HOLE || tt == TRAPDOOR)) { if (Is_stronghold(&u.uz)) { assign_level(&tolevel, &valley_level); } else if (Is_botlevel(&u.uz)) { if (in_sight && trap->tseen) pline("%s avoids the %s.", Monnam(mtmp), (tt == HOLE) ? "hole" : "trap"); return 0; } else { get_level(&tolevel, depth(&u.uz) + 1); } } else if (tt == MAGIC_PORTAL) { if (In_endgame(&u.uz) && (mon_has_amulet(mtmp) || is_home_elemental(&mtmp->dlevel->z, mptr))) { if (in_sight && mptr->mlet != S_ELEMENTAL) { pline("%s seems to shimmer for a moment.", Monnam(mtmp)); seetrap(trap); } return 0; } else { assign_level(&tolevel, &trap->dst); migrate_typ = MIGR_PORTAL; } } else { /* (tt == LEVEL_TELEP) */ int nlev; if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) { if (in_sight) pline("%s seems very disoriented for a moment.", Monnam(mtmp)); return 0; } nlev = random_teleport_level(); if (nlev == depth(&u.uz)) { if (in_sight) pline("%s shudders for a moment.", Monnam(mtmp)); return 0; } get_level(&tolevel, nlev); } if (in_sight) { pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp)); seetrap(trap); } migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, NULL); return 3; /* no longer on this level */ } return 0; }
/* create a new shopkeeper in the given room; uses level creation RNG */ static int shkinit(const struct shclass *shp, struct level *lev, struct mkroom *sroom) { int sh, sx, sy; struct monst *shk; /* place the shopkeeper in the given room */ sh = sroom->fdoor; sx = lev->doors[sh].x; sy = lev->doors[sh].y; /* check that the shopkeeper placement is sane */ if (sroom->irregular) { int rmno = (sroom - lev->rooms) + ROOMOFFSET; if (isok(sx - 1, sy) && !lev->locations[sx - 1][sy].edge && (int)lev->locations[sx - 1][sy].roomno == rmno) sx--; else if (isok(sx + 1, sy) && !lev->locations[sx + 1][sy].edge && (int)lev->locations[sx + 1][sy].roomno == rmno) sx++; else if (isok(sx, sy - 1) && !lev->locations[sx][sy - 1].edge && (int)lev->locations[sx][sy - 1].roomno == rmno) sy--; else if (isok(sx, sy + 1) && !lev->locations[sx][sy + 1].edge && (int)lev->locations[sx][sy + 1].roomno == rmno) sx++; else goto shk_failed; } else if (sx == sroom->lx - 1) sx++; else if (sx == sroom->hx + 1) sx--; else if (sy == sroom->ly - 1) sy++; else if (sy == sroom->hy + 1) sy--; else { shk_failed: return -1; } if (MON_AT(lev, sx, sy)) rloc(m_at(lev, sx, sy), FALSE); /* insurance */ /* now initialize the shopkeeper monster structure */ if (!(shk = makemon(&mons[PM_SHOPKEEPER], lev, sx, sy, MM_ALLLEVRNG))) return -1; shk->isshk = 1; msethostility(shk, FALSE, TRUE); shk->msleeping = 0; shk->mtrapseen = ~0; /* we know all the traps already */ ESHK(shk)->shoproom = (sroom - lev->rooms) + ROOMOFFSET; sroom->resident = shk; ESHK(shk)->shoptype = sroom->rtype; assign_level(&(ESHK(shk)->shoplevel), &lev->z); ESHK(shk)->shd = lev->doors[sh]; ESHK(shk)->shk.x = sx; ESHK(shk)->shk.y = sy; ESHK(shk)->robbed = 0L; ESHK(shk)->credit = 0L; ESHK(shk)->debit = 0L; ESHK(shk)->loan = 0L; ESHK(shk)->visitct = 0; ESHK(shk)->following = 0; ESHK(shk)->billct = 0; ESHK(shk)->bill_inactive = FALSE; /* initial capital */ mkmonmoney(shk, 1030L + 30L * mklev_rn2(100, lev), rng_for_level(&lev->z)); if (shp->shknms == shkrings) mongets(shk, TOUCHSTONE, rng_for_level(&lev->z)); nameshk(shk, shp->shknms, lev); return sh; }
/* 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); } } }
pixelinfo_t * ri_sis(float *texels, int ngensamples, int width, int height) { int i; int maxlevel = 6; double m; double s; double v; double domega0; pixelinfo_t *info; pixelinfo_t **layer; pixelinfo_t *gensamples; FILE *fp; fp = fopen("gensamples.dat", "w"); if (!fp) exit(-1); printf("start sis\n"); gensamples = (pixelinfo_t *)malloc(sizeof(pixelinfo_t) * ngensamples); if (!gensamples) { printf("muda muda muda. gensamples = NULL\n"); exit(-1); } layer = (pixelinfo_t **)malloc(sizeof(pixelinfo_t *) * maxlevel); if (!layer) { printf("muda muda muda. layer = NULL\n"); exit(-1); } for (i = 0; i < maxlevel; i++) { layer[i] = (pixelinfo_t *)malloc(sizeof(pixelinfo_t) * width * height); } info = initpixelinfo(texels, width, height); mean(&m, info, width * height); sd (&s, info, width * height, m); assign_level(info, width * height, s, maxlevel); layerize(layer, maxlevel, info, width * height); //output_hdr(layer[1], 1, width, height); /* detect connected components each layer */ for (i = 0; i < maxlevel; i++) { connected_components(layer[i], width, height); //output_cc(layer[i], i, width, height); } domega0 = 0.01; gamma_4pi(&v, info, width * height, domega0); generate_sample(gensamples, ngensamples, v, layer, maxlevel, width, height); /* Output samples */ fprintf(fp, "%d\n", ngensamples); fprintf(fp, "%d %d\n", width, height); for (i = 0; i < ngensamples; i++) { fprintf(fp, "%d %d %f %f %f\n", gensamples[i].x, gensamples[i].y, gensamples[i].c[0], gensamples[i].c[1], gensamples[i].c[2]); } fclose(fp); return info; }
void invault(void) { struct monst *guard; int trycount, vaultroom = (int)vault_occupied(u.urooms); if (!vaultroom) { u.uinvault = 0; return; } vaultroom -= ROOMOFFSET; guard = findgd(); if (++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */ char buf[BUFSZ]; int x, y, dd, gx, gy; int lx = 0, ly = 0; /* first find the goal for the guard */ for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) { for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) { if (y < 0 || y > ROWNO - 1) continue; for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) { if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd) x = u.ux + dd; if (x < 1 || x > COLNO - 1) continue; if (levl[x][y].typ == CORR) { if (x < u.ux) lx = x + 1; else if (x > u.ux) lx = x - 1; else lx = x; if (y < u.uy) ly = y + 1; else if (y > u.uy) ly = y - 1; else ly = y; if (levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR) goto incr_radius; goto fnd; } } } incr_radius: ; } impossible("Not a single corridor on this level??"); tele(); return; fnd: gx = x; gy = y; /* next find a good place for a door in the wall */ x = u.ux; y = u.uy; if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */ if (levl[x + 1][y].typ == ROOM) x = x + 1; else if (levl[x][y + 1].typ == ROOM) y = y + 1; else if (levl[x - 1][y].typ == ROOM) x = x - 1; else if (levl[x][y - 1].typ == ROOM) y = y - 1; else if (levl[x + 1][y + 1].typ == ROOM) { x = x + 1; y = y + 1; } else if (levl[x - 1][y - 1].typ == ROOM) { x = x - 1; y = y - 1; } else if (levl[x + 1][y - 1].typ == ROOM) { x = x + 1; y = y - 1; } else if (levl[x - 1][y + 1].typ == ROOM) { x = x - 1; y = y + 1; } } while (levl[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 (levl[x + 1][y].typ == HWALL || levl[x + 1][y].typ == DOOR) x = x + 1; else if (levl[x - 1][y].typ == HWALL || levl[x - 1][y].typ == DOOR) x = x - 1; else if (levl[x][y + 1].typ == VWALL || levl[x][y + 1].typ == DOOR) y = y + 1; else if (levl[x][y - 1].typ == VWALL || levl[x][y - 1].typ == DOOR) y = y - 1; else return; } /* make something interesting happen */ if (!(guard = makemon(&mons[PM_GUARD], x, y, NO_MM_FLAGS))) return; guard->isgd = 1; guard->mpeaceful = 1; set_malign(guard); 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; reset_faint(); /* if fainted - wake up */ if (canspotmon(guard)) { char name[BUFSZ]; g_monnam(name, BUFSZ, guard); pline("Suddenly one of the Vault's %s enters!", makeplural(name)); } else { pline("Someone else has entered the Vault."); } newsym(guard->mx, guard->my); if (youmonst.m_ap_type == M_AP_OBJECT || u.uundetected) { 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. */ pline("Puzzled, %s turns around and leaves.", mhe(guard)); mongone(guard); return; } if (Strangled|| is_silent(youmonst.data) || multi < 0) { /* [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; } stop_occupation(); /* if occupied, stop it *now* */ trycount = 5; do { getlin("\"Hello stranger, who are you?\" -", buf); (void)mungspaces(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, plname, (int)strlen(plname)) != 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; (void)mon_wield_item(guard); } } return; } verbalize("I don't know you."); if (!u.ugold && !hidden_gold()) verbalize("Please follow me."); else { if (!u.ugold) verbalize("You have hidden gold."); verbalize("Most likely all your gold was stolen from this vault."); verbalize("Please drop that gold 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(levl[x][y].typ)) EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ; else { /* the initial guard location is a dug door */ int vlt = EGD(guard)->vroom; signed char lowx = rooms[vlt].lx, hix = rooms[vlt].hx; signed char lowy = rooms[vlt].ly, hiy = 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; } levl[x][y].typ = DOOR; levl[x][y].flags = D_NODOOR; unblock_point(x, y); /* doesn't block light */ EGD(guard)->fcend = 1; EGD(guard)->warncnt = 1; } }
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; } }