Mercurial > hg > early-roguelike
comparison urogue/maze.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 maze.c - functions for dealing with armor | |
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 See the file LICENSE.TXT for full copyright and licensing information. | |
13 */ | |
14 | |
15 #include <stdlib.h> | |
16 #include "rogue.h" | |
17 | |
18 static char *frontier; | |
19 static char *bits; | |
20 static int urlines; | |
21 static int urcols; | |
22 | |
23 /* | |
24 domaze() | |
25 Draw the maze on this level. | |
26 */ | |
27 | |
28 void | |
29 do_maze(void) | |
30 { | |
31 int i, least; | |
32 struct room *rp; | |
33 struct linked_list *item; | |
34 struct object *obj; | |
35 struct thing *mp; | |
36 int treas; | |
37 coord tp; | |
38 | |
39 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) | |
40 { | |
41 rp->r_nexits = 0; /* no exits */ | |
42 rp->r_flags = ISGONE; /* kill all rooms */ | |
43 rp->r_fires = 0; /* no fires */ | |
44 } | |
45 | |
46 rp = &rooms[0]; /* point to only room */ | |
47 rp->r_flags = ISDARK; /* mazes always dark */ | |
48 rp->r_pos.x = 0; /* room fills whole screen */ | |
49 rp->r_pos.y = 1; | |
50 rp->r_max.x = COLS - 1; | |
51 rp->r_max.y = LINES - 3; | |
52 draw_maze(); /* put maze into window */ | |
53 | |
54 /* add some gold to make it worth looking for */ | |
55 | |
56 item = spec_item(GOLD, 0, 0, 0); | |
57 obj = OBJPTR(item); | |
58 obj->o_count *= (rnd(10) + 5); /* add in one large hunk */ | |
59 | |
60 do | |
61 { | |
62 rnd_pos(rp, &tp); | |
63 } | |
64 while( mvwinch(stdscr, tp.y, tp.x) != FLOOR); | |
65 | |
66 obj->o_pos = tp; | |
67 add_obj(item, tp.y, tp.x); | |
68 | |
69 /* add in some food to make sure he has enough */ | |
70 | |
71 item = spec_item(FOOD, 0, 0, 0); | |
72 obj = OBJPTR(item); | |
73 | |
74 do | |
75 { | |
76 rnd_pos(rp, &tp); | |
77 } | |
78 while( mvwinch(stdscr, tp.y, tp.x) != FLOOR); | |
79 | |
80 obj->o_pos = tp; | |
81 add_obj(item, tp.y, tp.x); | |
82 | |
83 if (rnd(100) < 5) /* 5% for treasure maze level */ | |
84 { | |
85 treas = TRUE; | |
86 least = 20; | |
87 debug("Treasure maze."); | |
88 } | |
89 else /* normal maze level */ | |
90 { | |
91 least = 1; | |
92 treas = FALSE; | |
93 } | |
94 | |
95 for (i = 0; i < level + least; i++) | |
96 { | |
97 if (!treas && rnd(100) < 50) /* put in some little buggers */ | |
98 continue; | |
99 | |
100 /* Put the monster in */ | |
101 | |
102 item = new_item(sizeof *mp); | |
103 | |
104 mp = THINGPTR(item); | |
105 | |
106 do | |
107 { | |
108 rnd_pos(rp, &tp); | |
109 } | |
110 while(mvwinch(stdscr, tp.y, tp.x) != FLOOR); | |
111 | |
112 new_monster(item, randmonster(NOWANDER, NOGRAB), &tp, NOMAXSTATS); | |
113 | |
114 /* See if we want to give it a treasure to carry around. */ | |
115 | |
116 if (rnd(100) < monsters[mp->t_index].m_carry) | |
117 attach(mp->t_pack, new_thing()); | |
118 | |
119 /* If it carries gold, give it some */ | |
120 | |
121 if (on(*mp, CARRYGOLD)) | |
122 { | |
123 item = spec_item(GOLD, 0, 0, 0); | |
124 obj = OBJPTR(item); | |
125 obj->o_count = GOLDCALC + GOLDCALC + GOLDCALC; | |
126 obj->o_pos = mp->t_pos; | |
127 attach(mp->t_pack, item); | |
128 } | |
129 | |
130 } | |
131 } | |
132 | |
133 /* | |
134 draw_maze() | |
135 Generate and draw the maze on the screen | |
136 */ | |
137 | |
138 void | |
139 draw_maze(void) | |
140 { | |
141 int i, j, more; | |
142 char *ptr; | |
143 | |
144 urlines = (LINES - 3) / 2; | |
145 urcols = (COLS - 1) / 2; | |
146 | |
147 bits = ur_alloc((unsigned int) ((LINES - 3) * (COLS - 1))); | |
148 frontier = ur_alloc((unsigned int) (urlines * urcols)); | |
149 ptr = frontier; | |
150 | |
151 while (ptr < (frontier + (urlines * urcols))) | |
152 *ptr++ = TRUE; | |
153 | |
154 for (i = 0; i < LINES - 3; i++) | |
155 { | |
156 for (j = 0; j < COLS - 1; j++) | |
157 { | |
158 if (i % 2 == 1 && j % 2 == 1) | |
159 *moffset(i, j) = FALSE; /* floor */ | |
160 else | |
161 *moffset(i, j) = TRUE; /* wall */ | |
162 } | |
163 } | |
164 | |
165 for (i = 0; i < urlines; i++) | |
166 { | |
167 for (j = 0; j < urcols; j++) | |
168 { | |
169 do | |
170 more = findcells(i, j); | |
171 while (more != 0); | |
172 } | |
173 } | |
174 | |
175 crankout(); | |
176 ur_free(frontier); | |
177 ur_free(bits); | |
178 } | |
179 | |
180 /* | |
181 moffset() | |
182 Calculate memory address for bits | |
183 */ | |
184 | |
185 char * | |
186 moffset(int y, int x) | |
187 { | |
188 return (bits + (y * (COLS - 1)) + x); | |
189 } | |
190 | |
191 /* | |
192 foffset() | |
193 Calculate memory address for frontier | |
194 */ | |
195 | |
196 char * | |
197 foffset(int y, int x) | |
198 { | |
199 return (frontier + (y * urcols) + x); | |
200 } | |
201 | |
202 /* | |
203 findcells() | |
204 Figure out cells to open up | |
205 */ | |
206 | |
207 int | |
208 findcells(int y, int x) | |
209 { | |
210 int rtpos, i; | |
211 | |
212 struct | |
213 { | |
214 int num_pos; /* number of frontier cells next to you */ | |
215 | |
216 struct | |
217 { | |
218 int y_pos; | |
219 int x_pos; | |
220 } conn[4]; /* the y,x position of above cell */ | |
221 } mborder; | |
222 | |
223 *foffset(y, x) = FALSE; | |
224 mborder.num_pos = 0; | |
225 | |
226 if (y < urlines - 1) { /* look below */ | |
227 if (*foffset(y + 1, x)) | |
228 { | |
229 mborder.conn[mborder.num_pos].y_pos = y + 1; | |
230 mborder.conn[mborder.num_pos].x_pos = x; | |
231 mborder.num_pos += 1; | |
232 } | |
233 } | |
234 | |
235 if (y > 0) /* look above */ | |
236 { | |
237 if (*foffset(y - 1, x)) | |
238 { | |
239 mborder.conn[mborder.num_pos].y_pos = y - 1; | |
240 mborder.conn[mborder.num_pos].x_pos = x; | |
241 mborder.num_pos += 1; | |
242 } | |
243 } | |
244 | |
245 if (x < urcols - 1) /* look right */ | |
246 { | |
247 if (*foffset(y, x + 1)) | |
248 { | |
249 mborder.conn[mborder.num_pos].y_pos = y; | |
250 mborder.conn[mborder.num_pos].x_pos = x + 1; | |
251 mborder.num_pos += 1; | |
252 } | |
253 } | |
254 | |
255 if (x > 0) /* look left */ | |
256 { | |
257 if (*foffset(y, x - 1)) | |
258 { | |
259 mborder.conn[mborder.num_pos].y_pos = y; | |
260 mborder.conn[mborder.num_pos].x_pos = x - 1; | |
261 mborder.num_pos += 1; | |
262 } | |
263 } | |
264 | |
265 if (mborder.num_pos == 0)/* no neighbors available */ | |
266 return(0); | |
267 else | |
268 { | |
269 i = rnd(mborder.num_pos); | |
270 rtpos = mborder.num_pos - 1; | |
271 rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x); | |
272 return(rtpos); | |
273 } | |
274 } | |
275 | |
276 /* | |
277 rmwall() | |
278 Removes appropriate walls from the maze | |
279 */ | |
280 | |
281 void | |
282 rmwall(int newy, int newx, int oldy, int oldx) | |
283 { | |
284 int xdif, ydif; | |
285 | |
286 xdif = newx - oldx; | |
287 ydif = newy - oldy; | |
288 | |
289 *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE; | |
290 | |
291 findcells(newy, newx); | |
292 } | |
293 | |
294 | |
295 /* | |
296 crankout() | |
297 Does actual drawing of maze to window | |
298 */ | |
299 | |
300 void | |
301 crankout(void) | |
302 { | |
303 int x, y; | |
304 | |
305 for (y = 0; y < LINES - 3; y++) | |
306 { | |
307 move(y + 1, 0); | |
308 | |
309 for (x = 0; x < COLS - 1; x++) | |
310 { | |
311 if (*moffset(y, x)) /* here is a wall */ | |
312 { | |
313 if (y == 0 || y == LINES - 4) /* top or bottom line */ | |
314 addch('-'); | |
315 else if (x == 0 || x == COLS - 2) /* left | right side */ | |
316 addch('|'); | |
317 else if (y % 2 == 0 && x % 2 == 0) | |
318 { | |
319 if (*moffset(y, x - 1) || *moffset(y, x + 1)) | |
320 addch('-'); | |
321 else | |
322 addch('|'); | |
323 } | |
324 else if (y % 2 == 0) | |
325 addch('-'); | |
326 else | |
327 addch('|'); | |
328 } | |
329 else | |
330 addch(FLOOR); | |
331 } | |
332 } | |
333 } |