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