OSDN Git Service

rearrange main dungeon
[nethackexpress/trunk.git] / src / rect.c
1 /*      SCCS Id: @(#)rect.c     3.4     1990/02/22      */
2 /* Copyright (c) 1990 by Jean-Christophe Collet  */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "hack.h"
6
7 int FDECL(get_rect_ind, (NhRect *));
8
9 static boolean FDECL(intersect, (NhRect *,NhRect *,NhRect *));
10
11     /*
12      * In this file, we will handle the various rectangle functions we
13      * need for room generation.
14      */
15
16 #define MAXRECT 50
17 #define XLIM    4
18 #define YLIM    3
19
20 static NhRect rect[MAXRECT+1];
21 static int rect_cnt;
22
23 /*
24  * Initialisation of internal structures. Should be called for every
25  * new level to be build...
26  */
27
28 void
29 init_rect()
30 {
31         rect_cnt = 1;
32         rect[0].lx = rect[0].ly = 0;
33         rect[0].hx = COLNO - 1;
34         rect[0].hy = ROWNO - 1;
35 }
36
37 /*
38  * Search Index of one precise NhRect.
39  *
40  */
41
42 int
43 get_rect_ind(r)
44 NhRect *r;
45 {
46         register NhRect *rectp;
47         register int lx, ly, hx, hy;
48         register int i;
49
50         lx = r->lx; ly = r->ly;
51         hx = r->hx; hy = r->hy;
52         for (i=0,rectp = &rect[0];i<rect_cnt;i++,rectp++)
53             if ( lx == rectp->lx && ly == rectp->ly &&
54                  hx == rectp->hx && hy == rectp->hy)
55                 return i;
56         return -1;
57 }
58
59 /*
60  * Search a free rectangle that include the one given in arg
61  */
62
63 NhRect *
64 get_rect(r)
65 NhRect *r;
66 {
67         register NhRect *rectp;
68         register int lx, ly, hx, hy;
69         register int i;
70
71         lx = r->lx; ly = r->ly;
72         hx = r->hx; hy = r->hy;
73         for (i=0,rectp = &rect[0];i<rect_cnt;i++,rectp++)
74             if ( lx >= rectp->lx && ly >= rectp->ly &&
75                  hx <= rectp->hx && hy <= rectp->hy)
76                 return rectp;
77         return 0;
78 }
79
80 /*
81  * Get some random NhRect from the list.
82  */
83
84 NhRect *
85 rnd_rect()
86 {
87             return rect_cnt > 0 ? &rect[rn2(rect_cnt)] : 0;
88 }
89
90 /*
91  * Search intersection between two rectangles (r1 & r2).
92  * return TRUE if intersection exist and put it in r3.
93  * otherwise returns FALSE
94  */
95
96 static boolean
97 intersect(r1, r2, r3)
98 NhRect *r1, *r2, *r3;
99 {
100         if (r2->lx > r1->hx || r2->ly > r1->hy ||
101             r2->hx < r1->lx || r2->hy < r1->ly)
102             return FALSE;
103
104         r3->lx = (r2->lx > r1->lx ? r2->lx : r1->lx);
105         r3->ly = (r2->ly > r1->ly ? r2->ly : r1->ly);
106         r3->hx = (r2->hx > r1->hx ? r1->hx : r2->hx);
107         r3->hy = (r2->hy > r1->hy ? r1->hy : r2->hy);
108
109         if (r3->lx > r3->hx || r3->ly > r3->hy)
110             return FALSE;
111         return TRUE;
112 }
113
114 /*
115  * Remove a rectangle from the list of free NhRect.
116  */
117
118 void
119 remove_rect(r)
120 NhRect *r;
121 {
122         int ind;
123
124         ind = get_rect_ind(r);
125         if ( ind >=0 )
126             rect[ind] = rect[--rect_cnt];
127 }
128
129 /*
130  * Add a NhRect to the list.
131  */
132
133 void
134 add_rect(r)
135 NhRect *r;
136 {
137         if (rect_cnt >= MAXRECT) {
138 #ifdef WIZARD
139                 if (wizard) pline("MAXRECT may be too small.");
140 #endif
141                 return;
142         }
143         /* Check that this NhRect is not included in another one */
144         if (get_rect(r))
145             return;
146         rect[rect_cnt] = *r;
147         rect_cnt++;
148 }
149
150 /*
151  * Okay, here we have two rectangles (r1 & r2).
152  * r1 was already in the list and r2 is included in r1.
153  * What we want is to allocate r2, that is split r1 into smaller rectangles
154  * then remove it.
155  */
156
157 void
158 split_rects(r1, r2)
159 NhRect *r1, *r2;
160 {
161         NhRect r, old_r;
162         int i;
163
164         old_r = *r1;
165         remove_rect(r1);
166
167         /* Walk down since rect_cnt & rect[] will change... */
168         for (i=rect_cnt-1; i>=0; i--)
169             if (intersect(&rect[i], r2, &r))
170                 split_rects(&rect[i], &r);
171         
172         if (r2->ly - old_r.ly-1 > (old_r.hy < ROWNO - 1 ? 2*YLIM : YLIM+1)+4) {
173                 r = old_r;
174                 r.hy = r2->ly - 2;
175                 add_rect(&r);
176         }
177         if (r2->lx - old_r.lx-1 > (old_r.hx < COLNO - 1 ? 2*XLIM : XLIM+1)+4) {
178                 r = old_r;
179                 r.hx = r2->lx - 2;
180                 add_rect(&r);
181         }
182         if (old_r.hy - r2->hy-1 > (old_r.ly > 0 ? 2*YLIM : YLIM+1)+4) {
183                 r = old_r;
184                 r.ly = r2->hy + 2;
185                 add_rect(&r);
186         }
187         if (old_r.hx - r2->hx-1 > (old_r.lx > 0 ? 2*XLIM : XLIM+1)+4) {
188                 r = old_r;
189                 r.lx = r2->hx + 2;
190                 add_rect(&r);
191         }
192 }
193
194 /*rect.c*/