void mkzoo(int type) { struct mkroom *sroom; struct monst *mon; int sh, sx, sy, i; int goldlim = 500 * dlevel; int moct = 0; i = nroom; for (sroom = &rooms[rn2(nroom)];; sroom++) { if (sroom == &rooms[nroom]) sroom = &rooms[0]; if (!i-- || sroom->hx < 0) return; if (sroom->rtype) continue; if (type == MORGUE && sroom->rlit) continue; if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) continue; if (sroom->doorct == 1 || !rn2(5)) break; } sroom->rtype = type; sh = sroom->fdoor; for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) { if ((sx == sroom->lx && doors[sh].x == sx - 1) || (sx == sroom->hx && doors[sh].x == sx + 1) || (sy == sroom->ly && doors[sh].y == sy - 1) || (sy == sroom->hy && doors[sh].y == sy + 1)) continue; mon = makemon((type == MORGUE) ? morguemon() : (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, sx, sy); if (mon) mon->msleep = 1; switch (type) { case ZOO: i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y)); if (i >= goldlim) i = 5 * dlevel; goldlim -= i; mkgold((long) (10 + rn2(i)), sx, sy); break; case MORGUE: // Usually there is one dead body in the morgue if (!moct && rn2(3)) { mksobj_at(CORPSE, sx, sy); moct++; } break; case BEEHIVE: if (!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); break; } } }
/* make a swarm of undead around mm; uses the main RNG */ void mkundead(struct level *lev, coord *mm, boolean revive_corpses, int mm_flags) { int cnt = (level_difficulty(&lev->z) + 1) / 10 + rnd(5); const struct permonst *mdat; struct obj *otmp; coord cc; while (cnt--) { mdat = morguemon(&lev->z, rng_main); if (enexto(&cc, lev, mm->x, mm->y, mdat) && (!revive_corpses || !(otmp = sobj_at(CORPSE, lev, cc.x, cc.y)) || !revive(otmp))) makemon(mdat, lev, cc.x, cc.y, mm_flags); } lev->flags.graveyard = TRUE; /* reduced chance for undead corpse */ }
/* make a swarm of undead around mm */ void mkundead (coord *mm, bool revive_corpses, int mm_flags) { int cnt = (level_difficulty() + 1)/10 + rnd(5); struct permonst *mdat; struct obj *otmp; coord cc; while (cnt--) { mdat = morguemon(); if (enexto(&cc, mm->x, mm->y, mdat) && (!revive_corpses || !(otmp = sobj_at(CORPSE, cc.x, cc.y)) || !revive(otmp))) (void) makemon(mdat, cc.x, cc.y, mm_flags); } level.flags.graveyard = true; /* reduced chance for undead corpse */ }
void fill_zoo (struct mkroom *sroom) { struct monst *mon; int sx,sy,i; int sh, tx, ty, goldlim, type = sroom->rtype; int rmno = (sroom - rooms) + ROOMOFFSET; coord mm; sh = sroom->fdoor; switch(type) { case COURT: if(level.flags.is_maze_lev) { for(tx = sroom->lx; tx <= sroom->hx; tx++) for(ty = sroom->ly; ty <= sroom->hy; ty++) if(IS_THRONE(levl[tx][ty].typ)) goto throne_placed; } i = 100; do { /* don't place throne on top of stairs */ (void) somexy(sroom, &mm); tx = mm.x; ty = mm.y; } while (occupied((signed char)tx, (signed char)ty) && --i > 0); throne_placed: /* TODO: try to ensure the enthroned monster is an M2_PRINCE */ break; case BEEHIVE: tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2; ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2; if(sroom->irregular) { /* center might not be valid, so put queen elsewhere */ if ((int) levl[tx][ty].roomno != rmno || levl[tx][ty].edge) { (void) somexy(sroom, &mm); tx = mm.x; ty = mm.y; } } break; case ZOO: case LEPREHALL: goldlim = 500 * level_difficulty(); break; } for(sx = sroom->lx; sx <= sroom->hx; sx++) for(sy = sroom->ly; sy <= sroom->hy; sy++) { if(sroom->irregular) { if ((int) levl[sx][sy].roomno != rmno || levl[sx][sy].edge || (sroom->doorct && distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1)) continue; } else if(!SPACE_POS(levl[sx][sy].typ) || (sroom->doorct && ((sx == sroom->lx && doors[sh].x == sx-1) || (sx == sroom->hx && doors[sh].x == sx+1) || (sy == sroom->ly && doors[sh].y == sy-1) || (sy == sroom->hy && doors[sh].y == sy+1)))) continue; /* don't place monster on explicitly placed throne */ if(type == COURT && IS_THRONE(levl[sx][sy].typ)) continue; mon = makemon( (type == COURT) ? courtmon() : (type == BARRACKS) ? squadmon() : (type == MORGUE) ? morguemon() : (type == BEEHIVE) ? (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : &mons[PM_KILLER_BEE]) : (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] : (type == COCKNEST) ? &mons[PM_COCKATRICE] : (type == ANTHOLE) ? antholemon() : (struct permonst *) 0, sx, sy, NO_MM_FLAGS); if(mon) { mon->msleeping = 1; if (type==COURT && mon->mpeaceful) { mon->mpeaceful = 0; set_malign(mon); } } switch(type) { case ZOO: case LEPREHALL: if(sroom->doorct) { int distval = dist2(sx,sy,doors[sh].x,doors[sh].y); i = sq(distval); } else i = goldlim; if(i >= goldlim) i = 5*level_difficulty(); goldlim -= i; (void) mkgold((long) rn1(i, 10), sx, sy); break; case MORGUE: if(!rn2(5)) (void) mk_tt_object(CORPSE, sx, sy); if(!rn2(10)) /* lots of treasure buried with dead */ (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy, true, false); if (!rn2(5)) make_grave(sx, sy, (char *)0); break; case BEEHIVE: if(!rn2(3)) (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy, true, false); break; case BARRACKS: if(!rn2(20)) /* the payroll and some loot */ (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy, true, false); break; case COCKNEST: if(!rn2(3)) { struct obj *sobj = mk_tt_object(STATUE, sx, sy); if (sobj) { for (i = rn2(5); i; i--) (void) add_to_container(sobj, mkobj(RANDOM_CLASS, false)); sobj->owt = weight(sobj); } } break; case ANTHOLE: if(!rn2(3)) (void) mkobj_at(FOOD_CLASS, sx, sy, false); break; } } switch (type) { case COURT: { struct obj *chest; levl[tx][ty].typ = THRONE; (void) somexy(sroom, &mm); (void) mkgold((long) rn1(50 * level_difficulty(),10), mm.x, mm.y); /* the royal coffers */ chest = mksobj_at(CHEST, mm.x, mm.y, true, false); chest->spe = 2; /* so it can be found later */ level.flags.has_court = 1; break; } case BARRACKS: level.flags.has_barracks = 1; break; case ZOO: level.flags.has_zoo = 1; break; case MORGUE: level.flags.has_morgue = 1; break; case SWAMP: level.flags.has_swamp = 1; break; case BEEHIVE: level.flags.has_beehive = 1; break; } }
void fill_zoo(struct level *lev, struct mkroom *sroom, enum rng rng) { struct monst *mon; int sx, sy, i; int sh, tx, ty, goldlim, type = sroom->rtype; int rmno = (sroom - lev->rooms) + ROOMOFFSET; coord mm; tx = ty = goldlim = 0; sh = sroom->fdoor; switch (type) { case COURT: if (lev->flags.is_maze_lev) { for (tx = sroom->lx; tx <= sroom->hx; tx++) for (ty = sroom->ly; ty <= sroom->hy; ty++) if (IS_THRONE(lev->locations[tx][ty].typ)) goto throne_placed; } i = 100; do { /* don't place throne on top of stairs */ somexy(lev, sroom, &mm, rng); tx = mm.x; ty = mm.y; } while (occupied(lev, tx, ty) && --i > 0); throne_placed: /* TODO: try to ensure the enthroned monster is an M2_PRINCE */ break; case BEEHIVE: tx = sroom->lx + (sroom->hx - sroom->lx + 1) / 2; ty = sroom->ly + (sroom->hy - sroom->ly + 1) / 2; if (sroom->irregular) { /* center might not be valid, so put queen elsewhere */ if ((int)lev->locations[tx][ty].roomno != rmno || lev->locations[tx][ty].edge) { somexy(lev, sroom, &mm, rng); tx = mm.x; ty = mm.y; } } break; case ZOO: case LEPREHALL: goldlim = 500 * level_difficulty(&lev->z); break; } for (sx = sroom->lx; sx <= sroom->hx; sx++) for (sy = sroom->ly; sy <= sroom->hy; sy++) { if (sroom->irregular) { if ((int)lev->locations[sx][sy].roomno != rmno || lev->locations[sx][sy].edge || (sroom->doorct && distmin(sx, sy, lev->doors[sh].x, lev->doors[sh].y) <= 1)) continue; } else if (!SPACE_POS(lev->locations[sx][sy].typ) || (sroom->doorct && ((sx == sroom->lx && lev->doors[sh].x == sx - 1) || (sx == sroom->hx && lev->doors[sh].x == sx + 1) || (sy == sroom->ly && lev->doors[sh].y == sy - 1) || (sy == sroom->hy && lev->doors[sh].y == sy + 1)))) continue; /* don't place monster on explicitly placed throne */ if (type == COURT && IS_THRONE(lev->locations[sx][sy].typ)) continue; mon = makemon((type == COURT) ? courtmon(&lev->z, rng) : (type == BARRACKS) ? squadmon(&lev->z) : (type == MORGUE) ? morguemon(&lev->z, rng) : (type == BEEHIVE) ? (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : &mons[PM_KILLER_BEE]) : (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] : (type == COCKNEST) ? &mons[PM_COCKATRICE] : (type == ANTHOLE) ? antholemon(&lev->z) : NULL, lev, sx, sy, rng == rng_main ? NO_MM_FLAGS : MM_ALLLEVRNG); if (mon) { mon->msleeping = 1; if (type == COURT && mon->mpeaceful) msethostility(mon, TRUE, TRUE); } switch (type) { case ZOO: case LEPREHALL: if (sroom->doorct) { int distval = dist2(sx, sy, lev->doors[sh].x, lev->doors[sh].y); i = sq(distval); } else i = goldlim; if (i >= goldlim) i = 5 * level_difficulty(&lev->z); goldlim -= i; mkgold(10 + rn2_on_rng(i, rng), lev, sx, sy, rng); break; case MORGUE: if (!rn2_on_rng(5, rng)) mk_tt_object(lev, CORPSE, sx, sy); if (!rn2_on_rng(10, rng)) /* lots of treasure */ mksobj_at(rn2_on_rng(3, rng) ? LARGE_BOX : CHEST, lev, sx, sy, TRUE, FALSE, rng); if (!rn2_on_rng(5, rng)) make_grave(lev, sx, sy, NULL); break; case BEEHIVE: if (!rn2_on_rng(3, rng)) mksobj_at(LUMP_OF_ROYAL_JELLY, lev, sx, sy, TRUE, FALSE, rng); break; case BARRACKS: if (!rn2_on_rng(20, rng)) /* the payroll and some loot */ mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, lev, sx, sy, TRUE, FALSE, rng); break; case COCKNEST: if (!rn2_on_rng(3, rng)) { struct obj *sobj = mk_tt_object(lev, STATUE, sx, sy); if (sobj) { for (i = rn2_on_rng(5, rng); i; i--) add_to_container(sobj, mkobj(lev, RANDOM_CLASS, FALSE, rng)); sobj->owt = weight(sobj); } } break; case ANTHOLE: if (!rn2_on_rng(3, rng)) mkobj_at(FOOD_CLASS, lev, sx, sy, FALSE, rng); break; } } if (type == COURT) { struct obj *chest; lev->locations[tx][ty].typ = THRONE; somexy(lev, sroom, &mm, rng); mkgold(10 + rn2_on_rng(50 * level_difficulty(&lev->z), rng), lev, mm.x, mm.y, rng); /* the royal coffers */ chest = mksobj_at(CHEST, lev, mm.x, mm.y, TRUE, FALSE, rng); chest->spe = 2; /* so it can be found later */ } }