comparison arogue7/new_level.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 f9ef86cf22b2
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
1 /*
2 * new_level.c - Dig and draw a new level
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 #include "curses.h"
16 #include "rogue.h"
17 #define TERRASAVE 3
18
19 /*
20 * new_level:
21 * Dig and draw a new level
22 *
23 */
24
25 new_level(ltype)
26 LEVTYPE ltype; /* designates type of level to create */
27 {
28 register int rm, i, cnt;
29 register char ch;
30 register struct linked_list *item;
31 register struct thing *tp;
32 register struct object *obj;
33 int waslit = 0; /* Was the previous outside level lit? */
34 int starty, startx, deltay, deltax;
35 bool fresh=TRUE, vert, top;
36 struct room *rp;
37 struct linked_list *nitem, *savmonst=NULL, *savitems=NULL;
38 coord stairs;
39
40 if (wizard) {
41 msg("Turns: %d", turns); /* Number of turns for last level */
42 mpos = 0;
43 }
44
45 /* Start player off right */
46 turn_off(player, ISHELD);
47 turn_off(player, ISFLEE);
48 extinguish(suffocate);
49 hold_count = 0;
50 trap_tries = 0;
51
52 /* Are we just entering a dungeon? If so, how big is it? */
53 if (ltype != OUTSIDE && nfloors < 0) nfloors = HARDER+10 + rnd(11);
54
55 if (level > max_level)
56 max_level = level;
57
58 /* Are we starting a new outside level? */
59 if (ltype == OUTSIDE) {
60 register int i, j;
61
62 /* Save some information prior to clearing the screen */
63 if (level == -1 || mvinch(hero.y, hero.x) == '-') vert = TRUE;
64 else vert = FALSE;
65
66 if (level == -1) {
67 fresh = TRUE;
68 starty = 2;
69 startx = 1;
70 deltay = deltax = 1;
71 level = 0; /* Restore the level */
72 }
73 else { /* Copy several lines of the terrain to the other end */
74 char cch; /* Copy character */
75
76 /* Was the area dark (not magically lit)? */
77 if (!(rooms[0].r_flags & ISDARK)) waslit = 1;
78
79 fresh = FALSE;
80 if ((vert && hero.y == 1) || (!vert && hero.x == 0)) top = TRUE;
81 else top = FALSE;
82 for (i=0; i<TERRASAVE; i++) {
83 if (vert)
84 for (j=1; j<cols-1; j++) {
85 if (top) {
86 cch = CCHAR( mvinch(i+2, j) );
87 mvaddch(lines-6+i, j, cch);
88 }
89 else {
90 cch = CCHAR( mvinch(lines-4-i, j) );
91 mvaddch(4-i, j, cch);
92 }
93 }
94 else
95 for (j=2; j<lines-3; j++) {
96 if (top) {
97 cch = CCHAR( mvinch(j, i+1) );
98 mvaddch(j, cols-4+i, cch);
99 }
100 else {
101 cch = CCHAR( mvinch(j, cols-2-i) );
102 mvaddch(j, 3-i, cch);
103 }
104 }
105 }
106
107 if (vert) {
108 startx = deltax = 1;
109 if (top) {
110 starty = lines-4-TERRASAVE;
111 deltay = -1;
112 }
113 else {
114 starty = TERRASAVE + 2;
115 deltay = 1;
116 }
117 }
118 else {
119 starty = 2;
120 deltay = 1;
121 if (top) {
122 startx = cols-2-TERRASAVE;
123 deltax = -1;
124 }
125 else {
126 deltax = 1;
127 startx = TERRASAVE + 1;
128 }
129 }
130
131 /* Check if any monsters should be saved */
132 for (item = mlist; item != NULL; item = nitem) {
133 nitem = next(item);
134 tp = THINGPTR(item);
135 if (vert) {
136 if (top) {
137 if (tp->t_pos.y < TERRASAVE + 2)
138 tp->t_pos.y += lines - 5 - TERRASAVE;
139 else continue;
140 }
141 else {
142 if (tp->t_pos.y > lines - 4 - TERRASAVE)
143 tp->t_pos.y += 5 + TERRASAVE - lines;
144 else continue;
145 }
146 }
147 else {
148 if (top) {
149 if (tp->t_pos.x < TERRASAVE + 1)
150 tp->t_pos.x += cols - 2 - TERRASAVE;
151 else continue;
152 }
153 else {
154 if (tp->t_pos.x > cols - 2 - TERRASAVE)
155 tp->t_pos.x += 2 + TERRASAVE - cols;
156 else continue;
157 }
158 }
159
160 /*
161 * If the monster is busy chasing another monster, don't save
162 * it
163 */
164 if (tp->t_dest && tp->t_dest != &hero) continue;
165
166 detach(mlist, item);
167 attach(savmonst, item);
168 }
169
170 /* Check if any treasure should be saved */
171 for (item = lvl_obj; item != NULL; item = nitem) {
172 nitem = next(item);
173 obj = OBJPTR(item);
174 if (vert) {
175 if (top) {
176 if (obj->o_pos.y < TERRASAVE + 2)
177 obj->o_pos.y += lines - 5 - TERRASAVE;
178 else continue;
179 }
180 else {
181 if (obj->o_pos.y > lines - 4 - TERRASAVE)
182 obj->o_pos.y += 5 + TERRASAVE - lines;
183 else continue;
184 }
185 }
186 else {
187 if (top) {
188 if (obj->o_pos.x < TERRASAVE + 1)
189 obj->o_pos.x += cols - 2 - TERRASAVE;
190 else continue;
191 }
192 else {
193 if (obj->o_pos.x > cols - 2 - TERRASAVE)
194 obj->o_pos.x += 2 + TERRASAVE - cols;
195 else continue;
196 }
197 }
198 detach(lvl_obj, item);
199 attach(savitems, item);
200 }
201 }
202 }
203
204
205 wclear(cw);
206 wclear(mw);
207 if (fresh) clear();
208 /*
209 * check to see if he missed a UNIQUE, If he did then put it back
210 * in the monster table for next time
211 */
212 for (item = mlist; item != NULL; item = next(item)) {
213 tp = THINGPTR(item);
214 if (on(*tp, ISUNIQUE))
215 monsters[tp->t_index].m_normal = TRUE;
216 }
217 /*
218 * Free up the monsters on the last level
219 */
220 t_free_list(monst_dead);
221 t_free_list(mlist);
222 o_free_list(lvl_obj); /* Free up previous objects (if any) */
223 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
224 r_free_list(rp->r_exit); /* Free up the exit lists */
225
226 levtype = ltype;
227 foods_this_level = 0; /* food for hero this level */
228 if (ltype == POSTLEV || ltype == STARTLEV) {
229 if (ltype == POSTLEV) do_post(FALSE); /* Trading post */
230 else do_post(TRUE); /* Equippage */
231 levtype = ltype = POSTLEV;
232 }
233 else if (ltype == MAZELEV) {
234 do_maze();
235 no_food++;
236 put_things(ltype); /* Place objects (if any) */
237 }
238 else if (ltype == OUTSIDE) {
239 init_terrain();
240 do_terrain(starty, startx, deltay, deltax, (bool) (fresh || !vert));
241 no_food++;
242 put_things(ltype);
243
244 /* Should we magically light this area? */
245 if (waslit) rooms[0].r_flags &= ~ISDARK;
246 }
247 else {
248 do_rooms(); /* Draw rooms */
249 do_passages(); /* Draw passages */
250 no_food++;
251 put_things(ltype); /* Place objects (if any) */
252 }
253 /*
254 * Place the staircase down. Only a small chance for an outside stairway.
255 */
256 if (ltype != OUTSIDE || roll(1, 4) == 4) {
257 cnt = 0;
258 do {
259 rm = rnd_room();
260 rnd_pos(&rooms[rm], &stairs);
261 } until (mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
262 addch(STAIRS);
263 }
264 /*
265 * maybe add a trading post
266 */
267 if (level > 5 && rnd(11) == 7 && ltype == NORMLEV) {
268 cnt = 0;
269 do {
270 rm = rnd_room();
271 if (rooms[rm].r_flags & ISTREAS)
272 continue;
273 rnd_pos(&rooms[rm], &stairs);
274 } until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
275 addch(POST);
276 }
277 if (ltype != POSTLEV) { /* Add monsters that fell through */
278 nitem = tlist;
279 while (nitem != NULL) {
280 item = nitem;
281 nitem = next(item); /* because detach and attach mess up ptrs */
282 tp = THINGPTR(item);
283 cnt = 0;
284 do {
285 rm = rnd_room();
286 rnd_pos(&rooms[rm], &tp->t_pos);
287 } until (cnt++ > 5000 || winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
288 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
289 tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
290
291 /*
292 * If it has a fire, mark it
293 */
294 if (on(*tp, HASFIRE)) {
295 register struct linked_list *fire_item;
296
297 fire_item = creat_item();
298 ldata(fire_item) = (char *) tp;
299 attach(rooms[rm].r_fires, fire_item);
300 rooms[rm].r_flags |= HASFIRE;
301 }
302 turn_off(*tp,ISELSEWHERE);
303 detach(tlist, item);
304 attach(mlist, item);
305 }
306 }
307
308 /* Restore any saved monsters */
309 for (item = savmonst; item != NULL; item = nitem) {
310 nitem = next(item);
311 tp = THINGPTR(item);
312 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
313 tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
314
315 /*
316 * If it has a fire, mark it
317 */
318 if (on(*tp, HASFIRE)) {
319 register struct linked_list *fire_item;
320
321 fire_item = creat_item();
322 ldata(fire_item) = (char *) tp;
323 attach(rooms[rm].r_fires, fire_item);
324 rooms[rm].r_flags |= HASFIRE;
325 }
326
327 detach(savmonst, item);
328 attach(mlist, item);
329 }
330
331 /* Restore any saved objects */
332 for(item = savitems; item != NULL; item = nitem) {
333 nitem = next(item);
334 obj = OBJPTR(item);
335 mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
336 detach(savitems, item);
337 attach(lvl_obj, item);
338 }
339
340
341 /*
342 * Place the traps (except for trading post)
343 */
344 ntraps = 0; /* No traps yet */
345 if (levtype == NORMLEV) {
346 if (rnd(10) < vlevel) {
347 ntraps = rnd(vlevel/4)+1;
348 if (ntraps > MAXTRAPS)
349 ntraps = MAXTRAPS;
350 i = ntraps;
351 while (i--)
352 {
353 cnt = 0;
354 do {
355 rm = rnd_room();
356 if (rooms[rm].r_flags & ISTREAS)
357 continue;
358 rnd_pos(&rooms[rm], &stairs);
359 } until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
360
361 traps[i].tr_flags = 0;
362
363 /* If we are at the bottom, we can't set a trap door */
364 if (level >= nfloors) ch = (char) rnd(7) + 1;
365 else ch = (char) rnd(8);
366
367 switch((int) ch) {
368 case 0: ch = TRAPDOOR;
369 when 1: ch = BEARTRAP;
370 when 2: ch = SLEEPTRAP;
371 when 3: ch = ARROWTRAP;
372 when 4: ch = TELTRAP;
373 when 5: ch = DARTTRAP;
374 when 6: ch = POOL;
375 traps[i].tr_flags = ISFOUND;
376 when 7: ch = MAZETRAP;
377 }
378 addch(ch);