var lvName = "Courtyard"; function buildMainRooms() { trace("Starting Desolated Courtyard."); trace("Generating main rooms."); Struct.createSpecificRoom("aCEntrance").setName("start") .chain(Struct.createSpecificRoom("aCMountainLeft").setName("cliffLeft")) .chain(Struct.createSpecificRoom("aCMountainRight").setName("cliffRight")) .chain(Struct.createSpecificExit("decayingCells", "aCMidExit")) .chain(Struct.createSpecificExit("T_Roof", "aCEndExit").setName("mainExit")) .chain(Struct.createSpecificRoom("aCTeleportGate")) .chain(Struct.createSpecificExit("T_PrisonDepths", "aCEndRoom")); // Struct.createExit("decayingCells") // .branchBetween("cliffLeft", "cliffRight") // .setName("decayingCells"); // Struct.createRoomWithType("WallJumpGate") // .addBefore("decayingCells"); if(Random.isBelow(0.6)) { Struct.createShop(MerchantType.Weapons) .setName("shop1") .branchBetween("start", "cliffLeft"); } else { Struct.createShop(MerchantType.Weapons) .setName("shop1") .branchBetween("cliffRight", "mainExit"); } Struct.createRoomWithType("BreakableGroundGate") .addBefore("shop1"); if(Random.isBelow(0.4)) { Struct.createShop(MerchantType.Actives) .setName("shop2") .branchBetween("start", "cliffLeft"); } else { Struct.createShop(MerchantType.Actives) .setName("shop2") .branchBetween("cliffRight", "mainExit"); } Struct.createRoomWithType("TeleportGate") .addBefore("shop2"); if(Random.isBelow(0.6)) { Struct.createRoomWithType("Treasure") .branchBetween("start", "cliffLeft"); } if(Random.isBelow(0.4)) { Struct.createRoomWithType("Treasure") .branchBetween("cliffRight", "mainExit"); } Struct.createSpecificRoom("aCMountainTeleport1") .addBetween("cliffLeft", "cliffRight"); trace("Generating fixed rooms."); Struct.createSpecificRoom("aCLadderGate") .addBetween("cliffRight", "mainExit", 2); Struct.createSpecificRoom("aCMultiTreasure") .addBetween("start", "cliffLeft"); Struct.createRoomWithTypeFromGroup("DualTreasure", "alaahCourtyardCommon") .addFlag(RoomFlag.Outside) .addBetween("cliffRight", "mainExit"); Struct.createRoomWithTypeFromGroup("HealPotion", "alaahCourtyardCommon") .addFlag(RoomFlag.Outside) .addBetween("start", "cliffLeft"); Struct.createRoomWithTypeFromGroup("CursedTreasure", "alaahCourtyardCommon") .addFlag(RoomFlag.Outside) .addBetween("start", "cliffLeft"); Struct.createRoomWithTypeFromGroup("BuyableTreasure", "alaahCourtyardCommon") .addFlag(RoomFlag.Outside) .addBetween("cliffRight", "mainExit"); Struct.createSpecificRoom("aCEvilRoom") .addBetween("start", "cliffLeft", 1); Struct.createSpecificRoom("aCEvilRoomEvil") .addBetween("start", "cliffLeft", 1); var exit = Struct.getRoomByName("mainExit"); var undergrounds = Struct.allRooms.filter(function(_room) return _room != exit && _room.isMainLevel() && !_room.isParentOf(exit) && !_room.isChildOf(exit) ); var outRooms = Struct.allRooms.filter(function(_room) return _room.isMainLevel() && _room.parent != null && _room.isParentOf(exit) && _room != exit && (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight"))) ); trace("Generating celldoors."); Struct.createRunicZDoor(Struct.createRoomWithType("Treasure"), 1, undergrounds); Struct.createRunicZDoor(Struct.createRoomWithTypeFromGroup("Special", "alaahCourtyardKey"), 2, undergrounds); Struct.createRunicZDoor(Struct.createRoomWithType("Treasure"), 3, undergrounds); Struct.createRunicZDoor(Struct.createRoomWithType("CursedTreasure"), 4, undergrounds); Struct.createRunicZDoor(Struct.createRoomWithTypeFromGroup("Special", "alaahCourtyardKey"), 4, undergrounds); Struct.createRunicZDoor(Struct.createSpecificRoom("GenericZDoor_LR"), 4, undergrounds); trace("Generating more fixed rooms."); Struct.createSpecificRoom("aCSecretWallJump") .addBefore(Random.arraySplice(outRooms).getName()); Struct.createSpecificRoom("aCSecretStomp") .addBefore(Random.arraySplice(outRooms).getName()); Struct.createSpecificRoom("aCSecretHouse") .addBefore(Random.arraySplice(outRooms).getName()); Struct.createSpecificRoom("aCSecretFlower") .addBefore(Random.arraySplice(outRooms).getName()); Struct.createSpecificRoom("aCIsland") .addBefore(Random.arraySplice(outRooms).getName()) .addZChild(Struct.createSpecificRoom("aCIslandInt")) .setName("desolate"); } function buildSecondaryRooms() { var exit = Struct.getRoomByName("mainExit"); var mains = Struct.allRooms.filter(function(_room) return _room.isMainLevel() && _room.parent != null && _room.isParentOf(exit) && _room != exit && _room.childrenCount > 1 && (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight"))) ); trace("Generating combat rooms."); var mainsCopy = mains.copy(); for(i in 0...4) { if(mainsCopy.length == 0) { mainsCopy = mains.copy(); } Struct.createRoomWithTypeFromGroup("Combat", "alaahCourtyardCommon") .addFlag(RoomFlag.Outside) .addBefore(Random.arraySplice(mainsCopy).getName()); } var combatRooms = Struct.allRooms.filter(function(_room) return _room.type == "Combat" && _room.hasFlag(RoomFlag.Outside) && (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight"))) ); var undergrounds = Struct.allRooms.filter(function(_room) return _room != exit && _room.isMainLevel() && !_room.isParentOf(exit) && !_room.isChildOf(exit) ); trace("Generating trap rooms."); for(i in 0...Random.irange(2, 3)){ Struct.createRoomWithTypeFromGroup("Trap_1", "alaahCourtyardCommon") .addFlag(RoomFlag.Outside) .addBefore(Random.arraySplice(combatRooms).getName()); } Struct.createRoomWithTypeFromGroup("Combat", "alaahCourtyardKey") .addFlag(RoomFlag.Outside) .addBefore(Random.arraySplice(combatRooms).getName()); for(i in 0...Random.irange(3, 5)) { Struct.createRoomWithTypeFromGroup("Trap_1", "CommonTraps") .addBefore(Random.arrayPick(undergrounds).getName()); } } function addTeleports() { var exit = Struct.getRoomByName("mainExit"); var secondExit = Struct.getRoomByName("mainExit"); var rooms = Struct.allRooms.filter(function(_room) return _room.isMainLevel() ); var mains = Struct.allRooms.filter(function(_room) return _room.isMainLevel() && _room.parent != null && _room.isParentOf(exit) && (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight"))) ); trace("Generating TPs."); //Turn crosses into teleports for(room in rooms) { if(room.type == "Corridor" && room.isParentOf(exit) && room.childrenCount > 1 && room.calcTypeDistance("Teleport", true) > 1) { room.setType("Teleport"); } } // Meta gates teleport for(room in rooms.filter(function(_room) return !_room.hasFlag(RoomFlag.Outside) && (_room.type == "WallJumpGate" || _room.type == "LadderGate" || _room.type == "TeleportGate" || _room.type == "BreakableGroundGate")) ){ if(room.calcTypeDistance("Teleport", false) > 1 ){ Struct.createTeleportBefore(room); } } // more common teleports in the overworld for(room in rooms.filter(function(_room) return _room.hasFlag(RoomFlag.Outside))) { if(room.calcTypeDistance("Teleport", true) > 3){ trace("Generating a tp before " + room.getName()); Struct.createRoomWithTypeFromGroup("Teleport", "alaahCourtyardCommon").addFlag(RoomFlag.Outside).addBefore(room.getName()); } } // Dead Ends for(room in rooms) { if(room.childrenCount == 0 && room != secondExit && room.calcTypeDistance("Teleport", true) > 1){ Struct.createRoomWithType("Teleport").addBefore(room.getName()); } } // final tp if(exit.parent.type != "Teleport") { Struct.createRoomWithTypeFromGroup("Teleport", "alaahCourtyardCommon").addFlag(RoomFlag.Outside).addBefore(exit.getName()); } var nodes = rooms.filter(function(_room) return _room.isMainLevel() && _room.hasFlag(RoomFlag.Outside) && (_room.isParentOf(Struct.getRoomByName("cliffLeft")) || _room.isChildOf(Struct.getRoomByName("cliffRight"))) ); nodes.sort(function(a, b) return compare(a.spawnDistance, b.spawnDistance)); for(n in nodes) { if(n.spawnDistance > 1 && n.prent != null && n.calcTypeDistance("Teleport", true) > 2) { trace("Generating a tp before " + n.getName()); if(n.hasFlag(RoomFlag.Outside)) { Struct.createRoomWithTypeFromGroup("Teleport", "alaahCourtyardCommon").addFlag(RoomFlag.Outside).addBefore(n.getName()); } else { Struct.createRoomWithType("Teleport").addBefore(n.getName()); } } } } function buildTimedDoors() { var cliff = Struct.getRoomByName("cliffRight"); // DecisionHelper doesn't appear in the docs // Refer to this: // https://github.com/deepnight/ld40-catsAreAssholes/blob/master/src/DecisionHelper.hx var dh = new DecisionHelper(Struct.allRooms); // Remove: // * not main level (zDoors) // although a zDoor timedoor would be cool // * not outside (underground) // * before the vine cliff dh.remove(function(_room) return !_room.isMainLevel() || !_room.hasFlag(RoomFlag.Outside) || _room.isParentOf(cliff) || _room.getName() == "cliffRight"); /// RoomNode::spawnDistance is nowhere to be found // So I have honestly no fucking idea what it does // But the previous line does the job well enough for the thing to work well dh.score(function(_room) return _room.spawnDistance <= 1 ? -4 : _room.spawnDistance >= 3 ? -10 : 0); // Randomly add +1 score to some rooms dh.score(function(_room) return Random.irange(0, 1)); trace("The Timedoor is " + dh.getBest().getName() + "."); Struct.createTimedBranchBefore(dh.getBest()); } function finalize() { var exit = Struct.getRoomByName("mainExit"); trace("Finalizing."); for(room in Struct.allRooms){ if((room.type == "Corridor" || room.type == "Teleport") && room.isParentOf(exit)){ room.setGroup("alaahCourtyardCommon"); room.addFlag(RoomFlag.Outside); } } // Add vertical elevator spacers /* for(room in Struct.allRooms.copy()){ if(room != exit && room.isMainLevel() && ! room.isParentOf(exit) && room.parent != null && room.parent.isParentOf(exit)) { Struct.createRoomWithTypeFromGroup("Corridor", "CourtyardVerticalCorridor").addBefore(room.getName()); } } // Switch useless corridors to Combat corridors for(room in Struct.allRooms){ if( room.type == "Corridor" && room.hasFlag(RoomFlag.Outside) && room.childrenCount > 1 ){ room.setType("Combat"); room.setGroup("CourtyardCombatCorridor"); } }*/ for(room in Struct.allRooms) { if(room.type == "TimedDoor" || room.type == "TimedTreasure"){ room.setGroup("alaahCourtyardCommon"); } } Struct.createSpecificRoom("aCMountainPrelude") .addBefore("cliffLeft"); for(i in 0...2) { Struct.createRoomWithTypeFromGroup("Combat", "alaahCourtyardMountain") .addFlag(RoomFlag.Outside) .addBetween("cliffLeft", "cliffRight"); } // Horizontal overworld for(room in Struct.allRooms) { if(room.parent != null && room.hasFlag(RoomFlag.Outside)) { room.setConstraint(LinkConstraint.HorizontalSameDirOnly); room.setChildPriority(1); } } Struct.getRoomByName("start").chain(Struct.createSpecificExit("BoatDock", "aCStartExit"));//.setConstraint(LinkConstraint.VerticalSameDirOnly)); trace("Done."); } function buildMobRoster(_mobList) { trace("Applying mob roster."); addMobRosterFrom("PrisonCourtyard", _mobList); } function setLevelProps(_levelProps) { trace("Applying props."); _levelProps.timedDoor = 5.5; _levelProps.timedGoldMul = 1.5; _levelProps.timedScrolls = 1; _levelProps.wind = -3.0; _levelProps.musicIntro = "music/courtyard_intro.ogg"; _levelProps.musicLoop = "music/courtyard_loop.ogg"; _levelProps.doorColor = 144411; _levelProps.zDoorColor = 144411; _levelProps.loadingColor = 1055263; _levelProps.loadingDescColor = 6652612; } function setLevelInfo(_levelInfo) { trace("Applying level info."); _levelInfo.baseLootLevel = 2; _levelInfo.baseMobTier = 2; _levelInfo.biome = "PrisonCourtyard2"; _levelInfo.cellBonus = 0.0; _levelInfo.doubleUps = 0; _levelInfo.eliteRoomChance = 0.0; _levelInfo.eliteWanderChance = 1.0; _levelInfo.extraMobTier = 0; _levelInfo.flags = 13; _levelInfo.goldBonus = 0; _levelInfo.mobDensity = 3.0; _levelInfo.name = "Desolated Courtyard"; _levelInfo.tripleUps = 2; }