Mercurial > hg > early-roguelike
diff xrogue/rooms.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 21 Apr 2015 08:55:20 -0400 |
parents | |
children | ce0cf824c192 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xrogue/rooms.c Tue Apr 21 08:55:20 2015 -0400 @@ -0,0 +1,295 @@ +/* + rooms.c - Draw the nine rooms on the screen + + XRogue: Expeditions into the Dungeons of Doom + Copyright (C) 1991 Robert Pietkivitch + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T + 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 <curses.h> +#include "rogue.h" + +do_rooms() +{ + register int i; + register struct room *rp; + register struct linked_list *item; + register struct thing *tp; + int left_out; + int num_monsters; + int which_monster; + int j; + coord top; + coord bsze; + coord mp; + coord *np; + + /* + * bsze is the maximum room size + */ + bsze.x = cols/3; + bsze.y = (lines-2)/3; + /* + * Clear things for a new level + */ + for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) { + rp->r_flags = 0; + _r_free_fire_list(&rp->r_fires); + } + /* + * 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++) + { + bool has_gold=FALSE; + + /* + * Find upper left corner of box that this room goes in + */ + top.x = (i%3)*bsze.x; + top.y = i/3*bsze.y + 1; + 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.y = -lines; + } 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 + */ + 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); + + /* Draw the room */ + draw_room(rp); + + /* + * Put the gold in + */ + if (rnd(100) < 55 && level >= cur_max) + { + register struct linked_list *item; + register struct object *cur; + coord tp; + + has_gold = TRUE; /* This room has gold in it */ + + item = spec_item(GOLD, NULL, NULL, NULL); + cur = OBJPTR(item); + + /* Put the gold into the level list of items */ + attach(lvl_obj, item); + + /* Put it somewhere */ + rnd_pos(rp, &tp); + mvaddch(tp.y, tp.x, GOLD); + cur->o_pos = tp; + if (roomin(&tp) != rp) { + endwin(); + abort(); + } + } + + /* + * Put the monster in + */ + if (rnd(100) < (has_gold ? 80 : 25) + vlevel/2) + { + do + { + rnd_pos(rp, &mp); + } until(mvwinch(stdscr, mp.y, mp.x) == FLOOR); + which_monster = randmonster(FALSE, FALSE); + num_monsters = 1; + /* + * see if we should make a whole bunch + */ + for (j=0; j<MAXFLAGS; j++) { + if (monsters[which_monster].m_flags[j] == AREMANY) + num_monsters = roll(7,2); + } + for (j=0; j<num_monsters; j++) { + if ((np = fallpos(&mp, FALSE, 2)) != NULL && + mvwinch(stdscr, np->y, np->x) == FLOOR) { + item = new_item(sizeof *tp); + tp = THINGPTR(item); + new_monster(item, which_monster, np, FALSE); + /* + * See if we want to give it a treasure to + * carry around. + */ + carry_obj(tp, monsters[tp->t_index].m_carry); + tp->t_no_move = movement(tp); + + /* + * If it has a fire, mark it + */ + if (on(*tp, HASFIRE)) { + register struct linked_list *fire_item; + + fire_item = creat_item(); + ldata(fire_item) = (char *) tp; + attach(rp->r_fires, fire_item); + rp->r_flags |= HASFIRE; + } + } + } + } + } +} + +/* + * Given a room pointer and a pointer to a door, supposedly in that room, + * return the coordinates of the entrance to the doorway. + */ + +coord * +doorway(rp, door) +register struct room *rp; +register coord *door; +{ + register int misses = 0; + static coord answer; + + /* Do we have decent parameters? */ + if (rp == NULL || door == NULL) return(NULL); + + /* Initialize the answer to be the door, then calculate the offset */ + answer = *door; + + /* Calculate the x-offset */ + if (door->x == rp->r_pos.x) answer.x++; + else if (door->x == rp->r_pos.x + rp->r_max.x - 1) answer.x--; + else misses++; + + /* Calculate the y-offset */ + if (door->y == rp->r_pos.y) answer.y++; + else if (door->y == rp->r_pos.y + rp->r_max.y - 1) answer.y--; + else misses++; + + if (misses <= 1) return(&answer); + else return(NULL); +} + +/* + * Draw a box around a room + */ + +draw_room(rp) +register struct room *rp; +{ + register 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); + } +} + +/* + * horiz: + * draw a horizontal line + */ + +horiz(cnt) +register int cnt; +{ + while (cnt--) + addch(HORZWALL); +} + +/* + * 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; +} + + + +/* + * roomin: + * Find what room some coordinates are in. NULL means they aren't + * in any room. + */ + +struct room * +roomin(cp) +register coord *cp; +{ + register struct room *rp; + + for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) + if (inroom(rp, cp)) + return rp; + return NULL; +} + +/* + * vert: + * draw a vertical line + */ + +vert(cnt) +register int cnt; +{ + register int x, y; + + getyx(stdscr, y, x); + x--; + while (cnt--) { + move(++y, x); + addch(VERTWALL); + } +} +