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