main.hx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. var lvName = "Courtyard";
  2. function buildMainRooms()
  3. {
  4. trace("Starting Desolated Courtyard.");
  5. trace("Generating main rooms.");
  6. Struct.createSpecificRoom("aCEntrance").setName("start")
  7. .chain(Struct.createSpecificRoom("aCMountainLeft").setName("cliffLeft"))
  8. .chain(Struct.createSpecificRoom("aCMountainRight").setName("cliffRight"))
  9. .chain(Struct.createSpecificExit("decayingCells", "aCMidExit"))
  10. .chain(Struct.createSpecificExit("T_Roof", "aCEndExit").setName("mainExit"))
  11. .chain(Struct.createSpecificRoom("aCTeleportGate"))
  12. .chain(Struct.createSpecificExit("T_PrisonDepths", "aCEndRoom"));
  13. // Struct.createExit("decayingCells")
  14. // .branchBetween("cliffLeft", "cliffRight")
  15. // .setName("decayingCells");
  16. // Struct.createRoomWithType("WallJumpGate")
  17. // .addBefore("decayingCells");
  18. if(Random.isBelow(0.6)) {
  19. Struct.createShop(MerchantType.Weapons)
  20. .setName("shop1")
  21. .branchBetween("start", "cliffLeft");
  22. }
  23. else {
  24. Struct.createShop(MerchantType.Weapons)
  25. .setName("shop1")
  26. .branchBetween("cliffRight", "mainExit");
  27. }
  28. Struct.createRoomWithType("BreakableGroundGate")
  29. .addBefore("shop1");
  30. if(Random.isBelow(0.4)) {
  31. Struct.createShop(MerchantType.Actives)
  32. .setName("shop2")
  33. .branchBetween("start", "cliffLeft");
  34. }
  35. else {
  36. Struct.createShop(MerchantType.Actives)
  37. .setName("shop2")
  38. .branchBetween("cliffRight", "mainExit");
  39. }
  40. Struct.createRoomWithType("TeleportGate")
  41. .addBefore("shop2");
  42. if(Random.isBelow(0.6)) {
  43. Struct.createRoomWithType("Treasure")
  44. .branchBetween("start", "cliffLeft");
  45. }
  46. if(Random.isBelow(0.4)) {
  47. Struct.createRoomWithType("Treasure")
  48. .branchBetween("cliffRight", "mainExit");
  49. }
  50. Struct.createSpecificRoom("aCMountainTeleport1")
  51. .addBetween("cliffLeft", "cliffRight");
  52. trace("Generating fixed rooms.");
  53. Struct.createSpecificRoom("aCLadderGate")
  54. .addBetween("cliffRight", "mainExit", 2);
  55. Struct.createSpecificRoom("aCMultiTreasure")
  56. .addBetween("start", "cliffLeft");
  57. Struct.createRoomWithTypeFromGroup("DualTreasure", "alaahCourtyardCommon")
  58. .addFlag(RoomFlag.Outside)
  59. .addBetween("cliffRight", "mainExit");
  60. Struct.createRoomWithTypeFromGroup("HealPotion", "alaahCourtyardCommon")
  61. .addFlag(RoomFlag.Outside)
  62. .addBetween("start", "cliffLeft");
  63. Struct.createRoomWithTypeFromGroup("CursedTreasure", "alaahCourtyardCommon")
  64. .addFlag(RoomFlag.Outside)
  65. .addBetween("start", "cliffLeft");
  66. Struct.createRoomWithTypeFromGroup("BuyableTreasure", "alaahCourtyardCommon")
  67. .addFlag(RoomFlag.Outside)
  68. .addBetween("cliffRight", "mainExit");
  69. Struct.createSpecificRoom("aCEvilRoom")
  70. .addBetween("start", "cliffLeft", 1);
  71. Struct.createSpecificRoom("aCEvilRoomEvil")
  72. .addBetween("start", "cliffLeft", 1);
  73. var exit = Struct.getRoomByName("mainExit");
  74. var undergrounds = Struct.allRooms.filter(function(_room)
  75. return _room != exit && _room.isMainLevel() && !_room.isParentOf(exit) && !_room.isChildOf(exit)
  76. );
  77. var outRooms = Struct.allRooms.filter(function(_room)
  78. return _room.isMainLevel() && _room.parent != null && _room.isParentOf(exit) && _room != exit &&
  79. (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight")))
  80. );
  81. trace("Generating celldoors.");
  82. Struct.createRunicZDoor(Struct.createRoomWithType("Treasure"), 1, undergrounds);
  83. Struct.createRunicZDoor(Struct.createRoomWithTypeFromGroup("Special", "alaahCourtyardKey"), 2, undergrounds);
  84. Struct.createRunicZDoor(Struct.createRoomWithType("Treasure"), 3, undergrounds);
  85. Struct.createRunicZDoor(Struct.createRoomWithType("CursedTreasure"), 4, undergrounds);
  86. Struct.createRunicZDoor(Struct.createRoomWithTypeFromGroup("Special", "alaahCourtyardKey"), 4, undergrounds);
  87. Struct.createRunicZDoor(Struct.createSpecificRoom("GenericZDoor_LR"), 4, undergrounds);
  88. trace("Generating more fixed rooms.");
  89. Struct.createSpecificRoom("aCSecretWallJump")
  90. .addBefore(Random.arraySplice(outRooms).getName());
  91. Struct.createSpecificRoom("aCSecretStomp")
  92. .addBefore(Random.arraySplice(outRooms).getName());
  93. Struct.createSpecificRoom("aCSecretHouse")
  94. .addBefore(Random.arraySplice(outRooms).getName());
  95. Struct.createSpecificRoom("aCSecretFlower")
  96. .addBefore(Random.arraySplice(outRooms).getName());
  97. Struct.createSpecificRoom("aCIsland")
  98. .addBefore(Random.arraySplice(outRooms).getName())
  99. .addZChild(Struct.createSpecificRoom("aCIslandInt"))
  100. .setName("desolate");
  101. }
  102. function buildSecondaryRooms()
  103. {
  104. var exit = Struct.getRoomByName("mainExit");
  105. var mains = Struct.allRooms.filter(function(_room)
  106. return _room.isMainLevel() && _room.parent != null && _room.isParentOf(exit) && _room != exit && _room.childrenCount > 1 &&
  107. (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight")))
  108. );
  109. trace("Generating combat rooms.");
  110. var mainsCopy = mains.copy();
  111. for(i in 0...4) {
  112. if(mainsCopy.length == 0) {
  113. mainsCopy = mains.copy();
  114. }
  115. Struct.createRoomWithTypeFromGroup("Combat", "alaahCourtyardCommon")
  116. .addFlag(RoomFlag.Outside)
  117. .addBefore(Random.arraySplice(mainsCopy).getName());
  118. }
  119. var combatRooms = Struct.allRooms.filter(function(_room)
  120. return _room.type == "Combat" && _room.hasFlag(RoomFlag.Outside) &&
  121. (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight")))
  122. );
  123. var undergrounds = Struct.allRooms.filter(function(_room)
  124. return _room != exit && _room.isMainLevel() && !_room.isParentOf(exit) && !_room.isChildOf(exit)
  125. );
  126. trace("Generating trap rooms.");
  127. for(i in 0...Random.irange(2, 3)){
  128. Struct.createRoomWithTypeFromGroup("Trap_1", "alaahCourtyardCommon")
  129. .addFlag(RoomFlag.Outside)
  130. .addBefore(Random.arraySplice(combatRooms).getName());
  131. }
  132. Struct.createRoomWithTypeFromGroup("Combat", "alaahCourtyardKey")
  133. .addFlag(RoomFlag.Outside)
  134. .addBefore(Random.arraySplice(combatRooms).getName());
  135. for(i in 0...Random.irange(3, 5)) {
  136. Struct.createRoomWithTypeFromGroup("Trap_1", "CommonTraps")
  137. .addBefore(Random.arrayPick(undergrounds).getName());
  138. }
  139. }
  140. function addTeleports()
  141. {
  142. var exit = Struct.getRoomByName("mainExit");
  143. var secondExit = Struct.getRoomByName("mainExit");
  144. var rooms = Struct.allRooms.filter(function(_room)
  145. return _room.isMainLevel()
  146. );
  147. var mains = Struct.allRooms.filter(function(_room)
  148. return _room.isMainLevel() && _room.parent != null && _room.isParentOf(exit) &&
  149. (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight")))
  150. );
  151. trace("Generating TPs.");
  152. //Turn crosses into teleports
  153. for(room in rooms) {
  154. if(room.type == "Corridor" && room.isParentOf(exit) && room.childrenCount > 1 && room.calcTypeDistance("Teleport", true) > 1) {
  155. room.setType("Teleport");
  156. }
  157. }
  158. // Meta gates teleport
  159. for(room in rooms.filter(function(_room) return !_room.hasFlag(RoomFlag.Outside) && (_room.type == "WallJumpGate" || _room.type == "LadderGate" || _room.type == "TeleportGate" || _room.type == "BreakableGroundGate")) ){
  160. if(room.calcTypeDistance("Teleport", false) > 1 ){
  161. Struct.createTeleportBefore(room);
  162. }
  163. }
  164. // more common teleports in the overworld
  165. for(room in rooms.filter(function(_room) return _room.hasFlag(RoomFlag.Outside))) {
  166. if(room.calcTypeDistance("Teleport", true) > 3){
  167. trace("Generating a tp before " + room.getName());
  168. Struct.createRoomWithTypeFromGroup("Teleport", "alaahCourtyardCommon").addFlag(RoomFlag.Outside).addBefore(room.getName());
  169. }
  170. }
  171. // Dead Ends
  172. for(room in rooms) {
  173. if(room.childrenCount == 0 && room != secondExit && room.calcTypeDistance("Teleport", true) > 1){
  174. Struct.createRoomWithType("Teleport").addBefore(room.getName());
  175. }
  176. }
  177. // final tp
  178. if(exit.parent.type != "Teleport") {
  179. Struct.createRoomWithTypeFromGroup("Teleport", "alaahCourtyardCommon").addFlag(RoomFlag.Outside).addBefore(exit.getName());
  180. }
  181. var nodes = rooms.filter(function(_room)
  182. return _room.isMainLevel() && _room.hasFlag(RoomFlag.Outside) &&
  183. (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight")))
  184. );
  185. nodes.sort(function(a, b) return compare(a.spawnDistance, b.spawnDistance));
  186. for(n in nodes) {
  187. if(n.spawnDistance > 1 && n.prent != null && n.calcTypeDistance("Teleport", true) > 2) {
  188. trace("Generating a tp before " + n.getName());
  189. if(n.hasFlag(RoomFlag.Outside)) {
  190. Struct.createRoomWithTypeFromGroup("Teleport", "alaahCourtyardCommon").addFlag(RoomFlag.Outside).addBefore(n.getName());
  191. }
  192. else {
  193. Struct.createRoomWithType("Teleport").addBefore(n.getName());
  194. }
  195. }
  196. }
  197. }
  198. function buildTimedDoors()
  199. {
  200. var cliff = Struct.getRoomByName("cliffRight");
  201. // DecisionHelper doesn't appear in the docs
  202. // Refer to this:
  203. // https://github.com/deepnight/ld40-catsAreAssholes/blob/master/src/DecisionHelper.hx
  204. var dh = new DecisionHelper(Struct.allRooms);
  205. // Remove:
  206. // * not main level (zDoors)
  207. // although a zDoor timedoor would be cool
  208. // * not outside (underground)
  209. // * before the vine cliff
  210. dh.remove(function(_room) return !_room.isMainLevel() || !_room.hasFlag(RoomFlag.Outside) || _room.isParentOf(cliff) || _room.getName() == "cliffRight");
  211. /// RoomNode::spawnDistance is nowhere to be found
  212. // So I have honestly no fucking idea what it does
  213. // But the previous line does the job well enough for the thing to work well
  214. dh.score(function(_room) return _room.spawnDistance <= 1 ? -4 : _room.spawnDistance >= 3 ? -10 : 0);
  215. // Randomly add +1 score to some rooms
  216. dh.score(function(_room) return Random.irange(0, 1));
  217. trace("The Timedoor is " + dh.getBest().getName() + ".");
  218. Struct.createTimedBranchBefore(dh.getBest());
  219. }
  220. function finalize()
  221. {
  222. var exit = Struct.getRoomByName("mainExit");
  223. trace("Finalizing.");
  224. for(room in Struct.allRooms){
  225. if((room.type == "Corridor" || room.type == "Teleport") && room.isParentOf(exit)){
  226. room.setGroup("alaahCourtyardCommon");
  227. room.addFlag(RoomFlag.Outside);
  228. }
  229. }
  230. // Add vertical elevator spacers
  231. /* for(room in Struct.allRooms.copy()){
  232. if(room != exit && room.isMainLevel() && ! room.isParentOf(exit) && room.parent != null && room.parent.isParentOf(exit)) {
  233. Struct.createRoomWithTypeFromGroup("Corridor", "CourtyardVerticalCorridor").addBefore(room.getName());
  234. }
  235. }
  236. // Switch useless corridors to Combat corridors
  237. for(room in Struct.allRooms){
  238. if( room.type == "Corridor" && room.hasFlag(RoomFlag.Outside) && room.childrenCount > 1 ){
  239. room.setType("Combat");
  240. room.setGroup("CourtyardCombatCorridor");
  241. }
  242. }*/
  243. for(room in Struct.allRooms) {
  244. if(room.type == "TimedDoor" || room.type == "TimedTreasure"){
  245. room.setGroup("alaahCourtyardCommon");
  246. }
  247. }
  248. Struct.createSpecificRoom("aCMountainPrelude")
  249. .addBefore("cliffLeft");
  250. for(i in 0...2) {
  251. Struct.createRoomWithTypeFromGroup("Combat", "alaahCourtyardMountain")
  252. .addFlag(RoomFlag.Outside)
  253. .addBetween("cliffLeft", "cliffRight");
  254. }
  255. // Horizontal overworld
  256. for(room in Struct.allRooms) {
  257. if(room.parent != null && room.hasFlag(RoomFlag.Outside)) {
  258. room.setConstraint(LinkConstraint.HorizontalSameDirOnly);
  259. room.setChildPriority(1);
  260. }
  261. }
  262. Struct.getRoomByName("start").chain(Struct.createSpecificExit("BoatDock", "aCStartExit"));//.setConstraint(LinkConstraint.VerticalSameDirOnly));
  263. trace("Done.");
  264. }
  265. function buildMobRoster(_mobList)
  266. {
  267. trace("Applying mob roster.");
  268. addMobRosterFrom("PrisonCourtyard", _mobList);
  269. }
  270. function setLevelProps(_levelProps)
  271. {
  272. trace("Applying props.");
  273. _levelProps.timedDoor = 5.5;
  274. _levelProps.timedGoldMul = 1.5;
  275. _levelProps.timedScrolls = 1;
  276. _levelProps.wind = -3.0;
  277. _levelProps.musicIntro = "music/courtyard_intro.ogg";
  278. _levelProps.musicLoop = "music/courtyard_loop.ogg";
  279. _levelProps.doorColor = 144411;
  280. _levelProps.zDoorColor = 144411;
  281. _levelProps.loadingColor = 1055263;
  282. _levelProps.loadingDescColor = 6652612;
  283. }
  284. function setLevelInfo(_levelInfo)
  285. {
  286. trace("Applying level info.");
  287. _levelInfo.baseLootLevel = 2;
  288. _levelInfo.baseMobTier = 2;
  289. _levelInfo.biome = "PrisonCourtyard2";
  290. _levelInfo.cellBonus = 0.0;
  291. _levelInfo.doubleUps = 0;
  292. _levelInfo.eliteRoomChance = 0.0;
  293. _levelInfo.eliteWanderChance = 1.0;
  294. _levelInfo.extraMobTier = 0;
  295. _levelInfo.flags = 13;
  296. _levelInfo.goldBonus = 0;
  297. _levelInfo.mobDensity = 3.0;
  298. _levelInfo.name = "Desolated Courtyard";
  299. _levelInfo.tripleUps = 2;
  300. }