diff rogue5/new_level.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue5/new_level.c	Mon May 24 20:10:59 2010 +0000
@@ -0,0 +1,232 @@
+/*
+ * new_level:
+ *	Dig and draw a new level
+ *
+ * @(#)new_level.c	4.38 (Berkeley) 02/05/99
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980-1983, 1985, 1999 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 <string.h>
+#include "rogue.h"
+
+#define TREAS_ROOM 20	/* one chance in TREAS_ROOM for a treasure room */
+#define MAXTREAS 10	/* maximum number of treasures in a treasure room */
+#define MINTREAS 2	/* minimum number of treasures in a treasure room */
+
+void
+new_level(void)
+{
+    THING *tp;
+    PLACE *pp;
+    int *sp;
+    int i;
+
+    player.t_flags &= ~ISHELD;	/* unhold when you go down just in case */
+    if (level > max_level)
+	max_level = level;
+    /*
+     * Clean things off from last level
+     */
+    for (pp = places; pp < &places[MAXCOLS*MAXLINES]; pp++)
+    {
+	pp->p_ch = ' ';
+	pp->p_flags = F_REAL;
+	pp->p_monst = NULL;
+    }
+    clear();
+    /*
+     * Free up the monsters on the last level
+     */
+    for (tp = mlist; tp != NULL; tp = next(tp))
+	free_list(tp->t_pack);
+    free_list(mlist);
+    /*
+     * Throw away stuff left on the previous level (if anything)
+     */
+    free_list(lvl_obj);
+    do_rooms();				/* Draw rooms */
+    do_passages();			/* Draw passages */
+    no_food++;
+    put_things();			/* Place objects (if any) */
+    /*
+     * Place the traps
+     */
+    if (rnd(10) < level)
+    {
+	ntraps = rnd(level / 4) + 1;
+	if (ntraps > MAXTRAPS)
+	    ntraps = MAXTRAPS;
+	i = ntraps;
+	while (i--)
+	{
+	    /*
+	     * not only wouldn't it be NICE to have traps in mazes
+	     * (not that we care about being nice), since the trap
+	     * number is stored where the passage number is, we
+	     * can't actually do it.
+	     */
+	    do
+	    {
+		find_floor(NULL, &stairs, FALSE, FALSE);
+	    } while ( (chat(stairs.y, stairs.x) != FLOOR) &&
+	              (flat(stairs.y, stairs.x) & F_REAL) );
+	    sp = &flat(stairs.y, stairs.x);
+	    *sp &= ~(F_REAL | F_TMASK);
+	    *sp |= rnd(NTRAPS);
+	}
+    }
+    /*
+     * Place the staircase down.
+     */
+    find_floor(NULL, &stairs, FALSE, FALSE);
+    chat(stairs.y, stairs.x) = STAIRS;
+    seenstairs = FALSE;
+
+    for (tp = mlist; tp != NULL; tp = next(tp))
+	tp->t_room = roomin(&tp->t_pos);
+
+    find_floor(NULL, &hero, FALSE, TRUE);
+    enter_room(&hero);
+    mvaddch(hero.y, hero.x, PLAYER);
+    if (on(player, SEEMONST))
+	turn_see(FALSE);
+    if (on(player, ISHALU))
+	visuals();
+}
+
+/*
+ * rnd_room:
+ *	Pick a room that is really there
+ */
+int
+rnd_room(void)
+{
+    int rm;
+
+    do
+    {
+	rm = rnd(MAXROOMS);
+    } while (rooms[rm].r_flags & ISGONE);
+    return rm;
+}
+
+/*
+ * put_things:
+ *	Put potions and scrolls on this level
+ */
+
+void
+put_things(void)
+{
+    int i;
+    THING *obj;
+
+    /*
+     * Once you have found the amulet, the only way to get new stuff is
+     * go down into the dungeon.
+     */
+    if (amulet && level < max_level)
+	return;
+    /*
+     * check for treasure rooms, and if so, put it in.
+     */
+    if (rnd(TREAS_ROOM) == 0)
+	treas_room();
+    /*
+     * Do MAXOBJ attempts to put things on a level
+     */
+    for (i = 0; i < MAXOBJ; i++)
+	if (rnd(100) < 36)
+	{
+	    /*
+	     * Pick a new object and link it in the list
+	     */
+	    obj = new_thing();
+	    attach(lvl_obj, obj);
+	    /*
+	     * Put it somewhere
+	     */
+	    find_floor(NULL, &obj->o_pos, FALSE, FALSE);
+	    chat(obj->o_pos.y, obj->o_pos.x) = obj->o_type;
+	}
+    /*
+     * If he is really deep in the dungeon and he hasn't found the
+     * amulet yet, put it somewhere on the ground
+     */
+    if (level >= AMULETLEVEL && !amulet)
+    {
+	obj = new_item();
+	attach(lvl_obj, obj);
+	obj->o_hplus = 0;
+	obj->o_dplus = 0;
+	strncpy(obj->o_damage,"0x0",sizeof(obj->o_damage));
+        strncpy(obj->o_hurldmg,"0x0",sizeof(obj->o_hurldmg));
+	obj->o_arm = 11;
+	obj->o_type = AMULET;
+	/*
+	 * Put it somewhere
+	 */
+	find_floor(NULL, &obj->o_pos, FALSE, FALSE);
+	chat(obj->o_pos.y, obj->o_pos.x) = AMULET;
+    }
+}
+
+/*
+ * treas_room:
+ *	Add a treasure room
+ */
+#define MAXTRIES 10	/* max number of tries to put down a monster */
+
+
+void
+treas_room(void)
+{
+    int nm;
+    THING *tp;
+    struct room *rp;
+    int spots, num_monst;
+    coord mp;
+
+    rp = &rooms[rnd_room()];
+    spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS;
+    if (spots > (MAXTREAS - MINTREAS))
+	spots = (MAXTREAS - MINTREAS);
+    num_monst = nm = rnd(spots) + MINTREAS;
+    while (nm--)
+    {
+	find_floor(rp, &mp, 2 * MAXTRIES, FALSE);
+	tp = new_thing();
+	tp->o_pos = mp;
+	attach(lvl_obj, tp);
+	chat(mp.y, mp.x) = tp->o_type;
+    }
+
+    /*
+     * fill up room with monsters from the next level down
+     */
+
+    if ((nm = rnd(spots) + MINTREAS) < num_monst + 2)
+	nm = num_monst + 2;
+    spots = (rp->r_max.y - 2) * (rp->r_max.x - 2);
+    if (nm > spots)
+	nm = spots;
+    level++;
+    while (nm--)
+    {
+	spots = 0;
+	if (find_floor(rp, &mp, MAXTRIES, TRUE))
+	{
+	    tp = new_item();
+	    new_monster(tp, randmonster(FALSE), &mp);
+	    tp->t_flags |= ISMEAN;	/* no sloughers in THIS room */
+	    give_pack(tp);
+	}
+    }
+    level--;
+}