comparison urogue/rooms.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 rooms.c - Draw the nine rooms on the screen
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
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 <stdlib.h>
20 #include "rogue.h"
21
22 void
23 do_rooms(void)
24 {
25 int i;
26 struct room *rp;
27 struct linked_list *item;
28 struct thing *tp;
29 int left_out;
30 coord top;
31 coord bsze;
32 coord mp;
33
34 /* bsze is the maximum room size */
35
36 bsze.x = COLS / 3;
37 bsze.y = (LINES - 2) / 3;
38
39 /* Clear things for a new level */
40
41 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
42 rp->r_nexits = rp->r_flags = rp->r_fires = 0;
43
44 /* Put the gone rooms, if any, on the level */
45
46 left_out = rnd(3);
47
48 for (i = 0; i < left_out; i++)
49 rooms[rnd_room()].r_flags |= ISGONE;
50
51 /* dig and populate all the rooms on the level */
52
53 for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++)
54 {
55 int has_gold = FALSE;
56
57 /* Find upper left corner of box that this room goes in */
58
59 top.x = (i % 3) * bsze.x;
60 top.y = i / 3 * bsze.y + 1;
61
62 if (rp->r_flags & ISGONE)
63 {
64 /*
65 * Place a gone room. Make certain that there is a
66 * blank line for passage drawing.
67 */
68
69 do
70 {
71 rp->r_pos.x = top.x + rnd(bsze.x - 2) + 1;
72 rp->r_pos.y = top.y + rnd(bsze.y - 2) + 1;
73 rp->r_max.x = -COLS;
74 rp->r_max.x = -LINES;
75 }
76 while (rp->r_pos.y < 1 || rp->r_pos.y > LINES - 3);
77
78 continue;
79 }
80
81 if (rnd(40) < level - 5)
82 rp->r_flags |= ISDARK;
83
84 /* Find a place and size for a random room */
85
86 do
87 {
88 rp->r_max.x = rnd(bsze.x - 4) + 4;
89 rp->r_max.y = rnd(bsze.y - 4) + 4;
90 rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
91 rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
92 }
93 while (rp->r_pos.y == 0);
94
95 /* Draw the room */
96
97 draw_room(rp);
98
99 /* Put the gold in */
100
101 if (rnd(10) < 3 && (!has_artifact || level >= max_level))
102 {
103 struct linked_list *itm;
104 struct object *cur;
105 coord tpos;
106
107 has_gold = TRUE; /* This room has gold in it */
108
109 itm = spec_item(GOLD, 0, 0, 0);
110 cur = OBJPTR(itm);
111
112 /* Put it somewhere */
113
114 rnd_pos(rp, &tpos);
115 cur->o_pos = tpos;
116
117 /* Put the gold into the level list of items */
118
119 add_obj(itm, tpos.y, tpos.x);
120
121 if (roomin(tpos) != rp)
122 {
123 endwin();
124 abort();
125 }
126 }
127
128 /* Put the monster in */
129
130 if (rnd(100) < (has_gold ? 80 : 40))
131 {
132 int which;
133 int n, cnt;
134
135 item = new_item(sizeof *tp);
136 tp = THINGPTR(item);
137
138 do
139 rnd_pos(rp, &mp);
140 while (mvwinch(stdscr, mp.y, mp.x) != FLOOR);
141
142 which = randmonster(NOWANDER, NOGRAB);
143 new_monster(item, which, &mp, NOMAXSTATS);
144
145 /* See if we want to give it a treasure to carry around. */
146
147 if (rnd(100) < monsters[tp->t_index].m_carry)
148 attach(tp->t_pack, new_thing());
149
150 /* If it has a fire, mark it */
151
152 if (on(*tp, HASFIRE))
153 {
154 rp->r_flags |= HASFIRE;
155 rp->r_fires++;
156 }
157
158 /* If it carries gold, give it some */
159
160 if (on(*tp, CARRYGOLD))
161 {
162 struct object *cur;
163
164 item = spec_item(GOLD, 0, 0, 0);
165 cur = OBJPTR(item);
166 cur->o_count = GOLDCALC + GOLDCALC + GOLDCALC;
167 cur->o_pos = tp->t_pos;
168 attach(tp->t_pack, item);
169 }
170
171 n = rnd(7);
172
173 if (on(*tp, ISSWARM) && n < 5)
174 cnt = roll(2, 4);
175 else if (on(*tp, ISFLOCK) && n < 5)
176 cnt = roll(1, 4);
177 else
178 cnt = 0;
179
180 for (n = 1; n <= cnt; n++)
181 {
182 coord pos;
183
184 if (place_mons(mp.y, mp.x, &pos)!= FALSE)
185 {
186 struct linked_list *nitem;
187
188 nitem = new_item(sizeof(struct thing));
189 new_monster(nitem, which, &pos, NOMAXSTATS);
190
191 /* If the monster is on a trap, trap it */
192
193 if (isatrap(mvinch(pos.y, pos.x)))
194 be_trapped(THINGPTR(nitem), mp);
195
196 if (on(*tp, ISFRIENDLY))
197 turn_on(*(THINGPTR(nitem)), ISFRIENDLY);
198 else
199 turn_off(*(THINGPTR(nitem)), ISFRIENDLY);
200 }
201 }
202
203 if (cnt > 0)
204 {
205 int boost = rnd(3) + 1;
206
207 if (on(*tp, LOWCAST) || on(*tp, MEDCAST) || on(*tp, HIGHCAST))
208 turn_on(*tp, CANCAST);
209
210 tp->t_stats.s_hpt += 3 * boost;
211 tp->t_stats.s_arm -= 2 * boost;
212 tp->t_stats.s_lvl += 2 * boost;
213 tp->t_stats.s_str += 2 * boost;
214 tp->t_stats.s_intel += 2 * boost;
215 tp->t_stats.s_exp += 4 * boost * monsters[which].m_add_exp;
216 }
217 }
218 }
219 }
220
221 /*
222 draw_room()
223 Draw a box around a room
224 */
225
226 void
227 draw_room(struct room *rp)
228 {
229 int j, k;
230
231 move(rp->r_pos.y, rp->r_pos.x + 1);
232 vert(rp->r_max.y - 2); /* Draw left side */
233 move(rp->r_pos.y + rp->r_max.y - 1, rp->r_pos.x);
234 horiz(rp->r_max.x); /* Draw bottom */
235 move(rp->r_pos.y, rp->r_pos.x);
236 horiz(rp->r_max.x); /* Draw top */
237 vert(rp->r_max.y - 2); /* Draw right side */
238
239 /* Put the floor down */
240
241 for (j = 1; j < rp->r_max.y - 1; j++)
242 {
243 move(rp->r_pos.y + j, rp->r_pos.x + 1);
244
245 for (k = 1; k < rp->r_max.x - 1; k++)
246 addch(FLOOR);
247 }
248 }
249
250 /*
251 horiz()
252 draw a horizontal line
253 */
254
255 void
256 horiz(int cnt)
257 {
258 while(cnt--)
259 addch('-');
260 }
261
262 /*
263 vert()
264 draw a vertical line
265 */
266
267 void
268 vert(int cnt)
269 {
270 int x, y;
271
272 getyx(stdscr, y, x);
273
274 x--;
275
276 while(cnt--)
277 {
278 move(++y, x);
279 addch('|');
280 }
281 }
282
283 /*
284 rnd_pos()
285 pick a random spot in a room
286 */
287
288 void
289 rnd_pos(struct room *rp, coord *cp)
290 {
291 cp->x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1;
292 cp->y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1;
293 }
294
295 /*
296 rnd_room()
297 Pick a room that is really there
298 */
299
300 int
301 rnd_room(void)
302 {
303 int rm;
304
305 if (levtype != NORMLEV)
306 rm = 0;
307 else
308 do
309 {
310 rm = rnd(MAXROOMS);
311 }
312 while (rooms[rm].r_flags & ISGONE);
313
314 return(rm);
315 }