[BACK]Return to newlvl.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / urogue

Annotation of early-roguelike/urogue/newlvl.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:     newlvl.c - Dig and draw a new level
                      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:     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: /*
                     20:     Notes
                     21:
                     22:         Add treasure room code from Rogue 5.2,
                     23:         put in #ifdef 0/#endif bracket at end of code
                     24: */
                     25:
                     26: #include "rogue.h"
                     27:
                     28: /*
                     29:     new_level()
                     30:         Dig and draw a new level
                     31: */
                     32:
                     33: void
                     34: new_level(LEVTYPE ltype, int special)
                     35: {
                     36:     int rm, i, cnt;
                     37:     struct linked_list  *item, *nitem;
                     38:     struct thing    *tp;
                     39:     struct linked_list  *fpack = NULL;
                     40:     int     going_down = TRUE;
                     41:     coord   stairs;
                     42:
                     43:     /* Start player off right */
                     44:
                     45:     turn_off(player, ISHELD);
                     46:     turn_off(player, ISFLEE);
                     47:     extinguish_fuse(FUSE_SUFFOCATE);
                     48:     hold_count = 0;
                     49:     trap_tries = 0;
                     50:     no_food++;
                     51:
                     52:     if (level >= max_level)
                     53:         max_level = level;
                     54:     else
                     55:         going_down = FALSE;
                     56:
                     57:     /* Free up the monsters on the last level */
                     58:
                     59:     if (fam_ptr != NULL)    /* save what familiar is carrying */
                     60:     {
                     61:         fpack = (THINGPTR(fam_ptr))->t_pack;
                     62:         (THINGPTR(fam_ptr))->t_pack = NULL;
                     63:         fam_ptr = NULL; /* just in case */
                     64:     }
                     65:
                     66:     for (i = 1; i <= mons_summoned; i++)
                     67:         extinguish_fuse(FUSE_UNSUMMON);
                     68:
                     69:     mons_summoned = 0;
                     70:
                     71:     for (item = mlist; item != NULL; item = nitem)
                     72:     {
                     73:         tp = THINGPTR(item);
                     74:         nitem = next(item);
                     75:
                     76:         if (on(*tp, ISUNIQUE))  /* Put alive UNIQUE on next level */
                     77:             monsters[tp->t_index].m_normal = TRUE;
                     78:
                     79:         killed(NULL, item, NOMESSAGE, NOPOINTS);
                     80:     }
                     81:
                     82:     free_list(lvl_obj); /* Free up previous objects (if any) */
                     83:
                     84:     wclear(cw);
                     85:     wclear(mw);
                     86:     clear();
                     87:     refresh();
                     88:     levtype = ltype;
                     89:
                     90:     switch (ltype)
                     91:     {
                     92:         case THRONE:
                     93:             do_throne(special);    /* do monster throne stuff */
                     94:             break;
                     95:
                     96:         case MAZELEV:
                     97:             do_maze();
                     98:             break;
                     99:
                    100:         case POSTLEV:
                    101:                        do_post();
                    102:                        levtype = ltype = NORMLEV;
                    103:                        level++;
                    104:
                    105:         default:
                    106:             do_rooms(); /* Draw rooms */
                    107:             do_passages();  /* Draw passages */
                    108:                        break;
                    109:     }
                    110:
                    111:     /* Place the staircase down. */
                    112:
                    113:     cnt = 0;
                    114:
                    115:     do
                    116:     {
                    117:         rm = rnd_room();
                    118:         rnd_pos(&rooms[rm], &stairs);
                    119:     }
                    120:     while (!(mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000));
                    121:
                    122:     addch(STAIRS);
                    123:
                    124:     put_things(ltype);  /* Place objects (if any) */
                    125:
                    126:     if (has_artifact && level == 1)
                    127:         create_lucifer(&stairs);
                    128:
                    129:     /* Place the traps */
                    130:
                    131:     ntraps = 0;     /* No traps yet */
                    132:
                    133:     if (levtype == NORMLEV)
                    134:     {
                    135:         if (rnd(10) < level)
                    136:         {
                    137:             char    ch = 0;
                    138:
                    139:             i = ntraps = min(MAXTRAPS, rnd(level / 2) + 1);
                    140:
                    141:             /* maybe a lair */
                    142:
                    143:             if (level > 35 && ltype == NORMLEV && rnd(wizard ? 3 : 10) == 0)
                    144:             {
                    145:                 cnt = 0;
                    146:
                    147:                 do
                    148:                 {
                    149:                     rm = rnd_room();
                    150:
                    151:                     if (rooms[rm].r_flags & ISTREAS)
                    152:                         continue;
                    153:
                    154:                     rnd_pos(&rooms[rm], &stairs);
                    155:                 }
                    156:                 while (!(mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000));
                    157:
                    158:                 addch(LAIR);
                    159:                 i--;
                    160:                 traps[i].tr_flags = 0;
                    161:                 traps[i].tr_type = LAIR;
                    162:                 traps[i].tr_show = FLOOR;
                    163:                 traps[i].tr_pos = stairs;
                    164:             }
                    165:
                    166:             while (i--)
                    167:             {
                    168:                 cnt = 0;
                    169:
                    170:                 do
                    171:                 {
                    172:                     rm = rnd_room();
                    173:
                    174:                     if (rooms[rm].r_flags & ISTREAS)
                    175:                         continue;
                    176:
                    177:                     rnd_pos(&rooms[rm], &stairs);
                    178:                 }
                    179:                 while (!(mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000));
                    180:
                    181:                 traps[i].tr_flags = 0;
                    182:
                    183:                 switch (rnd(11))
                    184:                 {
                    185:                     case 0:
                    186:                         ch = TRAPDOOR;
                    187:                         break;
                    188:
                    189:                     case 1:
                    190:                         ch = BEARTRAP;
                    191:                         break;
                    192:
                    193:                     case 2:
                    194:                         ch = SLEEPTRAP;
                    195:                         break;
                    196:
                    197:                     case 3:
                    198:                         ch = ARROWTRAP;
                    199:                         break;
                    200:
                    201:                     case 4:
                    202:                         ch = TELTRAP;
                    203:                         break;
                    204:
                    205:                     case 5:
                    206:                         ch = DARTTRAP;
                    207:                         break;
                    208:
                    209:                     case 6:
                    210:                         ch = POOL;
                    211:
                    212:                         if (rnd(10))
                    213:                             traps[i].tr_flags = ISFOUND;
                    214:
                    215:                         break;
                    216:
                    217:                     case 7:
                    218:                         ch = MAZETRAP;
                    219:                         break;
                    220:
                    221:                     case 8:
                    222:                         ch = FIRETRAP;
                    223:                         break;
                    224:
                    225:                     case 9:
                    226:                         ch = POISONTRAP;
                    227:                         break;
                    228:
                    229:                     case 10:
                    230:                         ch = RUSTTRAP;
                    231:                         break;
                    232:                 }
                    233:
                    234:                 addch(ch);
                    235:                 traps[i].tr_type = ch;
                    236:                 traps[i].tr_show = FLOOR;
                    237:                 traps[i].tr_pos = stairs;
                    238:             }
                    239:         }
                    240:     }
                    241:
                    242:     do              /* Position hero */
                    243:     {
                    244:         rm = rnd_room();
                    245:
                    246:         if (levtype != THRONE && (rooms[rm].r_flags & ISTREAS))
                    247:             continue;
                    248:
                    249:         rnd_pos(&rooms[rm], &hero);
                    250:     }
                    251:     while(!(winat(hero.y, hero.x) == FLOOR &&
                    252:            DISTANCE(hero, stairs) > 16));
                    253:
                    254:     oldrp = &rooms[rm]; /* Set the current room */
                    255:     player.t_oldpos = player.t_pos; /* Set the current position */
                    256:
                    257:     if (levtype != POSTLEV && levtype != THRONE)
                    258:     {
                    259:         if (on(player, BLESSMAP) && rnd(5) == 0)
                    260:         {
                    261:             read_scroll(&player, S_MAP, ISNORMAL);
                    262:
                    263:             if (rnd(3) == 0)
                    264:                 turn_off(player, BLESSMAP);
                    265:         }
                    266:
                    267:         if (player.t_ctype == C_THIEF || on(player, BLESSGOLD) && rnd(5) == 0)
                    268:         {
                    269:             read_scroll(&player, S_GFIND, ISNORMAL);
                    270:
                    271:             if (rnd(3) == 0)
                    272:                 turn_off(player, BLESSGOLD);
                    273:         }
                    274:
                    275:         if (player.t_ctype == C_RANGER || on(player, BLESSFOOD) && rnd(5) == 0)
                    276:         {
                    277:             read_scroll(&player, S_FOODDET, ISNORMAL);
                    278:
                    279:             if (rnd(3) == 0)
                    280:                 turn_off(player, BLESSFOOD);
                    281:         }
                    282:
                    283:         if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_ILLUSION ||
                    284:             on(player, BLESSMAGIC) && rnd(5) == 0)
                    285:         {
                    286:             quaff(&player, P_TREASDET, ISNORMAL);
                    287:
                    288:             if (rnd(3) == 0)
                    289:                 turn_off(player, BLESSMAGIC);
                    290:         }
                    291:
                    292:         if (player.t_ctype == C_DRUID || on(player, BLESSMONS) && rnd(5) == 0)
                    293:         {
                    294:             quaff(&player, P_MONSTDET, ISNORMAL);
                    295:
                    296:             if (rnd(3) == 0)
                    297:                 turn_off(player, BLESSMONS);
                    298:         }
                    299:         else if (player.t_ctype == C_CLERIC ||
                    300:             player.t_ctype == C_PALADIN || is_wearing(R_PIETY))
                    301:             undead_sense();
                    302:     }
                    303:
                    304:     if (is_wearing(R_AGGR))
                    305:         aggravate();
                    306:
                    307:     if (is_wearing(R_ADORNMENT) ||
                    308:         cur_armor != NULL && cur_armor->o_which == MITHRIL)
                    309:     {
                    310:         int greed = FALSE;
                    311:
                    312:         for (item = mlist; item != NULL; item = next(item))
                    313:         {
                    314:             tp = THINGPTR(item);
                    315:
                    316:             if (on(*tp, ISGREED))
                    317:             {
                    318:                 turn_on(*tp, ISRUN);
                    319:                 turn_on(*tp, ISMEAN);
                    320:                 tp->t_ischasing = TRUE;
                    321:                 tp->t_chasee = &player;
                    322:                 greed = TRUE;
                    323:             }
                    324:         }
                    325:
                    326:         if (greed)
                    327:             msg("An uneasy feeling comes over you.");
                    328:     }
                    329:
                    330:     if (is_carrying(TR_PALANTIR))   /* Palantir shows all */
                    331:     {
                    332:         msg("The Palantir reveals all!");
                    333:
                    334:         overlay(stdscr, cw);    /* Wizard mode 'f' command */
                    335:         overlay(mw, cw);        /* followed by 'm' command */
                    336:     }
                    337:
                    338:     if (is_carrying(TR_PHIAL))  /* Phial lights your way */
                    339:     {
                    340:         if (!is_carrying(TR_PALANTIR))
                    341:             msg("The Phial banishes the darkness!");
                    342:
                    343:         for (i = 0; i < MAXROOMS; i++)
                    344:             rooms[i].r_flags &= ~ISDARK;
                    345:     }
                    346:
                    347:     if (is_carrying(TR_AMULET)) /* Amulet describes the level */
                    348:     {
                    349:         level_eval();
                    350:     }
                    351:
                    352:
                    353:     wmove(cw, hero.y, hero.x);
                    354:     waddch(cw, PLAYER);
                    355:     light(&hero);
                    356:
                    357:     /* Summon familiar if player has one */
                    358:
                    359:     if (on(player, HASFAMILIAR))
                    360:     {
                    361:         summon_monster((short) fam_type, FAMILIAR, MESSAGE);
                    362:
                    363:         if (fam_ptr != NULL)    /* add old pack to new */
                    364:         {
                    365:             tp = THINGPTR(fam_ptr);
                    366:
                    367:             if (tp->t_pack == NULL)
                    368:                 tp->t_pack = fpack;
                    369:             else if (fpack != NULL)
                    370:             {
                    371:                 for (item = tp->t_pack; item->l_next != NULL;item = next(item))
                    372:                     ;
                    373:
                    374:                 item->l_next = fpack;
                    375:                 debug("new_level: l_prev = %p",item);
                    376:                 fpack->l_prev = item;
                    377:             }
                    378:         }
                    379:         else
                    380:             free_list(fpack);
                    381:     }
                    382:
                    383:     mem_check(__FILE__,__LINE__);
                    384:     status(TRUE);
                    385: }
                    386:
                    387: /*
                    388:     put_things()
                    389:         put potions and scrolls on this level
                    390: */
                    391:
                    392: void
                    393: put_things(LEVTYPE ltype)
                    394: {
                    395:     int i, rm, cnt;
                    396:     struct linked_list  *item;
                    397:     struct object   *cur;
                    398:     int    got_unique = FALSE;
                    399:     int length, width, maxobjects;
                    400:     coord   tp;
                    401:
                    402:     /*
                    403:      * Once you have found an artifact, the only way to get new stuff is
                    404:      * go down into the dungeon.
                    405:      */
                    406:
                    407:     if (has_artifact && level < max_level && ltype != THRONE)
                    408:         return;
                    409:
                    410:     /*
                    411:      * There is a chance that there is a treasure room on this level
                    412:      * Increasing chance after level 10
                    413:      */
                    414:
                    415:     if (ltype != MAZELEV && rnd(50) < level - 10)
                    416:     {
                    417:         int n, j;
                    418:         struct room *rp;
                    419:
                    420:         /* Count the number of free spaces */
                    421:         n = 0;      /* 0 tries */
                    422:
                    423:         do
                    424:         {
                    425:             rp = &rooms[rnd_room()];
                    426:             width = rp->r_max.y - 2;
                    427:             length = rp->r_max.x - 2;
                    428:         }
                    429:         while(!((width * length <= MAXTREAS) || (n++ > MAXROOMS * 4)));
                    430:
                    431:         /* Mark the room as a treasure room */
                    432:
                    433:         rp->r_flags |= ISTREAS;
                    434:
                    435:         /* Make all the doors secret doors */
                    436:
                    437:         for (n = 0; n < rp->r_nexits; n++)
                    438:         {
                    439:             move(rp->r_exit[n].y, rp->r_exit[n].x);
                    440:             addch(SECRETDOOR);
                    441:         }
                    442:
                    443:         /* Put in the monsters and treasures */
                    444:
                    445:         for (j = 1; j < rp->r_max.y - 1; j++)
                    446:             for (n = 1; n < rp->r_max.x - 1; n++)
                    447:             {
                    448:                 coord   trp;
                    449:
                    450:                 trp.y = rp->r_pos.y + j;
                    451:                 trp.x = rp->r_pos.x + n;
                    452:
                    453:                 /* Monsters */
                    454:
                    455:                 if ((rnd(100) < (MAXTREAS * 100) /
                    456:                     (width * length)) &&
                    457:                     (mvwinch(mw, rp->r_pos.y + j,
                    458:                     rp->r_pos.x + n) == ' '))
                    459:                 {
                    460:                     struct thing    *th;
                    461:
                    462:                     /* Make a monster */
                    463:
                    464:                     item = new_item(sizeof *th);
                    465:                     th = THINGPTR(item);
                    466:
                    467:                     /*
                    468:                      * Put it there and aggravate it
                    469:                      * (unless it can escape) only put
                    470:                      * one UNIQUE per treasure room at
                    471:                      * most
                    472:                      */
                    473:
                    474:                     if (got_unique)
                    475:                         new_monster(item, randmonster(NOWANDER, GRAB), &trp,
                    476:                             NOMAXSTATS);
                    477:                     else
                    478:                     {
                    479:                         new_monster(item, randmonster(NOWANDER, NOGRAB), &trp,
                    480:                             NOMAXSTATS);
                    481:
                    482:                         if (on(*th, ISUNIQUE))
                    483:                             got_unique = TRUE;
                    484:                     }
                    485:
                    486:                     turn_off(*th, ISFRIENDLY);
                    487:                     turn_on(*th, ISMEAN);
                    488:
                    489:                     if (off(*th, CANINWALL))
                    490:                     {
                    491:                         th->t_ischasing = TRUE;
                    492:                         th->t_chasee = &player;
                    493:                         turn_on(*th, ISRUN);
                    494:                     }
                    495:                 }
                    496:
                    497:                 /* Treasures */
                    498:
                    499:                 if ((rnd(100) < (MAXTREAS * 100) /
                    500:                     (width * length)) &&
                    501:                     (mvinch(rp->r_pos.y + j,
                    502:                     rp->r_pos.x + n) == FLOOR))
                    503:                 {
                    504:                     item = new_thing();
                    505:                     cur = OBJPTR(item);
                    506:                     cur->o_pos = trp;
                    507:                     add_obj(item, trp.y, trp.x);
                    508:                 }
                    509:             }
                    510:     }
                    511:
                    512:     /* Do MAXOBJ attempts to put things on a level, maybe  */
                    513:
                    514:     maxobjects = (ltype == THRONE) ? rnd(3 * MAXOBJ) + 35 : MAXOBJ;
                    515:
                    516:     for (i = 0; i < maxobjects; i++)
                    517:         if (rnd(100) < 40 || ltype == THRONE)
                    518:         {
                    519:             /* Pick a new object and link it in the list */
                    520:
                    521:             item = new_thing();
                    522:             cur = OBJPTR(item);
                    523:
                    524:             /* Put it somewhere */
                    525:
                    526:             cnt = 0;
                    527:
                    528:             do
                    529:             {
                    530:                 rm = rnd_room();
                    531:                 rnd_pos(&rooms[rm], &tp);
                    532:             }
                    533:             while(!(winat(tp.y, tp.x) == FLOOR || cnt++ > 500));
                    534:
                    535:             cur->o_pos = tp;
                    536:             add_obj(item, tp.y, tp.x);
                    537:         }
                    538:
                    539:     /*
                    540:      * If he is really deep in the dungeon and he hasn't found an
                    541:      * artifact yet, put it somewhere on the ground
                    542:      */
                    543:
                    544:     if (make_artifact())
                    545:     {
                    546:         item = new_item(sizeof *cur);
                    547:         cur = OBJPTR(item);
                    548:         new_artifact(-1, cur);
                    549:         cnt = 0;
                    550:
                    551:         do
                    552:         {
                    553:             rm = rnd_room();
                    554:             rnd_pos(&rooms[rm], &tp);
                    555:         }
                    556:         while(!(winat(tp.y, tp.x) == FLOOR || cnt++ > 500));
                    557:
                    558:         cur->o_pos = tp;
                    559:         add_obj(item, tp.y, tp.x);
                    560:     }
                    561: }
                    562:
                    563: /*
                    564:     do_throne()
                    565:         Put a monster's throne room and monsters on the screen
                    566: */
                    567:
                    568: void
                    569: do_throne(int special)
                    570: {
                    571:     coord   mp;
                    572:     int save_level;
                    573:     int i;
                    574:     struct room *rp;
                    575:     struct thing    *tp;
                    576:     struct linked_list  *item;
                    577:     int throne_monster;
                    578:
                    579:     for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
                    580:     {
                    581:         rp->r_nexits = 0;   /* no exits */
                    582:         rp->r_flags = ISGONE;   /* kill all rooms */
                    583:     }
                    584:
                    585:     rp = &rooms[0];     /* point to only room */
                    586:     rp->r_flags = 0;    /* this room NOT gone */
                    587:     rp->r_max.x = 40;
                    588:     rp->r_max.y = 10;   /* 10 * 40 room */
                    589:     rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */
                    590:     rp->r_pos.y = 3;    /* 2nd line */
                    591:     draw_room(rp);      /* draw the only room */
                    592:
                    593:     save_level = level;
                    594:     level = max(2 * level, level + roll(4, 6));
                    595:
                    596:     if (special == 0)    /* Who has he offended? */
                    597:         do
                    598:             throne_monster = nummonst - roll(1, NUMSUMMON);
                    599:         while(!monsters[throne_monster].m_normal);
                    600:     else
                    601:         throne_monster = special;
                    602:
                    603:     /* Create summoning monster */
                    604:
                    605:     item = new_item(sizeof *tp);
                    606:
                    607:     tp = THINGPTR(item);
                    608:
                    609:     do
                    610:     {
                    611:         rnd_pos(rp, &mp);
                    612:     }
                    613:     while(mvwinch(stdscr, mp.y, mp.x) != FLOOR);
                    614:
                    615:     new_monster(item, throne_monster, &mp, MAXSTATS);
                    616:     turn_on(*tp, CANSEE);
                    617:     turn_off(*tp, ISFRIENDLY);
                    618:
                    619:     if (on(*tp, CANSUMMON)) /* summon his helpers */
                    620:         summon_help(tp, FORCE);
                    621:     else
                    622:     {
                    623:         for (i = roll(4, 10); i >= 0; i--)
                    624:         {
                    625:             item = new_item(sizeof *tp);
                    626:             tp = THINGPTR(item);
                    627:
                    628:             do
                    629:             {
                    630:                 rnd_pos(rp, &mp);
                    631:             }
                    632:             while(mvwinch(stdscr, mp.y, mp.x) != FLOOR);
                    633:
                    634:             new_monster(item, randmonster(NOWANDER, NOGRAB), &mp, MAXSTATS);
                    635:             turn_on(*tp, CANSEE);
                    636:             turn_off(*tp, ISFRIENDLY);
                    637:         }
                    638:     }
                    639:
                    640:     level = save_level + roll(2, 3);    /* send the hero down */
                    641:     aggravate();
                    642: }
                    643:
                    644: /*
                    645:     create_lucifer()
                    646:         special surprise on the way back up create Lucifer
                    647:         with more than the usual god abilities
                    648: */
                    649:
                    650: void
                    651: create_lucifer(coord *stairs)
                    652: {
                    653:     struct linked_list  *item = new_item(sizeof(struct thing));
                    654:     struct thing    *tp = THINGPTR(item);
                    655:
                    656:     new_monster(item, nummonst + 1, stairs, MAXSTATS);
                    657:     turn_on(*tp, CANINWALL);
                    658:     turn_on(*tp, CANHUH);
                    659:     turn_on(*tp, CANBLINK);
                    660:     turn_on(*tp, CANSNORE);
                    661:     turn_on(*tp, CANDISEASE);
                    662:     turn_on(*tp, NOCOLD);
                    663:     turn_on(*tp, TOUCHFEAR);
                    664:     turn_on(*tp, BMAGICHIT);
                    665:     turn_on(*tp, NOFIRE);
                    666:     turn_on(*tp, NOBOLT);
                    667:     turn_on(*tp, CANBLIND);
                    668:     turn_on(*tp, CANINFEST);
                    669:     turn_on(*tp, CANSMELL);
                    670:     turn_on(*tp, CANPARALYZE);
                    671:     turn_on(*tp, CANSTINK);
                    672:     turn_on(*tp, CANCHILL);
                    673:     turn_on(*tp, CANFRIGHTEN);
                    674:     turn_on(*tp, CANHOLD);
                    675:     turn_on(*tp, CANBRANDOM);
                    676: }

CVSweb