Commit | Line | Data |
---|---|---|
fc3e88fd KB |
1 | /* |
2 | * Copyright (c) 1988 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Timothy C. Stoehr. | |
7 | * | |
3b2381a2 | 8 | * %sccs.include.redist.c% |
fc3e88fd KB |
9 | */ |
10 | ||
11 | #ifndef lint | |
3b2381a2 | 12 | static char sccsid[] = "@(#)level.c 5.3 (Berkeley) %G%"; |
fc3e88fd KB |
13 | #endif /* not lint */ |
14 | ||
b3afadef KB |
15 | /* |
16 | * level.c | |
17 | * | |
18 | * This source herein may be modified and/or distributed by anybody who | |
19 | * so desires, with the following restrictions: | |
20 | * 1.) No portion of this notice shall be removed. | |
21 | * 2.) Credit shall not be taken for the creation of this source. | |
22 | * 3.) This code is not to be traded, sold, or used for personal | |
23 | * gain or profit. | |
24 | * | |
25 | */ | |
26 | ||
b3afadef KB |
27 | #include "rogue.h" |
28 | ||
29 | #define swap(x,y) {t = x; x = y; y = t;} | |
30 | ||
31 | short cur_level = 0; | |
32 | short max_level = 1; | |
33 | short cur_room; | |
34 | char *new_level_message = 0; | |
35 | short party_room = NO_ROOM; | |
36 | short r_de; | |
37 | ||
38 | long level_points[MAX_EXP_LEVEL] = { | |
39 | 10L, | |
40 | 20L, | |
41 | 40L, | |
42 | 80L, | |
43 | 160L, | |
44 | 320L, | |
45 | 640L, | |
46 | 1300L, | |
47 | 2600L, | |
48 | 5200L, | |
49 | 10000L, | |
50 | 20000L, | |
51 | 40000L, | |
52 | 80000L, | |
53 | 160000L, | |
54 | 320000L, | |
55 | 1000000L, | |
56 | 3333333L, | |
57 | 6666666L, | |
58 | MAX_EXP, | |
59 | 99900000L | |
60 | }; | |
61 | ||
62 | short random_rooms[MAXROOMS] = {3, 7, 5, 2, 0, 6, 1, 4, 8}; | |
63 | ||
64 | extern boolean being_held, wizard, detect_monster; | |
65 | extern boolean see_invisible; | |
66 | extern short bear_trap, levitate, extra_hp, less_hp, cur_room; | |
67 | ||
68 | make_level() | |
69 | { | |
70 | short i, j; | |
71 | short must_1, must_2, must_3; | |
72 | boolean big_room; | |
73 | ||
74 | if (cur_level < LAST_DUNGEON) { | |
75 | cur_level++; | |
76 | } | |
77 | if (cur_level > max_level) { | |
78 | max_level = cur_level; | |
79 | } | |
80 | must_1 = get_rand(0, 5); | |
81 | ||
82 | switch(must_1) { | |
83 | case 0: | |
84 | must_1 = 0; | |
85 | must_2 = 1; | |
86 | must_3 = 2; | |
87 | break; | |
88 | case 1: | |
89 | must_1 = 3; | |
90 | must_2 = 4; | |
91 | must_3 = 5; | |
92 | break; | |
93 | case 2: | |
94 | must_1 = 6; | |
95 | must_2 = 7; | |
96 | must_3 = 8; | |
97 | break; | |
98 | case 3: | |
99 | must_1 = 0; | |
100 | must_2 = 3; | |
101 | must_3 = 6; | |
102 | break; | |
103 | case 4: | |
104 | must_1 = 1; | |
105 | must_2 = 4; | |
106 | must_3 = 7; | |
107 | break; | |
108 | case 5: | |
109 | must_1 = 2; | |
110 | must_2 = 5; | |
111 | must_3 = 8; | |
112 | break; | |
113 | } | |
114 | if (rand_percent(8)) { | |
115 | party_room = 0; | |
116 | } | |
117 | big_room = ((party_room != NO_ROOM) && rand_percent(1)); | |
118 | if (big_room) { | |
119 | make_room(BIG_ROOM, 0, 0, 0); | |
120 | } else { | |
121 | for (i = 0; i < MAXROOMS; i++) { | |
122 | make_room(i, must_1, must_2, must_3); | |
123 | } | |
124 | } | |
125 | if (!big_room) { | |
126 | add_mazes(); | |
127 | ||
128 | mix_random_rooms(); | |
129 | ||
130 | for (j = 0; j < MAXROOMS; j++) { | |
131 | ||
132 | i = random_rooms[j]; | |
133 | ||
134 | if (i < (MAXROOMS-1)) { | |
135 | (void) connect_rooms(i, i+1); | |
136 | } | |
137 | if (i < (MAXROOMS-3)) { | |
138 | (void) connect_rooms(i, i+3); | |
139 | } | |
140 | if (i < (MAXROOMS-2)) { | |
141 | if (rooms[i+1].is_room & R_NOTHING) { | |
142 | if (connect_rooms(i, i+2)) { | |
143 | rooms[i+1].is_room = R_CROSS; | |
144 | } | |
145 | } | |
146 | } | |
147 | if (i < (MAXROOMS-6)) { | |
148 | if (rooms[i+3].is_room & R_NOTHING) { | |
149 | if (connect_rooms(i, i+6)) { | |
150 | rooms[i+3].is_room = R_CROSS; | |
151 | } | |
152 | } | |
153 | } | |
154 | if (is_all_connected()) { | |
155 | break; | |
156 | } | |
157 | } | |
158 | fill_out_level(); | |
159 | } | |
160 | if (!has_amulet() && (cur_level >= AMULET_LEVEL)) { | |
161 | put_amulet(); | |
162 | } | |
163 | } | |
164 | ||
165 | make_room(rn, r1, r2, r3) | |
166 | short rn, r1, r2, r3; | |
167 | { | |
168 | short left_col, right_col, top_row, bottom_row; | |
169 | short width, height; | |
170 | short row_offset, col_offset; | |
171 | short i, j, ch; | |
172 | ||
173 | switch(rn) { | |
174 | case 0: | |
175 | left_col = 0; | |
176 | right_col = COL1-1; | |
177 | top_row = MIN_ROW; | |
178 | bottom_row = ROW1-1; | |
179 | break; | |
180 | case 1: | |
181 | left_col = COL1+1; | |
182 | right_col = COL2-1; | |
183 | top_row = MIN_ROW; | |
184 | bottom_row = ROW1-1; | |
185 | break; | |
186 | case 2: | |
187 | left_col = COL2+1; | |
188 | right_col = DCOLS-1; | |
189 | top_row = MIN_ROW; | |
190 | bottom_row = ROW1-1; | |
191 | break; | |
192 | case 3: | |
193 | left_col = 0; | |
194 | right_col = COL1-1; | |
195 | top_row = ROW1+1; | |
196 | bottom_row = ROW2-1; | |
197 | break; | |
198 | case 4: | |
199 | left_col = COL1+1; | |
200 | right_col = COL2-1; | |
201 | top_row = ROW1+1; | |
202 | bottom_row = ROW2-1; | |
203 | break; | |
204 | case 5: | |
205 | left_col = COL2+1; | |
206 | right_col = DCOLS-1; | |
207 | top_row = ROW1+1; | |
208 | bottom_row = ROW2-1; | |
209 | break; | |
210 | case 6: | |
211 | left_col = 0; | |
212 | right_col = COL1-1; | |
213 | top_row = ROW2+1; | |
214 | bottom_row = DROWS - 2; | |
215 | break; | |
216 | case 7: | |
217 | left_col = COL1+1; | |
218 | right_col = COL2-1; | |
219 | top_row = ROW2+1; | |
220 | bottom_row = DROWS - 2; | |
221 | break; | |
222 | case 8: | |
223 | left_col = COL2+1; | |
224 | right_col = DCOLS-1; | |
225 | top_row = ROW2+1; | |
226 | bottom_row = DROWS - 2; | |
227 | break; | |
228 | case BIG_ROOM: | |
229 | top_row = get_rand(MIN_ROW, MIN_ROW+5); | |
230 | bottom_row = get_rand(DROWS-7, DROWS-2); | |
231 | left_col = get_rand(0, 10);; | |
232 | right_col = get_rand(DCOLS-11, DCOLS-1); | |
233 | rn = 0; | |
234 | goto B; | |
235 | } | |
236 | height = get_rand(4, (bottom_row - top_row + 1)); | |
237 | width = get_rand(7, (right_col - left_col - 2)); | |
238 | ||
239 | row_offset = get_rand(0, ((bottom_row - top_row) - height + 1)); | |
240 | col_offset = get_rand(0, ((right_col - left_col) - width + 1)); | |
241 | ||
242 | top_row += row_offset; | |
243 | bottom_row = top_row + height - 1; | |
244 | ||
245 | left_col += col_offset; | |
246 | right_col = left_col + width - 1; | |
247 | ||
248 | if ((rn != r1) && (rn != r2) && (rn != r3) && rand_percent(40)) { | |
249 | goto END; | |
250 | } | |
251 | B: | |
252 | rooms[rn].is_room = R_ROOM; | |
253 | ||
254 | for (i = top_row; i <= bottom_row; i++) { | |
255 | for (j = left_col; j <= right_col; j++) { | |
256 | if ((i == top_row) || (i == bottom_row)) { | |
257 | ch = HORWALL; | |
258 | } else if ( ((i != top_row) && (i != bottom_row)) && | |
259 | ((j == left_col) || (j == right_col))) { | |
260 | ch = VERTWALL; | |
261 | } else { | |
262 | ch = FLOOR; | |
263 | } | |
264 | dungeon[i][j] = ch; | |
265 | } | |
266 | } | |
267 | END: | |
268 | rooms[rn].top_row = top_row; | |
269 | rooms[rn].bottom_row = bottom_row; | |
270 | rooms[rn].left_col = left_col; | |
271 | rooms[rn].right_col = right_col; | |
272 | } | |
273 | ||
274 | connect_rooms(room1, room2) | |
275 | short room1, room2; | |
276 | { | |
277 | short row1, col1, row2, col2, dir; | |
278 | ||
279 | if ((!(rooms[room1].is_room & (R_ROOM | R_MAZE))) || | |
280 | (!(rooms[room2].is_room & (R_ROOM | R_MAZE)))) { | |
281 | return(0); | |
282 | } | |
283 | if (same_row(room1, room2) && | |
284 | (rooms[room1].left_col > rooms[room2].right_col)) { | |
285 | put_door(&rooms[room1], LEFT, &row1, &col1); | |
286 | put_door(&rooms[room2], RIGHT, &row2, &col2); | |
287 | dir = LEFT; | |
288 | } else if (same_row(room1, room2) && | |
289 | (rooms[room2].left_col > rooms[room1].right_col)) { | |
290 | put_door(&rooms[room1], RIGHT, &row1, &col1); | |
291 | put_door(&rooms[room2], LEFT, &row2, &col2); | |
292 | dir = RIGHT; | |
293 | } else if (same_col(room1, room2) && | |
294 | (rooms[room1].top_row > rooms[room2].bottom_row)) { | |
295 | put_door(&rooms[room1], UPWARD, &row1, &col1); | |
296 | put_door(&rooms[room2], DOWN, &row2, &col2); | |
297 | dir = UPWARD; | |
298 | } else if (same_col(room1, room2) && | |
299 | (rooms[room2].top_row > rooms[room1].bottom_row)) { | |
300 | put_door(&rooms[room1], DOWN, &row1, &col1); | |
301 | put_door(&rooms[room2], UPWARD, &row2, &col2); | |
302 | dir = DOWN; | |
303 | } else { | |
304 | return(0); | |
305 | } | |
306 | ||
307 | do { | |
308 | draw_simple_passage(row1, col1, row2, col2, dir); | |
309 | } while (rand_percent(4)); | |
310 | ||
311 | rooms[room1].doors[dir/2].oth_room = room2; | |
312 | rooms[room1].doors[dir/2].oth_row = row2; | |
313 | rooms[room1].doors[dir/2].oth_col = col2; | |
314 | ||
315 | rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_room = room1; | |
316 | rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_row = row1; | |
317 | rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_col = col1; | |
318 | return(1); | |
319 | } | |
320 | ||
321 | clear_level() | |
322 | { | |
323 | short i, j; | |
324 | ||
325 | for (i = 0; i < MAXROOMS; i++) { | |
326 | rooms[i].is_room = R_NOTHING; | |
327 | for (j = 0; j < 4; j++) { | |
328 | rooms[i].doors[j].oth_room = NO_ROOM; | |
329 | } | |
330 | } | |
331 | ||
332 | for (i = 0; i < MAX_TRAPS; i++) { | |
333 | traps[i].trap_type = NO_TRAP; | |
334 | } | |
335 | for (i = 0; i < DROWS; i++) { | |
336 | for (j = 0; j < DCOLS; j++) { | |
337 | dungeon[i][j] = NOTHING; | |
338 | } | |
339 | } | |
340 | detect_monster = see_invisible = 0; | |
341 | being_held = bear_trap = 0; | |
342 | party_room = NO_ROOM; | |
343 | rogue.row = rogue.col = -1; | |
344 | clear(); | |
345 | } | |
346 | ||
347 | put_door(rm, dir, row, col) | |
348 | room *rm; | |
349 | short dir; | |
350 | short *row, *col; | |
351 | { | |
352 | short wall_width; | |
353 | ||
354 | wall_width = (rm->is_room & R_MAZE) ? 0 : 1; | |
355 | ||
356 | switch(dir) { | |
357 | case UPWARD: | |
358 | case DOWN: | |
359 | *row = ((dir == UPWARD) ? rm->top_row : rm->bottom_row); | |
360 | do { | |
361 | *col = get_rand(rm->left_col+wall_width, | |
362 | rm->right_col-wall_width); | |
363 | } while (!(dungeon[*row][*col] & (HORWALL | TUNNEL))); | |
364 | break; | |
365 | case RIGHT: | |
366 | case LEFT: | |
367 | *col = (dir == LEFT) ? rm->left_col : rm->right_col; | |
368 | do { | |
369 | *row = get_rand(rm->top_row+wall_width, | |
370 | rm->bottom_row-wall_width); | |
371 | } while (!(dungeon[*row][*col] & (VERTWALL | TUNNEL))); | |
372 | break; | |
373 | } | |
374 | if (rm->is_room & R_ROOM) { | |
375 | dungeon[*row][*col] = DOOR; | |
376 | } | |
377 | if ((cur_level > 2) && rand_percent(HIDE_PERCENT)) { | |
378 | dungeon[*row][*col] |= HIDDEN; | |
379 | } | |
380 | rm->doors[dir/2].door_row = *row; | |
381 | rm->doors[dir/2].door_col = *col; | |
382 | } | |
383 | ||
384 | draw_simple_passage(row1, col1, row2, col2, dir) | |
385 | short row1, col1, row2, col2, dir; | |
386 | { | |
387 | short i, middle, t; | |
388 | ||
389 | if ((dir == LEFT) || (dir == RIGHT)) { | |
390 | if (col1 > col2) { | |
391 | swap(row1, row2); | |
392 | swap(col1, col2); | |
393 | } | |
394 | middle = get_rand(col1+1, col2-1); | |
395 | for (i = col1+1; i != middle; i++) { | |
396 | dungeon[row1][i] = TUNNEL; | |
397 | } | |
398 | for (i = row1; i != row2; i += (row1 > row2) ? -1 : 1) { | |
399 | dungeon[i][middle] = TUNNEL; | |
400 | } | |
401 | for (i = middle; i != col2; i++) { | |
402 | dungeon[row2][i] = TUNNEL; | |
403 | } | |
404 | } else { | |
405 | if (row1 > row2) { | |
406 | swap(row1, row2); | |
407 | swap(col1, col2); | |
408 | } | |
409 | middle = get_rand(row1+1, row2-1); | |
410 | for (i = row1+1; i != middle; i++) { | |
411 | dungeon[i][col1] = TUNNEL; | |
412 | } | |
413 | for (i = col1; i != col2; i += (col1 > col2) ? -1 : 1) { | |
414 | dungeon[middle][i] = TUNNEL; | |
415 | } | |
416 | for (i = middle; i != row2; i++) { | |
417 | dungeon[i][col2] = TUNNEL; | |
418 | } | |
419 | } | |
420 | if (rand_percent(HIDE_PERCENT)) { | |
421 | hide_boxed_passage(row1, col1, row2, col2, 1); | |
422 | } | |
423 | } | |
424 | ||
425 | same_row(room1, room2) | |
426 | { | |
427 | return((room1 / 3) == (room2 / 3)); | |
428 | } | |
429 | ||
430 | same_col(room1, room2) | |
431 | { | |
432 | return((room1 % 3) == (room2 % 3)); | |
433 | } | |
434 | ||
435 | add_mazes() | |
436 | { | |
437 | short i, j; | |
438 | short start; | |
439 | short maze_percent; | |
440 | ||
441 | if (cur_level > 1) { | |
442 | start = get_rand(0, (MAXROOMS-1)); | |
443 | maze_percent = (cur_level * 5) / 4; | |
444 | ||
445 | if (cur_level > 15) { | |
446 | maze_percent += cur_level; | |
447 | } | |
448 | for (i = 0; i < MAXROOMS; i++) { | |
449 | j = ((start + i) % MAXROOMS); | |
450 | if (rooms[j].is_room & R_NOTHING) { | |
451 | if (rand_percent(maze_percent)) { | |
452 | rooms[j].is_room = R_MAZE; | |
453 | make_maze(get_rand(rooms[j].top_row+1, rooms[j].bottom_row-1), | |
454 | get_rand(rooms[j].left_col+1, rooms[j].right_col-1), | |
455 | rooms[j].top_row, rooms[j].bottom_row, | |
456 | rooms[j].left_col, rooms[j].right_col); | |
457 | hide_boxed_passage(rooms[j].top_row, rooms[j].left_col, | |
458 | rooms[j].bottom_row, rooms[j].right_col, | |
459 | get_rand(0, 2)); | |
460 | } | |
461 | } | |
462 | } | |
463 | } | |
464 | } | |
465 | ||
466 | fill_out_level() | |
467 | { | |
468 | short i, rn; | |
469 | ||
470 | mix_random_rooms(); | |
471 | ||
472 | r_de = NO_ROOM; | |
473 | ||
474 | for (i = 0; i < MAXROOMS; i++) { | |
475 | rn = random_rooms[i]; | |
476 | if ((rooms[rn].is_room & R_NOTHING) || | |
477 | ((rooms[rn].is_room & R_CROSS) && coin_toss())) { | |
478 | fill_it(rn, 1); | |
479 | } | |
480 | } | |
481 | if (r_de != NO_ROOM) { | |
482 | fill_it(r_de, 0); | |
483 | } | |
484 | } | |
485 | ||
486 | fill_it(rn, do_rec_de) | |
487 | int rn; | |
488 | boolean do_rec_de; | |
489 | { | |
490 | short i, tunnel_dir, door_dir, drow, dcol; | |
491 | short target_room, rooms_found = 0; | |
492 | short srow, scol, t; | |
493 | static short offsets[4] = {-1, 1, 3, -3}; | |
494 | boolean did_this = 0; | |
495 | ||
496 | for (i = 0; i < 10; i++) { | |
497 | srow = get_rand(0, 3); | |
498 | scol = get_rand(0, 3); | |
499 | t = offsets[srow]; | |
500 | offsets[srow] = offsets[scol]; | |
501 | offsets[scol] = t; | |
502 | } | |
503 | for (i = 0; i < 4; i++) { | |
504 | ||
505 | target_room = rn + offsets[i]; | |
506 | ||
507 | if (((target_room < 0) || (target_room >= MAXROOMS)) || | |
508 | (!(same_row(rn,target_room) || same_col(rn,target_room))) || | |
509 | (!(rooms[target_room].is_room & (R_ROOM | R_MAZE)))) { | |
510 | continue; | |
511 | } | |
512 | if (same_row(rn, target_room)) { | |
513 | tunnel_dir = (rooms[rn].left_col < rooms[target_room].left_col) ? | |
514 | RIGHT : LEFT; | |
515 | } else { | |
516 | tunnel_dir = (rooms[rn].top_row < rooms[target_room].top_row) ? | |
517 | DOWN : UPWARD; | |
518 | } | |
519 | door_dir = ((tunnel_dir + 4) % DIRS); | |
520 | if (rooms[target_room].doors[door_dir/2].oth_room != NO_ROOM) { | |
521 | continue; | |
522 | } | |
523 | if (((!do_rec_de) || did_this) || | |
524 | (!mask_room(rn, &srow, &scol, TUNNEL))) { | |
525 | srow = (rooms[rn].top_row + rooms[rn].bottom_row) / 2; | |
526 | scol = (rooms[rn].left_col + rooms[rn].right_col) / 2; | |
527 | } | |
528 | put_door(&rooms[target_room], door_dir, &drow, &dcol); | |
529 | rooms_found++; | |
530 | draw_simple_passage(srow, scol, drow, dcol, tunnel_dir); | |
531 | rooms[rn].is_room = R_DEADEND; | |
532 | dungeon[srow][scol] = TUNNEL; | |
533 | ||
534 | if ((i < 3) && (!did_this)) { | |
535 | did_this = 1; | |
536 | if (coin_toss()) { | |
537 | continue; | |
538 | } | |
539 | } | |
540 | if ((rooms_found < 2) && do_rec_de) { | |
541 | recursive_deadend(rn, offsets, srow, scol); | |
542 | } | |
543 | break; | |
544 | } | |
545 | } | |
546 | ||
547 | recursive_deadend(rn, offsets, srow, scol) | |
548 | short rn; | |
549 | short *offsets; | |
550 | short srow, scol; | |
551 | { | |
552 | short i, de; | |
553 | short drow, dcol, tunnel_dir; | |
554 | ||
555 | rooms[rn].is_room = R_DEADEND; | |
556 | dungeon[srow][scol] = TUNNEL; | |
557 | ||
558 | for (i = 0; i < 4; i++) { | |
559 | de = rn + offsets[i]; | |
560 | if (((de < 0) || (de >= MAXROOMS)) || | |
561 | (!(same_row(rn, de) || same_col(rn, de)))) { | |
562 | continue; | |
563 | } | |
564 | if (!(rooms[de].is_room & R_NOTHING)) { | |
565 | continue; | |
566 | } | |
567 | drow = (rooms[de].top_row + rooms[de].bottom_row) / 2; | |
568 | dcol = (rooms[de].left_col + rooms[de].right_col) / 2; | |
569 | if (same_row(rn, de)) { | |
570 | tunnel_dir = (rooms[rn].left_col < rooms[de].left_col) ? | |
571 | RIGHT : LEFT; | |
572 | } else { | |
573 | tunnel_dir = (rooms[rn].top_row < rooms[de].top_row) ? | |
574 | DOWN : UPWARD; | |
575 | } | |
576 | draw_simple_passage(srow, scol, drow, dcol, tunnel_dir); | |
577 | r_de = de; | |
578 | recursive_deadend(de, offsets, drow, dcol); | |
579 | } | |
580 | } | |
581 | ||
582 | boolean | |
583 | mask_room(rn, row, col, mask) | |
584 | short rn; | |
585 | short *row, *col; | |
586 | unsigned short mask; | |
587 | { | |
588 | short i, j; | |
589 | ||
590 | for (i = rooms[rn].top_row; i <= rooms[rn].bottom_row; i++) { | |
591 | for (j = rooms[rn].left_col; j <= rooms[rn].right_col; j++) { | |
592 | if (dungeon[i][j] & mask) { | |
593 | *row = i; | |
594 | *col = j; | |
595 | return(1); | |
596 | } | |
597 | } | |
598 | } | |
599 | return(0); | |
600 | } | |
601 | ||
602 | make_maze(r, c, tr, br, lc, rc) | |
603 | short r, c, tr, br, lc, rc; | |
604 | { | |
605 | char dirs[4]; | |
606 | short i, t; | |
607 | ||
608 | dirs[0] = UPWARD; | |
609 | dirs[1] = DOWN; | |
610 | dirs[2] = LEFT; | |
611 | dirs[3] = RIGHT; | |
612 | ||
613 | dungeon[r][c] = TUNNEL; | |
614 | ||
615 | if (rand_percent(20)) { | |
616 | for (i = 0; i < 10; i++) { | |
617 | short t1, t2; | |
618 | ||
619 | t1 = get_rand(0, 3); | |
620 | t2 = get_rand(0, 3); | |
621 | ||
622 | swap(dirs[t1], dirs[t2]); | |
623 | } | |
624 | } | |
625 | for (i = 0; i < 4; i++) { | |
626 | switch(dirs[i]) { | |
627 | case UPWARD: | |
628 | if (((r-1) >= tr) && | |
629 | (dungeon[r-1][c] != TUNNEL) && | |
630 | (dungeon[r-1][c-1] != TUNNEL) && | |
631 | (dungeon[r-1][c+1] != TUNNEL) && | |
632 | (dungeon[r-2][c] != TUNNEL)) { | |
633 | make_maze((r-1), c, tr, br, lc, rc); | |
634 | } | |
635 | break; | |
636 | case DOWN: | |
637 | if (((r+1) <= br) && | |
638 | (dungeon[r+1][c] != TUNNEL) && | |
639 | (dungeon[r+1][c-1] != TUNNEL) && | |
640 | (dungeon[r+1][c+1] != TUNNEL) && | |
641 | (dungeon[r+2][c] != TUNNEL)) { | |
642 | make_maze((r+1), c, tr, br, lc, rc); | |
643 | } | |
644 | break; | |
645 | case LEFT: | |
646 | if (((c-1) >= lc) && | |
647 | (dungeon[r][c-1] != TUNNEL) && | |
648 | (dungeon[r-1][c-1] != TUNNEL) && | |
649 | (dungeon[r+1][c-1] != TUNNEL) && | |
650 | (dungeon[r][c-2] != TUNNEL)) { | |
651 | make_maze(r, (c-1), tr, br, lc, rc); | |
652 | } | |
653 | break; | |
654 | case RIGHT: | |
655 | if (((c+1) <= rc) && | |
656 | (dungeon[r][c+1] != TUNNEL) && | |
657 | (dungeon[r-1][c+1] != TUNNEL) && | |
658 | (dungeon[r+1][c+1] != TUNNEL) && | |
659 | (dungeon[r][c+2] != TUNNEL)) { | |
660 | make_maze(r, (c+1), tr, br, lc, rc); | |
661 | } | |
662 | break; | |
663 | } | |
664 | } | |
665 | } | |
666 | ||
667 | hide_boxed_passage(row1, col1, row2, col2, n) | |
668 | short row1, col1, row2, col2, n; | |
669 | { | |
670 | short i, j, t; | |
671 | short row, col, row_cut, col_cut; | |
672 | short h, w; | |
673 | ||
674 | if (cur_level > 2) { | |
675 | if (row1 > row2) { | |
676 | swap(row1, row2); | |
677 | } | |
678 | if (col1 > col2) { | |
679 | swap(col1, col2); | |
680 | } | |
681 | h = row2 - row1; | |
682 | w = col2 - col1; | |
683 | ||
684 | if ((w >= 5) || (h >= 5)) { | |
685 | row_cut = ((h >= 2) ? 1 : 0); | |
686 | col_cut = ((w >= 2) ? 1 : 0); | |
687 | ||
688 | for (i = 0; i < n; i++) { | |
689 | for (j = 0; j < 10; j++) { | |
690 | row = get_rand(row1 + row_cut, row2 - row_cut); | |
691 | col = get_rand(col1 + col_cut, col2 - col_cut); | |
692 | if (dungeon[row][col] == TUNNEL) { | |
693 | dungeon[row][col] |= HIDDEN; | |
694 | break; | |
695 | } | |
696 | } | |
697 | } | |
698 | } | |
699 | } | |
700 | } | |
701 | ||
702 | put_player(nr) | |
703 | short nr; /* try not to put in this room */ | |
704 | { | |
705 | short rn = nr, misses; | |
706 | short row, col; | |
707 | ||
708 | for (misses = 0; ((misses < 2) && (rn == nr)); misses++) { | |
709 | gr_row_col(&row, &col, (FLOOR | TUNNEL | OBJECT | STAIRS)); | |
710 | rn = get_room_number(row, col); | |
711 | } | |
712 | rogue.row = row; | |
713 | rogue.col = col; | |
714 | ||
715 | if (dungeon[rogue.row][rogue.col] & TUNNEL) { | |
716 | cur_room = PASSAGE; | |
717 | } else { | |
718 | cur_room = rn; | |
719 | } | |
720 | if (cur_room != PASSAGE) { | |
721 | light_up_room(cur_room); | |
722 | } else { | |
723 | light_passage(rogue.row, rogue.col); | |
724 | } | |
725 | rn = get_room_number(rogue.row, rogue.col); | |
726 | wake_room(rn, 1, rogue.row, rogue.col); | |
727 | if (new_level_message) { | |
728 | message(new_level_message, 0); | |
729 | new_level_message = 0; | |
730 | } | |
731 | mvaddch(rogue.row, rogue.col, rogue.fchar); | |
732 | } | |
733 | ||
734 | drop_check() | |
735 | { | |
736 | if (wizard) { | |
737 | return(1); | |
738 | } | |
739 | if (dungeon[rogue.row][rogue.col] & STAIRS) { | |
740 | if (levitate) { | |
741 | message("you're floating in the air!", 0); | |
742 | return(0); | |
743 | } | |
744 | return(1); | |
745 | } | |
746 | message("I see no way down", 0); | |
747 | return(0); | |
748 | } | |
749 | ||
750 | check_up() | |
751 | { | |
752 | if (!wizard) { | |
753 | if (!(dungeon[rogue.row][rogue.col] & STAIRS)) { | |
754 | message("I see no way up", 0); | |
755 | return(0); | |
756 | } | |
757 | if (!has_amulet()) { | |
758 | message("your way is magically blocked", 0); | |
759 | return(0); | |
760 | } | |
761 | } | |
762 | new_level_message = "you feel a wrenching sensation in your gut"; | |
763 | if (cur_level == 1) { | |
764 | win(); | |
765 | } else { | |
766 | cur_level -= 2; | |
767 | return(1); | |
768 | } | |
769 | return(0); | |
770 | } | |
771 | ||
772 | add_exp(e, promotion) | |
773 | int e; | |
774 | boolean promotion; | |
775 | { | |
776 | char mbuf[40]; | |
777 | short new_exp; | |
778 | short i, hp; | |
779 | ||
780 | rogue.exp_points += e; | |
781 | ||
782 | if (rogue.exp_points >= level_points[rogue.exp-1]) { | |
783 | new_exp = get_exp_level(rogue.exp_points); | |
784 | if (rogue.exp_points > MAX_EXP) { | |
785 | rogue.exp_points = MAX_EXP + 1; | |
786 | } | |
787 | for (i = rogue.exp+1; i <= new_exp; i++) { | |
788 | sprintf(mbuf, "welcome to level %d", i); | |
789 | message(mbuf, 0); | |
790 | if (promotion) { | |
791 | hp = hp_raise(); | |
792 | rogue.hp_current += hp; | |
793 | rogue.hp_max += hp; | |
794 | } | |
795 | rogue.exp = i; | |
796 | print_stats(STAT_HP | STAT_EXP); | |
797 | } | |
798 | } else { | |
799 | print_stats(STAT_EXP); | |
800 | } | |
801 | } | |
802 | ||
803 | get_exp_level(e) | |
804 | long e; | |
805 | { | |
806 | short i; | |
807 | ||
808 | for (i = 0; i < (MAX_EXP_LEVEL - 1); i++) { | |
809 | if (level_points[i] > e) { | |
810 | break; | |
811 | } | |
812 | } | |
813 | return(i+1); | |
814 | } | |
815 | ||
816 | hp_raise() | |
817 | { | |
818 | int hp; | |
819 | ||
820 | hp = (wizard ? 10 : get_rand(3, 10)); | |
821 | return(hp); | |
822 | } | |
823 | ||
824 | show_average_hp() | |
825 | { | |
826 | char mbuf[80]; | |
827 | float real_average; | |
828 | float effective_average; | |
829 | ||
830 | if (rogue.exp == 1) { | |
831 | real_average = effective_average = 0.00; | |
832 | } else { | |
833 | real_average = (float) | |
834 | ((rogue.hp_max - extra_hp - INIT_HP) + less_hp) / (rogue.exp - 1); | |
835 | effective_average = (float) (rogue.hp_max - INIT_HP) / (rogue.exp - 1); | |
836 | ||
837 | } | |
838 | sprintf(mbuf, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average, | |
839 | effective_average, extra_hp, less_hp); | |
840 | message(mbuf, 0); | |
841 | } | |
842 | ||
843 | mix_random_rooms() | |
844 | { | |
845 | short i, t; | |
846 | short x, y; | |
847 | ||
848 | for (i = 0; i < (3 * MAXROOMS); i++) { | |
849 | do { | |
850 | x = get_rand(0, (MAXROOMS-1)); | |
851 | y = get_rand(0, (MAXROOMS-1)); | |
852 | } while (x == y); | |
853 | swap(random_rooms[x], random_rooms[y]); | |
854 | } | |
855 | } |