Mercurial > hg > early-roguelike
comparison urogue/maze.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 31 Jan 2017 19:56:04 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 253:d9badb9c0179 | 256:c495a4f288c6 |
|---|---|
| 1 /* | |
| 2 maze.c - functions for dealing with armor | |
| 3 | |
| 4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom | |
| 5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong | |
| 6 All rights reserved. | |
| 7 | |
| 8 Based on "Advanced Rogue" | |
| 9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka | |
| 10 All rights reserved. | |
| 11 | |
| 12 See the file LICENSE.TXT for full copyright and licensing information. | |
| 13 */ | |
| 14 | |
| 15 #include <stdlib.h> | |
| 16 #include "rogue.h" | |
| 17 | |
| 18 static char *frontier; | |
| 19 static char *bits; | |
| 20 static int urlines; | |
| 21 static int urcols; | |
| 22 | |
| 23 /* | |
| 24 domaze() | |
| 25 Draw the maze on this level. | |
| 26 */ | |
| 27 | |
| 28 void | |
| 29 do_maze(void) | |
| 30 { | |
| 31 int i, least; | |
| 32 struct room *rp; | |
| 33 struct linked_list *item; | |
| 34 struct object *obj; | |
| 35 struct thing *mp; | |
| 36 int treas; | |
| 37 coord tp; | |
| 38 | |
| 39 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) | |
| 40 { | |
| 41 rp->r_nexits = 0; /* no exits */ | |
| 42 rp->r_flags = ISGONE; /* kill all rooms */ | |
| 43 rp->r_fires = 0; /* no fires */ | |
| 44 } | |
| 45 | |
| 46 rp = &rooms[0]; /* point to only room */ | |
| 47 rp->r_flags = ISDARK; /* mazes always dark */ | |
| 48 rp->r_pos.x = 0; /* room fills whole screen */ | |
| 49 rp->r_pos.y = 1; | |
| 50 rp->r_max.x = COLS - 1; | |
| 51 rp->r_max.y = LINES - 3; | |
| 52 draw_maze(); /* put maze into window */ | |
| 53 | |
| 54 /* add some gold to make it worth looking for */ | |
| 55 | |
| 56 item = spec_item(GOLD, 0, 0, 0); | |
| 57 obj = OBJPTR(item); | |
| 58 obj->o_count *= (rnd(10) + 5); /* add in one large hunk */ | |
| 59 | |
| 60 do | |
| 61 { | |
| 62 rnd_pos(rp, &tp); | |
| 63 } | |
| 64 while( mvwinch(stdscr, tp.y, tp.x) != FLOOR); | |
| 65 | |
| 66 obj->o_pos = tp; | |
| 67 add_obj(item, tp.y, tp.x); | |
| 68 | |
| 69 /* add in some food to make sure he has enough */ | |
| 70 | |
| 71 item = spec_item(FOOD, 0, 0, 0); | |
| 72 obj = OBJPTR(item); | |
| 73 | |
| 74 do | |
| 75 { | |
| 76 rnd_pos(rp, &tp); | |
| 77 } | |
| 78 while( mvwinch(stdscr, tp.y, tp.x) != FLOOR); | |
| 79 | |
| 80 obj->o_pos = tp; | |
| 81 add_obj(item, tp.y, tp.x); | |
| 82 | |
| 83 if (rnd(100) < 5) /* 5% for treasure maze level */ | |
| 84 { | |
| 85 treas = TRUE; | |
| 86 least = 20; | |
| 87 debug("Treasure maze."); | |
| 88 } | |
| 89 else /* normal maze level */ | |
| 90 { | |
| 91 least = 1; | |
| 92 treas = FALSE; | |
| 93 } | |
| 94 | |
| 95 for (i = 0; i < level + least; i++) | |
| 96 { | |
| 97 if (!treas && rnd(100) < 50) /* put in some little buggers */ | |
| 98 continue; | |
| 99 | |
| 100 /* Put the monster in */ | |
| 101 | |
| 102 item = new_item(sizeof *mp); | |
| 103 | |
| 104 mp = THINGPTR(item); | |
| 105 | |
| 106 do | |
| 107 { | |
| 108 rnd_pos(rp, &tp); | |
| 109 } | |
| 110 while(mvwinch(stdscr, tp.y, tp.x) != FLOOR); | |
| 111 | |
| 112 new_monster(item, randmonster(NOWANDER, NOGRAB), &tp, NOMAXSTATS); | |
| 113 | |
| 114 /* See if we want to give it a treasure to carry around. */ | |
| 115 | |
| 116 if (rnd(100) < monsters[mp->t_index].m_carry) | |
| 117 attach(mp->t_pack, new_thing()); | |
| 118 | |
| 119 /* If it carries gold, give it some */ | |
| 120 | |
| 121 if (on(*mp, CARRYGOLD)) | |
| 122 { | |
| 123 item = spec_item(GOLD, 0, 0, 0); | |
| 124 obj = OBJPTR(item); | |
| 125 obj->o_count = GOLDCALC + GOLDCALC + GOLDCALC; | |
| 126 obj->o_pos = mp->t_pos; | |
| 127 attach(mp->t_pack, item); | |
| 128 } | |
| 129 | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 /* | |
| 134 draw_maze() | |
| 135 Generate and draw the maze on the screen | |
| 136 */ | |
| 137 | |
| 138 void | |
| 139 draw_maze(void) | |
| 140 { | |
| 141 int i, j, more; | |
| 142 char *ptr; | |
| 143 | |
| 144 urlines = (LINES - 3) / 2; | |
| 145 urcols = (COLS - 1) / 2; | |
| 146 | |
| 147 bits = ur_alloc((unsigned int) ((LINES - 3) * (COLS - 1))); | |
| 148 frontier = ur_alloc((unsigned int) (urlines * urcols)); | |
| 149 ptr = frontier; | |
| 150 | |
| 151 while (ptr < (frontier + (urlines * urcols))) | |
| 152 *ptr++ = TRUE; | |
| 153 | |
| 154 for (i = 0; i < LINES - 3; i++) | |
| 155 { | |
| 156 for (j = 0; j < COLS - 1; j++) | |
| 157 { | |
| 158 if (i % 2 == 1 && j % 2 == 1) | |
| 159 *moffset(i, j) = FALSE; /* floor */ | |
| 160 else | |
| 161 *moffset(i, j) = TRUE; /* wall */ | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 for (i = 0; i < urlines; i++) | |
| 166 { | |
| 167 for (j = 0; j < urcols; j++) | |
| 168 { | |
| 169 do | |
| 170 more = findcells(i, j); | |
| 171 while (more != 0); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 crankout(); | |
| 176 ur_free(frontier); | |
| 177 ur_free(bits); | |
| 178 } | |
| 179 | |
| 180 /* | |
| 181 moffset() | |
| 182 Calculate memory address for bits | |
| 183 */ | |
| 184 | |
| 185 char * | |
| 186 moffset(int y, int x) | |
| 187 { | |
| 188 return (bits + (y * (COLS - 1)) + x); | |
| 189 } | |
| 190 | |
| 191 /* | |
| 192 foffset() | |
| 193 Calculate memory address for frontier | |
| 194 */ | |
| 195 | |
| 196 char * | |
| 197 foffset(int y, int x) | |
| 198 { | |
| 199 return (frontier + (y * urcols) + x); | |
| 200 } | |
| 201 | |
| 202 /* | |
| 203 findcells() | |
| 204 Figure out cells to open up | |
| 205 */ | |
| 206 | |
| 207 int | |
| 208 findcells(int y, int x) | |
| 209 { | |
| 210 int rtpos, i; | |
| 211 | |
| 212 struct | |
| 213 { | |
| 214 int num_pos; /* number of frontier cells next to you */ | |
| 215 | |
| 216 struct | |
| 217 { | |
| 218 int y_pos; | |
| 219 int x_pos; | |
| 220 } conn[4]; /* the y,x position of above cell */ | |
| 221 } mborder; | |
| 222 | |
| 223 *foffset(y, x) = FALSE; | |
| 224 mborder.num_pos = 0; | |
| 225 | |
| 226 if (y < urlines - 1) { /* look below */ | |
| 227 if (*foffset(y + 1, x)) | |
| 228 { | |
| 229 mborder.conn[mborder.num_pos].y_pos = y + 1; | |
| 230 mborder.conn[mborder.num_pos].x_pos = x; | |
| 231 mborder.num_pos += 1; | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 if (y > 0) /* look above */ | |
| 236 { | |
| 237 if (*foffset(y - 1, x)) | |
| 238 { | |
| 239 mborder.conn[mborder.num_pos].y_pos = y - 1; | |
| 240 mborder.conn[mborder.num_pos].x_pos = x; | |
| 241 mborder.num_pos += 1; | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 if (x < urcols - 1) /* look right */ | |
| 246 { | |
| 247 if (*foffset(y, x + 1)) | |
| 248 { | |
| 249 mborder.conn[mborder.num_pos].y_pos = y; | |
| 250 mborder.conn[mborder.num_pos].x_pos = x + 1; | |
| 251 mborder.num_pos += 1; | |
| 252 } | |
| 253 } | |
| 254 | |
| 255 if (x > 0) /* look left */ | |
| 256 { | |
| 257 if (*foffset(y, x - 1)) | |
| 258 { | |
| 259 mborder.conn[mborder.num_pos].y_pos = y; | |
| 260 mborder.conn[mborder.num_pos].x_pos = x - 1; | |
| 261 mborder.num_pos += 1; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 if (mborder.num_pos == 0)/* no neighbors available */ | |
| 266 return(0); | |
| 267 else | |
| 268 { | |
| 269 i = rnd(mborder.num_pos); | |
| 270 rtpos = mborder.num_pos - 1; | |
| 271 rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x); | |
| 272 return(rtpos); | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 /* | |
| 277 rmwall() | |
| 278 Removes appropriate walls from the maze | |
| 279 */ | |
| 280 | |
| 281 void | |
| 282 rmwall(int newy, int newx, int oldy, int oldx) | |
| 283 { | |
| 284 int xdif, ydif; | |
| 285 | |
| 286 xdif = newx - oldx; | |
| 287 ydif = newy - oldy; | |
| 288 | |
| 289 *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE; | |
| 290 | |
| 291 findcells(newy, newx); | |
| 292 } | |
| 293 | |
| 294 | |
| 295 /* | |
| 296 crankout() | |
| 297 Does actual drawing of maze to window | |
| 298 */ | |
| 299 | |
| 300 void | |
| 301 crankout(void) | |
| 302 { | |
| 303 int x, y; | |
| 304 | |
| 305 for (y = 0; y < LINES - 3; y++) | |
| 306 { | |
| 307 move(y + 1, 0); | |
| 308 | |
| 309 for (x = 0; x < COLS - 1; x++) | |
| 310 { | |
| 311 if (*moffset(y, x)) /* here is a wall */ | |
| 312 { | |
| 313 if (y == 0 || y == LINES - 4) /* top or bottom line */ | |
| 314 addch('-'); | |
| 315 else if (x == 0 || x == COLS - 2) /* left | right side */ | |
| 316 addch('|'); | |
| 317 else if (y % 2 == 0 && x % 2 == 0) | |
| 318 { | |
| 319 if (*moffset(y, x - 1) || *moffset(y, x + 1)) | |
| 320 addch('-'); | |
| 321 else | |
| 322 addch('|'); | |
| 323 } | |
| 324 else if (y % 2 == 0) | |
| 325 addch('-'); | |
| 326 else | |
| 327 addch('|'); | |
| 328 } | |
| 329 else | |
| 330 addch(FLOOR); | |
| 331 } | |
| 332 } | |
| 333 } |
