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 class EntityGenTemple : EntityGen transient;
21 transient bool ashGraveGenerated;
24 // Note: depth of trees, statues is 9005
25 override void generateEntities () {
26 global = levgen.global;
29 global.TombLord = false;
30 global.totalTombLords = 0;
31 global.gaveSceptre = false;
32 global.genTombLord = false;
33 if (global.currLevel == 13) global.genTombLord = true;
34 else if (global.randRoom(1, trunci(fceil(4.0/global.config.enemyMult))) == 1) global.genTombLord = true;
36 global.genGoldEntrance = false;
37 if (global.currLevel == 14) global.genGoldEntrance = true;
38 global.madeGoldEntrance = false;
41 level.forEachSolidTileOnGrid(delegate bool (int tileX, int tileY, MapTile t) {
42 auto rg = levgen.getRoomGenForTileAt(tileX, tileY, allowBorders:false);
43 if (rg) rg.genEntityAt(tileX, tileY);
48 // force generate tomb lord
49 if (global.currLevel == 13 && global.genTombLord && !global.TombLord) {
50 if (level.allExits.length) {
51 auto exit = level.allExits[0];
52 auto obj = EnemyTombLord(level.MakeMapObject(exit.ix, exit.iy-16, 'oTombLord'));
53 ++global.totalTombLords;
55 obj.hasSceptre = true;
56 global.gaveSceptre = true;
61 // force generate gold door
62 if (global.genGoldEntrance && !global.madeGoldEntrance) {
63 level.forEachSolidTileOnGrid(delegate bool (int tileX, int tileY, MapTile t) {
64 if (tileY*16 > 32 && !level.isSolidAtPoint(t.ix, t.iy-16)) {
65 auto gt = level.MakeMapTile(tileX, tileY-1, 'oGoldDoor');
67 global.madeGoldEntrance = true;
75 // `return false;` means "continue"
76 level.forEachSolidTileOnGrid(delegate bool (int tileX, int tileY, MapTile t) {
77 if (t.objType != 'oBlock') return false; // continue
78 if (level.isInShop(tileX, tileY) || t.invincible || t.border) return false; // continue
79 int x = tileX*16, y = tileY*16;
80 auto n = level.calcNearestEnterDist(x, y);
81 if (n > 48 && !(level.isYAtEntranceRow(y) && n < 144) &&
82 global.randRoom(1, trunci(fceil(3.0/global.config.trapMult))) == 1)
84 if (level.isSolidAtPoint(x+16, y) && !level.isSolidInRect(x-32, y, 32, 16)) {
86 level.RemoveMapTileFromGrid(tileX, tileY);
87 level.MakeMapTile(tileX, tileY, (global.darkLevel ? 'oArrowTrapLeftLit' : 'oArrowTrapLeft'));
90 } else if (level.isSolidAtPoint(x-16, y) && !level.isSolidInRect(x+16, y, 33, 16)) {
92 level.RemoveMapTileFromGrid(tileX, tileY);
93 level.MakeMapTile(tileX, tileY, (global.darkLevel ? 'oArrowTrapRightLit' : 'oArrowTrapRight'));
98 return false; // continue
101 if (global.config.trapMult >= 2) {
102 level.forEachSolidTileOnGrid(delegate bool (int tileX, int tileY, MapTile t) {
103 if (t.objType != 'oTemple') return false; // continue
104 if (level.isInShop(tileX, tileY) || t.invincible || t.border) return false; // continue
105 int x = tileX*16, y = tileY*16;
106 auto n = level.calcNearestEnterDist(x, y);
107 if (tileX >= 1 && tileX < level.tilesWidth-1 &&
108 n > 48 && !(level.isYAtEntranceRow(y) && n < 144) &&
109 global.randRoom(1, trunci(fceil(60.0/global.config.trapMult))) == 1)
111 if (level.isSolidAtPoint(x+16, y) && !level.isSolidInRect(x-32, y, 32, 16)) {
113 level.RemoveMapTileFromGrid(tileX, tileY);
114 level.MakeMapTile(tileX, tileY, (global.darkLevel ? 'oArrowTrapLeftLit' : 'oArrowTrapLeft'));
116 //instance_destroy();
117 } else if (level.isSolidAtPoint(x-16, y) && !level.isSolidInRect(x+16, y, 33, 16)) {
119 level.RemoveMapTileFromGrid(tileX, tileY);
120 level.MakeMapTile(tileX, tileY, (global.darkLevel ? 'oArrowTrapRightLit' : 'oArrowTrapRight'));
122 //instance_destroy();
125 return false; // continue