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