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