Branch data Line data Source code
1 : : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 : : /* gen1.c */
3 : : /* level generator functions */
4 : :
5 : : #include "glob.h"
6 : :
7 : : #include <time.h>
8 : :
9 : : /* Deallocate current dungeon */
10 : 1 : void free_dungeon(void)
11 : : {
12 : : #ifndef SAVE_LEVELS
13 : : plv tlv;
14 : :
15 [ - + ]: 1 : while (Dungeon != NULL) {
16 : 0 : tlv = Dungeon;
17 : 0 : Dungeon = Dungeon->next;
18 : 0 : free_level(tlv);
19 : : }
20 : : #else
21 : : if (Dungeon != NULL)
22 : : {
23 : : sprintf(Str2,"om%d*.lev",Dungeon->environment);
24 : : kill_levels(Str2);
25 : : }
26 : : #endif
27 : 1 : }
28 : :
29 : :
30 : : /* erase the level w/o deallocating it*/
31 : 3 : void clear_level(struct level *dungeon_level)
32 : : {
33 : : int i,j;
34 [ + - ]: 3 : if (dungeon_level != NULL) {
35 : 3 : dungeon_level->generated = FALSE;
36 : 3 : dungeon_level->numrooms = 0;
37 : 3 : dungeon_level->level_length = 0;
38 : 3 : dungeon_level->level_width = 0;
39 : 3 : dungeon_level->tunnelled = 0;
40 : 3 : dungeon_level->depth = 0;
41 : 3 : dungeon_level->mlist = NULL;
42 : 3 : dungeon_level->next = NULL;
43 : 3 : dungeon_level->last_visited = time(NULL);
44 [ + + ]: 387 : for(i=0;i<MAXWIDTH;i++)
45 [ + + ]: 24960 : for(j=0;j<MAXLENGTH;j++) {
46 : 24576 : dungeon_level->site[i][j].locchar = WALL;
47 : 24576 : dungeon_level->site[i][j].showchar = SPACE;
48 : 24576 : dungeon_level->site[i][j].creature = NULL;
49 : 24576 : dungeon_level->site[i][j].things = NULL;
50 : : /* PGM: clear_level is called from restore_level, before it knows anything about the current environment, which is where difficulty() gets its information! */
51 : 24576 : dungeon_level->site[i][j].aux = difficulty()*20;
52 : 24576 : dungeon_level->site[i][j].buildaux = 0;
53 : 24576 : dungeon_level->site[i][j].p_locf = L_NO_OP;
54 : 24576 : dungeon_level->site[i][j].lstatus = 0;
55 : 24576 : dungeon_level->site[i][j].roomnumber = RS_WALLSPACE;
56 : : }
57 : : }
58 : 3 : }
59 : :
60 : :
61 : :
62 : : /* Looks for level tolevel in current dungeon which is named by
63 : : Dungeon, which may be NULL. If the level is found, and rewrite_level
64 : : is FALSE, and the level has already been generated, nothing happens
65 : : beyond Level being set correctly. Otherwise the level is recreated
66 : : from scratch */
67 : :
68 : 1 : void change_level (char fromlevel, char tolevel, char rewrite_level)
69 : : {
70 : 1 : struct level * thislevel = NULL;
71 : 1 : Player.sx = -1;
72 : 1 : Player.sy = -1; /* sanctuary effect dispelled */
73 : :
74 : : #ifndef SAVE_LEVELS
75 : 1 : thislevel = findlevel(Dungeon, tolevel);
76 : 1 : deepest[Current_Environment] = max(deepest[Current_Environment], tolevel);
77 [ + - ]: 1 : if (!thislevel)
78 : : {
79 : 1 : thislevel = checkmalloc(sizeof(levtype));
80 : 1 : clear_level(thislevel);
81 : 1 : Level = thislevel;
82 : 1 : Level->next = Dungeon;
83 : 1 : Dungeon = Level;
84 : : }
85 : : #else
86 : : thislevel = msdos_changelevel(Level, Current_Environment, tolevel);
87 : : deepest[Current_Environment] = max(deepest[Current_Environment], tolevel);
88 : : if (!thislevel)
89 : : {
90 : : thislevel = &TheLevel;
91 : : clear_level(thislevel);
92 : : Level = thislevel;
93 : : Level->next = Dungeon;
94 : : Dungeon = Level;
95 : : }
96 : : #endif
97 : :
98 : 1 : Level = thislevel;
99 [ - + ][ # # ]: 1 : if ((!Level->generated) || rewrite_level)
100 : : {
101 : 1 : initrand(Current_Environment, tolevel);
102 : 1 : Level->environment = Current_Environment;
103 : 1 : Level->depth = tolevel;
104 : 1 : Level->generated = TRUE;
105 : :
106 [ + - - - : 1 : switch (Current_Environment)
- - - ]
107 : : {
108 : : case E_CAVES:
109 : 1 : Level->level_width = CAVES_WIDTH;
110 : 1 : Level->level_length = CAVES_LENGTH;
111 [ - + ][ # # ]: 1 : if ((0 == random_range(4)) && (tolevel < MaxDungeonLevels))
112 : 0 : room_level();
113 : : else
114 : 1 : cavern_level();
115 : 1 : break;
116 : :
117 : : case E_SEWERS:
118 : 0 : Level->level_width = SEWERS_WIDTH;
119 : 0 : Level->level_length = SEWERS_LENGTH;
120 [ # # ][ # # ]: 0 : if ((0 == random_range(4)) && (tolevel < MaxDungeonLevels))
121 : 0 : room_level();
122 : : else
123 : 0 : sewer_level();
124 : 0 : break;
125 : :
126 : : case E_CASTLE:
127 : 0 : Level->level_width = CASTLE_WIDTH;
128 : 0 : Level->level_length = CASTLE_LENGTH;
129 : 0 : room_level();
130 : 0 : break;
131 : :
132 : : case E_PALACE: /* PGM TODO */
133 : 0 : Level->level_width = PALACE_WIDTH;
134 : 0 : Level->level_length = PALACE_LENGTH;
135 : 0 : room_level();
136 : 0 : break;
137 : :
138 : : case E_ASTRAL:
139 : 0 : Level->level_width = ASTRAL_WIDTH;
140 : 0 : Level->level_length = ASTRAL_LENGTH;
141 : 0 : maze_level();
142 : 0 : break;
143 : :
144 : : case E_VOLCANO:
145 : 0 : Level->level_width = VOLCANO_WIDTH;
146 : 0 : Level->level_length = VOLCANO_LENGTH;
147 [ # # # # ]: 0 : switch (random_range(3))
148 : : {
149 : 0 : case 0: cavern_level(); break;
150 : 0 : case 1: room_level(); break;
151 : 0 : case 2: maze_level(); break;
152 : : }
153 : 0 : break;
154 : :
155 : : default:
156 : 0 : print3("This dungeon not implemented!");
157 : 0 : assert(FALSE);
158 : : break;
159 : : }
160 : :
161 : 1 : install_traps();
162 : 1 : install_specials();
163 : 1 : make_stairs(fromlevel);
164 : 1 : make_stairs(fromlevel);
165 : 1 : initrand(E_RESTORE, 0);
166 : 1 : populate_level(Current_Environment);
167 : 1 : stock_level();
168 : : }
169 : :
170 : 1 : find_stairs(fromlevel, tolevel);
171 : 1 : ScreenOffset = Player.y - (ScreenLength/2);
172 : 1 : show_screen();
173 : 1 : screencheck(Player.x,Player.y);
174 : 1 : drawvision(Player.x,Player.y);
175 : :
176 : : /* synchronize with player on level change */
177 : 1 : Player.click = (Tick+1)%60;
178 : 1 : roomcheck();
179 : 1 : }
180 : :
181 : : #ifndef SAVE_LEVELS
182 : : /* tries to find the level of depth levelnum in dungeon; if can't find
183 : : it returns NULL */
184 : 1 : plv findlevel(struct level *dungeon, char levelnum)
185 : : {
186 [ + - ]: 1 : if (dungeon == NULL) return(NULL);
187 : : else {
188 [ # # ][ # # ]: 0 : while((dungeon->next != NULL) && (dungeon->depth != levelnum))
189 : 0 : dungeon = dungeon->next;
190 [ # # ]: 0 : if (dungeon->depth == levelnum) {
191 : 0 : dungeon->last_visited = time(NULL);
192 : 0 : return(dungeon);
193 : : }
194 : 0 : else return(NULL);
195 : : }
196 : : }
197 : : #endif
198 : :
199 : :
200 : :
201 : : /* keep going in one orthogonal direction or another until we hit our */
202 : : /* destination */
203 : :
204 : 17 : void straggle_corridor(int fx, int fy, int tx, int ty, Symbol loc, char rsi)
205 : : {
206 : : int dx,dy;
207 [ + + ][ + + ]: 109 : while ((fx != tx) || (fy != ty)) {
208 : 92 : dx = tx - fx;
209 : 92 : dy = ty - fy;
210 [ + + ]: 92 : if (random_range(abs(dx)+abs(dy)) < abs(dx))
211 [ + + ]: 40 : corridor_crawl(&fx,&fy,sign(dx),0,random_range(abs(dx))+1,loc,rsi);
212 [ + + ]: 52 : else corridor_crawl(&fx,&fy,0,sign(dy),random_range(abs(dy))+1,loc,rsi);
213 : : }
214 : 17 : }
215 : :
216 : :
217 : 0 : void makedoor(int x, int y)
218 : : {
219 [ # # ]: 0 : if (random_range(20) <= Level->depth/10) {
220 : 0 : Level->site[x][y].locchar = FLOOR;
221 : 0 : lset(x,y,SECRET);
222 : : }
223 [ # # ]: 0 : else if (random_range(20)<=Level->depth/2) {
224 : 0 : Level->site[x][y].locchar = CLOSED_DOOR;
225 [ # # ]: 0 : if (random_range(20) <= Level->depth/10)
226 : 0 : lset(x,y,SECRET);
227 [ # # ]: 0 : if (random_range(40) <= Level->depth)
228 : 0 : Level->site[x][y].aux = LOCKED;
229 : 0 : else Level->site[x][y].aux = UNLOCKED;
230 : : }
231 : : else {
232 : 0 : Level->site[x][y].locchar = OPEN_DOOR;
233 : 0 : Level->site[x][y].aux = UNLOCKED;
234 : : }
235 [ # # ]: 0 : if (! loc_statusp(x,y,SECRET)) {
236 : 0 : lset(x,y+1,STOPS);
237 : 0 : lset(x+1,y,STOPS);
238 : 0 : lset(x-1,y,STOPS);
239 : 0 : lset(x,y-1,STOPS);
240 : 0 : lset(x,y,STOPS);
241 : : }
242 : 0 : Level->site[x][y].p_locf = L_NO_OP;
243 : : /* prevents water corridors from being instant death in sewers */
244 : 0 : }
245 : :
246 : :
247 : 92 : void corridor_crawl(int *fx, int *fy, int sx, int sy, int n,
248 : : Symbol loc, char rsi)
249 : : {
250 : : int i;
251 [ + + ]: 613 : for (i=0;i<n;i++) {
252 : 521 : *fx += sx;
253 : 521 : *fy += sy;
254 [ + - ][ + - ]: 521 : if ((*fx < Level->level_width) &&
255 [ + - ]: 521 : (*fx > -1) &&
256 [ + - ]: 521 : (*fy > -1) &&
257 : 521 : (*fy < Level->level_length)) {
258 : 521 : Level->site[*fx][*fy].locchar = loc;
259 [ + + ]: 521 : if (Level->site[*fx][*fy].roomnumber == RS_WALLSPACE)
260 : 352 : Level->site[*fx][*fy].roomnumber = rsi;
261 [ + + ]: 521 : if (loc==WATER)
262 : 51 : Level->site[*fx][*fy].p_locf = L_WATER;
263 [ + - ]: 470 : else if (loc==FLOOR)
264 : 470 : Level->site[*fx][*fy].p_locf = L_NO_OP;
265 [ # # ]: 0 : else if (loc==RUBBLE)
266 : 0 : Level->site[*fx][*fy].p_locf = L_RUBBLE;
267 : : }
268 : : }
269 : 92 : }
270 : :
271 : :
272 : 3 : char *roomname(int index)
273 : : {
274 [ - - - - : 3 : switch(index) {
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - ]
275 : 0 : case RS_ZORCH:strcpy(Str4,"A place zorched by powerful magic.");break;
276 : 0 : case RS_COURT:strcpy(Str4,"The Court of the ArchMage."); break;
277 : 0 : case RS_CIRCLE:strcpy(Str4,"The Astral Demesne of the Circle of Sorcerors");
278 : 0 : break;
279 : 0 : case RS_MAGIC_ISLE: strcpy(Str4,"An island positively reeking of magic");
280 : 0 : break;
281 : 0 : case RS_STARPEAK: strcpy(Str4,"Near the oddly glowing peak of a mountain");
282 : 0 : break;
283 : 0 : case RS_VOLCANO: strcpy(Str4,"Deep within the bowels of the earth"); break;
284 : 0 : case RS_HIGHASTRAL: strcpy(Str4,"The High Astral Plane"); break;
285 : 0 : case RS_EARTHPLANE: strcpy(Str4,"The Plane of Earth"); break;
286 : 0 : case RS_WATERPLANE: strcpy(Str4,"The Plane of Water"); break;
287 : 0 : case RS_FIREPLANE: strcpy(Str4,"The Plane of Fire"); break;
288 : 0 : case RS_AIRPLANE: strcpy(Str4,"The Plane of Air"); break;
289 : 0 : case RS_KITCHEN: strcpy(Str4,"A kitchen"); break;
290 : 0 : case RS_BATHROOM: strcpy(Str4,"A bathroom"); break;
291 : 0 : case RS_BEDROOM: strcpy(Str4,"A bedroom"); break;
292 : 0 : case RS_DININGROOM: strcpy(Str4,"A dining room"); break;
293 : 0 : case RS_SECRETPASSAGE: strcpy(Str4,"A secret passage"); break;
294 : 0 : case RS_CLOSET: strcpy(Str4,"A stuffy closet"); break;
295 : 0 : case RS_ARENA: strcpy(Str4,"The Rampart Arena"); break;
296 : 0 : case RS_DROWNED_SEWER: strcpy(Str4,"A water-filled sewer node"); break;
297 : 0 : case RS_DRAINED_SEWER: strcpy(Str4,"An unused sewer node"); break;
298 : 0 : case RS_SEWER_DUCT: strcpy(Str4,"A winding sewer duct"); break;
299 : 0 : case RS_DESTINY: strcpy(Str4,"The Halls of Fate"); break;
300 : 0 : case RS_DRUID: strcpy(Str4,"The Great Henge"); break;
301 : 0 : case RS_HECATE: strcpy(Str4,"The Church of the Far Side"); break;
302 : 0 : case RS_SET: strcpy(Str4,"The Temple of the Black Hand"); break;
303 : 0 : case RS_ATHENA: strcpy(Str4,"The Parthenon"); break;
304 : 0 : case RS_ODIN: strcpy(Str4,"The Shrine of the Noose"); break;
305 : 0 : case RS_ADEPT: strcpy(Str4,"The Adept's Challenge"); break;
306 : 0 : case RS_WYRM: strcpy(Str4,"The Sunken Cavern of the Great Wyrm."); break;
307 : 0 : case RS_OCEAN: strcpy(Str4,"The Underground Ocean."); break;
308 : 0 : case RS_PONDS: strcpy(Str4,"A series of subterranean pools and streams."); break;
309 : 0 : case RS_DRAGONLORD: strcpy(Str4,"The Lair of the DragonLord."); break;
310 : 0 : case RS_GOBLINKING: strcpy(Str4,"The Caves of the Goblins."); break;
311 : 3 : case RS_CAVERN: strcpy(Str4,"A vast natural cavern."); break;
312 : 0 : case RS_CORRIDOR: strcpy(Str4,"A dimly lit corridor."); break;
313 : 0 : case RS_WALLSPACE: strcpy(Str4,"A niche hollowed out of the wall."); break;
314 : : /* following are above ROOMBASE */
315 : 0 : case RS_GARDEROBE: strcpy(Str4,"An abandoned garderobe."); break;
316 : 0 : case RS_CELL: strcpy(Str4,"A dungeon cell."); break;
317 : 0 : case RS_TILED: strcpy(Str4,"A tiled chamber."); break;
318 : 0 : case RS_CRYSTAL_CAVE: strcpy(Str4,"A crystal cavern."); break;
319 : 0 : case RS_BEDROOM2: strcpy(Str4,"Someone's bedroom."); break;
320 : 0 : case RS_STOREROOM: strcpy(Str4,"An old storeroom."); break;
321 : 0 : case RS_CHARRED: strcpy(Str4,"A room with charred walls."); break;
322 : 0 : case RS_MARBLE_HALL: strcpy(Str4,"A marble hall."); break;
323 : 0 : case RS_EERIE_CAVE: strcpy(Str4,"An eerie cave."); break;
324 : 0 : case RS_TREASURE: strcpy(Str4,"A ransacked treasure-chamber."); break;
325 : 0 : case RS_SMOKEY: strcpy(Str4,"A smoke-filled room."); break;
326 : 0 : case RS_APARTMENT: strcpy(Str4,"A well-appointed apartment."); break;
327 : 0 : case RS_ANTECHAMBER: strcpy(Str4,"An antechamber."); break;
328 : 0 : case RS_HAREM: strcpy(Str4,"An unoccupied harem."); break;
329 : 0 : case RS_MULTIPURPOSE: strcpy(Str4,"A multi-purpose room."); break;
330 : 0 : case RS_STALACTITES: strcpy(Str4,"A room filled with stalactites."); break;
331 : 0 : case RS_GREENHOUSE: strcpy(Str4,"An underground greenhouse."); break;
332 : 0 : case RS_WATERCLOSET: strcpy(Str4,"A water closet."); break;
333 : 0 : case RS_STUDY: strcpy(Str4,"A study."); break;
334 : 0 : case RS_LIVING_ROOM: strcpy(Str4,"A living room."); break;
335 : 0 : case RS_DEN: strcpy(Str4,"A comfortable den."); break;
336 : 0 : case RS_ABATOIR: strcpy(Str4,"An abatoir."); break;
337 : 0 : case RS_BOUDOIR: strcpy(Str4,"A boudoir.");break;
338 : 0 : case RS_STAR_CHAMBER: strcpy(Str4,"A star chamber.");break;
339 : 0 : case RS_MANMADE_CAVE: strcpy(Str4,"A manmade cavern."); break;
340 : 0 : case RS_SEWER_CONTROL: strcpy(Str4,"A sewer control room");break;
341 : 0 : case RS_SHRINE: strcpy(Str4,"A shrine to High Magic"); break;
342 : 0 : case RS_MAGIC_LAB: strcpy(Str4,"A magic laboratory"); break;
343 : 0 : case RS_PENTAGRAM: strcpy(Str4,"A room with inscribed pentagram");break;
344 : 0 : case RS_OMEGA_DAIS: strcpy(Str4,"A chamber with a blue crystal omega dais");
345 : 0 : break;
346 : : /* WDT: removed period from description. */
347 : 0 : default: strcpy(Str4,"A room of mystery and allure"); break;
348 : : }
349 : 3 : return(Str4);
350 : : }
351 : :
352 : :
353 : : /* puts the player on the first set of stairs from the apt level */
354 : : /* if can't find them, just drops player anywhere.... */
355 : 1 : void find_stairs(char fromlevel, char tolevel)
356 : : {
357 : 1 : int i,j,found=FALSE;
358 : : Symbol sitechar;
359 [ - + ]: 1 : if (fromlevel > tolevel) sitechar = STAIRS_DOWN; else sitechar = STAIRS_UP;
360 [ + + ]: 65 : for(i=0;i<Level->level_width;i++)
361 [ + + ]: 4114 : for(j=0;j<Level->level_length;j++)
362 [ + + ][ + + ]: 4051 : if ((Level->site[i][j].locchar == sitechar) && (! found)) {
363 : 1 : found = TRUE;
364 : 1 : Player.x = i;
365 : 1 : Player.y = j;
366 : 1 : break;
367 : : }
368 [ - + ]: 1 : if (! found) {
369 : 0 : findspace(&Player.x,&Player.y,-1);
370 [ # # ]: 0 : if (Level->environment != E_ASTRAL) {
371 : 0 : Level->site[Player.x][Player.y].locchar = sitechar;
372 : 0 : lset(Player.x, Player.y, CHANGED);
373 : : }
374 : : }
375 : 1 : }
376 : :
377 : :
378 : :
379 : 1 : void install_traps(void)
380 : : {
381 : : int i,j;
382 [ + + ]: 65 : for(i=0;i<Level->level_width;i++)
383 [ + + ]: 4160 : for(j=0;j<Level->level_length;j++)
384 [ + + ][ + - ]: 4096 : if ((Level->site[i][j].locchar == FLOOR) &&
385 [ + + ]: 436 : (Level->site[i][j].p_locf == L_NO_OP) &&
386 : 436 : random_range(500) <= ((int)(Level->depth/6)))
387 : 3 : Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
388 : 1 : }
389 : :
390 : :
391 : : /* x, y, is top left corner, l is length of side, rsi is room string index */
392 : : /* baux is so all rooms will have a key field. */
393 : 1 : void build_square_room(int x, int y, int l, char rsi, int baux)
394 : : {
395 : : int i,j;
396 : :
397 [ + + ]: 14 : for(i=x;i<=x+l;i++)
398 [ + + ]: 182 : for(j=y;j<=y+l;j++){
399 : 169 : Level->site[i][j].roomnumber = rsi;
400 : 169 : Level->site[i][j].buildaux = baux;
401 : : }
402 [ + + ]: 12 : for(i=x+1;i<x+l;i++)
403 [ + + ]: 132 : for(j=y+1;j<y+l;j++) {
404 : 121 : Level->site[i][j].locchar = FLOOR;
405 : 121 : Level->site[i][j].p_locf = L_NO_OP;
406 : : }
407 : 1 : }
408 : :
409 : :
410 : 0 : void build_room(int x, int y, int l, char rsi, int baux)
411 : : {
412 : 0 : build_square_room(x,y,l,rsi,baux);
413 : 0 : }
414 : :
415 : 1 : void cavern_level(void)
416 : : {
417 : : int i,fx,fy,tx,ty,t,l,e;
418 : : char rsi;
419 : :
420 : 1 : Level->numrooms = 1;
421 : :
422 [ + - ][ - + ]: 1 : if ((Current_Dungeon == E_CAVES) && (Level->depth == CAVELEVELS))
423 : 0 : rsi = RS_GOBLINKING;
424 : 1 : else rsi = RS_CAVERN;
425 : 1 : t = random_range((Level->level_length)/2);
426 : 1 : l = random_range((Level->level_width)/2);
427 : 1 : e = random_range((Level->level_width)/8)+(Level->level_width)/8;
428 : 1 : build_square_room(t,l,e,rsi,0);
429 : :
430 [ + + ]: 17 : for (i=0;i<16;i++) {
431 : 16 : findspace(&tx,&ty,-1);
432 : 16 : fx = random_range((Level->level_width)-2)+1;
433 : 16 : fy = random_range((Level->level_length)-2)+1;
434 : 16 : straggle_corridor(fx,fy,tx,ty,FLOOR,RS_CORRIDOR);
435 : : }
436 [ + + ]: 2 : while (random_range(3)==1) {
437 : 1 : findspace(&tx,&ty,-1);
438 : 1 : fx = random_range((Level->level_width)-2)+1;
439 : 1 : fy = random_range((Level->level_length)-2)+1;
440 : 1 : straggle_corridor(fx,fy,tx,ty,WATER,RS_PONDS);
441 : : }
442 [ + - ]: 1 : if (Current_Dungeon == E_CAVES) {
443 [ - + ][ # # ]: 1 : if ((Level->depth == CAVELEVELS) && (! gamestatusp(COMPLETED_CAVES))) {
444 : 0 : findspace(&tx,&ty,-1);
445 : 0 : Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
446 : 0 : Level->mlist->next = NULL;
447 : 0 : Level->mlist->m =
448 : 0 : Level->site[tx][ty].creature =
449 : 0 : ((pmt) make_creature(GOBLIN_KING)); /* goblin king */
450 : 0 : Level->mlist->m->x = tx;
451 : 1 : Level->mlist->m->y = ty;
452 : : }
453 : : }
454 [ # # ]: 0 : else if (Current_Environment == E_VOLCANO) {
455 [ # # ]: 0 : if (Level->depth == VOLCANOLEVELS) {
456 : 0 : findspace(&tx,&ty,-1);
457 : 0 : Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
458 : 0 : Level->mlist->next = NULL;
459 : 0 : Level->mlist->m =
460 : 0 : Level->site[tx][ty].creature =
461 : 0 : ((pmt) make_creature(DEMON_EMP)); /* The demon emp */
462 : 0 : Level->mlist->m->x = tx;
463 : 0 : Level->mlist->m->y = ty;
464 : : }
465 : : }
466 : 1 : }
467 : :
468 : :
469 : 0 : void sewer_level(void)
470 : : {
471 : : int i,tx,ty,t,l,e;
472 : : char rsi;
473 : : Symbol lchar;
474 : :
475 : 0 : Level->numrooms = random_range(3)+3;
476 : 0 : rsi = RS_DRAINED_SEWER;
477 [ # # ]: 0 : for (i=0;i<Level->numrooms;i++) {
478 : : do {
479 : 0 : t = random_range((Level->level_length)-10)+1;
480 : 0 : l = random_range((Level->level_width)-10)+1;
481 : 0 : e = 4;
482 [ # # ]: 0 : } while ((Level->site[l][t].roomnumber == rsi) ||
483 [ # # ]: 0 : (Level->site[l+e][t].roomnumber == rsi) ||
484 [ # # ]: 0 : (Level->site[l][t+e].roomnumber == rsi) ||
485 [ # # ]: 0 : (Level->site[l+e][t+e].roomnumber == rsi));
486 [ # # ]: 0 : if (random_range(5)) {
487 : 0 : lchar = FLOOR;
488 : 0 : rsi = RS_DRAINED_SEWER;
489 : : }
490 : : else {
491 : 0 : lchar = WATER;
492 : 0 : rsi = RS_DROWNED_SEWER;
493 : : }
494 : 0 : build_room(l,t,e,rsi,i);
495 : 0 : sewer_corridor(l,t,-1,-1,lchar);
496 : 0 : sewer_corridor(l+e,t,1,-1,lchar);
497 : 0 : sewer_corridor(l,t+e,-1,1,lchar);
498 : 0 : sewer_corridor(l+e,t+e,1,1,lchar);
499 : : }
500 [ # # ]: 0 : if (Current_Dungeon == E_SEWERS) {
501 [ # # ][ # # ]: 0 : if ((Level->depth == SEWERLEVELS) && (! gamestatusp(COMPLETED_SEWERS))) {
502 : 0 : findspace(&tx,&ty,-1);
503 : 0 : Level->mlist = ((pml) checkmalloc(sizeof(mltype)));
504 : 0 : Level->mlist->next = NULL;
505 : 0 : Level->mlist->m =
506 : 0 : Level->site[tx][ty].creature =
507 : 0 : ((pmt) make_creature(GREAT_WYRM)); /* The Great Wyrm */
508 : 0 : Level->mlist->m->x = tx;
509 : 0 : Level->mlist->m->y = ty;
510 : : }
511 : : }
512 : 0 : }
513 : :
514 : :
515 : 0 : void sewer_corridor(int x, int y, int dx, int dy, Symbol locchar)
516 : : {
517 : 0 : int continuing = TRUE;
518 : 0 : makedoor(x,y);
519 : 0 : x+=dx;
520 : 0 : y+=dy;
521 [ # # ]: 0 : while(continuing) {
522 : 0 : Level->site[x][y].locchar = locchar;
523 [ # # ]: 0 : if (locchar == WATER)
524 : 0 : Level->site[x][y].p_locf = L_WATER;
525 : 0 : else Level->site[x][y].p_locf = L_NO_OP;
526 : 0 : Level->site[x][y].roomnumber = RS_SEWER_DUCT;
527 : 0 : x+=dx;
528 : 0 : y+=dy;
529 [ # # ]: 0 : if (locchar == WATER)
530 [ # # ][ # # ]: 0 : continuing = (inbounds(x,y) &&
531 [ # # ]: 0 : ((Level->site[x][y].locchar == WALL) ||
532 : 0 : (Level->site[x][y].locchar == WATER)));
533 : : else
534 [ # # ][ # # ]: 0 : continuing = (inbounds(x,y) &&
535 [ # # ]: 0 : ((Level->site[x][y].roomnumber == RS_WALLSPACE) ||
536 : 0 : (Level->site[x][y].roomnumber == RS_SEWER_DUCT)));
537 : : }
538 [ # # ]: 0 : if (inbounds(x,y))
539 : 0 : makedoor(x,y);
540 : 0 : }
541 : :
542 : :
543 : 1 : void install_specials(void)
544 : : {
545 : : int i,j,x,y;
546 : :
547 [ + + ]: 65 : for(x=0;x<Level->level_width;x++)
548 [ + + ]: 4160 : for(y=0;y<Level->level_length;y++)
549 [ + + ][ + + ]: 4096 : if ((Level->site[x][y].locchar == FLOOR) &&
550 [ + + ]: 433 : (Level->site[x][y].p_locf == L_NO_OP) &&
551 : 433 : (random_range(300) < difficulty())) {
552 : 3 : i = random_range(100);
553 [ - + ]: 3 : if (i < 10) {
554 : 0 : Level->site[x][y].locchar = ALTAR;
555 : 0 : Level->site[x][y].p_locf = L_ALTAR;
556 : 0 : Level->site[x][y].aux = random_range(10);
557 : : }
558 [ - + ]: 3 : else if (i < 20) {
559 : 0 : Level->site[x][y].locchar = WATER;
560 : 0 : Level->site[x][y].p_locf = L_MAGIC_POOL;
561 : : }
562 [ - + ]: 3 : else if (i < 35) {
563 : 0 : Level->site[x][y].locchar = RUBBLE;
564 : 0 : Level->site[x][y].p_locf = L_RUBBLE;
565 : : }
566 [ - + ]: 3 : else if (i < 40) {
567 : 0 : Level->site[x][y].locchar = LAVA;
568 : 0 : Level->site[x][y].p_locf = L_LAVA;
569 : : }
570 [ - + ]: 3 : else if (i < 45) {
571 : 0 : Level->site[x][y].locchar = FIRE;
572 : 0 : Level->site[x][y].p_locf = L_FIRE;
573 : : }
574 [ - + ][ # # ]: 3 : else if ((i < 50) && (Current_Environment != E_ASTRAL)) {
575 : 0 : Level->site[x][y].locchar = LIFT;
576 : 0 : Level->site[x][y].p_locf = L_LIFT;
577 : : }
578 [ - + ][ # # ]: 3 : else if ((i < 55) && (Current_Environment != E_VOLCANO)) {
579 : 0 : Level->site[x][y].locchar = HEDGE;
580 : 0 : Level->site[x][y].p_locf = L_HEDGE;
581 : : }
582 [ - + ]: 3 : else if (i < 57) {
583 : 0 : Level->site[x][y].locchar = HEDGE;
584 : 0 : Level->site[x][y].p_locf = L_TRIFID;
585 : : }
586 [ + + ]: 3 : else if (i< 70) {
587 : 1 : Level->site[x][y].locchar = STATUE;
588 [ - + ]: 1 : if (random_range(100) < difficulty())
589 [ # # ]: 0 : for (j=0;j<8;j++) {
590 [ # # ]: 0 : if (Level->site[x+Dirs[0][j]][y+Dirs[1][j]].p_locf != L_NO_OP)
591 : 0 : Level->site[x+Dirs[0][j]][y+Dirs[1][j]].locchar = FLOOR;
592 : 0 : Level->site[x+Dirs[0][j]][y+Dirs[1][j]].p_locf =
593 : : L_STATUE_WAKE;
594 : : }
595 : : }
596 : : else {
597 [ - + ]: 2 : if (Current_Environment == E_VOLCANO) {
598 : 0 : Level->site[x][y].locchar = LAVA;
599 : 0 : Level->site[x][y].p_locf = L_LAVA;
600 : : }
601 [ - + ]: 2 : else if (Current_Environment == E_ASTRAL) {
602 [ # # ]: 0 : if (Level->depth == 1) {
603 : 0 : Level->site[x][y].locchar = RUBBLE;
604 : 0 : Level->site[x][y].p_locf = L_RUBBLE;
605 : : }
606 [ # # ]: 0 : else if (Level->depth == 2) {
607 : 0 : Level->site[x][y].locchar = FIRE;
608 : 0 : Level->site[x][y].p_locf = L_FIRE;
609 : : }
610 [ # # ]: 0 : else if (Level->depth == 3) {
611 : 0 : Level->site[x][y].locchar = WATER;
612 : 0 : Level->site[x][y].p_locf = L_WATER;
613 : : }
614 [ # # ]: 0 : else if (Level->depth == 4) {
615 : 0 : Level->site[x][y].locchar = ABYSS;
616 : 0 : Level->site[x][y].p_locf = L_ABYSS;
617 : : }
618 : : }
619 : : else {
620 : 2 : Level->site[x][y].locchar = WATER;
621 : 2 : Level->site[x][y].p_locf = L_WATER;
622 : : }
623 : : }
624 : : }
625 : 1 : }
|