1 1.12 dholland /* $NetBSD: create.c,v 1.12 2012/06/19 05:30:43 dholland Exp $ */ 2 1.6 christos 3 1.6 christos /* create.c Larn is copyrighted 1986 by Noah Morgan. */ 4 1.6 christos 5 1.6 christos #include <sys/cdefs.h> 6 1.2 mycroft #ifndef lint 7 1.12 dholland __RCSID("$NetBSD: create.c,v 1.12 2012/06/19 05:30:43 dholland Exp $"); 8 1.6 christos #endif /* not lint */ 9 1.2 mycroft 10 1.1 cgd #include "header.h" 11 1.6 christos #include "extern.h" 12 1.6 christos #include <unistd.h> 13 1.10 dholland 14 1.10 dholland static void makemaze(int); 15 1.10 dholland static int cannedlevel(int); 16 1.10 dholland static void treasureroom(int); 17 1.10 dholland static void troom(int, int, int, int, int, int); 18 1.10 dholland static void makeobject(int); 19 1.10 dholland static void fillmroom(int, int, int); 20 1.10 dholland static void froom(int, int, int); 21 1.7 jsm static void fillroom(int, int); 22 1.10 dholland static void sethp(int); 23 1.10 dholland static void checkgen(void); 24 1.6 christos 25 1.1 cgd /* 26 1.1 cgd makeplayer() 27 1.1 cgd 28 1.1 cgd subroutine to create the player and the players attributes 29 1.1 cgd this is called at the beginning of a game and at no other time 30 1.1 cgd */ 31 1.6 christos void 32 1.12 dholland makeplayer(void) 33 1.6 christos { 34 1.6 christos int i; 35 1.6 christos scbr(); 36 1.6 christos clear(); 37 1.6 christos c[HPMAX] = c[HP] = 10; /* start player off with 15 hit points */ 38 1.6 christos c[LEVEL] = 1; /* player starts at level one */ 39 1.6 christos c[SPELLMAX] = c[SPELLS] = 1; /* total # spells starts off as 3 */ 40 1.6 christos c[REGENCOUNTER] = 16; 41 1.6 christos c[ECOUNTER] = 96; /* start regeneration correctly */ 42 1.1 cgd c[SHIELD] = c[WEAR] = c[WIELD] = -1; 43 1.6 christos for (i = 0; i < 26; i++) 44 1.6 christos iven[i] = 0; 45 1.6 christos spelknow[0] = spelknow[1] = 1; /* he knows protection, magic missile */ 46 1.6 christos if (c[HARDGAME] <= 0) { 47 1.6 christos iven[0] = OLEATHER; 48 1.6 christos iven[1] = ODAGGER; 49 1.6 christos ivenarg[1] = ivenarg[0] = c[WEAR] = 0; 50 1.6 christos c[WIELD] = 1; 51 1.6 christos } 52 1.6 christos playerx = rnd(MAXX - 2); 53 1.6 christos playery = rnd(MAXY - 2); 54 1.6 christos oldx = 0; 55 1.6 christos oldy = 25; 56 1.6 christos gltime = 0; /* time clock starts at zero */ 57 1.1 cgd cbak[SPELLS] = -50; 58 1.6 christos for (i = 0; i < 6; i++) 59 1.6 christos c[i] = 12; /* make the attributes, ie str, int, etc. */ 60 1.1 cgd recalc(); 61 1.6 christos } 62 1.6 christos 63 1.6 christos 64 1.1 cgd /* 65 1.1 cgd newcavelevel(level) 66 1.1 cgd int level; 67 1.1 cgd 68 1.1 cgd function to enter a new level. This routine must be called anytime the 69 1.1 cgd player changes levels. If that level is unknown it will be created. 70 1.1 cgd A new set of monsters will be created for a new level, and existing 71 1.1 cgd levels will get a few more monsters. 72 1.1 cgd Note that it is here we remove genocided monsters from the present level. 73 1.1 cgd */ 74 1.6 christos void 75 1.12 dholland newcavelevel(int x) 76 1.6 christos { 77 1.6 christos int i, j; 78 1.6 christos if (beenhere[level]) 79 1.6 christos savelevel(); /* put the level back into storage */ 80 1.6 christos level = x; /* get the new level and put in working 81 1.6 christos * storage */ 82 1.11 dholland if (beenhere[x]) { 83 1.6 christos getlevel(); 84 1.6 christos sethp(0); 85 1.11 dholland checkgen(); 86 1.11 dholland return; 87 1.6 christos } 88 1.11 dholland 89 1.11 dholland /* fill in new level */ 90 1.11 dholland for (i = 0; i < MAXY; i++) 91 1.11 dholland for (j = 0; j < MAXX; j++) 92 1.11 dholland know[j][i] = mitem[j][i] = 0; 93 1.6 christos makemaze(x); 94 1.6 christos makeobject(x); 95 1.6 christos beenhere[x] = 1; 96 1.6 christos sethp(1); 97 1.11 dholland checkgen(); /* wipe out any genocided monsters */ 98 1.1 cgd 99 1.1 cgd #if WIZID 100 1.6 christos if (wizard || x == 0) 101 1.1 cgd #else 102 1.6 christos if (x == 0) 103 1.1 cgd #endif 104 1.6 christos for (j = 0; j < MAXY; j++) 105 1.6 christos for (i = 0; i < MAXX; i++) 106 1.6 christos know[i][j] = 1; 107 1.6 christos } 108 1.1 cgd 109 1.1 cgd /* 110 1.1 cgd makemaze(level) 111 1.1 cgd int level; 112 1.1 cgd 113 1.1 cgd subroutine to make the caverns for a given level. only walls are made. 114 1.1 cgd */ 115 1.6 christos static int mx, mxl, mxh, my, myl, myh, tmp2; 116 1.10 dholland 117 1.10 dholland static void 118 1.12 dholland makemaze(int k) 119 1.6 christos { 120 1.6 christos int i, j, tmp; 121 1.6 christos int z; 122 1.6 christos if (k > 1 && (rnd(17) <= 4 || k == MAXLEVEL - 1 || k == MAXLEVEL + MAXVLEVEL - 1)) { 123 1.8 simonb if (cannedlevel(k)) 124 1.8 simonb return; /* read maze from data file */ 125 1.6 christos } 126 1.6 christos if (k == 0) 127 1.6 christos tmp = 0; 128 1.6 christos else 129 1.6 christos tmp = OWALL; 130 1.6 christos for (i = 0; i < MAXY; i++) 131 1.6 christos for (j = 0; j < MAXX; j++) 132 1.6 christos item[j][i] = tmp; 133 1.6 christos if (k == 0) 134 1.6 christos return; 135 1.6 christos eat(1, 1); 136 1.6 christos if (k == 1) 137 1.6 christos item[33][MAXY - 1] = 0; /* exit from dungeon */ 138 1.6 christos 139 1.6 christos /* now for open spaces -- not on level 10 */ 140 1.6 christos if (k != MAXLEVEL - 1) { 141 1.6 christos tmp2 = rnd(3) + 3; 142 1.6 christos for (tmp = 0; tmp < tmp2; tmp++) { 143 1.6 christos my = rnd(11) + 2; 144 1.6 christos myl = my - rnd(2); 145 1.6 christos myh = my + rnd(2); 146 1.6 christos if (k < MAXLEVEL) { 147 1.6 christos mx = rnd(44) + 5; 148 1.6 christos mxl = mx - rnd(4); 149 1.6 christos mxh = mx + rnd(12) + 3; 150 1.6 christos z = 0; 151 1.6 christos } else { 152 1.6 christos mx = rnd(60) + 3; 153 1.6 christos mxl = mx - rnd(2); 154 1.6 christos mxh = mx + rnd(2); 155 1.1 cgd z = makemonst(k); 156 1.6 christos } 157 1.6 christos for (i = mxl; i < mxh; i++) 158 1.6 christos for (j = myl; j < myh; j++) { 159 1.6 christos item[i][j] = 0; 160 1.6 christos if ((mitem[i][j] = z)) 161 1.6 christos hitp[i][j] = monster[z].hitpoints; 162 1.1 cgd } 163 1.1 cgd } 164 1.1 cgd } 165 1.6 christos if (k != MAXLEVEL - 1) { 166 1.6 christos my = rnd(MAXY - 2); 167 1.6 christos for (i = 1; i < MAXX - 1; i++) 168 1.6 christos item[i][my] = 0; 169 1.6 christos } 170 1.6 christos if (k > 1) 171 1.6 christos treasureroom(k); 172 1.6 christos } 173 1.1 cgd 174 1.1 cgd /* 175 1.1 cgd function to eat away a filled in maze 176 1.1 cgd */ 177 1.6 christos void 178 1.12 dholland eat(int xx, int yy) 179 1.6 christos { 180 1.6 christos int dir, try; 181 1.6 christos dir = rnd(4); 182 1.6 christos try = 2; 183 1.6 christos while (try) { 184 1.6 christos switch (dir) { 185 1.6 christos case 1: 186 1.6 christos if (xx <= 2) 187 1.6 christos break; /* west */ 188 1.6 christos if ((item[xx - 1][yy] != OWALL) || (item[xx - 2][yy] != OWALL)) 189 1.6 christos break; 190 1.6 christos item[xx - 1][yy] = item[xx - 2][yy] = 0; 191 1.6 christos eat(xx - 2, yy); 192 1.6 christos break; 193 1.6 christos 194 1.6 christos case 2: 195 1.6 christos if (xx >= MAXX - 3) 196 1.6 christos break; /* east */ 197 1.6 christos if ((item[xx + 1][yy] != OWALL) || (item[xx + 2][yy] != OWALL)) 198 1.6 christos break; 199 1.6 christos item[xx + 1][yy] = item[xx + 2][yy] = 0; 200 1.6 christos eat(xx + 2, yy); 201 1.6 christos break; 202 1.6 christos 203 1.6 christos case 3: 204 1.6 christos if (yy <= 2) 205 1.6 christos break; /* south */ 206 1.6 christos if ((item[xx][yy - 1] != OWALL) || (item[xx][yy - 2] != OWALL)) 207 1.6 christos break; 208 1.6 christos item[xx][yy - 1] = item[xx][yy - 2] = 0; 209 1.6 christos eat(xx, yy - 2); 210 1.6 christos break; 211 1.6 christos 212 1.6 christos case 4: 213 1.6 christos if (yy >= MAXY - 3) 214 1.6 christos break; /* north */ 215 1.6 christos if ((item[xx][yy + 1] != OWALL) || (item[xx][yy + 2] != OWALL)) 216 1.6 christos break; 217 1.6 christos item[xx][yy + 1] = item[xx][yy + 2] = 0; 218 1.6 christos eat(xx, yy + 2); 219 1.6 christos break; 220 1.6 christos }; 221 1.6 christos if (++dir > 4) { 222 1.6 christos dir = 1; 223 1.6 christos --try; 224 1.1 cgd } 225 1.1 cgd } 226 1.6 christos } 227 1.1 cgd 228 1.1 cgd /* 229 1.1 cgd * function to read in a maze from a data file 230 1.1 cgd * 231 1.1 cgd * Format of maze data file: 1st character = # of mazes in file (ascii digit) 232 1.1 cgd * For each maze: 18 lines (1st 17 used) 67 characters per line 233 1.1 cgd * 234 1.1 cgd * Special characters in maze data file: 235 1.1 cgd * 236 1.1 cgd * # wall D door . random monster 237 1.1 cgd * ~ eye of larn ! cure dianthroritis 238 1.1 cgd * - random object 239 1.1 cgd */ 240 1.10 dholland static int 241 1.12 dholland cannedlevel(int k) 242 1.6 christos { 243 1.6 christos char *row; 244 1.6 christos int i, j; 245 1.6 christos int it, arg, mit, marg; 246 1.6 christos if (lopen(larnlevels) < 0) { 247 1.6 christos write(1, "Can't open the maze data file\n", 30); 248 1.6 christos died(-282); 249 1.6 christos return (0); 250 1.6 christos } 251 1.6 christos i = lgetc(); 252 1.6 christos if (i <= '0') { 253 1.6 christos died(-282); 254 1.6 christos return (0); 255 1.6 christos } 256 1.6 christos for (i = 18 * rund(i - '0'); i > 0; i--) 257 1.6 christos lgetl(); /* advance to desired maze */ 258 1.6 christos for (i = 0; i < MAXY; i++) { 259 1.1 cgd row = lgetl(); 260 1.6 christos for (j = 0; j < MAXX; j++) { 261 1.1 cgd it = mit = arg = marg = 0; 262 1.6 christos switch (*row++) { 263 1.6 christos case '#': 264 1.6 christos it = OWALL; 265 1.6 christos break; 266 1.6 christos case 'D': 267 1.6 christos it = OCLOSEDDOOR; 268 1.6 christos arg = rnd(30); 269 1.6 christos break; 270 1.6 christos case '~': 271 1.6 christos if (k != MAXLEVEL - 1) 272 1.6 christos break; 273 1.6 christos it = OLARNEYE; 274 1.6 christos mit = rund(8) + DEMONLORD; 275 1.6 christos marg = monster[mit].hitpoints; 276 1.6 christos break; 277 1.6 christos case '!': 278 1.6 christos if (k != MAXLEVEL + MAXVLEVEL - 1) 279 1.6 christos break; 280 1.6 christos it = OPOTION; 281 1.6 christos arg = 21; 282 1.6 christos mit = DEMONLORD + 7; 283 1.6 christos marg = monster[mit].hitpoints; 284 1.6 christos break; 285 1.6 christos case '.': 286 1.6 christos if (k < MAXLEVEL) 287 1.6 christos break; 288 1.6 christos mit = makemonst(k + 1); 289 1.6 christos marg = monster[mit].hitpoints; 290 1.6 christos break; 291 1.6 christos case '-': 292 1.6 christos it = newobject(k + 1, &arg); 293 1.6 christos break; 294 1.6 christos }; 295 1.6 christos item[j][i] = it; 296 1.6 christos iarg[j][i] = arg; 297 1.6 christos mitem[j][i] = mit; 298 1.6 christos hitp[j][i] = marg; 299 1.1 cgd 300 1.1 cgd #if WIZID 301 1.1 cgd know[j][i] = (wizard) ? 1 : 0; 302 1.1 cgd #else 303 1.1 cgd know[j][i] = 0; 304 1.1 cgd #endif 305 1.1 cgd } 306 1.6 christos } 307 1.1 cgd lrclose(); 308 1.6 christos return (1); 309 1.6 christos } 310 1.1 cgd 311 1.1 cgd /* 312 1.1 cgd function to make a treasure room on a level 313 1.1 cgd level 10's treasure room has the eye in it and demon lords 314 1.1 cgd level V3 has potion of cure dianthroritis and demon prince 315 1.1 cgd */ 316 1.10 dholland static void 317 1.12 dholland treasureroom(int lv) 318 1.6 christos { 319 1.6 christos int tx, ty, xsize, ysize; 320 1.6 christos 321 1.6 christos for (tx = 1 + rnd(10); tx < MAXX - 10; tx += 10) 322 1.6 christos if ((lv == MAXLEVEL - 1) || (lv == MAXLEVEL + MAXVLEVEL - 1) || rnd(13) == 2) { 323 1.6 christos xsize = rnd(6) + 3; 324 1.6 christos ysize = rnd(3) + 3; 325 1.6 christos ty = rnd(MAXY - 9) + 1; /* upper left corner of room */ 326 1.6 christos if (lv == MAXLEVEL - 1 || lv == MAXLEVEL + MAXVLEVEL - 1) 327 1.6 christos troom(lv, xsize, ysize, tx = tx + rnd(MAXX - 24), ty, rnd(3) + 6); 328 1.6 christos else 329 1.6 christos troom(lv, xsize, ysize, tx, ty, rnd(9)); 330 1.1 cgd } 331 1.6 christos } 332 1.1 cgd 333 1.1 cgd /* 334 1.6 christos * subroutine to create a treasure room of any size at a given location 335 1.6 christos * room is filled with objects and monsters 336 1.1 cgd * the coordinate given is that of the upper left corner of the room 337 1.1 cgd */ 338 1.10 dholland static void 339 1.12 dholland troom(int lv, int xsize, int ysize, int tx, int ty, int glyph) 340 1.6 christos { 341 1.6 christos int i, j; 342 1.6 christos int tp1, tp2; 343 1.6 christos for (j = ty - 1; j <= ty + ysize; j++) 344 1.6 christos for (i = tx - 1; i <= tx + xsize; i++) /* clear out space for 345 1.6 christos * room */ 346 1.6 christos item[i][j] = 0; 347 1.6 christos for (j = ty; j < ty + ysize; j++) 348 1.6 christos for (i = tx; i < tx + xsize; i++) { /* now put in the walls */ 349 1.6 christos item[i][j] = OWALL; 350 1.6 christos mitem[i][j] = 0; 351 1.6 christos } 352 1.6 christos for (j = ty + 1; j < ty + ysize - 1; j++) 353 1.6 christos for (i = tx + 1; i < tx + xsize - 1; i++) /* now clear out 354 1.6 christos * interior */ 355 1.6 christos item[i][j] = 0; 356 1.6 christos 357 1.6 christos switch (rnd(2)) { /* locate the door on the treasure room */ 358 1.6 christos case 1: 359 1.6 christos item[i = tx + rund(xsize)][j = ty + (ysize - 1) * rund(2)] = OCLOSEDDOOR; 360 1.6 christos iarg[i][j] = glyph; /* on horizontal walls */ 361 1.6 christos break; 362 1.6 christos case 2: 363 1.6 christos item[i = tx + (xsize - 1) * rund(2)][j = ty + rund(ysize)] = OCLOSEDDOOR; 364 1.6 christos iarg[i][j] = glyph; /* on vertical walls */ 365 1.6 christos break; 366 1.6 christos }; 367 1.6 christos 368 1.6 christos tp1 = playerx; 369 1.6 christos tp2 = playery; 370 1.6 christos playery = ty + (ysize >> 1); 371 1.6 christos if (c[HARDGAME] < 2) 372 1.6 christos for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2) 373 1.6 christos for (i = 0, j = rnd(6); i <= j; i++) { 374 1.6 christos something(lv + 2); 375 1.6 christos createmonster(makemonst(lv + 1)); 376 1.6 christos } 377 1.6 christos else 378 1.6 christos for (playerx = tx + 1; playerx <= tx + xsize - 2; playerx += 2) 379 1.6 christos for (i = 0, j = rnd(4); i <= j; i++) { 380 1.6 christos something(lv + 2); 381 1.6 christos createmonster(makemonst(lv + 3)); 382 1.1 cgd } 383 1.1 cgd 384 1.6 christos playerx = tp1; 385 1.6 christos playery = tp2; 386 1.6 christos } 387 1.1 cgd 388 1.1 cgd 389 1.1 cgd /* 390 1.1 cgd *********** 391 1.1 cgd MAKE_OBJECT 392 1.1 cgd *********** 393 1.1 cgd subroutine to create the objects in the maze for the given level 394 1.1 cgd */ 395 1.10 dholland static void 396 1.12 dholland makeobject(int j) 397 1.6 christos { 398 1.6 christos int i; 399 1.6 christos if (j == 0) { 400 1.6 christos fillroom(OENTRANCE, 0); /* entrance to dungeon */ 401 1.6 christos fillroom(ODNDSTORE, 0); /* the DND STORE */ 402 1.6 christos fillroom(OSCHOOL, 0); /* college of Larn */ 403 1.6 christos fillroom(OBANK, 0); /* 1st national bank of larn */ 404 1.6 christos fillroom(OVOLDOWN, 0); /* volcano shaft to temple */ 405 1.6 christos fillroom(OHOME, 0); /* the players home & family */ 406 1.6 christos fillroom(OTRADEPOST, 0); /* the trading post */ 407 1.6 christos fillroom(OLRS, 0); /* the larn revenue service */ 408 1.1 cgd return; 409 1.6 christos } 410 1.6 christos if (j == MAXLEVEL) 411 1.6 christos fillroom(OVOLUP, 0); /* volcano shaft up from the temple */ 412 1.1 cgd 413 1.6 christos /* make the fixed objects in the maze STAIRS */ 414 1.6 christos if ((j > 0) && (j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1)) 415 1.6 christos fillroom(OSTAIRSDOWN, 0); 416 1.6 christos if ((j > 1) && (j != MAXLEVEL)) 417 1.6 christos fillroom(OSTAIRSUP, 0); 418 1.6 christos 419 1.6 christos /* make the random objects in the maze */ 420 1.6 christos 421 1.6 christos fillmroom(rund(3), OBOOK, j); 422 1.6 christos fillmroom(rund(3), OALTAR, 0); 423 1.6 christos fillmroom(rund(3), OSTATUE, 0); 424 1.6 christos fillmroom(rund(3), OPIT, 0); 425 1.6 christos fillmroom(rund(3), OFOUNTAIN, 0); 426 1.6 christos fillmroom(rnd(3) - 2, OIVTELETRAP, 0); 427 1.6 christos fillmroom(rund(2), OTHRONE, 0); 428 1.6 christos fillmroom(rund(2), OMIRROR, 0); 429 1.6 christos fillmroom(rund(2), OTRAPARROWIV, 0); 430 1.6 christos fillmroom(rnd(3) - 2, OIVDARTRAP, 0); 431 1.6 christos fillmroom(rund(3), OCOOKIE, 0); 432 1.6 christos if (j == 1) 433 1.6 christos fillmroom(1, OCHEST, j); 434 1.6 christos else 435 1.6 christos fillmroom(rund(2), OCHEST, j); 436 1.6 christos if ((j != MAXLEVEL - 1) && (j != MAXLEVEL + MAXVLEVEL - 1)) 437 1.6 christos fillmroom(rund(2), OIVTRAPDOOR, 0); 438 1.6 christos if (j <= 10) { 439 1.6 christos fillmroom((rund(2)), ODIAMOND, rnd(10 * j + 1) + 10); 440 1.6 christos fillmroom(rund(2), ORUBY, rnd(6 * j + 1) + 6); 441 1.6 christos fillmroom(rund(2), OEMERALD, rnd(4 * j + 1) + 4); 442 1.6 christos fillmroom(rund(2), OSAPPHIRE, rnd(3 * j + 1) + 2); 443 1.6 christos } 444 1.6 christos for (i = 0; i < rnd(4) + 3; i++) 445 1.6 christos fillroom(OPOTION, newpotion()); /* make a POTION */ 446 1.6 christos for (i = 0; i < rnd(5) + 3; i++) 447 1.6 christos fillroom(OSCROLL, newscroll()); /* make a SCROLL */ 448 1.6 christos for (i = 0; i < rnd(12) + 11; i++) 449 1.6 christos fillroom(OGOLDPILE, 12 * rnd(j + 1) + (j << 3) + 10); /* make GOLD */ 450 1.6 christos if (j == 5) 451 1.6 christos fillroom(OBANK2, 0); /* branch office of the bank */ 452 1.6 christos froom(2, ORING, 0); /* a ring mail */ 453 1.6 christos froom(1, OSTUDLEATHER, 0); /* a studded leather */ 454 1.6 christos froom(3, OSPLINT, 0); /* a splint mail */ 455 1.6 christos froom(5, OSHIELD, rund(3)); /* a shield */ 456 1.6 christos froom(2, OBATTLEAXE, rund(3)); /* a battle axe */ 457 1.6 christos froom(5, OLONGSWORD, rund(3)); /* a long sword */ 458 1.6 christos froom(5, OFLAIL, rund(3)); /* a flail */ 459 1.6 christos froom(4, OREGENRING, rund(3)); /* ring of regeneration */ 460 1.6 christos froom(1, OPROTRING, rund(3)); /* ring of protection */ 461 1.6 christos froom(2, OSTRRING, 4); /* ring of strength + 4 */ 462 1.6 christos froom(7, OSPEAR, rnd(5)); /* a spear */ 463 1.6 christos froom(3, OORBOFDRAGON, 0); /* orb of dragon slaying */ 464 1.6 christos froom(4, OSPIRITSCARAB, 0); /* scarab of negate spirit */ 465 1.6 christos froom(4, OCUBEofUNDEAD, 0); /* cube of undead control */ 466 1.6 christos froom(2, ORINGOFEXTRA, 0); /* ring of extra regen */ 467 1.6 christos froom(3, ONOTHEFT, 0); /* device of antitheft */ 468 1.6 christos froom(2, OSWORDofSLASHING, 0); /* sword of slashing */ 469 1.6 christos if (c[BESSMANN] == 0) { 470 1.6 christos froom(4, OHAMMER, 0); /* Bessman's flailing hammer */ 471 1.6 christos c[BESSMANN] = 1; 472 1.6 christos } 473 1.6 christos if (c[HARDGAME] < 3 || (rnd(4) == 3)) { 474 1.6 christos if (j > 3) { 475 1.6 christos froom(3, OSWORD, 3); /* sunsword + 3 */ 476 1.6 christos froom(5, O2SWORD, rnd(4)); /* a two handed sword */ 477 1.6 christos froom(3, OBELT, 4); /* belt of striking */ 478 1.6 christos froom(3, OENERGYRING, 3); /* energy ring */ 479 1.6 christos froom(4, OPLATE, 5); /* platemail + 5 */ 480 1.1 cgd } 481 1.1 cgd } 482 1.6 christos } 483 1.1 cgd 484 1.1 cgd /* 485 1.1 cgd subroutine to fill in a number of objects of the same kind 486 1.1 cgd */ 487 1.1 cgd 488 1.10 dholland static void 489 1.12 dholland fillmroom(int n, int what_i, int arg) 490 1.6 christos { 491 1.6 christos int i; 492 1.12 dholland char what; 493 1.12 dholland 494 1.12 dholland /* truncate to char width (just in case it matters) */ 495 1.12 dholland what = (char)what_i; 496 1.6 christos for (i = 0; i < n; i++) 497 1.6 christos fillroom(what, arg); 498 1.6 christos } 499 1.10 dholland 500 1.10 dholland static void 501 1.9 dholland froom(int n, int theitem, int arg) 502 1.6 christos { 503 1.6 christos if (rnd(151) < n) 504 1.9 dholland fillroom(theitem, arg); 505 1.6 christos } 506 1.1 cgd 507 1.1 cgd /* 508 1.1 cgd subroutine to put an object into an empty room 509 1.1 cgd * uses a random walk 510 1.1 cgd */ 511 1.1 cgd static void 512 1.12 dholland fillroom(int what_i, int arg) 513 1.6 christos { 514 1.6 christos int x, y; 515 1.12 dholland char what; 516 1.12 dholland 517 1.12 dholland /* truncate to char width (just in case it matters) */ 518 1.12 dholland what = (char)what_i; 519 1.1 cgd 520 1.1 cgd #ifdef EXTRA 521 1.1 cgd c[FILLROOM]++; 522 1.1 cgd #endif 523 1.1 cgd 524 1.6 christos x = rnd(MAXX - 2); 525 1.6 christos y = rnd(MAXY - 2); 526 1.6 christos while (item[x][y]) { 527 1.1 cgd 528 1.1 cgd #ifdef EXTRA 529 1.6 christos c[RANDOMWALK]++;/* count up these random walks */ 530 1.1 cgd #endif 531 1.1 cgd 532 1.6 christos x += rnd(3) - 2; 533 1.6 christos y += rnd(3) - 2; 534 1.6 christos if (x > MAXX - 2) 535 1.6 christos x = 1; 536 1.6 christos if (x < 1) 537 1.6 christos x = MAXX - 2; 538 1.6 christos if (y > MAXY - 2) 539 1.6 christos y = 1; 540 1.6 christos if (y < 1) 541 1.6 christos y = MAXY - 2; 542 1.6 christos } 543 1.6 christos item[x][y] = what; 544 1.6 christos iarg[x][y] = arg; 545 1.6 christos } 546 1.1 cgd 547 1.1 cgd /* 548 1.1 cgd subroutine to put monsters into an empty room without walls or other 549 1.1 cgd monsters 550 1.1 cgd */ 551 1.6 christos int 552 1.12 dholland fillmonst(int what) 553 1.6 christos { 554 1.6 christos int x, y, trys; 555 1.6 christos for (trys = 5; trys > 0; --trys) { /* max # of creation attempts */ 556 1.6 christos x = rnd(MAXX - 2); 557 1.6 christos y = rnd(MAXY - 2); 558 1.6 christos if ((item[x][y] == 0) && (mitem[x][y] == 0) && ((playerx != x) || (playery != y))) { 559 1.6 christos mitem[x][y] = what; 560 1.6 christos know[x][y] = 0; 561 1.6 christos hitp[x][y] = monster[what].hitpoints; 562 1.6 christos return (0); 563 1.1 cgd } 564 1.1 cgd } 565 1.6 christos return (-1); /* creation failure */ 566 1.6 christos } 567 1.1 cgd 568 1.1 cgd /* 569 1.1 cgd creates an entire set of monsters for a level 570 1.1 cgd must be done when entering a new level 571 1.1 cgd if sethp(1) then wipe out old monsters else leave them there 572 1.1 cgd */ 573 1.10 dholland static void 574 1.12 dholland sethp(int flg) 575 1.6 christos { 576 1.6 christos int i, j; 577 1.6 christos if (flg) 578 1.6 christos for (i = 0; i < MAXY; i++) 579 1.6 christos for (j = 0; j < MAXX; j++) 580 1.6 christos stealth[j][i] = 0; 581 1.6 christos if (level == 0) { 582 1.6 christos c[TELEFLAG] = 0; 583 1.6 christos return; 584 1.6 christos } /* if teleported and found level 1 then know 585 1.6 christos * level we are on */ 586 1.6 christos if (flg) 587 1.6 christos j = rnd(12) + 2 + (level >> 1); 588 1.6 christos else 589 1.6 christos j = (level >> 1) + 1; 590 1.6 christos for (i = 0; i < j; i++) 591 1.6 christos fillmonst(makemonst(level)); 592 1.1 cgd positionplayer(); 593 1.6 christos } 594 1.1 cgd 595 1.1 cgd /* 596 1.1 cgd * Function to destroy all genocided monsters on the present level 597 1.1 cgd */ 598 1.10 dholland static void 599 1.10 dholland checkgen(void) 600 1.6 christos { 601 1.6 christos int x, y; 602 1.6 christos for (y = 0; y < MAXY; y++) 603 1.6 christos for (x = 0; x < MAXX; x++) 604 1.1 cgd if (monster[mitem[x][y]].genocided) 605 1.6 christos mitem[x][y] = 0; /* no more monster */ 606 1.6 christos } 607