Mercurial > hg > early-roguelike
diff srogue/rooms.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 25 Nov 2010 12:21:41 +0000 |
parents | |
children | 94a0d9dd5ce1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/rooms.c Thu Nov 25 12:21:41 2010 +0000 @@ -0,0 +1,257 @@ +/* + * Draw the nine rooms on the screen + * + * @(#)rooms.c 9.0 (rdk) 7/17/84 + * + * Super-Rogue + * Copyright (C) 1984 Robert D. Kindelberger + * All rights reserved. + * + * Based on "Rogue: Exploring the Dungeons of Doom" + * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + * All rights reserved. + * + * See the file LICENSE.TXT for full copyright and licensing information. + */ + +#include "rogue.h" +#include "rogue.ext" + +/* + * do_rooms: + * Place the rooms in the dungeon + */ +do_rooms() +{ + int mloops, mchance, nummons, left_out, roomtries; + bool treas = FALSE; + reg int i; + reg struct room *rp; + reg struct linked_list *item; + reg struct thing *tp; + struct coord top, bsze, mp; + + /* + * bsze is the maximum room size + */ + bsze.x = COLS / 3; + bsze.y = (LINES - 1) / 3; + /* + * Clear things for a new level + */ + for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) + rp->r_goldval = rp->r_nexits = rp->r_flags = 0; + /* + * Put the gone rooms, if any, on the level + */ + left_out = rnd(4); + for (i = 0; i < left_out; i++) + rooms[rnd_room()].r_flags |= ISGONE; + /* + * dig and populate all the rooms on the level + */ + for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) { + /* + * Find upper left corner of box that this room goes in + */ + top.x = (i%3) * bsze.x + 1; + top.y = i/3 * bsze.y; + if (rf_on(rp,ISGONE)) { + /* + * Place a gone room. Make certain that there is a + * blank line for passage drawing. + */ + roomtries = 0; + do { + rp->r_pos.x = top.x + rnd(bsze.x-2) + 1; + rp->r_pos.y = top.y + rnd(bsze.y-2) + 1; + rp->r_max.x = -COLS; + rp->r_max.x = -LINES; + if (++roomtries > 250) + fatal("failed to place a gone room"); + } until(rp->r_pos.y > 0 && rp->r_pos.y < LINES-2); + continue; + } + if (rnd(10) < level-1) + rp->r_flags |= ISDARK; + /* + * Find a place and size for a random room + */ + roomtries = 0; + do { + rp->r_max.x = rnd(bsze.x - 4) + 4; + rp->r_max.y = rnd(bsze.y - 4) + 4; + rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x); + rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y); + if (++roomtries > 250) { + fatal("failed to place a good room"); + } + } until (rp->r_pos.y != 0); + if (level < max_level) + mchance = 30; /* 30% when going up (all monsters) */ + else + mchance = 3; /* 3% when going down */ + treas = FALSE; + if (rnd(100) < mchance && (rp->r_max.x * rp->r_max.y) > + ((bsze.x * bsze.y * 55) / 100)) { + treas = TRUE; + rp->r_flags |= ISTREAS; + rp->r_flags |= ISDARK; + } + /* + * Put the gold in + */ + if ((rnd(100) < 50 || treas) && (!amulet || level >= max_level)) { + rp->r_goldval = GOLDCALC; + if (treas) + rp->r_goldval += 200 + (15 * (rnd(level) + 2)); + rp->r_gold.y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1; + rp->r_gold.x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1; + } + draw_room(rp); + /* + * Put the monster in + */ + if (treas) { + mloops = rnd(level / 3) + 6; + mchance = 1; + } + else { + mloops = 1; + mchance = 100; + } + for (nummons = 0; nummons < mloops; nummons++) { + if (rnd(mchance) < (rp->r_goldval > 0 ? 80 : 25)) + add_mon(rp, treas); + } + } +} + +/* + * add_mon: + * Add a monster to a room + */ +add_mon(rm, treas) +struct room *rm; +bool treas; +{ + reg struct thing *tp; + reg struct linked_list *item; + struct coord mp; + int chance; + + mp = *rnd_pos(rm); + item = new_monster(rnd_mon(FALSE,FALSE), &mp, treas); + tp = THINGPTR(item); + chance = rnd(100); + if (levtype == MAZELEV) + chance = rnd(50); + /* + * See if monster has a treasure + */ + if (levtype == MAZELEV && rnd(100) < 20) { + reg struct linked_list *fd; + + fd = new_thing(FALSE, FOOD, 0); + attach(tp->t_pack, fd); + } + else { + if (chance < monsters[tp->t_indx].m_carry) + attach(tp->t_pack, new_thing(FALSE, ANYTHING)); + } +} + +/* + * draw_room: + * Draw a box around a room + */ +draw_room(rp) +struct room *rp; +{ + reg int j, k; + + move(rp->r_pos.y, rp->r_pos.x+1); + vert(rp->r_max.y-2); /* Draw left side */ + move(rp->r_pos.y+rp->r_max.y-1, rp->r_pos.x); + horiz(rp->r_max.x); /* Draw bottom */ + move(rp->r_pos.y, rp->r_pos.x); + horiz(rp->r_max.x); /* Draw top */ + vert(rp->r_max.y-2); /* Draw right side */ + /* + * Put the floor down + */ + for (j = 1; j < rp->r_max.y - 1; j++) { + move(rp->r_pos.y + j, rp->r_pos.x + 1); + for (k = 1; k < rp->r_max.x - 1; k++) { + addch(FLOOR); + } + } + /* + * Put the gold there + */ + if (rp->r_goldval > 0) + mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD); +} + +/* + * horiz: + * draw a horizontal line + */ +horiz(cnt) +int cnt; +{ + while (cnt-- > 0) + addch('-'); +} + + +/* + * vert: + * draw a vertical line + */ +vert(cnt) +int cnt; +{ + reg int x, y; + + getyx(stdscr, y, x); + x--; + while (cnt-- > 0) { + move(++y, x); + addch('|'); + } +} + + +/* + * rnd_pos: + * pick a random spot in a room + */ +struct coord * +rnd_pos(rp) +struct room *rp; +{ + reg int y, x, i; + static struct coord spot; + + i = 0; + do { + x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1; + y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1; + i += 1; + } while(winat(y, x) != FLOOR && i < 1000); + spot.x = x; + spot.y = y; + return &spot; +} + +/* + * rf_on: + * Returns TRUE if flag is set for room stuff + */ +rf_on(rm, bit) +struct room *rm; +long bit; +{ + return (rm->r_flags & bit); +}