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