checkpoint of hacking for mail.cs.berkeley.edu
[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 *
3b2381a2 8 * %sccs.include.redist.c%
fc3e88fd
KB
9 */
10
11#ifndef lint
3b2381a2 12static 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
31short cur_level = 0;
32short max_level = 1;
33short cur_room;
34char *new_level_message = 0;
35short party_room = NO_ROOM;
36short r_de;
37
38long 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
62short random_rooms[MAXROOMS] = {3, 7, 5, 2, 0, 6, 1, 4, 8};
63
64extern boolean being_held, wizard, detect_monster;
65extern boolean see_invisible;
66extern short bear_trap, levitate, extra_hp, less_hp, cur_room;
67
68make_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
165make_room(rn, r1, r2, r3)
166short 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 }
251B:
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 }
267END:
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
274connect_rooms(room1, room2)
275short 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
321clear_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
347put_door(rm, dir, row, col)
348room *rm;
349short dir;
350short *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
384draw_simple_passage(row1, col1, row2, col2, dir)
385short 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
425same_row(room1, room2)
426{
427 return((room1 / 3) == (room2 / 3));
428}
429
430same_col(room1, room2)
431{
432 return((room1 % 3) == (room2 % 3));
433}
434
435add_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
466fill_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
486fill_it(rn, do_rec_de)
487int rn;
488boolean 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
547recursive_deadend(rn, offsets, srow, scol)
548short rn;
549short *offsets;
550short 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
582boolean
583mask_room(rn, row, col, mask)
584short rn;
585short *row, *col;
586unsigned 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
602make_maze(r, c, tr, br, lc, rc)
603short 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
667hide_boxed_passage(row1, col1, row2, col2, n)
668short 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
702put_player(nr)
703short 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
734drop_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
750check_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
772add_exp(e, promotion)
773int e;
774boolean 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
803get_exp_level(e)
804long 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
816hp_raise()
817{
818 int hp;
819
820 hp = (wizard ? 10 : get_rand(3, 10));
821 return(hp);
822}
823
824show_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
843mix_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}