diff rogue4/new_level.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 1b73a8641b37
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue4/new_level.c	Sat Oct 24 16:52:52 2009 +0000
@@ -0,0 +1,254 @@
+/*
+ * new_level:
+ *	Dig and draw a new level
+ *
+ * @(#)new_level.c	4.19 (Berkeley) 1/12/82
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <time.h>
+#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 */
+
+new_level()
+{
+    register int rm, i;
+    register THING *tp;
+    register char *sp;
+    register THING **mp;
+    register int index;
+    coord stairs;
+
+    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
+     */
+    clear();
+    for (sp = _level; sp < &_level[MAXCOLS*MAXLINES]; )
+	*sp++ = ' ';
+    for (sp = _flags; sp < &_flags[MAXCOLS*MAXLINES]; )
+	*sp++ = F_REAL;
+    for (mp = _monst; mp < &_monst[MAXCOLS*MAXLINES]; )
+	*mp++ = 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 staircase down.
+     */
+    i = 0;
+    do {
+        rm = rnd_room();
+	rnd_pos(&rooms[rm], &stairs);
+	index = INDEX(stairs.y, stairs.x);
+	if (i++ > 100)
+	{
+	    i = 0;
+	    srand(getpid() + (int) time((time_t *) NULL));
+	}
+    } until (_level[index] == FLOOR);
+    _level[index] = STAIRS;
+    /*
+     * Place the traps
+     */
+    if (rnd(10) < level)
+    {
+	ntraps = rnd(level / 4) + 1;
+	if (ntraps > MAXTRAPS)
+	    ntraps = MAXTRAPS;
+	i = ntraps;
+	while (i--)
+	{
+	    do
+	    {
+		rm = rnd_room();
+		rnd_pos(&rooms[rm], &stairs);
+		index = INDEX(stairs.y, stairs.x);
+	    } until (_level[index] == FLOOR && (_flags[index] & F_REAL));
+	    sp = &_flags[index];
+	    *sp &= ~(F_REAL | F_TMASK);
+	    *sp |= rnd(NTRAPS);
+	}
+    }
+    do
+    {
+	rm = rnd_room();
+	rnd_pos(&rooms[rm], &hero);
+	index = INDEX(hero.y, hero.x);
+    } until (_level[index] == FLOOR && (_flags[index] & F_REAL)
+	&& _monst[index] == NULL);
+    enter_room(&hero);
+    move(hero.y, hero.x);
+    addch(PLAYER);
+    if (on(player, SEEMONST))
+	turn_see(FALSE);
+}
+
+/*
+ * rnd_room:
+ *	Pick a room that is really there
+ */
+rnd_room()
+{
+    register int rm;
+
+    do
+    {
+	rm = rnd(MAXROOMS);
+    } while (rooms[rm].r_flags & ISGONE);
+    return rm;
+}
+
+/*
+ * put_things:
+ *	Put potions and scrolls on this level
+ */
+put_things()
+{
+    register int i;
+    register THING *cur;
+    register int rm;
+    coord tp;
+
+    /*
+     * 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) < 35)
+	{
+	    /*
+	     * Pick a new object and link it in the list
+	     */
+	    cur = new_thing();
+	    attach(lvl_obj, cur);
+	    /*
+	     * Put it somewhere
+	     */
+	    do {
+	        rm = rnd_room();
+		rnd_pos(&rooms[rm], &tp);
+	    } until (chat(tp.y, tp.x) == FLOOR);
+	    chat(tp.y, tp.x) = cur->o_type;
+	    cur->o_pos = tp;
+	}
+    /*
+     * 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)
+    {
+	cur = new_item();
+	attach(lvl_obj, cur);
+	cur->o_hplus = cur->o_dplus = 0;
+	strcpy(cur->o_damage,"0d0");
+	strcpy(cur->o_hurldmg,"0d0");
+	cur->o_ac = 11;
+	cur->o_type = AMULET;
+	/*
+	 * Put it somewhere
+	 */
+	do {
+	    rm = rnd_room();
+	    rnd_pos(&rooms[rm], &tp);
+	} until (winat(tp.y, tp.x) == FLOOR);
+	chat(tp.y, tp.x) = AMULET;
+	cur->o_pos = tp;
+    }
+}
+
+/*
+ * treas_room:
+ *	Add a treasure room
+ */
+#define MAXTRIES 10	/* max number of tries to put down a monster */
+
+treas_room()
+{
+    register int nm, index;
+    register THING *tp;
+    register struct room *rp;
+    register 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--)
+    {
+	do
+	{
+	    rnd_pos(rp, &mp);
+	    index = INDEX(mp.y, mp.x);
+	} until (_level[index] == FLOOR);
+	tp = new_thing();
+	tp->o_pos = mp;
+	attach(lvl_obj, tp);
+	_level[index] = 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;
+	do
+	{
+	    rnd_pos(rp, &mp);
+	    index = INDEX(mp.y, mp.x);
+	    spots++;
+	} until (_monst[index] == NULL || spots > MAXTRIES);
+	if (_monst[index] == NULL)
+	{
+	    tp = new_item();
+	    new_monster(tp, randmonster(FALSE), &mp);
+	    tp->t_flags |= ISMEAN;	/* no sloughers in THIS room */
+	    give_pack(tp);
+	}
+    }
+    level--;
+}