1 /**********************************************************************************
2 * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3 * Copyright (c) 2010, Moloch
4 * Copyright (c) 2018, Ketmar Dark
6 * This file is part of Spelunky.
8 * You can redistribute and/or modify Spelunky, including its source code, under
9 * the terms of the Spelunky User License.
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.
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/>
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"~
35 int roomPath = levgen.getRPath(rx, ry); //[scrGetRoomX(x), scrGetRoomY(y)];
36 //int roomPathAbove = -1;
38 //if (ry != 0) roomPathAbove = levgen.getRPath(rx, ry-1); //scrGetRoomY(y-128)];
40 if (rx == levgen.startRoomX && ry == levgen.startRoomY) {
42 int n = (roomPath == 2 ? 2 : 1);
44 case 1: { strTemp = "0000000000"~
54 case 2: { strTemp = "0000000000"~
63 default: FatalError("000");
65 } else if (rx == levgen.endRoomX && ry == levgen.endRoomY) {
67 strTemp = "0000000000"~
75 } else if (roomPath == 0 && global.randRoom(1, 4) > 1) {
78 if (global.cityOfGold == 1) {
79 n = global.randRoom(1, 14);
81 } else if (!global.altar && global.randRoom(1, 12) == 1) {
84 } else if (global.idol) {
85 n = global.randRoom(1, 11);
87 n = global.randRoom(1, 12);
88 if (n == 12) global.idol = true;
92 case 1: { strTemp = "1111100000"~
101 case 2: { strTemp = "0000011111"~
111 case 3: { strTemp = "1100000000"~
120 case 4: { strTemp = "0000000011"~
129 case 5: { strTemp = "1111111111"~
138 case 6: { strTemp = "1111111111"~
147 case 7: { strTemp = "1111111111"~
156 case 8: { strTemp = "1111111111"~
165 case 9: { strTemp = "1111111111"~
176 if (global.randRoom(1, 2) == 1) {
177 strTemp = "1000000001"~
186 strTemp = "1000000001"~
197 case 11: { strTemp = "1000000001"~
207 case 12: { strTemp = "11CCCCCC11"~
217 case 13: { strTemp = "11ttttt011"~
226 case 14: { strTemp = "1111111111"~
235 case 15: { strTemp = "1111111111"~
245 case 16: { strTemp = "2200000022"~
254 default: FatalError("002");
256 } else if (roomPath == 0 || roomPath == 1) {
258 int n = (global.cityOfGold == 1 ? global.randRoom(1, 12) : global.randRoom(1, 10));
261 case 1: { strTemp = "1000000001"~
270 case 2: { strTemp = "1000000000"~
279 case 3: { strTemp = "0000000001"~
288 case 4: { strTemp = "0000000001"~
297 case 5: { strTemp = "1100000011"~
307 case 6: { strTemp = "1111111111"~
316 case 7: { strTemp = "1000000001"~
325 case 8: { strTemp = "120r000021"~
334 case 9: { strTemp = "1111111111"~
344 case 10: { strTemp = "0000000000"~
353 case 11: { strTemp = "1000000001"~
362 case 12: { strTemp = "1000000001"~
371 default: FatalError("003");
373 } else if (roomPath == 3) {
375 switch (global.randRoom(1, 3)) {
377 case 1: { strTemp = "1000000001"~
386 case 2: { strTemp = "1000000000"~
395 case 3: { strTemp = "0000000001"~
405 case 4: { strTemp = "0000000000"~
414 default: FatalError("004");
416 } else if (roomPath == LevelGen::RType.Shop4) {
418 strTemp = "1111111111"~
426 int n = global.randRoom(1, 6+(global.damsel ? 1 : 0));
427 if (global.scumGenShopType > 0) n = global.scumGenShopType;
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"~
444 case 7: shopType = 'Kissing';
445 strTemp = "1111111111"~
453 /*oGame*/global.damsel = true;
455 default: FatalError("005");
457 } else if (roomPath == LevelGen::RType.Shop5) {
459 strTemp = "1111111111"~
467 int n = global.randRoom(1, 6+(global.damsel ? 1 : 0));
468 if (global.scumGenShopType > 0) n = global.scumGenShopType;
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"~
485 case 7: shopType = 'Kissing';
486 strTemp = "1111111111"~
494 /*oGame*/global.damsel = true;
496 default: FatalError("006");
498 } else if (roomPath == 6) {
500 strTemp = "0000000000"~
508 } else if (roomPath == 7) {
510 strTemp = "0000000000"~
518 } else if (roomPath == 8) {
520 strTemp = "1120000211"~
528 } else if (roomPath == 9) {
530 strTemp = "1120000211"~
540 switch (global.randRoom(1, 8)) {
541 case 1: { strTemp = "0000000000"~
550 case 2: { strTemp = "0000000000"~
559 case 3: { strTemp = "0000000000"~
568 case 4: { strTemp = "0000000000"~
577 case 5: { strTemp = "0000000000"~
586 case 6: { strTemp = "0000000000"~
595 case 7: { strTemp = "0000000000"~
604 case 8: { strTemp = "0000000000"~
613 default: FatalError("007");
617 if (strTemp.length != 80) FatalError("ooops");
620 foreach (int i; 0..80) {
623 string strObs1 = "00000";
624 string strObs2 = "00000";
625 string strObs3 = "00000";
626 int tile = strTemp[i];
632 } else if (tile == "5") {
634 switch (global.randRoom(1, 8)) {
635 case 1: { strObs1 = "00000";
639 case 2: { strObs1 = "00000";
643 case 3: { strObs1 = "11100";
647 case 4: { strObs1 = "00111";
651 case 5: { strObs1 = "21112";
655 case 6: { strObs1 = "00022";
659 case 7: { strObs1 = "22000";
663 case 8: { strObs1 = "00000";
667 default: FatalError("009");
669 } else if (tile == "6") {
671 switch (global.randRoom(1, 10)) {
672 case 1: { strObs1 = "11111";
676 case 2: { strObs1 = "22222";
680 case 3: { strObs1 = "22200";
684 case 4: { strObs1 = "02220";
688 case 5: { strObs1 = "00222";
692 case 6: { strObs1 = "00000";
696 case 7: { strObs1 = "00000";
700 case 8: { strObs1 = "00000";
704 case 9: { strObs1 = "00000";
708 case 10: { strObs1 = "00000";
712 default: FatalError("00a");
714 } else if (tile == "r") {
716 switch (global.randRoom(1, 10)) {
717 case 1: { strObs1 = "1111";
721 case 2: { strObs1 = "2222";
725 case 3: { strObs1 = "2220";
729 case 4: { strObs1 = "0222";
733 case 5: { strObs1 = "2222";
737 case 6: { strObs1 = "0000";
741 case 7: { strObs1 = "0000";
745 case 8: { strObs1 = "0000";
749 case 9: { strObs1 = "0000";
753 case 10: { strObs1 = "0000";
757 default: FatalError("00a");
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;
766 //strTemp = string_delete(strTemp, j, 5);
767 //strTemp = string_insert(strObs2, strTemp, j);
768 strTemp[j..j+5] = strObs2;
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;
778 //strTemp = string_delete(strTemp, j, 4);
779 //strTemp = string_insert(strObs2, strTemp, j);
780 strTemp[j..j+4] = strObs2;
782 //strTemp = string_delete(strTemp, j, 4);
783 //strTemp = string_insert(strObs3, strTemp, j);
784 strTemp[j..j+4] = strObs3;
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) {
800 tile = level.MakeMapTile(tileX, tileY, 'oEdgeBrick');
801 tile.setSprite('sTemple');
802 tile.invincible = true;
805 //tile.treasure = '';
807 level.MakeMapTile(tileX, tileY, 'oTemple');
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;
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');
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');
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');
843 if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
844 auto bt = level.MakeMapTile(tileX, tileY, 'oTemple');
845 if (bt) bt.setGem('oRubyBig');
850 level.MakeMapTile(tileX, tileY, 'oLadderOrange');
855 level.MakeMapTile(tileX, tileY, 'oLadderTop');
860 if (global.randRoom(1, trunci(fceil(3.0/global.config.trapMult))) == 1) {
861 level.MakeMapTile(tileX, tileY, level.scrGenSpikeType());
867 if (global.randRoom(1, 4) != 1) return;
868 level.MakeMapTile(tileX, tileY, 'oPushBlock');
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);
878 level.MakeMapTile(tileX, tileY, 'oExit');
879 block.invincible = true;
886 level.scrLevGenCreateChest(tileX*16+8, tileY*16+8);
891 if (global.randRoom(1, 2) == 1) level.scrLevGenCreateChest(xpos+8, ypos+8);
892 else level.scrLevGenCreateCrate(xpos+8, ypos+8);
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');
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');
913 foreach (int l; 0..6) {
914 foreach (int k; 0..5) {
915 auto bt = level.MakeMapTile(tileX+k, tileY+l, 'oXocBlock');
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');
924 level.MakeMapBackTile('bgLadyXoc', k*16, l*16, 16, 16, xpos+k*16, ypos+l*16, 99);
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
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
947 auto obj = MapTileLushTrapBlock(level.MakeMapTile(tileX, tileY, 'oTrapBlock'));
949 /*auto idol = */level.findNearestObject(tileX*16, tileY*16, delegate bool (MapObject o) {
950 return (o isa ItemGoldIdol);
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;
961 level.MakeMapTile(tileX, tileY, 'oCeilingTrap');
966 level.MakeMapTile(tileX, tileY, 'oDoor');
967 level.MakeMapTile(tileX, tileY, 'oTempleFake');
968 level.MakeMapTile(tileX, tileY+1, 'oTempleFake');
973 auto obj = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDamsel');
976 obj.status = MonsterDamsel::SLAVE;
977 obj.shopType = 'Kissing';
983 level.MakeMapObject(xpos, ypos, 'oTombLord');
988 if (level.checkTileAtPoint(tileX*16, tileY*16)) return;
989 auto obj = level.MakeMapTile(tileX, tileY, 'oTemple');
995 if (shopType == 'Craps') level.MakeMapBackTile('bgDiceSign', 0, 0, 48, 32, tileX*16, tileY*16, 9004);
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;
1007 auto obj = level.MakeMapTile(tileX, tileY, /*'oSolid'*/'oSolidIceBlock');
1008 //obj.sprite_index = sIceBlock;
1009 obj.shopWall = true;
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);
1023 auto obj = level.MakeMapTile(tileX, tileY, 'oTemple');
1024 obj.shopWall = true;
1029 level.MakeMapTile(tileX, tileY, 'oLamp');
1034 level.MakeMapTile(tileX, tileY, 'oLampRed');
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);
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');
1058 level.scrShopItemsGen(tileX*16, tileY*16, shopType);
1063 level.MakeMapTile(tileX, tileY, 'oLava');
1068 auto die = level.MakeMapObject(tileX*16+8, tileY*16+8, 'oDice');
1071 die.shopType = 'Craps';
1077 level.MakeMapTile(tileX, tileY, (global.cityOfGold ? 'oTemple' : 'oLush'));
1082 if (global.randRoom(1, 2) == 1) level.MakeMapTile(tileX, tileY, (global.cityOfGold ? 'oTemple' : 'oLush'));
1088 //int xpos = tileX*16, ypos = tileY*16;
1089 level.MakeMapTileAtPix(xpos, ypos, 'oTree');
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))
1101 level.MakeMapTileAtPix(tx, ty, 'oTree');
1103 if (!b1 && global.randRoom(1, 5) < 4) {
1104 level.MakeMapTileAtPix(tx+16, ty, 'oTreeBranch');
1109 if (!b2 && global.randRoom(1, 5) < 4) {
1110 level.MakeMapTileAtPix(tx-16, ty, 'oTreeBranch');
1121 level.MakeMapTileAtPix(tx-16, ty+16, 'oLeaves');
1122 level.MakeMapTileAtPix(tx+16, ty+16, 'oLeaves');
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);
1149 if (level.isInShop(tileX, tileY)) return;
1151 MapTile t = level.getTileAtGrid(tileX, tileY);
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;
1159 --global.goldChance;
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)
1169 if (global.randRoom(1, trunci(fceil(12.0/global.config.trapMult))) == 1 &&
1170 level.calcNearestEnterDist(x, y) > 64)
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))
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;
1194 if (y < level.tilesHeight*16-64 &&
1195 !level.checkTileAtPoint(x, y+16, &cbIsSolidOrWater) &&
1196 !level.checkTileAtPoint(x, y+32, &cbIsSolidOrWater))
1198 if (global.darkLevel && global.randRoom(1, 40) == 1) level.MakeMapObject(x, y+16, 'oScarab');
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 &&
1209 !level.checkTilesInRect(x, y-32, 33, 31) &&
1210 global.randRoom(1, trunci(fceil(40.0/global.config.enemyMult))) == 1)
1212 auto obj = EnemyTombLord(level.MakeMapObject(x, y-32, 'oTombLord'));
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;
1222 if (global.totalTombLords >= global.config.enemyMult || global.randRoom(1, global.config.enemyMult)) {
1223 global.TombLord = true; // don't make any more tomb lords
1225 if (global.TombLord && !global.gaveSceptre) {
1226 obj.hasSceptre = true;
1227 global.gaveSceptre = true;
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'));
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)
1245 if rand(1, fceil(60/global.trapMult)) == 1 instance_create(x, y+16, oThwompTrap);
1249 if (t && t.isInstanceAlive && !t.altar) level.scrTreasureGen(x, y);