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