cosmetix
[k8vacspelynky.git] / packages / Generator / RoomGenT1.vc
blob787d34f1c52c6e97bbf93196ae461b3138318acd
1 /**********************************************************************************
2  * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3  * Copyright (c) 2018, Ketmar Dark
4  *
5  * This file is part of Spelunky.
6  *
7  * You can redistribute and/or modify Spelunky, including its source code, under
8  * the terms of the Spelunky User License.
9  *
10  * Spelunky is distributed in the hope that it will be entertaining and useful,
11  * but WITHOUT WARRANTY.  Please see the Spelunky User License for more details.
12  *
13  * The Spelunky User License should be available in "Game Information", which
14  * can be found in the Resource Explorer, or as an external file called COPYING.
15  * If not, please obtain a new copy of Spelunky from <http://spelunkyworld.com/>
16  *
17  **********************************************************************************/
18 // room generation for Area 2, the Lush Jungle
19 class RoomGenT1 : RoomGen;
22 void generateBlackMarket (int rx, int ry) {
23   GameGlobal global = levgen.global;
25   strTemp = "0000000000"~
26             "0000000000"~
27             "0000000000"~
28             "0000000000"~
29             "0000000000"~
30             "0000000000"~
31             "0000000000"~
32             "0000000000";
34   int roomPath = levgen.getRPath(rx, ry); //[scrGetRoomX(x), scrGetRoomY(y)];
35   int roomPathAbove = -1;
36   shopType = 'General';
37   if (ry != 0) roomPathAbove = levgen.getRPath(rx, ry-1); //scrGetRoomY(y-128)];
39   if (rx == levgen.startRoomX && ry == levgen.startRoomY) {
40     // starting room
41     int n = (roomPath == 2 ? global.randRoom(3, 4) : global.randRoom(1, 2));
42     switch (n) {
43       case 1: { strTemp = "6000060000"~
44                           "0000000000"~
45                           "0000000000"~
46                           "0000000000"~
47                           "0008000000"~
48                           "0000000000"~
49                           "0000000000"~
50                           "1111111111";
51                           break; }
52       case 2: { strTemp = "1111111111"~
53                           "2222222222"~
54                           "0000000000"~
55                           "0000000000"~
56                           "0008000000"~
57                           "0000000000"~
58                           "0000000000"~
59                           "1111111111";
60                           break; }
61       // hole
62       case 3: { strTemp = "6000060000"~
63                           "0000000000"~
64                           "0000000000"~
65                           "0000000000"~
66                           "0008000000"~
67                           "0000000000"~
68                           "0000000000"~
69                           "2021111120";
70                           break; }
71       case 4: { strTemp = "1111111111"~
72                           "2222222222"~
73                           "0000000000"~
74                           "0000000000"~
75                           "0008000000"~
76                           "0000000000"~
77                           "0000000000"~
78                           "2021111120";
79                           break; }
80       default: FatalError("000");
81     }
82   } else if (rx == levgen.endRoomX && ry == levgen.endRoomY) {
83     // exit room
84     int n = (roomPathAbove == 2 ? global.randRoom(1, 2) : global.randRoom(3, 4));
85     switch (n) {
86       case 1: { strTemp = "0000000000"~
87                           "0000000000"~
88                           "0000000000"~
89                           "0000000000"~
90                           "0008000000"~
91                           "0000000000"~
92                           "0000000000"~
93                           "1111111111";
94                           break; }
95       case 2: { strTemp = "0000000000"~
96                           "6000060000"~
97                           "0000000000"~
98                           "0000000000"~
99                           "0008000000"~
100                           "0000000000"~
101                           "0000000000"~
102                           "1111111111";
103                           break; }
104       case 3: { strTemp = "6000060000"~
105                           "0000000000"~
106                           "0000000000"~
107                           "0000000000"~
108                           "0008000000"~
109                           "0000000000"~
110                           "0000000000"~
111                           "1111111111";
112                           break; }
113       case 4: { strTemp = "1111111111"~
114                           "2222222222"~
115                           "0000000000"~
116                           "0000000000"~
117                           "0008000000"~
118                           "0000000000"~
119                           "0000000000"~
120                           "1111111111";
121                           break; }
122       default: FatalError("001");
123     }
124   } else if (roomPath == 1) {
125     switch (global.randRoom(1, 8)) {
126       // basic rooms
127       case 1: { strTemp = "6000060000"~
128                           "0000000000"~
129                           "0000000000"~
130                           "0000000000"~
131                           "0050000000"~
132                           "0000000000"~
133                           "0000000000"~
134                           "1111111111";
135                           break; }
136       case 2: { strTemp = "6000060000"~
137                           "0000000000"~
138                           "0000000000"~
139                           "0000000000"~
140                           "5000050000"~
141                           "0000000000"~
142                           "0000000000"~
143                           "1111111111";
144                           break; }
145       case 3: { strTemp = "6000060000"~
146                           "0000000000"~
147                           "0000000000"~
148                           "5000050000"~
149                           "0000000000"~
150                           "0000000000"~
151                           "1111111111"~
152                           "1111111111";
153                           break; }
154       case 4: { strTemp = "6000060000"~
155                           "0000000000"~
156                           "0000000000"~
157                           "0000000000"~
158                           "0000000000"~
159                           "0001111100"~
160                           "0011111100"~
161                           "1111111111";
162                           break; }
163       // spikes
164       case 5: { strTemp = "1111111111"~
165                           "V0000V0000"~
166                           "0000000000"~
167                           "0000000000"~
168                           "0000000000"~
169                           "1000000001"~
170                           "1ssssssss1"~
171                           "1111111111";
172                           break; }
173       // upper plats
174       case 6: { strTemp = "0000000000"~
175                           "0000000000"~
176                           "0000000000"~
177                           "0000000000"~
178                           "5000050000"~
179                           "0000000000"~
180                           "0000000000"~
181                           "1111111111";
182                           break; }
183       // water
184       case 7: { strTemp = "0000000000"~
185                           "0000000000"~
186                           "0000000000"~
187                           "013wwww310"~
188                           "013wwww310"~
189                           "113wwww311"~
190                           "1113333111"~
191                           "1111111111";
192                           break; }
193       case 8: { strTemp = "0060000000"~
194                           "0000000000"~
195                           "0000000000"~
196                           "0000000000"~
197                           "013wwww310"~
198                           "113wwww311"~
199                           "1113333111"~
200                           "1111111111";
201                           break; }
202       default: FatalError("002");
203     }
204   } else if (roomPath == 3) {
205     // main room
206     switch (global.randRoom(1, 7)) {
207       // basic rooms
208       case 1: { strTemp = "0000000000"~
209                           "0000000000"~
210                           "0000000000"~
211                           "0000000000"~
212                           "0050000000"~
213                           "0000000000"~
214                           "0000000000"~
215                           "1111111111";
216                           break; }
217       case 2: { strTemp = "0000000000"~
218                           "0000000000"~
219                           "0000000000"~
220                           "0000000000"~
221                           "5000050000"~
222                           "0000000000"~
223                           "0000000000"~
224                           "1111111111";
225                           break; }
226       case 3: { strTemp = "0000000000"~
227                           "0000000000"~
228                           "0000000000"~
229                           "5000050000"~
230                           "0000000000"~
231                           "0000000000"~
232                           "1111111111"~
233                           "1111111111";
234                           break; }
236       // upper plats
237       case 4: { strTemp = "0000000000"~
238                           "0000000000"~
239                           "0000000000"~
240                           "0000000000"~
241                           "0002222220"~
242                           "0011111110"~
243                           "1111111111"~
244                           "1111111111";
245                           break; }
246       case 5: { strTemp = "0000000000"~
247                           "0000000000"~
248                           "0000000000"~
249                           "0000000000"~
250                           "0000000221"~
251                           "0000022111"~
252                           "0000221111"~
253                           "1111111111";
254                           break; }
255       // water
256       case 6: { strTemp = "0000000000"~
257                           "0000000000"~
258                           "0000000000"~
259                           "013wwww310"~
260                           "013wwww310"~
261                           "113wwww311"~
262                           "1113333111"~
263                           "1111111111";
264                           break; }
265       case 7: { strTemp = "0000000000"~
266                           "0060000000"~
267                           "0000000000"~
268                           "0000000000"~
269                           "013wwww310"~
270                           "113wwww311"~
271                           "1113333111"~
272                           "1111111111";
273                           break; }
274       default: FatalError("003");
275     }
276   } else if (roomPath == LevelGen::RType.Shop4 && rx == 3/*496*/) {
277     // ankh shop
278     strTemp = "0000000011"~
279               ".....b0AlK"~
280               "......bbbb"~
281               ".........."~
282               "1111111111"~
283               "1111111111"~
284               "1111111111"~
285               "1111111111";
286     shopType = 'Ankh';
287     writeln("*** generated Ankh shop");
288   } else if (roomPath == LevelGen::RType.Shop4) {
289     // shop
290     strTemp = ".........."~
291               ".........."~
292               "....22...."~
293               "..2l00l2.."~
294               "0.000000.0"~
295               "0k000000k0"~
296               "000iiiiK00"~
297               "bbbbbbbbbb";
299     shopType = '';
301     int n = global.randRoom(1, 5);
302     int m = n;
304     while (!shopType) {
305            if (n == 1) { if (!global.genSupplyShop) { shopType = 'General'; global.genSupplyShop = true; } }
306       else if (n == 2) { if (!global.genBombShop) { shopType = 'Bomb'; global.genBombShop = true; } }
307       else if (n == 3) { if (!global.genWeaponShop) { shopType = 'Weapon'; global.genWeaponShop = true; } }
308       else if (n == 4) { if (!global.genRareShop) { shopType = 'Rare'; global.genRareShop = true; } }
309       else if (n == 5) { if (!global.genClothingShop) { shopType = 'Clothing'; global.genClothingShop = true; } }
310       ++n;
311       if (n > 5) n = 1;
312       if (n == m) {
313         shopType = 'General';
314         break;
315       }
316     }
317   } else if (roomPath == LevelGen::RType.Shop5) {
318     // craps
319     strTemp = "1111111111"~
320               "1111111111"~
321               "1111221111"~
322               "112000lK11"~
323               "01W0Q00b.."~
324               "0k00000+0."~
325               "00000zz+q."~
326               "bbbbbbbbbb";
327     shopType = 'Craps';
328   } else {
329     // drop
330     int n = (roomPathAbove != 2 ? global.randRoom(1, 6) : global.randRoom(1, 5));
331     switch (n) {
332       case 1: { strTemp = "00G0000000"~
333                           "00H1111000"~
334                           "00G2222000"~
335                           "00G0000000"~
336                           "00G0000000"~
337                           "00G0000022"~
338                           "0000000211"~
339                           "1111202111";
340                           break; }
341       case 2: { strTemp = "0000000G00"~
342                           "0001111H00"~
343                           "0002222G00"~
344                           "0000000G00"~
345                           "0000000G00"~
346                           "2200000G00"~
347                           "112T000000"~
348                           "1111202111";
349                           break; }
350       case 3: { strTemp = "00000000G0"~
351                           "60000011H0"~
352                           "00000000G0"~
353                           "00000000G0"~
354                           "G0000000G0"~
355                           "H1122000G0"~
356                           "G0000000G0"~
357                           "11100001H1";
358                           break; }
359       case 4: { strTemp = "0000000G00"~
360                           "0001111H00"~
361                           "0002222G00"~
362                           "0000000G00"~
363                           "0000000G00"~
364                           "0000000000"~
365                           "2000022222"~
366                           "1000111111";
367                           break; }
368       case 5: { strTemp = "00G0000000"~
369                           "00H1111000"~
370                           "00G2222000"~
371                           "00G0000000"~
372                           "00G0000000"~
373                           "0000000000"~
374                           "2222200002"~
375                           "1111110001";
376                           break; }
377       //
378       case 6: { strTemp = "1111111111"~
379                           "1111111111"~
380                           "1200000021"~
381                           "2000000002"~
382                           "0000000000"~
383                           "0220000220"~
384                           "2112002112"~
385                           "1111001111";
386                           break; }
387       default: FatalError("007");
388     }
389   }
391   if (strTemp.length != 80) FatalError("ooops");
393   // add obstacles
394   foreach (int i; 0..80) {
395     int j = i;
397     string strObs1 = "00000";
398     string strObs2 = "00000";
399     string strObs3 = "00000";
400     string strObs4 = "00000";
401     int tile = strTemp[i];
403     if (tile == "8") {
404       strObs1 = "00900";
405       strObs2 = "01110";
406       strObs3 = "11111";
407     } else if (tile == "5") {
408       // ground
409       int n = (global.randRoom(1, 8) == 1 ? global.randRoom(100, 102) : global.randRoom(1, 2));
410       switch (n) {
411         case 1: { strObs1 = "00000";
412                   strObs2 = "00000";
413                   strObs3 = "22222";
414                   break; }
415         case 2: { strObs1 = "00000";
416                   strObs2 = "22222";
417                   strObs3 = "11111";
418                   break; }
419         case 100: { strObs1 = "00000";
420                     strObs2 = "00000";
421                     strObs3 = "0T022";
422                     break; }
423         case 101: { strObs1 = "00000";
424                     strObs2 = "00000";
425                     strObs3 = "20T02";
426                     break; }
427         case 102: { strObs1 = "00000";
428                     strObs2 = "00000";
429                     strObs3 = "220T0";
430                     break; }
431         default: FatalError("009");
432       }
433     } else if (tile == "6") {
434       // air
435       switch (global.randRoom(1, 4)) {
436         case 1: { strObs1 = "11112";
437                   strObs2 = "22220";
438                   strObs3 = "00000";
439                   break; }
440         case 2: { strObs1 = "21111";
441                   strObs2 = "02222";
442                   strObs3 = "00000";
443                   break; }
444         case 3: { strObs1 = "22222";
445                   strObs2 = "00000";
446                   strObs3 = "00000";
447                   break; }
448         case 4: { strObs1 = "11111";
449                   strObs2 = "21112";
450                   strObs3 = "02120";
451                   break; }
452         default: FatalError("00a");
453       }
454     } else if (tile == "V") {
455       // vines
456       switch (global.randRoom(1, 3)) {
457         case 1: { strObs1 = "L0L0L";
458                   strObs2 = "L0L0L";
459                   strObs3 = "L000L";
460                   strObs4 = "L0000";
461                   break; }
462         case 2: { strObs1 = "L0L0L";
463                   strObs2 = "L0L0L";
464                   strObs3 = "L000L";
465                   strObs4 = "0000L";
466                   break; }
467         case 3: { strObs1 = "0L0L0";
468                   strObs2 = "0L0L0";
469                   strObs3 = "0L0L0";
470                   strObs4 = "000L0";
471                   break; }
472         default: FatalError("00a");
473       }
474     }
476     if (tile == "5" || tile == "6" || tile == "8" || tile == "V") {
477       //strTemp = string_delete(strTemp, j, 5);
478       //strTemp = string_insert(strObs1, strTemp, j);
479       strTemp[j..j+5] = strObs1;
480       j += 10;
481       //strTemp = string_delete(strTemp, j, 5);
482       //strTemp = string_insert(strObs2, strTemp, j);
483       strTemp[j..j+5] = strObs2;
484       j += 10;
485       //strTemp = string_delete(strTemp, j, 5);
486       //strTemp = string_insert(strObs3, strTemp, j);
487       strTemp[j..j+5] = strObs3;
488     }
489     if (tile == "V") {
490       j += 10;
491       //strTemp = string_delete(strTemp, j, 5);
492       //strTemp = string_insert(strObs4, strTemp, j);
493       strTemp[j..j+5] = strObs4;
494     }
495   }
499 override void generate (int rx, int ry) {
500   GameGlobal global = levgen.global;
502   if (global.blackMarket) {
503     generateBlackMarket(rx, ry);
504     return;
505   }
507   strTemp = "0000000000"~
508             "0000000000"~
509             "0000000000"~
510             "0000000000"~
511             "0000000000"~
512             "0000000000"~
513             "0000000000"~
514             "0000000000";
516   int roomPath = levgen.getRPath(rx, ry); //[scrGetRoomX(x), scrGetRoomY(y)];
517   int roomPathAbove = -1;
518   shopType = 'General';
519   if (ry != 0) roomPathAbove = levgen.getRPath(rx, ry-1); //scrGetRoomY(y-128)];
521   if (rx == levgen.startRoomX && ry == levgen.startRoomY) {
522     // starting room
523     int n = (roomPath == 2 ? global.randRoom(3, 4) : global.randRoom(1, 2));
524     switch (n) {
525       case 1: { strTemp = "6000060000"~
526                           "0000000000"~
527                           "0000000000"~
528                           "0000000000"~
529                           "0008000000"~
530                           "0000000000"~
531                           "0000000000"~
532                           "1111111111";
533                           break; }
534       case 2: { strTemp = "1111111111"~
535                           "2222222222"~
536                           "0000000000"~
537                           "0000000000"~
538                           "0008000000"~
539                           "0000000000"~
540                           "0000000000"~
541                           "1111111111";
542                           break; }
543       // hole
544       case 3: { strTemp = "6000060000"~
545                           "0000000000"~
546                           "0000000000"~
547                           "0000000000"~
548                           "0008000000"~
549                           "0000000000"~
550                           "0000000000"~
551                           "2021111120";
552                           break; }
553       case 4: { strTemp = "1111111111"~
554                           "2222222222"~
555                           "0000000000"~
556                           "0000000000"~
557                           "0008000000"~
558                           "0000000000"~
559                           "0000000000"~
560                           "2021111120";
561                           break; }
562       default: FatalError("000");
563     }
564   } else if (rx == levgen.endRoomX && ry == levgen.endRoomY) {
565     // exit room
566     int n = (global.lake ? 5 : roomPathAbove == 2 ? global.randRoom(1, 4) : global.randRoom(3, 4));
567     switch (n) {
568       case 1: { strTemp = "0000000000"~
569                           "0000000000"~
570                           "0000000000"~
571                           "0000000000"~
572                           "0008000000"~
573                           "0000000000"~
574                           "0000000000"~
575                           "1111111111";
576                           break; }
577       case 2: { strTemp = "0000000000"~
578                           "0011111100"~
579                           "0000000000"~
580                           "0000000000"~
581                           "0008000000"~
582                           "0000000000"~
583                           "0000000000"~
584                           "1111111111";
585                           break; }
586       case 3: { strTemp = "6000060000"~
587                           "0000000000"~
588                           "0000000000"~
589                           "0000000000"~
590                           "0008000000"~
591                           "0000000000"~
592                           "0000000000"~
593                           "1111111111";
594                           break; }
595       case 4: { strTemp = "1111111111"~
596                           "2222222222"~
597                           "0000000000"~
598                           "0000000000"~
599                           "0008000000"~
600                           "0000000000"~
601                           "0000000000"~
602                           "1111111111";
603                           break; }
604       case 5: { strTemp = "0000000000"~
605                           "0000090000"~
606                           "0221111220"~
607                           "wwvvvvvvww"~
608                           "wwwwwwwwww"~
609                           "wwwwwwwwww"~
610                           "wwwwwwwwww"~
611                           "wwwwwwwwww";
612                           break; }
613       default: FatalError("001");
614     }
615   } else if (roomPath == 0 && global.randRoom(1, 3) <= 2) {
616     // side room
617     int n;
618     if (!global.altar && global.randRoom(1, 12) == 1) {
619       n = 10;
620       global.altar = true;
621     } else if (global.idol) {
622       n = global.randRoom(1, 8);
623     } else {
624       n = global.randRoom(1, 9);
625       if (n == 9) global.idol = true;
626     }
628     switch (n) {
629       // upper plats
630       case 1: { strTemp = "0000000000"~
631                           "0010111100"~
632                           "0000000000"~
633                           "0001101000"~
634                           "0050000000"~
635                           "0000000000"~
636                           "0000000000"~
637                           "1111111111";
638                           break; }
639       case 2: { strTemp = "1111111111"~
640                           "11V0000211"~
641                           "1200000211"~
642                           "0000000211"~
643                           "0000000211"~
644                           "1120000211"~
645                           "1112002111"~
646                           "1111001111";
647                           break; }
648       case 3: { strTemp = "1111111111"~
649                           "112V000011"~
650                           "1120000021"~
651                           "1120000000"~
652                           "1120000000"~
653                           "1120000211"~
654                           "1112002111"~
655                           "1111001111";
656                           break; }
657       case 4: { strTemp = "1112002111"~
658                           "1100000222"~
659                           "1200000211"~
660                           "0000000222"~
661                           "0000000211"~
662                           "1120000222"~
663                           "11177T7111"~
664                           "1111111111";
665                           break; }
666       case 5: { strTemp = "1112002111"~
667                           "2220000011"~
668                           "1120000021"~
669                           "2220000000"~
670                           "1120000000"~
671                           "2220000211"~
672                           "1117T77111"~
673                           "1111111111";
674                           break; }
675       case 6: { strTemp = "1112002111"~
676                           "2220000011"~
677                           "1120000021"~
678                           "2220000000"~
679                           "1120000000"~
680                           "2220000211"~
681                           "1117T77111"~
682                           "1111111111";
683                           break; }
684       // water rooms
685       case 7: { strTemp = "0000000000"~
686                           "11wwwwww11"~
687                           "11wwwwww11"~
688                           "113wwww311"~
689                           "113wwww311"~
690                           "113wwww311"~
691                           "1113333111"~
692                           "1111111111";
693                           break; }
694       case 8: { strTemp = "0000000000"~
695                           "0000rr0000"~
696                           "000rttr000"~
697                           "00rrrrrr00"~
698                           "00V0000000"~
699                           "0000000000"~
700                           "0000000000"~
701                           "0000000000";
702                           break; }
703       // idols
704       case 9:
705       {
706           if (global.cemetary) strTemp = "tttttttttt"~
707                                          "tttttttttt"~
708                                          "ttp0C00ptt"~
709                                          "ttt0tt0ttt"~
710                                          "4000000004"~
711                                          "ttt0tt0ttt"~
712                                          "ttp0000ptt"~
713                                          "1111111111";
714           else strTemp = "0100000010"~
715                          "0000I00000"~
716                          "01BBBBBB10"~
717                          "1100000011"~
718                          "11wwwwww11"~
719                          "11wwwwww11"~
720                          "113wwww311"~
721                          "1111111111";
722           break;
723       }
724       // altars
725       case 10: { strTemp = "2200000022"~
726                            "0000000000"~
727                            "0000000000"~
728                            "0000000000"~
729                            "0000000000"~
730                            "0000x00000"~
731                            "0221111220"~
732                            "1111111111";
733                            break; }
734       default: FatalError("002");
735     }
736   } else if (roomPath == 0 || roomPath == 1) {
737     // main room
738     switch (global.randRoom(1, 10)) {
739       // basic rooms
740       case 1: { strTemp = "6000060000"~
741                           "0000000000"~
742                           "0000000000"~
743                           "0000000000"~
744                           "0050000000"~
745                           "0000000000"~
746                           "0000000000"~
747                           "1111111111";
748                           break; }
749       case 2: { strTemp = "6000060000"~
750                           "0000000000"~
751                           "0000000000"~
752                           "0000000000"~
753                           "5000050000"~
754                           "0000000000"~
755                           "0000000000"~
756                           "1111111111";
757                           break; }
758       case 3: { strTemp = "6000060000"~
759                           "0000000000"~
760                           "0000000000"~
761                           "5000050000"~
762                           "0000000000"~
763                           "0000000000"~
764                           "1111111111"~
765                           "1111111111";
766                           break; }
767       case 4: { strTemp = "6000060000"~
768                           "0000000000"~
769                           "0000000000"~
770                           "0000000000"~
771                           "0000000000"~
772                           "0001111100"~
773                           "0011111100"~
774                           "1111111111";
775                           break; }
776       case 5: { strTemp = "2222222222"~
777                           "0000000000"~
778                           "0000000000"~
779                           "0000tt0000"~
780                           "00r0220r00"~
781                           "00t0tt0t00"~
782                           "0rtrttrtr0"~
783                           "1111111111";
784                           break; }
785       case 6: {
786           if (global.randRoom(1,2) == 1) strTemp = "0L00000000"~
787                                                   "1L11111111"~
788                                                   "0L22222220"~
789                                                   "0L00000000"~
790                                                   "0002002000"~
791                                                   "0111221110"~
792                                                   "1120000211"~
793                                                   "1111111111";
794           else strTemp = "00000000L0"~
795                          "11111111L1"~
796                          "02222222L0"~
797                          "00000000L0"~
798                          "0002002000"~
799                          "0111221110"~
800                          "1120000211"~
801                          "1111111111";
802           break;
803       }
804       // spikes
805       case 7: { strTemp = "1111111111"~
806                           "V0000V0000"~
807                           "0000000000"~
808                           "0000000000"~
809                           "0000000000"~
810                           "1000000001"~
811                           "1ssssssss1"~
812                           "1111111111";
813                           break; }
814       // upper plats
815       case 8: { strTemp = "0000000000"~
816                           "0000000000"~
817                           "0000000000"~
818                           "0000000000"~
819                           "5000050000"~
820                           "0000000000"~
821                           "0000000000"~
822                           "1111111111";
823                           break; }
824       // water
825       case 9: { strTemp = "0000000000"~
826                           "0000000000"~
827                           "0000000000"~
828                           "013wwww310"~
829                           "013wwww310"~
830                           "113wwww311"~
831                           "1113333111"~
832                           "1111111111";
833                           break; }
834       case 10: { strTemp = "0060000000"~
835                            "0000000000"~
836                            "0000000000"~
837                            "0000000000"~
838                            "013wwww310"~
839                            "113wwww311"~
840                            "1113333111"~
841                            "1111111111";
842                            break; }
843       default: FatalError("003");
844     }
845   } else if (roomPath == 3) {
846     // main room
847     switch (global.randRoom(1, 7)) {
848       // basic rooms
849       case 1: { strTemp = "0000000000"~
850                           "0000000000"~
851                           "0000000000"~
852                           "0000000000"~
853                           "0050000000"~
854                           "0000000000"~
855                           "0000000000"~
856                           "1111111111";
857                           break; }
858       case 2: { strTemp = "0000000000"~
859                           "0000000000"~
860                           "0000000000"~
861                           "0000000000"~
862                           "5000050000"~
863                           "0000000000"~
864                           "0000000000"~
865                           "1111111111";
866                           break; }
867       case 3: { strTemp = "0000000000"~
868                           "0000000000"~
869                           "0000000000"~
870                           "5000050000"~
871                           "0000000000"~
872                           "0000000000"~
873                           "1111111111"~
874                           "1111111111";
875                           break; }
877       // upper plats
878       case 4: { strTemp = "0000000000"~
879                           "0000000000"~
880                           "0000000000"~
881                           "0000000000"~
882                           "0002222220"~
883                           "0011111110"~
884                           "1111111111"~
885                           "1111111111";
886                           break; }
887       case 5: { strTemp = "0000000000"~
888                           "0000000000"~
889                           "0000000000"~
890                           "0000000000"~
891                           "0000000221"~
892                           "0000022111"~
893                           "0000221111"~
894                           "1111111111";
895                           break; }
896       // water
897       case 6: { strTemp = "0000000000"~
898                           "0000000000"~
899                           "0000000000"~
900                           "013wwww310"~
901                           "013wwww310"~
902                           "113wwww311"~
903                           "1113333111"~
904                           "1111111111";
905                           break; }
906       case 7: { strTemp = "0000000000"~
907                           "0060000000"~
908                           "0000000000"~
909                           "0000000000"~
910                           "013wwww310"~
911                           "113wwww311"~
912                           "1113333111"~
913                           "1111111111";
914                           break; }
915       default: FatalError("004");
916     }
917   } else if (roomPath == LevelGen::RType.Shop4) {
918     // shop
919     strTemp = "1111111111"~
920               "1111111111"~
921               "1111221111"~
922               "111l000211"~
923               "...000W010"~
924               "...00000k0"~
925               "..Kiiii000"~
926               "bbbbbbbbbb";
927     int n = global.randRoom(1, 7);
928     if (global.scumGenShopType > 0) n = global.scumGenShopType;
929     switch (n) {
930       case 1: shopType = 'General'; break;
931       case 2: shopType = 'Bomb'; break;
932       case 3: shopType = 'Weapon'; break;
933       case 4: shopType = 'Rare'; break;
934       case 5: shopType = 'Clothing'; break;
935       case 6: shopType = 'Craps';
936         strTemp = "1111111111"~
937                   "1111111111"~
938                   "1111221111"~
939                   "11Kl000211"~
940                   "..bQ00W010"~
941                   ".0+00000k0"~
942                   ".q+uu00000"~
943                   "bbbbbbbbbb";
944         break;
945       case 7: shopType = 'Kissing';
946         strTemp = "1111111111"~
947                   "1111111111"~
948                   "1111221111"~
949                   "111l000211"~
950                   "...000W010"~
951                   "...00000k0"~
952                   "..K00D0000"~
953                   "bbbbbbbbbb";
954         /*oGame*/global.damsel = true;
955         break;
956       default: FatalError("005");
957     }
958   } else if (roomPath == LevelGen::RType.Shop5) {
959     // shop
960     strTemp = "1111111111"~
961               "1111111111"~
962               "1111221111"~
963               "112000l111"~
964               "01W0000..."~
965               "0k00000..."~
966               "000iiiiK.."~
967               "bbbbbbbbbb";
968     int n = global.randRoom(1, 7);
969     if (global.scumGenShopType > 0) n = global.scumGenShopType;
970     switch (n) {
971       case 1: shopType = 'General'; break;
972       case 2: shopType = 'Bomb'; break;
973       case 3: shopType = 'Weapon'; break;
974       case 4: shopType = 'Rare'; break;
975       case 5: shopType = 'Clothing'; break;
976       case 6: shopType = 'Craps';
977         strTemp = "1111111111"~
978                   "1111111111"~
979                   "1111221111"~
980                   "112000lK11"~
981                   "01W0Q00b.."~
982                   "0k00000+0."~
983                   "00000uu+q."~
984                   "bbbbbbbbbb";
985         break;
986       case 7: shopType = 'Kissing';
987         strTemp = "1111111111"~
988                   "1111111111"~
989                   "1111221111"~
990                   "112000l111"~
991                   "01W0000..."~
992                   "0k00000..."~
993                   "0000D00K.."~
994                   "bbbbbbbbbb";
995         /*oGame*/global.damsel = true;
996         break;
997       default: FatalError("006");
998     }
999   } else if (roomPath == 7) {
1000     // Lake Bottom
1001     switch (global.randRoom(1, 8)) {
1002       case 1: { strTemp = "wwwwwwwwww"~
1003                           "wwwwwwwwww"~
1004                           "wwwwwwwwww"~
1005                           "wwwwwwwwww"~
1006                           "wwwwwwwwww"~
1007                           "wwwwwwwwww"~
1008                           "wwwwwwwwww"~
1009                           "wwwwwwwwww";
1010                           break; }
1011       case 2: { strTemp = "wwwwwwwwww"~
1012                           "wwwwwwwwww"~
1013                           "wwwwwwwwww"~
1014                           "wwwwwwwwww"~
1015                           "wwwwwwwwww"~
1016                           "wwwwwwwwww"~
1017                           "wwwwwwwwww"~
1018                           ",,,,,,,,,,";
1019                           break; }
1020       case 3: { strTemp = "wwwwwwwwww"~
1021                           "wwwwwwwwww"~
1022                           "wwwwwwwwww"~
1023                           "wwwwwwwwww"~
1024                           ",,wwwwww,,"~
1025                           "wwwwwwwwww"~
1026                           "wwwwwwwwww"~
1027                           ",,,,,,,,,,";
1028                           break; }
1029       case 4: { strTemp = "wwwwwwwwww"~
1030                           "wwwwwwwwww"~
1031                           "wwwwwwwwww"~
1032                           "wwwwwwwwww"~
1033                           ",v,wwwwwww"~
1034                           "wwv,wwwwww"~
1035                           "w,v,wwwwww"~
1036                           ",,v,,,,,ww";
1037                           break; }
1038       case 5: { strTemp = "wwwwwwwwww"~
1039                           "wwwwwwwwww"~
1040                           "wwwwwwwwww"~
1041                           "wwwwwwwwww"~
1042                           "wwwwwww,v,"~
1043                           "wwwwww,vww"~
1044                           "wwwwww,v,w"~
1045                           "w,,,,,,v,,";
1046                           break; }
1047       case 6: { strTemp = "wwwwwwwwww"~
1048                           "wwwwwwwwww"~
1049                           "wwwwwwwwww"~
1050                           "wwww,,wwww"~
1051                           "www,vv,www"~
1052                           "www,vv,www"~
1053                           "ww,,vv,,ww"~
1054                           ",,,vvvv,,,";
1055                           break; }
1056       case 7: { strTemp = "wwwwwwwwww"~
1057                           "wwwwwwwwww"~
1058                           "wwwwwwwwww"~
1059                           "www,,,,www"~
1060                           "ww,vvvv,ww"~
1061                           "w,v,w,vv,w"~
1062                           "w,wwww,vv,"~
1063                           ",,,,,,,,,,";
1064                           break; }
1065       case 8: { strTemp = "wwwwwwwwww"~
1066                           "wwwwwwwwww"~
1067                           "wwwwwwwwww"~
1068                           "www,,,,www"~
1069                           "ww,vvvv,ww"~
1070                           "w,vv,w,v,w"~
1071                           ",vv,wwww,w"~
1072                           ",,,,,,,,,,";
1073                           break; }
1074     }
1075   } else if (roomPath == 8) {
1076     // Lake Top
1077     int n = (roomPathAbove == 2 ? global.randRoom(1, 5) : global.randRoom(1, 8));
1078     switch (n) {
1079       case 1: { strTemp = "0000000000"~
1080                           "0000000000"~
1081                           "0001111000"~
1082                           "w,,vvvv,,w"~
1083                           "wwww,,wwww"~
1084                           "wwwwwwwwww"~
1085                           "wwwwwwwwww"~
1086                           "wwwwwwwwww";
1087                           break; }
1088       case 2: { strTemp = "0000000000"~
1089                           "0000000000"~
1090                           "1200000000"~
1091                           "vvwwwwwwww"~
1092                           ",wwwwwwwww"~
1093                           "wwwwwwwwww"~
1094                           "wwwwwwwwww"~
1095                           "wwwwwwwwww";
1096                           break; }
1097       case 3: { strTemp = "0000000000"~
1098                           "0000000000"~
1099                           "0000000021"~
1100                           "wwwwwwwwvv"~
1101                           "wwwwwwwww,"~
1102                           "wwwwwwwwww"~
1103                           "wwwwwwwwww"~
1104                           "wwwwwwwwww";
1105                           break; }
1106       case 4: { strTemp = "0000000000"~
1107                           "0000000000"~
1108                           "0000000000"~
1109                           "wwwwwwwwww"~
1110                           "wwwwwwwwww"~
1111                           "wwwwwwwwww"~
1112                           "wwwwwwwwww"~
1113                           "wwwwwwwwww";
1114                           break; }
1115       case 5: { strTemp = "0000000000"~
1116                           "0000000000"~
1117                           "0001111000"~
1118                           "w,,vvvv,,w"~
1119                           "www,vv,www"~
1120                           "wwwwvvwwww"~
1121                           "wwww,,wwww"~
1122                           "wwwwwwwwww";
1123                           break; }
1124       case 6: { strTemp = "0000220000"~
1125                           "0002112000"~
1126                           "0001111000"~
1127                           "w,,vvvv,,w"~
1128                           "www,vv,www"~
1129                           "wwwwvvwwww"~
1130                           "wwww,,wwww"~
1131                           "wwwwwwwwww";
1132                           break; }
1133       case 7: { strTemp = "6000060000"~
1134                           "0000000000"~
1135                           "0000000000"~
1136                           "wwwvvvvwww"~
1137                           "wwww,,wwww"~
1138                           "wwwwwwwwww"~
1139                           "wwwwwwwwww"~
1140                           "wwwwwwwwww";
1141                           break; }
1142       case 8: { strTemp = "0000220000"~
1143                           "0002112000"~
1144                           "0221111220"~
1145                           "www,,,,www"~
1146                           "wwwwwwwwww"~
1147                           "wwwwwwwwww"~
1148                           "wwwwwwwwww"~
1149                           "wwwwwwwwww";
1150                           break; }
1151     }
1152   } else if (roomPath == 9) {
1153     // Mega Mouth
1154     strTemp = "wwwwwwwwww"~
1155               "wwwwwwwwww"~
1156               "wwwwwwwwww"~
1157               "wwwwwwwwww"~
1158               "wwwJwwwwww"~
1159               "wwwwwwwwww"~
1160               "wwwwwwwwww"~
1161               ",,,,,,,,,,";
1162   } else {
1163     // drop
1164     int n = (roomPathAbove != 2 ? global.randRoom(1, 6) : global.randRoom(1, 5));
1165     switch (n) {
1166       case 1: { strTemp = "0000000000"~
1167                           "0000000000"~
1168                           "0000000000"~
1169                           "0000000000"~
1170                           "0000000000"~
1171                           "0000000022"~
1172                           "0000000211"~
1173                           "1111202111";
1174                           break; }
1175       case 2: { strTemp = "0000000000"~
1176                           "0000000000"~
1177                           "0000000000"~
1178                           "0000000000"~
1179                           "0000000000"~
1180                           "2200000000"~
1181                           "112T000000"~
1182                           "1111202111";
1183                           break; }
1184       case 3: { strTemp = "0000000000"~
1185                           "6000000000"~
1186                           "0000000000"~
1187                           "0000000000"~
1188                           "0000000000"~
1189                           "0000000000"~
1190                           "0000000000"~
1191                           "1000000001";
1192                           break; }
1193       case 4: { strTemp = "0000000000"~
1194                           "0000000000"~
1195                           "0000000000"~
1196                           "0000000000"~
1197                           "0000000000"~
1198                           "0000000000"~
1199                           "2000022222"~
1200                           "1000111111";
1201                           break; }
1202       case 5: { strTemp = "0000000000"~
1203                           "0000000000"~
1204                           "0000000000"~
1205                           "0000000000"~
1206                           "0000000000"~
1207                           "0000000000"~
1208                           "2222200002"~
1209                           "1111110001";
1210                           break; }
1211       //
1212       case 6: { strTemp = "1111111111"~
1213                           "1111111111"~
1214                           "1200000021"~
1215                           "0000000000"~
1216                           "0000000000"~
1217                           "0220000220"~
1218                           "2112002112"~
1219                           "1111001111";
1220                           break; }
1221       default: FatalError("007");
1222     }
1223   }
1225   if (strTemp.length != 80) FatalError("ooops");
1227   // add obstacles
1228   foreach (int i; 0..80) {
1229     int j = i;
1231     string strObs1 = "00000";
1232     string strObs2 = "00000";
1233     string strObs3 = "00000";
1234     string strObs4 = "00000";
1235     int tile = strTemp[i];
1237     if (tile == "8") {
1238       strObs1 = "00900";
1239       strObs2 = "01110";
1240       strObs3 = "11111";
1241     } else if (tile == "5") {
1242       // ground
1243       int n = (global.randRoom(1, 8) == 1 ? global.randRoom(100, 102) : global.randRoom(1, 2));
1244       switch (n) {
1245         case 1: { strObs1 = "00000";
1246                   strObs2 = "00000";
1247                   strObs3 = "22222";
1248                   break; }
1249         case 2: { strObs1 = "00000";
1250                   strObs2 = "22222";
1251                   strObs3 = "11111";
1252                   break; }
1253         case 100: { strObs1 = "00000";
1254                     strObs2 = "00000";
1255                     strObs3 = "0T022";
1256                     break; }
1257         case 101: { strObs1 = "00000";
1258                     strObs2 = "00000";
1259                     strObs3 = "20T02";
1260                     break; }
1261         case 102: { strObs1 = "00000";
1262                     strObs2 = "00000";
1263                     strObs3 = "220T0";
1264                     break; }
1265         default: FatalError("009");
1266       }
1267     } else if (tile == "6") {
1268       // air
1269       switch (global.randRoom(1, 4)) {
1270         case 1: { strObs1 = "11112";
1271                   strObs2 = "22220";
1272                   strObs3 = "00000";
1273                   break; }
1274         case 2: { strObs1 = "21111";
1275                   strObs2 = "02222";
1276                   strObs3 = "00000";
1277                   break; }
1278         case 3: { strObs1 = "22222";
1279                   strObs2 = "00000";
1280                   strObs3 = "00000";
1281                   break; }
1282         case 4: { strObs1 = "11111";
1283                   strObs2 = "21112";
1284                   strObs3 = "00000";
1285                   break; }
1286         default: FatalError("00a");
1287       }
1288     } else if (tile == "V") {
1289       // vines
1290       switch (global.randRoom(1, 3)) {
1291         case 1: { strObs1 = "L0L0L";
1292                   strObs2 = "L0L0L";
1293                   strObs3 = "L000L";
1294                   strObs4 = "L0000";
1295                   break; }
1296         case 2: { strObs1 = "L0L0L";
1297                   strObs2 = "L0L0L";
1298                   strObs3 = "L000L";
1299                   strObs4 = "0000L";
1300                   break; }
1301         case 3: { strObs1 = "0L0L0";
1302                   strObs2 = "0L0L0";
1303                   strObs3 = "0L0L0";
1304                   strObs4 = "000L0";
1305                   break; }
1306         default: FatalError("00a");
1307       }
1308     }
1310     if (tile == "5" || tile == "6" || tile == "8" || tile == "V") {
1311       //strTemp = string_delete(strTemp, j, 5);
1312       //strTemp = string_insert(strObs1, strTemp, j);
1313       strTemp[j..j+5] = strObs1;
1314       j += 10;
1315       //strTemp = string_delete(strTemp, j, 5);
1316       //strTemp = string_insert(strObs2, strTemp, j);
1317       strTemp[j..j+5] = strObs2;
1318       j += 10;
1319       //strTemp = string_delete(strTemp, j, 5);
1320       //strTemp = string_insert(strObs3, strTemp, j);
1321       strTemp[j..j+5] = strObs3;
1322     }
1323     if (tile == "V") {
1324       j += 10;
1325       //strTemp = string_delete(strTemp, j, 5);
1326       //strTemp = string_insert(strObs4, strTemp, j);
1327       strTemp[j..j+5] = strObs4;
1328     }
1329   }
1333 override void genTileAt (int tileX, int tileY) {
1334   name shopType = levgen.roomShopType(tileX, tileY);
1335   //if (shopType && shopType != 'General') writeln("::: ", shopType, " :::");
1337   auto global = levgen.global;
1338   auto level = levgen.level;
1340   // border tiles (moved to LevelGen)
1341   if (tileX == 0 || tileY == 0 || tileX == level.tilesWidth-1 || tileY == level.tilesHeight-1) {
1342     /+
1343     MapTile tile;
1344     // Great Lake is bottomless (nope)
1345     if (false /*global.lake && tileY == level.tilesHeight-1*/) {
1346       tile = level.MakeMapTile(tileX, tileY, 'oWaterSwim');
1347     } else {
1348       tile = level.MakeMapTile(tileX, tileY, 'oEdgeBrick');
1349       tile.setSprite('sLush');
1350       tile.invincible = true;
1351       tile.border = true;
1352     }
1353     tile.ore = 0;
1354     //tile.treasure = '';
1355     +/
1356     level.MakeMapTile(tileX, tileY, 'oLush');
1357     return;
1358   }
1360   int roomX, roomY;
1361   level.tileXY2roomXY(tileX, tileY, roomX, roomY);
1362   level.setTileTypeAt(tileX, tileY, levgen.getRPath(roomX, roomY));
1364   auto tile = levgen.roomGetXYTileType(tileX, tileY);
1366   if (tile == "0") return;
1368   if (tile == "1") {
1369     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
1370     level.MakeMapTile(tileX, tileY, 'oLush');
1371     return;
1372   }
1374   if (tile == "2") {
1375     if (global.randRoom(1, 2) != 1) return;
1376     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
1377     level.MakeMapTile(tileX, tileY, 'oLush');
1378     return;
1379   }
1381   if (tile == "t") {
1382     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
1383     level.MakeMapTile(tileX, tileY, 'oTemple');
1384     return;
1385   }
1387   if (tile == "r") {
1388     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
1389     level.MakeMapTile(tileX, tileY, (global.randRoom(1, 2) == 1 ? 'oTemple' : 'oLush'));
1390     return;
1391   }
1393   if (tile == "3") {
1394     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
1395     level.MakeMapTile(tileX, tileY, (global.randRoom(1, 2) == 1 ? 'oWaterSwim' : 'oLush'));
1396     return;
1397   }
1399   if (tile == "L") {
1400     level.MakeMapTile(tileX, tileY, 'oVine');
1401     return;
1402   }
1404   if (tile == "P") {
1405     level.MakeMapTile(tileX, tileY, 'oVineTop');
1406     return;
1407   }
1409   if (tile == "G") {
1410     level.MakeMapTile(tileX, tileY, 'oLadderOrange');
1411     return;
1412   }
1414   if (tile == "H") {
1415     level.MakeMapTile(tileX, tileY, 'oLadderTop');
1416     return;
1417   }
1419   if (tile == "7") {
1420     if (global.randRoom(1, trunc(ceil(3.0/global.config.trapMult))) == 1) {
1421       level.MakeMapTile(tileX, tileY, level.scrGenSpikeType());
1422     }
1423     return;
1424   }
1426   if (tile == "s") {
1427     level.MakeMapTile(tileX, tileY, level.scrGenSpikeType());
1428     return;
1429   }
1431   if (tile == "4") {
1432     level.MakeMapTile(tileX, tileY, 'oPushBlock');
1433     return;
1434   }
1436   if (tile == "9") {
1437     auto block = level.MakeMapTile(tileX, tileY+1, 'oLush');
1438     if (roomX == levgen.startRoomX && roomY == levgen.startRoomY) {
1439       level.MakeMapTile(tileX, tileY, 'oEntrance');
1440       level.spawnPlayerAt(tileX*16+8, tileY*16+8);
1441     } else {
1442       level.MakeMapTile(tileX, tileY, 'oExit');
1443       block.invincible = true;
1444       block.ore = 0;
1445     }
1446     return;
1447   }
1449   if (tile == "c") {
1450     level.scrLevGenCreateChest(tileX*16+8, tileY*16+8);
1451     return;
1452   }
1454   if (tile == "d") {
1455     level.MakeMapTile(tileX, tileY, 'oWaterSwim');
1456     level.scrLevGenCreateChest(tileX*16+8, tileY*16+8);
1457     return;
1458   }
1460   if (tile == "w") {
1461     level.MakeMapTile(tileX, tileY, 'oWaterSwim');
1462     return;
1463   }
1465   if (tile == "A") {
1466     auto obj = level.MakeMapObject(tileX*16+7, tileY*16+8, 'oAnkh');
1467     if (obj) obj.forSale = true;
1468     return;
1469   }
1471   if (tile == "z") {
1472     auto die = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDice');
1473     if (die) die.forSale = true;
1474     return;
1475   }
1477   if (tile == "v") {
1478     // k8: it looks like a brick in the water; dunno why it is done this way
1479     //     it seems that water brick is created to mark it as "water"
1480     //k8:???level.MakeMapTile(tileX, tileY, 'oWaterSwim');
1481     level.MakeMapTile(tileX, tileY, 'oLush');
1482     level.MarkTileAsWet(tileX, tileY);
1483     return;
1484   }
1486   if (tile == ",") {
1487     // k8: it looks like a brick in the water; dunno why it is done this way
1488     //     it seems that water brick is created to mark it as "water"
1489     //k8:???level.MakeMapTile(tileX, tileY, 'oWaterSwim');
1490     if (global.randRoom(1, 2) == 1) {
1491       level.MakeMapTile(tileX, tileY, 'oLush');
1492       level.MarkTileAsWet(tileX, tileY);
1493     }
1494     return;
1495   }
1497   if (tile == "J") {
1498     // k8: it looks like a brick in the water; dunno why it is done this way
1499     //     it seems that water brick is created to mark it as "water"
1500     level.MakeMapTile(tileX, tileY, 'oWaterSwim');
1501     level.MakeMapObject(tileX*16, tileY*16, 'oJaws'); // jaws crates are done in jaws object
1502     return;
1503   }
1505   if (tile == "I") {
1506     level.MakeMapObject(tileX*16+16, tileY*16+12, 'oGoldIdol');
1507     // create trap activator
1508     auto obj = level.MakeMapObject(tileX+1, tileY+1, 'oTikiCurseRemoveBricks');
1509     obj.active = false; // force it here
1510     return;
1511   }
1513   if (tile == "C") {
1514     level.MakeMapObject(tileX*16+16, tileY*16+12, 'oCrystalSkull');
1515     // create trap activator
1516     auto obj = level.MakeMapObject(tileX+1, tileY+1, 'oTikiCurseRemoveBricks');
1517     obj.active = false; // force it here
1518     return;
1519   }
1521   if (tile == ".") {
1522     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
1523     auto obj = level.MakeMapTile(tileX, tileY, 'oLush');
1524     obj.shopWall = true;
1525     return;
1526   }
1528   if (tile == "Q") {
1529     if (shopType == 'Craps') level.MakeMapBackTile('bgDiceSign', 0, 0, 48, 32, tileX*16, tileY*16, 9004);
1530     return;
1531   }
1533   if (tile == "q") {
1534     //???: n = rand(1,6);
1535     auto obj = level.scrGenerateItem(tileX*16+8, tileY*16+8, GameLevel::GenItemSet.Craps);
1536     if (obj) obj.inDiceHouse = true;
1537     return;
1538   }
1540   if (tile == "+") {
1541     auto obj = level.MakeMapTile(tileX, tileY, /*'oSolid'*/'oSolidIceBlock');
1542     //obj.sprite_index = sIceBlock;
1543     obj.shopWall = true;
1544     return;
1545   }
1547   if (tile == "W") {
1548     if (global.murderer || global.thiefLevel > 0) {
1549            if (global.isDamsel) level.MakeMapBackTile('bgWanted', 32, 0, 32, 32, tileX*16, tileY*16, 9004);
1550       else if (global.isTunnelMan) level.MakeMapBackTile('bgWanted', 64, 0, 32, 32, tileX*16, tileY*16, 9004);
1551       else level.MakeMapBackTile('bgWanted', 0, 0, 32, 32, tileX*16, tileY*16, 9004);
1552     }
1553     return;
1554   }
1556   if (tile == "b") {
1557     auto obj = level.MakeMapTile(tileX, tileY, 'oBrickSmooth');
1558     obj.setSprite('sLushSmooth');
1559     obj.shopWall = true;
1560     return;
1561   }
1563   if (tile == "l") {
1564     level.MakeMapTile(tileX, tileY, (shopType == 'Kissing' ? 'oLampRed' : 'oLamp'));
1565     return;
1566   }
1568   if (tile == "K") {
1569     //auto obj = MonsterShopkeeper(level.MakeMapObject(tileX*16, tileY*16, 'oShopkeeper'));
1570     //if (obj) obj.style = shopType;
1571     level.scrLevGenShopkeeper(tileX*16, tileY*16, shopType);
1572     return;
1573   }
1575   if (tile == "k") {
1576          if (shopType == 'General') level.MakeMapTile(tileX, tileY, 'oSignGeneral');
1577     else if (shopType == 'Bomb') level.MakeMapTile(tileX, tileY, 'oSignBomb');
1578     else if (shopType == 'Weapon') level.MakeMapTile(tileX, tileY, 'oSignWeapon');
1579     else if (shopType == 'Clothing') level.MakeMapTile(tileX, tileY, 'oSignClothing');
1580     else if (shopType == 'Rare') level.MakeMapTile(tileX, tileY, 'oSignRare');
1581     else if (shopType == 'Craps') level.MakeMapTile(tileX, tileY, 'oSignCraps');
1582     else if (shopType == 'Kissing') level.MakeMapTile(tileX, tileY, 'oSignKissing');
1583     else level.MakeMapTile(tileX, tileY, 'oSign');
1584     return;
1585   }
1587   if (tile == "i") {
1588     level.scrShopItemsGen(tileX*16, tileY*16, shopType);
1589     return;
1590   }
1592   if (tile == "u") {
1593     auto die = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDice');
1594     if (die) die.forSale = true;
1595     return;
1596   }
1598   if (tile == "D") {
1599     auto obj = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDamsel');
1600     if (obj) {
1601       obj.forSale = true;
1602       obj.status = MonsterDamsel::SLAVE;
1603     }
1604     return;
1605   }
1607   if (tile == "B") {
1608     auto obj = MapTileLavaLushTrapBlock(level.MakeMapTile(tileX, tileY, 'oTrapBlock'));
1609     if (obj) {
1610       auto idol = level.findNearestObject(tileX*16, tileY*16, delegate bool (MapObject o) {
1611         return (o isa ItemGoldIdol);
1612       });
1613       obj.deathTimer = 40-abs(obj.ix-(idol ? idol.ix-8 : 0));
1614       //writeln("DEATH TIMER: ", obj.deathTimer);
1615       if (obj.deathTimer < 0) obj.deathTimer = 0;
1616     }
1617     return;
1618   }
1620   if (tile == "x") {
1621     level.MakeMapTile(tileX+0, tileY, 'oSacAltarLeft');
1622     level.MakeMapTile(tileX+1, tileY, 'oSacAltarRight');
1623     level.MakeMapBackTile('bgKaliBody', 0, 0, 64, 64, tileX*16-16, tileY*16-48, 10001);
1624     level.MakeMapTile(tileX+1, tileY-4, 'oKaliHead');
1625     return;
1626   }
1628   if (tile == "p") {
1629     int xpos = tileX*16, ypos = tileY*16;
1630     if (global.randRoom(1, 2) == 1) level.MakeMapObject(xpos, ypos, 'oFakeBones'); //k8: was without `==`
1631     else level.scrLevGenCreateJar(xpos+8, ypos+10);
1632     return;
1633   }
1635   if (tile == "T") {
1636     // tree
1637     int xpos = tileX*16, ypos = tileY*16;
1638     level.MakeMapTileAtPix(xpos, ypos, 'oTree');
1639     int n = 0;
1640     int tx = xpos;
1641     int ty = ypos-16;
1642     bool b1 = false;
1643     bool b2 = false;
1644     foreach (int m; 0..5) {
1645       if (global.randRoom(0, m) > 2) break;
1646       if (!level.isSolidAtPoint(tx, ty-16) &&
1647           !level.isSolidAtPoint(tx-16, ty-16) &&
1648           !level.isSolidAtPoint(tx+16, ty-16))
1649       {
1650         level.MakeMapTileAtPix(tx, ty, 'oTree');
1651         if (m < 4) {
1652           if (!b1 && global.randRoom(1, 5) < 4) {
1653             level.MakeMapTileAtPix(tx+16, ty, 'oTreeBranch');
1654             b1 = true;
1655           } else if (b1) {
1656             b1 = false;
1657           }
1658           if (!b2 && global.randRoom(1, 5) < 4) {
1659             level.MakeMapTileAtPix(tx-16, ty, 'oTreeBranch');
1660             b2 = true;
1661           } else if (b2) {
1662             b2 = false;
1663           }
1664         }
1665       } else {
1666         break;
1667       }
1668       ty -= 16;
1669     }
1670     level.MakeMapTileAtPix(tx-16, ty+16, 'oLeaves');
1671     level.MakeMapTileAtPix(tx+16, ty+16, 'oLeaves');
1672     return;
1673   }
1675   FatalError("INVALID JUNGLE BLOCK: '%s'", string.fromChar(tile));
1679 // ////////////////////////////////////////////////////////////////////////// //
1680 final bool cbIsObjectXMarket (MapObject o) { return false/*!(o isa ObjXMarketEntrance)*/; }
1681 final bool cbIsSolidOrWater (MapTile t) { return (t.solid || t.water || t.lava); }
1682 final bool cbIsWater (MapTile t) { return (t.water || t.lava); }
1683 final bool cbIsSolidOrSpikes (MapTile t) { return (t.solid || t.spikes); }
1684 final bool cbIsSpikes (MapTile t) { return (t.spikes); }
1687 override void genEntityAt (int tileX, int tileY) {
1688   auto global = levgen.global;
1689   auto level = levgen.level;
1691   int x = tileX*16, y = tileY*16;
1693   if (global.randRoom(1, 100) == 1 && !level.isSolidAtPoint(x, y-16)) {
1694     level.MakeMapBackTile('bgTrees', 0, 0, 16, 48, x, y-32, 9998);
1695   }
1697   if (level.isInShop(tileX, tileY)) return;
1699   MapTile t = level.getTileAt(tileX, tileY);
1701   if (y > 32 && level.isSolidAtPoint(x, y-16) && global.genMarketEntrance && !global.madeMarketEntrance) {
1702     auto obj = level.isSolidAtPoint(x, y-16);
1703     if (!obj.altar && !obj.tree && !obj.invincible && global.randRoom(1, global.marketChance) <= 1) {
1704       level.MakeMapTile(tileX, tileY-1, 'oXMarket');
1705       t.invincible = true;
1706       global.madeMarketEntrance = true;
1707     } else {
1708       global.marketChance -= 1;
1709     }
1710   } else if ((!t || !t.altar && !t.tree) && y != 0 &&
1711              !level.checkTilesInRect(x, y-32, 16, 32) &&
1712              !level.isObjectInRect(x, y-16, 16, 16, &level.cbIsObjectEnemy) &&
1713              (!level.isSolidAtPoint(x-16, y) || !level.isSolidAtPoint(x+16, y)) &&
1714              level.isSolidAtPoint(x, y+16) &&
1715              !level.isObjectAtPoint(x, y, &cbIsObjectXMarket) &&
1716              //!isInShop(x, y) && // in the original
1717              level.calcNearestEnterDist(x, y) > 64)
1718   {
1719     if (global.darkLevel && !level.checkTileAtPoint(x, y-32, &level.cbCollisionWater) && global.randRoom(1, 20) == 1) {
1720       //level.MakeMapObject(x, y-32, 'oTikiTorch');
1721       level.MakeMapTile(tileX, tileY-2, 'oTikiTorch');
1722     } else if (global.randRoom(1, trunc(ceil(12.0/global.config.trapMult))) == 1 && x != 160 && x != 176 && x != 320 && x != 336 && x != 480 && x != 496) {
1723       // don't create tiki traps near the entrance
1724       //writeln("===================");
1725       //!dbg:if (level.calcNearestEnterDist(x, y) < 64) writeln("************** edist: ", level.calcNearestEnterDist(x, y));
1726       /*
1727       writeln("trap at: (", x, ",", y, ")");
1728       foreach (MapTile ttt; level.allEnters) {
1729         int xc = x-ttt.xCenter, c = py-ttt.yCenter;
1730         int distsq = xc*xc+yc*yc;
1731         writeln("  exit at: (", ttt.ix, ",", ttt.iy, "); center at: (", ttt.xCenter, ",", ttt.yCenter, "); dist=", round(sqrt(distsq)));
1732       }
1733       */
1734       if (level.calcNearestEnterDist(x, y) >= 32) {
1735         bool wet = false;
1736         if (level.isSolidAtPoint(x, y-16)) {
1737           auto sol = level.isSolidAtPoint(x, y-16);
1738           //delete sol;
1739           wet = sol.water || sol.wet;
1740           sol.cleanDeath = true;
1741           sol.instanceRemove();
1742           //with (sol) { cleanDeath = true; instance_destroy(); }
1743         }
1744         if (!wet &&
1745             (level.isLiquidAtPoint(x-2, y) || level.isLiquidAtPoint(x+18, y) ||
1746              level.isLiquidAtPoint(x-2, y-16) || level.isLiquidAtPoint(x+18, y-16)))
1747         {
1748           wet = true;
1749         }
1750         auto trap = level.MakeMapTile(tileX, tileY, 'oSpearTrapBottom');
1751         trap.wet = wet;
1752         trap = level.MakeMapTile(tileX, tileY-1, (global.darkLevel ? 'oSpearTrapLit' : 'oSpearTrapTop'));
1753         trap.wet = wet;
1754         //if (wet) writeln("generated WET spear trap");
1755         if (t) {
1756           t.cleanDeath = true;
1757           t.instanceRemove();
1758         }
1759       }
1760     }
1761   }
1763   if (t && t.isInstanceAlive && !t.altar) {
1764     if (global.cemetary) level.scrTreasureGen(x, y, 10); else level.scrTreasureGen(x, y);
1765   }
1767   int roomX, roomY;
1768   level.tileXY2roomXY(tileX, tileY-1, roomX, roomY); //k8: why -1?
1770   // enemies
1771   if (roomX == level.startRoomX && roomY == level.startRoomY) return;
1773   if (!level.checkTileAtPoint(x, y+16, &cbIsSolidOrWater) &&
1774       !level.checkTileAtPoint(x, y+32, &cbIsSolidOrWater))
1775   {
1776     {
1777       int n = (global.cemetary ? 60 : 80);
1778            if (global.darkLevel && global.randRoom(1, 40) == 1) level.MakeMapObject(x, y+16, 'oScarab');
1779       else if (global.randRoom(1, trunc(ceil(float(n)/global.config.enemyMult))) == 1) level.MakeMapObject(x, y+16, 'oBat');
1780       // else if (randRoom(1, 40) == 1) MakeMapObject(x, y+16, 'oSpiderHang'); // in the original
1781     }
1783     if (!level.isSolidAtPoint(x, y-16) &&
1784         !level.isObjectAtPoint(x, y, &level.cbIsObjectEnemy) &&
1785         !level.checkTileAtPoint(x, y, &cbIsSpikes))
1786     {
1787       if (global.cemetary) {
1788              if (global.randRoom(1, trunc(ceil(25.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oZombie');
1789         else if (global.randRoom(1, trunc(ceil(160.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oVampire');
1790       } else if (!level.checkTileAtPoint(x, y-16, &cbIsWater)) {
1791         int n = (global.blackMarket && (y%128 == 0) ? 0 : 1); // to prevent mantraps from spawning near shopkeepers in black market
1792              if (global.randRoom(1, trunc(ceil(60.0/global.config.enemyMult))) == n) level.MakeMapObject(x, y-16, 'oManTrap');
1793         else if (global.randRoom(1, trunc(ceil(60.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oCaveman');
1794         else if (global.randRoom(1, trunc(ceil(120.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oFireFrog');
1795         else if (global.randRoom(1, trunc(ceil(30.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, level.scrGenGetFrogType());
1796       }
1797       else if (global.randRoom(1, trunc(ceil(120.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oFireFrog');
1798       else if (global.randRoom(1, trunc(ceil(30.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, level.scrGenGetFrogType());
1799     }
1800   }
1804 defaultproperties {
1805   rgLevelType = 1;
1806   rgBizarre = false;