Mercurial > hg > early-roguelike
diff xrogue/n_level.c @ 142:6b5fbd7c3ece
Merge arogue7 and xrogue trees.
| author | John "Elwin" Edwards |
|---|---|
| date | Tue, 12 May 2015 21:39:39 -0400 |
| parents | e6179860cb76 |
| children | f54901b9c39b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xrogue/n_level.c Tue May 12 21:39:39 2015 -0400 @@ -0,0 +1,672 @@ +/* + n_level.c - Dig and draw a new level + + XRogue: Expeditions into the Dungeons of Doom + Copyright (C) 1991 Robert Pietkivitch + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T + All rights reserved. + + Based on "Rogue: Exploring the Dungeons of Doom" + Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + All rights reserved. + + See the file LICENSE.TXT for full copyright and licensing information. +*/ + +#include <curses.h> +#include "rogue.h" +#define TERRASAVE 3 + +/* + * new_level: + * Dig and draw a new level + */ + +new_level(ltype) +LEVTYPE ltype; /* designates type of level to create */ +{ + register int rm = 0, i, cnt; + register unsigned char ch; + register struct linked_list *item; + register struct thing *tp; + register struct object *obj; + int waslit = 0; /* Was the previous outside level lit? */ + int starty = 0, startx = 0, deltay = 0, deltax = 0; + bool fresh=TRUE, vert = 0, top; + struct room *rp; + struct linked_list *nitem, *savmonst=NULL, *savitems=NULL; + coord stairs = {0,0}; + + if (wizard) { + msg("Turns: %ld", turns); /* Number of turns for last level */ + mpos = 0; + } + + /* Start player off right */ + turn_off(player, ISHELD); + turn_off(player, ISFLEE); + extinguish(suffocate); + hold_count = 0; + trap_tries = 0; + + /* Are we just entering a dungeon? If so, how big is it? */ + if (ltype != OUTSIDE && nfloors < 0) nfloors = HARDER+20 + rnd(51); + + if (level > max_level) + max_level = level; + + /* Are we starting a new outside level? */ + if (ltype == OUTSIDE) { + register int i, j; + + /* Save some information prior to clearing the screen */ + if (level == -1 || mvinch(hero.y, hero.x) == HORZWALL) vert = TRUE; + else vert = FALSE; + + if (level < 1) { + fresh = TRUE; + starty = 2; + startx = 1; + deltay = deltax = 1; + level = max_level; /* Restore level to deepest attempt */ + prev_max = level; /* reset for boundary crossings below */ + } + else if (level >= 1 && prev_max == 1000) { + fresh = TRUE; + starty = 2; + startx = 1; + deltay = deltax = 1; + prev_max = level; /* reset for boundary crossings below */ + } + else { /* Copy several lines of the terrain to the other end */ + + unsigned char cch; /* Copy character */ + + if (wizard) msg("Crossing sector boundary "); + + /* Was the area dark (not magically lit)? */ + if (!(rooms[0].r_flags & ISDARK)) waslit = 1; + + fresh = FALSE; + if ((vert && hero.y == 1) || (!vert && hero.x == 0)) top = TRUE; + else top = FALSE; + for (i=0; i<TERRASAVE; i++) { + if (vert) + for (j=1; j<cols-1; j++) { + if (top) { + cch = mvinch(i+2, j); + mvaddch(lines-6+i, j, cch); + } + else { + cch = mvinch(lines-4-i, j); + mvaddch(4-i, j, cch); + } + } + else + for (j=2; j<lines-3; j++) { + if (top) { + cch = mvinch(j, i+1); + mvaddch(j, cols-4+i, cch); + } + else { + cch = mvinch(j, cols-2-i); + mvaddch(j, 3-i, cch); + } + } + } + + if (vert) { + startx = deltax = 1; + if (top) { + starty = lines-4-TERRASAVE; + deltay = -1; + } + else { + starty = TERRASAVE + 2; + deltay = 1; + } + } + else { + starty = 2; + deltay = 1; + if (top) { + startx = cols-2-TERRASAVE; + deltax = -1; + } + else { + deltax = 1; + startx = TERRASAVE + 1; + } + } + + /* Check if any monsters should be saved */ + for (item = mlist; item != NULL; item = nitem) { + nitem = next(item); + tp = THINGPTR(item); + if (vert) { + if (top) { + if (tp->t_pos.y < TERRASAVE + 2) + tp->t_pos.y += lines - 5 - TERRASAVE; + else continue; + } + else { + if (tp->t_pos.y > lines - 4 - TERRASAVE) + tp->t_pos.y += 5 + TERRASAVE - lines; + else continue; + } + } + else { + if (top) { + if (tp->t_pos.x < TERRASAVE + 1) + tp->t_pos.x += cols - 2 - TERRASAVE; + else continue; + } + else { + if (tp->t_pos.x > cols - 2 - TERRASAVE) + tp->t_pos.x += 2 + TERRASAVE - cols; + else continue; + } + } + + /* + * If the monster is busy chasing another monster, don't save + * it + */ + if (tp->t_dest && tp->t_dest != &hero) continue; + + /* Outside has plenty of monsters, don't need these. + * detach(mlist, item); + * attach(savmonst, item); + */ + } + + /* Check if any treasure should be saved */ + for (item = lvl_obj; item != NULL; item = nitem) { + nitem = next(item); + obj = OBJPTR(item); + if (vert) { + if (top) { + if (obj->o_pos.y < TERRASAVE + 2) + obj->o_pos.y += lines - 5 - TERRASAVE; + else continue; + } + else { + if (obj->o_pos.y > lines - 4 - TERRASAVE) + obj->o_pos.y += 5 + TERRASAVE - lines; + else continue; + } + } + else { + if (top) { + if (obj->o_pos.x < TERRASAVE + 1) + obj->o_pos.x += cols - 2 - TERRASAVE; + else continue; + } + else { + if (obj->o_pos.x > cols - 2 - TERRASAVE) + obj->o_pos.x += 2 + TERRASAVE - cols; + else continue; + } + } + detach(lvl_obj, item); + attach(savitems, item); + } + } + } + + wclear(cw); + wclear(mw); + if (fresh || levtype != OUTSIDE) clear(); + /* + * check to see if he missed a UNIQUE, If he did then put it back + * in the monster table for next time + */ + for (item = mlist; item != NULL; item = next(item)) { + tp = THINGPTR(item); + if (on(*tp, ISUNIQUE)) + monsters[tp->t_index].m_normal = TRUE; + } + /* + * Free up the monsters on the last level + */ + t_free_list(mlist); + o_free_list(lvl_obj); /* Free up previous objects (if any) */ + for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) + r_free_list(rp->r_exit); /* Free up the exit lists */ + + levtype = ltype; + foods_this_level = 0; /* food for hero this level */ + + /* What kind of level are we on? */ + if (ltype == POSTLEV || ltype == STARTLEV) { + if (ltype == POSTLEV) + do_post(FALSE); /* Trading post */ + else + do_post(TRUE); /* Equipage */ + + levtype = ltype = POSTLEV; + } + else if (ltype == MAZELEV) { + do_maze(); + no_food++; + put_things(ltype); /* Place objects (if any) */ + } + else if (ltype == OUTSIDE) { + /* Move the cursor back onto the hero */ + wmove(cw, hero.y, hero.x); + init_terrain(); + do_terrain(starty, startx, deltay, deltax, (bool) (fresh || !vert)); + no_food++; + put_things(ltype); + + /* Should we magically light this area? */ + if (waslit) rooms[0].r_flags &= ~ISDARK; + } + else { + do_rooms(); /* Draw rooms */ + do_passages(); /* Draw passages */ + no_food++; + put_things(ltype); /* Place objects (if any) */ + } + /* + * Place the staircase down. Only a small chance for an outside stairway. + */ + if (ltype != OUTSIDE || roll(1, 5) == 5) { + cnt = 0; + do { + rm = rnd_room(); + rnd_pos(&rooms[rm], &stairs); + } until (mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 2500); + addch(STAIRS); + } + /* + * maybe add a trading post + */ + if (level > 5 && rnd(10) == 7 && ltype == NORMLEV) { + cnt = 0;
