• R/O
  • SSH
  • HTTPS

deeangband: Commit


Commit MetaInfo

Revision9115 (tree)
Time2013-11-02 23:54:23
Authordeskull

Log Message

Change Summary

Incremental Difference

--- source/trunk/src/generate.c (revision 9114)
+++ source/trunk/src/generate.c (nonexistent)
@@ -1,1350 +0,0 @@
1-/* File: generate.c */
2-
3-/*
4- * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
5- *
6- * This software may be copied and distributed for educational, research,
7- * and not for profit purposes provided that this copyright and statement
8- * are included in all such copies. Other copyrights may also apply.
9- */
10-
11-/* Purpose: Dungeon generation */
12-
13-/*
14- * Note that Level generation is *not* an important bottleneck,
15- * though it can be annoyingly slow on older machines... Thus
16- * we emphasize "simplicity" and "correctness" over "speed".
17- *
18- * This entire file is only needed for generating levels.
19- * This may allow smart compilers to only load it when needed.
20- *
21- * Consider the "vault_info.txt" file for vault generation.
22- *
23- * In this file, we use the "special" granite and perma-wall sub-types,
24- * where "basic" is normal, "inner" is inside a room, "outer" is the
25- * outer wall of a room, and "solid" is the outer wall of the dungeon
26- * or any walls that may not be pierced by corridors. Thus the only
27- * wall type that may be pierced by a corridor is the "outer granite"
28- * type. The "basic granite" type yields the "actual" corridors.
29- *
30- * Note that we use the special "solid" granite wall type to prevent
31- * multiple corridors from piercing a wall in two adjacent locations,
32- * which would be messy, and we use the special "outer" granite wall
33- * to indicate which walls "surround" rooms, and may thus be "pierced"
34- * by corridors entering or leaving the room.
35- *
36- * Note that a tunnel which attempts to leave a room near the "edge"
37- * of the dungeon in a direction toward that edge will cause "silly"
38- * wall piercings, but will have no permanently incorrect effects,
39- * as long as the tunnel can *eventually* exit from another side.
40- * And note that the wall may not come back into the room by the
41- * hole it left through, so it must bend to the left or right and
42- * then optionally re-enter the room (at least 2 grids away). This
43- * is not a problem since every room that is large enough to block
44- * the passage of tunnels is also large enough to allow the tunnel
45- * to pierce the room itself several times.
46- *
47- * Note that no two corridors may enter a room through adjacent grids,
48- * they must either share an entryway or else use entryways at least
49- * two grids apart. This prevents "large" (or "silly") doorways.
50- *
51- * To create rooms in the dungeon, we first divide the dungeon up
52- * into "blocks" of 11x11 grids each, and require that all rooms
53- * occupy a rectangular group of blocks. As long as each room type
54- * reserves a sufficient number of blocks, the room building routines
55- * will not need to check bounds. Note that most of the normal rooms
56- * actually only use 23x11 grids, and so reserve 33x11 grids.
57- *
58- * Note that the use of 11x11 blocks (instead of the old 33x11 blocks)
59- * allows more variability in the horizontal placement of rooms, and
60- * at the same time has the disadvantage that some rooms (two thirds
61- * of the normal rooms) may be "split" by panel boundaries. This can
62- * induce a situation where a player is in a room and part of the room
63- * is off the screen. It may be annoying enough to go back to 33x11
64- * blocks to prevent this visual situation.
65- *
66- * Note that the dungeon generation routines are much different (2.7.5)
67- * and perhaps "DUN_ROOMS" should be less than 50.
68- *
69- * Note that it is possible to create a room which is only
70- * connected to itself, because the "tunnel generation" code allows a
71- * tunnel to leave a room, wander around, and then re-enter the room.
72- *
73- * Note that it is possible to create a set of rooms which
74- * are only connected to other rooms in that set, since there is nothing
75- * explicit in the code to prevent this from happening. But this is less
76- * likely than the "isolated room" problem, because each room attempts to
77- * connect to another room, in a giant cycle, thus requiring at least two
78- * bizarre occurances to create an isolated section of the dungeon.
79- *
80- * Note that (2.7.9) creature pits have been split into creature "nests"
81- * and creature "pits". The "nests" have a collection of creatures of a
82- * given type strewn randomly around the room (jelly, animal, or undead),
83- * while the "pits" have a collection of creatures of a given type placed
84- * around the room in an organized manner (orc, troll, giant, dragon, or
85- * demon). Note that both "nests" and "pits" are now "level dependant",
86- * and both make 16 "expensive" calls to the "get_species_num(floor_ptr, )" function.
87- *
88- * Note that the cave grid flags changed in a rather drastic manner
89- * for Angband 2.8.0 (and 2.7.9+), in particular, dungeon terrain
90- * features, such as doors and stairs and traps and rubble and walls,
91- * are all handled as a set of 64 possible "terrain features", and
92- * not as "fake" objects (440-479) as in pre-2.8.0 versions.
93- *
94- * The 64 new "dungeon features" will also be used for "visual display"
95- * but we must be careful not to allow, for example, the user to display
96- * hidden traps in a different way from floors, or secret doors in a way
97- * different from granite walls, or even permanent granite in a different
98- * way from granite.
99- */
100-
101-#include "angband.h"
102-#include "cave.h"
103-#include "creature_const.h"
104-#include "generate.h"
105-#include "grid.h"
106-#include "init.h"
107-#include "object.h"
108-#include "rooms.h"
109-#include "streams.h"
110-#include "diary.h"
111-#include "quest.h"
112-
113-int dun_tun_rnd;
114-int dun_tun_chg;
115-int dun_tun_con;
116-int dun_tun_pen;
117-int dun_tun_jct;
118-
119-
120-/*
121- * Dungeon generation data -- see "create_cave_structure()"
122- */
123-dun_data *dungeon_ptr;
124-
125-
126-// Count the number of walls adjacent to the given grid.
127-// Note -- Assumes "IN_BOUNDS(floor_ptr, y, x)"
128-// We count only granite walls and permanent walls.
129-static int next_to_walls(floor_type *floor_ptr, int y, int x)
130-{
131- int k = 0;
132- if(IN_BOUNDS(floor_ptr, y + 1, x) && is_extra_bold(floor_ptr, y + 1, x)) k++;
133- if(IN_BOUNDS(floor_ptr, y - 1, x) && is_extra_bold(floor_ptr, y - 1, x)) k++;
134- if(IN_BOUNDS(floor_ptr, y, x + 1) && is_extra_bold(floor_ptr, y, x + 1)) k++;
135- if(IN_BOUNDS(floor_ptr, y, x - 1) && is_extra_bold(floor_ptr, y, x - 1)) k++;
136- return (k);
137-}
138-
139-
140-// Helper function for alloc_stairs().
141-// Is this a good location for stairs?
142-static bool alloc_stairs_aux(floor_type *floor_ptr, int y, int x, int walls)
143-{
144- /* Access the grid */
145- cave_type *c_ptr = &floor_ptr->cave[y][x];
146-
147- /* Require "naked" floor grid */
148- if(!is_floor_grid(c_ptr)) return FALSE;
149- if(pattern_tile(floor_ptr, y, x)) return FALSE;
150- if(c_ptr->object_idx || c_ptr->creature_idx) return FALSE;
151-
152- /* Require a certain number of adjacent walls */
153- if(next_to_walls(floor_ptr, y, x) < walls) return FALSE;
154-
155- return TRUE;
156-}
157-
158-
159-/*
160- * Places some staircases near walls
161- */
162-static bool alloc_stairs(floor_type *floor_ptr, FEATURE_ID feat, int num, int walls)
163-{
164- int i;
165- int shaft_num = 0;
166-
167- feature_type *f_ptr = &feature_info[feat];
168-
169- if(have_flag(f_ptr->flags, FF_LESS))
170- {
171- if(ironman_downward || !floor_ptr->depth) return TRUE; /* No up stairs in town or in ironman mode */
172- if(floor_ptr->depth > dungeon_info[floor_ptr->dungeon_id].mindepth) shaft_num = (randint1(num+1))/2;
173- }
174- else if(have_flag(f_ptr->flags, FF_MORE))
175- {
176- int q_idx = quest_number(floor_ptr);
177- if(floor_ptr->depth > 1 && q_idx) /* No downstairs on quest levels */
178- {
179- species_type *species_ptr = &species_info[quest[q_idx].species_idx];
180- if(!(has_trait_species(species_ptr, TRAIT_UNIQUE)) || 0 < species_ptr->max_num) return TRUE; /* The quest creature(s) is still alive? */
181- }
182-
183- if(floor_ptr->depth >= dungeon_info[floor_ptr->dungeon_id].maxdepth) return TRUE; /* No downstairs at the bottom */
184- if((floor_ptr->depth < dungeon_info[floor_ptr->dungeon_id].maxdepth-1)) //TODO !quest_number(floor_ptr->depth+1))
185- shaft_num = (randint1(num)+1)/2;
186- }
187- else return FALSE;
188-
189- /* Place "num" stairs */
190- for (i = 0; i < num; i++)
191- {
192- while (TRUE)
193- {
194- int y = 0, x = 0;
195- cave_type *c_ptr;
196-
197- int candidates = 0;
198- int pick;
199-
200- for (y = 1; y < floor_ptr->height - 1; y++)
201- {
202- for (x = 1; x < floor_ptr->width - 1; x++)
203- {
204- if(alloc_stairs_aux(floor_ptr, y, x, walls)) candidates++; /* A valid space found */
205- }
206- }
207-
208- if(!candidates) /* No valid place! */
209- {
210- if(walls <= 0) return FALSE; /* There are exactly no place! */
211- walls--; /* Decrease walls limit, and try again */
212- continue;
213- }
214-
215- pick = randint1(candidates); /* Choose a random one */
216-
217- for (y = 1; y < floor_ptr->height - 1; y++)
218- {
219- for (x = 1; x < floor_ptr->width - 1; x++)
220- {
221- if(alloc_stairs_aux(floor_ptr, y, x, walls))
222- {
223- pick--;
224- if(!pick) break; /* Is this a picked one? */
225- }
226- }
227- if(!pick) break;
228- }
229-
230- c_ptr = &floor_ptr->cave[y][x]; /* Access the grid */
231- c_ptr->mimic = 0; /* Clear possible garbage of hidden trap */
232- c_ptr->feat = (i < shaft_num) ? feat_state(floor_ptr, feat, FF_SHAFT) : feat; /* Clear previous contents, add stairs */
233- c_ptr->info &= ~(CAVE_FLOOR); /* No longer "FLOOR" */
234- break;
235- }
236- }
237- return TRUE;
238-}
239-
240-
241-/*
242- * Allocates some objects (using "place" and "type")
243- */
244-static void alloc_object(floor_type *floor_ptr, creature_type *player_ptr, int set, int typ, int num)
245-{
246- COODINATES y = 0, x = 0;
247- int dummy = 0, k;
248- cave_type *c_ptr;
249-
250- /* A small level has few objects. */
251- num = num * floor_ptr->height * floor_ptr->width / (MAX_HGT * MAX_WID) +1;
252-
253- /* Place some objects */
254- for (k = 0; k < num; k++)
255- {
256- /* Pick a "legal" spot */
257- while (dummy < SAFE_MAX_ATTEMPTS)
258- {
259- bool room;
260- dummy++;
261-
262- y = (COODINATES)randint0(floor_ptr->height);
263- x = (COODINATES)randint0(floor_ptr->width);
264-
265- c_ptr = &floor_ptr->cave[y][x];
266-
267- if(!is_floor_grid(c_ptr) || c_ptr->object_idx || c_ptr->creature_idx) continue; /* Require "naked" floor grid */
268- if(CREATURE_BOLD(player_ptr, y, x)) continue; /* Avoid player location */
269- room = (floor_ptr->cave[y][x].info & CAVE_ROOM) ? TRUE : FALSE; /* Check for "room" */
270- if((set == ALLOC_SET_CORR) && room) continue; /* Require corridor? */
271- if((set == ALLOC_SET_ROOM) && !room) continue; /* Require room? */
272- break; /* Accept it */
273- }
274-
275- if(dummy >= SAFE_MAX_ATTEMPTS)
276- {
277- if(cheat_room) msg_warning(MES_DEBUG_DISABLE_ITEM);
278- return;
279- }
280-
281-
282- /* Place something */
283- switch (typ)
284- {
285- case ALLOC_TYP_RUBBLE:
286- place_rubble(floor_ptr, y, x);
287- floor_ptr->cave[y][x].info &= ~(CAVE_FLOOR);
288- break;
289-
290- case ALLOC_TYP_TRAP:
291- place_trap(floor_ptr, y, x);
292- floor_ptr->cave[y][x].info &= ~(CAVE_FLOOR);
293- break;
294-
295- case ALLOC_TYP_GOLD:
296- place_gold(floor_ptr, y, x);
297- break;
298-
299- case ALLOC_TYP_OBJECT:
300- place_object(floor_ptr, y, x, 0L);
301- break;
302- }
303- }
304-}
305-
306-
307-/*
308- * Count the number of "corridor" grids adjacent to the given grid.
309- *
310- * Note -- Assumes "IN_BOUNDS(floor_ptr, y1, x1)"
311- *
312- * This routine currently only counts actual "empty floor"
313- * grids which are not in rooms. We might want to also count stairs,
314- * open doors, closed doors, etc.
315- */
316-static int next_to_corr(floor_type *floor_ptr, int y1, int x1)
317-{
318- int i, y, x, k = 0;
319-
320- cave_type *c_ptr;
321-
322- /* Scan adjacent grids */
323- for (i = 0; i < 4; i++)
324- {
325- /* Extract the location */
326- y = y1 + ddy_ddd[i];
327- x = x1 + ddx_ddd[i];
328-
329- /* Access the grid */
330- c_ptr = &floor_ptr->cave[y][x];
331-
332- /* Skip non floors */
333- if(CAVE_HAVE_FLAG_GRID(c_ptr, FF_WALL)) continue;
334-
335- /* Skip non "empty floor" grids */
336- if(!is_floor_grid(c_ptr)) continue;
337-
338- /* Skip grids inside rooms */
339- if(c_ptr->info & (CAVE_ROOM)) continue;
340-
341- /* Count these grids */
342- k++;
343- }
344-
345- /* Return the number of corridors */
346- return (k);
347-}
348-
349-
350-/*
351- * Determine if the given location is "between" two walls,
352- * and "next to" two corridor spaces.
353- *
354- * Assumes "IN_BOUNDS(floor_ptr, y, x)"
355- */
356-static bool possible_doorway(floor_type *floor_ptr, int y, int x)
357-{
358- /* Count the adjacent corridors */
359- if(next_to_corr(floor_ptr, y, x) >= 2)
360- {
361- /* Check Vertical */
362- if(CAVE_HAVE_FLAG_BOLD(floor_ptr, y - 1, x, FF_WALL) &&
363- CAVE_HAVE_FLAG_BOLD(floor_ptr, y + 1, x, FF_WALL))
364- {
365- return TRUE;
366- }
367-
368- /* Check Horizontal */
369- if(CAVE_HAVE_FLAG_BOLD(floor_ptr, y, x - 1, FF_WALL) &&
370- CAVE_HAVE_FLAG_BOLD(floor_ptr, y, x + 1, FF_WALL))
371- {
372- return TRUE;
373- }
374- }
375-
376- /* No doorway */
377- return FALSE;
378-}
379-
380-
381-
382-// Places door at y, x position if at least 2 walls found
383-static void try_door(floor_type *floor_ptr, int y, int x)
384-{
385-
386- if(!IN_BOUNDS(floor_ptr, y, x)) return;
387- if(CAVE_HAVE_FLAG_BOLD(floor_ptr, y, x, FF_WALL)) return; // Ignore walls
388-
389- /* Ignore room grids */
390- if(floor_ptr->cave[y][x].info & (CAVE_ROOM)) return;
391-
392- /* Occasional door (if allowed) */
393- if((randint0(100) < dun_tun_jct) && possible_doorway(floor_ptr, y, x) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_NO_DOORS))
394- place_random_door(floor_ptr, y, x, FALSE);
395-}
396-
397-
398-/*
399- * Set boundary mimic and add "solid" perma-wall
400- */
401-static void set_bound_perm_wall(cave_type *c_ptr)
402-{
403- if(bound_walls_perm)
404- {
405- /* Clear boundary mimic */
406- c_ptr->mimic = 0;
407- }
408- else
409- {
410- feature_type *f_ptr = &feature_info[c_ptr->feat];
411-
412- /* Hack -- Decline boundary walls with known treasure */
413- if((have_flag(f_ptr->flags, FF_HAS_GOLD) || have_flag(f_ptr->flags, FF_HAS_ITEM)) &&
414- !have_flag(f_ptr->flags, FF_SECRET))
415- c_ptr->feat = feat_state(CURRENT_FLOOR_PTR, c_ptr->feat, FF_ENSECRET);
416-
417- /* Set boundary mimic */
418- c_ptr->mimic = c_ptr->feat;
419- }
420-
421- /* Add "solid" perma-wall */
422- place_solid_perm_grid(c_ptr);
423-}
424-
425-
426-
427-// Generate various caverns and lakes
428-// There were moved from create_cave_structure().
429-static void generate_caverns_and_lakes(floor_type *floor_ptr)
430-{
431- /* Possible "destroyed" level */
432- if((floor_ptr->depth > 30) && one_in_(DUN_DEST*2) && (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_DESTROY))
433- {
434- dungeon_ptr->destroyed = TRUE;
435-
436- /* extra rubble around the place looks cool */
437- build_lake(floor_ptr, one_in_(2) ? LAKE_T_CAVE : LAKE_T_EARTH_VAULT);
438- }
439-
440- /* Make a lake some of the time */
441- if(one_in_(LAKE_LEVEL) && !dungeon_ptr->empty_level && !dungeon_ptr->destroyed &&
442- (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_MASK))
443- {
444- int count = 0;
445- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_WATER) count += 3;
446- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_LAVA) count += 3;
447- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_RUBBLE) count += 3;
448- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_TREE) count += 3;
449-
450- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_LAVA)
451- {
452- /* Lake of Lava */
453- if((floor_ptr->depth > 80) && (randint0(count) < 2)) dungeon_ptr->laketype = LAKE_T_LAVA;
454- count -= 2;
455-
456- /* Lake of Lava2 */
457- if(!dungeon_ptr->laketype && (floor_ptr->depth > 80) && one_in_(count)) dungeon_ptr->laketype = LAKE_T_FIRE_VAULT;
458- count--;
459- }
460-
461- if((dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_WATER) && !dungeon_ptr->laketype)
462- {
463- /* Lake of Water */
464- if((floor_ptr->depth > 50) && randint0(count) < 2) dungeon_ptr->laketype = LAKE_T_WATER;
465- count -= 2;
466-
467- /* Lake of Water2 */
468- if(!dungeon_ptr->laketype && (floor_ptr->depth > 50) && one_in_(count)) dungeon_ptr->laketype = LAKE_T_WATER_VAULT;
469- count--;
470- }
471-
472- if((dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_RUBBLE) && !dungeon_ptr->laketype)
473- {
474- /* Lake of rubble */
475- if((floor_ptr->depth > 35) && (randint0(count) < 2)) dungeon_ptr->laketype = LAKE_T_CAVE;
476- count -= 2;
477-
478- /* Lake of rubble2 */
479- if(!dungeon_ptr->laketype && (floor_ptr->depth > 35) && one_in_(count)) dungeon_ptr->laketype = LAKE_T_EARTH_VAULT;
480- count--;
481- }
482-
483- /* Lake of tree */
484- if((floor_ptr->depth > 5) && (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_TREE) && !dungeon_ptr->laketype) dungeon_ptr->laketype = LAKE_T_AIR_VAULT;
485-
486- if(dungeon_ptr->laketype)
487- {
488- if(cheat_room) msg_print(MES_DEBUG_LAKE);
489- build_lake(floor_ptr, dungeon_ptr->laketype);
490- }
491- }
492-
493- if((floor_ptr->depth > DUN_CAVERN) && !dungeon_ptr->empty_level &&
494- (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_CAVERN) &&
495- !dungeon_ptr->laketype && !dungeon_ptr->destroyed && (randint1(1000) < floor_ptr->depth))
496- {
497- dungeon_ptr->cavern = TRUE;
498-
499- /* make a large fractal cave in the middle of the dungeon */
500-
501- if(cheat_room) msg_print(MES_DEBUG_CAVE);
502- build_cavern(floor_ptr);
503- }
504-
505- /* Hack -- No destroyed "quest" levels */
506- if(quest_number(floor_ptr)) dungeon_ptr->destroyed = FALSE;
507-}
508-
509-
510-
511-/*
512- * Generate a new dungeon level
513- *
514- * Note that "dun_body" adds about 4000 bytes of memory to the stack.
515- */
516-static bool create_cave_structure(floor_type *floor_ptr)
517-{
518- int i, k;
519- COODINATES y, x;
520- dun_data dun_body;
521-
522- // Global data
523- dungeon_ptr = &dun_body;
524-
525- dungeon_ptr->destroyed = FALSE;
526- dungeon_ptr->empty_level = FALSE;
527- dungeon_ptr->cavern = FALSE;
528- dungeon_ptr->laketype = 0;
529-
530- // Fill the arrays of floors and walls in the good proportions
531- set_floor_and_wall(floor_ptr->dungeon_id);
532-
533- // Prepare allocation table
534- //TODO get_creature_list_terrain()
535-
536- // Randomize the dungeon creation values
537- dun_tun_rnd = rand_range(DUN_TUN_RND_MIN, DUN_TUN_RND_MAX);
538- dun_tun_chg = rand_range(DUN_TUN_CHG_MIN, DUN_TUN_CHG_MAX);
539- dun_tun_con = rand_range(DUN_TUN_CON_MIN, DUN_TUN_CON_MAX);
540- dun_tun_pen = rand_range(DUN_TUN_PEN_MIN, DUN_TUN_PEN_MAX);
541- dun_tun_jct = rand_range(DUN_TUN_JCT_MIN, DUN_TUN_JCT_MAX);
542-
543- // Actual maximum number of rooms on this level
544- dungeon_ptr->row_rooms = floor_ptr->height / BLOCK_HGT;
545- dungeon_ptr->col_rooms = floor_ptr->width / BLOCK_WID;
546-
547- // Initialize the room table
548- for (y = 0; y < dungeon_ptr->row_rooms; y++)
549- {
550- for (x = 0; x < dungeon_ptr->col_rooms; x++)
551- {
552- dungeon_ptr->room_map[y][x] = FALSE;
553- }
554- }
555-
556- // No rooms yet
557- dungeon_ptr->cent_n = 0;
558-
559- // Empty arena levels
560- if(ironman_empty_levels || ((dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_ARENA) && (empty_levels && one_in_(EMPTY_LEVEL))))
561- {
562- dungeon_ptr->empty_level = TRUE;
563- if(cheat_room) msg_print(MES_DEBUG_ARENA);
564- }
565-
566- if(dungeon_ptr->empty_level)
567- {
568- // Start with floors
569- for (y = 0; y < floor_ptr->height; y++)
570- {
571- for (x = 0; x < floor_ptr->width; x++)
572- {
573- place_floor_bold(floor_ptr, y, x);
574- }
575- }
576-
577- // Special boundary walls -- Top and bottom
578- for (x = 0; x < floor_ptr->width; x++)
579- {
580- place_extra_bold(floor_ptr, 0, x);
581- place_extra_bold(floor_ptr, floor_ptr->height - 1, x);
582- }
583-
584- // Special boundary walls -- Left and right
585- for (y = 1; y < (floor_ptr->height - 1); y++)
586- {
587- place_extra_bold(floor_ptr, y, 0);
588- place_extra_bold(floor_ptr, y, floor_ptr->width - 1);
589- }
590- }
591- else
592- {
593- // Start with walls
594- for (y = 0; y < floor_ptr->height; y++)
595- {
596- for (x = 0; x < floor_ptr->width; x++)
597- {
598- place_extra_bold(floor_ptr, y, x);
599- }
600- }
601- }
602-
603- // Generate various caverns and lakes
604- generate_caverns_and_lakes(floor_ptr);
605-
606- // Build maze
607- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_MAZE)
608- {
609- build_maze_vault(floor_ptr, floor_ptr->width / 2 - 1, floor_ptr->height / 2 - 1, floor_ptr->width - 4, floor_ptr->height - 4, FALSE);
610-
611- /* Place stairs */
612- if(!alloc_stairs(floor_ptr, feat_down_stair, rand_range(2, 3), 3)) return FALSE;
613- if(!alloc_stairs(floor_ptr, feat_up_stair, 1, 3)) return FALSE;
614- }
615-
616- // Build some rooms
617- else
618- {
619- int tunnel_fail_count = 0;
620-
621- // Build each type of room in turn until we cannot build any more.
622- if(!generate_rooms(floor_ptr))
623- return FALSE;
624-
625-
626- /* Make a hole in the dungeon roof sometimes at level 1 */
627- if(floor_ptr->depth == 1)
628- {
629- while (one_in_(DUN_MOS_DEN))
630- place_trees(floor_ptr, (COODINATES)randint1(floor_ptr->width - 2), (COODINATES)randint1(floor_ptr->height - 2));
631- }
632-
633- /* Destroy the level if necessary */
634- if(dungeon_ptr->destroyed) destroy_level(floor_ptr);
635-
636- /* Hack -- Add some rivers */
637- if(one_in_(3) && (randint1(floor_ptr->depth) > 5))
638- {
639- FEATURE_ID feat1 = 0, feat2 = 0;
640-
641- /* Choose water or lava or poison swamp*/
642- if((randint1(MAX_DEPTH * 2) - 1 > floor_ptr->depth) && (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_WATER_RIVER))
643- {
644- feat1 = feat_deep_water;
645- feat2 = feat_shallow_water;
646- }
647- else if (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAVA_RIVER & one_in_(3))
648- {
649- feat1 = feat_deep_lava;
650- feat2 = feat_shallow_lava;
651- }
652- else if (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_POISON_RIVER & one_in_(2))
653- {
654- feat1 = feat_deep_poison;
655- feat2 = feat_shallow_poison;
656- }
657- else if (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_ACID_RIVER)
658- {
659- feat1 = feat_deep_acid;
660- feat2 = feat_shallow_acid;
661- }
662- else feat1 = 0;
663-
664- if(feat1)
665- {
666- feature_type *f_ptr = &feature_info[feat1];
667-
668- /* Only add river if matches lake type or if have no lake at all */
669- if(((dungeon_ptr->laketype == LAKE_T_LAVA) && have_flag(f_ptr->flags, FF_LAVA)) ||
670- ((dungeon_ptr->laketype == LAKE_T_WATER) && have_flag(f_ptr->flags, FF_WATER)) ||
671- !dungeon_ptr->laketype)
672- {
673- add_river(floor_ptr, feat1, feat2);
674- }
675- }
676- }
677-
678- /* Hack -- Scramble the room order */
679- for (i = 0; i < dungeon_ptr->cent_n; i++)
680- {
681- COODINATES ty, tx;
682- int pick = rand_range(0, i);
683-
684- ty = dungeon_ptr->cent[i].y;
685- tx = dungeon_ptr->cent[i].x;
686- dungeon_ptr->cent[i].y = dungeon_ptr->cent[pick].y;
687- dungeon_ptr->cent[i].x = dungeon_ptr->cent[pick].x;
688- dungeon_ptr->cent[pick].y = ty;
689- dungeon_ptr->cent[pick].x = tx;
690- }
691-
692- /* Start with no tunnel doors */
693- dungeon_ptr->door_n = 0;
694-
695- /* Hack -- connect the first room to the last room */
696- y = dungeon_ptr->cent[dungeon_ptr->cent_n-1].y;
697- x = dungeon_ptr->cent[dungeon_ptr->cent_n-1].x;
698-
699- /* Connect all the rooms together */
700- for (i = 0; i < dungeon_ptr->cent_n; i++)
701- {
702- int j;
703-
704- /* Reset the arrays */
705- dungeon_ptr->tunn_n = 0;
706- dungeon_ptr->wall_n = 0;
707-
708- /* Connect the room to the previous room */
709- if(randint1(floor_ptr->depth) > dungeon_info[floor_ptr->dungeon_id].tunnel_percent)
710- {
711- /* make cave-like tunnel */
712- (void)build_tunnel2(floor_ptr, dungeon_ptr->cent[i].x, dungeon_ptr->cent[i].y, x, y, 2, 2);
713- }
714- else
715- {
716- /* make normal tunnel */
717- if(!build_tunnel(floor_ptr, dungeon_ptr->cent[i].y, dungeon_ptr->cent[i].x, y, x)) tunnel_fail_count++;
718- }
719-
720- if(tunnel_fail_count >= 2) return FALSE;
721-
722- /* Turn the tunnel into corridor */
723- for (j = 0; j < dungeon_ptr->tunn_n; j++)
724- {
725- cave_type *c_ptr;
726- feature_type *f_ptr;
727-
728- /* Access the grid */
729- y = dungeon_ptr->tunn[j].y;
730- x = dungeon_ptr->tunn[j].x;
731-
732- /* Access the grid */
733- c_ptr = &floor_ptr->cave[y][x];
734- f_ptr = &feature_info[c_ptr->feat];
735-
736- /* Clear previous contents (if not a lake), add a floor */
737- if(!have_flag(f_ptr->flags, FF_MOVE) || (!have_flag(f_ptr->flags, FF_WATER) && !have_flag(f_ptr->flags, FF_LAVA)))
738- {
739- /* Clear mimic type */
740- c_ptr->mimic = 0;
741-
742- place_floor_grid(c_ptr);
743- }
744- }
745-
746- /* Apply the piercings that we found */
747- for (j = 0; j < dungeon_ptr->wall_n; j++)
748- {
749- cave_type *c_ptr;
750-
751- /* Access the grid */
752- y = dungeon_ptr->wall[j].y;
753- x = dungeon_ptr->wall[j].x;
754-
755- /* Access the grid */
756- c_ptr = &floor_ptr->cave[y][x];
757-
758- /* Clear mimic type */
759- c_ptr->mimic = 0;
760-
761- /* Clear previous contents, add up floor */
762- place_floor_grid(c_ptr);
763-
764- /* Occasional doorway */
765- if((randint0(100) < dun_tun_pen) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_NO_DOORS))
766- {
767- /* Place a random door */
768- place_random_door(floor_ptr, y, x, TRUE);
769- }
770- }
771-
772- /* Remember the "previous" room */
773- y = dungeon_ptr->cent[i].y;
774- x = dungeon_ptr->cent[i].x;
775- }
776-
777- /* Place intersection doors */
778- for (i = 0; i < dungeon_ptr->door_n; i++)
779- {
780- /* Extract junction location */
781- y = dungeon_ptr->door[i].y;
782- x = dungeon_ptr->door[i].x;
783-
784- /* Try placing doors */
785- try_door(floor_ptr, y, x - 1);
786- try_door(floor_ptr, y, x + 1);
787- try_door(floor_ptr, y - 1, x);
788- try_door(floor_ptr, y + 1, x);
789- }
790-
791- // Place some down stairs near some walls
792- if(!alloc_stairs(floor_ptr, feat_down_stair, rand_range(1, 4) + (floor_ptr->width / SCREEN_WID * floor_ptr->height / SCREEN_HGT) / 8, 3)) return FALSE;
793-
794- // Place some up stairs near some walls
795- if(!alloc_stairs(floor_ptr, feat_up_stair, rand_range(1, 4) + (floor_ptr->width / SCREEN_WID * floor_ptr->height / SCREEN_HGT) / 8, 3)) return FALSE;
796- }
797-
798- if(!dungeon_ptr->laketype)
799- {
800- if(dungeon_info[floor_ptr->dungeon_id].stream2)
801- {
802- // Hack -- Add some quartz streamers
803- for (i = 0; i < DUN_STR_QUA; i++)
804- {
805- build_streamer(floor_ptr, dungeon_info[floor_ptr->dungeon_id].stream2, DUN_STR_QC);
806- }
807- }
808-
809- if(dungeon_info[floor_ptr->dungeon_id].stream1)
810- {
811- // Hack -- Add some magma streamers
812- for (i = 0; i < DUN_STR_MAG; i++)
813- {
814- build_streamer(floor_ptr, dungeon_info[floor_ptr->dungeon_id].stream1, DUN_STR_MC);
815- }
816- }
817- }
818-
819- // Special boundary walls -- Top and bottom
820- for (x = 0; x < floor_ptr->width; x++)
821- {
822- set_bound_perm_wall(&floor_ptr->cave[0][x]);
823- set_bound_perm_wall(&floor_ptr->cave[floor_ptr->height - 1][x]);
824- }
825-
826- // Special boundary walls -- Left and right
827- for (y = 1; y < (floor_ptr->height - 1); y++)
828- {
829- set_bound_perm_wall(&floor_ptr->cave[y][0]);
830- set_bound_perm_wall(&floor_ptr->cave[y][floor_ptr->width - 1]);
831- }
832-
833- if(!place_quest_creatures(floor_ptr, player_ptr)) return FALSE; // Set Quest Creature
834-
835- // Basic "amount"
836- k = (floor_ptr->depth / 3);
837- if(k > 10) k = 10;
838- if(k < 2) k = 2;
839-
840- // Pick a base number of creatures
841- i = dungeon_info[floor_ptr->dungeon_id].min_m_alloc_level;
842-
843- // To make small levels a bit more playable
844- if(floor_ptr->height < MAX_HGT || floor_ptr->width < MAX_WID)
845- {
846- int small_tester = i;
847-
848- i = (i * floor_ptr->height) / MAX_HGT;
849- i = (i * floor_ptr->width) / MAX_WID;
850- i += 1;
851-
852- if(i > small_tester) i = small_tester;
853- else if(cheat_hear) msg_format(MES_DEBUG_DEC_CREATURE(small_tester, i));
854- }
855-
856- // Put some creatures in the dungeon
857- i += randint1(8);
858- for (i = i + k; i > 0; i--) (void)alloc_creature(floor_ptr, player_ptr->fy, player_ptr->fx, 0, PC_ALLOW_SLEEP);
859-
860- // Place some traps in the dungeon
861- alloc_object(floor_ptr, player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(k));
862-
863- // Put some rubble in corridors (except NO_CAVE dungeon (Castle))
864- if(!(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_NO_CAVE)) alloc_object(floor_ptr, player_ptr, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k));
865-
866- // Mega Hack -- No object at first level of deeper dungeon
867- if(player_ptr->enter_dungeon && floor_ptr->depth > 1) floor_ptr->object_level = 1; // No stair scum!
868-
869- // Put some objects in rooms
870- alloc_object(floor_ptr, player_ptr, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
871-
872- // Put some objects/gold in the dungeon
873- alloc_object(floor_ptr, player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
874- alloc_object(floor_ptr, player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
875-
876- floor_ptr->object_level = floor_ptr->depth; // Set back to default
877-
878- if(!alloc_guardian(floor_ptr, TRUE)) return FALSE; // Put the Guardian
879-
880- if(dungeon_ptr->empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > floor_ptr->depth)) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_DARKNESS))
881- {
882- // Lite the cave
883- for (y = 0; y < floor_ptr->height; y++)
884- {
885- for (x = 0; x < floor_ptr->width; x++)
886- {
887- floor_ptr->cave[y][x].info |= (CAVE_GLOW);
888- }
889- }
890- }
891-
892- return TRUE;
893-}
894-
895-
896-/*
897- * Builds the arena after it is entered -KMW-
898- */
899-static void build_arena(floor_type *floor_ptr, int height, int width)
900-{
901- int yval, y_height, y_depth, xval, x_left, x_right;
902- register int i, j;
903-
904- yval = height/ 2;
905- xval = width / 2;
906- y_height = yval - 10;
907- y_depth = yval + 10;
908- x_left = xval - 32;
909- x_right = xval + 32;
910-
911- for (i = y_height; i <= y_height + 5; i++)
912- for (j = x_left; j <= x_right; j++)
913- {
914- place_extra_perm_bold(floor_ptr, i, j);
915- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
916- }
917- for (i = y_depth; i >= y_depth - 5; i--)
918- for (j = x_left; j <= x_right; j++)
919- {
920- place_extra_perm_bold(floor_ptr, i, j);
921- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
922- }
923- for (j = x_left; j <= x_left + 17; j++)
924- for (i = y_height; i <= y_depth; i++)
925- {
926- place_extra_perm_bold(floor_ptr, i, j);
927- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
928- }
929- for (j = x_right; j >= x_right - 17; j--)
930- for (i = y_height; i <= y_depth; i++)
931- {
932- place_extra_perm_bold(floor_ptr, i, j);
933- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
934- }
935-
936- place_extra_perm_bold(floor_ptr, y_height+6, x_left+18);
937- floor_ptr->cave[y_height+6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
938- place_extra_perm_bold(floor_ptr, y_depth-6, x_left+18);
939- floor_ptr->cave[y_depth-6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
940- place_extra_perm_bold(floor_ptr, y_height+6, x_right-18);
941- floor_ptr->cave[y_height+6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
942- place_extra_perm_bold(floor_ptr, y_depth-6, x_right-18);
943- floor_ptr->cave[y_depth-6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
944-
945- i = y_height + 5;
946- j = xval;
947- floor_ptr->cave[i][j].feat = feature_tag_to_index("ARENA_GATE");
948- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
949- move_creature(player_ptr, floor_ptr, i, j, 0);
950-}
951-
952-
953-/*
954- * Town logic flow for generation of arena -KMW-
955- */
956-void generate_floor_arena(floor_type *floor_ptr, COODINATES height, COODINATES width)
957-{
958- COODINATES y, x;
959- COODINATES qy = 0, qx = 0;
960- floor_ptr->generate_type = F_GENE_FIGHTING_ARENA;
961-
962- // Small area
963- floor_ptr->height = height;
964- floor_ptr->width = width;
965-
966- // Start with solid walls
967- for (y = 0; y < height; y++)
968- {
969- for (x = 0; x < width; x++)
970- {
971- place_solid_perm_bold(floor_ptr, y, x); // Create "solid" perma-wall
972- floor_ptr->cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); // Illuminate and memorize the walls
973- }
974- }
975-
976- // Then place some floors
977- for (y = qy + 1; y < qy + height - 1; y++)
978- for (x = qx + 1; x < qx + width - 1; x++)
979- floor_ptr->cave[y][x].feat = feat_floor; // Create empty floor
980-
981- build_arena(floor_ptr, height, width);
982- place_creature_fixed_species(player_ptr, floor_ptr, player_ptr->fy + 5, player_ptr->fx, arena_info[arena_number].species_idx, (PC_NO_KAGE | PC_NO_PET));
983-}
984-
985-
986-
987-/*
988- * Builds the arena after it is entered -KMW-
989- */
990-static void build_battle(floor_type *floor_ptr, creature_type *player_ptr)
991-{
992- int yval, y_height, y_depth, xval, x_left, x_right;
993- register int i, j;
994-
995- yval = SCREEN_HGT / 2;
996- xval = SCREEN_WID / 2;
997- y_height = yval - 10;
998- y_depth = yval + 10;
999- x_left = xval - 32;
1000- x_right = xval + 32;
1001-
1002- for (i = y_height; i <= y_height + 5; i++)
1003- for (j = x_left; j <= x_right; j++)
1004- {
1005- place_extra_perm_bold(floor_ptr, i, j);
1006- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1007- }
1008- for (i = y_depth; i >= y_depth - 3; i--)
1009- for (j = x_left; j <= x_right; j++)
1010- {
1011- place_extra_perm_bold(floor_ptr, i, j);
1012- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1013- }
1014- for (j = x_left; j <= x_left + 17; j++)
1015- for (i = y_height; i <= y_depth; i++)
1016- {
1017- place_extra_perm_bold(floor_ptr, i, j);
1018- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1019- }
1020- for (j = x_right; j >= x_right - 17; j--)
1021- for (i = y_height; i <= y_depth; i++)
1022- {
1023- place_extra_perm_bold(floor_ptr, i, j);
1024- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1025- }
1026-
1027- place_extra_perm_bold(floor_ptr, y_height+6, x_left+18);
1028- floor_ptr->cave[y_height+6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
1029- place_extra_perm_bold(floor_ptr, y_depth-4, x_left+18);
1030- floor_ptr->cave[y_depth-4][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
1031- place_extra_perm_bold(floor_ptr, y_height+6, x_right-18);
1032- floor_ptr->cave[y_height+6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
1033- place_extra_perm_bold(floor_ptr, y_depth-4, x_right-18);
1034- floor_ptr->cave[y_depth-4][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
1035-
1036- for (i = y_height + 1; i <= y_height + 5; i++)
1037- for (j = x_left + 20 + 2 * (y_height + 5 - i); j <= x_right - 20 - 2 * (y_height + 5 - i); j++)
1038- {
1039- floor_ptr->cave[i][j].feat = feat_permanent_glass_wall;
1040- }
1041-
1042- i = y_height + 1;
1043- j = xval;
1044- floor_ptr->cave[i][j].feat = feature_tag_to_index("BUILDING_3");
1045- floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1046- move_creature(player_ptr, floor_ptr, i, j, 0);
1047-}
1048-
1049-
1050-/*
1051- * Town logic flow for generation of arena -KMW-
1052- */
1053-void generate_floor_creature_arena(floor_type *floor_ptr)
1054-{
1055- COODINATES y, x;
1056- COODINATES qy = 0, qx = 0;
1057- int i;
1058- floor_ptr->generate_type = F_GENE_GAMBLE_ARENA;
1059-
1060- // Start with solid walls
1061- for (y = 0; y < MAX_HGT; y++)
1062- {
1063- for (x = 0; x < MAX_WID; x++)
1064- {
1065- place_solid_perm_bold(floor_ptr, y, x); // Create "solid" perma-wall
1066- floor_ptr->cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); // Illuminate and memorize the walls
1067- }
1068- }
1069-
1070- // Then place some floors
1071- for (y = qy + 1; y < qy + SCREEN_HGT - 1; y++)
1072- for (x = qx + 1; x < qx + SCREEN_WID - 1; x++)
1073- floor_ptr->cave[y][x].feat = feat_floor; // Create empty floor
1074-
1075- build_battle(floor_ptr, player_ptr);
1076-
1077- for(i = 0; i < 4;i ++)
1078- {
1079- place_creature_fixed_species(player_ptr, floor_ptr, player_ptr->fy + 8 + (i / 2) * 4, player_ptr->fx - 2 + (i % 2) * 4, battle_creature[i], (PC_NO_KAGE | PC_NO_PET));
1080- //TODO set_camp(&creature_list[floor_ptr->cave[player_ptr->fy + 8 + (i / 2) * 4][player_ptr->fx - 2 + (i % 2) * 4].creature_idx]);
1081- }
1082-
1083- for(i = 1; i < creature_max; i++)
1084- {
1085- creature_type *m_ptr = &creature_list[i];
1086- if(!is_valid_creature(m_ptr)) continue;
1087- m_ptr->sc_flag2 |= (SC_FLAG2_MARK | SC_FLAG2_SHOW); // Hack -- Detect creature
1088- update_creature_view(player_ptr, i, FALSE); // Update the creature
1089- }
1090-}
1091-
1092-/* Generate a quest level */
1093-void generate_floor_quest(floor_type *floor_ptr, QUEST_ID quest_id)
1094-{
1095- int x, y;
1096- floor_ptr->generate_type = F_GENE_QUEST;
1097-
1098- /* Start with perm walls */
1099- for (y = 0; y < floor_ptr->height; y++)
1100- {
1101- for (x = 0; x < floor_ptr->width; x++)
1102- {
1103- place_solid_perm_bold(floor_ptr, y, x);
1104- }
1105- }
1106-
1107- /* Set the quest level */
1108- floor_ptr->depth = quest[quest_id].level;
1109- floor_ptr->depth = floor_ptr->depth;
1110- floor_ptr->object_level = floor_ptr->depth;
1111- floor_ptr->enemy_level = floor_ptr->depth;
1112- floor_ptr->quest = quest_id;
1113-
1114- if(record_stair) write_diary(DIARY_TO_QUEST, quest_id, NULL);
1115-
1116- // Prepare allocation table
1117- //TODO get_creature_list_terrain()
1118- process_dungeon_file(floor_ptr, QUEST_INFO_FILE, 0, 0, MAX_HGT, MAX_WID, INIT_CREATE_DUNGEON | INIT_ASSIGN, quest_id);
1119-}
1120-
1121-// Generate a fortless level
1122-static void generate_floor_fortress(floor_type *floor_ptr, int type)
1123-{
1124- int x, y;
1125- floor_ptr->generate_type = F_GENE_FORTLESS;
1126-
1127- // Start with perm walls
1128- for (y = 0; y < floor_ptr->height; y++)
1129- {
1130- for (x = 0; x < floor_ptr->width; x++)
1131- {
1132- place_solid_perm_bold(floor_ptr, y, x);
1133- }
1134- }
1135-
1136- // Prepare allocation table
1137- //TODO get_creature_list_terrain()
1138- process_dungeon_file(floor_ptr, QUEST_INFO_FILE, 0, 0, MAX_HGT, MAX_WID, INIT_CREATE_DUNGEON | INIT_ASSIGN, type);
1139-}
1140-
1141-
1142-
1143-// Make a real level
1144-static bool generate_floor_dungeon(floor_type *floor_ptr, cptr *why)
1145-{
1146- int level_height, level_width, i;
1147-
1148- floor_ptr->generate_type = F_GENE_DUNGEON;
1149- i = 0;
1150- while(i < MAX_DUNEGON_FORTLESS)
1151- {
1152- int p = !one_in_(dungeon_info[floor_ptr->dungeon_id].vault_quest_probability[i]);
1153- if(dungeon_info[floor_ptr->dungeon_id].vault_quest_level[i] <= floor_ptr->depth && dungeon_info[floor_ptr->dungeon_id].vault_quest_level_max[i] >= floor_ptr->depth && !p) break;
1154- i++;
1155- }
1156-
1157- if(i != MAX_DUNEGON_FORTLESS)
1158- {
1159- if(cheat_room) msg_format("Fortless level -- type %d.", dungeon_info[floor_ptr->dungeon_id].vault_quest_type[i]);
1160- generate_floor_fortress(floor_ptr, dungeon_info[floor_ptr->dungeon_id].vault_quest_type[i]);
1161- return TRUE;
1162- }
1163-
1164- if((always_small_levels || ironman_small_levels || one_in_(SMALL_LEVEL) || (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_BEGINNER) ||
1165- (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_SMALLEST)) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_BIG))
1166- {
1167- if(cheat_room) msg_print(MES_DEBUG_SMALL_LEVEL);
1168-
1169- if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_SMALLEST)
1170- {
1171- level_height = MIN_SCREEN_HGT;
1172- level_width = MIN_SCREEN_WID;
1173- }
1174- else if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_BEGINNER)
1175- {
1176- level_height = rand_range(MIN_SCREEN_HGT, MAX_HGT / SCREEN_HGT / 4);
1177- level_width = rand_range(MIN_SCREEN_WID, MAX_WID / SCREEN_WID / 4);
1178- }
1179- else
1180- {
1181- level_height = rand_range(MIN_SCREEN_HGT, MAX_HGT / SCREEN_HGT / 3);
1182- level_width = rand_range(MIN_SCREEN_WID, MAX_WID / SCREEN_WID / 3);
1183- }
1184-
1185- floor_ptr->height = level_height * SCREEN_HGT;
1186- floor_ptr->width = level_width * SCREEN_WID;
1187-
1188- // Assume illegal panel
1189- panel_row_min = floor_ptr->height;
1190- panel_col_min = floor_ptr->width;
1191-
1192- }
1193- else
1194- {
1195- // Big dungeon
1196- do{
1197- level_height = rand_range(MAX_HGT / SCREEN_HGT / 3, MAX_HGT/SCREEN_HGT);
1198- level_width = rand_range(MAX_WID / SCREEN_WID / 3, MAX_WID/SCREEN_WID);
1199- } while (level_height + level_width < (MAX_HGT / SCREEN_HGT + MAX_WID / SCREEN_WID) / 2 || (level_height + level_width >= (MAX_HGT / SCREEN_HGT + MAX_WID / SCREEN_WID) * 3 / 4));
1200- floor_ptr->height = level_height * SCREEN_HGT;
1201- floor_ptr->width = level_width * SCREEN_WID;
1202-
1203- // Assume illegal panel
1204- panel_row_min = floor_ptr->height;
1205- panel_col_min = floor_ptr->width;
1206-
1207- }
1208- if(cheat_room) msg_format(MES_DEBUG_FLOOR_SIZE(floor_ptr->width, floor_ptr->height));
1209-
1210- // Make a dungeon
1211- if(!create_cave_structure(floor_ptr))
1212- {
1213- *why = MES_DEBUG_FAILED_FLOOR;
1214- return FALSE;
1215- }
1216-
1217- else return TRUE;
1218-}
1219-
1220-
1221-/*
1222- * Wipe all unnecessary flags after cave generation
1223- */
1224-void wipe_generate_floor_flags(floor_type *floor_ptr)
1225-{
1226- int x, y;
1227-
1228- for (y = 0; y < floor_ptr->height; y++)
1229- {
1230- for (x = 0; x < floor_ptr->width; x++)
1231- {
1232- floor_ptr->cave[y][x].info &= ~(CAVE_MASK); // Wipe unused flags
1233- }
1234- }
1235-
1236- if(floor_ptr->depth)
1237- {
1238- for (y = 1; y < floor_ptr->height - 1; y++)
1239- {
1240- for (x = 1; x < floor_ptr->width - 1; x++)
1241- {
1242- floor_ptr->cave[y][x].info |= CAVE_UNSAFE; // There might be trap
1243- }
1244- }
1245- }
1246-}
1247-
1248-// Clear and empty the cave
1249-void clear_cave(floor_type *floor_ptr)
1250-{
1251- int x, y;
1252-
1253- // Start with a blank cave
1254- for (y = 0; y < MAX_HGT; y++)
1255- {
1256- for (x = 0; x < MAX_WID; x++)
1257- {
1258- cave_type *c_ptr = &floor_ptr->cave[y][x];
1259-
1260- c_ptr->info = 0;
1261- c_ptr->feat = 0;
1262- c_ptr->object_idx = 0;
1263- c_ptr->creature_idx = 0;
1264- c_ptr->quest_idx = 0;
1265- c_ptr->town_idx = 0;
1266- c_ptr->to_floor = 0;
1267- c_ptr->mimic = 0;
1268- c_ptr->cost = 0;
1269- c_ptr->dist = 0;
1270- c_ptr->when = 0;
1271- c_ptr->message[0] = '\0';
1272- }
1273- }
1274-
1275- //TODO clear creatures and objects.
1276-
1277- // Set the base level
1278- floor_ptr->enemy_level = floor_ptr->depth;
1279- floor_ptr->object_level = floor_ptr->depth;
1280-}
1281-
1282-// Generates a random dungeon level -RAK-
1283-// Hack -- regenerate any "overflow" levels
1284-bool generate_floor(floor_type *floor_ptr, DUNGEON_ID dungeon_id, COODINATES world_y, COODINATES world_x, FLOOR_LEV depth)
1285-{
1286- int num;
1287-
1288- /* Prepare new floor data */
1289- floor_ptr->last_visit = 0;
1290- floor_ptr->generated = FALSE;
1291- floor_ptr->global_map = FALSE;
1292- floor_ptr->world_x = world_x;
1293- floor_ptr->world_y = world_y;
1294-
1295- floor_ptr->dungeon_id = dungeon_id;
1296-
1297- floor_ptr->depth = depth;
1298- floor_ptr->enemy_level = depth;
1299- floor_ptr->object_level = depth;
1300-
1301- floor_ptr->town_num = wilderness[world_y][world_x].town;
1302- floor_ptr->floor_turn = 1;
1303-
1304- // Fill the arrays of floors and walls in the good proportions
1305- set_floor_and_wall(floor_ptr->dungeon_id);
1306-
1307- // Generate
1308- if(depth <= 0) generate_floor_wilderness(floor_ptr);
1309- else
1310- {
1311- for (num = 0; TRUE; num++)
1312- {
1313- bool okay = TRUE;
1314- cptr why = NULL;
1315- clear_cave(floor_ptr); // Clear and empty the cave
1316-
1317- okay = generate_floor_dungeon(floor_ptr, &why);
1318-
1319- // Prevent object over-flow
1320- if(object_max >= max_object_idx)
1321- {
1322- why = MES_DEBUG_TOO_ITEM;
1323- okay = FALSE;
1324- }
1325- else if(creature_max >= max_creature_idx)
1326- {
1327- why = MES_DEBUG_TOO_CREATURE;
1328- okay = FALSE;
1329- }
1330-
1331- if(okay) break;
1332- if(why) msg_format(MES_DEBUG_FLOOR_RETAKE(why));
1333- wipe_object_list(0);
1334- wipe_creature_list(0);
1335- }
1336- }
1337-
1338- // Glow deep lava and building entrances
1339- glow_deep_lava_and_bldg(floor_ptr);
1340-
1341- // Reset flag
1342- player_ptr->enter_dungeon = FALSE;
1343- wipe_generate_floor_flags(floor_ptr);
1344-
1345- // Hack -- Munchkin characters always get whole map
1346- if(player_ptr->chara_idx == CHARA_MUNCHKIN) wiz_lite(floor_ptr, player_ptr, (bool)(player_ptr->class_idx == CLASS_NINJA));
1347-
1348- floor_ptr->generated = TRUE;
1349- return TRUE;
1350-}
--- source/trunk/src/externs.h (revision 9114)
+++ source/trunk/src/externs.h (revision 9115)
@@ -676,15 +676,7 @@
676676 extern void cast_shuffle(creature_type *caster_ptr);
677677 extern bool cast_summon_greater_demon(creature_type *creature_ptr);
678678
679-// generate.c
680-extern void wipe_generate_floor_flags(floor_type *floor_ptr);
681-extern void clear_cave(floor_type *floor_ptr);
682-extern bool generate_floor(floor_type *floor_ptr, DUNGEON_ID dungeon_id, COODINATES world_y, COODINATES world_x, FLOOR_LEV depth);
683-extern void generate_floor_quest(floor_type *floor_ptr, QUEST_ID quest_id);
684-extern void generate_floor_arena(floor_type *floor_ptr, COODINATES height, COODINATES width);
685-extern void generate_floor_creature_arena(floor_type *floor_ptr);
686679
687-
688680 // load.c
689681 extern errr rd_savefile_new(void);
690682 extern bool load_floor(floor_type *sf_ptr, FLAGS_32 mode);
--- source/trunk/src/floors.c (revision 9114)
+++ source/trunk/src/floors.c (revision 9115)
@@ -578,3 +578,1354 @@
578578 for(i = 1; i <= floor_max; i++) if(floor_ptr == &floor_list[i]) return i;
579579 return 0;
580580 }
581+
582+/* File: generate.c */
583+
584+/*
585+ * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
586+ *
587+ * This software may be copied and distributed for educational, research,
588+ * and not for profit purposes provided that this copyright and statement
589+ * are included in all such copies. Other copyrights may also apply.
590+ */
591+
592+/* Purpose: Dungeon generation */
593+
594+/*
595+ * Note that Level generation is *not* an important bottleneck,
596+ * though it can be annoyingly slow on older machines... Thus
597+ * we emphasize "simplicity" and "correctness" over "speed".
598+ *
599+ * This entire file is only needed for generating levels.
600+ * This may allow smart compilers to only load it when needed.
601+ *
602+ * Consider the "vault_info.txt" file for vault generation.
603+ *
604+ * In this file, we use the "special" granite and perma-wall sub-types,
605+ * where "basic" is normal, "inner" is inside a room, "outer" is the
606+ * outer wall of a room, and "solid" is the outer wall of the dungeon
607+ * or any walls that may not be pierced by corridors. Thus the only
608+ * wall type that may be pierced by a corridor is the "outer granite"
609+ * type. The "basic granite" type yields the "actual" corridors.
610+ *
611+ * Note that we use the special "solid" granite wall type to prevent
612+ * multiple corridors from piercing a wall in two adjacent locations,
613+ * which would be messy, and we use the special "outer" granite wall
614+ * to indicate which walls "surround" rooms, and may thus be "pierced"
615+ * by corridors entering or leaving the room.
616+ *
617+ * Note that a tunnel which attempts to leave a room near the "edge"
618+ * of the dungeon in a direction toward that edge will cause "silly"
619+ * wall piercings, but will have no permanently incorrect effects,
620+ * as long as the tunnel can *eventually* exit from another side.
621+ * And note that the wall may not come back into the room by the
622+ * hole it left through, so it must bend to the left or right and
623+ * then optionally re-enter the room (at least 2 grids away). This
624+ * is not a problem since every room that is large enough to block
625+ * the passage of tunnels is also large enough to allow the tunnel
626+ * to pierce the room itself several times.
627+ *
628+ * Note that no two corridors may enter a room through adjacent grids,
629+ * they must either share an entryway or else use entryways at least
630+ * two grids apart. This prevents "large" (or "silly") doorways.
631+ *
632+ * To create rooms in the dungeon, we first divide the dungeon up
633+ * into "blocks" of 11x11 grids each, and require that all rooms
634+ * occupy a rectangular group of blocks. As long as each room type
635+ * reserves a sufficient number of blocks, the room building routines
636+ * will not need to check bounds. Note that most of the normal rooms
637+ * actually only use 23x11 grids, and so reserve 33x11 grids.
638+ *
639+ * Note that the use of 11x11 blocks (instead of the old 33x11 blocks)
640+ * allows more variability in the horizontal placement of rooms, and
641+ * at the same time has the disadvantage that some rooms (two thirds
642+ * of the normal rooms) may be "split" by panel boundaries. This can
643+ * induce a situation where a player is in a room and part of the room
644+ * is off the screen. It may be annoying enough to go back to 33x11
645+ * blocks to prevent this visual situation.
646+ *
647+ * Note that the dungeon generation routines are much different (2.7.5)
648+ * and perhaps "DUN_ROOMS" should be less than 50.
649+ *
650+ * Note that it is possible to create a room which is only
651+ * connected to itself, because the "tunnel generation" code allows a
652+ * tunnel to leave a room, wander around, and then re-enter the room.
653+ *
654+ * Note that it is possible to create a set of rooms which
655+ * are only connected to other rooms in that set, since there is nothing
656+ * explicit in the code to prevent this from happening. But this is less
657+ * likely than the "isolated room" problem, because each room attempts to
658+ * connect to another room, in a giant cycle, thus requiring at least two
659+ * bizarre occurances to create an isolated section of the dungeon.
660+ *
661+ * Note that (2.7.9) creature pits have been split into creature "nests"
662+ * and creature "pits". The "nests" have a collection of creatures of a
663+ * given type strewn randomly around the room (jelly, animal, or undead),
664+ * while the "pits" have a collection of creatures of a given type placed
665+ * around the room in an organized manner (orc, troll, giant, dragon, or
666+ * demon). Note that both "nests" and "pits" are now "level dependant",
667+ * and both make 16 "expensive" calls to the "get_species_num(floor_ptr, )" function.
668+ *
669+ * Note that the cave grid flags changed in a rather drastic manner
670+ * for Angband 2.8.0 (and 2.7.9+), in particular, dungeon terrain
671+ * features, such as doors and stairs and traps and rubble and walls,
672+ * are all handled as a set of 64 possible "terrain features", and
673+ * not as "fake" objects (440-479) as in pre-2.8.0 versions.
674+ *
675+ * The 64 new "dungeon features" will also be used for "visual display"
676+ * but we must be careful not to allow, for example, the user to display
677+ * hidden traps in a different way from floors, or secret doors in a way
678+ * different from granite walls, or even permanent granite in a different
679+ * way from granite.
680+ */
681+
682+#include "angband.h"
683+#include "cave.h"
684+#include "creature_const.h"
685+#include "generate.h"
686+#include "grid.h"
687+#include "init.h"
688+#include "object.h"
689+#include "rooms.h"
690+#include "streams.h"
691+#include "diary.h"
692+#include "quest.h"
693+
694+int dun_tun_rnd;
695+int dun_tun_chg;
696+int dun_tun_con;
697+int dun_tun_pen;
698+int dun_tun_jct;
699+
700+
701+/*
702+ * Dungeon generation data -- see "create_cave_structure()"
703+ */
704+dun_data *dungeon_ptr;
705+
706+
707+// Count the number of walls adjacent to the given grid.
708+// Note -- Assumes "IN_BOUNDS(floor_ptr, y, x)"
709+// We count only granite walls and permanent walls.
710+static int next_to_walls(floor_type *floor_ptr, int y, int x)
711+{
712+ int k = 0;
713+ if(IN_BOUNDS(floor_ptr, y + 1, x) && is_extra_bold(floor_ptr, y + 1, x)) k++;
714+ if(IN_BOUNDS(floor_ptr, y - 1, x) && is_extra_bold(floor_ptr, y - 1, x)) k++;
715+ if(IN_BOUNDS(floor_ptr, y, x + 1) && is_extra_bold(floor_ptr, y, x + 1)) k++;
716+ if(IN_BOUNDS(floor_ptr, y, x - 1) && is_extra_bold(floor_ptr, y, x - 1)) k++;
717+ return (k);
718+}
719+
720+
721+// Helper function for alloc_stairs().
722+// Is this a good location for stairs?
723+static bool alloc_stairs_aux(floor_type *floor_ptr, int y, int x, int walls)
724+{
725+ /* Access the grid */
726+ cave_type *c_ptr = &floor_ptr->cave[y][x];
727+
728+ /* Require "naked" floor grid */
729+ if(!is_floor_grid(c_ptr)) return FALSE;
730+ if(pattern_tile(floor_ptr, y, x)) return FALSE;
731+ if(c_ptr->object_idx || c_ptr->creature_idx) return FALSE;
732+
733+ /* Require a certain number of adjacent walls */
734+ if(next_to_walls(floor_ptr, y, x) < walls) return FALSE;
735+
736+ return TRUE;
737+}
738+
739+
740+/*
741+ * Places some staircases near walls
742+ */
743+static bool alloc_stairs(floor_type *floor_ptr, FEATURE_ID feat, int num, int walls)
744+{
745+ int i;
746+ int shaft_num = 0;
747+
748+ feature_type *f_ptr = &feature_info[feat];
749+
750+ if(have_flag(f_ptr->flags, FF_LESS))
751+ {
752+ if(ironman_downward || !floor_ptr->depth) return TRUE; /* No up stairs in town or in ironman mode */
753+ if(floor_ptr->depth > dungeon_info[floor_ptr->dungeon_id].mindepth) shaft_num = (randint1(num+1))/2;
754+ }
755+ else if(have_flag(f_ptr->flags, FF_MORE))
756+ {
757+ int q_idx = quest_number(floor_ptr);
758+ if(floor_ptr->depth > 1 && q_idx) /* No downstairs on quest levels */
759+ {
760+ species_type *species_ptr = &species_info[quest[q_idx].species_idx];
761+ if(!(has_trait_species(species_ptr, TRAIT_UNIQUE)) || 0 < species_ptr->max_num) return TRUE; /* The quest creature(s) is still alive? */
762+ }
763+
764+ if(floor_ptr->depth >= dungeon_info[floor_ptr->dungeon_id].maxdepth) return TRUE; /* No downstairs at the bottom */
765+ if((floor_ptr->depth < dungeon_info[floor_ptr->dungeon_id].maxdepth-1)) //TODO !quest_number(floor_ptr->depth+1))
766+ shaft_num = (randint1(num)+1)/2;
767+ }
768+ else return FALSE;
769+
770+ /* Place "num" stairs */
771+ for (i = 0; i < num; i++)
772+ {
773+ while (TRUE)
774+ {
775+ int y = 0, x = 0;
776+ cave_type *c_ptr;
777+
778+ int candidates = 0;
779+ int pick;
780+
781+ for (y = 1; y < floor_ptr->height - 1; y++)
782+ {
783+ for (x = 1; x < floor_ptr->width - 1; x++)
784+ {
785+ if(alloc_stairs_aux(floor_ptr, y, x, walls)) candidates++; /* A valid space found */
786+ }
787+ }
788+
789+ if(!candidates) /* No valid place! */
790+ {
791+ if(walls <= 0) return FALSE; /* There are exactly no place! */
792+ walls--; /* Decrease walls limit, and try again */
793+ continue;
794+ }
795+
796+ pick = randint1(candidates); /* Choose a random one */
797+
798+ for (y = 1; y < floor_ptr->height - 1; y++)
799+ {
800+ for (x = 1; x < floor_ptr->width - 1; x++)
801+ {
802+ if(alloc_stairs_aux(floor_ptr, y, x, walls))
803+ {
804+ pick--;
805+ if(!pick) break; /* Is this a picked one? */
806+ }
807+ }
808+ if(!pick) break;
809+ }
810+
811+ c_ptr = &floor_ptr->cave[y][x]; /* Access the grid */
812+ c_ptr->mimic = 0; /* Clear possible garbage of hidden trap */
813+ c_ptr->feat = (i < shaft_num) ? feat_state(floor_ptr, feat, FF_SHAFT) : feat; /* Clear previous contents, add stairs */
814+ c_ptr->info &= ~(CAVE_FLOOR); /* No longer "FLOOR" */
815+ break;
816+ }
817+ }
818+ return TRUE;
819+}
820+
821+
822+/*
823+ * Allocates some objects (using "place" and "type")
824+ */
825+static void alloc_object(floor_type *floor_ptr, creature_type *player_ptr, int set, int typ, int num)
826+{
827+ COODINATES y = 0, x = 0;
828+ int dummy = 0, k;
829+ cave_type *c_ptr;
830+
831+ /* A small level has few objects. */
832+ num = num * floor_ptr->height * floor_ptr->width / (MAX_HGT * MAX_WID) +1;
833+
834+ /* Place some objects */
835+ for (k = 0; k < num; k++)
836+ {
837+ /* Pick a "legal" spot */
838+ while (dummy < SAFE_MAX_ATTEMPTS)
839+ {
840+ bool room;
841+ dummy++;
842+
843+ y = (COODINATES)randint0(floor_ptr->height);
844+ x = (COODINATES)randint0(floor_ptr->width);
845+
846+ c_ptr = &floor_ptr->cave[y][x];
847+
848+ if(!is_floor_grid(c_ptr) || c_ptr->object_idx || c_ptr->creature_idx) continue; /* Require "naked" floor grid */
849+ if(CREATURE_BOLD(player_ptr, y, x)) continue; /* Avoid player location */
850+ room = (floor_ptr->cave[y][x].info & CAVE_ROOM) ? TRUE : FALSE; /* Check for "room" */
851+ if((set == ALLOC_SET_CORR) && room) continue; /* Require corridor? */
852+ if((set == ALLOC_SET_ROOM) && !room) continue; /* Require room? */
853+ break; /* Accept it */
854+ }
855+
856+ if(dummy >= SAFE_MAX_ATTEMPTS)
857+ {
858+ if(cheat_room) msg_warning(MES_DEBUG_DISABLE_ITEM);
859+ return;
860+ }
861+
862+
863+ /* Place something */
864+ switch (typ)
865+ {
866+ case ALLOC_TYP_RUBBLE:
867+ place_rubble(floor_ptr, y, x);
868+ floor_ptr->cave[y][x].info &= ~(CAVE_FLOOR);
869+ break;
870+
871+ case ALLOC_TYP_TRAP:
872+ place_trap(floor_ptr, y, x);
873+ floor_ptr->cave[y][x].info &= ~(CAVE_FLOOR);
874+ break;
875+
876+ case ALLOC_TYP_GOLD:
877+ place_gold(floor_ptr, y, x);
878+ break;
879+
880+ case ALLOC_TYP_OBJECT:
881+ place_object(floor_ptr, y, x, 0L);
882+ break;
883+ }
884+ }
885+}
886+
887+
888+/*
889+ * Count the number of "corridor" grids adjacent to the given grid.
890+ *
891+ * Note -- Assumes "IN_BOUNDS(floor_ptr, y1, x1)"
892+ *
893+ * This routine currently only counts actual "empty floor"
894+ * grids which are not in rooms. We might want to also count stairs,
895+ * open doors, closed doors, etc.
896+ */
897+static int next_to_corr(floor_type *floor_ptr, int y1, int x1)
898+{
899+ int i, y, x, k = 0;
900+
901+ cave_type *c_ptr;
902+
903+ /* Scan adjacent grids */
904+ for (i = 0; i < 4; i++)
905+ {
906+ /* Extract the location */
907+ y = y1 + ddy_ddd[i];
908+ x = x1 + ddx_ddd[i];
909+
910+ /* Access the grid */
911+ c_ptr = &floor_ptr->cave[y][x];
912+
913+ /* Skip non floors */
914+ if(CAVE_HAVE_FLAG_GRID(c_ptr, FF_WALL)) continue;
915+
916+ /* Skip non "empty floor" grids */
917+ if(!is_floor_grid(c_ptr)) continue;
918+
919+ /* Skip grids inside rooms */
920+ if(c_ptr->info & (CAVE_ROOM)) continue;
921+
922+ /* Count these grids */
923+ k++;
924+ }
925+
926+ /* Return the number of corridors */
927+ return (k);
928+}
929+
930+
931+/*
932+ * Determine if the given location is "between" two walls,
933+ * and "next to" two corridor spaces.
934+ *
935+ * Assumes "IN_BOUNDS(floor_ptr, y, x)"
936+ */
937+static bool possible_doorway(floor_type *floor_ptr, int y, int x)
938+{
939+ /* Count the adjacent corridors */
940+ if(next_to_corr(floor_ptr, y, x) >= 2)
941+ {
942+ /* Check Vertical */
943+ if(CAVE_HAVE_FLAG_BOLD(floor_ptr, y - 1, x, FF_WALL) &&
944+ CAVE_HAVE_FLAG_BOLD(floor_ptr, y + 1, x, FF_WALL))
945+ {
946+ return TRUE;
947+ }
948+
949+ /* Check Horizontal */
950+ if(CAVE_HAVE_FLAG_BOLD(floor_ptr, y, x - 1, FF_WALL) &&
951+ CAVE_HAVE_FLAG_BOLD(floor_ptr, y, x + 1, FF_WALL))
952+ {
953+ return TRUE;
954+ }
955+ }
956+
957+ /* No doorway */
958+ return FALSE;
959+}
960+
961+
962+
963+// Places door at y, x position if at least 2 walls found
964+static void try_door(floor_type *floor_ptr, int y, int x)
965+{
966+
967+ if(!IN_BOUNDS(floor_ptr, y, x)) return;
968+ if(CAVE_HAVE_FLAG_BOLD(floor_ptr, y, x, FF_WALL)) return; // Ignore walls
969+
970+ /* Ignore room grids */
971+ if(floor_ptr->cave[y][x].info & (CAVE_ROOM)) return;
972+
973+ /* Occasional door (if allowed) */
974+ if((randint0(100) < dun_tun_jct) && possible_doorway(floor_ptr, y, x) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_NO_DOORS))
975+ place_random_door(floor_ptr, y, x, FALSE);
976+}
977+
978+
979+/*
980+ * Set boundary mimic and add "solid" perma-wall
981+ */
982+static void set_bound_perm_wall(cave_type *c_ptr)
983+{
984+ if(bound_walls_perm)
985+ {
986+ /* Clear boundary mimic */
987+ c_ptr->mimic = 0;
988+ }
989+ else
990+ {
991+ feature_type *f_ptr = &feature_info[c_ptr->feat];
992+
993+ /* Hack -- Decline boundary walls with known treasure */
994+ if((have_flag(f_ptr->flags, FF_HAS_GOLD) || have_flag(f_ptr->flags, FF_HAS_ITEM)) &&
995+ !have_flag(f_ptr->flags, FF_SECRET))
996+ c_ptr->feat = feat_state(CURRENT_FLOOR_PTR, c_ptr->feat, FF_ENSECRET);
997+
998+ /* Set boundary mimic */
999+ c_ptr->mimic = c_ptr->feat;
1000+ }
1001+
1002+ /* Add "solid" perma-wall */
1003+ place_solid_perm_grid(c_ptr);
1004+}
1005+
1006+
1007+
1008+// Generate various caverns and lakes
1009+// There were moved from create_cave_structure().
1010+static void generate_caverns_and_lakes(floor_type *floor_ptr)
1011+{
1012+ /* Possible "destroyed" level */
1013+ if((floor_ptr->depth > 30) && one_in_(DUN_DEST*2) && (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_DESTROY))
1014+ {
1015+ dungeon_ptr->destroyed = TRUE;
1016+
1017+ /* extra rubble around the place looks cool */
1018+ build_lake(floor_ptr, one_in_(2) ? LAKE_T_CAVE : LAKE_T_EARTH_VAULT);
1019+ }
1020+
1021+ /* Make a lake some of the time */
1022+ if(one_in_(LAKE_LEVEL) && !dungeon_ptr->empty_level && !dungeon_ptr->destroyed &&
1023+ (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_MASK))
1024+ {
1025+ int count = 0;
1026+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_WATER) count += 3;
1027+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_LAVA) count += 3;
1028+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_RUBBLE) count += 3;
1029+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_TREE) count += 3;
1030+
1031+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_LAVA)
1032+ {
1033+ /* Lake of Lava */
1034+ if((floor_ptr->depth > 80) && (randint0(count) < 2)) dungeon_ptr->laketype = LAKE_T_LAVA;
1035+ count -= 2;
1036+
1037+ /* Lake of Lava2 */
1038+ if(!dungeon_ptr->laketype && (floor_ptr->depth > 80) && one_in_(count)) dungeon_ptr->laketype = LAKE_T_FIRE_VAULT;
1039+ count--;
1040+ }
1041+
1042+ if((dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_WATER) && !dungeon_ptr->laketype)
1043+ {
1044+ /* Lake of Water */
1045+ if((floor_ptr->depth > 50) && randint0(count) < 2) dungeon_ptr->laketype = LAKE_T_WATER;
1046+ count -= 2;
1047+
1048+ /* Lake of Water2 */
1049+ if(!dungeon_ptr->laketype && (floor_ptr->depth > 50) && one_in_(count)) dungeon_ptr->laketype = LAKE_T_WATER_VAULT;
1050+ count--;
1051+ }
1052+
1053+ if((dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_RUBBLE) && !dungeon_ptr->laketype)
1054+ {
1055+ /* Lake of rubble */
1056+ if((floor_ptr->depth > 35) && (randint0(count) < 2)) dungeon_ptr->laketype = LAKE_T_CAVE;
1057+ count -= 2;
1058+
1059+ /* Lake of rubble2 */
1060+ if(!dungeon_ptr->laketype && (floor_ptr->depth > 35) && one_in_(count)) dungeon_ptr->laketype = LAKE_T_EARTH_VAULT;
1061+ count--;
1062+ }
1063+
1064+ /* Lake of tree */
1065+ if((floor_ptr->depth > 5) && (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAKE_TREE) && !dungeon_ptr->laketype) dungeon_ptr->laketype = LAKE_T_AIR_VAULT;
1066+
1067+ if(dungeon_ptr->laketype)
1068+ {
1069+ if(cheat_room) msg_print(MES_DEBUG_LAKE);
1070+ build_lake(floor_ptr, dungeon_ptr->laketype);
1071+ }
1072+ }
1073+
1074+ if((floor_ptr->depth > DUN_CAVERN) && !dungeon_ptr->empty_level &&
1075+ (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_CAVERN) &&
1076+ !dungeon_ptr->laketype && !dungeon_ptr->destroyed && (randint1(1000) < floor_ptr->depth))
1077+ {
1078+ dungeon_ptr->cavern = TRUE;
1079+
1080+ /* make a large fractal cave in the middle of the dungeon */
1081+
1082+ if(cheat_room) msg_print(MES_DEBUG_CAVE);
1083+ build_cavern(floor_ptr);
1084+ }
1085+
1086+ /* Hack -- No destroyed "quest" levels */
1087+ if(quest_number(floor_ptr)) dungeon_ptr->destroyed = FALSE;
1088+}
1089+
1090+
1091+
1092+/*
1093+ * Generate a new dungeon level
1094+ *
1095+ * Note that "dun_body" adds about 4000 bytes of memory to the stack.
1096+ */
1097+static bool create_cave_structure(floor_type *floor_ptr)
1098+{
1099+ int i, k;
1100+ COODINATES y, x;
1101+ dun_data dun_body;
1102+
1103+ // Global data
1104+ dungeon_ptr = &dun_body;
1105+
1106+ dungeon_ptr->destroyed = FALSE;
1107+ dungeon_ptr->empty_level = FALSE;
1108+ dungeon_ptr->cavern = FALSE;
1109+ dungeon_ptr->laketype = 0;
1110+
1111+ // Fill the arrays of floors and walls in the good proportions
1112+ set_floor_and_wall(floor_ptr->dungeon_id);
1113+
1114+ // Prepare allocation table
1115+ //TODO get_creature_list_terrain()
1116+
1117+ // Randomize the dungeon creation values
1118+ dun_tun_rnd = rand_range(DUN_TUN_RND_MIN, DUN_TUN_RND_MAX);
1119+ dun_tun_chg = rand_range(DUN_TUN_CHG_MIN, DUN_TUN_CHG_MAX);
1120+ dun_tun_con = rand_range(DUN_TUN_CON_MIN, DUN_TUN_CON_MAX);
1121+ dun_tun_pen = rand_range(DUN_TUN_PEN_MIN, DUN_TUN_PEN_MAX);
1122+ dun_tun_jct = rand_range(DUN_TUN_JCT_MIN, DUN_TUN_JCT_MAX);
1123+
1124+ // Actual maximum number of rooms on this level
1125+ dungeon_ptr->row_rooms = floor_ptr->height / BLOCK_HGT;
1126+ dungeon_ptr->col_rooms = floor_ptr->width / BLOCK_WID;
1127+
1128+ // Initialize the room table
1129+ for (y = 0; y < dungeon_ptr->row_rooms; y++)
1130+ {
1131+ for (x = 0; x < dungeon_ptr->col_rooms; x++)
1132+ {
1133+ dungeon_ptr->room_map[y][x] = FALSE;
1134+ }
1135+ }
1136+
1137+ // No rooms yet
1138+ dungeon_ptr->cent_n = 0;
1139+
1140+ // Empty arena levels
1141+ if(ironman_empty_levels || ((dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_ARENA) && (empty_levels && one_in_(EMPTY_LEVEL))))
1142+ {
1143+ dungeon_ptr->empty_level = TRUE;
1144+ if(cheat_room) msg_print(MES_DEBUG_ARENA);
1145+ }
1146+
1147+ if(dungeon_ptr->empty_level)
1148+ {
1149+ // Start with floors
1150+ for (y = 0; y < floor_ptr->height; y++)
1151+ {
1152+ for (x = 0; x < floor_ptr->width; x++)
1153+ {
1154+ place_floor_bold(floor_ptr, y, x);
1155+ }
1156+ }
1157+
1158+ // Special boundary walls -- Top and bottom
1159+ for (x = 0; x < floor_ptr->width; x++)
1160+ {
1161+ place_extra_bold(floor_ptr, 0, x);
1162+ place_extra_bold(floor_ptr, floor_ptr->height - 1, x);
1163+ }
1164+
1165+ // Special boundary walls -- Left and right
1166+ for (y = 1; y < (floor_ptr->height - 1); y++)
1167+ {
1168+ place_extra_bold(floor_ptr, y, 0);
1169+ place_extra_bold(floor_ptr, y, floor_ptr->width - 1);
1170+ }
1171+ }
1172+ else
1173+ {
1174+ // Start with walls
1175+ for (y = 0; y < floor_ptr->height; y++)
1176+ {
1177+ for (x = 0; x < floor_ptr->width; x++)
1178+ {
1179+ place_extra_bold(floor_ptr, y, x);
1180+ }
1181+ }
1182+ }
1183+
1184+ // Generate various caverns and lakes
1185+ generate_caverns_and_lakes(floor_ptr);
1186+
1187+ // Build maze
1188+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_MAZE)
1189+ {
1190+ build_maze_vault(floor_ptr, floor_ptr->width / 2 - 1, floor_ptr->height / 2 - 1, floor_ptr->width - 4, floor_ptr->height - 4, FALSE);
1191+
1192+ /* Place stairs */
1193+ if(!alloc_stairs(floor_ptr, feat_down_stair, rand_range(2, 3), 3)) return FALSE;
1194+ if(!alloc_stairs(floor_ptr, feat_up_stair, 1, 3)) return FALSE;
1195+ }
1196+
1197+ // Build some rooms
1198+ else
1199+ {
1200+ int tunnel_fail_count = 0;
1201+
1202+ // Build each type of room in turn until we cannot build any more.
1203+ if(!generate_rooms(floor_ptr))
1204+ return FALSE;
1205+
1206+
1207+ /* Make a hole in the dungeon roof sometimes at level 1 */
1208+ if(floor_ptr->depth == 1)
1209+ {
1210+ while (one_in_(DUN_MOS_DEN))
1211+ place_trees(floor_ptr, (COODINATES)randint1(floor_ptr->width - 2), (COODINATES)randint1(floor_ptr->height - 2));
1212+ }
1213+
1214+ /* Destroy the level if necessary */
1215+ if(dungeon_ptr->destroyed) destroy_level(floor_ptr);
1216+
1217+ /* Hack -- Add some rivers */
1218+ if(one_in_(3) && (randint1(floor_ptr->depth) > 5))
1219+ {
1220+ FEATURE_ID feat1 = 0, feat2 = 0;
1221+
1222+ /* Choose water or lava or poison swamp*/
1223+ if((randint1(MAX_DEPTH * 2) - 1 > floor_ptr->depth) && (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_WATER_RIVER))
1224+ {
1225+ feat1 = feat_deep_water;
1226+ feat2 = feat_shallow_water;
1227+ }
1228+ else if (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_LAVA_RIVER & one_in_(3))
1229+ {
1230+ feat1 = feat_deep_lava;
1231+ feat2 = feat_shallow_lava;
1232+ }
1233+ else if (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_POISON_RIVER & one_in_(2))
1234+ {
1235+ feat1 = feat_deep_poison;
1236+ feat2 = feat_shallow_poison;
1237+ }
1238+ else if (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_ACID_RIVER)
1239+ {
1240+ feat1 = feat_deep_acid;
1241+ feat2 = feat_shallow_acid;
1242+ }
1243+ else feat1 = 0;
1244+
1245+ if(feat1)
1246+ {
1247+ feature_type *f_ptr = &feature_info[feat1];
1248+
1249+ /* Only add river if matches lake type or if have no lake at all */
1250+ if(((dungeon_ptr->laketype == LAKE_T_LAVA) && have_flag(f_ptr->flags, FF_LAVA)) ||
1251+ ((dungeon_ptr->laketype == LAKE_T_WATER) && have_flag(f_ptr->flags, FF_WATER)) ||
1252+ !dungeon_ptr->laketype)
1253+ {
1254+ add_river(floor_ptr, feat1, feat2);
1255+ }
1256+ }
1257+ }
1258+
1259+ /* Hack -- Scramble the room order */
1260+ for (i = 0; i < dungeon_ptr->cent_n; i++)
1261+ {
1262+ COODINATES ty, tx;
1263+ int pick = rand_range(0, i);
1264+
1265+ ty = dungeon_ptr->cent[i].y;
1266+ tx = dungeon_ptr->cent[i].x;
1267+ dungeon_ptr->cent[i].y = dungeon_ptr->cent[pick].y;
1268+ dungeon_ptr->cent[i].x = dungeon_ptr->cent[pick].x;
1269+ dungeon_ptr->cent[pick].y = ty;
1270+ dungeon_ptr->cent[pick].x = tx;
1271+ }
1272+
1273+ /* Start with no tunnel doors */
1274+ dungeon_ptr->door_n = 0;
1275+
1276+ /* Hack -- connect the first room to the last room */
1277+ y = dungeon_ptr->cent[dungeon_ptr->cent_n-1].y;
1278+ x = dungeon_ptr->cent[dungeon_ptr->cent_n-1].x;
1279+
1280+ /* Connect all the rooms together */
1281+ for (i = 0; i < dungeon_ptr->cent_n; i++)
1282+ {
1283+ int j;
1284+
1285+ /* Reset the arrays */
1286+ dungeon_ptr->tunn_n = 0;
1287+ dungeon_ptr->wall_n = 0;
1288+
1289+ /* Connect the room to the previous room */
1290+ if(randint1(floor_ptr->depth) > dungeon_info[floor_ptr->dungeon_id].tunnel_percent)
1291+ {
1292+ /* make cave-like tunnel */
1293+ (void)build_tunnel2(floor_ptr, dungeon_ptr->cent[i].x, dungeon_ptr->cent[i].y, x, y, 2, 2);
1294+ }
1295+ else
1296+ {
1297+ /* make normal tunnel */
1298+ if(!build_tunnel(floor_ptr, dungeon_ptr->cent[i].y, dungeon_ptr->cent[i].x, y, x)) tunnel_fail_count++;
1299+ }
1300+
1301+ if(tunnel_fail_count >= 2) return FALSE;
1302+
1303+ /* Turn the tunnel into corridor */
1304+ for (j = 0; j < dungeon_ptr->tunn_n; j++)
1305+ {
1306+ cave_type *c_ptr;
1307+ feature_type *f_ptr;
1308+
1309+ /* Access the grid */
1310+ y = dungeon_ptr->tunn[j].y;
1311+ x = dungeon_ptr->tunn[j].x;
1312+
1313+ /* Access the grid */
1314+ c_ptr = &floor_ptr->cave[y][x];
1315+ f_ptr = &feature_info[c_ptr->feat];
1316+
1317+ /* Clear previous contents (if not a lake), add a floor */
1318+ if(!have_flag(f_ptr->flags, FF_MOVE) || (!have_flag(f_ptr->flags, FF_WATER) && !have_flag(f_ptr->flags, FF_LAVA)))
1319+ {
1320+ /* Clear mimic type */
1321+ c_ptr->mimic = 0;
1322+
1323+ place_floor_grid(c_ptr);
1324+ }
1325+ }
1326+
1327+ /* Apply the piercings that we found */
1328+ for (j = 0; j < dungeon_ptr->wall_n; j++)
1329+ {
1330+ cave_type *c_ptr;
1331+
1332+ /* Access the grid */
1333+ y = dungeon_ptr->wall[j].y;
1334+ x = dungeon_ptr->wall[j].x;
1335+
1336+ /* Access the grid */
1337+ c_ptr = &floor_ptr->cave[y][x];
1338+
1339+ /* Clear mimic type */
1340+ c_ptr->mimic = 0;
1341+
1342+ /* Clear previous contents, add up floor */
1343+ place_floor_grid(c_ptr);
1344+
1345+ /* Occasional doorway */
1346+ if((randint0(100) < dun_tun_pen) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_NO_DOORS))
1347+ {
1348+ /* Place a random door */
1349+ place_random_door(floor_ptr, y, x, TRUE);
1350+ }
1351+ }
1352+
1353+ /* Remember the "previous" room */
1354+ y = dungeon_ptr->cent[i].y;
1355+ x = dungeon_ptr->cent[i].x;
1356+ }
1357+
1358+ /* Place intersection doors */
1359+ for (i = 0; i < dungeon_ptr->door_n; i++)
1360+ {
1361+ /* Extract junction location */
1362+ y = dungeon_ptr->door[i].y;
1363+ x = dungeon_ptr->door[i].x;
1364+
1365+ /* Try placing doors */
1366+ try_door(floor_ptr, y, x - 1);
1367+ try_door(floor_ptr, y, x + 1);
1368+ try_door(floor_ptr, y - 1, x);
1369+ try_door(floor_ptr, y + 1, x);
1370+ }
1371+
1372+ // Place some down stairs near some walls
1373+ if(!alloc_stairs(floor_ptr, feat_down_stair, rand_range(1, 4) + (floor_ptr->width / SCREEN_WID * floor_ptr->height / SCREEN_HGT) / 8, 3)) return FALSE;
1374+
1375+ // Place some up stairs near some walls
1376+ if(!alloc_stairs(floor_ptr, feat_up_stair, rand_range(1, 4) + (floor_ptr->width / SCREEN_WID * floor_ptr->height / SCREEN_HGT) / 8, 3)) return FALSE;
1377+ }
1378+
1379+ if(!dungeon_ptr->laketype)
1380+ {
1381+ if(dungeon_info[floor_ptr->dungeon_id].stream2)
1382+ {
1383+ // Hack -- Add some quartz streamers
1384+ for (i = 0; i < DUN_STR_QUA; i++)
1385+ {
1386+ build_streamer(floor_ptr, dungeon_info[floor_ptr->dungeon_id].stream2, DUN_STR_QC);
1387+ }
1388+ }
1389+
1390+ if(dungeon_info[floor_ptr->dungeon_id].stream1)
1391+ {
1392+ // Hack -- Add some magma streamers
1393+ for (i = 0; i < DUN_STR_MAG; i++)
1394+ {
1395+ build_streamer(floor_ptr, dungeon_info[floor_ptr->dungeon_id].stream1, DUN_STR_MC);
1396+ }
1397+ }
1398+ }
1399+
1400+ // Special boundary walls -- Top and bottom
1401+ for (x = 0; x < floor_ptr->width; x++)
1402+ {
1403+ set_bound_perm_wall(&floor_ptr->cave[0][x]);
1404+ set_bound_perm_wall(&floor_ptr->cave[floor_ptr->height - 1][x]);
1405+ }
1406+
1407+ // Special boundary walls -- Left and right
1408+ for (y = 1; y < (floor_ptr->height - 1); y++)
1409+ {
1410+ set_bound_perm_wall(&floor_ptr->cave[y][0]);
1411+ set_bound_perm_wall(&floor_ptr->cave[y][floor_ptr->width - 1]);
1412+ }
1413+
1414+ if(!place_quest_creatures(floor_ptr, player_ptr)) return FALSE; // Set Quest Creature
1415+
1416+ // Basic "amount"
1417+ k = (floor_ptr->depth / 3);
1418+ if(k > 10) k = 10;
1419+ if(k < 2) k = 2;
1420+
1421+ // Pick a base number of creatures
1422+ i = dungeon_info[floor_ptr->dungeon_id].min_m_alloc_level;
1423+
1424+ // To make small levels a bit more playable
1425+ if(floor_ptr->height < MAX_HGT || floor_ptr->width < MAX_WID)
1426+ {
1427+ int small_tester = i;
1428+
1429+ i = (i * floor_ptr->height) / MAX_HGT;
1430+ i = (i * floor_ptr->width) / MAX_WID;
1431+ i += 1;
1432+
1433+ if(i > small_tester) i = small_tester;
1434+ else if(cheat_hear) msg_format(MES_DEBUG_DEC_CREATURE(small_tester, i));
1435+ }
1436+
1437+ // Put some creatures in the dungeon
1438+ i += randint1(8);
1439+ for (i = i + k; i > 0; i--) (void)alloc_creature(floor_ptr, player_ptr->fy, player_ptr->fx, 0, PC_ALLOW_SLEEP);
1440+
1441+ // Place some traps in the dungeon
1442+ alloc_object(floor_ptr, player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(k));
1443+
1444+ // Put some rubble in corridors (except NO_CAVE dungeon (Castle))
1445+ if(!(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_NO_CAVE)) alloc_object(floor_ptr, player_ptr, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k));
1446+
1447+ // Mega Hack -- No object at first level of deeper dungeon
1448+ if(player_ptr->enter_dungeon && floor_ptr->depth > 1) floor_ptr->object_level = 1; // No stair scum!
1449+
1450+ // Put some objects in rooms
1451+ alloc_object(floor_ptr, player_ptr, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
1452+
1453+ // Put some objects/gold in the dungeon
1454+ alloc_object(floor_ptr, player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
1455+ alloc_object(floor_ptr, player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
1456+
1457+ floor_ptr->object_level = floor_ptr->depth; // Set back to default
1458+
1459+ if(!alloc_guardian(floor_ptr, TRUE)) return FALSE; // Put the Guardian
1460+
1461+ if(dungeon_ptr->empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > floor_ptr->depth)) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_DARKNESS))
1462+ {
1463+ // Lite the cave
1464+ for (y = 0; y < floor_ptr->height; y++)
1465+ {
1466+ for (x = 0; x < floor_ptr->width; x++)
1467+ {
1468+ floor_ptr->cave[y][x].info |= (CAVE_GLOW);
1469+ }
1470+ }
1471+ }
1472+
1473+ return TRUE;
1474+}
1475+
1476+
1477+/*
1478+ * Builds the arena after it is entered -KMW-
1479+ */
1480+static void build_arena(floor_type *floor_ptr, int height, int width)
1481+{
1482+ int yval, y_height, y_depth, xval, x_left, x_right;
1483+ register int i, j;
1484+
1485+ yval = height/ 2;
1486+ xval = width / 2;
1487+ y_height = yval - 10;
1488+ y_depth = yval + 10;
1489+ x_left = xval - 32;
1490+ x_right = xval + 32;
1491+
1492+ for (i = y_height; i <= y_height + 5; i++)
1493+ for (j = x_left; j <= x_right; j++)
1494+ {
1495+ place_extra_perm_bold(floor_ptr, i, j);
1496+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1497+ }
1498+ for (i = y_depth; i >= y_depth - 5; i--)
1499+ for (j = x_left; j <= x_right; j++)
1500+ {
1501+ place_extra_perm_bold(floor_ptr, i, j);
1502+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1503+ }
1504+ for (j = x_left; j <= x_left + 17; j++)
1505+ for (i = y_height; i <= y_depth; i++)
1506+ {
1507+ place_extra_perm_bold(floor_ptr, i, j);
1508+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1509+ }
1510+ for (j = x_right; j >= x_right - 17; j--)
1511+ for (i = y_height; i <= y_depth; i++)
1512+ {
1513+ place_extra_perm_bold(floor_ptr, i, j);
1514+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1515+ }
1516+
1517+ place_extra_perm_bold(floor_ptr, y_height+6, x_left+18);
1518+ floor_ptr->cave[y_height+6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
1519+ place_extra_perm_bold(floor_ptr, y_depth-6, x_left+18);
1520+ floor_ptr->cave[y_depth-6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
1521+ place_extra_perm_bold(floor_ptr, y_height+6, x_right-18);
1522+ floor_ptr->cave[y_height+6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
1523+ place_extra_perm_bold(floor_ptr, y_depth-6, x_right-18);
1524+ floor_ptr->cave[y_depth-6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
1525+
1526+ i = y_height + 5;
1527+ j = xval;
1528+ floor_ptr->cave[i][j].feat = feature_tag_to_index("ARENA_GATE");
1529+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1530+ move_creature(player_ptr, floor_ptr, i, j, 0);
1531+}
1532+
1533+
1534+/*
1535+ * Town logic flow for generation of arena -KMW-
1536+ */
1537+void generate_floor_arena(floor_type *floor_ptr, COODINATES height, COODINATES width)
1538+{
1539+ COODINATES y, x;
1540+ COODINATES qy = 0, qx = 0;
1541+ floor_ptr->generate_type = F_GENE_FIGHTING_ARENA;
1542+
1543+ // Small area
1544+ floor_ptr->height = height;
1545+ floor_ptr->width = width;
1546+
1547+ // Start with solid walls
1548+ for (y = 0; y < height; y++)
1549+ {
1550+ for (x = 0; x < width; x++)
1551+ {
1552+ place_solid_perm_bold(floor_ptr, y, x); // Create "solid" perma-wall
1553+ floor_ptr->cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); // Illuminate and memorize the walls
1554+ }
1555+ }
1556+
1557+ // Then place some floors
1558+ for (y = qy + 1; y < qy + height - 1; y++)
1559+ for (x = qx + 1; x < qx + width - 1; x++)
1560+ floor_ptr->cave[y][x].feat = feat_floor; // Create empty floor
1561+
1562+ build_arena(floor_ptr, height, width);
1563+ place_creature_fixed_species(player_ptr, floor_ptr, player_ptr->fy + 5, player_ptr->fx, arena_info[arena_number].species_idx, (PC_NO_KAGE | PC_NO_PET));
1564+}
1565+
1566+
1567+
1568+/*
1569+ * Builds the arena after it is entered -KMW-
1570+ */
1571+static void build_battle(floor_type *floor_ptr, creature_type *player_ptr)
1572+{
1573+ int yval, y_height, y_depth, xval, x_left, x_right;
1574+ register int i, j;
1575+
1576+ yval = SCREEN_HGT / 2;
1577+ xval = SCREEN_WID / 2;
1578+ y_height = yval - 10;
1579+ y_depth = yval + 10;
1580+ x_left = xval - 32;
1581+ x_right = xval + 32;
1582+
1583+ for (i = y_height; i <= y_height + 5; i++)
1584+ for (j = x_left; j <= x_right; j++)
1585+ {
1586+ place_extra_perm_bold(floor_ptr, i, j);
1587+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1588+ }
1589+ for (i = y_depth; i >= y_depth - 3; i--)
1590+ for (j = x_left; j <= x_right; j++)
1591+ {
1592+ place_extra_perm_bold(floor_ptr, i, j);
1593+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1594+ }
1595+ for (j = x_left; j <= x_left + 17; j++)
1596+ for (i = y_height; i <= y_depth; i++)
1597+ {
1598+ place_extra_perm_bold(floor_ptr, i, j);
1599+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1600+ }
1601+ for (j = x_right; j >= x_right - 17; j--)
1602+ for (i = y_height; i <= y_depth; i++)
1603+ {
1604+ place_extra_perm_bold(floor_ptr, i, j);
1605+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1606+ }
1607+
1608+ place_extra_perm_bold(floor_ptr, y_height+6, x_left+18);
1609+ floor_ptr->cave[y_height+6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
1610+ place_extra_perm_bold(floor_ptr, y_depth-4, x_left+18);
1611+ floor_ptr->cave[y_depth-4][x_left+18].info |= (CAVE_GLOW | CAVE_MARK);
1612+ place_extra_perm_bold(floor_ptr, y_height+6, x_right-18);
1613+ floor_ptr->cave[y_height+6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
1614+ place_extra_perm_bold(floor_ptr, y_depth-4, x_right-18);
1615+ floor_ptr->cave[y_depth-4][x_right-18].info |= (CAVE_GLOW | CAVE_MARK);
1616+
1617+ for (i = y_height + 1; i <= y_height + 5; i++)
1618+ for (j = x_left + 20 + 2 * (y_height + 5 - i); j <= x_right - 20 - 2 * (y_height + 5 - i); j++)
1619+ {
1620+ floor_ptr->cave[i][j].feat = feat_permanent_glass_wall;
1621+ }
1622+
1623+ i = y_height + 1;
1624+ j = xval;
1625+ floor_ptr->cave[i][j].feat = feature_tag_to_index("BUILDING_3");
1626+ floor_ptr->cave[i][j].info |= (CAVE_GLOW | CAVE_MARK);
1627+ move_creature(player_ptr, floor_ptr, i, j, 0);
1628+}
1629+
1630+
1631+/*
1632+ * Town logic flow for generation of arena -KMW-
1633+ */
1634+void generate_floor_creature_arena(floor_type *floor_ptr)
1635+{
1636+ COODINATES y, x;
1637+ COODINATES qy = 0, qx = 0;
1638+ int i;
1639+ floor_ptr->generate_type = F_GENE_GAMBLE_ARENA;
1640+
1641+ // Start with solid walls
1642+ for (y = 0; y < MAX_HGT; y++)
1643+ {
1644+ for (x = 0; x < MAX_WID; x++)
1645+ {
1646+ place_solid_perm_bold(floor_ptr, y, x); // Create "solid" perma-wall
1647+ floor_ptr->cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); // Illuminate and memorize the walls
1648+ }
1649+ }
1650+
1651+ // Then place some floors
1652+ for (y = qy + 1; y < qy + SCREEN_HGT - 1; y++)
1653+ for (x = qx + 1; x < qx + SCREEN_WID - 1; x++)
1654+ floor_ptr->cave[y][x].feat = feat_floor; // Create empty floor
1655+
1656+ build_battle(floor_ptr, player_ptr);
1657+
1658+ for(i = 0; i < 4;i ++)
1659+ {
1660+ place_creature_fixed_species(player_ptr, floor_ptr, player_ptr->fy + 8 + (i / 2) * 4, player_ptr->fx - 2 + (i % 2) * 4, battle_creature[i], (PC_NO_KAGE | PC_NO_PET));
1661+ //TODO set_camp(&creature_list[floor_ptr->cave[player_ptr->fy + 8 + (i / 2) * 4][player_ptr->fx - 2 + (i % 2) * 4].creature_idx]);
1662+ }
1663+
1664+ for(i = 1; i < creature_max; i++)
1665+ {
1666+ creature_type *m_ptr = &creature_list[i];
1667+ if(!is_valid_creature(m_ptr)) continue;
1668+ m_ptr->sc_flag2 |= (SC_FLAG2_MARK | SC_FLAG2_SHOW); // Hack -- Detect creature
1669+ update_creature_view(player_ptr, i, FALSE); // Update the creature
1670+ }
1671+}
1672+
1673+/* Generate a quest level */
1674+void generate_floor_quest(floor_type *floor_ptr, QUEST_ID quest_id)
1675+{
1676+ int x, y;
1677+ floor_ptr->generate_type = F_GENE_QUEST;
1678+
1679+ /* Start with perm walls */
1680+ for (y = 0; y < floor_ptr->height; y++)
1681+ {
1682+ for (x = 0; x < floor_ptr->width; x++)
1683+ {
1684+ place_solid_perm_bold(floor_ptr, y, x);
1685+ }
1686+ }
1687+
1688+ /* Set the quest level */
1689+ floor_ptr->depth = quest[quest_id].level;
1690+ floor_ptr->depth = floor_ptr->depth;
1691+ floor_ptr->object_level = floor_ptr->depth;
1692+ floor_ptr->enemy_level = floor_ptr->depth;
1693+ floor_ptr->quest = quest_id;
1694+
1695+ if(record_stair) write_diary(DIARY_TO_QUEST, quest_id, NULL);
1696+
1697+ // Prepare allocation table
1698+ //TODO get_creature_list_terrain()
1699+ process_dungeon_file(floor_ptr, QUEST_INFO_FILE, 0, 0, MAX_HGT, MAX_WID, INIT_CREATE_DUNGEON | INIT_ASSIGN, quest_id);
1700+}
1701+
1702+// Generate a fortless level
1703+static void generate_floor_fortress(floor_type *floor_ptr, int type)
1704+{
1705+ int x, y;
1706+ floor_ptr->generate_type = F_GENE_FORTLESS;
1707+
1708+ // Start with perm walls
1709+ for (y = 0; y < floor_ptr->height; y++)
1710+ {
1711+ for (x = 0; x < floor_ptr->width; x++)
1712+ {
1713+ place_solid_perm_bold(floor_ptr, y, x);
1714+ }
1715+ }
1716+
1717+ // Prepare allocation table
1718+ //TODO get_creature_list_terrain()
1719+ process_dungeon_file(floor_ptr, QUEST_INFO_FILE, 0, 0, MAX_HGT, MAX_WID, INIT_CREATE_DUNGEON | INIT_ASSIGN, type);
1720+}
1721+
1722+
1723+
1724+// Make a real level
1725+static bool generate_floor_dungeon(floor_type *floor_ptr, cptr *why)
1726+{
1727+ int level_height, level_width, i;
1728+
1729+ floor_ptr->generate_type = F_GENE_DUNGEON;
1730+ i = 0;
1731+ while(i < MAX_DUNEGON_FORTLESS)
1732+ {
1733+ int p = !one_in_(dungeon_info[floor_ptr->dungeon_id].vault_quest_probability[i]);
1734+ if(dungeon_info[floor_ptr->dungeon_id].vault_quest_level[i] <= floor_ptr->depth && dungeon_info[floor_ptr->dungeon_id].vault_quest_level_max[i] >= floor_ptr->depth && !p) break;
1735+ i++;
1736+ }
1737+
1738+ if(i != MAX_DUNEGON_FORTLESS)
1739+ {
1740+ if(cheat_room) msg_format("Fortless level -- type %d.", dungeon_info[floor_ptr->dungeon_id].vault_quest_type[i]);
1741+ generate_floor_fortress(floor_ptr, dungeon_info[floor_ptr->dungeon_id].vault_quest_type[i]);
1742+ return TRUE;
1743+ }
1744+
1745+ if((always_small_levels || ironman_small_levels || one_in_(SMALL_LEVEL) || (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_BEGINNER) ||
1746+ (dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_SMALLEST)) && !(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_BIG))
1747+ {
1748+ if(cheat_room) msg_print(MES_DEBUG_SMALL_LEVEL);
1749+
1750+ if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_SMALLEST)
1751+ {
1752+ level_height = MIN_SCREEN_HGT;
1753+ level_width = MIN_SCREEN_WID;
1754+ }
1755+ else if(dungeon_info[floor_ptr->dungeon_id].flags1 & DF1_BEGINNER)
1756+ {
1757+ level_height = rand_range(MIN_SCREEN_HGT, MAX_HGT / SCREEN_HGT / 4);
1758+ level_width = rand_range(MIN_SCREEN_WID, MAX_WID / SCREEN_WID / 4);
1759+ }
1760+ else
1761+ {
1762+ level_height = rand_range(MIN_SCREEN_HGT, MAX_HGT / SCREEN_HGT / 3);
1763+ level_width = rand_range(MIN_SCREEN_WID, MAX_WID / SCREEN_WID / 3);
1764+ }
1765+
1766+ floor_ptr->height = level_height * SCREEN_HGT;
1767+ floor_ptr->width = level_width * SCREEN_WID;
1768+
1769+ // Assume illegal panel
1770+ panel_row_min = floor_ptr->height;
1771+ panel_col_min = floor_ptr->width;
1772+
1773+ }
1774+ else
1775+ {
1776+ // Big dungeon
1777+ do{
1778+ level_height = rand_range(MAX_HGT / SCREEN_HGT / 3, MAX_HGT/SCREEN_HGT);
1779+ level_width = rand_range(MAX_WID / SCREEN_WID / 3, MAX_WID/SCREEN_WID);
1780+ } while (level_height + level_width < (MAX_HGT / SCREEN_HGT + MAX_WID / SCREEN_WID) / 2 || (level_height + level_width >= (MAX_HGT / SCREEN_HGT + MAX_WID / SCREEN_WID) * 3 / 4));
1781+ floor_ptr->height = level_height * SCREEN_HGT;
1782+ floor_ptr->width = level_width * SCREEN_WID;
1783+
1784+ // Assume illegal panel
1785+ panel_row_min = floor_ptr->height;
1786+ panel_col_min = floor_ptr->width;
1787+
1788+ }
1789+ if(cheat_room) msg_format(MES_DEBUG_FLOOR_SIZE(floor_ptr->width, floor_ptr->height));
1790+
1791+ // Make a dungeon
1792+ if(!create_cave_structure(floor_ptr))
1793+ {
1794+ *why = MES_DEBUG_FAILED_FLOOR;
1795+ return FALSE;
1796+ }
1797+
1798+ else return TRUE;
1799+}
1800+
1801+
1802+/*
1803+ * Wipe all unnecessary flags after cave generation
1804+ */
1805+void wipe_generate_floor_flags(floor_type *floor_ptr)
1806+{
1807+ int x, y;
1808+
1809+ for (y = 0; y < floor_ptr->height; y++)
1810+ {
1811+ for (x = 0; x < floor_ptr->width; x++)
1812+ {
1813+ floor_ptr->cave[y][x].info &= ~(CAVE_MASK); // Wipe unused flags
1814+ }
1815+ }
1816+
1817+ if(floor_ptr->depth)
1818+ {
1819+ for (y = 1; y < floor_ptr->height - 1; y++)
1820+ {
1821+ for (x = 1; x < floor_ptr->width - 1; x++)
1822+ {
1823+ floor_ptr->cave[y][x].info |= CAVE_UNSAFE; // There might be trap
1824+ }
1825+ }
1826+ }
1827+}
1828+
1829+// Clear and empty the cave
1830+void clear_cave(floor_type *floor_ptr)
1831+{
1832+ int x, y;
1833+
1834+ // Start with a blank cave
1835+ for (y = 0; y < MAX_HGT; y++)
1836+ {
1837+ for (x = 0; x < MAX_WID; x++)
1838+ {
1839+ cave_type *c_ptr = &floor_ptr->cave[y][x];
1840+
1841+ c_ptr->info = 0;
1842+ c_ptr->feat = 0;
1843+ c_ptr->object_idx = 0;
1844+ c_ptr->creature_idx = 0;
1845+ c_ptr->quest_idx = 0;
1846+ c_ptr->town_idx = 0;
1847+ c_ptr->to_floor = 0;
1848+ c_ptr->mimic = 0;
1849+ c_ptr->cost = 0;
1850+ c_ptr->dist = 0;
1851+ c_ptr->when = 0;
1852+ c_ptr->message[0] = '\0';
1853+ }
1854+ }
1855+
1856+ //TODO clear creatures and objects.
1857+
1858+ // Set the base level
1859+ floor_ptr->enemy_level = floor_ptr->depth;
1860+ floor_ptr->object_level = floor_ptr->depth;
1861+}
1862+
1863+// Generates a random dungeon level -RAK-
1864+// Hack -- regenerate any "overflow" levels
1865+bool generate_floor(floor_type *floor_ptr, DUNGEON_ID dungeon_id, COODINATES world_y, COODINATES world_x, FLOOR_LEV depth)
1866+{
1867+ int num;
1868+
1869+ /* Prepare new floor data */
1870+ floor_ptr->last_visit = 0;
1871+ floor_ptr->generated = FALSE;
1872+ floor_ptr->global_map = FALSE;
1873+ floor_ptr->world_x = world_x;
1874+ floor_ptr->world_y = world_y;
1875+
1876+ floor_ptr->dungeon_id = dungeon_id;
1877+
1878+ floor_ptr->depth = depth;
1879+ floor_ptr->enemy_level = depth;
1880+ floor_ptr->object_level = depth;
1881+
1882+ floor_ptr->town_num = wilderness[world_y][world_x].town;
1883+ floor_ptr->floor_turn = 1;
1884+
1885+ // Fill the arrays of floors and walls in the good proportions
1886+ set_floor_and_wall(floor_ptr->dungeon_id);
1887+
1888+ // Generate
1889+ if(depth <= 0) generate_floor_wilderness(floor_ptr);
1890+ else
1891+ {
1892+ for (num = 0; TRUE; num++)
1893+ {
1894+ bool okay = TRUE;
1895+ cptr why = NULL;
1896+ clear_cave(floor_ptr); // Clear and empty the cave
1897+
1898+ okay = generate_floor_dungeon(floor_ptr, &why);
1899+
1900+ // Prevent object over-flow
1901+ if(object_max >= max_object_idx)
1902+ {
1903+ why = MES_DEBUG_TOO_ITEM;
1904+ okay = FALSE;
1905+ }
1906+ else if(creature_max >= max_creature_idx)
1907+ {
1908+ why = MES_DEBUG_TOO_CREATURE;
1909+ okay = FALSE;
1910+ }
1911+
1912+ if(okay) break;
1913+ if(why) msg_format(MES_DEBUG_FLOOR_RETAKE(why));
1914+ wipe_object_list(0);
1915+ wipe_creature_list(0);
1916+ }
1917+ }
1918+
1919+ // Glow deep lava and building entrances
1920+ glow_deep_lava_and_bldg(floor_ptr);
1921+
1922+ // Reset flag
1923+ player_ptr->enter_dungeon = FALSE;
1924+ wipe_generate_floor_flags(floor_ptr);
1925+
1926+ // Hack -- Munchkin characters always get whole map
1927+ if(player_ptr->chara_idx == CHARA_MUNCHKIN) wiz_lite(floor_ptr, player_ptr, (bool)(player_ptr->class_idx == CLASS_NINJA));
1928+
1929+ floor_ptr->generated = TRUE;
1930+ return TRUE;
1931+}
--- source/trunk/src/floors.h (revision 9114)
+++ source/trunk/src/floors.h (revision 9115)
@@ -8,3 +8,10 @@
88 extern void reset_cave_creature_reference(void);
99 extern FLOOR_ID get_floor_idx(floor_type *floor_ptr);
1010
11+// generate.c
12+extern void wipe_generate_floor_flags(floor_type *floor_ptr);
13+extern void clear_cave(floor_type *floor_ptr);
14+extern bool generate_floor(floor_type *floor_ptr, DUNGEON_ID dungeon_id, COODINATES world_y, COODINATES world_x, FLOOR_LEV depth);
15+extern void generate_floor_quest(floor_type *floor_ptr, QUEST_ID quest_id);
16+extern void generate_floor_arena(floor_type *floor_ptr, COODINATES height, COODINATES width);
17+extern void generate_floor_creature_arena(floor_type *floor_ptr);
Show on old repository browser