small fixes for API changes
[k8vacspelynky.git] / packages / Generator / RoomGenT0B.vc
blobfc3516a160005a58e6c5f75dbb0461710813eacf
1 /**********************************************************************************
2  * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3  * Copyright (c) 2010, Moloch
4  * Copyright (c) 2018, Ketmar Dark
5  *
6  * This file is part of Spelunky.
7  *
8  * You can redistribute and/or modify Spelunky, including its source code, under
9  * the terms of the Spelunky User License.
10  *
11  * Spelunky is distributed in the hope that it will be entertaining and useful,
12  * but WITHOUT WARRANTY.  Please see the Spelunky User License for more details.
13  *
14  * The Spelunky User License should be available in "Game Information", which
15  * can be found in the Resource Explorer, or as an external file called COPYING.
16  * If not, please obtain a new copy of Spelunky from <http://spelunkyworld.com/>
17  *
18  **********************************************************************************/
19 // room generation for Area 2, the Mines (bizarre mode)
20 class RoomGenT0B : RoomGenT0;
22 private final string choose (string s0, string s1) {
23   return (levgen.global.randRoom(0, 1) ? s1 : s0);
26 private final string choose4 (string s0, string s1, string s2, string s3) {
27   switch (levgen.global.randRoom(0, 3)) {
28     case 0: return s0;
29     case 1: return s1;
30     case 2: return s2;
31     case 3: return s3;
32   }
33   FatalError("FUCK?!");
34   return "";
37 private final string choose6 (string s0, string s1, string s2, string s3, string s4, string s5) {
38   switch (levgen.global.randRoom(0, 5)) {
39     case 0: return s0;
40     case 1: return s1;
41     case 2: return s2;
42     case 3: return s3;
43     case 4: return s4;
44     case 5: return s5;
45   }
46   FatalError("FUCK?!");
47   return "";
51 override void generate (int rx, int ry) {
52   //string strTemp, strObs1, strObs2, strObs3;
53   //int roomPath, roomPathAbove;
54   //var n, i, j, obj;
55   //var tile, xpos, ypos, block;
57   GameGlobal global = levgen.global;
59   strTemp = "0000000000"~
60             "0000000000"~
61             "0000000000"~
62             "0000000000"~
63             "0000000000"~
64             "0000000000"~
65             "0000000000"~
66             "0000000000";
68   int roomPath = levgen.getRPath(rx, ry); //[scrGetRoomX(x), scrGetRoomY(y)];
69   int roomPathAbove = -1;
70   shopType = 'General';
71   if (ry != 0) roomPathAbove = levgen.getRPath(rx, ry-1); //scrGetRoomY(y-128)];
73   if (rx == levgen.startRoomX && ry == levgen.startRoomY) {
74     // starting room
75     int n = (roomPath == 2 ? global.randRoom(5, 8) : global.randRoom(1, 4));
76     switch (n) {
77       case 1:
78         strTemp = choose(
79           "6000060000"~
80           "0000000000"~
81           "0000000000"~
82           "0000000000"~
83           "0008000000"~
84           "0000000000"~
85           "0000000000"~
86           "1111111111",
87           //
88           "0000000222"~
89           "L090000000"~
90           "P111000000"~
91           "L111200000"~
92           "L221112000"~
93           "0002112000"~
94           "0002111120"~
95           "1111111111");
96           break;
97         case 2: strTemp = choose("11111111112222222222000000000000000000000008000000000000000000000000001111111111",
98             "2220000000000000090L000000111P000002111L000211122L000211200002111120001111111111"); break;
99         case 3: strTemp = choose("00000000000008000000000000000000L000000000P111111000L111111000L00111111111111111",
100             "00000002200211120000002220022000000021100000000220009020000001111727201111111111"); break;
101         case 4: strTemp = choose("0000000000008000000000000000000000000L000111111P000111111L001111100L001111111111",
102             "21112222220222000000000000002000000900000200212000000021200007711111701111111111"); break;
103         // hole
104         case 5: strTemp = choose("60000600000000000000000000000000000000000008000000000000000000000000002021111120",
105             "111111111122222222220000000000L022200000P111110000L022210900L0000111101112022211"); break;
106         case 6: strTemp = choose("11111111112222222222000000000000000000000008000000000000000000000000002021111120",
107             "111111111122222222220000000000000002220L000011111P009012220L011110000L1122202111"); break;
108         case 7: strTemp = choose("00000000000008000000000000000000L000000000P111111000L111111000L00011111111101111",
109             "22222222220000000000000900000000111021000012002100011102111001200002101111001111"); break;
110         case 8: strTemp = choose("0000000000008000000000000000000000000L000111111P000111111L001111000L001111011111",
111             "21111221120222200220000000000000020900000001111000021122112000400004001112002111"); break;
112     }
113   } else if (rx == levgen.endRoomX && ry == levgen.endRoomY) {
114     // end room
115     int n = (roomPathAbove == 2 ? global.randRoom(1, 4) : global.randRoom(3, 6));
116     switch (n) {
117       case 1: { strTemp = choose("00000000006000060000000000000000000000000008000000000000000000000000001111111111",
118           "00000000000000222000000211100000011112000011221100000000040001100001101120900211"); break; }
119       case 2: { strTemp = choose("00000000000000000000000000000000000000000008000000000000000000000000001111111111",
120           "00000000000000000000000100000000012000000001100100090400110021111022011111201101"); break; }
121       case 3: { strTemp = choose("00000000000010021110001001111000110111129012000000111111111021111111201111111111",
122           "00000000000000000000000000100000000210000010011000001100409010220111121011021111"); break; }
123       case 4: { strTemp = choose("00000000000111200100011110010021111011000000002109011111111102111111121111111111",
124           "00000000000220090000000011100000002120000001111100000211120000111111100021111120"); break; }
125       // no drop
126       case 5: { strTemp = choose("60000600000000000000000000000000000000000008000000000000000000000000001111111111",
127           "11111111110000000000000800000000000000000000000000021111111001111111101111111111"); break; }
128       case 6: { strTemp = choose("11111111110222222220000000000000000000000008000000000000000000000000001111111111",
129           "11111111110211111120022222222000000000000008000000220000000022000000001111111111"); break; }
130     }
131   } else if (roomPath == 0) {
132     // side room
133     int n;
134     if (global.currLevel > 1 && !global.altar && global.randRoom(1, 12) == 1) { //rand(1,16) == 1)
135       n = 11;
136       global.altar = true;
137     } else if (global.idol || ry == 3) {
138       n = global.randRoom(1, 9);
139     } else {
140       n = global.randRoom(1, 10);
141       if (n == 10) global.idol = true;
142       // else n = rand(1,9);
143     }
145     switch (n) {
146       // upper plats
147       case 1: { strTemp = choose4("00000000000010111100000000000000011010000050000000000000000000000000001111111111",
148           "00000000000010111100000000000000011010000050000000000000000000000000001111111111",
149           "00000000000210211220000000000000021012000050000000000000000000000000001111111111",
150           "00000000000222222220000000000000022020000050000000000000000000000000001111111111"); break; }
151       // high walls
152       case 2: { strTemp = choose("110000000040L600000011P000000011L000000011L5000000110000000011000000001111111111",
153           "120600000040000000001100000000120L000000111P500000111L000000112L0000001111111111"); break; }
154       case 3: { strTemp = choose("00000000110060000L040000000P110000000L110050000L11000000001100000000111111111111",
155           "006000002100000000040000000011000000L021050000P111000000L111000000L2111111111111"); break; }
156       case 4: { strTemp = choose("110000000040L600000011P000000011L000000011L0000000110000000011000000001112222111",
157           "22200002220000000000100000000110L002200211P221120212L222220212L00000001112222211"); break; }
158       case 5: { strTemp = choose("00000000110060000L040000000P110000000L110000000L11000000001100000000111112222111",
159           "2220000222000000000010000000012002200L012021122P112022222L210000000L211122222111"); break; }
160       case 6: { strTemp = choose("11111111110221111220002111120000022220000002222000002111120002211112201111111111",
161           "11111111110112112110022011022000002200000020220200021211212001111111101111111111"); break; }
162       case 7: { strTemp = choose4("11111111111112222111112000021111102201111120000211111022011111200002111112222111",
163           "11111111111122222211120000002111022220111200000021111200211112000000211112222111",
164           "111111111111tttttt1111t0v00t1111t0000t1111t0000t1111tG$$0t1111tttttt111111111111", // these 2 are sealed treasure rooms
165           "111111111111tttttt1121t00v0t1121t0000t1221t0000t1211tG$$0t1211tttttt111111111111"); break; }
166       case 8: { strTemp = choose("11111111110000000000110000001111222222111111111111112222221122000000221100000011",
167           "11111111110002222000100000000112002200211102112011122111122120112211021000000001"); break; }
168       case 9: { strTemp = choose6("121111112100L2112L0011P1111P1111L2112L1111L1111L1111L1221L1100L0000L001111221111",
169           "121122112100L0000L0011P1111P1111L2112L1112L1111L2111L2112L1100L2112L001211111121",
170           "121111112100L2120L0011P1111P1112L0000L2112L2000L211211221P110000000L001111221111",
171           "12111111210021221200100200200110000000011100000011120211202100000000001111221111",
172           "12111111210L000000001P122221011L111111011L212212011L110011010L000000001111221111",
173           "12111111210000110000100002001112120001111020000021100021201100200020001111221111"); break; }
174       // idols
175       case 10: { strTemp = "22000000220000B0000000000000000000000000000000000000000000000000I000001111A01111"; break; }
176       // altars
177       case 11: { strTemp = "220000002200000000000000000000000000000000000000000000x0000002211112201111111111"; break; }
178     }
179   } else if (roomPath == 0 || roomPath == 1) {
180     // main room
181     switch (global.randRoom(1, 13)) {
182       // basic rooms
183       case 1: { strTemp = "60000600000000000000000000000000000000000050000000000000000000000000001111111111"; break; }
184       case 2: { strTemp = "60000600000000000000000000000000000000005000050000000000000000000000001111111111"; break; }
185       case 3: { strTemp = choose("60000600000000000000000000000000050000000000000000000000000011111111111111111111",
186           "60000600000000000000000000000060000600000000000000000000000000000000001111111111"); break; }
187       case 4: { strTemp = choose("60000600000000000000000000000000000000000000000000000222220000111111001111111111",
188           "00000000000600000000000000000000000000000000000000002000000002200000001111111111"); break; }
189       case 5: { strTemp = "11111111112222222222000000000000000000000050000000000000000000000000001111111111"; break; }
190       case 6: { strTemp = "11111111112111111112022222222000000000000050000000000000000000000000001111111111"; break; }
191       // low ceiling
192       case 7: { strTemp = choose4("11111111112111111112211111111221111111120111111110022222222000000000001111111111",
193           "11111111112111111112211112111221121011120110202210022000002000000000001111111111",
194           "11111111112111111112211111111221221211120200202110000000022000211200001111111111",
195           "11111111112111111112211112111221120022120222200020000000200002222112201111111111"); break; }
196       // ladders
197       case 8: {
198           if (global.randRoom(1, 2) == 1) strTemp = "1111111111000000000L111111111P000000000L5000050000000000000000000000001111111111";
199           else strTemp = "1111111111L000000000P111111111L0000000005000050000000000000000000000001111111111"; break;
200       }
201       case 9: { strTemp = choose6("000000000000L0000L0000P1111P0000L0000L0000P1111P0000L1111L0000L1111L001111111111",
202           "000000000000L022200000P111100000L111110000L111110000L111111000L11111101111111111",
203           "00000000000002220L000001111P000011111L000011111L000111111L000211111L001111111111",
204           "000000000000000220000L002120000P111111000L11111200002111111000211111201111111111",
205           "0000000000000022200000002120L000011111P000211111L0011111120002111112001111111111",
206           "00000000000L000000L00P112211P00L112200L00L111111P000221111L000221111L01111111111"); break; }
207       // upper plats
208       case 10: { strTemp = choose("00000000000111111110001111110000000000005000050000000000000000000000001111111111",
209           "00000000000111111110002222220000000000000050000000000000000000000000001111111111"); break; }
210       case 11: { strTemp = choose("00000000000000000000000000000000000000000021111200021111112021111111121111111111",
211           "00000000000000000000000200200000112212000021111100011111111021111111121111111111"); break; }
212       // treasure below
213       case 12: { strTemp = choose4("2222222222000000000000000000L001111111P001050000L011000000L010000000L01111111111",
214           "222222222200000000L000222221P001111111L001050000L0110000000010000000001111111111", // new
215           "222222222200000000000L000000000P111111100L500000100L000000110L000000011111111111",
216           "22222222220L000000000P122222000L111111100L50000010000000001100000000011111111111"); break; } // new
217       // lava/water
218       case 13:
219         switch (global.randRoom(0, 11)) {
220           case 0: strTemp = "00000000000000000000000000000000000000000NHyyyyN3003HyyyyH30333HHHH3333333333333"; break;
221           case 1: strTemp = "000000000000000002000002000000000000000003HyHHyH3003HyyyyH30333HHHH33NNN333N3N33"; break;
222           case 2: strTemp = "00000000000000000N00000N00000000000000000NHyyyyH3003HyyyyH30333HHHH3333NNN33NN33"; break;
223           case 3: strTemp = "00000000000000000000000000000000000000000NJyyyyJ100NJyyyyJ10111JJJJ1111111111111"; break;
224           case 4: strTemp = "000000000000000002000002000000000000000001JyJJyJ1001JyyyyJ10111JJJJ1111111111111"; break;
225           case 5: strTemp = "000000000000000001000001000000000000000001JyyyyJ1001JyyyyJ10111JJJJ1111111111111"; break;
226           case 6: strTemp = "00000000000000000000000000000000000000000N^wwwwN3003^wwww^30333^^^^3333333333333"; break;
227           case 7: strTemp = "000000000000000002000002000000000000000003^w^^w^3003^wwww^30333^^^^33NNN333N3N33"; break;
228           case 8: strTemp = "00000000000000000N00000N00000000000000000N^wwww^3003^wwww^30333^^^^3333NNN33NN33"; break;
229           case 9: strTemp = "00000000000000000000000000000000000000000NZwwwwZ100NZwwwwZ10111ZZZZ1111111111111"; break;
230           case 10: strTemp = "000000000000000002000002000000000000000001ZwZZwZ1001ZwwwwZ10111ZZZZ1111111111111"; break;
231           case 11: strTemp = "000000000000000001000001000000000000000001ZwwwwZ1001ZwwwwZ10111ZZZZ1111111111111"; break;
232           default: FatalError("FUCK?!");
233         }
234         break;
235     }
236   } else if (roomPath == 3) {
237     // main room
238     switch (global.randRoom(1, 8)) {
239       // basic rooms
240       case 1: { strTemp = "00000000000000000000000000000000000000000050000000000000000000000000001111111111"; break; }
241       case 2: { strTemp = "00000000000000000000000000000000000000005000050000000000000000000000001111111111"; break; }
242       case 3: { strTemp = "00000000000000000000000000000050000500000000000000000000000011111111111111111111"; break; }
243       case 4: { strTemp = choose("00000000000000000000000600000000000000000000000000000111110000111111001111111111",
244           "00000000000000000000020600002000000000000000000000000211120000111111001111111111"); break; }
245       // upper plats
246       case 5: { strTemp = choose("00000000000111111110001111110000000000005000050000000000000000000000001111111111",
247           "00000000000211111120002222220000000000005000050000000000000000000000001111111111"); break; }
248       case 6: { strTemp = choose("00000000000000000000000000000000000000000021111200021111112021111111121111111111",
249           "00000000000000000000000022000000021120000021111200021111112021111111121111111111"); break; }
250       case 7: { strTemp = choose("10000000011112002111111200211100000000000022222000111111111111111111111111111111",
251           "10000000011112002111111100111100220022000000000000110000001111222222111111111111"); break; }
252       // treasure below
253       case 8: { strTemp = choose4("0000000000000000000000000000L001111111P001050000L011000000L010000000L01111111111",
254           "000000000000022000L000211221P001111111L001050000L0110000000010000000001111111111", // new
255           "000000000000000000000L000000000P111111100L500000100L000000110L000000011111111111",
256           "00000000000L000220000P122112000L111111100L50000010000000001100000000011111111111"); break; // new
257       }
258     }
259   } else if (roomPath == 4) {
260     // shop
261     strTemp = "111111111111111111111111221111111l000211...000W010...00000k0..Kiiii000bbbbbbbbbb";
262     int n = global.randRoom(1, 7);
263     //n = 6;
264     if (global.scumGenShopType > 0) n = global.scumGenShopType;
265     switch (n) {
266       case 1: shopType = 'General'; break;
267       case 2: shopType = 'Bomb'; break;
268       case 3: shopType = 'Weapon'; break;
269       case 4: shopType = 'Rare'; break;
270       case 5: shopType = 'Clothing'; break;
271       case 6: shopType = 'Craps'; strTemp = "11111111111111111111111122111111Kl000211..bQ00W010.0+00000k0.q+dd00000bbbbbbbbbb"; break;
272       case 7: shopType = 'Kissing'; strTemp = "111111111111111111111111221111111l000211...000W010...00000k0..K00D0000bbbbbbbbbb"; global.damsel = true; break;
273     }
274   } else if (roomPath == 5) {
275     // shop
276     strTemp = "111111111111111111111111221111112000l11101W0000...0k00000...000iiiiK..bbbbbbbbbb";
277     int n = global.randRoom(1, 7);
278     //n = 6;
279     if (global.scumGenShopType > 0) n = global.scumGenShopType;
280     switch (n) {
281       case 1: shopType = 'General'; break;
282       case 2: shopType = 'Bomb'; break;
283       case 3: shopType = 'Weapon'; break;
284       case 4: shopType = 'Rare'; break;
285       case 5: shopType = 'Clothing'; break;
286       case 6: shopType = 'Craps'; strTemp = "111111111111111111111111221111112000lK1101W0Q00b..0k00000+0.00000dd+q.bbbbbbbbbb"; break;
287       case 7: shopType = 'Kissing'; strTemp = "111111111111111111111111221111112000l11101W0000...0k00000...0000D00K..bbbbbbbbbb"; global.damsel = true; break;
288     }
289   } else if (roomPath == 8) {
290     // snake pit
291     strTemp = "111000011111s0000s11111200211111s0000s11111200211111s0000s11111200211111s0000s11";
292   } else if (roomPath == 9) {
293     // snake pit bottom
294     strTemp = "111000011111s0000s1111100001111100S0001111S0110S11111STTS1111111M111111111111111";
295   } else {
296     // drop
297     int n;
298          if (roomPath == 7) n = global.randRoom(4, 12); // top of pit
299     else if (roomPathAbove != 2) n = global.randRoom(1, 12); // any
300     else n = global.randRoom(1, 8); // need open ceiling
301     switch (n) {
302       case 1: { strTemp = choose("00000000006000060000000000000000000000006000060000000000000000000000000000000000",
303           "00000000000060000000000000000000000000000000600000000000000000000000000000000000"); break; }
304       case 2: { strTemp = choose("00000000006000060000000000000000000000000000050000000000000000000000001202111111",
305           "00000000000000000000022202220000000000000000250000020200000000000000001202111111"); break; }
306       case 3: { strTemp = choose("00000000006000060000000000000000000000005000000000000000000000000000001111112021",
307           "00000000000002220000000000022000000000005000020000000000022000000000001111112021"); break; }
308       case 4: { strTemp = choose("00000000006000060000000000000000000000000000000000000000000002200002201112002111",
309           "00000000000000000000002222220000110011000000000000002000020002120021201111001111"); break; }
310       case 5: { strTemp = choose("00000000000000220000000000000000200002000112002110011100111012000000211111001111",
311           "00000000000021111200000000000000200002000212002120011100111011000000111112001111"); break; }
312       case 6: { strTemp = choose("00000000000060000000000000000000000000000000000000001112220002100000001110111111",
313           "00000000000022000000000002220000010111000001000000001112220002100000001110211111"); break; }
314       case 7: { strTemp = choose("00000000000060000000000000000000000000000000000000002221110000000001201111110111",
315           "00000000000000002200002220000000111010000000001000002221110000000001201111120111"); break; }
316       case 8: { strTemp = choose("00000000000060000000000000000000000000000000000000002022020000100001001111001111",
317           "00000000000002002000000100100000110011000012002100011100111001200002101111001111"); break; }
318       case 9: { strTemp = choose("11111111112222222222000000000000000000000000000000000000000000000000001120000211",
319           "11111111112111111112021111112000211112000002222000000000000002000000201120000211"); break; }
320       case 10: { strTemp = choose("11111111112222111111000002211100000002110000000000200000000000000000211120000211",
321           "11111111110111111111021111111100212111110002021110000000200002000000111120000111"); break; }
322       case 11: { strTemp = choose("11111111111111112222111220000011200000000000000000000000000012000000001120000211",
323           "11111111111111111110111111112011111221000111200200000200000012000000201120000211"); break; }
324       case 12: { strTemp = choose("11111111112111111112021111112000211112000002112000000022000002200002201111001111",
325           "11111111112112222112012000021001002200100102112110000000000002200002201111001111"); break; }
326     }
327   }
329   // add obstacles
330   foreach (int i; 0..80) {
331     int j = i;
333     string strObs1 = "00000";
334     string strObs2 = "00000";
335     string strObs3 = "00000";
336     int tile = strTemp[i];
338     //if (tile == "8") { strObs1 = "00000"; strObs2 = "00000"; strObs3 = "00900" }
340     if (tile == "8") {
341       // entrance/exit
342       switch (global.randRoom(1, 12)) {
343         case 1: { strObs1 = "00900"; strObs2 = "01110"; strObs3 = "11111"; break; }
344         case 2: { strObs1 = "00900"; strObs2 = "02120"; strObs3 = "02120"; break; }
345         case 3: { strObs1 = "00000"; strObs2 = "00000"; strObs3 = "92222"; break; }
346         case 4: { strObs1 = "00000"; strObs2 = "00000"; strObs3 = "22229"; break; }
347         case 5: { strObs1 = "00000"; strObs2 = "11001"; strObs3 = "19001"; break; }
348         case 6: { strObs1 = "00000"; strObs2 = "10011"; strObs3 = "10091"; break; }
349         case 7: { strObs1 = "11111"; strObs2 = "10001"; strObs3 = "40094"; break; }
350         case 8: { strObs1 = "00000"; strObs2 = "12021"; strObs3 = "12921"; break; }
351         case 9: { strObs1 = "00900"; strObs2 = "03330"; strObs3 = "33333"; break; }
352         case 10: { strObs1 = "00000"; strObs2 = "33003"; strObs3 = "39003"; break; }
353         case 11: { strObs1 = "00000"; strObs2 = "N00N3"; strObs3 = "N0093"; break; }
354         case 12: { strObs1 = "N3333"; strObs2 = "30003"; strObs3 = "40094"; break; }
355       }
356     } else if (tile == "5") {
357       // ground
358       switch (global.randRoom(1, 19)) {
359         case 1: { strObs1 = "11111"; strObs2 = "00000"; strObs3 = "00000"; break; }
360         case 2: { strObs1 = "00000"; strObs2 = "11110"; strObs3 = "00000"; break; }
361         case 3: { strObs1 = "00000"; strObs2 = "01111"; strObs3 = "00000"; break; }
362         case 4: { strObs1 = "00000"; strObs2 = "00000"; strObs3 = "11111"; break; }
363         case 5: { strObs1 = "00000"; strObs2 = "20200"; strObs3 = "17177"; break; }
364         case 6: { strObs1 = "00000"; strObs2 = "02020"; strObs3 = "71717"; break; }
365         case 7: { strObs1 = "00000"; strObs2 = "00202"; strObs3 = "77171"; break; }
366         case 8: { strObs1 = "00000"; strObs2 = "22200"; strObs3 = "11100"; break; }
367         case 9: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "01110"; break; }
368         case 10: { strObs1 = "00000"; strObs2 = "00222"; strObs3 = "00111"; break; }
369         case 11: { strObs1 = "11100"; strObs2 = "22200"; strObs3 = "00000"; break; }
370         case 12: { strObs1 = "01110"; strObs2 = "02220"; strObs3 = "00000"; break; }
371         case 13: { strObs1 = "00111"; strObs2 = "00222"; strObs3 = "00000"; break; }
372         case 14: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "21112"; break; }
373         case 15: { strObs1 = "00000"; strObs2 = "20100"; strObs3 = "77117"; break; }
374         case 16: { strObs1 = "00000"; strObs2 = "00102"; strObs3 = "71177"; break; }
375         case 17: { strObs1 = "NN3NN"; strObs2 = "00000"; strObs3 = "00000"; break; }
376         case 18: { strObs1 = "00000"; strObs2 = "N33N0"; strObs3 = "00000"; break; }
377         case 19: { strObs1 = "00000"; strObs2 = "0N33N"; strObs3 = "00000"; break; }
378       }
379     } else if (tile == "6") {
380       // air
381       switch (global.randRoom(1, 12)) {
382         case 1: { strObs1 = "11111"; strObs2 = "00000"; strObs3 = "00000"; break; }
383         case 2: { strObs1 = "22222"; strObs2 = "00000"; strObs3 = "00000"; break; }
384         case 3: { strObs1 = "11100"; strObs2 = "22200"; strObs3 = "00000"; break; }
385         case 4: { strObs1 = "01110"; strObs2 = "02220"; strObs3 = "00000"; break; }
386         case 5: { strObs1 = "00111"; strObs2 = "00222"; strObs3 = "00000"; break; }
387         case 6: { strObs1 = "00000"; strObs2 = "01110"; strObs3 = "00000"; break; }
388         case 7: { strObs1 = "00000"; strObs2 = "01110"; strObs3 = "02220"; break; }
389         case 8: { strObs1 = "00000"; strObs2 = "02220"; strObs3 = "01110"; break; }
390         case 9: { strObs1 = "00000"; strObs2 = "00220"; strObs3 = "01111"; break; }
391         case 10: { strObs1 = "00000"; strObs2 = "22200"; strObs3 = "11100"; break; }
392         case 11: { strObs1 = "NNNNN"; strObs2 = "00000"; strObs3 = "00000"; break; }
393         case 12: { strObs1 = "00000"; strObs2 = "0NNN0"; strObs3 = "00000"; break; }
394       }
395     }
397     if (tile == "5" || tile == "6" || tile == "8") {
398       //strTemp = string_delete(strTemp, j, 5);
399       //strTemp = string_insert(strObs1, strTemp, j);
400       strTemp[j..j+5] = strObs1;
401       j += 10;
402       //strTemp = string_delete(strTemp, j, 5);
403       //strTemp = string_insert(strObs2, strTemp, j);
404       strTemp[j..j+5] = strObs2;
405       j += 10;
406       //strTemp = string_delete(strTemp, j, 5);
407       //strTemp = string_insert(strObs3, strTemp, j);
408       strTemp[j..j+5] = strObs3;
409     }
410   }
414 transient array!int bzprobs;
416 // used by scrEntityGenBizarre to avoid creating a bunch more global variables
417 // called by scrEntityGenMix
418 // higher number = less chance of enemy spawning
419 int bizGetProbBase (name aname) {
420   auto global = levgen.global;
421   // defaults (area 1 - mines)
422   switch (aname) {
423     case 'spearTrap': return 80;
424     case 'giantSpider': return 50;
425     case 'bat': return 80;
426     case 'spider': return 90;
427     case 'ufo': return 350;
428     case 'springTrap': return 80;
429     case 'snake': return 70;
430     case 'caveman': return 110;
431     case 'manTrap': return 270;
432     case 'hawkman': return 400;
433     case 'frog': return 300;
434     case 'yeti': return 300;
435     case 'fireFrog': return 350;
436     case 'zombie': return 270;
437     case 'vampire': return 950;
438     case 'alien': return 400;
439     case 'monkey': return 320;
440     case 'outlaw': return 9000; // disabled in levelgen
441     case 'magmaMan': return 1200;
442     case 'tombLord': return 90;
443     case 'yetiKing': return 80;
444     case 'alienBoss': return 120;
445     case 'smashTrap': return 480;
446     case 'thwompTrap': return 200;
447     case 'arrowTrap': return 4;
448     case 'arrowTrap2': return 40;
449     case 'monkeyVine': return 20;
450     case 'fish': return 30;
451     case 'blob': return 300; // slime
452     case 'greenFrog': return 460;
453     case 'cobra': return 300;
454     case 'greenSpider': return 440;
455     case 'man': return 400;
456     case 'floater': return 520; //700
457   }
459   if (global.levelType == 1) {
460     // area 2 - lush jungle
461     if (global.cemetary) {
462       switch (aname) {
463         case 'zombie': return 800;
464         case 'vampire': return 1000;
465       }
466     }
467     switch (aname) {
468       case 'bat': return 70;
469       case 'spider': return 90;
470       case 'snake': return 80;
471       case 'frog': return 40;
472       case 'manTrap': return 70;
473       case 'vampire': return 420;
474       case 'ufo': return 340;
475       case 'spearTrap': return 15;
476       case 'fireFrog': return 150;
477       case 'smashTrap': return 290;
478       case 'thwompTrap': return 110;
479       case 'yetiKing': return 70;
480       case 'alienBoss': return 90;
481     }
482   } else if (global.levelType == 2) {
483     // area 3 - ice caves
484     if (!global.yetiLair && aname == 'ufo') return 30;
485     switch (aname) {
486       case 'snake': return 200;
487       case 'bat': return 140;
488       case 'spider': return 150;
489       case 'springTrap': return 10;
490       case 'fireFrog': return 360;
491       case 'manTrap': return 320;
492       case 'yeti': return 25;
493       case 'smashTrap': return 200;
494       case 'thwompTrap': return 70;
495       case 'tombLord': return 60;
496       case 'yetiKing': return 20;
497       case 'alienBoss': return 30;
498       case 'cobra': return 400;
499       case 'blob': return 240;
500     }
501   } else if (global.levelType == 3) {
502     // area 4 - temple
503     switch (aname) {
504       case 'snake': return 80;
505       case 'bat': return 80;
506       case 'spider': return 100;
507       case 'caveman': return 60;
508       case 'hawkman': return 60;
509       case 'yeti': return 300;
510       case 'vampire': return 600;
511       case 'fireFrog': return 300;
512       case 'spearTrap': return 12;
513       case 'smashTrap': return 70;
514       case 'thwompTrap': return 40;
515       case 'magmaMan': return 1600;
516       case 'tombLord': return 40;
517       case 'yetiKing': return 70;
518       case 'alienBoss': return 80;
519       case 'cobra': return 180;
520       case 'blob': return 290;
521       case 'floater': return 480;
522       case 'man': return 150;
523     }
524   }
525   return 0;
529 int bizGetProb (name aname) {
530   if (!aname) return 0;
532   int aid = NameToIIndex(aname);
533   if (aid > 0 && aid < bzprobs.length && bzprobs[aid] >= 0) return bzprobs[aid];
535   auto global = levgen.global;
537   auto res = bizGetProbBase(aname);
539   if (global.genGiantSpider) {
540     if (aname == 'spider') res = round(res/2.0);
541     if (aname == 'greenSpider') res = round(res/2.0);
542   }
543   if (global.genYetiKing && aname == 'yeti') res = round(res/2.0);
544   if (global.genAlienBoss) {
545     if (aname == 'alien') res = round(res/2.0);
546     if (aname == 'ufo') res = round(res/2.0);
547   }
548   if (global.genTombLord) {
549     if (aname == 'zombie') res = round(res/2.0);
550     if (aname == 'cobra') res = round(res/2.0);
551     if (aname == 'hawkman') res = round(res/2.0);
552   }
553   if (global.cemetary && aname == 'zombie') res = round(res/2);
555   // entity quantity variations
556   int c = 16;
557   float d = global.randRoom(4, 6)/2.0;
558        if (aname == 'springTrap' && global.randRoom(1, c) == 1) res = round(res/d);
559   else if (aname == 'spearTrap' && global.randRoom(1, c) == 1) res = round(res/d);
560   else if (aname == 'smashTrap' && global.randRoom(1, c) == 1) res = round(res/d);
561   else if (aname == 'thwompTrap' && global.randRoom(1, c) == 1) res = round(res/d);
562   else if (aname == 'fireFrog' && global.randRoom(1, c) == 1) res = round(res/d);
563   else if (aname == 'magmaMan' && global.randRoom(1, c) == 1) res = round(res/d);
564   else if (aname == 'yeti' && !global.genYetiKing && global.randRoom(1, c) == 1) res = round(res/d);
565   else if ((aname == 'ufo' || aname == 'alien') && !global.genAlienBoss && global.randRoom(1, c) == 1) {
566     if (aname == 'ufo') res = round(res/d);
567     if (aname == 'alien') res = round(res/d);
568   }
569   else if (aname == 'blob' && global.randRoom(1, c) == 1) res = round(res/d);
570   else if (aname == 'floater' && global.randRoom(1, c) == 1) res = round(res/d);
571   else if (aname == 'man' && global.randRoom(1, c) == 1) res = round(res/d);
572   else if (aname == 'monkey' && global.randRoom(1, c) == 1) res = round(res/d);
573   else if (aname == 'frog' && global.randRoom(1, c) == 1) res = round(res/d);
574   else if (aname == 'greenFrog' && global.randRoom(1, c) == 1) res = round(res/d);
575   else if (aname == 'hawkman' && !global.genTombLord && global.randRoom(1, c) == 1) res = round(res/d);
576   else if (aname == 'cobra' && !global.genTombLord && global.randRoom(1, c) == 1) res = round(res/d);
578   while (bzprobs.length <= aid) bzprobs[$] = -1;
579   bzprobs[aid] = res;
580   return res;
584 /+k8: not ready yet
585 override void genEntityAt (int tileX, int tileY) {
586   auto global = levgen.global;
587   auto level = levgen.level;
589   if (level.isInShop(tileX, tileY) || tileY == 0) return;
591   MapTile t = level.getTileAt(tileX, tileY);
593   int x = tileX*16, y = tileY*16;
595   if ((!t || (!t.altar && !t.tree)) &&
596        tileY != 0 &&
597        !level.checkTilesInRect(x, y-32, 16, 32) &&
598        !level.isEnemyInRect(x, y-16, 16, 16) &&
599        !level.isLavaAtPoint(x, y-16) &&
600        (!level.isSolidAtPoint(x-16, y) || !level.isSolidAtPoint(x+16, y)) &&
601        level.isSolidAtPoint(x, y+16) &&
602        //!!!!level.isSolidAtPoint(x, y, oXMarket) &&
603        level.calcNearestEnterDist(x, y) > 64)
604   {
605     if (global.levelType == 1 && global.darkLevel && !level.isLiquidAtPoint(x, y-32) && global.randRoom(1, 20) == 1) {
606       level.MakeMapObject(x, y-32, 'oTikiTorch');
607     } else if (global.randRoom(1, trunc(ceil(float(bizGetProb('spearTrap'))/global.trapMult))) == 1 &&
608                x != 160 && x != 176 && x != 320 && x != 336 && x != 480 && x != 496 &&
609                (!t || (!t.invincible && t.objName != 'Xoc Block')))
610     {
611       auto sol = level.isSolidAtPoint(x, y-16);
612       bool doCreate = true;
613       if (global.levelType != 1 && global.levelType != 3) {
614         doCreate = !level.checkTilesInRect(x-16, y-32, 48, 32);
615       }
616       if (doCreate) {
617         bool wet = false;
618         if (sol) {
619           wet = sol.water || sol.wet;
620           sol.cleanDeath = true;
621           sol.instanceRemove();
622         }
623         if (!wet &&
624             (level.isLiquidAtPoint(x-2, y) || level.isLiquidAtPoint(x+18, y) ||
625              level.isLiquidAtPoint(x-2, y-16) || level.isLiquidAtPoint(x+18, y-16)))
626         {
627           wet = true;
628         }
629         auto trap = level.MakeMapTile(tileX, tileY, 'oSpearTrapBottom');
630         trap.wet = wet;
631         trap = level.MakeMapTile(tileX, tileY-1, (global.darkLevel ? 'oSpearTrapLit' : 'oSpearTrapTop'));
632         trap.wet = wet;
633         //if (wet) writeln("generated WET spear trap");
634         if (t) {
635           t.cleanDeath = true;
636           t.instanceRemove();
637         }
638       }
639     }
640   }
643   if (y > 32 && !level.isSolidAtPoint(x, y-16) && global.genGoldEntrance && !global.madeGoldEntrance) {
644     if (global.randRoom(1, global.goldChance) == 1) {
645       /+!!!
646       instance_create(x, y-16, oGoldDoor);
647       invincible = true;
648       global.madeGoldEntrance = true;
649       +/
650     } else {
651       global.goldChance -= 1;
652     }
653   }
655   if (t && t.isInstanceAlive && !t.altar) {
656     if (global.cemetary) level.scrTreasureGenBizarre(x, y, 10); else level.scrTreasureGenBizarre(x, y);
657   }
660   int roomX, roomY;
661   level.tileXY2roomXY(tileX, tileY-1, roomX, roomY); //k8: why -1?
663   // enemies
664   if (roomX == level.startRoomX && roomY == level.startRoomY) return;
666   if (tileY < GameLevel::NormalTilesHeight-4 &&
667       !level.checkTilesInRect(tileX*16, (tileY+1)*16, 17, 33, &level.cbCollisionAnySolidOrLiquid) &&
668       !level.isObjectAtPoint(tileX*16+8, (tileY+1)*16+8, &level.cbIsObjectEnemy))
669   {
670     if (global.genGiantSpider && !global.giantSpider &&
671         global.randRoom(1, trunc(ceil(40.0/global.config.enemyMult))) == 1 &&
672         !level.checkTilesInRect((tileX+1)*16, (tileY+1)*16, 17, 33, &level.cbCollisionAnySolid/*k8:???OrLiquid*/))
673     {
674       level.MakeMapObject(tileX*16, (tileY+1)*16, 'oGiantSpiderHang');
675       //!!!if (global.hasStickyBombs and rand(1, 2) == 1) { obj.pasteless = true; obj.carries = "Crate"; }
676       if (global.enemyMult >= 2 && global.randRoom(1, trunc(ceil(200.0/global.config.eMult))) == 1) global.giantSpider = false;
677       else global.giantSpider = true;
678     }
679     else if (global.darkLevel && global.randRoom(1, 60) == 1) level.MakeMapTile(tileX, tileY+1, 'oLamp');
680     else if (global.darkLevel && global.randRoom(1, 40) == 1) level.MakeMapObject(tileX*16, (tileY+1)*16, 'oScarab');
681     else if (global.randRoom(1, trunc(ceil(float(bizGetProb('floater'))/global.eMult))) == 1) {
682       auto obj = level.MakeMapObject(x, y+16, 'oFloater');
683       if (obj) {
684         /+!!!
685         switch (rand(1, 6)) {
686           case 4:
687           case 5: obj.carries = "Big Sapphire"; break;
688           case 6: obj.carries = "Big Ruby"; break;
689           default: obj.carries = "Big Emerald";
690         }
691         if (rand(1, 20-global.currLevel) == 1) { obj.explosive = true; obj.sprite_index = sFloaterEvil; }
692         +/
693       }
694     }
695     else if (global.randRoom(1, trunc(ceil(float(bizGetProb('bat'))/global.eMult))) == 1) level.MakeMapObject(x, y+16, 'oBat');
696     else if (global.randRoom(1, trunc(ceil(float(bizGetProb('spider'))/global.eMult))) == 1 && !level.isLadderAtPoint(x+8, y+24)) level.MakeMapObject(x, y+16, 'oSpiderHang');
697     else if (global.randRoom(1, trunc(ceil(float(bizGetProb('greenSpider'))/global.eMult))) == 1 && !level.isLadderAtPoint(x+8, y+24)) level.MakeMapObject(x, y+16, 'oGreenSpiderHang');
698     else if (y > 16 && tileY < GameLevel::NormalTilesHeight-3 && !level.isSolidAtPoint(x, y-16)) {
699       if (global.randRoom(1, trunc(ceil(float(bizGetProb('ufo'))/global.eMult))) == 1) level.MakeMapObject(x, y-16, 'oUFO');
700     }
701   }
706 defaultproperties {
707   rgLevelType = 0; // not ready yet
708   rgBizarre = true;