1 /**
2 * @file drlg_l1.cpp
3 *
4 * Implementation of the cathedral level generation algorithms.
5 */
6 #include "all.h"
7
8 DEVILUTION_BEGIN_NAMESPACE
9
10 int UberRow;
11 int UberCol;
12 bool IsUberRoomOpened;
13 int UberLeverRow;
14 int UberLeverCol;
15 bool IsUberLeverActivated;
16 int UberDiabloMonsterIndex;
17
18 namespace {
19
20 /** Represents a tile ID map of twice the size, repeating each tile of the original map in blocks of 4. */
21 BYTE L5dungeon[80][80];
22 BYTE L5dflags[DMAXX][DMAXY];
23 /** Specifies whether a single player quest DUN has been loaded. */
24 BOOL L5setloadflag;
25 /** Specifies whether to generate a horizontal room at position 1 in the Cathedral. */
26 int HR1;
27 /** Specifies whether to generate a horizontal room at position 2 in the Cathedral. */
28 int HR2;
29 /** Specifies whether to generate a horizontal room at position 3 in the Cathedral. */
30 int HR3;
31
32 /** Specifies whether to generate a vertical room at position 1 in the Cathedral. */
33 BOOL VR1;
34 /** Specifies whether to generate a vertical room at position 2 in the Cathedral. */
35 BOOL VR2;
36 /** Specifies whether to generate a vertical room at position 3 in the Cathedral. */
37 BOOL VR3;
38 /** Contains the contents of the single player quest DUN file. */
39 BYTE *L5pSetPiece;
40
41 /** Contains shadows for 2x2 blocks of base tile IDs in the Cathedral. */
42 const ShadowStruct SPATS[37] = {
43 // clang-format off
44 // strig, s1, s2, s3, nv1, nv2, nv3
45 { 7, 13, 0, 13, 144, 0, 142 },
46 { 16, 13, 0, 13, 144, 0, 142 },
47 { 15, 13, 0, 13, 145, 0, 142 },
48 { 5, 13, 13, 13, 152, 140, 139 },
49 { 5, 13, 1, 13, 143, 146, 139 },
50 { 5, 13, 13, 2, 143, 140, 148 },
51 { 5, 0, 1, 2, 0, 146, 148 },
52 { 5, 13, 11, 13, 143, 147, 139 },
53 { 5, 13, 13, 12, 143, 140, 149 },
54 { 5, 13, 11, 12, 150, 147, 149 },
55 { 5, 13, 1, 12, 143, 146, 149 },
56 { 5, 13, 11, 2, 143, 147, 148 },
57 { 9, 13, 13, 13, 144, 140, 142 },
58 { 9, 13, 1, 13, 144, 146, 142 },
59 { 9, 13, 11, 13, 151, 147, 142 },
60 { 8, 13, 0, 13, 144, 0, 139 },
61 { 8, 13, 0, 12, 143, 0, 149 },
62 { 8, 0, 0, 2, 0, 0, 148 },
63 { 11, 0, 0, 13, 0, 0, 139 },
64 { 11, 13, 0, 13, 139, 0, 139 },
65 { 11, 2, 0, 13, 148, 0, 139 },
66 { 11, 12, 0, 13, 149, 0, 139 },
67 { 11, 13, 11, 12, 139, 0, 149 },
68 { 14, 0, 0, 13, 0, 0, 139 },
69 { 14, 13, 0, 13, 139, 0, 139 },
70 { 14, 2, 0, 13, 148, 0, 139 },
71 { 14, 12, 0, 13, 149, 0, 139 },
72 { 14, 13, 11, 12, 139, 0, 149 },
73 { 10, 0, 13, 0, 0, 140, 0 },
74 { 10, 13, 13, 0, 140, 140, 0 },
75 { 10, 0, 1, 0, 0, 146, 0 },
76 { 10, 13, 11, 0, 140, 147, 0 },
77 { 12, 0, 13, 0, 0, 140, 0 },
78 { 12, 13, 13, 0, 140, 140, 0 },
79 { 12, 0, 1, 0, 0, 146, 0 },
80 { 12, 13, 11, 0, 140, 147, 0 },
81 { 3, 13, 11, 12, 150, 0, 0 }
82 // clang-format on
83 };
84
85 // BUGFIX: This array should contain an additional 0 (207 elements).
86 /** Maps tile IDs to their corresponding base tile ID. */
87 const BYTE BSTYPES[] = {
88 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
89 10, 11, 12, 13, 14, 15, 16, 17, 0, 0,
90 0, 0, 0, 0, 0, 1, 2, 10, 4, 5,
91 6, 7, 8, 9, 10, 11, 12, 14, 5, 14,
92 10, 4, 14, 4, 5, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
96 2, 3, 4, 1, 6, 7, 16, 17, 2, 1,
97 1, 2, 2, 1, 1, 2, 2, 2, 2, 2,
98 1, 1, 11, 1, 13, 13, 13, 1, 2, 1,
99 2, 1, 2, 1, 2, 2, 2, 2, 12, 0,
100 0, 11, 1, 11, 1, 13, 0, 0, 0, 0,
101 0, 0, 0, 13, 13, 13, 13, 13, 13, 13,
102 13, 13, 13, 13, 13, 13, 1, 11, 2, 12,
103 13, 13, 13, 12, 2, 1, 2, 2, 4, 14,
104 4, 10, 13, 13, 4, 4, 1, 1, 4, 2,
105 2, 13, 13, 13, 13, 25, 26, 28, 30, 31,
106 41, 43, 40, 41, 42, 43, 25, 41, 43, 28,
107 28, 1, 2, 25, 26, 22, 22, 25, 26, 0,
108 0, 0, 0, 0, 0, 0, 0
109 };
110
111 // BUGFIX: This array should contain an additional 0 (207 elements) (fixed).
112 /** Maps tile IDs to their corresponding undecorated tile ID. */
113 const BYTE L5BTYPES[] = {
114 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
115 10, 11, 12, 13, 14, 15, 16, 17, 0, 0,
116 0, 0, 0, 0, 0, 25, 26, 0, 28, 0,
117 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
118 40, 41, 42, 43, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121 0, 0, 0, 0, 0, 0, 0, 0, 0, 79,
122 80, 0, 82, 0, 0, 0, 0, 0, 0, 79,
123 0, 80, 0, 0, 79, 80, 0, 2, 2, 2,
124 1, 1, 11, 25, 13, 13, 13, 1, 2, 1,
125 2, 1, 2, 1, 2, 2, 2, 2, 12, 0,
126 0, 11, 1, 11, 1, 13, 0, 0, 0, 0,
127 0, 0, 0, 13, 13, 13, 13, 13, 13, 0,
128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0
135 };
136 /** Miniset: stairs up on a corner wall. */
137 const BYTE STAIRSUP[] = {
138 // clang-format off
139 4, 4, // width, height
140
141 13, 13, 13, 13, // search
142 2, 2, 2, 2,
143 13, 13, 13, 13,
144 13, 13, 13, 13,
145
146 0, 66, 6, 0, // replace
147 63, 64, 65, 0,
148 0, 67, 68, 0,
149 0, 0, 0, 0,
150 // clang-format on
151 };
152 const BYTE L5STAIRSUPHF[] = {
153 // clang-format off
154 4, 5, // width, height
155
156 22, 22, 22, 22, // search
157 22, 22, 22, 22,
158 2, 2, 2, 2,
159 13, 13, 13, 13,
160 13, 13, 13, 13,
161
162 0, 54, 23, 0, // replace
163 0, 53, 18, 0,
164 55, 56, 57, 0,
165 58, 59, 60, 0,
166 0, 0, 0, 0
167 // clang-format on
168 };
169 /** Miniset: stairs up. */
170 const BYTE L5STAIRSUP[] = {
171 // clang-format off
172 4, 4, // width, height
173
174 22, 22, 22, 22, // search
175 2, 2, 2, 2,
176 13, 13, 13, 13,
177 13, 13, 13, 13,
178
179 0, 66, 23, 0, // replace
180 63, 64, 65, 0,
181 0, 67, 68, 0,
182 0, 0, 0, 0,
183 // clang-format on
184 };
185 /** Miniset: stairs down. */
186 const BYTE STAIRSDOWN[] = {
187 // clang-format off
188 4, 3, // width, height
189
190 13, 13, 13, 13, // search
191 13, 13, 13, 13,
192 13, 13, 13, 13,
193
194 62, 57, 58, 0, // replace
195 61, 59, 60, 0,
196 0, 0, 0, 0,
197 // clang-format on
198 };
199 const BYTE L5STAIRSDOWN[] = {
200 // clang-format off
201 4, 5, // width, height
202
203 13, 13, 13, 13, // search
204 13, 13, 13, 13,
205 13, 13, 13, 13,
206 13, 13, 13, 13,
207 13, 13, 13, 13,
208
209 0, 0, 52, 0, // replace
210 0, 48, 51, 0,
211 0, 47, 50, 0,
212 45, 46, 49, 0,
213 0, 0, 0, 0,
214 // clang-format on
215 };
216 const BYTE L5STAIRSTOWN[] = {
217 // clang-format off
218 4, 5, // width, height
219
220 22, 22, 22, 22, // search
221 22, 22, 22, 22,
222 2, 2, 2, 2,
223 13, 13, 13, 13,
224 13, 13, 13, 13,
225
226 0, 62, 23, 0, // replace
227 0, 61, 18, 0,
228 63, 64, 65, 0,
229 66, 67, 68, 0,
230 0, 0, 0, 0,
231 // clang-format on
232 };
233 /** Miniset: candlestick. */
234 const BYTE LAMPS[] = {
235 // clang-format off
236 2, 2, // width, height
237
238 13, 0, // search
239 13, 13,
240
241 129, 0, // replace
242 130, 128,
243 // clang-format on
244 };
245 /** Miniset: Poisoned Water Supply entrance. */
246 const BYTE PWATERIN[] = {
247 // clang-format off
248 6, 6, // width, height
249
250 13, 13, 13, 13, 13, 13, // search
251 13, 13, 13, 13, 13, 13,
252 13, 13, 13, 13, 13, 13,
253 13, 13, 13, 13, 13, 13,
254 13, 13, 13, 13, 13, 13,
255 13, 13, 13, 13, 13, 13,
256
257 0, 0, 0, 0, 0, 0, // replace
258 0, 202, 200, 200, 84, 0,
259 0, 199, 203, 203, 83, 0,
260 0, 85, 206, 80, 81, 0,
261 0, 0, 134, 135, 0, 0,
262 0, 0, 0, 0, 0, 0,
263 // clang-format on
264 };
265 const BYTE byte_48A1B4[4] = { 1, 1, 11, 95 };
266 const BYTE byte_48A1B8[8] = { 1, 1, 12, 96 };
267 const BYTE byte_48A1C0[8] = {
268 // clang-format off
269 1, 3, // width, height
270
271 1, // search
272 1,
273 1,
274
275 91, // replace
276 90,
277 89,
278 // clang-format on
279 };
280 const BYTE byte_48A1C8[8] = {
281 // clang-format off
282 3, 1, // width, height
283
284 2, 2, 2, // search
285
286 94, 93, 92, // replace
287 // clang-format on
288 };
289 const BYTE byte_48A1D0[4] = { 1, 1, 13, 97 };
290 const BYTE byte_48A1D4[4] = { 1, 1, 13, 98 };
291 const BYTE byte_48A1D8[4] = { 1, 1, 13, 99 };
292 const BYTE byte_48A1DC[4] = { 1, 1, 13, 100 };
293 const BYTE byte_48A1E0[20] = {
294 // clang-format off
295 3, 3, // width, height
296
297 13, 13, 13, // search
298 13, 13, 13,
299 13, 13, 13,
300
301 0, 0, 0, // replace
302 0, 101, 0,
303 0, 0, 0,
304 // clang-format on
305 };
306 const BYTE byte_48A1F4[4] = { 1, 1, 11, 185 };
307 const BYTE byte_48A1F8[4] = { 1, 1, 11, 186 };
308 const BYTE byte_48A1FC[4] = { 1, 1, 12, 187 };
309 const BYTE byte_48A200[4] = { 1, 1, 12, 188 };
310 const BYTE byte_48A204[4] = { 1, 1, 89, 173 };
311 const BYTE byte_48A208[4] = { 1, 1, 89, 174 };
312 const BYTE byte_48A20C[4] = { 1, 1, 90, 175 };
313 const BYTE byte_48A210[4] = { 1, 1, 90, 176 };
314 const BYTE byte_48A214[4] = { 1, 1, 91, 177 };
315 const BYTE byte_48A218[4] = { 1, 1, 91, 178 };
316 const BYTE byte_48A21C[4] = { 1, 1, 92, 179 };
317 const BYTE byte_48A220[4] = { 1, 1, 92, 180 };
318 const BYTE byte_48A224[4] = { 1, 1, 92, 181 };
319 const BYTE byte_48A228[4] = { 1, 1, 92, 182 };
320 const BYTE byte_48A22C[4] = { 1, 1, 92, 183 };
321 const BYTE byte_48A230[4] = { 1, 1, 92, 184 };
322 const BYTE byte_48A234[4] = { 1, 1, 98, 189 };
323 const BYTE byte_48A238[4] = { 1, 1, 98, 190 };
324 const BYTE byte_48A23C[4] = { 1, 1, 97, 191 };
325 const BYTE byte_48A240[4] = { 1, 1, 15, 192 };
326 const BYTE byte_48A244[4] = { 1, 1, 99, 193 };
327 const BYTE byte_48A248[4] = { 1, 1, 99, 194 };
328 const BYTE byte_48A24C[4] = { 1, 1, 100, 195 };
329 const BYTE byte_48A250[4] = { 1, 1, 101, 196 };
330 const BYTE byte_48A254[4] = { 1, 1, 101, 197 };
331 const BYTE byte_48A258[8] = { 1, 1, 101, 198 };
332 const BYTE byte_48A260[24] = {
333 // clang-format off
334 3, 3, // width, height
335
336 13, 13, 13, // search
337 13, 13, 13,
338 13, 13, 13,
339
340 0, 0, 0, // replace
341 0, 167, 0,
342 0, 0, 0,
343 // clang-format on
344 };
345 const BYTE byte_48A278[24] = {
346 // clang-format off
347 3, 3, // width, height
348
349 13, 13, 13, // search
350 13, 13, 13,
351 13, 13, 13,
352
353 0, 0, 0, // replace
354 0, 168, 0,
355 0, 0, 0,
356 // clang-format on
357 };
358 const BYTE byte_48A290[24] = {
359 // clang-format off
360 3, 3, // width, height
361
362 13, 13, 13, // search
363 13, 13, 13,
364 13, 13, 13,
365
366 0, 0, 0, // replace
367 0, 169, 0,
368 0, 0, 0,
369 };
370 const BYTE byte_48A2A8[24] = {
371 // clang-format off
372 3, 3, // width, height
373
374 13, 13, 13, // search
375 13, 13, 13,
376 13, 13, 13,
377
378 0, 0, 0, // replace
379 0, 170, 0,
380 0, 0, 0,
381 // clang-format on
382 };
383 const BYTE byte_48A2C0[24] = {
384 // clang-format off
385 3, 3, // width, height
386
387 13, 13, 13, // search
388 13, 13, 13,
389 13, 13, 13,
390
391 0, 0, 0, // replace
392 0, 171, 0,
393 0, 0, 0,
394 // clang-format on
395 };
396 const BYTE byte_48A2D8[20] = {
397 // clang-format off
398 3, 3, // width, height
399
400 13, 13, 13, // search
401 13, 13, 13,
402 13, 13, 13,
403
404 0, 0, 0, // replace
405 0, 172, 0,
406 0, 0, 0,
407 // clang-format on
408 };
409 const BYTE byte_48A2EC[4] = { 1, 1, 13, 163 };
410 const BYTE byte_48A2F0[4] = { 1, 1, 13, 164 };
411 const BYTE byte_48A2F4[4] = { 1, 1, 13, 165 };
412 const BYTE byte_48A2F8[4] = { 1, 1, 13, 166 };
413 const BYTE byte_48A2FC[4] = { 1, 1, 1, 112 };
414 const BYTE byte_48A300[4] = { 1, 1, 2, 113 };
415 const BYTE byte_48A304[4] = { 1, 1, 3, 114 };
416 const BYTE byte_48A308[4] = { 1, 1, 4, 115 };
417 const BYTE byte_48A30C[4] = { 1, 1, 5, 116 };
418 const BYTE byte_48A310[4] = { 1, 1, 6, 117 };
419 const BYTE byte_48A314[4] = { 1, 1, 7, 118 };
420 const BYTE byte_48A318[4] = { 1, 1, 8, 119 };
421 const BYTE byte_48A31C[4] = { 1, 1, 9, 120 };
422 const BYTE byte_48A320[4] = { 1, 1, 10, 121 };
423 const BYTE byte_48A324[4] = { 1, 1, 11, 122 };
424 const BYTE byte_48A328[4] = { 1, 1, 12, 123 };
425 const BYTE byte_48A32C[4] = { 1, 1, 13, 124 };
426 const BYTE byte_48A330[4] = { 1, 1, 14, 125 };
427 const BYTE byte_48A334[4] = { 1, 1, 15, 126 };
428 const BYTE byte_48A338[4] = { 1, 1, 16, 127 };
429 const BYTE byte_48A33C[4] = { 1, 1, 17, 128 };
430 const BYTE byte_48A340[4] = { 1, 1, 1, 129 };
431 const BYTE byte_48A344[4] = { 1, 1, 2, 130 };
432 const BYTE byte_48A348[4] = { 1, 1, 3, 131 };
433 const BYTE byte_48A34C[4] = { 1, 1, 4, 132 };
434 const BYTE byte_48A350[4] = { 1, 1, 5, 133 };
435 const BYTE byte_48A354[4] = { 1, 1, 6, 134 };
436 const BYTE byte_48A358[4] = { 1, 1, 7, 135 };
437 const BYTE byte_48A35C[4] = { 1, 1, 8, 136 };
438 const BYTE byte_48A360[4] = { 1, 1, 9, 137 };
439 const BYTE byte_48A364[4] = { 1, 1, 10, 138 };
440 const BYTE byte_48A368[4] = { 1, 1, 11, 139 };
441 const BYTE byte_48A36C[4] = { 1, 1, 12, 140 };
442 const BYTE byte_48A370[4] = { 1, 1, 13, 141 };
443 const BYTE byte_48A374[4] = { 1, 1, 14, 142 };
444 const BYTE byte_48A378[4] = { 1, 1, 15, 143 };
445 const BYTE byte_48A37C[4] = { 1, 1, 16, 144 };
446 const BYTE byte_48A380[4] = { 1, 1, 17, 145 };
447 const BYTE byte_48A384[4] = { 1, 1, 1, 146 };
448 const BYTE byte_48A388[4] = { 1, 1, 2, 147 };
449 const BYTE byte_48A38C[4] = { 1, 1, 3, 148 };
450 const BYTE byte_48A390[4] = { 1, 1, 4, 149 };
451 const BYTE byte_48A394[4] = { 1, 1, 5, 150 };
452 const BYTE byte_48A398[4] = { 1, 1, 6, 151 };
453 const BYTE byte_48A39C[4] = { 1, 1, 7, 152 };
454 const BYTE byte_48A3A0[4] = { 1, 1, 8, 153 };
455 const BYTE byte_48A3A4[4] = { 1, 1, 9, 154 };
456 const BYTE byte_48A3A8[4] = { 1, 1, 10, 155 };
457 const BYTE byte_48A3AC[4] = { 1, 1, 11, 156 };
458 const BYTE byte_48A3B0[4] = { 1, 1, 12, 157 };
459 const BYTE byte_48A3B4[4] = { 1, 1, 13, 158 };
460 const BYTE byte_48A3B8[4] = { 1, 1, 14, 159 };
461 const BYTE byte_48A3BC[4] = { 1, 1, 15, 160 };
462 const BYTE byte_48A3C0[4] = { 1, 1, 16, 161 };
463 const BYTE byte_48A3C4[4] = { 1, 1, 17, 162 };
464 const BYTE byte_48A3C8[4] = { 1, 1, 1, 199 };
465 const BYTE byte_48A3CC[4] = { 1, 1, 1, 201 };
466 const BYTE byte_48A3D0[4] = { 1, 1, 2, 200 };
467 const BYTE byte_48A3D4[4] = { 1, 1, 2, 202 };
468
469 /* data */
470
471 BYTE UberRoomPattern[32] = { 4, 6, 115, 130, 6, 13, 129, 108, 1, 13, 1, 107, 103, 13, 146, 106, 102, 13, 129, 168, 1, 13, 7, 2, 3, 13, 0, 0, 0, 0, 0, 0 };
472 BYTE CornerstoneRoomPattern[32] = { 5, 5, 4, 2, 2, 2, 6, 1, 111, 172, 0, 1, 1, 172, 0, 0, 25, 1, 0, 0, 0, 1, 7, 2, 2, 2, 3, 0, 0, 0, 0, 0 };
473 /**
474 * A lookup table for the 16 possible patterns of a 2x2 area,
475 * where each cell either contains a SW wall or it doesn't.
476 */
477 BYTE L5ConvTbl[16] = { 22, 13, 1, 13, 2, 13, 13, 13, 4, 13, 1, 13, 2, 13, 16, 13 };
478
479 } // namespace
480
DRLG_InitL5Vals()481 void DRLG_InitL5Vals()
482 {
483 int i, j, pc;
484
485 for (j = 0; j < MAXDUNY; j++) {
486 for (i = 0; i < MAXDUNX; i++) {
487 if (dPiece[i][j] == 77) {
488 pc = 1;
489 } else if (dPiece[i][j] == 80) {
490 pc = 2;
491 } else {
492 continue;
493 }
494 dSpecial[i][j] = pc;
495 }
496 }
497 }
498
DRLG_PlaceDoor(int x,int y)499 static void DRLG_PlaceDoor(int x, int y)
500 {
501 if ((L5dflags[x][y] & DLRG_PROTECTED) == 0) {
502 BYTE df = L5dflags[x][y] & 0x7F;
503 BYTE c = dungeon[x][y];
504
505 if (df == 1) {
506 if (y != 1 && c == 2)
507 dungeon[x][y] = 26;
508 if (y != 1 && c == 7)
509 dungeon[x][y] = 31;
510 if (y != 1 && c == 14)
511 dungeon[x][y] = 42;
512 if (y != 1 && c == 4)
513 dungeon[x][y] = 43;
514 if (x != 1 && c == 1)
515 dungeon[x][y] = 25;
516 if (x != 1 && c == 10)
517 dungeon[x][y] = 40;
518 if (x != 1 && c == 6)
519 dungeon[x][y] = 30;
520 }
521 if (df == 2) {
522 if (x != 1 && c == 1)
523 dungeon[x][y] = 25;
524 if (x != 1 && c == 6)
525 dungeon[x][y] = 30;
526 if (x != 1 && c == 10)
527 dungeon[x][y] = 40;
528 if (x != 1 && c == 4)
529 dungeon[x][y] = 41;
530 if (y != 1 && c == 2)
531 dungeon[x][y] = 26;
532 if (y != 1 && c == 14)
533 dungeon[x][y] = 42;
534 if (y != 1 && c == 7)
535 dungeon[x][y] = 31;
536 }
537 if (df == 3) {
538 if (x != 1 && y != 1 && c == 4)
539 dungeon[x][y] = 28;
540 if (x != 1 && c == 10)
541 dungeon[x][y] = 40;
542 if (y != 1 && c == 14)
543 dungeon[x][y] = 42;
544 if (y != 1 && c == 2)
545 dungeon[x][y] = 26;
546 if (x != 1 && c == 1)
547 dungeon[x][y] = 25;
548 if (y != 1 && c == 7)
549 dungeon[x][y] = 31;
550 if (x != 1 && c == 6)
551 dungeon[x][y] = 30;
552 }
553 }
554
555 L5dflags[x][y] = DLRG_PROTECTED;
556 }
557
drlg_l1_crypt_lavafloor()558 void drlg_l1_crypt_lavafloor()
559 {
560 int i, j;
561
562 for (j = 1; j < 40; j++) {
563 for (i = 1; i < 40; i++) {
564 switch (dungeon[i][j]) {
565 case 5:
566 if (dungeon[i - 1][j] == 13)
567 dungeon[i - 1][j] = 203;
568 if (dungeon[i - 1][j - 1] == 13)
569 dungeon[i - 1][j - 1] = 204;
570 if (dungeon[i][j - 1] == 13)
571 dungeon[i][j - 1] = 205;
572 break;
573 case 7:
574 if (dungeon[i - 1][j] == 13)
575 dungeon[i - 1][j] = 206;
576 if (dungeon[i - 1][j - 1] == 13)
577 dungeon[i - 1][j - 1] = 207;
578 break;
579 case 8:
580 if (dungeon[i - 1][j] == 13)
581 dungeon[i - 1][j] = 203;
582 if (dungeon[i - 1][j - 1] == 13)
583 dungeon[i - 1][j - 1] = 204;
584 break;
585 case 9:
586 if (dungeon[i - 1][j] == 13)
587 dungeon[i - 1][j] = 206;
588 if (dungeon[i - 1][j - 1] == 13)
589 dungeon[i - 1][j - 1] = 207;
590 if (dungeon[i][j - 1] == 13)
591 dungeon[i][j - 1] = 205;
592 break;
593 case 10:
594 if (dungeon[i][j - 1] == 13)
595 dungeon[i][j - 1] = 205;
596 break;
597 case 11:
598 if (dungeon[i - 1][j] == 13)
599 dungeon[i - 1][j] = 203;
600 if (dungeon[i - 1][j - 1] == 13)
601 dungeon[i - 1][j - 1] = 204;
602 break;
603 case 12:
604 if (dungeon[i][j - 1] == 13)
605 dungeon[i][j - 1] = 205;
606 break;
607 case 14:
608 if (dungeon[i - 1][j] == 13)
609 dungeon[i - 1][j] = 203;
610 if (dungeon[i - 1][j - 1] == 13)
611 dungeon[i - 1][j - 1] = 204;
612 break;
613 case 15:
614 if (dungeon[i - 1][j] == 13)
615 dungeon[i - 1][j] = 206;
616 if (dungeon[i - 1][j - 1] == 13)
617 dungeon[i - 1][j - 1] = 207;
618 break;
619 case 17:
620 if (dungeon[i - 1][j] == 13)
621 dungeon[i - 1][j] = 206;
622 if (dungeon[i - 1][j - 1] == 13)
623 dungeon[i - 1][j - 1] = 207;
624 break;
625 case 95:
626 if (dungeon[i - 1][j] == 13)
627 dungeon[i - 1][j] = 203;
628 if (dungeon[i - 1][j - 1] == 13)
629 dungeon[i - 1][j - 1] = 204;
630 break;
631 case 96:
632 if (dungeon[i][j - 1] == 13)
633 dungeon[i][j - 1] = 208;
634 break;
635 case 116:
636 if (dungeon[i - 1][j] == 13)
637 dungeon[i - 1][j] = 203;
638 if (dungeon[i - 1][j - 1] == 13)
639 dungeon[i - 1][j - 1] = 204;
640 if (dungeon[i][j - 1] == 13)
641 dungeon[i][j - 1] = 205;
642 break;
643 case 118:
644 if (dungeon[i - 1][j] == 13)
645 dungeon[i - 1][j] = 206;
646 if (dungeon[i - 1][j - 1] == 13)
647 dungeon[i - 1][j - 1] = 207;
648 break;
649 case 119:
650 if (dungeon[i - 1][j] == 13)
651 dungeon[i - 1][j] = 203;
652 if (dungeon[i - 1][j - 1] == 13)
653 dungeon[i - 1][j - 1] = 204;
654 break;
655 case 120:
656 if (dungeon[i - 1][j] == 13)
657 dungeon[i - 1][j] = 206;
658 if (dungeon[i - 1][j - 1] == 13)
659 dungeon[i - 1][j - 1] = 207;
660 if (dungeon[i][j - 1] == 13)
661 dungeon[i][j - 1] = 205;
662 break;
663 case 121:
664 if (dungeon[i][j - 1] == 13)
665 dungeon[i][j - 1] = 205;
666 break;
667 case 122:
668 if (dungeon[i - 1][j] == 13)
669 dungeon[i - 1][j] = 211;
670 if (dungeon[i - 1][j - 1] == 13)
671 dungeon[i - 1][j - 1] = 212;
672 break;
673 case 123:
674 if (dungeon[i][j - 1] == 13)
675 dungeon[i][j - 1] = 205;
676 break;
677 case 125:
678 if (dungeon[i - 1][j] == 13)
679 dungeon[i - 1][j] = 203;
680 if (dungeon[i - 1][j - 1] == 13)
681 dungeon[i - 1][j - 1] = 204;
682 break;
683 case 126:
684 if (dungeon[i - 1][j] == 13)
685 dungeon[i - 1][j] = 206;
686 if (dungeon[i - 1][j - 1] == 13)
687 dungeon[i - 1][j - 1] = 207;
688 break;
689 case 128:
690 if (dungeon[i - 1][j] == 13)
691 dungeon[i - 1][j] = 206;
692 if (dungeon[i - 1][j - 1] == 13)
693 dungeon[i - 1][j - 1] = 207;
694 break;
695 case 133:
696 if (dungeon[i - 1][j] == 13)
697 dungeon[i - 1][j] = 203;
698 if (dungeon[i - 1][j - 1] == 13)
699 dungeon[i - 1][j - 1] = 204;
700 if (dungeon[i][j - 1] == 13)
701 dungeon[i][j - 1] = 205;
702 break;
703 case 135:
704 if (dungeon[i - 1][j] == 13)
705 dungeon[i - 1][j] = 206;
706 if (dungeon[i - 1][j - 1] == 13)
707 dungeon[i - 1][j - 1] = 207;
708 break;
709 case 136:
710 if (dungeon[i - 1][j] == 13)
711 dungeon[i - 1][j] = 203;
712 if (dungeon[i - 1][j - 1] == 13)
713 dungeon[i - 1][j - 1] = 204;
714 break;
715 case 137:
716 if (dungeon[i - 1][j] == 13)
717 dungeon[i - 1][j] = 213;
718 if (dungeon[i - 1][j - 1] == 13)
719 dungeon[i - 1][j - 1] = 214;
720 if (dungeon[i][j - 1] == 13)
721 dungeon[i][j - 1] = 205;
722 break;
723 case 138:
724 if (dungeon[i][j - 1] == 13)
725 dungeon[i][j - 1] = 205;
726 break;
727 case 139:
728 if (dungeon[i - 1][j] == 13)
729 dungeon[i - 1][j] = 215;
730 if (dungeon[i - 1][j - 1] == 13)
731 dungeon[i - 1][j - 1] = 216;
732 break;
733 case 140:
734 if (dungeon[i][j - 1] == 13)
735 dungeon[i][j - 1] = 217;
736 break;
737 case 142:
738 if (dungeon[i - 1][j] == 13)
739 dungeon[i - 1][j] = 203;
740 if (dungeon[i - 1][j - 1] == 13)
741 dungeon[i - 1][j - 1] = 204;
742 break;
743 case 143:
744 if (dungeon[i - 1][j] == 13)
745 dungeon[i - 1][j] = 213;
746 if (dungeon[i - 1][j - 1] == 13)
747 dungeon[i - 1][j - 1] = 214;
748 break;
749 case 145:
750 if (dungeon[i - 1][j] == 13)
751 dungeon[i - 1][j] = 213;
752 if (dungeon[i - 1][j - 1] == 13)
753 dungeon[i - 1][j - 1] = 214;
754 break;
755 case 150:
756 if (dungeon[i - 1][j] == 13)
757 dungeon[i - 1][j] = 203;
758 if (dungeon[i - 1][j - 1] == 13)
759 dungeon[i - 1][j - 1] = 204;
760 if (dungeon[i][j - 1] == 13)
761 dungeon[i][j - 1] = 217;
762 break;
763 case 152:
764 if (dungeon[i - 1][j] == 13)
765 dungeon[i - 1][j] = 206;
766 if (dungeon[i - 1][j - 1] == 13)
767 dungeon[i - 1][j - 1] = 207;
768 break;
769 case 153:
770 if (dungeon[i - 1][j] == 13)
771 dungeon[i - 1][j] = 203;
772 if (dungeon[i - 1][j - 1] == 13)
773 dungeon[i - 1][j - 1] = 204;
774 break;
775 case 154:
776 if (dungeon[i - 1][j] == 13)
777 dungeon[i - 1][j] = 206;
778 if (dungeon[i - 1][j - 1] == 13)
779 dungeon[i - 1][j - 1] = 207;
780 if (dungeon[i][j - 1] == 13)
781 dungeon[i][j - 1] = 205;
782 break;
783 case 155:
784 if (dungeon[i][j - 1] == 13)
785 dungeon[i][j - 1] = 205;
786 break;
787 case 156:
788 if (dungeon[i - 1][j] == 13)
789 dungeon[i - 1][j] = 203;
790 if (dungeon[i - 1][j - 1] == 13)
791 dungeon[i - 1][j - 1] = 204;
792 break;
793 case 157:
794 if (dungeon[i][j - 1] == 13)
795 dungeon[i][j - 1] = 217;
796 break;
797 case 159:
798 if (dungeon[i - 1][j] == 13)
799 dungeon[i - 1][j] = 203;
800 if (dungeon[i - 1][j - 1] == 13)
801 dungeon[i - 1][j - 1] = 204;
802 break;
803 case 160:
804 if (dungeon[i - 1][j] == 13)
805 dungeon[i - 1][j] = 206;
806 if (dungeon[i - 1][j - 1] == 13)
807 dungeon[i - 1][j - 1] = 207;
808 break;
809 case 162:
810 if (dungeon[i - 1][j] == 13)
811 dungeon[i - 1][j] = 209;
812 if (dungeon[i - 1][j - 1] == 13)
813 dungeon[i - 1][j - 1] = 210;
814 break;
815 case 167:
816 if (dungeon[i - 1][j] == 13)
817 dungeon[i - 1][j] = 209;
818 if (dungeon[i - 1][j - 1] == 13)
819 dungeon[i - 1][j - 1] = 210;
820 break;
821 case 187:
822 if (dungeon[i][j - 1] == 13)
823 dungeon[i][j - 1] = 208;
824 break;
825 case 185:
826 if (dungeon[i - 1][j] == 13)
827 dungeon[i - 1][j] = 203;
828 if (dungeon[i - 1][j - 1] == 13)
829 dungeon[i - 1][j - 1] = 204;
830 break;
831 case 186:
832 if (dungeon[i - 1][j] == 13)
833 dungeon[i - 1][j] = 203;
834 if (dungeon[i - 1][j - 1] == 13)
835 dungeon[i - 1][j - 1] = 204;
836 break;
837 case 192:
838 if (dungeon[i - 1][j] == 13)
839 dungeon[i - 1][j] = 209;
840 if (dungeon[i - 1][j - 1] == 13)
841 dungeon[i - 1][j - 1] = 210;
842 break;
843 }
844 }
845 }
846 }
847
DRLG_L1Shadows()848 static void DRLG_L1Shadows()
849 {
850 int x, y, i;
851 BYTE sd[2][2];
852 BYTE tnv3;
853 BOOL patflag;
854
855 for (y = 1; y < DMAXY; y++) {
856 for (x = 1; x < DMAXX; x++) {
857 sd[0][0] = BSTYPES[dungeon[x][y]];
858 sd[1][0] = BSTYPES[dungeon[x - 1][y]];
859 sd[0][1] = BSTYPES[dungeon[x][y - 1]];
860 sd[1][1] = BSTYPES[dungeon[x - 1][y - 1]];
861
862 for (i = 0; i < 37; i++) {
863 if (SPATS[i].strig == sd[0][0]) {
864 patflag = TRUE;
865 if (SPATS[i].s1 && SPATS[i].s1 != sd[1][1])
866 patflag = FALSE;
867 if (SPATS[i].s2 && SPATS[i].s2 != sd[0][1])
868 patflag = FALSE;
869 if (SPATS[i].s3 && SPATS[i].s3 != sd[1][0])
870 patflag = FALSE;
871 if (patflag == TRUE) {
872 if (SPATS[i].nv1 && !L5dflags[x - 1][y - 1])
873 dungeon[x - 1][y - 1] = SPATS[i].nv1;
874 if (SPATS[i].nv2 && !L5dflags[x][y - 1])
875 dungeon[x][y - 1] = SPATS[i].nv2;
876 if (SPATS[i].nv3 && !L5dflags[x - 1][y])
877 dungeon[x - 1][y] = SPATS[i].nv3;
878 }
879 }
880 }
881 }
882 }
883
884 for (y = 1; y < DMAXY; y++) {
885 for (x = 1; x < DMAXX; x++) {
886 if (dungeon[x - 1][y] == 139 && !L5dflags[x - 1][y]) {
887 tnv3 = 139;
888 if (dungeon[x][y] == 29)
889 tnv3 = 141;
890 if (dungeon[x][y] == 32)
891 tnv3 = 141;
892 if (dungeon[x][y] == 35)
893 tnv3 = 141;
894 if (dungeon[x][y] == 37)
895 tnv3 = 141;
896 if (dungeon[x][y] == 38)
897 tnv3 = 141;
898 if (dungeon[x][y] == 39)
899 tnv3 = 141;
900 dungeon[x - 1][y] = tnv3;
901 }
902 if (dungeon[x - 1][y] == 149 && !L5dflags[x - 1][y]) {
903 tnv3 = 149;
904 if (dungeon[x][y] == 29)
905 tnv3 = 153;
906 if (dungeon[x][y] == 32)
907 tnv3 = 153;
908 if (dungeon[x][y] == 35)
909 tnv3 = 153;
910 if (dungeon[x][y] == 37)
911 tnv3 = 153;
912 if (dungeon[x][y] == 38)
913 tnv3 = 153;
914 if (dungeon[x][y] == 39)
915 tnv3 = 153;
916 dungeon[x - 1][y] = tnv3;
917 }
918 if (dungeon[x - 1][y] == 148 && !L5dflags[x - 1][y]) {
919 tnv3 = 148;
920 if (dungeon[x][y] == 29)
921 tnv3 = 154;
922 if (dungeon[x][y] == 32)
923 tnv3 = 154;
924 if (dungeon[x][y] == 35)
925 tnv3 = 154;
926 if (dungeon[x][y] == 37)
927 tnv3 = 154;
928 if (dungeon[x][y] == 38)
929 tnv3 = 154;
930 if (dungeon[x][y] == 39)
931 tnv3 = 154;
932 dungeon[x - 1][y] = tnv3;
933 }
934 }
935 }
936 }
937
DRLG_PlaceMiniSet(const BYTE * miniset,int tmin,int tmax,int cx,int cy,BOOL setview,int noquad,int ldir)938 static int DRLG_PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, BOOL setview, int noquad, int ldir)
939 {
940 int sx, sy, sw, sh, xx, yy, i, ii, numt, found, t;
941 BOOL abort;
942
943 sw = miniset[0];
944 sh = miniset[1];
945
946 if (tmax - tmin == 0)
947 numt = 1;
948 else
949 numt = random_(0, tmax - tmin) + tmin;
950
951 for (i = 0; i < numt; i++) {
952 sx = random_(0, DMAXX - sw);
953 sy = random_(0, DMAXY - sh);
954 abort = FALSE;
955 found = 0;
956
957 while (abort == FALSE) {
958 abort = TRUE;
959 if (cx != -1 && sx >= cx - sw && sx <= cx + 12) {
960 sx++;
961 abort = FALSE;
962 }
963 if (cy != -1 && sy >= cy - sh && sy <= cy + 12) {
964 sy++;
965 abort = FALSE;
966 }
967
968 switch (noquad) {
969 case 0:
970 if (sx < cx && sy < cy)
971 abort = FALSE;
972 break;
973 case 1:
974 if (sx > cx && sy < cy)
975 abort = FALSE;
976 break;
977 case 2:
978 if (sx < cx && sy > cy)
979 abort = FALSE;
980 break;
981 case 3:
982 if (sx > cx && sy > cy)
983 abort = FALSE;
984 break;
985 }
986
987 ii = 2;
988
989 for (yy = 0; yy < sh && abort == TRUE; yy++) {
990 for (xx = 0; xx < sw && abort == TRUE; xx++) {
991 if (miniset[ii] && dungeon[xx + sx][sy + yy] != miniset[ii])
992 abort = FALSE;
993 if (L5dflags[xx + sx][sy + yy])
994 abort = FALSE;
995 ii++;
996 }
997 }
998
999 if (abort == FALSE) {
1000 if (++sx == DMAXX - sw) {
1001 sx = 0;
1002 if (++sy == DMAXY - sh)
1003 sy = 0;
1004 }
1005 if (++found > 4000)
1006 return -1;
1007 }
1008 }
1009
1010 ii = sw * sh + 2;
1011
1012 for (yy = 0; yy < sh; yy++) {
1013 for (xx = 0; xx < sw; xx++) {
1014 if (miniset[ii])
1015 dungeon[xx + sx][sy + yy] = miniset[ii];
1016 ii++;
1017 }
1018 }
1019 }
1020
1021 if (miniset == PWATERIN) {
1022 t = TransVal;
1023 TransVal = 0;
1024 DRLG_MRectTrans(sx, sy + 2, sx + 5, sy + 4);
1025 TransVal = t;
1026
1027 quests[Q_PWATER]._qtx = 2 * sx + 21;
1028 quests[Q_PWATER]._qty = 2 * sy + 22;
1029 }
1030
1031 if (setview == TRUE) {
1032 ViewX = 2 * sx + 19;
1033 ViewY = 2 * sy + 20;
1034 }
1035
1036 if (ldir == 0) {
1037 LvlViewX = 2 * sx + 19;
1038 LvlViewY = 2 * sy + 20;
1039 }
1040
1041 if (sx < cx && sy < cy)
1042 return 0;
1043 if (sx > cx && sy < cy)
1044 return 1;
1045 if (sx < cx && sy > cy)
1046 return 2;
1047 else
1048 return 3;
1049 }
1050
DRLG_L1Floor()1051 static void DRLG_L1Floor()
1052 {
1053 int i, j;
1054 LONG rv;
1055
1056 for (j = 0; j < DMAXY; j++) {
1057 for (i = 0; i < DMAXX; i++) {
1058 if (L5dflags[i][j] == 0 && dungeon[i][j] == 13) {
1059 rv = random_(0, 3);
1060
1061 if (rv == 1)
1062 dungeon[i][j] = 162;
1063 if (rv == 2)
1064 dungeon[i][j] = 163;
1065 }
1066 }
1067 }
1068 }
1069
DRLG_L1Pass3()1070 static void DRLG_L1Pass3()
1071 {
1072 int i, j, xx, yy;
1073 long v1, v2, v3, v4, lv;
1074 WORD *MegaTiles;
1075
1076 lv = 22 - 1;
1077
1078 MegaTiles = (WORD *)&pMegaTiles[lv * 8];
1079 v1 = SDL_SwapLE16(*(MegaTiles + 0)) + 1;
1080 v2 = SDL_SwapLE16(*(MegaTiles + 1)) + 1;
1081 v3 = SDL_SwapLE16(*(MegaTiles + 2)) + 1;
1082 v4 = SDL_SwapLE16(*(MegaTiles + 3)) + 1;
1083
1084 for (j = 0; j < MAXDUNY; j += 2) {
1085 for (i = 0; i < MAXDUNX; i += 2) {
1086 dPiece[i][j] = v1;
1087 dPiece[i + 1][j] = v2;
1088 dPiece[i][j + 1] = v3;
1089 dPiece[i + 1][j + 1] = v4;
1090 }
1091 }
1092
1093 yy = 16;
1094 for (j = 0; j < DMAXY; j++) {
1095 xx = 16;
1096 for (i = 0; i < DMAXX; i++) {
1097 lv = dungeon[i][j] - 1;
1098 /// ASSERT: assert(lv >= 0);
1099 MegaTiles = (WORD *)&pMegaTiles[lv * 8];
1100 v1 = SDL_SwapLE16(*(MegaTiles + 0)) + 1;
1101 v2 = SDL_SwapLE16(*(MegaTiles + 1)) + 1;
1102 v3 = SDL_SwapLE16(*(MegaTiles + 2)) + 1;
1103 v4 = SDL_SwapLE16(*(MegaTiles + 3)) + 1;
1104 dPiece[xx][yy] = v1;
1105 dPiece[xx + 1][yy] = v2;
1106 dPiece[xx][yy + 1] = v3;
1107 dPiece[xx + 1][yy + 1] = v4;
1108 xx += 2;
1109 }
1110 yy += 2;
1111 }
1112 }
1113
DRLG_LoadL1SP()1114 static void DRLG_LoadL1SP()
1115 {
1116 L5setloadflag = FALSE;
1117 if (QuestStatus(Q_BUTCHER)) {
1118 L5pSetPiece = LoadFileInMem("Levels\\L1Data\\rnd6.DUN", NULL);
1119 L5setloadflag = TRUE;
1120 }
1121 if (QuestStatus(Q_SKELKING) && !gbIsMultiplayer) {
1122 L5pSetPiece = LoadFileInMem("Levels\\L1Data\\SKngDO.DUN", NULL);
1123 L5setloadflag = TRUE;
1124 }
1125 if (QuestStatus(Q_LTBANNER)) {
1126 L5pSetPiece = LoadFileInMem("Levels\\L1Data\\Banner2.DUN", NULL);
1127 L5setloadflag = TRUE;
1128 }
1129 }
1130
DRLG_FreeL1SP()1131 static void DRLG_FreeL1SP()
1132 {
1133 MemFreeDbg(L5pSetPiece);
1134 }
1135
DRLG_Init_Globals()1136 void DRLG_Init_Globals()
1137 {
1138 char c;
1139
1140 memset(dFlags, 0, sizeof(dFlags));
1141 memset(dPlayer, 0, sizeof(dPlayer));
1142 memset(dMonster, 0, sizeof(dMonster));
1143 memset(dDead, 0, sizeof(dDead));
1144 memset(dObject, 0, sizeof(dObject));
1145 memset(dItem, 0, sizeof(dItem));
1146 memset(dMissile, 0, sizeof(dMissile));
1147 memset(dSpecial, 0, sizeof(dSpecial));
1148 if (!lightflag) {
1149 if (light4flag)
1150 c = 3;
1151 else
1152 c = 15;
1153 } else {
1154 c = 0;
1155 }
1156 memset(dLight, c, sizeof(dLight));
1157 }
1158
DRLG_InitL1Vals()1159 static void DRLG_InitL1Vals()
1160 {
1161 int i, j, pc;
1162
1163 for (j = 0; j < MAXDUNY; j++) {
1164 for (i = 0; i < MAXDUNX; i++) {
1165 if (dPiece[i][j] == 12) {
1166 pc = 1;
1167 } else if (dPiece[i][j] == 11) {
1168 pc = 2;
1169 } else if (dPiece[i][j] == 71) {
1170 pc = 1;
1171 } else if (dPiece[i][j] == 253) {
1172 pc = 3;
1173 } else if (dPiece[i][j] == 267) {
1174 pc = 6;
1175 } else if (dPiece[i][j] == 259) {
1176 pc = 5;
1177 } else if (dPiece[i][j] == 249) {
1178 pc = 2;
1179 } else if (dPiece[i][j] == 325) {
1180 pc = 2;
1181 } else if (dPiece[i][j] == 321) {
1182 pc = 1;
1183 } else if (dPiece[i][j] == 255) {
1184 pc = 4;
1185 } else if (dPiece[i][j] == 211) {
1186 pc = 1;
1187 } else if (dPiece[i][j] == 344) {
1188 pc = 2;
1189 } else if (dPiece[i][j] == 341) {
1190 pc = 1;
1191 } else if (dPiece[i][j] == 331) {
1192 pc = 2;
1193 } else if (dPiece[i][j] == 418) {
1194 pc = 1;
1195 } else if (dPiece[i][j] == 421) {
1196 pc = 2;
1197 } else {
1198 continue;
1199 }
1200 dSpecial[i][j] = pc;
1201 }
1202 }
1203 }
1204
LoadL1Dungeon(const char * sFileName,int vx,int vy)1205 void LoadL1Dungeon(const char *sFileName, int vx, int vy)
1206 {
1207 int i, j, rw, rh;
1208 BYTE *pLevelMap, *lm;
1209
1210 dminx = 16;
1211 dminy = 16;
1212 dmaxx = 96;
1213 dmaxy = 96;
1214
1215 DRLG_InitTrans();
1216 pLevelMap = LoadFileInMem(sFileName, NULL);
1217
1218 for (j = 0; j < DMAXY; j++) {
1219 for (i = 0; i < DMAXX; i++) {
1220 dungeon[i][j] = 22;
1221 L5dflags[i][j] = 0;
1222 }
1223 }
1224
1225 lm = pLevelMap;
1226 rw = *lm;
1227 lm += 2;
1228 rh = *lm;
1229 lm += 2;
1230
1231 for (j = 0; j < rh; j++) {
1232 for (i = 0; i < rw; i++) {
1233 if (*lm != 0) {
1234 dungeon[i][j] = *lm;
1235 L5dflags[i][j] |= DLRG_PROTECTED;
1236 } else {
1237 dungeon[i][j] = 13;
1238 }
1239 lm += 2;
1240 }
1241 }
1242
1243 DRLG_L1Floor();
1244 ViewX = vx;
1245 ViewY = vy;
1246 DRLG_L1Pass3();
1247 DRLG_Init_Globals();
1248 if (currlevel < 17)
1249 DRLG_InitL1Vals();
1250 SetMapMonsters(pLevelMap, 0, 0);
1251 SetMapObjects(pLevelMap, 0, 0);
1252 mem_free_dbg(pLevelMap);
1253 }
1254
LoadPreL1Dungeon(const char * sFileName,int vx,int vy)1255 void LoadPreL1Dungeon(const char *sFileName, int vx, int vy)
1256 {
1257 int i, j, rw, rh;
1258 BYTE *pLevelMap, *lm;
1259
1260 dminx = 16;
1261 dminy = 16;
1262 dmaxx = 96;
1263 dmaxy = 96;
1264
1265 pLevelMap = LoadFileInMem(sFileName, NULL);
1266
1267 for (j = 0; j < DMAXY; j++) {
1268 for (i = 0; i < DMAXX; i++) {
1269 dungeon[i][j] = 22;
1270 L5dflags[i][j] = 0;
1271 }
1272 }
1273
1274 lm = pLevelMap;
1275 rw = *lm;
1276 lm += 2;
1277 rh = *lm;
1278 lm += 2;
1279
1280 for (j = 0; j < rh; j++) {
1281 for (i = 0; i < rw; i++) {
1282 if (*lm != 0) {
1283 dungeon[i][j] = *lm;
1284 L5dflags[i][j] |= DLRG_PROTECTED;
1285 } else {
1286 dungeon[i][j] = 13;
1287 }
1288 lm += 2;
1289 }
1290 }
1291
1292 DRLG_L1Floor();
1293
1294 for (j = 0; j < DMAXY; j++) {
1295 for (i = 0; i < DMAXX; i++) {
1296 pdungeon[i][j] = dungeon[i][j];
1297 }
1298 }
1299
1300 mem_free_dbg(pLevelMap);
1301 }
1302
InitL5Dungeon()1303 static void InitL5Dungeon()
1304 {
1305 int i, j;
1306
1307 for (j = 0; j < DMAXY; j++) {
1308 for (i = 0; i < DMAXX; i++) {
1309 dungeon[i][j] = 0;
1310 L5dflags[i][j] = 0;
1311 }
1312 }
1313 }
1314
L5ClearFlags()1315 static void L5ClearFlags()
1316 {
1317 int i, j;
1318
1319 for (j = 0; j < DMAXY; j++) {
1320 for (i = 0; i < DMAXX; i++) {
1321 L5dflags[i][j] &= 0xBF;
1322 }
1323 }
1324 }
1325
L5drawRoom(int x,int y,int w,int h)1326 static void L5drawRoom(int x, int y, int w, int h)
1327 {
1328 int i, j;
1329
1330 for (j = 0; j < h; j++) {
1331 for (i = 0; i < w; i++) {
1332 dungeon[x + i][y + j] = 1;
1333 }
1334 }
1335 }
1336
L5checkRoom(int x,int y,int width,int height)1337 static BOOL L5checkRoom(int x, int y, int width, int height)
1338 {
1339 int i, j;
1340
1341 for (j = 0; j < height; j++) {
1342 for (i = 0; i < width; i++) {
1343 if (i + x < 0 || i + x >= DMAXX || j + y < 0 || j + y >= DMAXY)
1344 return FALSE;
1345 if (dungeon[i + x][j + y])
1346 return FALSE;
1347 }
1348 }
1349
1350 return TRUE;
1351 }
1352
L5roomGen(int x,int y,int w,int h,int dir)1353 static void L5roomGen(int x, int y, int w, int h, int dir)
1354 {
1355 BOOL ran, ran2;
1356 int width, height, rx, ry, ry2;
1357 int cw, ch, cx1, cy1, cx2;
1358
1359 int dirProb = random_(0, 4);
1360 int num = 0;
1361
1362 if ((dir == 1 && dirProb == 0) || (dir != 1 && dirProb != 0)) {
1363 do {
1364 cw = (random_(0, 5) + 2) & ~1;
1365 ch = (random_(0, 5) + 2) & ~1;
1366 cy1 = h / 2 + y - ch / 2;
1367 cx1 = x - cw;
1368 ran = L5checkRoom(cx1 - 1, cy1 - 1, ch + 2, cw + 1); /// BUGFIX: swap args 3 and 4 ("ch+2" and "cw+1")
1369 num++;
1370 } while (ran == FALSE && num < 20);
1371
1372 if (ran == TRUE)
1373 L5drawRoom(cx1, cy1, cw, ch);
1374 cx2 = x + w;
1375 ran2 = L5checkRoom(cx2, cy1 - 1, cw + 1, ch + 2);
1376 if (ran2 == TRUE)
1377 L5drawRoom(cx2, cy1, cw, ch);
1378 if (ran == TRUE)
1379 L5roomGen(cx1, cy1, cw, ch, 1);
1380 if (ran2 == TRUE)
1381 L5roomGen(cx2, cy1, cw, ch, 1);
1382 return;
1383 }
1384
1385 do {
1386 width = (random_(0, 5) + 2) & ~1;
1387 height = (random_(0, 5) + 2) & ~1;
1388 rx = w / 2 + x - width / 2;
1389 ry = y - height;
1390 ran = L5checkRoom(rx - 1, ry - 1, width + 2, height + 1);
1391 num++;
1392 } while (ran == FALSE && num < 20);
1393
1394 if (ran == TRUE)
1395 L5drawRoom(rx, ry, width, height);
1396 ry2 = y + h;
1397 ran2 = L5checkRoom(rx - 1, ry2, width + 2, height + 1);
1398 if (ran2 == TRUE)
1399 L5drawRoom(rx, ry2, width, height);
1400 if (ran == TRUE)
1401 L5roomGen(rx, ry, width, height, 0);
1402 if (ran2 == TRUE)
1403 L5roomGen(rx, ry2, width, height, 0);
1404 }
1405
L5firstRoom()1406 static void L5firstRoom()
1407 {
1408 int ys, ye, y;
1409 int xs, xe, x;
1410
1411 if (random_(0, 2) == 0) {
1412 ys = 1;
1413 ye = DMAXY - 1;
1414
1415 VR1 = random_(0, 2);
1416 VR2 = random_(0, 2);
1417 VR3 = random_(0, 2);
1418
1419 if (VR1 + VR3 <= 1)
1420 VR2 = 1;
1421 if (VR1)
1422 L5drawRoom(15, 1, 10, 10);
1423 else
1424 ys = 18;
1425
1426 if (VR2)
1427 L5drawRoom(15, 15, 10, 10);
1428 if (VR3)
1429 L5drawRoom(15, 29, 10, 10);
1430 else
1431 ye = 22;
1432
1433 for (y = ys; y < ye; y++) {
1434 dungeon[17][y] = 1;
1435 dungeon[18][y] = 1;
1436 dungeon[19][y] = 1;
1437 dungeon[20][y] = 1;
1438 dungeon[21][y] = 1;
1439 dungeon[22][y] = 1;
1440 }
1441
1442 if (VR1)
1443 L5roomGen(15, 1, 10, 10, 0);
1444 if (VR2)
1445 L5roomGen(15, 15, 10, 10, 0);
1446 if (VR3)
1447 L5roomGen(15, 29, 10, 10, 0);
1448
1449 HR3 = 0;
1450 HR2 = 0;
1451 HR1 = 0;
1452 } else {
1453 xs = 1;
1454 xe = DMAXX - 1;
1455
1456 HR1 = random_(0, 2);
1457 HR2 = random_(0, 2);
1458 HR3 = random_(0, 2);
1459
1460 if (HR1 + HR3 <= 1)
1461 HR2 = 1;
1462 if (HR1)
1463 L5drawRoom(1, 15, 10, 10);
1464 else
1465 xs = 18;
1466
1467 if (HR2)
1468 L5drawRoom(15, 15, 10, 10);
1469 if (HR3)
1470 L5drawRoom(29, 15, 10, 10);
1471 else
1472 xe = 22;
1473
1474 for (x = xs; x < xe; x++) {
1475 dungeon[x][17] = 1;
1476 dungeon[x][18] = 1;
1477 dungeon[x][19] = 1;
1478 dungeon[x][20] = 1;
1479 dungeon[x][21] = 1;
1480 dungeon[x][22] = 1;
1481 }
1482
1483 if (HR1)
1484 L5roomGen(1, 15, 10, 10, 1);
1485 if (HR2)
1486 L5roomGen(15, 15, 10, 10, 1);
1487 if (HR3)
1488 L5roomGen(29, 15, 10, 10, 1);
1489
1490 VR3 = 0;
1491 VR2 = 0;
1492 VR1 = 0;
1493 }
1494 }
1495
L5GetArea()1496 static int L5GetArea()
1497 {
1498 int i, j;
1499 int rv;
1500
1501 rv = 0;
1502
1503 for (j = 0; j < DMAXY; j++) {
1504 for (i = 0; i < DMAXX; i++) {
1505 if (dungeon[i][j] == 1)
1506 rv++;
1507 }
1508 }
1509
1510 return rv;
1511 }
1512
L5makeDungeon()1513 static void L5makeDungeon()
1514 {
1515 int i, j;
1516 int i_2, j_2;
1517
1518 for (j = 0; j < DMAXY; j++) {
1519 for (i = 0; i < DMAXX; i++) {
1520 j_2 = j << 1;
1521 i_2 = i << 1;
1522 L5dungeon[i_2][j_2] = dungeon[i][j];
1523 L5dungeon[i_2][j_2 + 1] = dungeon[i][j];
1524 L5dungeon[i_2 + 1][j_2] = dungeon[i][j];
1525 L5dungeon[i_2 + 1][j_2 + 1] = dungeon[i][j];
1526 }
1527 }
1528 }
1529
L5makeDmt()1530 static void L5makeDmt()
1531 {
1532 int i, j, idx, val, dmtx, dmty;
1533
1534 for (j = 0; j < DMAXY; j++) {
1535 for (i = 0; i < DMAXX; i++) {
1536 dungeon[i][j] = 22;
1537 }
1538 }
1539
1540 for (j = 0, dmty = 1; dmty <= 77; j++, dmty += 2) {
1541 for (i = 0, dmtx = 1; dmtx <= 77; i++, dmtx += 2) {
1542 val = 8 * L5dungeon[dmtx + 1][dmty + 1]
1543 + 4 * L5dungeon[dmtx][dmty + 1]
1544 + 2 * L5dungeon[dmtx + 1][dmty]
1545 + L5dungeon[dmtx][dmty];
1546 idx = L5ConvTbl[val];
1547 dungeon[i][j] = idx;
1548 }
1549 }
1550 }
1551
L5HWallOk(int i,int j)1552 static int L5HWallOk(int i, int j)
1553 {
1554 int x;
1555 BOOL wallok;
1556
1557 for (x = 1; dungeon[i + x][j] == 13; x++) {
1558 if (dungeon[i + x][j - 1] != 13 || dungeon[i + x][j + 1] != 13 || L5dflags[i + x][j])
1559 break;
1560 }
1561
1562 wallok = FALSE;
1563 if (dungeon[i + x][j] >= 3 && dungeon[i + x][j] <= 7)
1564 wallok = TRUE;
1565 if (dungeon[i + x][j] >= 16 && dungeon[i + x][j] <= 24)
1566 wallok = TRUE;
1567 if (dungeon[i + x][j] == 22)
1568 wallok = FALSE;
1569 if (x == 1)
1570 wallok = FALSE;
1571
1572 if (wallok)
1573 return x;
1574 else
1575 return -1;
1576 }
1577
L5VWallOk(int i,int j)1578 static int L5VWallOk(int i, int j)
1579 {
1580 int y;
1581 BOOL wallok;
1582
1583 for (y = 1; dungeon[i][j + y] == 13; y++) {
1584 if (dungeon[i - 1][j + y] != 13 || dungeon[i + 1][j + y] != 13 || L5dflags[i][j + y])
1585 break;
1586 }
1587
1588 wallok = FALSE;
1589 if (dungeon[i][j + y] >= 3 && dungeon[i][j + y] <= 7)
1590 wallok = TRUE;
1591 if (dungeon[i][j + y] >= 16 && dungeon[i][j + y] <= 24)
1592 wallok = TRUE;
1593 if (dungeon[i][j + y] == 22)
1594 wallok = FALSE;
1595 if (y == 1)
1596 wallok = FALSE;
1597
1598 if (wallok)
1599 return y;
1600 else
1601 return -1;
1602 }
1603
L5HorizWall(int i,int j,char p,int dx)1604 static void L5HorizWall(int i, int j, char p, int dx)
1605 {
1606 int xx;
1607 char wt, dt;
1608
1609 switch (random_(0, 4)) {
1610 case 0:
1611 case 1:
1612 dt = 2;
1613 break;
1614 case 2:
1615 dt = 12;
1616 if (p == 2)
1617 p = 12;
1618 if (p == 4)
1619 p = 10;
1620 break;
1621 case 3:
1622 dt = 36;
1623 if (p == 2)
1624 p = 36;
1625 if (p == 4)
1626 p = 27;
1627 break;
1628 }
1629
1630 if (random_(0, 6) == 5)
1631 wt = 12;
1632 else
1633 wt = 26;
1634 if (dt == 12)
1635 wt = 12;
1636
1637 dungeon[i][j] = p;
1638
1639 for (xx = 1; xx < dx; xx++) {
1640 dungeon[i + xx][j] = dt;
1641 }
1642
1643 xx = random_(0, dx - 1) + 1;
1644
1645 if (wt == 12) {
1646 dungeon[i + xx][j] = wt;
1647 } else {
1648 dungeon[i + xx][j] = 2;
1649 L5dflags[i + xx][j] |= DLRG_HDOOR;
1650 }
1651 }
1652
L5VertWall(int i,int j,char p,int dy)1653 static void L5VertWall(int i, int j, char p, int dy)
1654 {
1655 int yy;
1656 char wt, dt;
1657
1658 switch (random_(0, 4)) {
1659 case 0:
1660 case 1:
1661 dt = 1;
1662 break;
1663 case 2:
1664 dt = 11;
1665 if (p == 1)
1666 p = 11;
1667 if (p == 4)
1668 p = 14;
1669 break;
1670 case 3:
1671 dt = 35;
1672 if (p == 1)
1673 p = 35;
1674 if (p == 4)
1675 p = 37;
1676 break;
1677 }
1678
1679 if (random_(0, 6) == 5)
1680 wt = 11;
1681 else
1682 wt = 25;
1683 if (dt == 11)
1684 wt = 11;
1685
1686 dungeon[i][j] = p;
1687
1688 for (yy = 1; yy < dy; yy++) {
1689 dungeon[i][j + yy] = dt;
1690 }
1691
1692 yy = random_(0, dy - 1) + 1;
1693
1694 if (wt == 11) {
1695 dungeon[i][j + yy] = wt;
1696 } else {
1697 dungeon[i][j + yy] = 1;
1698 L5dflags[i][j + yy] |= DLRG_VDOOR;
1699 }
1700 }
1701
L5AddWall()1702 static void L5AddWall()
1703 {
1704 int i, j, x, y;
1705
1706 for (j = 0; j < DMAXY; j++) {
1707 for (i = 0; i < DMAXX; i++) {
1708 if (!L5dflags[i][j]) {
1709 if (dungeon[i][j] == 3 && random_(0, 100) < 100) {
1710 x = L5HWallOk(i, j);
1711 if (x != -1)
1712 L5HorizWall(i, j, 2, x);
1713 }
1714 if (dungeon[i][j] == 3 && random_(0, 100) < 100) {
1715 y = L5VWallOk(i, j);
1716 if (y != -1)
1717 L5VertWall(i, j, 1, y);
1718 }
1719 if (dungeon[i][j] == 6 && random_(0, 100) < 100) {
1720 x = L5HWallOk(i, j);
1721 if (x != -1)
1722 L5HorizWall(i, j, 4, x);
1723 }
1724 if (dungeon[i][j] == 7 && random_(0, 100) < 100) {
1725 y = L5VWallOk(i, j);
1726 if (y != -1)
1727 L5VertWall(i, j, 4, y);
1728 }
1729 if (dungeon[i][j] == 2 && random_(0, 100) < 100) {
1730 x = L5HWallOk(i, j);
1731 if (x != -1)
1732 L5HorizWall(i, j, 2, x);
1733 }
1734 if (dungeon[i][j] == 1 && random_(0, 100) < 100) {
1735 y = L5VWallOk(i, j);
1736 if (y != -1)
1737 L5VertWall(i, j, 1, y);
1738 }
1739 }
1740 }
1741 }
1742 }
1743
DRLG_L5GChamber(int sx,int sy,BOOL topflag,BOOL bottomflag,BOOL leftflag,BOOL rightflag)1744 static void DRLG_L5GChamber(int sx, int sy, BOOL topflag, BOOL bottomflag, BOOL leftflag, BOOL rightflag)
1745 {
1746 int i, j;
1747
1748 if (topflag == TRUE) {
1749 dungeon[sx + 2][sy] = 12;
1750 dungeon[sx + 3][sy] = 12;
1751 dungeon[sx + 4][sy] = 3;
1752 dungeon[sx + 7][sy] = 9;
1753 dungeon[sx + 8][sy] = 12;
1754 dungeon[sx + 9][sy] = 2;
1755 }
1756 if (bottomflag == TRUE) {
1757 sy += 11;
1758 dungeon[sx + 2][sy] = 10;
1759 dungeon[sx + 3][sy] = 12;
1760 dungeon[sx + 4][sy] = 8;
1761 dungeon[sx + 7][sy] = 5;
1762 dungeon[sx + 8][sy] = 12;
1763 if (dungeon[sx + 9][sy] != 4) {
1764 dungeon[sx + 9][sy] = 21;
1765 }
1766 sy -= 11;
1767 }
1768 if (leftflag == TRUE) {
1769 dungeon[sx][sy + 2] = 11;
1770 dungeon[sx][sy + 3] = 11;
1771 dungeon[sx][sy + 4] = 3;
1772 dungeon[sx][sy + 7] = 8;
1773 dungeon[sx][sy + 8] = 11;
1774 dungeon[sx][sy + 9] = 1;
1775 }
1776 if (rightflag == TRUE) {
1777 sx += 11;
1778 dungeon[sx][sy + 2] = 14;
1779 dungeon[sx][sy + 3] = 11;
1780 dungeon[sx][sy + 4] = 9;
1781 dungeon[sx][sy + 7] = 5;
1782 dungeon[sx][sy + 8] = 11;
1783 if (dungeon[sx][sy + 9] != 4) {
1784 dungeon[sx][sy + 9] = 21;
1785 }
1786 sx -= 11;
1787 }
1788
1789 for (j = 1; j < 11; j++) {
1790 for (i = 1; i < 11; i++) {
1791 dungeon[i + sx][j + sy] = 13;
1792 L5dflags[i + sx][j + sy] |= DLRG_CHAMBER;
1793 }
1794 }
1795
1796 dungeon[sx + 4][sy + 4] = 15;
1797 dungeon[sx + 7][sy + 4] = 15;
1798 dungeon[sx + 4][sy + 7] = 15;
1799 dungeon[sx + 7][sy + 7] = 15;
1800 }
1801
DRLG_L5GHall(int x1,int y1,int x2,int y2)1802 static void DRLG_L5GHall(int x1, int y1, int x2, int y2)
1803 {
1804 int i;
1805
1806 if (y1 == y2) {
1807 for (i = x1; i < x2; i++) {
1808 dungeon[i][y1] = 12;
1809 dungeon[i][y1 + 3] = 12;
1810 }
1811 } else {
1812 for (i = y1; i < y2; i++) {
1813 dungeon[x1][i] = 11;
1814 dungeon[x1 + 3][i] = 11;
1815 }
1816 }
1817 }
1818
L5tileFix()1819 static void L5tileFix()
1820 {
1821 int i, j;
1822
1823 // BUGFIX: Bounds checks are required in all loop bodies.
1824 // See https://github.com/diasurgical/devilutionX/pull/401
1825
1826 for (j = 0; j < DMAXY; j++) {
1827 for (i = 0; i < DMAXX; i++) {
1828 if (i + 1 < DMAXX) {
1829 if (dungeon[i][j] == 2 && dungeon[i + 1][j] == 22)
1830 dungeon[i + 1][j] = 23;
1831 if (dungeon[i][j] == 13 && dungeon[i + 1][j] == 22)
1832 dungeon[i + 1][j] = 18;
1833 if (dungeon[i][j] == 13 && dungeon[i + 1][j] == 2)
1834 dungeon[i + 1][j] = 7;
1835 if (dungeon[i][j] == 6 && dungeon[i + 1][j] == 22)
1836 dungeon[i + 1][j] = 24;
1837 }
1838 if (j + 1 < DMAXY) {
1839 if (dungeon[i][j] == 1 && dungeon[i][j + 1] == 22)
1840 dungeon[i][j + 1] = 24;
1841 if (dungeon[i][j] == 13 && dungeon[i][j + 1] == 1)
1842 dungeon[i][j + 1] = 6;
1843 if (dungeon[i][j] == 13 && dungeon[i][j + 1] == 22)
1844 dungeon[i][j + 1] = 19;
1845 }
1846 }
1847 }
1848
1849 for (j = 0; j < DMAXY; j++) {
1850 for (i = 0; i < DMAXX; i++) {
1851 if (i + 1 < DMAXX) {
1852 if (dungeon[i][j] == 13 && dungeon[i + 1][j] == 19)
1853 dungeon[i + 1][j] = 21;
1854 if (dungeon[i][j] == 13 && dungeon[i + 1][j] == 22)
1855 dungeon[i + 1][j] = 20;
1856 if (dungeon[i][j] == 7 && dungeon[i + 1][j] == 22)
1857 dungeon[i + 1][j] = 23;
1858 if (dungeon[i][j] == 13 && dungeon[i + 1][j] == 24)
1859 dungeon[i + 1][j] = 21;
1860 if (dungeon[i][j] == 19 && dungeon[i + 1][j] == 22)
1861 dungeon[i + 1][j] = 20;
1862 if (dungeon[i][j] == 2 && dungeon[i + 1][j] == 19)
1863 dungeon[i + 1][j] = 21;
1864 if (dungeon[i][j] == 19 && dungeon[i + 1][j] == 1)
1865 dungeon[i + 1][j] = 6;
1866 if (dungeon[i][j] == 7 && dungeon[i + 1][j] == 19)
1867 dungeon[i + 1][j] = 21;
1868 if (dungeon[i][j] == 2 && dungeon[i + 1][j] == 1)
1869 dungeon[i + 1][j] = 6;
1870 if (dungeon[i][j] == 3 && dungeon[i + 1][j] == 22)
1871 dungeon[i + 1][j] = 24;
1872 if (dungeon[i][j] == 21 && dungeon[i + 1][j] == 1)
1873 dungeon[i + 1][j] = 6;
1874 if (dungeon[i][j] == 7 && dungeon[i + 1][j] == 1)
1875 dungeon[i + 1][j] = 6;
1876 if (dungeon[i][j] == 7 && dungeon[i + 1][j] == 24)
1877 dungeon[i + 1][j] = 21;
1878 if (dungeon[i][j] == 4 && dungeon[i + 1][j] == 16)
1879 dungeon[i + 1][j] = 17;
1880 if (dungeon[i][j] == 7 && dungeon[i + 1][j] == 13)
1881 dungeon[i + 1][j] = 17;
1882 if (dungeon[i][j] == 2 && dungeon[i + 1][j] == 24)
1883 dungeon[i + 1][j] = 21;
1884 if (dungeon[i][j] == 2 && dungeon[i + 1][j] == 13)
1885 dungeon[i + 1][j] = 17;
1886 }
1887 if (i > 0) {
1888 if (dungeon[i][j] == 23 && dungeon[i - 1][j] == 22)
1889 dungeon[i - 1][j] = 19;
1890 if (dungeon[i][j] == 19 && dungeon[i - 1][j] == 23)
1891 dungeon[i - 1][j] = 21;
1892 if (dungeon[i][j] == 6 && dungeon[i - 1][j] == 22)
1893 dungeon[i - 1][j] = 24;
1894 if (dungeon[i][j] == 6 && dungeon[i - 1][j] == 23)
1895 dungeon[i - 1][j] = 21;
1896 }
1897 if (j + 1 < DMAXY) {
1898 if (dungeon[i][j] == 1 && dungeon[i][j + 1] == 2)
1899 dungeon[i][j + 1] = 7;
1900 if (dungeon[i][j] == 6 && dungeon[i][j + 1] == 18)
1901 dungeon[i][j + 1] = 21;
1902 if (dungeon[i][j] == 18 && dungeon[i][j + 1] == 2)
1903 dungeon[i][j + 1] = 7;
1904 if (dungeon[i][j] == 6 && dungeon[i][j + 1] == 2)
1905 dungeon[i][j + 1] = 7;
1906 if (dungeon[i][j] == 21 && dungeon[i][j + 1] == 2)
1907 dungeon[i][j + 1] = 7;
1908 if (dungeon[i][j] == 6 && dungeon[i][j + 1] == 22)
1909 dungeon[i][j + 1] = 24;
1910 if (dungeon[i][j] == 6 && dungeon[i][j + 1] == 13)
1911 dungeon[i][j + 1] = 16;
1912 if (dungeon[i][j] == 1 && dungeon[i][j + 1] == 13)
1913 dungeon[i][j + 1] = 16;
1914 if (dungeon[i][j] == 13 && dungeon[i][j + 1] == 16)
1915 dungeon[i][j + 1] = 17;
1916 }
1917 if (j > 0) {
1918 if (dungeon[i][j] == 6 && dungeon[i][j - 1] == 22)
1919 dungeon[i][j - 1] = 7;
1920 if (dungeon[i][j] == 6 && dungeon[i][j - 1] == 22)
1921 dungeon[i][j - 1] = 24;
1922 if (dungeon[i][j] == 7 && dungeon[i][j - 1] == 24)
1923 dungeon[i][j - 1] = 21;
1924 if (dungeon[i][j] == 18 && dungeon[i][j - 1] == 24)
1925 dungeon[i][j - 1] = 21;
1926 }
1927 }
1928 }
1929
1930 for (j = 0; j < DMAXY; j++) {
1931 for (i = 0; i < DMAXX; i++) {
1932 if (j + 1 < DMAXY && dungeon[i][j] == 4 && dungeon[i][j + 1] == 2)
1933 dungeon[i][j + 1] = 7;
1934 if (i + 1 < DMAXX && dungeon[i][j] == 2 && dungeon[i + 1][j] == 19)
1935 dungeon[i + 1][j] = 21;
1936 if (j + 1 < DMAXY && dungeon[i][j] == 18 && dungeon[i][j + 1] == 22)
1937 dungeon[i][j + 1] = 20;
1938 }
1939 }
1940 }
1941
drlg_l1_crypt_rndset(const BYTE * miniset,int rndper)1942 void drlg_l1_crypt_rndset(const BYTE *miniset, int rndper)
1943 {
1944 int sx, sy, sw, sh, xx, yy, ii, kk;
1945 BOOL found;
1946
1947 sw = miniset[0];
1948 sh = miniset[1];
1949
1950 for (sy = 0; sy < DMAXY - sh; sy++) {
1951 for (sx = 0; sx < DMAXX - sw; sx++) {
1952 found = TRUE;
1953 ii = 2;
1954 for (yy = 0; yy < sh && found == TRUE; yy++) {
1955 for (xx = 0; xx < sw && found == TRUE; xx++) {
1956 if (miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) {
1957 found = FALSE;
1958 }
1959 if (dflags[xx + sx][yy + sy] != 0) {
1960 found = FALSE;
1961 }
1962 ii++;
1963 }
1964 }
1965 kk = sw * sh + 2;
1966 if (miniset[kk] >= 84 && miniset[kk] <= 100 && found == TRUE) {
1967 // BUGFIX: accesses to dungeon can go out of bounds (fixed)
1968 // BUGFIX: Comparisons vs 100 should use same tile as comparisons vs 84 (fixed)
1969 if (sx > 0 && dungeon[sx - 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) {
1970 found = FALSE;
1971 }
1972 if (sx < DMAXX - 1 && dungeon[sx + 1][sy] >= 84 && dungeon[sx + 1][sy] <= 100) {
1973 found = FALSE;
1974 }
1975 if (sy < DMAXY - 1 && dungeon[sx][sy + 1] >= 84 && dungeon[sx][sy + 1] <= 100) {
1976 found = FALSE;
1977 }
1978 if (sy > 0 && dungeon[sx][sy - 1] >= 84 && dungeon[sx][sy - 1] <= 100) {
1979 found = FALSE;
1980 }
1981 }
1982 if (found == TRUE && random_(0, 100) < rndper) {
1983 for (yy = 0; yy < sh; yy++) {
1984 for (xx = 0; xx < sw; xx++) {
1985 if (miniset[kk] != 0) {
1986 dungeon[xx + sx][yy + sy] = miniset[kk];
1987 }
1988 kk++;
1989 }
1990 }
1991 }
1992 }
1993 }
1994 }
1995
DRLG_L5Subs()1996 static void DRLG_L5Subs()
1997 {
1998 int x, y, rv, i;
1999
2000 for (y = 0; y < DMAXY; y++) {
2001 for (x = 0; x < DMAXX; x++) {
2002 if (random_(0, 4) == 0) {
2003 BYTE c = L5BTYPES[dungeon[x][y]];
2004
2005 if (c && !L5dflags[x][y]) {
2006 rv = random_(0, 16);
2007 i = -1;
2008
2009 while (rv >= 0) {
2010 if (++i == sizeof(L5BTYPES))
2011 i = 0;
2012 if (c == L5BTYPES[i])
2013 rv--;
2014 }
2015
2016 // BUGFIX: Add `&& y > 0` to the if statement. (fixed)
2017 if (i == 89 && y > 0) {
2018 if (L5BTYPES[dungeon[x][y - 1]] != 79 || L5dflags[x][y - 1])
2019 i = 79;
2020 else
2021 dungeon[x][y - 1] = 90;
2022 }
2023 // BUGFIX: Add `&& x + 1 < DMAXX` to the if statement. (fixed)
2024 if (i == 91 && x + 1 < DMAXX) {
2025 if (L5BTYPES[dungeon[x + 1][y]] != 80 || L5dflags[x + 1][y])
2026 i = 80;
2027 else
2028 dungeon[x + 1][y] = 92;
2029 }
2030 dungeon[x][y] = i;
2031 }
2032 }
2033 }
2034 }
2035 }
2036
DRLG_L5SetRoom(int rx1,int ry1)2037 static void DRLG_L5SetRoom(int rx1, int ry1)
2038 {
2039 int rw, rh, i, j;
2040 BYTE *sp;
2041
2042 rw = *L5pSetPiece;
2043 rh = *(L5pSetPiece + 2);
2044
2045 setpc_x = rx1;
2046 setpc_y = ry1;
2047 setpc_w = rw;
2048 setpc_h = rh;
2049
2050 sp = L5pSetPiece + 4;
2051
2052 for (j = 0; j < rh; j++) {
2053 for (i = 0; i < rw; i++) {
2054 if (*sp) {
2055 dungeon[rx1 + i][ry1 + j] = *sp;
2056 L5dflags[rx1 + i][ry1 + j] |= DLRG_PROTECTED;
2057 } else {
2058 dungeon[rx1 + i][ry1 + j] = 13;
2059 }
2060 sp += 2;
2061 }
2062 }
2063 }
2064
L5FillChambers()2065 static void L5FillChambers()
2066 {
2067 int c;
2068
2069 if (HR1)
2070 DRLG_L5GChamber(0, 14, 0, 0, 0, 1);
2071
2072 if (HR2) {
2073 if (HR1 && !HR3)
2074 DRLG_L5GChamber(14, 14, 0, 0, 1, 0);
2075 if (!HR1 && HR3)
2076 DRLG_L5GChamber(14, 14, 0, 0, 0, 1);
2077 if (HR1 && HR3)
2078 DRLG_L5GChamber(14, 14, 0, 0, 1, 1);
2079 if (!HR1 && !HR3)
2080 DRLG_L5GChamber(14, 14, 0, 0, 0, 0);
2081 }
2082
2083 if (HR3)
2084 DRLG_L5GChamber(28, 14, 0, 0, 1, 0);
2085 if (HR1 && HR2)
2086 DRLG_L5GHall(12, 18, 14, 18);
2087 if (HR2 && HR3)
2088 DRLG_L5GHall(26, 18, 28, 18);
2089 if (HR1 && !HR2 && HR3)
2090 DRLG_L5GHall(12, 18, 28, 18);
2091 if (VR1)
2092 DRLG_L5GChamber(14, 0, 0, 1, 0, 0);
2093
2094 if (VR2) {
2095 if (VR1 && !VR3)
2096 DRLG_L5GChamber(14, 14, 1, 0, 0, 0);
2097 if (!VR1 && VR3)
2098 DRLG_L5GChamber(14, 14, 0, 1, 0, 0);
2099 if (VR1 && VR3)
2100 DRLG_L5GChamber(14, 14, 1, 1, 0, 0);
2101 if (!VR1 && !VR3)
2102 DRLG_L5GChamber(14, 14, 0, 0, 0, 0);
2103 }
2104
2105 if (VR3)
2106 DRLG_L5GChamber(14, 28, 1, 0, 0, 0);
2107 if (VR1 && VR2)
2108 DRLG_L5GHall(18, 12, 18, 14);
2109 if (VR2 && VR3)
2110 DRLG_L5GHall(18, 26, 18, 28);
2111 if (VR1 && !VR2 && VR3)
2112 DRLG_L5GHall(18, 12, 18, 28);
2113
2114 if (currlevel == 24) {
2115 if (VR1 || VR2 || VR3) {
2116 c = 1;
2117 if (!VR1 && VR2 && VR3 && random_(0, 2) != 0)
2118 c = 2;
2119 if (VR1 && VR2 && !VR3 && random_(0, 2) != 0)
2120 c = 0;
2121
2122 if (VR1 && !VR2 && VR3) {
2123 if (random_(0, 2) != 0)
2124 c = 0;
2125 else
2126 c = 2;
2127 }
2128
2129 if (VR1 && VR2 && VR3)
2130 c = random_(0, 3);
2131
2132 switch (c) {
2133 case 0:
2134 drlg_l1_set_crypt_room(16, 2);
2135 break;
2136 case 1:
2137 drlg_l1_set_crypt_room(16, 16);
2138 break;
2139 case 2:
2140 drlg_l1_set_crypt_room(16, 30);
2141 break;
2142 }
2143 } else {
2144 c = 1;
2145 if (!HR1 && HR2 && HR3 && random_(0, 2) != 0)
2146 c = 2;
2147 if (HR1 && HR2 && !HR3 && random_(0, 2) != 0)
2148 c = 0;
2149
2150 if (HR1 && !HR2 && HR3) {
2151 if (random_(0, 2) != 0)
2152 c = 0;
2153 else
2154 c = 2;
2155 }
2156
2157 if (HR1 && HR2 && HR3)
2158 c = random_(0, 3);
2159
2160 switch (c) {
2161 case 0:
2162 drlg_l1_set_crypt_room(2, 16);
2163 break;
2164 case 1:
2165 drlg_l1_set_crypt_room(16, 16);
2166 break;
2167 case 2:
2168 drlg_l1_set_crypt_room(30, 16);
2169 break;
2170 }
2171 }
2172 }
2173 if (currlevel == 21) {
2174 if (VR1 || VR2 || VR3) {
2175 c = 1;
2176 if (!VR1 && VR2 && VR3 && random_(0, 2) != 0)
2177 c = 2;
2178 if (VR1 && VR2 && !VR3 && random_(0, 2) != 0)
2179 c = 0;
2180
2181 if (VR1 && !VR2 && VR3) {
2182 if (random_(0, 2) != 0)
2183 c = 0;
2184 else
2185 c = 2;
2186 }
2187
2188 if (VR1 && VR2 && VR3)
2189 c = random_(0, 3);
2190
2191 switch (c) {
2192 case 0:
2193 drlg_l1_set_corner_room(16, 2);
2194 break;
2195 case 1:
2196 drlg_l1_set_corner_room(16, 16);
2197 break;
2198 case 2:
2199 drlg_l1_set_corner_room(16, 30);
2200 break;
2201 }
2202 } else {
2203 c = 1;
2204 if (!HR1 && HR2 && HR3 && random_(0, 2))
2205 c = 2;
2206 if (HR1 && HR2 && !HR3 && random_(0, 2))
2207 c = 0;
2208
2209 if (HR1 && !HR2 && HR3) {
2210 if (random_(0, 2))
2211 c = 0;
2212 else
2213 c = 2;
2214 }
2215
2216 if (HR1 && HR2 && HR3)
2217 c = random_(0, 3);
2218
2219 switch (c) {
2220 case 0:
2221 drlg_l1_set_corner_room(2, 16);
2222 break;
2223 case 1:
2224 drlg_l1_set_corner_room(16, 16);
2225 break;
2226 case 2:
2227 drlg_l1_set_corner_room(30, 16);
2228 break;
2229 }
2230 }
2231 }
2232 if (L5setloadflag) {
2233 if (VR1 || VR2 || VR3) {
2234 c = 1;
2235 if (!VR1 && VR2 && VR3 && random_(0, 2) != 0)
2236 c = 2;
2237 if (VR1 && VR2 && !VR3 && random_(0, 2) != 0)
2238 c = 0;
2239
2240 if (VR1 && !VR2 && VR3) {
2241 if (random_(0, 2) != 0)
2242 c = 0;
2243 else
2244 c = 2;
2245 }
2246
2247 if (VR1 && VR2 && VR3)
2248 c = random_(0, 3);
2249
2250 switch (c) {
2251 case 0:
2252 DRLG_L5SetRoom(16, 2);
2253 break;
2254 case 1:
2255 DRLG_L5SetRoom(16, 16);
2256 break;
2257 case 2:
2258 DRLG_L5SetRoom(16, 30);
2259 break;
2260 }
2261 } else {
2262 c = 1;
2263 if (!HR1 && HR2 && HR3 && random_(0, 2) != 0)
2264 c = 2;
2265 if (HR1 && HR2 && !HR3 && random_(0, 2) != 0)
2266 c = 0;
2267
2268 if (HR1 && !HR2 && HR3) {
2269 if (random_(0, 2) != 0)
2270 c = 0;
2271 else
2272 c = 2;
2273 }
2274
2275 if (HR1 && HR2 && HR3)
2276 c = random_(0, 3);
2277
2278 switch (c) {
2279 case 0:
2280 DRLG_L5SetRoom(2, 16);
2281 break;
2282 case 1:
2283 DRLG_L5SetRoom(16, 16);
2284 break;
2285 case 2:
2286 DRLG_L5SetRoom(30, 16);
2287 break;
2288 }
2289 }
2290 }
2291 }
2292
drlg_l1_set_crypt_room(int rx1,int ry1)2293 void drlg_l1_set_crypt_room(int rx1, int ry1)
2294 {
2295 int rw, rh, i, j, sp;
2296
2297 rw = UberRoomPattern[0];
2298 rh = UberRoomPattern[1];
2299
2300 UberRow = 2 * rx1 + 6;
2301 UberCol = 2 * ry1 + 8;
2302 setpc_x = rx1;
2303 setpc_y = ry1;
2304 setpc_w = rw;
2305 setpc_h = rh;
2306 IsUberRoomOpened = false;
2307 IsUberLeverActivated = false;
2308
2309 sp = 2;
2310
2311 for (j = 0; j < rh; j++) {
2312 for (i = 0; i < rw; i++) {
2313 if (UberRoomPattern[sp]) {
2314 dungeon[rx1 + i][ry1 + j] = UberRoomPattern[sp];
2315 L5dflags[rx1 + i][ry1 + j] |= DLRG_PROTECTED;
2316 } else {
2317 dungeon[rx1 + i][ry1 + j] = 13;
2318 }
2319 sp++;
2320 }
2321 }
2322 }
2323
drlg_l1_set_corner_room(int rx1,int ry1)2324 void drlg_l1_set_corner_room(int rx1, int ry1)
2325 {
2326 int rw, rh, i, j, sp;
2327
2328 rw = CornerstoneRoomPattern[0];
2329 rh = CornerstoneRoomPattern[1];
2330
2331 setpc_x = rx1;
2332 setpc_y = ry1;
2333 setpc_w = rw;
2334 setpc_h = rh;
2335
2336 sp = 2;
2337
2338 for (j = 0; j < rh; j++) {
2339 for (i = 0; i < rw; i++) {
2340 if (CornerstoneRoomPattern[sp]) {
2341 dungeon[rx1 + i][ry1 + j] = CornerstoneRoomPattern[sp];
2342 L5dflags[rx1 + i][ry1 + j] |= DLRG_PROTECTED;
2343 } else {
2344 dungeon[rx1 + i][ry1 + j] = 13;
2345 }
2346 sp++;
2347 }
2348 }
2349 }
2350
DRLG_L5FTVR(int i,int j,int x,int y,int d)2351 static void DRLG_L5FTVR(int i, int j, int x, int y, int d)
2352 {
2353 if (dTransVal[x][y] || dungeon[i][j] != 13) {
2354 if (d == 1) {
2355 dTransVal[x][y] = TransVal;
2356 dTransVal[x][y + 1] = TransVal;
2357 }
2358 if (d == 2) {
2359 dTransVal[x + 1][y] = TransVal;
2360 dTransVal[x + 1][y + 1] = TransVal;
2361 }
2362 if (d == 3) {
2363 dTransVal[x][y] = TransVal;
2364 dTransVal[x + 1][y] = TransVal;
2365 }
2366 if (d == 4) {
2367 dTransVal[x][y + 1] = TransVal;
2368 dTransVal[x + 1][y + 1] = TransVal;
2369 }
2370 if (d == 5)
2371 dTransVal[x + 1][y + 1] = TransVal;
2372 if (d == 6)
2373 dTransVal[x][y + 1] = TransVal;
2374 if (d == 7)
2375 dTransVal[x + 1][y] = TransVal;
2376 if (d == 8)
2377 dTransVal[x][y] = TransVal;
2378 } else {
2379 dTransVal[x][y] = TransVal;
2380 dTransVal[x + 1][y] = TransVal;
2381 dTransVal[x][y + 1] = TransVal;
2382 dTransVal[x + 1][y + 1] = TransVal;
2383 DRLG_L5FTVR(i + 1, j, x + 2, y, 1);
2384 DRLG_L5FTVR(i - 1, j, x - 2, y, 2);
2385 DRLG_L5FTVR(i, j + 1, x, y + 2, 3);
2386 DRLG_L5FTVR(i, j - 1, x, y - 2, 4);
2387 DRLG_L5FTVR(i - 1, j - 1, x - 2, y - 2, 5);
2388 DRLG_L5FTVR(i + 1, j - 1, x + 2, y - 2, 6);
2389 DRLG_L5FTVR(i - 1, j + 1, x - 2, y + 2, 7);
2390 DRLG_L5FTVR(i + 1, j + 1, x + 2, y + 2, 8);
2391 }
2392 }
2393
DRLG_L5FloodTVal()2394 static void DRLG_L5FloodTVal()
2395 {
2396 int xx, yy, i, j;
2397
2398 yy = 16;
2399
2400 for (j = 0; j < DMAXY; j++) {
2401 xx = 16;
2402
2403 for (i = 0; i < DMAXX; i++) {
2404 if (dungeon[i][j] == 13 && !dTransVal[xx][yy]) {
2405 DRLG_L5FTVR(i, j, xx, yy, 0);
2406 TransVal++;
2407 }
2408 xx += 2;
2409 }
2410 yy += 2;
2411 }
2412 }
2413
DRLG_L5TransFix()2414 static void DRLG_L5TransFix()
2415 {
2416 int xx, yy, i, j;
2417
2418 yy = 16;
2419
2420 for (j = 0; j < DMAXY; j++) {
2421 xx = 16;
2422
2423 for (i = 0; i < DMAXX; i++) {
2424 // BUGFIX: Should check for `j > 0` first. (fixed)
2425 if (dungeon[i][j] == 23 && j > 0 && dungeon[i][j - 1] == 18) {
2426 dTransVal[xx + 1][yy] = dTransVal[xx][yy];
2427 dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy];
2428 }
2429 // BUGFIX: Should check for `i + 1 < DMAXY` first. (fixed)
2430 if (dungeon[i][j] == 24 && i + 1 < DMAXY && dungeon[i + 1][j] == 19) {
2431 dTransVal[xx][yy + 1] = dTransVal[xx][yy];
2432 dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy];
2433 }
2434 if (dungeon[i][j] == 18) {
2435 dTransVal[xx + 1][yy] = dTransVal[xx][yy];
2436 dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy];
2437 }
2438 if (dungeon[i][j] == 19) {
2439 dTransVal[xx][yy + 1] = dTransVal[xx][yy];
2440 dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy];
2441 }
2442 if (dungeon[i][j] == 20) {
2443 dTransVal[xx + 1][yy] = dTransVal[xx][yy];
2444 dTransVal[xx][yy + 1] = dTransVal[xx][yy];
2445 dTransVal[xx + 1][yy + 1] = dTransVal[xx][yy];
2446 }
2447 xx += 2;
2448 }
2449 yy += 2;
2450 }
2451 }
2452
DRLG_L5DirtFix()2453 static void DRLG_L5DirtFix()
2454 {
2455 int i, j;
2456
2457 if (currlevel < 21) {
2458 for (j = 0; j < DMAXY - 1; j++) {
2459 for (i = 0; i < DMAXX - 1; i++) {
2460 if (dungeon[i][j] == 21 && dungeon[i + 1][j] != 19)
2461 dungeon[i][j] = 202;
2462 if (dungeon[i][j] == 19 && dungeon[i + 1][j] != 19)
2463 dungeon[i][j] = 200;
2464 if (dungeon[i][j] == 24 && dungeon[i + 1][j] != 19)
2465 dungeon[i][j] = 205;
2466 if (dungeon[i][j] == 18 && dungeon[i][j + 1] != 18)
2467 dungeon[i][j] = 199;
2468 if (dungeon[i][j] == 21 && dungeon[i][j + 1] != 18)
2469 dungeon[i][j] = 202;
2470 if (dungeon[i][j] == 23 && dungeon[i][j + 1] != 18)
2471 dungeon[i][j] = 204;
2472 }
2473 }
2474 } else {
2475 for (j = 0; j < DMAXY - 1; j++) {
2476 for (i = 0; i < DMAXX - 1; i++) {
2477 if (dungeon[i][j] == 19)
2478 dungeon[i][j] = 83;
2479 if (dungeon[i][j] == 21)
2480 dungeon[i][j] = 85;
2481 if (dungeon[i][j] == 23)
2482 dungeon[i][j] = 87;
2483 if (dungeon[i][j] == 24)
2484 dungeon[i][j] = 88;
2485 if (dungeon[i][j] == 18)
2486 dungeon[i][j] = 82;
2487 }
2488 }
2489 }
2490 }
2491
DRLG_L5CornerFix()2492 static void DRLG_L5CornerFix()
2493 {
2494 int i, j;
2495
2496 for (j = 1; j < DMAXY - 1; j++) {
2497 for (i = 1; i < DMAXX - 1; i++) {
2498 if (!(L5dflags[i][j] & DLRG_PROTECTED) && dungeon[i][j] == 17 && dungeon[i - 1][j] == 13 && dungeon[i][j - 1] == 1) {
2499 dungeon[i][j] = 16;
2500 L5dflags[i][j - 1] &= DLRG_PROTECTED;
2501 }
2502 if (dungeon[i][j] == 202 && dungeon[i + 1][j] == 13 && dungeon[i][j + 1] == 1) {
2503 dungeon[i][j] = 8;
2504 }
2505 }
2506 }
2507 }
2508
DRLG_L5(int entry)2509 static void DRLG_L5(int entry)
2510 {
2511 int i, j;
2512 LONG minarea;
2513 BOOL doneflag;
2514
2515 switch (currlevel) {
2516 case 1:
2517 minarea = 533;
2518 break;
2519 case 2:
2520 minarea = 693;
2521 break;
2522 default:
2523 minarea = 761;
2524 break;
2525 }
2526
2527 do {
2528 DRLG_InitTrans();
2529
2530 do {
2531 InitL5Dungeon();
2532 L5firstRoom();
2533 } while (L5GetArea() < minarea);
2534
2535 L5makeDungeon();
2536 L5makeDmt();
2537 L5FillChambers();
2538 L5tileFix();
2539 L5AddWall();
2540 L5ClearFlags();
2541 DRLG_L5FloodTVal();
2542
2543 doneflag = TRUE;
2544
2545 if (QuestStatus(Q_PWATER)) {
2546 if (entry == ENTRY_MAIN) {
2547 if (DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2548 doneflag = FALSE;
2549 } else {
2550 if (DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, FALSE, -1, 0) < 0)
2551 doneflag = FALSE;
2552 ViewY--;
2553 }
2554 }
2555 if (QuestStatus(Q_LTBANNER)) {
2556 if (entry == ENTRY_MAIN) {
2557 if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2558 doneflag = FALSE;
2559 } else {
2560 if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, FALSE, -1, 0) < 0)
2561 doneflag = FALSE;
2562 if (entry == ENTRY_PREV) {
2563 ViewX = 2 * setpc_x + 20;
2564 ViewY = 2 * setpc_y + 28;
2565 } else {
2566 ViewY--;
2567 }
2568 }
2569 } else if (entry == ENTRY_MAIN) {
2570 if (currlevel < 21) {
2571 if (!plr[myplr].pOriginalCathedral) {
2572 if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2573 doneflag = FALSE;
2574 if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2575 doneflag = FALSE;
2576 } else {
2577 if (DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2578 doneflag = FALSE;
2579 else if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2580 doneflag = FALSE;
2581 }
2582 } else if (currlevel == 21) {
2583 if (DRLG_PlaceMiniSet(L5STAIRSTOWN, 1, 1, 0, 0, FALSE, -1, 6) < 0)
2584 doneflag = FALSE;
2585 if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2586 doneflag = FALSE;
2587 ViewY++;
2588 } else {
2589 if (DRLG_PlaceMiniSet(L5STAIRSUPHF, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2590 doneflag = FALSE;
2591 if (currlevel != 24) {
2592 if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2593 doneflag = FALSE;
2594 }
2595 ViewY++;
2596 }
2597 } else if (!plr[myplr].pOriginalCathedral && entry == ENTRY_PREV) {
2598 if (currlevel < 21) {
2599 if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, FALSE, -1, 0) < 0)
2600 doneflag = FALSE;
2601 if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, TRUE, -1, 1) < 0)
2602 doneflag = FALSE;
2603 ViewY--;
2604 } else if (currlevel == 21) {
2605 if (DRLG_PlaceMiniSet(L5STAIRSTOWN, 1, 1, 0, 0, FALSE, -1, 6) < 0)
2606 doneflag = FALSE;
2607 if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, TRUE, -1, 1) < 0)
2608 doneflag = FALSE;
2609 ViewY += 3;
2610 } else {
2611 if (DRLG_PlaceMiniSet(L5STAIRSUPHF, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2612 doneflag = FALSE;
2613 if (currlevel != 24) {
2614 if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, TRUE, -1, 1) < 0)
2615 doneflag = FALSE;
2616 }
2617 ViewY += 3;
2618 }
2619 } else {
2620 if (currlevel < 21) {
2621 if (!plr[myplr].pOriginalCathedral) {
2622 if (DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, FALSE, -1, 0) < 0)
2623 doneflag = FALSE;
2624 if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2625 doneflag = FALSE;
2626 } else {
2627 if (DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, FALSE, -1, 0) < 0)
2628 doneflag = FALSE;
2629 else if (DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, TRUE, -1, 1) < 0)
2630 doneflag = FALSE;
2631 ViewY--;
2632 }
2633 } else if (currlevel == 21) {
2634 if (DRLG_PlaceMiniSet(L5STAIRSTOWN, 1, 1, 0, 0, TRUE, -1, 6) < 0)
2635 doneflag = FALSE;
2636 if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2637 doneflag = FALSE;
2638 } else {
2639 if (DRLG_PlaceMiniSet(L5STAIRSUPHF, 1, 1, 0, 0, TRUE, -1, 0) < 0)
2640 doneflag = FALSE;
2641 if (currlevel != 24) {
2642 if (DRLG_PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, FALSE, -1, 1) < 0)
2643 doneflag = FALSE;
2644 }
2645 }
2646 }
2647 } while (doneflag == FALSE);
2648
2649 for (j = 0; j < DMAXY; j++) {
2650 for (i = 0; i < DMAXX; i++) {
2651 if (dungeon[i][j] == 64) {
2652 int xx = 2 * i + 16; /* todo: fix loop */
2653 int yy = 2 * j + 16;
2654 DRLG_CopyTrans(xx, yy + 1, xx, yy);
2655 DRLG_CopyTrans(xx + 1, yy + 1, xx + 1, yy);
2656 }
2657 }
2658 }
2659
2660 DRLG_L5TransFix();
2661 DRLG_L5DirtFix();
2662 DRLG_L5CornerFix();
2663
2664 for (j = 0; j < DMAXY; j++) {
2665 for (i = 0; i < DMAXX; i++) {
2666 if (L5dflags[i][j] & 0x7F)
2667 DRLG_PlaceDoor(i, j);
2668 }
2669 }
2670
2671 if (currlevel < 21) {
2672 DRLG_L5Subs();
2673 } else {
2674 drlg_l1_crypt_pattern1(10);
2675 drlg_l1_crypt_rndset(byte_48A1B4, 95);
2676 drlg_l1_crypt_rndset(byte_48A1B8, 95);
2677 drlg_l1_crypt_rndset(byte_48A1C0, 100);
2678 drlg_l1_crypt_rndset(byte_48A1C8, 100);
2679 drlg_l1_crypt_rndset(byte_48A1E0, 60);
2680 drlg_l1_crypt_lavafloor();
2681 switch (currlevel) {
2682 case 21:
2683 drlg_l1_crypt_pattern2(30);
2684 drlg_l1_crypt_pattern3(15);
2685 drlg_l1_crypt_pattern4(5);
2686 drlg_l1_crypt_lavafloor();
2687 drlg_l1_crypt_pattern7(10);
2688 drlg_l1_crypt_pattern6(5);
2689 drlg_l1_crypt_pattern5(20);
2690 break;
2691 case 22:
2692 drlg_l1_crypt_pattern7(10);
2693 drlg_l1_crypt_pattern6(10);
2694 drlg_l1_crypt_pattern5(20);
2695 drlg_l1_crypt_pattern2(30);
2696 drlg_l1_crypt_pattern3(20);
2697 drlg_l1_crypt_pattern4(10);
2698 drlg_l1_crypt_lavafloor();
2699 break;
2700 case 23:
2701 drlg_l1_crypt_pattern7(10);
2702 drlg_l1_crypt_pattern6(15);
2703 drlg_l1_crypt_pattern5(30);
2704 drlg_l1_crypt_pattern2(30);
2705 drlg_l1_crypt_pattern3(20);
2706 drlg_l1_crypt_pattern4(15);
2707 drlg_l1_crypt_lavafloor();
2708 break;
2709 default:
2710 drlg_l1_crypt_pattern7(10);
2711 drlg_l1_crypt_pattern6(20);
2712 drlg_l1_crypt_pattern5(30);
2713 drlg_l1_crypt_pattern2(30);
2714 drlg_l1_crypt_pattern3(20);
2715 drlg_l1_crypt_pattern4(20);
2716 drlg_l1_crypt_lavafloor();
2717 break;
2718 }
2719 }
2720
2721 if (currlevel < 21) {
2722 DRLG_L1Shadows();
2723 DRLG_PlaceMiniSet(LAMPS, 5, 10, 0, 0, FALSE, -1, 4);
2724 DRLG_L1Floor();
2725 }
2726
2727 for (j = 0; j < DMAXY; j++) {
2728 for (i = 0; i < DMAXX; i++) {
2729 pdungeon[i][j] = dungeon[i][j];
2730 }
2731 }
2732
2733 DRLG_Init_Globals();
2734 DRLG_CheckQuests(setpc_x, setpc_y);
2735 }
2736
CreateL5Dungeon(DWORD rseed,int entry)2737 void CreateL5Dungeon(DWORD rseed, int entry)
2738 {
2739 int i, j;
2740
2741 SetRndSeed(rseed);
2742
2743 dminx = 16;
2744 dminy = 16;
2745 dmaxx = 96;
2746 dmaxy = 96;
2747
2748 UberRow = 0;
2749 UberCol = 0;
2750 IsUberRoomOpened = false;
2751 UberLeverRow = 0;
2752 UberLeverCol = 0;
2753 IsUberLeverActivated = false;
2754 UberDiabloMonsterIndex = 0;
2755
2756 DRLG_InitTrans();
2757 DRLG_InitSetPC();
2758 DRLG_LoadL1SP();
2759 DRLG_L5(entry);
2760 DRLG_L1Pass3();
2761 DRLG_FreeL1SP();
2762
2763 if (currlevel < 17)
2764 DRLG_InitL1Vals();
2765 else
2766 DRLG_InitL5Vals();
2767
2768 DRLG_SetPC();
2769
2770 for (j = dminy; j < dmaxy; j++) {
2771 for (i = dminx; i < dmaxx; i++) {
2772 if (dPiece[i][j] == 290) {
2773 UberRow = i;
2774 UberCol = j;
2775 }
2776 if (dPiece[i][j] == 317) {
2777 CornerStone.x = i;
2778 CornerStone.y = j;
2779 }
2780 }
2781 }
2782 }
2783
drlg_l1_crypt_pattern1(int rndper)2784 void drlg_l1_crypt_pattern1(int rndper)
2785 {
2786 drlg_l1_crypt_rndset(byte_48A3C8, rndper);
2787 drlg_l1_crypt_rndset(byte_48A3CC, rndper);
2788 drlg_l1_crypt_rndset(byte_48A3D0, rndper);
2789 drlg_l1_crypt_rndset(byte_48A3D4, rndper);
2790 }
2791
drlg_l1_crypt_pattern2(int rndper)2792 void drlg_l1_crypt_pattern2(int rndper)
2793 {
2794 drlg_l1_crypt_rndset(byte_48A2FC, rndper);
2795 drlg_l1_crypt_rndset(byte_48A300, rndper);
2796 drlg_l1_crypt_rndset(byte_48A304, rndper);
2797 drlg_l1_crypt_rndset(byte_48A308, rndper);
2798 drlg_l1_crypt_rndset(byte_48A30C, rndper);
2799 drlg_l1_crypt_rndset(byte_48A310, rndper);
2800 drlg_l1_crypt_rndset(byte_48A314, rndper);
2801 drlg_l1_crypt_rndset(byte_48A318, rndper);
2802 drlg_l1_crypt_rndset(byte_48A31C, rndper);
2803 drlg_l1_crypt_rndset(byte_48A320, rndper);
2804 drlg_l1_crypt_rndset(byte_48A324, rndper);
2805 drlg_l1_crypt_rndset(byte_48A328, rndper);
2806 drlg_l1_crypt_rndset(byte_48A32C, rndper);
2807 drlg_l1_crypt_rndset(byte_48A330, rndper);
2808 drlg_l1_crypt_rndset(byte_48A334, rndper);
2809 drlg_l1_crypt_rndset(byte_48A338, rndper);
2810 drlg_l1_crypt_rndset(byte_48A33C, rndper);
2811 }
2812
drlg_l1_crypt_pattern3(int rndper)2813 void drlg_l1_crypt_pattern3(int rndper)
2814 {
2815 drlg_l1_crypt_rndset(byte_48A340, rndper);
2816 drlg_l1_crypt_rndset(byte_48A344, rndper);
2817 drlg_l1_crypt_rndset(byte_48A348, rndper);
2818 drlg_l1_crypt_rndset(byte_48A34C, rndper);
2819 drlg_l1_crypt_rndset(byte_48A350, rndper);
2820 drlg_l1_crypt_rndset(byte_48A354, rndper);
2821 drlg_l1_crypt_rndset(byte_48A358, rndper);
2822 drlg_l1_crypt_rndset(byte_48A35C, rndper);
2823 drlg_l1_crypt_rndset(byte_48A360, rndper);
2824 drlg_l1_crypt_rndset(byte_48A364, rndper);
2825 drlg_l1_crypt_rndset(byte_48A368, rndper);
2826 drlg_l1_crypt_rndset(byte_48A36C, rndper);
2827 drlg_l1_crypt_rndset(byte_48A370, rndper);
2828 drlg_l1_crypt_rndset(byte_48A374, rndper);
2829 drlg_l1_crypt_rndset(byte_48A378, rndper);
2830 drlg_l1_crypt_rndset(byte_48A37C, rndper);
2831 drlg_l1_crypt_rndset(byte_48A380, rndper);
2832 }
2833
drlg_l1_crypt_pattern4(int rndper)2834 void drlg_l1_crypt_pattern4(int rndper)
2835 {
2836 drlg_l1_crypt_rndset(byte_48A384, rndper);
2837 drlg_l1_crypt_rndset(byte_48A388, rndper);
2838 drlg_l1_crypt_rndset(byte_48A38C, rndper);
2839 drlg_l1_crypt_rndset(byte_48A390, rndper);
2840 drlg_l1_crypt_rndset(byte_48A394, rndper);
2841 drlg_l1_crypt_rndset(byte_48A398, rndper);
2842 drlg_l1_crypt_rndset(byte_48A39C, rndper);
2843 drlg_l1_crypt_rndset(byte_48A3A0, rndper);
2844 drlg_l1_crypt_rndset(byte_48A3A4, rndper);
2845 drlg_l1_crypt_rndset(byte_48A3A8, rndper);
2846 drlg_l1_crypt_rndset(byte_48A3AC, rndper);
2847 drlg_l1_crypt_rndset(byte_48A3B0, rndper);
2848 drlg_l1_crypt_rndset(byte_48A3B4, rndper);
2849 drlg_l1_crypt_rndset(byte_48A3B8, rndper);
2850 drlg_l1_crypt_rndset(byte_48A3BC, rndper);
2851 drlg_l1_crypt_rndset(byte_48A3C0, rndper);
2852 drlg_l1_crypt_rndset(byte_48A3C4, rndper);
2853 }
2854
drlg_l1_crypt_pattern5(int rndper)2855 void drlg_l1_crypt_pattern5(int rndper)
2856 {
2857 drlg_l1_crypt_rndset(byte_48A260, rndper);
2858 drlg_l1_crypt_rndset(byte_48A278, rndper);
2859 drlg_l1_crypt_rndset(byte_48A290, rndper);
2860 drlg_l1_crypt_rndset(byte_48A2A8, rndper);
2861 drlg_l1_crypt_rndset(byte_48A2C0, rndper);
2862 drlg_l1_crypt_rndset(byte_48A2D8, rndper);
2863 drlg_l1_crypt_rndset(byte_48A2EC, rndper);
2864 drlg_l1_crypt_rndset(byte_48A2F0, rndper);
2865 drlg_l1_crypt_rndset(byte_48A2F4, rndper);
2866 drlg_l1_crypt_rndset(byte_48A2F8, rndper);
2867 }
2868
drlg_l1_crypt_pattern6(int rndper)2869 void drlg_l1_crypt_pattern6(int rndper)
2870 {
2871 drlg_l1_crypt_rndset(byte_48A1F4, rndper);
2872 drlg_l1_crypt_rndset(byte_48A1FC, rndper);
2873 drlg_l1_crypt_rndset(byte_48A1F8, rndper);
2874 drlg_l1_crypt_rndset(byte_48A200, rndper);
2875 drlg_l1_crypt_rndset(byte_48A204, rndper);
2876 drlg_l1_crypt_rndset(byte_48A208, rndper);
2877 drlg_l1_crypt_rndset(byte_48A20C, rndper);
2878 drlg_l1_crypt_rndset(byte_48A210, rndper);
2879 drlg_l1_crypt_rndset(byte_48A214, rndper);
2880 drlg_l1_crypt_rndset(byte_48A218, rndper);
2881 drlg_l1_crypt_rndset(byte_48A21C, rndper);
2882 drlg_l1_crypt_rndset(byte_48A220, rndper);
2883 drlg_l1_crypt_rndset(byte_48A224, rndper);
2884 drlg_l1_crypt_rndset(byte_48A228, rndper);
2885 drlg_l1_crypt_rndset(byte_48A22C, rndper);
2886 drlg_l1_crypt_rndset(byte_48A230, rndper);
2887 drlg_l1_crypt_rndset(byte_48A234, rndper);
2888 drlg_l1_crypt_rndset(byte_48A238, rndper);
2889 drlg_l1_crypt_rndset(byte_48A23C, rndper);
2890 drlg_l1_crypt_rndset(byte_48A240, rndper);
2891 drlg_l1_crypt_rndset(byte_48A244, rndper);
2892 drlg_l1_crypt_rndset(byte_48A248, rndper);
2893 drlg_l1_crypt_rndset(byte_48A24C, rndper);
2894 drlg_l1_crypt_rndset(byte_48A250, rndper);
2895 drlg_l1_crypt_rndset(byte_48A254, rndper);
2896 drlg_l1_crypt_rndset(byte_48A258, rndper);
2897 }
2898
drlg_l1_crypt_pattern7(int rndper)2899 void drlg_l1_crypt_pattern7(int rndper)
2900 {
2901 drlg_l1_crypt_rndset(byte_48A1D0, rndper);
2902 drlg_l1_crypt_rndset(byte_48A1D4, rndper);
2903 drlg_l1_crypt_rndset(byte_48A1D8, rndper);
2904 drlg_l1_crypt_rndset(byte_48A1DC, rndper);
2905 }
2906
2907 DEVILUTION_END_NAMESPACE
2908