1 /* 2 * Create the layout for the new level 3 * 4 * rooms.c 1.4 (A.I. Design) 12/16/84 5 */ 6 7 #include "rogue.h" 8 #include "curses.h" 9 10 #define GOLDGRP 1 11 12 /* 13 * do_rooms: 14 * Create rooms and corridors with a connectivity graph 15 */ 16 do_rooms() 17 { 18 register int i, rm; 19 struct room *rp; 20 register THING *tp; 21 int left_out; 22 coord top; 23 coord bsze; 24 coord mp; 25 int old_lev; 26 int endline; 27 28 endline = maxrow + 1; 29 30 old_lev = level; 31 /* 32 * bsze is the maximum room size 33 */ 34 bsze.x = COLS/3; 35 bsze.y = endline/3; 36 /* 37 * Clear things for a new level 38 */ 39 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) 40 rp->r_goldval = rp->r_nexits = rp->r_flags = 0; 41 /* 42 * Put the gone rooms, if any, on the level 43 */ 44 left_out = rnd(4); 45 for (i = 0; i < left_out; i++) { 46 do 47 rp = &rooms[(rm = rnd_room())]; 48 while (rp->r_flags & ISMAZE); 49 rp->r_flags |= ISGONE; 50 #ifdef TEST 51 if (rm > 2 && ((level > 10 && rnd(20) < level - 9) || istest())) 52 #else TEST 53 if (rm > 2 && level > 10 && rnd(20) < level - 9) 54 #endif TEST 55 rp->r_flags |= ISMAZE; 56 } 57 /* 58 * dig and populate all the rooms on the level 59 */ 60 for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) { 61 /* 62 * Find upper left corner of box that this room goes in 63 */ 64 top.x = (i%3)*bsze.x + 1; 65 top.y = i/3*bsze.y; 66 if (rp->r_flags & ISGONE) { 67 /* 68 * If the gone room is a maze room, draw the maze and set the 69 * size equal to the maximum possible. 70 */ 71 if (rp->r_flags&ISMAZE) { 72 rp->r_pos.x = top.x; 73 rp->r_pos.y = top.y; 74 draw_maze(rp); 75 } else { 76 /* 77 * Place a gone room. Make certain that there is a blank line 78 * for passage drawing. 79 */ 80 do { 81 rp->r_pos.x = top.x + rnd(bsze.x-2) + 1; 82 rp->r_pos.y = top.y + rnd(bsze.y-2) + 1; 83 rp->r_max.x = -COLS; 84 rp->r_max.x = -endline; 85 } while (!(rp->r_pos.y > 0 && rp->r_pos.y < endline-1)); 86 } 87 continue; 88 } 89 if (rnd(10) < (level - 1)) 90 rp->r_flags |= ISDARK; 91 /* 92 * Find a place and size for a random room 93 */ 94 do { 95 rp->r_max.x = rnd(bsze.x - 4) + 4; 96 rp->r_max.y = rnd(bsze.y - 4) + 4; 97 rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x); 98 rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y); 99 } while (rp->r_pos.y == 0); 100 draw_room(rp); 101 /* 102 * Put the gold in 103 */ 104 if ((rnd(2) == 0) && (!saw_amulet || (level >= max_level))) { 105 THING *gold; 106 107 if ((gold = new_item()) != NULL) { 108 gold->o_goldval = rp->r_goldval = GOLDCALC; 109 while (1) { 110 byte gch; 111 112 rnd_pos(rp, &rp->r_gold); 113 gch = chat(rp->r_gold.y, rp->r_gold.x); 114 if (isfloor(gch)) 115 break; 116 } 117 bcopy(gold->o_pos,rp->r_gold); 118 gold->o_flags = ISMANY; 119 gold->o_group = GOLDGRP; 120 gold->o_type = GOLD; 121 attach(lvl_obj, gold); 122 chat(rp->r_gold.y, rp->r_gold.x) = GOLD; 123 } 124 } 125 /* 126 * Put the monster in 127 */ 128 if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25)) { 129 if ((tp = new_item()) != NULL) { 130 byte mch; 131 132 do { 133 rnd_pos(rp, &mp); 134 mch = winat(mp.y, mp.x); 135 } while (!isfloor(mch)); 136 new_monster(tp, randmonster(FALSE), &mp); 137 give_pack(tp); 138 } 139 } 140 } 141 } 142 143 /* 144 * draw_room: 145 * Draw a box around a room and lay down the floor 146 */ 147 draw_room(rp) 148 struct room *rp; 149 { 150 register int y, x; 151 152 /* 153 * Here we draw normal rooms, one side at a time 154 */ 155 vert(rp, rp->r_pos.x); /* Draw left side */ 156 vert(rp, rp->r_pos.x + rp->r_max.x - 1); /* Draw right side */ 157 horiz(rp, rp->r_pos.y); /* Draw top */ 158 horiz(rp, rp->r_pos.y + rp->r_max.y - 1); /* Draw bottom */ 159 chat(rp->r_pos.y,rp->r_pos.x) = ULWALL; 160 chat(rp->r_pos.y,rp->r_pos.x+rp->r_max.x - 1) = URWALL; 161 chat(rp->r_pos.y+rp->r_max.y-1,rp->r_pos.x) = LLWALL; 162 chat(rp->r_pos.y+rp->r_max.y-1,rp->r_pos.x+rp->r_max.x - 1) = LRWALL; 163 /* 164 * Put the floor down 165 */ 166 for (y = rp->r_pos.y + 1; y < rp->r_pos.y + rp->r_max.y - 1; y++) 167 for (x = rp->r_pos.x + 1; x < rp->r_pos.x + rp->r_max.x - 1; x++) 168 chat(y, x) = FLOOR; 169 } 170 171 /* 172 * vert: 173 * Draw a vertical line 174 */ 175 vert(rp, startx) 176 register struct room *rp; 177 register int startx; 178 { 179 register register int y; 180 181 for (y = rp->r_pos.y + 1; y <= rp->r_max.y + rp->r_pos.y - 1; y++) 182 chat(y, startx) = VWALL; 183 } 184 185 /* 186 * horiz: 187 * Draw a horizontal line 188 */ 189 horiz(rp, starty) 190 struct room *rp; 191 int starty; 192 { 193 register int x; 194 195 for (x = rp->r_pos.x; x <= rp->r_pos.x + rp->r_max.x - 1; x++) 196 chat(starty, x) = HWALL; 197 } 198 199 /* 200 * rnd_pos: 201 * Pick a random spot in a room 202 */ 203 rnd_pos(rp, cp) 204 register struct room *rp; 205 register coord *cp; 206 { 207 cp->x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1; 208 cp->y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1; 209 } 210 211 /* 212 * enter_room: 213 * Code that is executed whenver you appear in a room 214 */ 215 enter_room(cp) 216 register coord *cp; 217 { 218 register struct room *rp; 219 register int y, x; 220 register THING *tp; 221 222 rp = proom = roomin(cp); 223 if (bailout || (rp->r_flags & ISGONE && (rp->r_flags & ISMAZE) == 0)) { 224 #ifdef DEBUG 225 msg("in a gone room"); 226 #endif DEBUG 227 return; 228 } 229 door_open(rp); 230 if (!(rp->r_flags&ISDARK) && !on(player,ISBLIND) && !(rp->r_flags&ISMAZE)) 231 for (y = rp->r_pos.y; y < rp->r_max.y + rp->r_pos.y; y++) { 232 move(y, rp->r_pos.x); 233 for (x = rp->r_pos.x; x < rp->r_max.x + rp->r_pos.x; x++) { 234 /* 235 * Displaying monsters is all handled in the 236 * chase code now 237 */ 238 tp = moat(y, x); 239 if (tp == NULL || !see_monst(tp)) 240 addch(chat(y, x)); 241 else { 242 tp->t_oldch = chat(y,x); 243 addch(tp->t_disguise); 244 } 245 } 246 } 247 } 248 249 /* 250 * leave_room: 251 * Code for when we exit a room 252 */ 253 leave_room(cp) 254 register coord *cp; 255 { 256 register int y, x; 257 register struct room *rp; 258 register byte floor; 259 register byte ch; 260 261 rp = proom; 262 proom = &passages[flat(cp->y, cp->x) & F_PNUM]; 263 floor = ((rp->r_flags & ISDARK) && !on(player, ISBLIND)) ? ' ' : FLOOR; 264 if (rp->r_flags & ISMAZE) 265 floor = PASSAGE; 266 for (y = rp->r_pos.y + 1; y < rp->r_max.y + rp->r_pos.y - 1; y++) 267 for (x = rp->r_pos.x + 1; x < rp->r_max.x + rp->r_pos.x - 1; x++) 268 switch (ch = mvinch(y, x)) { 269 case ' ': 270 case PASSAGE: 271 case TRAP: 272 case STAIRS: 273 break; 274 case FLOOR: 275 if (floor == ' ') 276 addch(' '); 277 break; 278 default: 279 /* 280 * to check for monster, we have to strip out 281 * standout bit 282 */ 283 if (isupper(toascii(ch))) 284 if (on(player, SEEMONST)) { 285 standout(); 286 addch(ch); 287 standend(); 288 break; 289 } else 290 moat(y, x)->t_oldch = '@'; 291 addch(floor); 292 } 293 door_open(rp); 294 } 295 ÿ