rogue

Ken Arnold's Rogue
git clone https://git.woozle.org/neale/rogue.git

Neale Pickett  ·  2011-10-13

handle.c

  1#include <curses.h>
  2#include "netprot.h"
  3
  4#define TREAS_ROOM 20	/* one chance in TREAS_ROOM for a treasure room */
  5#define MAXTREAS 10	/* maximum number of treasures in a treasure room */
  6#define MINTREAS 2	/* minimum number of treasures in a treasure room */
  7
  8/*
  9 * new_level:
 10 *	Dig and draw a new level
 11 *
 12 * @(#)handle.c	4.38 (Berkeley) 02/05/99
 13 */
 14void
 15new_level(void)
 16{
 17    THING *tp;
 18    PLACE *pp;
 19    char *sp;
 20    int i;
 21
 22    Player.t_flags &= ~ISHELD;	/* unhold when you go down just in case */
 23    if (Level > Max_level)
 24	Max_level = Level;
 25    /*
 26     * Clean things off from last level
 27     */
 28    for (pp = Places; pp < &Places[MAXCOLS*MAXLINES]; pp++)
 29    {
 30	pp->p_ch = ' ';
 31	pp->p_flags = F_REAL;
 32	pp->p_monst = NULL;
 33    }
 34    clear();
 35    /*
 36     * Free up the monsters on the last level
 37     */
 38    for (tp = Mlist; tp != NULL; tp = next(tp))
 39	free_list(tp->t_pack);
 40    free_list(Mlist);
 41    /*
 42     * Throw away stuff left on the previous level (if anything)
 43     */
 44    free_list(Lvl_obj);
 45    do_rooms();				/* Draw rooms */
 46    do_passages();			/* Draw passages */
 47    No_food++;
 48    put_things();			/* Place objects (if any) */
 49    /*
 50     * Place the traps
 51     */
 52    if (rnd(10) < Level)
 53    {
 54	Ntraps = rnd(Level / 4) + 1;
 55	if (Ntraps > MAXTRAPS)
 56	    Ntraps = MAXTRAPS;
 57	i = Ntraps;
 58	while (i--)
 59	{
 60	    /*
 61	     * not only wouldn't it be NICE to have traps in mazes
 62	     * (not that we care about being nice), since the trap
 63	     * number is stored where the passage number is, we
 64	     * can't actually do it.
 65	     */
 66	    do
 67	    {
 68		find_floor((struct room *) NULL, &Stairs, FALSE, FALSE);
 69	    } while (chat(Stairs.y, Stairs.x) != FLOOR);
 70	    sp = &flat(Stairs.y, Stairs.x);
 71	    *sp &= ~F_REAL;
 72	    *sp |= rnd(NTRAPS);
 73	}
 74    }
 75    /*
 76     * Place the staircase down.
 77     */
 78    find_floor((struct room *) NULL, &Stairs, FALSE, FALSE);
 79    chat(Stairs.y, Stairs.x) = STAIRS;
 80    Seenstairs = FALSE;
 81
 82    for (tp = Mlist; tp != NULL; tp = next(tp))
 83	tp->t_room = roomin(&tp->t_pos);
 84
 85    find_floor((struct room *) NULL, &Hero, FALSE, TRUE);
 86    enter_room(&Hero);
 87    mvaddch(Hero.y, Hero.x, PLAYER);
 88    if (on(Player, SEEMONST))
 89	turn_see(FALSE);
 90    if (on(Player, ISHALU))
 91	visuals();
 92}
 93
 94/*
 95 * rnd_room:
 96 *	Pick a room that is really there
 97 */
 98int
 99rnd_room(void)
100{
101    int rm;
102
103    do
104    {
105	rm = rnd(MAXROOMS);
106    } while (Rooms[rm].r_flags & ISGONE);
107    return rm;
108}
109
110/*
111 * put_things:
112 *	Put potions and scrolls on this level
113 */
114void
115put_things(void)
116{
117    int i;
118    THING *obj;
119
120    /*
121     * Once you have found the amulet, the only way to get new stuff is
122     * go down into the dungeon.
123     */
124    if (Amulet && Level < Max_level)
125	return;
126    /*
127     * check for treasure rooms, and if so, put it in.
128     */
129    if (rnd(TREAS_ROOM) == 0)
130	treas_room();
131    /*
132     * Do MAXOBJ attempts to put things on a level
133     */
134    for (i = 0; i < MAXOBJ; i++)
135	if (rnd(100) < 36)
136	{
137	    /*
138	     * Pick a new object and link it in the list
139	     */
140	    obj = new_thing();
141	    attach(Lvl_obj, obj);
142	    /*
143	     * Put it somewhere
144	     */
145	    find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE);
146	    chat(obj->o_pos.y, obj->o_pos.x) = obj->o_type;
147	}
148    /*
149     * If he is really deep in the dungeon and he hasn't found the
150     * amulet yet, put it somewhere on the ground
151     */
152    if (Level >= AMULETLEVEL && !Amulet)
153    {
154	obj = new_item();
155	attach(Lvl_obj, obj);
156	obj->o_hplus = 0;
157	obj->o_dplus = 0;
158	obj->o_damage = obj->o_hurldmg = "0x0";
159	obj->o_arm = 11;
160	obj->o_type = AMULET;
161	/*
162	 * Put it somewhere
163	 */
164	find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE);
165	chat(obj->o_pos.y, obj->o_pos.x) = AMULET;
166    }
167}
168
169/*
170 * treas_room:
171 *	Add a treasure room
172 */
173#define MAXTRIES 10	/* max number of tries to put down a monster */
174
175void
176treas_room(void)
177{
178    int nm;
179    THING *tp;
180    struct room *rp;
181    int spots, num_monst;
182    static coord mp;
183
184    rp = &Rooms[rnd_room()];
185    spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS;
186    if (spots > (MAXTREAS - MINTREAS))
187	spots = (MAXTREAS - MINTREAS);
188    num_monst = nm = rnd(spots) + MINTREAS;
189    while (nm--)
190    {
191	find_floor(rp, &mp, 2 * MAXTRIES, FALSE);
192	tp = new_thing();
193	tp->o_pos = mp;
194	attach(Lvl_obj, tp);
195	chat(mp.y, mp.x) = tp->o_type;
196    }
197
198    /*
199     * fill up room with monsters from the next level down
200     */
201
202    if ((nm = rnd(spots) + MINTREAS) < num_monst + 2)
203	nm = num_monst + 2;
204    spots = (rp->r_max.y - 2) * (rp->r_max.x - 2);
205    if (nm > spots)
206	nm = spots;
207    Level++;
208    while (nm--)
209    {
210	spots = 0;
211	if (find_floor(rp, &mp, MAXTRIES, TRUE))
212	{
213	    tp = new_item();
214	    new_monster(tp, randmonster(FALSE), &mp);
215	    tp->t_flags |= ISMEAN;	/* no sloughers in THIS room */
216	    give_pack(tp);
217	}
218    }
219    Level--;
220}