bool somexy (struct mkroom *croom, coord *c) { int try_cnt = 0; int i; if (croom->irregular) { i = (croom - rooms) + ROOMOFFSET; while(try_cnt++ < 100) { c->x = somex(croom); c->y = somey(croom); if (!levl[c->x][c->y].edge && (int) levl[c->x][c->y].roomno == i) return true; } /* try harder; exhaustively search until one is found */ for(c->x = croom->lx; c->x <= croom->hx; c->x++) for(c->y = croom->ly; c->y <= croom->hy; c->y++) if (!levl[c->x][c->y].edge && (int) levl[c->x][c->y].roomno == i) return true; return false; } if (!croom->nsubrooms) { c->x = somex(croom); c->y = somey(croom); return true; } /* Check that coords doesn't fall into a subroom or into a wall */ while(try_cnt++ < 100) { c->x = somex(croom); c->y = somey(croom); if (IS_WALL(levl[c->x][c->y].typ)) continue; for(i=0 ; i<croom->nsubrooms;i++) if(inside_room(croom->sbrooms[i], c->x, c->y)) goto you_lose; break; you_lose: ; } if (try_cnt >= 100) return false; return true; }
void makerogueghost(struct level *lev) { struct monst *ghost; struct obj *ghostobj; struct mkroom *croom; int x,y; if (!lev->nroom) return; /* Should never happen */ croom = &lev->rooms[rn2(lev->nroom)]; x = somex(croom); y = somey(croom); if (!(ghost = makemon(&mons[PM_GHOST], lev, x, y, NO_MM_FLAGS))) return; ghost->msleeping = 1; christen_monst(ghost, roguename()); if (rn2(4)) { ghostobj = mksobj_at(FOOD_RATION, lev, x, y, FALSE, FALSE); ghostobj->quan = (long) rnd(7); ghostobj->owt = weight(ghostobj); } if (rn2(2)) { ghostobj = mksobj_at(MACE, lev, x, y, FALSE, FALSE); ghostobj->spe = rnd(3); if (rn2(4)) curse(ghostobj); } else { ghostobj = mksobj_at(TWO_HANDED_SWORD, lev, x, y, FALSE, FALSE); ghostobj->spe = rnd(5) - 2; if (rn2(4)) curse(ghostobj); } ghostobj = mksobj_at(BOW, lev, x, y, FALSE, FALSE); ghostobj->spe = 1; if (rn2(4)) curse(ghostobj); ghostobj = mksobj_at(ARROW, lev, x, y, FALSE, FALSE); ghostobj->spe = 0; ghostobj->quan = (long) rn1(10,25); ghostobj->owt = weight(ghostobj); if (rn2(4)) curse(ghostobj); if (rn2(2)) { ghostobj = mksobj_at(RING_MAIL, lev, x, y, FALSE, FALSE); ghostobj->spe = rn2(3); if (!rn2(3)) ghostobj->oerodeproof = TRUE; if (rn2(4)) curse(ghostobj); } else { ghostobj = mksobj_at(PLATE_MAIL, lev, x, y, FALSE, FALSE); ghostobj->spe = rnd(5) - 2; if (!rn2(3)) ghostobj->oerodeproof = TRUE; if (rn2(4)) curse(ghostobj); } if (rn2(2)) { ghostobj = mksobj_at(FAKE_AMULET_OF_YENDOR, lev, x, y, TRUE, FALSE); ghostobj->known = TRUE; } }
/* make a trap somewhere (in croom if mazeflag = 0) */ void mktrap(int num, int mazeflag, struct mkroom *croom) { struct trap *ttmp; int kind,nopierc,nomimic,fakedoor,fakegold,tryct = 0; xchar mx,my; if(!num || num >= TRAPNUM) { nopierc = (dlevel < 4) ? 1 : 0; nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; if(index(fut_geno, 'M')) nomimic = 1; kind = rn2(TRAPNUM - nopierc - nomimic); /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */ } else kind = num; if(kind == MIMIC) { struct monst *mtmp; fakedoor = (!rn2(3) && !mazeflag); fakegold = (!fakedoor && !rn2(2)); if(fakegold) goldseen = TRUE; do { if(++tryct > 200) return; if(fakedoor) { /* note: fakedoor maybe on actual door */ if(rn2(2)){ if(rn2(2)) mx = croom->hx+1; else mx = croom->lx-1; my = somey(); } else { if(rn2(2)) my = croom->hy+1; else my = croom->ly-1; mx = somex(); } } else if(mazeflag) { coord mm; mm = mazexy(); mx = mm.x; my = mm.y; } else { mx = somex(); my = somey(); } } while(m_at(mx,my) || levl[mx][my].typ == STAIRS); if((mtmp = makemon(PM_MIMIC,mx,my))) { mtmp->mimic = 1; mtmp->mappearance = fakegold ? '$' : fakedoor ? '+' : (mazeflag && rn2(2)) ? AMULET_SYM : "=/)%?![<>" [ rn2(9) ]; } return; } do { if(++tryct > 200) return; if(mazeflag){ coord mm; mm = mazexy(); mx = mm.x; my = mm.y; } else { mx = somex(); my = somey(); } } while(t_at(mx, my) || levl[mx][my].typ == STAIRS); ttmp = maketrap(mx, my, kind); if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC) ttmp->tseen = 1; }
void makelevel(void) { struct mkroom *croom, *troom; unsigned tryct; int x,y; nroom = 0; doorindex = 0; rooms[0].hx = -1; /* in case we are in a maze */ for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) levl[x][y] = zerorm; oinit(); /* assign level dependent obj probabilities */ if(dlevel >= rn1(3, 26)) { /* there might be several mazes */ makemaz(); return; } /* construct the rooms */ nroom = 0; secret = FALSE; makerooms(); /* construct stairs (up and down in different rooms if possible) */ croom = &rooms[rn2(nroom)]; xdnstair = somex(); ydnstair = somey(); levl[xdnstair][ydnstair].scrsym ='>'; levl[xdnstair][ydnstair].typ = STAIRS; if(nroom > 1) { troom = croom; croom = &rooms[rn2(nroom-1)]; if(croom >= troom) croom++; } xupstair = somex(); /* %% < and > might be in the same place */ yupstair = somey(); levl[xupstair][yupstair].scrsym ='<'; levl[xupstair][yupstair].typ = STAIRS; /* for each room: put things inside */ for(croom = rooms; croom->hx > 0; croom++) { /* put a sleeping monster inside */ /* Note: monster may be on the stairs. This cannot be avoided: maybe the player fell through a trapdoor while a monster was on the stairs. Conclusion: we have to check for monsters on the stairs anyway. */ if(!rn2(3)) makemon(NULL, somex(), somey()); /* put traps and mimics inside */ goldseen = FALSE; while(!rn2(8-(dlevel/6))) mktrap(0,0,croom); if(!goldseen && !rn2(3)) mkgold(0L,somex(),somey()); if(!rn2(3)) { mkobj_at(0, somex(), somey()); tryct = 0; while(!rn2(5)) { if(++tryct > 100){ printf("tryct overflow4\n"); break; } mkobj_at(0, somex(), somey()); } } } qsort((char *) rooms, nroom, sizeof(struct mkroom), comp); makecorridors(); make_niches(); /* make a secret treasure vault, not connected to the rest */ if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) { troom = &rooms[nroom]; secret = TRUE; if(makerooms()) { troom->rtype = VAULT; /* treasure vault */ for(x = troom->lx; x <= troom->hx; x++) for(y = troom->ly; y <= troom->hy; y++) mkgold((long)(rnd(dlevel*100) + 50), x, y); if(!rn2(3)) makevtele(); } } #ifndef QUEST #ifdef WIZARD if(wizard && getenv("SHOPTYPE")) mkshop(); else #endif /* WIZARD */ if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop(); else if(dlevel > 6 && !rn2(7)) mkzoo(ZOO); else if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE); else if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE); else if(dlevel > 18 && !rn2(6)) mkswamp(); #endif /* QUEST */ }