Prevent crash due to buffer overflow detection (and on some platforms probably actual...
[rogue-pphs.git] / rooms.c
1 /*
2 * Draw the nine rooms on the screen
3 *
4 * @(#)rooms.c 3.8 (Berkeley) 6/15/81
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include "curses.h"
14 #include "rogue.h"
15
16 do_rooms()
17 {
18 register int i;
19 register struct room *rp;
20 register struct linked_list *item;
21 register struct thing *tp;
22 register int left_out;
23 coord top;
24 coord bsze;
25 coord mp;
26
27 /*
28 * bsze is the maximum room size
29 */
30 bsze.x = COLS/3;
31 bsze.y = LINES/3;
32 /*
33 * Clear things for a new level
34 */
35 for (rp = rooms; rp <= &rooms[MAXROOMS-1]; rp++)
36 rp->r_goldval = rp->r_nexits = rp->r_flags = 0;
37 /*
38 * Put the gone rooms, if any, on the level
39 */
40 left_out = rnd(4);
41 for (i = 0; i < left_out; i++)
42 rooms[rnd_room()].r_flags |= ISGONE;
43 /*
44 * dig and populate all the rooms on the level
45 */
46 for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++)
47 {
48 /*
49 * Find upper left corner of box that this room goes in
50 */
51 top.x = (i%3)*bsze.x + 1;
52 top.y = i/3*bsze.y;
53 if (rp->r_flags & ISGONE)
54 {
55 /*
56 * Place a gone room. Make certain that there is a blank line
57 * for passage drawing.
58 */
59 do
60 {
61 rp->r_pos.x = top.x + rnd(bsze.x-2) + 1;
62 rp->r_pos.y = top.y + rnd(bsze.y-2) + 1;
63 rp->r_max.x = -COLS;
64 rp->r_max.y = -LINES;
65 } until(rp->r_pos.y > 0 && rp->r_pos.y < LINES-1);
66 continue;
67 }
68 if (rnd(10) < level-1)
69 rp->r_flags |= ISDARK;
70 /*
71 * Find a place and size for a random room
72 */
73 do
74 {
75 rp->r_max.x = rnd(bsze.x - 4) + 4;
76 rp->r_max.y = rnd(bsze.y - 4) + 4;
77 rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
78 rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
79 } until (rp->r_pos.y != 0);
80 /*
81 * Put the gold in
82 */
83 if (rnd(100) < 50 && (!amulet || level >= max_level))
84 {
85 rp->r_goldval = GOLDCALC;
86 rnd_pos(rp, &rp->r_gold);
87 if (roomin(&rp->r_gold) != rp)
88 endwin(), abort();
89 }
90 draw_room(rp);
91 /*
92 * Put the monster in
93 */
94 if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25))
95 {
96 item = new_item(sizeof *tp);
97 tp = (struct thing *) ldata(item);
98 do
99 {
100 rnd_pos(rp, &mp);
101 } until(mvwinch(stdscr, mp.y, mp.x) == FLOOR);
102 new_monster(item, randmonster(FALSE), &mp);
103 /*
104 * See if we want to give it a treasure to carry around.
105 */
106 if (rnd(100) < monsters[tp->t_type-'A'].m_carry)
107 attach(tp->t_pack, new_thing());
108 }
109 }
110 }
111
112 /*
113 * Draw a box around a room
114 */
115
116 draw_room(rp)
117 register struct room *rp;
118 {
119 register int j, k;
120
121 move(rp->r_pos.y, rp->r_pos.x+1);
122 vert(rp->r_max.y-2); /* Draw left side */
123 move(rp->r_pos.y+rp->r_max.y-1, rp->r_pos.x);
124 horiz(rp->r_max.x); /* Draw bottom */
125 move(rp->r_pos.y, rp->r_pos.x);
126 horiz(rp->r_max.x); /* Draw top */
127 vert(rp->r_max.y-2); /* Draw right side */
128 /*
129 * Put the floor down
130 */
131 for (j = 1; j < rp->r_max.y-1; j++)
132 {
133 move(rp->r_pos.y + j, rp->r_pos.x+1);
134 for (k = 1; k < rp->r_max.x-1; k++)
135 addch(FLOOR);
136 }
137 /*
138 * Put the gold there
139 */
140 if (rp->r_goldval)
141 mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD);
142 }
143
144 /*
145 * horiz:
146 * draw a horizontal line
147 */
148
149 horiz(cnt)
150 register int cnt;
151 {
152 while (cnt--)
153 addch('-');
154 }
155
156 /*
157 * vert:
158 * draw a vertical line
159 */
160
161 vert(cnt)
162 register int cnt;
163 {
164 register int x, y;
165
166 getyx(stdscr, y, x);
167 x--;
168 while (cnt--) {
169 move(++y, x);
170 addch('|');
171 }
172 }
173
174 /*
175 * rnd_pos:
176 * pick a random spot in a room
177 */
178
179 rnd_pos(rp, cp)
180 register struct room *rp;
181 register coord *cp;
182 {
183 cp->x = rp->r_pos.x + rnd(rp->r_max.x-2) + 1;
184 cp->y = rp->r_pos.y + rnd(rp->r_max.y-2) + 1;
185 }