comparison 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
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 rooms.c - Draw the nine rooms on the screen
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <curses.h>
20 #include "rogue.h"
21
22 do_rooms()
23 {
24 register int i;
25 register struct room *rp;
26 register struct linked_list *item;
27 register struct thing *tp;
28 int left_out;
29 int num_monsters;
30 int which_monster;
31 int j;
32 coord top;
33 coord bsze;
34 coord mp;
35 coord *np;
36
37 /*
38 * bsze is the maximum room size
39 */
40 bsze.x = cols/3;
41 bsze.y = (lines-2)/3;
42 /*
43 * Clear things for a new level
44 */
45 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
46 rp->r_flags = 0;
47 _r_free_fire_list(&rp->r_fires);
48 }
49 /*
50 * Put the gone rooms, if any, on the level
51 */
52 left_out = rnd(4);
53 for (i = 0; i < left_out; i++)
54 rooms[rnd_room()].r_flags |= ISGONE;
55 /*
56 * dig and populate all the rooms on the level
57 */
58 for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++)
59 {
60 bool has_gold=FALSE;
61
62 /*
63 * Find upper left corner of box that this room goes in
64 */
65 top.x = (i%3)*bsze.x;
66 top.y = i/3*bsze.y + 1;
67 if (rp->r_flags & ISGONE)
68 {
69 /*
70 * Place a gone room. Make certain that there is a blank line
71 * for passage drawing.
72 */
73 do
74 {
75 rp->r_pos.x = top.x + rnd(bsze.x-2) + 1;
76 rp->r_pos.y = top.y + rnd(bsze.y-2) + 1;
77 rp->r_max.x = -cols;
78 rp->r_max.y = -lines;
79 } until(rp->r_pos.y > 0 && rp->r_pos.y < lines-2);
80 continue;
81 }
82 if (rnd(10) < level-1)
83 rp->r_flags |= ISDARK;
84 /*
85 * Find a place and size for a random room
86 */
87 do
88 {
89 rp->r_max.x = rnd(bsze.x - 4) + 4;
90 rp->r_max.y = rnd(bsze.y - 4) + 4;
91 rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
92 rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
93 } until (rp->r_pos.y != 0);
94
95 /* Draw the room */
96 draw_room(rp);
97
98 /*
99 * Put the gold in
100 */
101 if (rnd(100) < 55 && level >= cur_max)
102 {
103 register struct linked_list *item;
104 register struct object *cur;
105 coord tp;
106
107 has_gold = TRUE; /* This room has gold in it */
108
109 item = spec_item(GOLD, NULL, NULL, NULL);
110 cur = OBJPTR(item);
111
112 /* Put the gold into the level list of items */
113 attach(lvl_obj, item);
114
115 /* Put it somewhere */
116 rnd_pos(rp, &tp);
117 mvaddch(tp.y, tp.x, GOLD);
118 cur->o_pos = tp;
119 if (roomin(&tp) != rp) {
120 endwin();
121 abort();
122 }
123 }
124
125 /*
126 * Put the monster in
127 */
128 if (rnd(100) < (has_gold ? 80 : 25) + vlevel/2)
129 {
130 do
131 {
132 rnd_pos(rp, &mp);
133 } until(mvwinch(stdscr, mp.y, mp.x) == FLOOR);
134 which_monster = randmonster(FALSE, FALSE);
135 num_monsters = 1;
136 /*
137 * see if we should make a whole bunch
138 */
139 for (j=0; j<MAXFLAGS; j++) {
140 if (monsters[which_monster].m_flags[j] == AREMANY)
141 num_monsters = roll(7,2);
142 }
143 for (j=0; j<num_monsters; j++) {
144 if ((np = fallpos(&mp, FALSE, 2)) != NULL &&
145 mvwinch(stdscr, np->y, np->x) == FLOOR) {
146 item = new_item(sizeof *tp);
147 tp = THINGPTR(item);
148 new_monster(item, which_monster, np, FALSE);
149 /*
150 * See if we want to give it a treasure to
151 * carry around.
152 */
153 carry_obj(tp, monsters[tp->t_index].m_carry);
154 tp->t_no_move = movement(tp);
155
156 /*
157 * If it has a fire, mark it
158 */
159 if (on(*tp, HASFIRE)) {
160 register struct linked_list *fire_item;
161
162 fire_item = creat_item();
163 ldata(fire_item) = (char *) tp;
164 attach(rp->r_fires, fire_item);
165 rp->r_flags |= HASFIRE;
166 }
167 }
168 }
169 }
170 }
171 }
172
173 /*
174 * Given a room pointer and a pointer to a door, supposedly in that room,
175 * return the coordinates of the entrance to the doorway.
176 */
177
178 coord *
179 doorway(rp, door)
180 register struct room *rp;
181 register coord *door;
182 {
183 register int misses = 0;
184 static coord answer;
185
186 /* Do we have decent parameters? */
187 if (rp == NULL || door == NULL) return(NULL);
188
189 /* Initialize the answer to be the door, then calculate the offset */
190 answer = *door;
191
192 /* Calculate the x-offset */
193 if (door->x == rp->r_pos.x) answer.x++;
194 else if (door->x == rp->r_pos.x + rp->r_max.x - 1) answer.x--;
195 else misses++;
196
197 /* Calculate the y-offset */
198 if (door->y == rp->r_pos.y) answer.y++;
199 else if (door->y == rp->r_pos.y + rp->r_max.y - 1) answer.y--;
200 else misses++;
201
202 if (misses <= 1) return(&answer);
203 else return(NULL);
204 }
205
206 /*
207 * Draw a box around a room
208 */
209
210 draw_room(rp)
211 register struct room *rp;
212 {
213 register int j, k;
214
215 move(rp->r_pos.y, rp->r_pos.x+1);
216 vert(rp->r_max.y-2); /* Draw left side */
217 move(rp->r_pos.y+rp->r_max.y-1, rp->r_pos.x);
218 horiz(rp->r_max.x); /* Draw bottom */
219 move(rp->r_pos.y, rp->r_pos.x);
220 horiz(rp->r_max.x); /* Draw top */
221 vert(rp->r_max.y-2); /* Draw right side */
222 /*
223 * Put the floor down
224 */
225 for (j = 1; j < rp->r_max.y-1; j++)
226 {
227 move(rp->r_pos.y + j, rp->r_pos.x+1);
228 for (k = 1; k < rp->r_max.x-1; k++)
229 addch(FLOOR);
230 }
231 }
232
233 /*
234 * horiz:
235 * draw a horizontal line
236 */
237
238 horiz(cnt)
239 register int cnt;
240 {
241 while (cnt--)
242 addch(HORZWALL);
243 }
244
245 /*
246 * rnd_pos:
247 * pick a random spot in a room
248 */
249
250 rnd_pos(rp, cp)
251 register struct room *rp;
252 register coord *cp;
253 {
254 cp->x = rp->r_pos.x + rnd(rp->r_max.x-2) + 1;
255 cp->y = rp->r_pos.y + rnd(rp->r_max.y-2) + 1;
256 }
257
258
259
260 /*
261 * roomin:
262 * Find what room some coordinates are in. NULL means they aren't
263 * in any room.
264 */
265
266 struct room *
267 roomin(cp)
268 register coord *cp;
269 {
270 register struct room *rp;
271
272 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
273 if (inroom(rp, cp))
274 return rp;
275 return NULL;
276 }
277
278 /*
279 * vert:
280 * draw a vertical line
281 */
282
283 vert(cnt)
284 register int cnt;
285 {
286 register int x, y;
287
288 getyx(stdscr, y, x);
289 x--;
290 while (cnt--) {
291 move(++y, x);
292 addch(VERTWALL);
293 }
294 }
295