Mercurial > hg > early-roguelike
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 } |