Annotation of early-roguelike/xrogue/n_level.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: n_level.c - Dig and draw a new level
! 3:
! 4: XRogue: Expeditions into the Dungeons of Doom
! 5: Copyright (C) 1991 Robert Pietkivitch
! 6: All rights reserved.
! 7:
! 8: Based on "Advanced Rogue"
! 9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
! 10: All rights reserved.
! 11:
! 12: Based on "Rogue: Exploring the Dungeons of Doom"
! 13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 14: All rights reserved.
! 15:
! 16: See the file LICENSE.TXT for full copyright and licensing information.
! 17: */
! 18:
! 19: #include <curses.h>
! 20: #include "rogue.h"
! 21: #define TERRASAVE 3
! 22:
! 23: void put_things(LEVTYPE ltype);
! 24:
! 25: /*
! 26: * new_level:
! 27: * Dig and draw a new level
! 28: * ltype: designates type of level to create
! 29: */
! 30:
! 31: void
! 32: new_level(LEVTYPE ltype)
! 33: {
! 34: register int rm = 0, i, cnt;
! 35: register unsigned char ch;
! 36: register struct linked_list *item;
! 37: register struct thing *tp;
! 38: register struct object *obj;
! 39: int waslit = 0; /* Was the previous outside level lit? */
! 40: int starty = 0, startx = 0, deltay = 0, deltax = 0;
! 41: bool fresh=TRUE, vert = 0, top;
! 42: struct room *rp;
! 43: struct linked_list *nitem, *savmonst=NULL, *savitems=NULL;
! 44: coord stairs = {0,0};
! 45:
! 46: if (wizard) {
! 47: msg("Turns: %ld", turns); /* Number of turns for last level */
! 48: mpos = 0;
! 49: }
! 50:
! 51: /* Start player off right */
! 52: turn_off(player, ISHELD);
! 53: turn_off(player, ISFLEE);
! 54: extinguish(suffocate);
! 55: hold_count = 0;
! 56: trap_tries = 0;
! 57:
! 58: /* Are we just entering a dungeon? If so, how big is it? */
! 59: if (ltype != OUTSIDE && nfloors < 0) nfloors = HARDER+20 + rnd(51);
! 60:
! 61: if (level > max_level)
! 62: max_level = level;
! 63:
! 64: /* Are we starting a new outside level? */
! 65: if (ltype == OUTSIDE) {
! 66: register int i, j;
! 67:
! 68: /* Save some information prior to clearing the screen */
! 69: if (level == -1 || mvinch(hero.y, hero.x) == HORZWALL) vert = TRUE;
! 70: else vert = FALSE;
! 71:
! 72: if (level < 1) {
! 73: fresh = TRUE;
! 74: starty = 2;
! 75: startx = 1;
! 76: deltay = deltax = 1;
! 77: level = max_level; /* Restore level to deepest attempt */
! 78: prev_max = level; /* reset for boundary crossings below */
! 79: }
! 80: else if (level >= 1 && prev_max == 1000) {
! 81: fresh = TRUE;
! 82: starty = 2;
! 83: startx = 1;
! 84: deltay = deltax = 1;
! 85: prev_max = level; /* reset for boundary crossings below */
! 86: }
! 87: else { /* Copy several lines of the terrain to the other end */
! 88:
! 89: unsigned char cch; /* Copy character */
! 90:
! 91: if (wizard) msg("Crossing sector boundary ");
! 92:
! 93: /* Was the area dark (not magically lit)? */
! 94: if (!(rooms[0].r_flags & ISDARK)) waslit = 1;
! 95:
! 96: fresh = FALSE;
! 97: if ((vert && hero.y == 1) || (!vert && hero.x == 0)) top = TRUE;
! 98: else top = FALSE;
! 99: for (i=0; i<TERRASAVE; i++) {
! 100: if (vert)
! 101: for (j=1; j<cols-1; j++) {
! 102: if (top) {
! 103: cch = mvinch(i+2, j);
! 104: mvaddch(lines-6+i, j, cch);
! 105: }
! 106: else {
! 107: cch = mvinch(lines-4-i, j);
! 108: mvaddch(4-i, j, cch);
! 109: }
! 110: }
! 111: else
! 112: for (j=2; j<lines-3; j++) {
! 113: if (top) {
! 114: cch = mvinch(j, i+1);
! 115: mvaddch(j, cols-4+i, cch);
! 116: }
! 117: else {
! 118: cch = mvinch(j, cols-2-i);
! 119: mvaddch(j, 3-i, cch);
! 120: }
! 121: }
! 122: }
! 123:
! 124: if (vert) {
! 125: startx = deltax = 1;
! 126: if (top) {
! 127: starty = lines-4-TERRASAVE;
! 128: deltay = -1;
! 129: }
! 130: else {
! 131: starty = TERRASAVE + 2;
! 132: deltay = 1;
! 133: }
! 134: }
! 135: else {
! 136: starty = 2;
! 137: deltay = 1;
! 138: if (top) {
! 139: startx = cols-2-TERRASAVE;
! 140: deltax = -1;
! 141: }
! 142: else {
! 143: deltax = 1;
! 144: startx = TERRASAVE + 1;
! 145: }
! 146: }
! 147:
! 148: /* Check if any monsters should be saved */
! 149: for (item = mlist; item != NULL; item = nitem) {
! 150: nitem = next(item);
! 151: tp = THINGPTR(item);
! 152: if (vert) {
! 153: if (top) {
! 154: if (tp->t_pos.y < TERRASAVE + 2)
! 155: tp->t_pos.y += lines - 5 - TERRASAVE;
! 156: else continue;
! 157: }
! 158: else {
! 159: if (tp->t_pos.y > lines - 4 - TERRASAVE)
! 160: tp->t_pos.y += 5 + TERRASAVE - lines;
! 161: else continue;
! 162: }
! 163: }
! 164: else {
! 165: if (top) {
! 166: if (tp->t_pos.x < TERRASAVE + 1)
! 167: tp->t_pos.x += cols - 2 - TERRASAVE;
! 168: else continue;
! 169: }
! 170: else {
! 171: if (tp->t_pos.x > cols - 2 - TERRASAVE)
! 172: tp->t_pos.x += 2 + TERRASAVE - cols;
! 173: else continue;
! 174: }
! 175: }
! 176:
! 177: /*
! 178: * If the monster is busy chasing another monster, don't save
! 179: * it
! 180: */
! 181: if (tp->t_dest && tp->t_dest != &hero) continue;
! 182:
! 183: /* Outside has plenty of monsters, don't need these.
! 184: * detach(mlist, item);
! 185: * attach(savmonst, item);
! 186: */
! 187: }
! 188:
! 189: /* Check if any treasure should be saved */
! 190: for (item = lvl_obj; item != NULL; item = nitem) {
! 191: nitem = next(item);
! 192: obj = OBJPTR(item);
! 193: if (vert) {
! 194: if (top) {
! 195: if (obj->o_pos.y < TERRASAVE + 2)
! 196: obj->o_pos.y += lines - 5 - TERRASAVE;
! 197: else continue;
! 198: }
! 199: else {
! 200: if (obj->o_pos.y > lines - 4 - TERRASAVE)
! 201: obj->o_pos.y += 5 + TERRASAVE - lines;
! 202: else continue;
! 203: }
! 204: }
! 205: else {
! 206: if (top) {
! 207: if (obj->o_pos.x < TERRASAVE + 1)
! 208: obj->o_pos.x += cols - 2 - TERRASAVE;
! 209: else continue;
! 210: }
! 211: else {
! 212: if (obj->o_pos.x > cols - 2 - TERRASAVE)
! 213: obj->o_pos.x += 2 + TERRASAVE - cols;
! 214: else continue;
! 215: }
! 216: }
! 217: detach(lvl_obj, item);
! 218: attach(savitems, item);
! 219: }
! 220: }
! 221: }
! 222:
! 223: wclear(cw);
! 224: wclear(mw);
! 225: if (fresh || levtype != OUTSIDE) clear();
! 226: /*
! 227: * check to see if he missed a UNIQUE, If he did then put it back
! 228: * in the monster table for next time
! 229: */
! 230: for (item = mlist; item != NULL; item = next(item)) {
! 231: tp = THINGPTR(item);
! 232: if (on(*tp, ISUNIQUE))
! 233: monsters[tp->t_index].m_normal = TRUE;
! 234: }
! 235: /*
! 236: * Free up the monsters on the last level
! 237: */
! 238: t_free_list(mlist);
! 239: o_free_list(lvl_obj); /* Free up previous objects (if any) */
! 240: for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
! 241: r_free_list(rp->r_exit); /* Free up the exit lists */
! 242:
! 243: levtype = ltype;
! 244: foods_this_level = 0; /* food for hero this level */
! 245:
! 246: /* What kind of level are we on? */
! 247: if (ltype == POSTLEV || ltype == STARTLEV) {
! 248: if (ltype == POSTLEV)
! 249: do_post(FALSE); /* Trading post */
! 250: else
! 251: do_post(TRUE); /* Equipage */
! 252:
! 253: levtype = ltype = POSTLEV;
! 254: }
! 255: else if (ltype == MAZELEV) {
! 256: do_maze();
! 257: no_food++;
! 258: put_things(ltype); /* Place objects (if any) */
! 259: }
! 260: else if (ltype == OUTSIDE) {
! 261: /* Move the cursor back onto the hero */
! 262: wmove(cw, hero.y, hero.x);
! 263: init_terrain();
! 264: do_terrain(starty, startx, deltay, deltax, (bool) (fresh || !vert));
! 265: no_food++;
! 266: put_things(ltype);
! 267:
! 268: /* Should we magically light this area? */
! 269: if (waslit) rooms[0].r_flags &= ~ISDARK;
! 270: }
! 271: else {
! 272: do_rooms(); /* Draw rooms */
! 273: do_passages(); /* Draw passages */
! 274: no_food++;
! 275: put_things(ltype); /* Place objects (if any) */
! 276: }
! 277: /*
! 278: * Place the staircase down. Only a small chance for an outside stairway.
! 279: */
! 280: if (ltype != OUTSIDE || roll(1, 5) == 5) {
! 281: cnt = 0;
! 282: do {
! 283: rm = rnd_room();
! 284: rnd_pos(&rooms[rm], &stairs);
! 285: } until (mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 2500);
! 286: addch(STAIRS);
! 287: }
! 288: /*
! 289: * maybe add a trading post
! 290: */
! 291: if (level > 5 && rnd(10) == 7 && ltype == NORMLEV) {
! 292: cnt = 0;
! 293: do {
! 294: rm = rnd_room();
! 295: if (rooms[rm].r_flags & ISTREAS)
! 296: continue;
! 297: rnd_pos(&rooms[rm], &stairs);
! 298: } until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 2500);
! 299: addch(POST);
! 300: }
! 301: if (ltype != POSTLEV) { /* Add monsters that fell through */
! 302: nitem = tlist;
! 303: while (nitem != NULL) {
! 304: item = nitem;
! 305: nitem = next(item); /* because detach and attach mess up ptrs */
! 306: tp = THINGPTR(item);
! 307: cnt = 0;
! 308: do {
! 309: rm = rnd_room();
! 310: rnd_pos(&rooms[rm], &tp->t_pos);
! 311: } until (cnt++ > 2500 || winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
! 312: mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
! 313: tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x);
! 314:
! 315: /*
! 316: * If it has a fire, mark it
! 317: */
! 318: if (on(*tp, HASFIRE)) {
! 319: register struct linked_list *fire_item;
! 320:
! 321: fire_item = creat_item();
! 322: ldata(fire_item) = (char *) tp;
! 323: attach(rooms[rm].r_fires, fire_item);
! 324: rooms[rm].r_flags |= HASFIRE;
! 325: }
! 326:
! 327: detach(tlist, item);
! 328: turn_off(*tp,ISELSEWHERE);
! 329: attach(mlist, item);
! 330: }
! 331: }
! 332:
! 333: /* Restore any saved monsters */
! 334: for (item = savmonst; item != NULL; item = nitem) {
! 335: nitem = next(item);
! 336: tp = THINGPTR(item);
! 337: mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
! 338: tp->t_oldch = mvwinch(cw, tp->t_pos.y, tp->t_pos.x);
! 339:
! 340: /*
! 341: * If it has a fire, mark it
! 342: */
! 343: if (on(*tp, HASFIRE)) {
! 344: register struct linked_list *fire_item;
! 345:
! 346: fire_item = creat_item();
! 347: ldata(fire_item) = (char *) tp;
! 348: attach(rooms[rm].r_fires, fire_item);
! 349: rooms[rm].r_flags |= HASFIRE;
! 350: }
! 351:
! 352: detach(savmonst, item);
! 353: attach(mlist, item);
! 354: }
! 355:
! 356: /* Restore any saved objects */
! 357: for(item = savitems; item != NULL; item = nitem) {
! 358: nitem = next(item);
! 359: obj = OBJPTR(item);
! 360: mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
! 361: detach(savitems, item);
! 362: attach(lvl_obj, item);
! 363: }
! 364:
! 365: /*
! 366: * Place the traps (except for trading post)
! 367: */
! 368: ntraps = 0; /* No traps yet */
! 369: if (levtype == NORMLEV) {
! 370: if (rnd(10) < vlevel) {
! 371: ntraps = rnd(vlevel/4)+2;
! 372: if (ntraps > MAXTRAPS)
! 373: ntraps = MAXTRAPS;
! 374: i = ntraps;
! 375: while (i--)
! 376: {
! 377: cnt = 0;
! 378: do {
! 379: rm = rnd_room();
! 380: if (rooms[rm].r_flags & ISTREAS)
! 381: continue;
! 382: rnd_pos(&rooms[rm], &stairs);
! 383: } until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 2500);
! 384:
! 385: traps[i].tr_flags = 0;
! 386:
! 387: /* If we are at the bottom, we can't set a trap door */
! 388: if (level >= nfloors) ch = (unsigned char) rnd(8) + 1;
! 389: else ch = (unsigned char) rnd(9);
! 390:
! 391: switch((int) ch) {
! 392: case 0: ch = TRAPDOOR;
! 393: when 1: ch = BEARTRAP;
! 394: when 2: ch = SLEEPTRAP;
! 395: when 3: ch = ARROWTRAP;
! 396: when 4: ch = TELTRAP;
! 397: when 5: ch = DARTTRAP;
! 398: when 6: ch = POOL;
! 399: traps[i].tr_flags = ISFOUND;
! 400: when 7: ch = MAZETRAP;
! 401: when 8: ch = WORMHOLE;
! 402: }
! 403: addch(ch);
! 404: traps[i].tr_type = ch;
! 405: traps[i].tr_show = FLOOR;
! 406: traps[i].tr_pos = stairs;
! 407: }
! 408: }
! 409: }
! 410: if (fresh) { /* A whole new picture */
! 411: /*
! 412: * try to find a room for the hero. The objective here is to:
! 413: * --> don't put him in a treasure room
! 414: * --> don't put him on an object
! 415: * --> try not to put him next to the stairs
! 416: */
! 417: cnt = 2500;
! 418: do {
! 419: if (ltype != OUTSIDE) rm = rnd_room();
! 420: else continue;
! 421:
! 422: if (rooms[rm].r_flags & ISTREAS)
! 423: continue;
! 424:
! 425: rnd_pos(&rooms[rm], &hero);
! 426: } until( cnt-- == 0 ||
! 427: (winat(hero.y, hero.x) == FLOOR &&
! 428: DISTANCE(hero.y, hero.x, stairs.y, stairs.x) > cnt/10));
! 429: }
! 430: else { /* We're extending into an adjacent outside plane */
! 431: rm = 0;
! 432: if (vert) {
! 433: if (hero.y == 1) hero.y = lines - 3 - TERRASAVE; /* Top to bottom */
! 434: else hero.y = TERRASAVE + 1; /* Bottom to top */
! 435: }
! 436: else {
! 437: if (hero.x == 0) hero.x = cols - 1 - TERRASAVE; /* Right to left */
! 438: else hero.x = TERRASAVE; /* Left to right */
! 439: }
! 440: }
! 441: oldrp = &rooms[rm]; /* Set the current room */
! 442: player.t_oldpos = player.t_pos; /* Set the current position */
! 443:
! 444: if (ISWEARING(R_AGGR) ||
! 445: (cur_misc[WEAR_JEWEL] != NULL &&
! 446: cur_misc[WEAR_JEWEL]->o_which == MM_JEWEL))
! 447: aggravate(TRUE, TRUE); /* affect all charactors */
! 448:
! 449: /*
! 450: * If player is moving up or above his deepest point, wake up any
! 451: * non-uniques
! 452: */
! 453: else if (level < cur_max) {
! 454: aggravate(FALSE, FALSE);
! 455: }
! 456:
! 457: light(&hero);
! 458: wmove(cw, hero.y, hero.x);
! 459: waddch(cw, PLAYER);
! 460:
! 461: if (level > cur_max)
! 462: cur_max = level;
! 463:
! 464: draw(cw);
! 465:
! 466: status(TRUE);
! 467:
! 468: /* Do we sense any food on this level? */
! 469: if (cur_relic[SURTUR_RING])
! 470: quaff(P_FFIND, 0, 0, FALSE);
! 471: }
! 472:
! 473: /*
! 474: * Pick a room that is really there
! 475: */
! 476:
! 477: int
! 478: rnd_room(void)
! 479: {
! 480: register int rm;
! 481:
! 482: if (levtype != NORMLEV)
! 483: rm = 0;
! 484: else do
! 485: {
! 486: rm = rnd(MAXROOMS);
! 487: } while (rooms[rm].r_flags & ISGONE);
! 488: return rm;
! 489: }
! 490:
! 491: /*
! 492: * put_things:
! 493: * put potions and scrolls on this level
! 494: * ltype: designates type of level to create
! 495: */
! 496:
! 497: void
! 498: put_things(LEVTYPE ltype)
! 499: {
! 500: register int i, rm, cnt;
! 501: register struct object *cur;
! 502: register struct linked_list *item, *nextitem, *exitptr;
! 503: int length, width;
! 504: int ITEMS = 0; /* number of items to place */
! 505: coord tp, *exit;
! 506:
! 507: /*
! 508: * The only way to get new stuff is to go down into the dungeon.
! 509: */
! 510: if (level < cur_max) {
! 511: if (ltype == NORMLEV)
! 512: return;
! 513: }
! 514:
! 515: if (ltype == OUTSIDE) goto jmp_here; /* a jump for outside */
! 516:
! 517: /*
! 518: * There is a chance that there is a Treasure Room on this level
! 519: */
! 520: if (ltype == NORMLEV && rnd(150) < level) {
! 521: register int j;
! 522: register struct room *rp;
! 523:
! 524: /* Count the number of free spaces */
! 525: i = 0; /* 0 tries */
! 526: do {
! 527: rp = &rooms[rnd_room()];
! 528: width = rp->r_max.y - 2;
! 529: length = rp->r_max.x - 2;
! 530: } until ((width*length >= MAXTREAS) || (i++ > MAXROOMS*4));
! 531:
! 532: /* Mark the room as a treasure room */
! 533: rp->r_flags |= ISTREAS;
! 534:
! 535: /* Make all the doors secret doors */
! 536: for (exitptr = rp->r_exit; exitptr; exitptr = next(exitptr)) {
! 537: exit = DOORPTR(exitptr);
! 538: move(exit->y, exit->x);
! 539: addch(SECRETDOOR);
! 540: }
! 541:
! 542: /*
! 543: * check to see if there are any monsters in room already
! 544: */
! 545: for (item = mlist; item != NULL; item = nextitem) {
! 546: register struct thing *tp;
! 547:
! 548: tp = THINGPTR(item);
! 549: nextitem = next(item);
! 550: if (rp == roomin(&tp->t_pos)) {
! 551: /*
! 552: * Don't let nice creatures be generated in a treasure
! 553: * room.
! 554: */
! 555: if ((player.t_ctype==C_PALADIN || player.t_ctype==C_RANGER ||
! 556: player.t_ctype==C_MONK) && off(*tp, ISMEAN)) {
! 557: int index;
! 558:
! 559: if (on(*tp, ISUNIQUE)) index = tp->t_index;
! 560: else index = -1;
! 561:
! 562: /* Get rid of the monster */
! 563: killed(item, FALSE, FALSE, FALSE);
! 564:
! 565: /* Restore uniques back in the table */
! 566: if (index != -1) monsters[index].m_normal = TRUE;
! 567:
! 568: continue;
! 569: }
! 570: turn_on(*tp, ISMEAN);
! 571: turn_on(*tp, ISGUARDIAN);
! 572: }
! 573: }
! 574:
! 575: /* Put in the monsters and treasures */
! 576: for (j=1; j<rp->r_max.y-1; j++)
! 577: for (i=1; i<rp->r_max.x-1; i++) {
! 578: coord trp;
! 579:
! 580: trp.y = rp->r_pos.y+j;
! 581: trp.x = rp->r_pos.x+i;
! 582:
! 583: /* Monsters */
! 584: if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
! 585: (mvwinch(mw, rp->r_pos.y+j, rp->r_pos.x+i) == ' ')) {
! 586: register struct thing *tp;
! 587:
! 588: /*
! 589: * Put it there and leave it asleep. Wake the monsters
! 590: * when the player enters the room. Hopefully, all bases
! 591: * are covered as far as the ways to get in. This way
! 592: * cpu time is not wasted on the awake monsters that
! 593: * can't get to the player anyway.
! 594: * try not to put any UNIQUEs in a treasure room.
! 595: * note that they may have put put in already by the
! 596: * non-treasure room code.
! 597: * also, try not to put ISMEAN monsters in a treasure
! 598: * room as these are supposed to be non-hostile until
! 599: * attacked. It also makes life simpler for the ranger,
! 600: * paladin, and monk.
! 601: */
! 602: for(;;) {
! 603: item = new_item(sizeof *tp); /* Make a monster */
! 604: tp = THINGPTR(item);
! 605: new_monster(item,randmonster(FALSE, TRUE),&trp,TRUE);
! 606: if (on(*tp, HASFIRE)) {
! 607: register struct linked_list *fire_item;
! 608:
! 609: fire_item = creat_item();
! 610: ldata(fire_item) = (char *) tp;
! 611: attach(rp->r_fires, fire_item);
! 612: rp->r_flags |= HASFIRE;
! 613: }
! 614: /*
! 615: * only picky for these classes
! 616: */
! 617: if (player.t_ctype != C_RANGER &&
! 618: player.t_ctype != C_PALADIN &&
! 619: player.t_ctype != C_MONK)
! 620: break;
! 621: if (on(*tp, ISMEAN))
! 622: break;
! 623: killed (item, FALSE, FALSE, FALSE);
! 624: }
! 625: if (on(*tp, ISUNIQUE)) { /* just in case */
! 626: carry_obj(tp, monsters[tp->t_index].m_carry);
! 627: tp->t_no_move = movement(tp);
! 628: }
! 629: turn_on(*tp, ISGUARDIAN);
! 630:
! 631: }
! 632:
! 633: /* Treasures */
! 634: if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
! 635: (mvinch(rp->r_pos.y+j, rp->r_pos.x+i) == FLOOR)) {
! 636: item = new_thing(ALL, TRUE);
! 637: attach(lvl_obj, item);
! 638: cur = OBJPTR(item);
! 639:
! 640: mvaddch(trp.y, trp.x, cur->o_type);
! 641: cur->o_pos = trp;
! 642: }
! 643: }
! 644: }
! 645:
! 646: jmp_here: /* outside jumper for equippage */
! 647:
! 648: /*
! 649: * Do ITEMS attempts to put things in dungeon, maze, or outside
! 650: */
! 651:
! 652: if (ltype == OUTSIDE) ITEMS = rnd(15)+1;
! 653: else if (ltype == MAZELEV) ITEMS = rnd(20)+1;
! 654: else ITEMS = MAXOBJ + rnd(4);
! 655:
! 656: for (i = 0; i < ITEMS; i++)
! 657: if (rnd(100) < 65) {
! 658: /*
! 659: * Pick a new object and link it in the list
! 660: */
! 661: item = new_thing(ALL, TRUE);
! 662: attach(lvl_obj, item);
! 663: cur = OBJPTR(item);
! 664: /*
! 665: * Put it somewhere
! 666: */
! 667: cnt = 0;
! 668: do {
! 669: if (ltype == OUTSIDE) rm = 0;
! 670: else rm = rnd_room();
! 671: rnd_pos(&rooms[rm], &tp);
! 672: } until (winat(tp.y, tp.x) == FLOOR || cnt++ > 2500);
! 673: mvaddch(tp.y, tp.x, cur->o_type);
! 674: cur->o_pos = tp;
! 675: }
! 676: }
! 677:
CVSweb