comparison arogue7/rooms.c @ 125:adfa37e67084

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