fixed alot of warnings, and some bugs, so it can be compiled with the current vccrun
[k8vacspelynky.git] / packages / Generator / RoomGenT3.vc
blobf6e74cb4f60b6b2691980b1447b77bcef27ccbf0
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 4, the Temple
20 class RoomGenT3 : RoomGen;
23 override void generate (int rx, int ry) {
24   GameGlobal global = levgen.global;
26   strTemp = "0000000000"~
27             "0000000000"~
28             "0000000000"~
29             "0000000000"~
30             "0000000000"~
31             "0000000000"~
32             "0000000000"~
33             "0000000000";
35   int roomPath = levgen.getRPath(rx, ry); //[scrGetRoomX(x), scrGetRoomY(y)];
36   //int roomPathAbove = -1;
37   shopType = 'General';
38   //if (ry != 0) roomPathAbove = levgen.getRPath(rx, ry-1); //scrGetRoomY(y-128)];
40   if (rx == levgen.startRoomX && ry == levgen.startRoomY) {
41     // starting room
42     int n = (roomPath == 2 ? 2 : 1);
43     switch (n) {
44       case 1: { strTemp = "0000000000"~
45                           "0000000000"~
46                           "0000000000"~
47                           "0000000000"~
48                           "0008000000"~
49                           "0000000000"~
50                           "0000000000"~
51                           "1111111111";
52                           break; }
53       // hole
54       case 2: { strTemp = "0000000000"~
55                           "0000000000"~
56                           "0000000000"~
57                           "0000000000"~
58                           "0008000000"~
59                           "0000000000"~
60                           "0000000000"~
61                           "2000000002";
62                           break; }
63       default: FatalError("000");
64     }
65   } else if (rx == levgen.endRoomX && ry == levgen.endRoomY) {
66     // exit room
67     strTemp = "0000000000"~
68               "0000000000"~
69               "0000000000"~
70               "0000000000"~
71               "0008000000"~
72               "0000000000"~
73               "0000000000"~
74               "0000000000";
75   } else if (roomPath == 0 && global.randRoom(1, 4) > 1) {
76     // side room
77     int n;
78     if (global.cityOfGold == 1) {
79       n = global.randRoom(1, 14);
80       if (n == 12) n = 15;
81     } else if (!global.altar && global.randRoom(1, 12) == 1) {
82       n = 16;
83       global.altar = true;
84     } else if (global.idol) {
85       n = global.randRoom(1, 11);
86     } else {
87       n = global.randRoom(1, 12);
88       if (n == 12) global.idol = true;
89     }
90     switch (n) {
91       // upper plats
92       case 1: { strTemp = "1111100000"~
93                           "1111100000"~
94                           "1111100000"~
95                           "1111100000"~
96                           "1111150000"~
97                           "1111100000"~
98                           "1111100000"~
99                           "1111111111";
100                           break; }
101       case 2: { strTemp = "0000011111"~
102                           "0000011111"~
103                           "0000011111"~
104                           "0000011111"~
105                           "5000011111"~
106                           "0000011111"~
107                           "0000011111"~
108                           "1111111111";
109                           break; }
110       // triangles
111       case 3: { strTemp = "1100000000"~
112                           "1110000000"~
113                           "2111000000"~
114                           "1111100000"~
115                           "2211110000"~
116                           "1111111000"~
117                           "2221111100"~
118                           "1111111111";
119                           break; }
120       case 4: { strTemp = "0000000011"~
121                           "0000000111"~
122                           "0000001112"~
123                           "0000011111"~
124                           "0000111122"~
125                           "0001111111"~
126                           "0011111222"~
127                           "1111111111";
128                           break; }
129       case 5: { strTemp = "1111111111"~
130                           "0000000000"~
131                           "1111111000"~
132                           "1111110000"~
133                           "1111100000"~
134                           "1111000000"~
135                           "1110000000"~
136                           "1100000011";
137                           break; }
138       case 6: { strTemp = "1111111111"~
139                           "0000000000"~
140                           "0001111111"~
141                           "0000111111"~
142                           "0000011111"~
143                           "0000001111"~
144                           "0000000111"~
145                           "1100000011";
146                           break; }
147       case 7: { strTemp = "1111111111"~
148                           "2000000002"~
149                           "1101221011"~
150                           "1100000011"~
151                           "1101221011"~
152                           "2000000002"~
153                           "2001221002"~
154                           "1100000011";
155                           break; }
156       case 8: { strTemp = "1111111111"~
157                           "0002112000"~
158                           "1100110011"~
159                           "1110220111"~
160                           "1100110011"~
161                           "0201111020"~
162                           "0002112000"~
163                           "1111111111";
164                           break; }
165       case 9: { strTemp = "1111111111"~
166                           "0000000000"~
167                           "1101111011"~
168                           "1101111011"~
169                           "1001111001"~
170                           "11wwwwww11"~
171                           "11wwwwww11"~
172                           "1111111111";
173                           break; }
174       // sun room
175       case 10: {
176           if (global.randRoom(1, 2) == 1) {
177             strTemp = "1000000001"~
178                       "0000000000"~
179                       "1000000001"~
180                       "1000000001"~
181                       "1000000001"~
182                       "00T0000T00"~
183                       "0dddddddd0"~
184                       "1111111111";
185           } else {
186             strTemp = "1000000001"~
187                       "0000000000"~
188                       "1000000001"~
189                       "1000000001"~
190                       "1000000001"~
191                       "00T0000T00"~
192                       "0dddddddd0"~
193                       "1111111111";
194           }
195           break;
196       }
197       case 11: { strTemp = "1000000001"~
198                            "0021111200"~
199                            "1000000001"~
200                            "1000000001"~
201                            "1111001111"~
202                            "1112002111"~
203                            "1112002111"~
204                            "1111001111";
205                            break; }
206       // idol
207       case 12: { strTemp = "11CCCCCC11"~
208                            "1100000011"~
209                            "1100000011"~
210                            "1D000000D1"~
211                            "1000000001"~
212                            "0000000000"~
213                            "0000I00000"~
214                            "1111111111";
215                            break; }
216       // treasure vaults
217       case 13: { strTemp = "11ttttt011"~
218                            "1111111011"~
219                            "110ttttt11"~
220                            "1101111111"~
221                            "11ttttt011"~
222                            "1111111011"~
223                            "11cttttt11"~
224                            "1111111111";
225                            break; }
226       case 14: { strTemp = "1111111111"~
227                            "110ttttc11"~
228                            "1101111111"~
229                            "11ttttt011"~
230                            "1111111011"~
231                            "110ttttt11"~
232                            "1101111111"~
233                            "1100000011";
234                            break; }
235       case 15: { strTemp = "1111111111"~
236                            "1111111111"~
237                            "1111cc1111"~
238                            "1101111011"~
239                            "11c1111c11"~
240                            "1111cc1111"~
241                            "1111111111"~
242                            "1111111111";
243                            break; }
244       // altars
245       case 16: { strTemp = "2200000022"~
246                            "0000000000"~
247                            "0000000000"~
248                            "0000000000"~
249                            "0000000000"~
250                            "0000x00000"~
251                            "0221111220"~
252                            "1111111111";
253                            break; }
254       default: FatalError("002");
255     }
256   } else if (roomPath == 0 || roomPath == 1) {
257     // main room
258     int n = (global.cityOfGold == 1 ? global.randRoom(1, 12) : global.randRoom(1, 10));
259     switch (n) {
260       // basic rooms
261       case 1: { strTemp = "1000000001"~
262                           "200r000002"~
263                           "1000000001"~
264                           "1000000001"~
265                           "1100000011"~
266                           "0000000000"~
267                           "0000000000"~
268                           "1111111111";
269                           break; }
270       case 2: { strTemp = "1000000000"~
271                           "100r000000"~
272                           "1000000000"~
273                           "1000000000"~
274                           "1100000000"~
275                           "0000000000"~
276                           "0000000000"~
277                           "1111111111";
278                           break; }
279       case 3: { strTemp = "0000000001"~
280                           "000r000001"~
281                           "0000000001"~
282                           "0000000001"~
283                           "0000000011"~
284                           "0000000000"~
285                           "0000000000"~
286                           "1111111111";
287                           break; }
288       case 4: { strTemp = "0000000001"~
289                           "000r000001"~
290                           "0000000001"~
291                           "0000000001"~
292                           "0000000011"~
293                           "0000220000"~
294                           "0001111000"~
295                           "1111111111";
296                           break; }
297       case 5: { strTemp = "1100000011"~
298                           "00L0000L00"~
299                           "11Pr000P11"~
300                           "11L0000L11"~
301                           "11L0000L11"~
302                           "02L0000L20"~
303                           "0000000000"~
304                           "1111111111";
305                           break; }
306       // hallways
307       case 6: { strTemp = "1111111111"~
308                           "1111111111"~
309                           "1111111111"~
310                           "1111111111"~
311                           "1111111111"~
312                           "0000000000"~
313                           "0000000000"~
314                           "1111111111";
315                           break; }
316       case 7: { strTemp = "1000000001"~
317                           "000r000000"~
318                           "1000000001"~
319                           "1000000001"~
320                           "1111111111"~
321                           "0000000000"~
322                           "0000000000"~
323                           "1111111111";
324                           break; }
325       case 8: { strTemp = "120r000021"~
326                           "0000000000"~
327                           "1200000021"~
328                           "1220LL0221"~
329                           "1111PP1111"~
330                           "0011LL1100"~
331                           "0000LL0000"~
332                           "1111111111";
333                           break; }
334       case 9: { strTemp = "1111111111"~
335                           "2400000042"~
336                           "1101111011"~
337                           "1200000021"~
338                           "1111111111"~
339                           "0000000000"~
340                           "0000000000"~
341                           "1111111111";
342                           break; }
343       // lava
344       case 10: { strTemp = "0000000000"~
345                            "0000000000"~
346                            "0000000000"~
347                            "0000000000"~
348                            "013wwww310"~
349                            "013wwww310"~
350                            "1113333111"~
351                            "1111111111";
352                            break; }
353       case 11: { strTemp = "1000000001"~
354                            "000r000000"~
355                            "1000000001"~
356                            "1000000001"~
357                            "1111111111"~
358                            "0000?00000"~
359                            "0000000000"~
360                            "1111111111";
361                            break; }
362       case 12: { strTemp = "1000000001"~
363                            "0000000000"~
364                            "1000?00001"~
365                            "1000000001"~
366                            "1111111111"~
367                            "0000000000"~
368                            "0000000000"~
369                            "1111111111";
370                            break; }
371       default: FatalError("003");
372     }
373   } else if (roomPath == 3) {
374     // main room
375     switch (global.randRoom(1, 3)) {
376       // basic rooms
377       case 1: { strTemp = "1000000001"~
378                           "100r000001"~
379                           "1000000001"~
380                           "1000000001"~
381                           "1100000011"~
382                           "0000000000"~
383                           "0000000000"~
384                           "1111111111";
385                           break; }
386       case 2: { strTemp = "1000000000"~
387                           "100r000000"~
388                           "1000000000"~
389                           "1000000000"~
390                           "1100000000"~
391                           "0000000000"~
392                           "0000000000"~
393                           "1111111111";
394                           break; }
395       case 3: { strTemp = "0000000001"~
396                           "000r000001"~
397                           "0000000001"~
398                           "0000000001"~
399                           "0000000011"~
400                           "0000000000"~
401                           "0000000000"~
402                           "1111111111";
403                           break; }
404       // lava
405       case 4: { strTemp = "0000000000"~
406                           "0000000000"~
407                           "0000000000"~
408                           "0000000000"~
409                           "013wwww310"~
410                           "013wwww310"~
411                           "1113333111"~
412                           "1111111111";
413                           break; }
414       default: FatalError("004");
415     }
416   } else if (roomPath == LevelGen::RType.Shop4) {
417     // shop
418     strTemp = "1111111111"~
419               "1111111111"~
420               "1111221111"~
421               "111l000211"~
422               "...000W010"~
423               "...00000k0"~
424               "..Kiiii000"~
425               "bbbbbbbbbb";
426     int n = global.randRoom(1, 6+(global.damsel ? 1 : 0));
427     if (global.scumGenShopType > 0) n = global.scumGenShopType;
428     switch (n) {
429       case 1: shopType = 'General'; break;
430       case 2: shopType = 'Bomb'; break;
431       case 3: shopType = 'Weapon'; break;
432       case 4: shopType = 'Rare'; break;
433       case 5: shopType = 'Clothing'; break;
434       case 6: shopType = 'Craps';
435         strTemp = "1111111111"~
436                   "1111111111"~
437                   "1111221111"~
438                   "11Kl000211"~
439                   "..bQ00W010"~
440                   ".0+00000k0"~
441                   ".q+uu00000"~
442                   "bbbbbbbbbb";
443         break;
444       case 7: shopType = 'Kissing';
445         strTemp = "1111111111"~
446                   "1111111111"~
447                   "1111221111"~
448                   "111p000211"~
449                   "...000W010"~
450                   "...00000k0"~
451                   "..K00A0000"~
452                   "bbbbbbbbbb";
453         /*oGame*/global.damsel = true;
454         break;
455       default: FatalError("005");
456     }
457   } else if (roomPath == LevelGen::RType.Shop5) {
458     // shop
459     strTemp = "1111111111"~
460               "1111111111"~
461               "1111221111"~
462               "112000l111"~
463               "01W0000..."~
464               "0k00000..."~
465               "000iiiiK.."~
466               "bbbbbbbbbb";
467     int n = global.randRoom(1, 6+(global.damsel ? 1 : 0));
468     if (global.scumGenShopType > 0) n = global.scumGenShopType;
469     switch (n) {
470       case 1: shopType = 'General'; break;
471       case 2: shopType = 'Bomb'; break;
472       case 3: shopType = 'Weapon'; break;
473       case 4: shopType = 'Rare'; break;
474       case 5: shopType = 'Clothing'; break;
475       case 6: shopType = 'Craps';
476         strTemp = "1111111111"~
477                   "1111111111"~
478                   "1111221111"~
479                   "112000lK11"~
480                   "01W0Q00b.."~
481                   "0k00000+0."~
482                   "00000uu+q."~
483                   "bbbbbbbbbb";
484         break;
485       case 7: shopType = 'Kissing';
486         strTemp = "1111111111"~
487                   "1111111111"~
488                   "1111221111"~
489                   "112000p111"~
490                   "01W0000..."~
491                   "0k00000..."~
492                   "0000A00K.."~
493                   "bbbbbbbbbb";
494         /*oGame*/global.damsel = true;
495         break;
496       default: FatalError("006");
497     }
498   } else if (roomPath == 6) {
499     // Lady Xoc
500     strTemp = "0000000000"~
501               "00X0000000"~
502               "0000000000"~
503               "0000000000"~
504               "0000000000"~
505               "0000000000"~
506               "0000000000"~
507               "1111111111";
508   } else if (roomPath == 7) {
509     // pit top
510     strTemp = "0000000000"~
511               "0000000000"~
512               "0000000000"~
513               "0000000000"~
514               "0001001000"~
515               "0011001100"~
516               "0111;01110"~
517               "111BBBB111";
518   } else if (roomPath == 8) {
519     // pit
520     strTemp = "1120000211"~
521               "1120000211"~
522               "1120000211"~
523               "1120000211"~
524               "1120000211"~
525               "1120000211"~
526               "1120000211"~
527               "1120000211";
528   } else if (roomPath == 9) {
529     // pit bottom
530     strTemp = "1120000211"~
531               "1120000211"~
532               "1120000211"~
533               "113wwww311"~
534               "113wwww311"~
535               "113wwww311"~
536               "11RRRRRR11"~
537               "1111111111";
538   } else {
539     // drop
540     switch (global.randRoom(1, 8)) {
541       case 1: { strTemp = "0000000000"~
542                           "0000000000"~
543                           "0000000000"~
544                           "0000000000"~
545                           "0000000000"~
546                           "0000000000"~
547                           "0044404440"~
548                           "1111101111";
549                           break; }
550       case 2: { strTemp = "0000000000"~
551                           "0000000000"~
552                           "0000000000"~
553                           "0000000000"~
554                           "0000000000"~
555                           "0000000000"~
556                           "0444000444"~
557                           "1111000111";
558                           break; }
559       case 3: { strTemp = "0000000000"~
560                           "6000060000"~
561                           "0000000000"~
562                           "0000000000"~
563                           "6000060000"~
564                           "0000000000"~
565                           "0000000000"~
566                           "1000000001";
567                           break; }
568       case 4: { strTemp = "0000000000"~
569                           "0000000000"~
570                           "0000000000"~
571                           "0000000000"~
572                           "0000000000"~
573                           "0000000000"~
574                           "0000000000"~
575                           "1000111111";
576                           break; }
577       case 5: { strTemp = "0000000000"~
578                           "0000000000"~
579                           "0000000000"~
580                           "0000000000"~
581                           "0000000000"~
582                           "0000000000"~
583                           "0000000000"~
584                           "1111110001";
585                           break; }
586       case 6: { strTemp = "0000000000"~
587                           "0060000000"~
588                           "0000000000"~
589                           "0000000000"~
590                           "0000000000"~
591                           "0011122200"~
592                           "0010000000"~
593                           "1110111111";
594                           break; }
595       case 7: { strTemp = "0000000000"~
596                           "0060000000"~
597                           "0000000000"~
598                           "0000000000"~
599                           "0000000000"~
600                           "0022211100"~
601                           "0000000100"~
602                           "1111110111";
603                           break; }
604       case 8: { strTemp = "0000000000"~
605                           "0060000000"~
606                           "0000000000"~
607                           "0000000000"~
608                           "0000000000"~
609                           "0010110100"~
610                           "0010000100"~
611                           "1111001111";
612                           break; }
613       default: FatalError("007");
614     }
615   }
617   if (strTemp.length != 80) FatalError("ooops");
619   // add obstacles
620   foreach (int i; 0..80) {
621     int j = i;
623     string strObs1 = "00000";
624     string strObs2 = "00000";
625     string strObs3 = "00000";
626     int tile = strTemp[i];
628     if (tile == "8") {
629       strObs1 = "00900";
630       strObs2 = "21112";
631       strObs3 = "21112";
632     } else if (tile == "5") {
633       // ground
634       switch (global.randRoom(1, 8)) {
635         case 1: { strObs1 = "00000";
636                   strObs2 = "02220";
637                   strObs3 = "21112";
638                   break; }
639         case 2: { strObs1 = "00000";
640                   strObs2 = "02020";
641                   strObs3 = "21212";
642                   break; }
643         case 3: { strObs1 = "11100";
644                   strObs2 = "11110";
645                   strObs3 = "11111";
646                   break; }
647         case 4: { strObs1 = "00111";
648                   strObs2 = "01111";
649                   strObs3 = "11111";
650                   break; }
651         case 5: { strObs1 = "21112";
652                   strObs2 = "22222";
653                   strObs3 = "00000";
654                   break; }
655         case 6: { strObs1 = "00022";
656                   strObs2 = "00011";
657                   strObs3 = "00011";
658                   break; }
659         case 7: { strObs1 = "22000";
660                   strObs2 = "11000";
661                   strObs3 = "11000";
662                   break; }
663         case 8: { strObs1 = "00000";
664                   strObs2 = "00000";
665                   strObs3 = "00000";
666                   break; }
667         default: FatalError("009");
668       }
669     } else if (tile == "6") {
670       // air
671       switch (global.randRoom(1, 10)) {
672         case 1: { strObs1 = "11111";
673                   strObs2 = "00000";
674                   strObs3 = "00000";
675                   break; }
676         case 2: { strObs1 = "22222";
677                   strObs2 = "00000";
678                   strObs3 = "00000";
679                   break; }
680         case 3: { strObs1 = "22200";
681                   strObs2 = "22200";
682                   strObs3 = "00000";
683                   break; }
684         case 4: { strObs1 = "02220";
685                   strObs2 = "02220";
686                   strObs3 = "00000";
687                   break; }
688         case 5: { strObs1 = "00222";
689                   strObs2 = "00222";
690                   strObs3 = "00000";
691                   break; }
692         case 6: { strObs1 = "00000";
693                   strObs2 = "01110";
694                   strObs3 = "00000";
695                   break; }
696         case 7: { strObs1 = "00000";
697                   strObs2 = "01110";
698                   strObs3 = "02220";
699                   break; }
700         case 8: { strObs1 = "00000";
701                   strObs2 = "02220";
702                   strObs3 = "01110";
703                   break; }
704         case 9: { strObs1 = "00000";
705                   strObs2 = "20100";
706                   strObs3 = "00111";
707                   break; }
708         case 10: { strObs1 = "00000";
709                    strObs2 = "00102";
710                    strObs3 = "11100";
711                    break; }
712         default: FatalError("00a");
713       }
714     } else if (tile == "r") {
715       // air
716       switch (global.randRoom(1, 10)) {
717         case 1: { strObs1 = "1111";
718                   strObs2 = "0000";
719                   strObs3 = "0000";
720                   break; }
721         case 2: { strObs1 = "2222";
722                   strObs2 = "0000";
723                   strObs3 = "0000";
724                   break; }
725         case 3: { strObs1 = "2220";
726                   strObs2 = "2220";
727                   strObs3 = "0000";
728                   break; }
729         case 4: { strObs1 = "0222";
730                   strObs2 = "0222";
731                   strObs3 = "0000";
732                   break; }
733         case 5: { strObs1 = "2222";
734                   strObs2 = "0000";
735                   strObs3 = "2222";
736                   break; }
737         case 6: { strObs1 = "0000";
738                   strObs2 = "1111";
739                   strObs3 = "0000";
740                   break; }
741         case 7: { strObs1 = "0000";
742                   strObs2 = "1111";
743                   strObs3 = "2222";
744                   break; }
745         case 8: { strObs1 = "0000";
746                   strObs2 = "2222";
747                   strObs3 = "1111";
748                   break; }
749         case 9: { strObs1 = "0000";
750                   strObs2 = "0220";
751                   strObs3 = "2112";
752                   break; }
753         case 10: { strObs1 = "0000";
754                    strObs2 = "2002";
755                    strObs3 = "1221";
756                    break; }
757         default: FatalError("00a");
758       }
759     }
761     if (tile == "5" || tile == "6" || tile == "8") {
762       //strTemp = string_delete(strTemp, j, 5);
763       //strTemp = string_insert(strObs1, strTemp, j);
764       strTemp[j..j+5] = strObs1;
765       j += 10;
766       //strTemp = string_delete(strTemp, j, 5);
767       //strTemp = string_insert(strObs2, strTemp, j);
768       strTemp[j..j+5] = strObs2;
769       j += 10;
770       //strTemp = string_delete(strTemp, j, 5);
771       //strTemp = string_insert(strObs3, strTemp, j);
772       strTemp[j..j+5] = strObs3;
773     } else if (tile == "r") {
774       //strTemp = string_delete(strTemp, j, 4);
775       //strTemp = string_insert(strObs1, strTemp, j);
776       strTemp[j..j+4] = strObs1;
777       j += 10;
778       //strTemp = string_delete(strTemp, j, 4);
779       //strTemp = string_insert(strObs2, strTemp, j);
780       strTemp[j..j+4] = strObs2;
781       j += 10;
782       //strTemp = string_delete(strTemp, j, 4);
783       //strTemp = string_insert(strObs3, strTemp, j);
784       strTemp[j..j+4] = strObs3;
785     }
786   }
790 override void genTileAt (int tileX, int tileY) {
791   name shopType = levgen.roomShopType(tileX, tileY);
793   auto global = levgen.global;
794   auto level = levgen.level;
796   // border tiles (moved to LevelGen)
797   if (tileX == 0 || tileY == 0 || tileX == level.tilesWidth-1 || tileY == level.tilesHeight-1) {
798     /*
799     MapTile tile;
800     tile = level.MakeMapTile(tileX, tileY, 'oEdgeBrick');
801     tile.setSprite('sTemple');
802     tile.invincible = true;
803     tile.border = true;
804     tile.ore = 0;
805     //tile.treasure = '';
806     */
807     level.MakeMapTile(tileX, tileY, 'oTemple');
808     return;
809   }
811   int roomX, roomY;
812   level.tileXY2roomXY(tileX, tileY, roomX, roomY);
813   level.setTileTypeAt(tileX, tileY, levgen.getRPath(roomX, roomY));
815   auto tile = levgen.roomGetXYTileType(tileX, tileY);
816   int xpos = tileX*16, ypos = tileY*16;
818   if (tile == "0") return;
820   if (tile == "1") {
821          if (!global.cityOfGold && global.randRoom(1, 100) == 1) level.MakeMapTile(tileX, tileY, 'oLush');
822     else if (global.randRoom(1, 10) == 1) level.MakeMapTile(tileX, tileY, 'oBlock');
823     else level.MakeMapTile(tileX, tileY, 'oTemple');
824     return;
825   }
827   if (tile == "2") {
828     if (global.randRoom(1, 2) != 1) return;
829     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
830          if (global.randRoom(1, 10) == 1) level.MakeMapTile(tileX, tileY, 'oBlock');
831     else level.MakeMapTile(tileX, tileY, 'oTemple');
832     return;
833   }
835   if (tile == "3") {
836     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
837          if (global.randRoom(1, 2) == 1) level.MakeMapTile(tileX, tileY, 'oLava');
838     else level.MakeMapTile(tileX, tileY, 'oTemple');
839     return;
840   }
842   if (tile == "R") {
843     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
844     auto bt = level.MakeMapTile(tileX, tileY, 'oTemple');
845     if (bt) bt.setGem('oRubyBig');
846     return;
847   }
849   if (tile == "L") {
850     level.MakeMapTile(tileX, tileY, 'oLadderOrange');
851     return;
852   }
854   if (tile == "P") {
855     level.MakeMapTile(tileX, tileY, 'oLadderTop');
856     return;
857   }
859   if (tile == "7") {
860     if (global.randRoom(1, trunci(fceil(3.0/global.config.trapMult))) == 1) {
861       level.MakeMapTile(tileX, tileY, level.scrGenSpikeType());
862     }
863     return;
864   }
866   if (tile == "4") {
867     if (global.randRoom(1, 4) != 1) return;
868     level.MakeMapTile(tileX, tileY, 'oPushBlock');
869     return;
870   }
872   if (tile == "9") {
873     auto block = level.MakeMapTile(tileX, tileY+1, 'oTemple');
874     if (roomX == levgen.startRoomX && roomY == levgen.startRoomY) {
875       level.MakeMapTile(tileX, tileY, 'oEntrance');
876       level.spawnPlayerAt(tileX*16+8, tileY*16+8);
877     } else {
878       level.MakeMapTile(tileX, tileY, 'oExit');
879       block.invincible = true;
880       block.ore = 0;
881     }
882     return;
883   }
885   if (tile == "a") {
886     level.scrLevGenCreateChest(tileX*16+8, tileY*16+8);
887     return;
888   }
890   if (tile == "c") {
891     if (global.randRoom(1, 2) == 1) level.scrLevGenCreateChest(xpos+8, ypos+8);
892     else level.scrLevGenCreateCrate(xpos+8, ypos+8);
893     return;
894   }
896   if (tile == "t") {
897          if (global.randRoom(1, 120) == 1) level.MakeMapObject(xpos+8, ypos+12, 'oRubyBig');
898     else if (global.randRoom(1, 80) == 1) level.MakeMapObject(xpos+8, ypos+12, 'oSapphireBig');
899     else if (global.randRoom(1, 60) == 1) level.MakeMapObject(xpos+8, ypos+12, 'oEmeraldBig');
900     else level.MakeMapObject(xpos+8, ypos+8, 'oGoldBars');
901     return;
902   }
904   if (tile == "x") {
905     level.MakeMapTile(tileX+0, tileY, 'oSacAltarLeft');
906     level.MakeMapTile(tileX+1, tileY, 'oSacAltarRight');
907     level.MakeMapBackTile('bgKaliBody', 0, 0, 64, 64, tileX*16-16, tileY*16-48, 10001);
908     level.MakeMapTile(tileX+1, tileY-4, 'oKaliHead');
909     return;
910   }
912   if (tile == "X") {
913     foreach (int l; 0..6) {
914       foreach (int k; 0..5) {
915         auto bt = level.MakeMapTile(tileX+k, tileY+l, 'oXocBlock');
916         if (bt) {
917           if (k == 2 && l == 1) bt.setGem('oDiamond');
918           if (k == 1 && l == 2) bt.setGem('oSapphireBig');
919           if (k == 3 && l == 2) bt.setGem('oSapphireBig');
920           if (k == 0 && l == 3) bt.setGem('oEmeraldBig');
921           if (k == 4 && l == 3) bt.setGem('oEmeraldBig');
922           if (k == 2 && l == 4) bt.setGem('oRubyBig');
923         }
924         level.MakeMapBackTile('bgLadyXoc', k*16, l*16, 16, 16, xpos+k*16, ypos+l*16, 99);
925       }
926     }
927     return;
928   }
930   if (tile == "I") {
931     level.MakeMapObject(tileX*16+16, tileY*16+12, 'oGoldIdol');
932     // create trap activator
933     auto obj = level.MakeMapObject(tileX+1, tileY+1, 'oTikiCurseCeilingTrap');
934     obj.active = false; // force it here
935     return;
936   }
938   if (tile == ";") {
939     level.MakeMapObject(tileX*16+16, tileY*16+12, 'oDamsel');
940     level.MakeMapObject(tileX*16+16+8, tileY*16+12, 'oGoldIdol');
941     auto obj = level.MakeMapObject(tileX+2, tileY+1, 'oTikiCurseRemoveBricks');
942     obj.active = false; // force it here
943     return;
944   }
946   if (tile == "B") {
947     auto obj = MapTileLushTrapBlock(level.MakeMapTile(tileX, tileY, 'oTrapBlock'));
948     if (obj) {
949       /*auto idol = */level.findNearestObject(tileX*16, tileY*16, delegate bool (MapObject o) {
950         return (o isa ItemGoldIdol);
951       });
952       //obj.deathTimer = 40-abs(obj.ix-(idol ? idol.ix-8 : 0));
953       obj.deathTimer = 2; // it should collapse immediately
954       //writeln("DEATH TIMER: ", obj.deathTimer);
955       if (obj.deathTimer < 0) obj.deathTimer = 0;
956     }
957     return;
958   }
960   if (tile == "C") {
961     level.MakeMapTile(tileX, tileY, 'oCeilingTrap');
962     return;
963   }
965   if (tile == "D") {
966     level.MakeMapTile(tileX, tileY, 'oDoor');
967     level.MakeMapTile(tileX, tileY, 'oTempleFake');
968     level.MakeMapTile(tileX, tileY+1, 'oTempleFake');
969     return;
970   }
972   if (tile == "A") {
973     auto obj = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDamsel');
974     if (obj) {
975       obj.forSale = true;
976       obj.status = MonsterDamsel::SLAVE;
977       obj.shopType = 'Kissing';
978     }
979     return;
980   }
982   if (tile == "?") {
983     level.MakeMapObject(xpos, ypos, 'oTombLord');
984     return;
985   }
987   if (tile == ".") {
988     if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
989     auto obj = level.MakeMapTile(tileX, tileY, 'oTemple');
990     obj.shopWall = true;
991     return;
992   }
994   if (tile == "Q") {
995     if (shopType == 'Craps') level.MakeMapBackTile('bgDiceSign', 0, 0, 48, 32, tileX*16, tileY*16, 9004);
996     return;
997   }
999   if (tile == "q") {
1000     //???: n = rand(1,6);
1001     auto obj = level.scrGenerateItem(tileX*16+8, tileY*16+8, GameLevel::GenItemSet.Craps);
1002     if (obj) obj.inDiceHouse = true;
1003     return;
1004   }
1006   if (tile == "+") {
1007     auto obj = level.MakeMapTile(tileX, tileY, /*'oSolid'*/'oSolidIceBlock');
1008     //obj.sprite_index = sIceBlock;
1009     obj.shopWall = true;
1010     return;
1011   }
1013   if (tile == "W") {
1014     if (global.murderer || global.thiefLevel > 0) {
1015            if (global.isDamsel) level.MakeMapBackTile('bgWanted', 32, 0, 32, 32, tileX*16, tileY*16, 9004);
1016       else if (global.isTunnelMan) level.MakeMapBackTile('bgWanted', 64, 0, 32, 32, tileX*16, tileY*16, 9004);
1017       else level.MakeMapBackTile('bgWanted', 0, 0, 32, 32, tileX*16, tileY*16, 9004);
1018     }
1019     return;
1020   }
1022   if (tile == "b") {
1023     auto obj = level.MakeMapTile(tileX, tileY, 'oTemple');
1024     obj.shopWall = true;
1025     return;
1026   }
1028   if (tile == "l") {
1029     level.MakeMapTile(tileX, tileY, 'oLamp');
1030     return;
1031   }
1033   if (tile == "p") {
1034     level.MakeMapTile(tileX, tileY, 'oLampRed');
1035     return;
1036   }
1038   if (tile == "K") {
1039     //auto obj = MonsterShopkeeper(level.MakeMapObject(tileX*16, tileY*16, 'oShopkeeper'));
1040     //if (obj) obj.style = shopType;
1041     level.scrLevGenShopkeeper(tileX*16, tileY*16, shopType);
1042     return;
1043   }
1045   if (tile == "k") {
1046          if (shopType == 'General') level.MakeMapTile(tileX, tileY, 'oSignGeneral');
1047     else if (shopType == 'Bomb') level.MakeMapTile(tileX, tileY, 'oSignBomb');
1048     else if (shopType == 'Weapon') level.MakeMapTile(tileX, tileY, 'oSignWeapon');
1049     else if (shopType == 'Clothing') level.MakeMapTile(tileX, tileY, 'oSignClothing');
1050     else if (shopType == 'Rare') level.MakeMapTile(tileX, tileY, 'oSignRare');
1051     else if (shopType == 'Craps') level.MakeMapTile(tileX, tileY, 'oSignCraps');
1052     else if (shopType == 'Kissing') level.MakeMapTile(tileX, tileY, 'oSignKissing');
1053     else level.MakeMapTile(tileX, tileY, 'oSign');
1054     return;
1055   }
1057   if (tile == "i") {
1058     level.scrShopItemsGen(tileX*16, tileY*16, shopType);
1059     return;
1060   }
1062   if (tile == "w") {
1063     level.MakeMapTile(tileX, tileY, 'oLava');
1064     return;
1065   }
1067   if (tile == "u") {
1068     auto die = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDice');
1069     if (die) {
1070       die.forSale = true;
1071       die.shopType = 'Craps';
1072     }
1073     return;
1074   }
1076   if (tile == "d") {
1077     level.MakeMapTile(tileX, tileY, (global.cityOfGold ? 'oTemple' : 'oLush'));
1078     return;
1079   }
1081   if (tile == "e") {
1082     if (global.randRoom(1, 2) == 1) level.MakeMapTile(tileX, tileY, (global.cityOfGold ? 'oTemple' : 'oLush'));
1083     return;
1084   }
1086   if (tile == "T") {
1087     // tree
1088     //int xpos = tileX*16, ypos = tileY*16;
1089     level.MakeMapTileAtPix(xpos, ypos, 'oTree');
1090     //int n = 0;
1091     int tx = xpos;
1092     int ty = ypos-16;
1093     bool b1 = false;
1094     bool b2 = false;
1095     foreach (int m; 0..5) {
1096       if (global.randRoom(0, m) > 2) break;
1097       if (!level.isSolidAtPoint(tx, ty-16) &&
1098           !level.isSolidAtPoint(tx-16, ty-16) &&
1099           !level.isSolidAtPoint(tx+16, ty-16))
1100       {
1101         level.MakeMapTileAtPix(tx, ty, 'oTree');
1102         if (m < 4) {
1103           if (!b1 && global.randRoom(1, 5) < 4) {
1104             level.MakeMapTileAtPix(tx+16, ty, 'oTreeBranch');
1105             b1 = true;
1106           } else if (b1) {
1107             b1 = false;
1108           }
1109           if (!b2 && global.randRoom(1, 5) < 4) {
1110             level.MakeMapTileAtPix(tx-16, ty, 'oTreeBranch');
1111             b2 = true;
1112           } else if (b2) {
1113             b2 = false;
1114           }
1115         }
1116       } else {
1117         break;
1118       }
1119       ty -= 16;
1120     }
1121     level.MakeMapTileAtPix(tx-16, ty+16, 'oLeaves');
1122     level.MakeMapTileAtPix(tx+16, ty+16, 'oLeaves');
1123     return;
1124   }
1126   FatalError("INVALID TEMPLE BLOCK: '%s'", string.fromChar(tile));
1130 // ////////////////////////////////////////////////////////////////////////// //
1131 final bool cbIsObjectXMarket (MapObject o) { return false/*!(o isa ObjXMarketEntrance)*/; }
1132 final bool cbIsSolidOrWater (MapTile t) { return (t.solid || t.water || t.lava); }
1133 final bool cbIsSolidOrLava (MapTile t) { return (t.solid || t.lava); }
1134 final bool cbIsWater (MapTile t) { return (t.water || t.lava); }
1135 final bool cbIsSolidOrSpikes (MapTile t) { return (t.solid || t.spikes); }
1136 final bool cbIsSpikes (MapTile t) { return (t.spikes); }
1139 override void genEntityAt (int tileX, int tileY) {
1140   auto global = levgen.global;
1141   auto level = levgen.level;
1143   int x = tileX*16, y = tileY*16;
1145   if (global.randRoom(1, 100) == 1 && !level.isSolidAtPoint(x, y-16)) {
1146     level.MakeMapBackTile('bgStatues', 0, 0, 16, 48, x, y-32, 9005);
1147   }
1149   if (level.isInShop(tileX, tileY)) return;
1151   MapTile t = level.getTileAtGrid(tileX, tileY);
1153   // traps
1154   if (y > 32 && global.genGoldEntrance && !global.madeGoldEntrance && !level.isSolidAtPoint(x, y-16)) {
1155     if (global.randRoom(1, global.goldChance) == 1) {
1156       level.MakeMapTile(tileX, tileY-1, 'oGoldDoor');
1157       global.madeGoldEntrance = true;
1158     } else {
1159       --global.goldChance;
1160     }
1161   } else if (t && t.isInstanceAlive && !t.tree && !t.altar && y != 0 &&
1162              !level.checkTileAtPoint(x, y-16, &cbIsSolidOrLava) &&
1163              !level.isSolidAtPoint(x, y-32) &&
1164              (!level.isSolidAtPoint(x-16, y) || !level.isSolidAtPoint(x+16, y)) &&
1165              level.isSolidAtPoint(x, y+16) &&
1166              !level.isObjectInRect(x, y-16, 16, 16, &level.cbIsObjectEnemy) &&
1167              x != 160 && x != 176 && x != 320 && x != 336 && x != 480 && x != 496)
1168   {
1169     if (global.randRoom(1, trunci(fceil(12.0/global.config.trapMult))) == 1 &&
1170         level.calcNearestEnterDist(x, y) > 64)
1171     {
1172       // to keep the spear trap from plugging up lava passage
1173       if (level.isSolidAtPoint(x-16, y-32) &&
1174           level.isSolidAtPoint(x+16, y-32) &&
1175           !level.isSolidAtPoint(x, y-32) &&
1176           !level.checkTilesInRect(tileX*16, (tileY-1)*16, 16, 16*2, castClass:MapTileSpearTrapBase))
1177       {
1178         // do nothing
1179       } else {
1180         level.RemoveMapTileFromGrid(tileX, tileY-1, "spear trap top");
1181         level.MakeMapTile(tileX, tileY-1, (global.darkLevel ? 'oSpearTrapTopLit' : 'oSpearTrapTop'));
1182         level.RemoveMapTileFromGrid(tileX, tileY, "spear trap bottom");
1183         level.MakeMapTile(tileX, tileY, 'oSpearTrapBottom');
1184         if (t && t.isInstanceAlive) {
1185           t.cleanDeath = true;
1186           t.instanceRemove();
1187         }
1188         t = none;
1189       }
1190     }
1191   }
1193   // enemies
1194   if (y < level.tilesHeight*16-64 &&
1195       !level.checkTileAtPoint(x, y+16, &cbIsSolidOrWater) &&
1196       !level.checkTileAtPoint(x, y+32, &cbIsSolidOrWater))
1197   {
1198     if (global.darkLevel && global.randRoom(1, 40) == 1) level.MakeMapObject(x, y+16, 'oScarab');
1199   }
1201   int roomX, roomY;
1202   level.tileXY2roomXY(tileX, tileY-1, roomX, roomY); //k8: why -1?
1203   bool inStartRoom = (roomX == level.startRoomX && roomY == level.startRoomY);
1205   if (!inStartRoom && !level.isObjectAtPoint(x, y-16, &level.cbIsObjectEnemy)) {
1206     if (y > 16 && !level.isSolidAtPoint(x, y-16)) {
1207       if (global.genTombLord &&
1208           !global.TombLord &&
1209           !level.checkTilesInRect(x, y-32, 33, 31) &&
1210           global.randRoom(1, trunci(fceil(40.0/global.config.enemyMult))) == 1)
1211       {
1212         auto obj = EnemyTombLord(level.MakeMapObject(x, y-32, 'oTombLord'));
1213         if (obj) {
1214           global.totalTombLords += 1;
1215           if (global.currLevel == 13) {
1216             if (!global.gaveSceptre) {
1217               if (global.randRoom(1, global.config.enemyMult) == 1) {
1218                 obj.hasSceptre = true;
1219                 global.gaveSceptre = true;
1220               }
1221             }
1222             if (global.totalTombLords >= global.config.enemyMult || global.randRoom(1, global.config.enemyMult)) {
1223               global.TombLord = true; // don't make any more tomb lords
1224             }
1225             if (global.TombLord && !global.gaveSceptre) {
1226               obj.hasSceptre = true;
1227               global.gaveSceptre = true;
1228             }
1229           }
1230         }
1231       }
1232       else if (global.randRoom(1, trunci(fceil(40.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oCaveman');
1233       else if (global.randRoom(1, trunci(fceil(40.0/global.config.enemyMult))) == 1) level.MakeMapObject(x, y-16, 'oHawkman');
1234       else if (global.randRoom(1, trunci(fceil(60.0/global.config.trapMult))) == 1) {
1235         level.MakeMapTile(tileX, tileY-1, (global.darkLevel ? 'oSmashTrapLit' : 'oSmashTrap'));
1236       }
1237     }
1238   }
1240   /* in the original
1241   if (scrGetRoomX(x) != global.startRoomX or scrGetRoomY(y) != global.startRoomY) and
1242       y >=16 and y < room_height-64 and
1243       !collision_rectangle(x, y+16, x+15, y+64, oSolid, 0, 0)
1244   {
1245     if rand(1, fceil(60/global.trapMult)) == 1 instance_create(x, y+16, oThwompTrap);
1246   }
1247   */
1249   if (t && t.isInstanceAlive && !t.altar) level.scrTreasureGen(x, y);
1253 defaultproperties {
1254   rgLevelType = 3;
1255   rgBizarre = false;