Mercurial > hg > early-roguelike
diff rogue4/rooms.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Sat, 24 Oct 2009 16:52:52 +0000 |
parents | |
children | 1b73a8641b37 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rogue4/rooms.c Sat Oct 24 16:52:52 2009 +0000 @@ -0,0 +1,275 @@ +/* + * Create the layout for the new level + * + * @(#)rooms.c 4.16 (Berkeley) 1/12/82 + * + * Rogue: Exploring the Dungeons of Doom + * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman + * All rights reserved. + * + * See the file LICENSE.TXT for full copyright and licensing information. + */ + +#include <ctype.h> +#include <curses.h> +#include "rogue.h" + +#define GOLDGRP 1 + +/* + * do_rooms: + * Create rooms and corridors with a connectivity graph + */ +do_rooms() +{ + register int i; + register struct room *rp; + register THING *tp; + register int left_out; + coord top; + coord bsze; + coord mp; + + /* + * bsze is the maximum room size + */ + bsze.x = COLS/3; + bsze.y = LINES/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 (rp->r_flags & ISGONE) + { + /* + * Place a gone room. Make certain that there is a blank line + * for passage drawing. + */ + 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; + } until (rp->r_pos.y > 0 && rp->r_pos.y < LINES-1); + continue; + } + if (rnd(10) < level - 1) + rp->r_flags |= ISDARK; + /* + * Find a place and size for a random room + */ + 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); + } until (rp->r_pos.y != 0); + /* + * Put the gold in + */ + if (rnd(2) == 0 && (!amulet || level >= max_level)) + { + register THING *gold; + + gold = new_item(); + gold->o_goldval = rp->r_goldval = GOLDCALC; + rnd_pos(rp, &rp->r_gold); + gold->o_pos = rp->r_gold; + gold->o_flags = ISMANY; + gold->o_group = GOLDGRP; + gold->o_type = GOLD; + attach(lvl_obj, gold); + } + draw_room(rp); + /* + * Put the monster in + */ + if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25)) + { + tp = new_item(); + do + { + rnd_pos(rp, &mp); + } until (winat(mp.y, mp.x) == FLOOR); + new_monster(tp, randmonster(FALSE), &mp); + give_pack(tp); + } + } +} + +/* + * draw_room: + * Draw a box around a room and lay down the floor + */ +draw_room(rp) +register struct room *rp; +{ + register int y, x; + + vert(rp, rp->r_pos.x); /* Draw left side */ + vert(rp, rp->r_pos.x + rp->r_max.x - 1); /* Draw right side */ + horiz(rp, rp->r_pos.y); /* Draw top */ + horiz(rp, rp->r_pos.y + rp->r_max.y - 1); /* Draw bottom */ + /* + * Put the floor down + */ + for (y = rp->r_pos.y + 1; y < rp->r_pos.y + rp->r_max.y - 1; y++) + /*strrep(&chat(rp->r_pos.y + 1, j), FLOOR, rp->r_max.y - rp->r_pos.y - 2);*/ + for (x = rp->r_pos.x + 1; x < rp->r_pos.x + rp->r_max.x - 1; x++) + chat(y, x) = FLOOR; + /* + * Put the gold there + */ + if (rp->r_goldval) + chat(rp->r_gold.y, rp->r_gold.x) = GOLD; +} + +/* + * vert: + * Draw a vertical line + */ +vert(rp, startx) +register struct room *rp; +register int startx; +{ + register int y; + + for (y = rp->r_pos.y + 1; y <= rp->r_max.y + rp->r_pos.y - 1; y++) + chat(y, startx) = '|'; +} + +/* + * horiz: + * Draw a horizontal line + */ +horiz(rp, starty) +register struct room *rp; +int starty; +{ + register int x; + + for (x = rp->r_pos.x; x <= rp->r_pos.x + rp->r_max.x - 1; x++) + chat(starty, x) = '-'; +} + +/* + * rnd_pos: + * Pick a random spot in a room + */ +rnd_pos(rp, cp) +register struct room *rp; +register coord *cp; +{ + cp->x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1; + cp->y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1; +} + +/* + * enter_room: + * Code that is executed whenver you appear in a room + */ +enter_room(cp) +register coord *cp; +{ + register struct room *rp; + register int y, x; + register THING *tp; + + rp = proom = roomin(cp); + if (rp->r_flags & ISGONE) + { + msg("in a gone room"); + return; + } + door_open(rp); + if (!(rp->r_flags & ISDARK) && !on(player, ISBLIND)) + for (y = rp->r_pos.y; y < rp->r_max.y + rp->r_pos.y; y++) + { + move(y, rp->r_pos.x); + for (x = rp->r_pos.x; x < rp->r_max.x + rp->r_pos.x; x++) + { + tp = moat(y, x); + if (tp == NULL || !see_monst(tp)) + addch(chat(y, x)); + else + addch(tp->t_disguise); + } + } +} + +/* + * leave_room: + * Code for when we exit a room + */ +leave_room(cp) +register coord *cp; +{ + register int y, x; + register struct room *rp; + register char floor; + register char ch; + + rp = proom; + proom = &passages[flat(cp->y, cp->x) & F_PNUM]; + floor = ((rp->r_flags & ISDARK) && !on(player, ISBLIND)) ? ' ' : FLOOR; + for (y = rp->r_pos.y + 1; y < rp->r_max.y + rp->r_pos.y - 1; y++) + for (x = rp->r_pos.x + 1; x < rp->r_max.x + rp->r_pos.x - 1; x++) + switch (ch = mvinch(y, x)) + { + case ' ': + case TRAP: + case STAIRS: + break; + case FLOOR: + if (floor == ' ') + addch(' '); + break; + default: + /* + * to check for monster, we have to strip out + * standout bit + */ + if (isupper(toascii(ch))) + if (on(player, SEEMONST)) + { + standout(); + addch(ch); + standend(); + break; + } + else + { + THING *tp = moat(y, x); + + if (tp != NULL) + tp->t_oldch = floor; + +#ifdef WIZARD + else + msg("couldn't find monster in leave_room at (%d,%d)", y, x); +#endif + } + + addch(floor); + } + door_open(rp); +}