Mercurial > hg > early-roguelike
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 |