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;