comparison 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
comparison
equal deleted inserted replaced
11:949d558c2162 12:9535a08ddc39
1 /*
2 * new_level:
3 * Dig and draw a new level
4 *
5 * @(#)new_level.c 4.19 (Berkeley) 1/12/82
6 *
7 * Rogue: Exploring the Dungeons of Doom
8 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
9 * All rights reserved.
10 *
11 * See the file LICENSE.TXT for full copyright and licensing information.
12 */
13
14 #include <time.h>
15 #include <curses.h>
16 #include <string.h>
17 #include "rogue.h"
18
19 #define TREAS_ROOM 20 /* one chance in TREAS_ROOM for a treasure room */
20 #define MAXTREAS 10 /* maximum number of treasures in a treasure room */
21 #define MINTREAS 2 /* minimum number of treasures in a treasure room */
22
23 new_level()
24 {
25 register int rm, i;
26 register THING *tp;
27 register char *sp;
28 register THING **mp;
29 register int index;
30 coord stairs;
31
32 player.t_flags &= ~ISHELD; /* unhold when you go down just in case */
33 if (level > max_level)
34 max_level = level;
35 /*
36 * Clean things off from last level
37 */
38 clear();
39 for (sp = _level; sp < &_level[MAXCOLS*MAXLINES]; )
40 *sp++ = ' ';
41 for (sp = _flags; sp < &_flags[MAXCOLS*MAXLINES]; )
42 *sp++ = F_REAL;
43 for (mp = _monst; mp < &_monst[MAXCOLS*MAXLINES]; )
44 *mp++ = NULL;
45 clear();
46 /*
47 * Free up the monsters on the last level
48 */
49 for (tp = mlist; tp != NULL; tp = next(tp))
50 free_list(tp->t_pack);
51 free_list(mlist);
52 /*
53 * Throw away stuff left on the previous level (if anything)
54 */
55 free_list(lvl_obj);
56 do_rooms(); /* Draw rooms */
57 do_passages(); /* Draw passages */
58 no_food++;
59 put_things(); /* Place objects (if any) */
60 /*
61 * Place the staircase down.
62 */
63 i = 0;
64 do {
65 rm = rnd_room();
66 rnd_pos(&rooms[rm], &stairs);
67 index = INDEX(stairs.y, stairs.x);
68 if (i++ > 100)
69 {
70 i = 0;
71 srand(getpid() + (int) time((time_t *) NULL));
72 }
73 } until (_level[index] == FLOOR);
74 _level[index] = STAIRS;
75 /*
76 * Place the traps
77 */
78 if (rnd(10) < level)
79 {
80 ntraps = rnd(level / 4) + 1;
81 if (ntraps > MAXTRAPS)
82 ntraps = MAXTRAPS;
83 i = ntraps;
84 while (i--)
85 {
86 do
87 {
88 rm = rnd_room();
89 rnd_pos(&rooms[rm], &stairs);
90 index = INDEX(stairs.y, stairs.x);
91 } until (_level[index] == FLOOR && (_flags[index] & F_REAL));
92 sp = &_flags[index];
93 *sp &= ~(F_REAL | F_TMASK);
94 *sp |= rnd(NTRAPS);
95 }
96 }
97 do
98 {
99 rm = rnd_room();
100 rnd_pos(&rooms[rm], &hero);
101 index = INDEX(hero.y, hero.x);
102 } until (_level[index] == FLOOR && (_flags[index] & F_REAL)
103 && _monst[index] == NULL);
104 enter_room(&hero);
105 move(hero.y, hero.x);
106 addch(PLAYER);
107 if (on(player, SEEMONST))
108 turn_see(FALSE);
109 }
110
111 /*
112 * rnd_room:
113 * Pick a room that is really there
114 */
115 rnd_room()
116 {
117 register int rm;
118
119 do
120 {
121 rm = rnd(MAXROOMS);
122 } while (rooms[rm].r_flags & ISGONE);
123 return rm;
124 }
125
126 /*
127 * put_things:
128 * Put potions and scrolls on this level
129 */
130 put_things()
131 {
132 register int i;
133 register THING *cur;
134 register int rm;
135 coord tp;
136
137 /*
138 * Once you have found the amulet, the only way to get new stuff is
139 * go down into the dungeon.
140 */
141 if (amulet && level < max_level)
142 return;
143 /*
144 * check for treasure rooms, and if so, put it in.
145 */
146 if (rnd(TREAS_ROOM) == 0)
147 treas_room();
148 /*
149 * Do MAXOBJ attempts to put things on a level
150 */
151 for (i = 0; i < MAXOBJ; i++)
152 if (rnd(100) < 35)
153 {
154 /*
155 * Pick a new object and link it in the list
156 */
157 cur = new_thing();
158 attach(lvl_obj, cur);
159 /*
160 * Put it somewhere
161 */
162 do {
163 rm = rnd_room();
164 rnd_pos(&rooms[rm], &tp);
165 } until (chat(tp.y, tp.x) == FLOOR);
166 chat(tp.y, tp.x) = cur->o_type;
167 cur->o_pos = tp;
168 }
169 /*
170 * If he is really deep in the dungeon and he hasn't found the
171 * amulet yet, put it somewhere on the ground
172 */
173 if (level >= AMULETLEVEL && !amulet)
174 {
175 cur = new_item();
176 attach(lvl_obj, cur);
177 cur->o_hplus = cur->o_dplus = 0;
178 strcpy(cur->o_damage,"0d0");
179 strcpy(cur->o_hurldmg,"0d0");
180 cur->o_ac = 11;
181 cur->o_type = AMULET;
182 /*
183 * Put it somewhere
184 */
185 do {
186 rm = rnd_room();
187 rnd_pos(&rooms[rm], &tp);
188 } until (winat(tp.y, tp.x) == FLOOR);
189 chat(tp.y, tp.x) = AMULET;
190 cur->o_pos = tp;
191 }
192 }
193
194 /*
195 * treas_room:
196 * Add a treasure room
197 */
198 #define MAXTRIES 10 /* max number of tries to put down a monster */
199
200 treas_room()
201 {
202 register int nm, index;
203 register THING *tp;
204 register struct room *rp;
205 register int spots, num_monst;
206 coord mp;
207
208 rp = &rooms[rnd_room()];
209 spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS;
210 if (spots > (MAXTREAS - MINTREAS))
211 spots = (MAXTREAS - MINTREAS);
212 num_monst = nm = rnd(spots) + MINTREAS;
213 while (nm--)
214 {
215 do
216 {
217 rnd_pos(rp, &mp);
218 index = INDEX(mp.y, mp.x);
219 } until (_level[index] == FLOOR);
220 tp = new_thing();
221 tp->o_pos = mp;
222 attach(lvl_obj, tp);
223 _level[index] = tp->o_type;
224 }
225
226 /*
227 * fill up room with monsters from the next level down
228 */
229
230 if ((nm = rnd(spots) + MINTREAS) < num_monst + 2)
231 nm = num_monst + 2;
232 spots = (rp->r_max.y - 2) * (rp->r_max.x - 2);
233 if (nm > spots)
234 nm = spots;
235 level++;
236 while (nm--)
237 {
238 spots = 0;
239 do
240 {
241 rnd_pos(rp, &mp);
242 index = INDEX(mp.y, mp.x);
243 spots++;
244 } until (_monst[index] == NULL || spots > MAXTRIES);
245 if (_monst[index] == NULL)
246 {
247 tp = new_item();
248 new_monster(tp, randmonster(FALSE), &mp);
249 tp->t_flags |= ISMEAN; /* no sloughers in THIS room */
250 give_pack(tp);
251 }
252 }
253 level--;
254 }