From 67220fa0c7c18a9bb479033c691a325d455b6a57 Mon Sep 17 00:00:00 2001 From: koka Date: Tue, 1 Sep 2026 20:43:57 +0200 Subject: [PATCH] feat(backroom): spawn exit beds on every level --- CHANGELOG.md | 7 +++ README.md | 2 + build.gradle | 55 ++++++++++--------- gradle.properties | 2 +- sanctuary/BACKROOM.md | 4 +- sanctuary/build.gradle | 30 +++++----- .../feature/BackroomArchitectureFeature.java | 23 ++++---- .../worldgen/feature/BackroomLayout.java | 26 +++++++++ .../backroom/BackroomModelSmoke.java | 21 +++++++ 9 files changed, 117 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 435a41d..5745b8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ Ce journal suit les **versions du modpack**. Lorsqu'un seul module change, sa ve - Depuis `26.2.0-alpha.6`, le pack et les modules ont des versions indépendantes. I Like To Move It et Only Fun deviennent les cinquième et sixième modules actifs dans l'alpha 46. - Les versions ci-dessous ont été reconstituées à partir des JAR archivés, des packs locaux et du code source actuel. Les dates n'étant pas enregistrées de manière fiable, elles ne sont pas inventées. +## Non publié + +Module modifié : **Sanctuary `0.0.0-alpha.133`**. + +- répartit les lits de sortie rares sur chacun des cinq niveaux de la Backroom, avec exactement un lit par cellule de 10 × 10 chunks et par niveau dans les nouveaux chunks ; +- conserve les IDs, les données Sanctuary v14 et le protocole réseau 24 ; les chunks Backroom déjà générés restent inchangés. + ## `26.2.0-alpha.229` Module modifié : **Red-Stoner `0.0.0-alpha.16`**. diff --git a/README.md b/README.md index 710e037..d9155af 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ Les descriptions FR/EN/RU sont déclarées dans chaque `fabric.mod.json` et dans Version courante du pack distribué : **`26.2.0-alpha.229`**. Cette release distribue Red-Stoner **`0.0.0-alpha.16`** ; les neuf autres modules conservent leur version issue de l'alpha.228. +Le prochain module Sanctuary **`0.0.0-alpha.133`** répartit les lits de sortie rares sur chacun des cinq niveaux de la Backroom. Chaque niveau garantit désormais un lit par cellule de 10 × 10 chunks dans les nouveaux chunks, sans modifier les sauvegardes, les données v14 ni le protocole réseau 24. + L’alpha.229 ajoute au terminal les tris alphabétique, par quantité croissante et par quantité décroissante. Le tri ne change que sur demande explicite et les rafraîchissements périodiques conservent l’ordre ainsi que les objets sous le curseur. Les sauvegardes, les données Red-Stoner v3 et le protocole réseau 7 restent compatibles. L’alpha.228 reconstruit la Backroom sur cinq niveaux empilés entre Y -64 et Y 383. Le monde devient entièrement noir et sans monstres ; l’arrivée est signalée par une torche récupérable. Les nouveaux chunks composent seuils modulaires, bibliothèques et bureaux, ville dense avec autoroutes et parcs, couloirs techniques, puis une grille 3D et un labyrinthe connecté dont certains trous mènent au vide. Red-Stoner corrige aussi le focus du terminal et permet de retrouver une boîte de Shulker par son contenu. Les chunks déjà générés et les sauvegardes existantes restent compatibles. diff --git a/build.gradle b/build.gradle index 0b69d22..6001fd6 100644 --- a/build.gradle +++ b/build.gradle @@ -2916,7 +2916,7 @@ tasks.register("verifyNotchEncounter") { def textureHash = MessageDigest.getInstance("SHA-256").digest(texture.bytes).encodeHex().toString() if (rootProject.itsalive_version != "0.0.0-alpha.38" || rootProject.ouch_version != "0.0.0-alpha.11" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || rootProject.masterkey_version != "0.0.0-alpha.9" || rootProject.pack_version != "26.2.0-alpha.229" || manifests.itsalive.custom?.sanctuary26?.data_version != 4 @@ -3010,7 +3010,7 @@ tasks.register("verifyMagicCarpet") { if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.iliketomoveit_version != "0.0.0-alpha.18" || rootProject.onlyfun_version != "0.0.0-alpha.27" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || manifests.iliketomoveit.custom?.sanctuary26?.data_version != 4 || manifests.iliketomoveit.custom?.sanctuary26?.network_protocol != 5 || manifests.iliketomoveit.depends?.sanctuary != ">=0.0.0-alpha.127" @@ -3641,7 +3641,7 @@ tasks.register("verifyProgressivePauseMenuRelease") { "sanctuary/src/main/resources/assets/sanctuary/lang/${locale}.json"))] } if (rootProject.pack_version != "26.2.0-alpha.229" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || rootProject.onlyfun_version != "0.0.0-alpha.27" || release.pack_version != rootProject.pack_version || index.versionId != rootProject.pack_version || migration.source?.modules != [sanctuary: "0.0.0-alpha.108", onlyfun: "0.0.0-alpha.17"] @@ -4488,7 +4488,7 @@ tasks.register("verifyShopPricingLayoutRelease") { def index = new JsonSlurper().parse(file("pack/prism/modrinth.index.json")) if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.onlyfun_version != "0.0.0-alpha.27" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || release.pack_version != rootProject.pack_version || index.versionId != rootProject.pack_version || migration.source?.pack_version != "26.2.0-alpha.192" || migration.target?.pack_version != "26.2.0-alpha.193" @@ -4582,7 +4582,7 @@ tasks.register("verifyShopCsvBossGatesRelease") { def offerCatalog = file("sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/ShopOfferCatalog.java").text if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.onlyfun_version != "0.0.0-alpha.27" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || release.pack_version != rootProject.pack_version || index.versionId != rootProject.pack_version || migration.source?.pack_version != "26.2.0-alpha.194" || migration.source?.modules != [onlyfun: "0.0.0-alpha.18", sanctuary: "0.0.0-alpha.110"] @@ -4675,7 +4675,7 @@ tasks.register("verifyQuestRequestsCauldronBatchesRelease") { def sanctuaryManifest = new JsonSlurper().parse(file("sanctuary/src/main/resources/fabric.mod.json")) if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.itsalive_version != "0.0.0-alpha.38" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.196" || migration.target?.pack_version != "26.2.0-alpha.197" || migration.target?.modules != [itsalive: "0.0.0-alpha.29", sanctuary: "0.0.0-alpha.113"] @@ -4775,7 +4775,7 @@ tasks.register("verifyQuestRequestContractsRelease") { def sanctuaryManifest = new JsonSlurper().parse(file("sanctuary/src/main/resources/fabric.mod.json")) if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.itsalive_version != "0.0.0-alpha.38" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.198" || migration.source?.modules?.sanctuary != "0.0.0-alpha.114" || migration.target?.pack_version != "26.2.0-alpha.199" @@ -4895,7 +4895,7 @@ tasks.register("verifyQuestRequestEscrowRelease") { def packwizIndex = file("pack/packwiz/index.toml").text def sanctuaryManifest = new JsonSlurper().parse(file("sanctuary/src/main/resources/fabric.mod.json")) if (rootProject.pack_version != "26.2.0-alpha.229" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.200" || migration.source?.modules?.sanctuary != "0.0.0-alpha.115" || migration.target?.pack_version != "26.2.0-alpha.201" @@ -4952,7 +4952,7 @@ tasks.register("verifyWaystoneShopCulinaryAlpha202Release") { || rootProject.anotherworld_version != "0.0.0-alpha.57" || rootProject.itsalive_version != "0.0.0-alpha.38" || rootProject.iliketomoveit_version != "0.0.0-alpha.18" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.201" || migration.source?.modules != [ itsalive: "0.0.0-alpha.30", @@ -5110,7 +5110,7 @@ tasks.register("verifySafeVaultFeature") { }.keySet() if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.anotherworld_version != "0.0.0-alpha.57" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.schema_version != 1 || migration.source?.pack_version != "26.2.0-alpha.201" || migration.target?.pack_version != "26.2.0-alpha.202" @@ -5970,7 +5970,7 @@ tasks.register("verifyAlpha210Release") { it.path == "mods/jei-26.2-fabric-30.29.0.199.jar" } if (rootProject.pack_version != "26.2.0-alpha.229" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || rootProject.onlyfun_version != "0.0.0-alpha.27" || rootProject.iliketomoveit_version != "0.0.0-alpha.18" || rootProject.itsalive_version != "0.0.0-alpha.38" @@ -6072,7 +6072,7 @@ tasks.register("verifyAlpha211Release") { itsalive: "0.0.0-alpha.38", ouch: "0.0.0-alpha.11", masterkey: "0.0.0-alpha.9"] - def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.132"] + def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.133"] def expectedDataVersions = [ambiance: 2, itsalive: 3, onlyfun: 2, ouch: 1, sanctuary: 11] def workspaceDataVersions = [ambiance: 2, itsalive: 4, onlyfun: 2, ouch: 1, sanctuary: 14] def expectedProtocols = [ambiance: 6, itsalive: 4, onlyfun: 3, ouch: 1, sanctuary: 22] @@ -6172,7 +6172,7 @@ tasks.register("verifyAlpha212Release") { it.path == "mods/jei-26.2-fabric-30.29.0.199.jar" } if (rootProject.pack_version != "26.2.0-alpha.229" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.211" || migration.source?.modules != [sanctuary: "0.0.0-alpha.119"] || migration.target?.pack_version != "26.2.0-alpha.212" @@ -6671,7 +6671,7 @@ tasks.register("verifyAlpha218Release") { } || rootProject.onlyfun_version != "0.0.0-alpha.27" || rootProject.iliketomoveit_version != "0.0.0-alpha.18" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.217" || migration.source?.modules != sourceModules || migration.target?.pack_version != "26.2.0-alpha.218" @@ -6757,7 +6757,7 @@ tasks.register("verifyAlpha219Release") { ambiance: "0.0.0-alpha.22", sanctuary: "0.0.0-alpha.132", iliketomoveit: "0.0.0-alpha.18", onlyfun: "0.0.0-alpha.27", itsalive: "0.0.0-alpha.38", ouch: "0.0.0-alpha.11", masterkey: "0.0.0-alpha.9"] - def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.132"] + def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.133"] def requiredJars = currentModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } @@ -7082,7 +7082,7 @@ tasks.register("verifyAlpha222Release") { } if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.redstoner_version != "0.0.0-alpha.16" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.221" || migration.source?.modules != [ redstoner: "0.0.0-alpha.12", sanctuary: "0.0.0-alpha.122"] @@ -7294,7 +7294,7 @@ tasks.register("verifyAlpha223Release") { it.path == "mods/jei-26.2-fabric-30.29.0.199.jar" } if (rootProject.pack_version != "26.2.0-alpha.229" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.222" || migration.source?.modules != [sanctuary: "0.0.0-alpha.124"] || migration.target?.pack_version != "26.2.0-alpha.223" @@ -7415,7 +7415,7 @@ tasks.register("verifyAlpha224Release") { def currentModules = targetModules + [ itsalive: "0.0.0-alpha.38", iliketomoveit: "0.0.0-alpha.18", onlyfun: "0.0.0-alpha.27", sanctuary: "0.0.0-alpha.132"] - def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.132"] + def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.133"] def inventorySort = file( "sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/gameplay/SanctuaryInventorySort.java").text def clientProgress = file( @@ -7537,11 +7537,11 @@ tasks.register("verifyAlpha225Release") { sanctuary: "0.0.0-alpha.129"] def currentModules = targetModules + [sanctuary: "0.0.0-alpha.132"] def currentWorkspaceModules = currentModules + [ - anotherworld: "0.0.0-alpha.57", sanctuary: "0.0.0-alpha.132"] + anotherworld: "0.0.0-alpha.57", sanctuary: "0.0.0-alpha.133"] def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def releasedModules = workspaceModules + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.132"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } @@ -7701,12 +7701,12 @@ tasks.register("verifyAlpha226Release") { def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def releasedModules = workspaceModules + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.132"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } if (rootProject.pack_version != "26.2.0-alpha.229" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.225" || migration.source?.modules != [sanctuary: "0.0.0-alpha.129"] @@ -7792,13 +7792,13 @@ tasks.register("verifyAlpha227Release") { def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def releasedModules = workspaceModules + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.132"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.anotherworld_version != "0.0.0-alpha.57" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.226" || migration.source?.modules != [ @@ -7890,13 +7890,13 @@ tasks.register("verifyAlpha228Release") { def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def releasedModules = workspaceModules + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.132"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } if (rootProject.pack_version != "26.2.0-alpha.229" || rootProject.redstoner_version != "0.0.0-alpha.16" - || rootProject.sanctuary_version != "0.0.0-alpha.132" + || rootProject.sanctuary_version != "0.0.0-alpha.133" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.227" || migration.source?.modules != [ @@ -7995,7 +7995,8 @@ tasks.register("verifyAlpha229Release") { def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def requiredJars = workspaceModules.collect { id, version -> + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.132"] + def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } def requiredTranslationKeys = [ diff --git a/gradle.properties b/gradle.properties index 2058ef0..87f818d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -28,7 +28,7 @@ iliketomoveit_version=0.0.0-alpha.18 iliketomoveit_lifecycle=active onlyfun_version=0.0.0-alpha.27 onlyfun_lifecycle=active -sanctuary_version=0.0.0-alpha.132 +sanctuary_version=0.0.0-alpha.133 sanctuary_lifecycle=active pack_version=26.2.0-alpha.229 maven_group=fr.koka99cab.sanctuary26 diff --git a/sanctuary/BACKROOM.md b/sanctuary/BACKROOM.md index 1ae608c..f1707f5 100644 --- a/sanctuary/BACKROOM.md +++ b/sanctuary/BACKROOM.md @@ -75,7 +75,9 @@ numérotés de haut en bas afin qu’une chute fasse toujours avancer vers le ni Les ouvertures entre deux niveaux sont calculées une seule fois puis appliquées à la fois au sol supérieur et au plafond inférieur : une chute annoncée ne débouche donc pas sur un bloc fermé. Les imperfections, morceaux suspendus et raccords volontairement cassés font partie de l’esthétique, -mais les portes des couloirs restent traversables. Les lits de sortie générés sont désormais rares. +mais les portes des couloirs restent traversables. Les lits de sortie restent rares, mais chacun +des cinq niveaux en génère exactement un par cellule de 10 × 10 chunks, sur un plancher praticable +propre à sa zone. Il n’est donc plus nécessaire de remonter jusqu’aux Archives pour ressortir. La Backroom ne possède ni ciel, ni soleil, ni lune, ni étoiles, ni lumière ambiante. Son biome ne déclare aucune créature et le serveur retire aussi toute entité de catégorie monstre qui y serait diff --git a/sanctuary/build.gradle b/sanctuary/build.gradle index 04c2a04..9ad6f87 100644 --- a/sanctuary/build.gradle +++ b/sanctuary/build.gradle @@ -199,7 +199,7 @@ tasks.register("verifyBlackMarket") { def questData = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardData.java").text def quests = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/QuestBoardService.java").text def inventoryView = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/api/inventory/SanctuaryPlayerInventoryView.java").text - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || !data.contains('SAVE_KEY = "black_market"') || !data.contains("DATA_VERSION = 2") || !data.contains("ItemStack.CODEC.fieldOf(\"item\")") || !data.contains("replaceListing") || !service.contains("LISTING_FEE_RUBIES = 1") || !service.contains("COMMISSION_PERCENT = 5") @@ -2915,7 +2915,7 @@ tasks.register("verifyShopCurrencyRowsRelease") { "src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/BlackMarketService.java").text def shop = file( "src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/ShopService.java").text - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.modules?.sanctuary != "0.0.0-alpha.117" || migration.shop_currency_inventory?.all_unlocked_rows_counted != true || migration.shop_currency_inventory?.overflow_rows_counted != true @@ -3081,7 +3081,7 @@ tasks.register("verifyProgressivePauseMenu") { "pack/migrations/26.2.0-alpha.190-progressive-pause-menu-to-alpha.191.json")) def pauseMenu = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/mixin/client/PauseScreenMixin.java").text def costs = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/progression/SanctuaryProgressionCosts.java").text - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.pack_version != "26.2.0-alpha.191" || migration.target?.modules?.sanctuary != "0.0.0-alpha.109" || migration.pause_menu?.progression_full_width != true @@ -3119,7 +3119,7 @@ tasks.register("verifyShopPricingLayout") { "pack/migrations/26.2.0-alpha.192-shop-pricing-layout-to-alpha.193.json")) def screen = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/client/SanctuaryShopScreen.java").text def progression = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/ShopProgression.java").text - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.modules?.sanctuary != "0.0.0-alpha.110" || migration.shop_layout?.locked_offer_buttons != 6 || migration.shop_layout?.button_slots != [4, 5, 6, 7, 8, 9] @@ -3150,7 +3150,7 @@ tasks.register("verifyShopCsvBossGates") { "pack/migrations/26.2.0-alpha.194-shop-csv-boss-gates-to-alpha.195.json")) def provider = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/ShopCatalogProvider.java").text def catalog = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/shop/ShopOfferCatalog.java").text - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.pack_version != "26.2.0-alpha.195" || migration.target?.modules?.sanctuary != "0.0.0-alpha.111" || migration.compatibility?.sanctuary_data_version != 11 @@ -3181,7 +3181,7 @@ tasks.register("verifyDeliveryBoxOrientation") { def blockstate = new JsonSlurper().parse( file("src/main/resources/assets/sanctuary/blockstates/delivery_box.json")) def expectedVariants = ["facing=north", "facing=east", "facing=south", "facing=west"].toSet() - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.modules?.sanctuary != "0.0.0-alpha.112" || migration.mailbox?.id != "sanctuary:delivery_box" || migration.mailbox?.horizontal_facing != true @@ -3209,7 +3209,7 @@ tasks.register("verifyInventoryShiftClick") { def mixin = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/mixin/AbstractContainerMenuMixin.java").text def screen = file("src/main/java/fr/koka99cab/sanctuary26/sanctuary/mixin/client/AbstractContainerScreenMixin.java").text def gui = file("INVENTORY_GUI.md").text - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || !transfer.contains("shouldAppendOverflow") || !transfer.contains("isVanillaStorageRange") || !transfer.contains("hotbarStart") @@ -3255,7 +3255,7 @@ tasks.register("verifyQuestRequests") { new JsonSlurper().parse(file("src/main/resources/data/sanctuary/loot_table/blocks/${path}.json")) .pools[0].entries[0].name } - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.modules?.sanctuary != "0.0.0-alpha.113" || migration.quest_requests?.save_key != "quest_requests" || migration.quest_requests?.data_version != 1 @@ -3313,7 +3313,7 @@ tasks.register("verifyQuestRequestContracts") { def locales = ["fr_fr", "en_us", "ru_ru"].collectEntries { locale -> [(locale): new JsonSlurper().parse(file("src/main/resources/assets/sanctuary/lang/${locale}.json"))] } - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.198" || migration.source?.modules?.sanctuary != "0.0.0-alpha.114" || migration.target?.pack_version != "26.2.0-alpha.199" @@ -3382,7 +3382,7 @@ tasks.register("verifyQuestRequestEscrow") { def locales = ["fr_fr", "en_us", "ru_ru"].collectEntries { locale -> [(locale): new JsonSlurper().parse(file("src/main/resources/assets/sanctuary/lang/${locale}.json"))] } - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.source?.pack_version != "26.2.0-alpha.200" || migration.source?.modules?.sanctuary != "0.0.0-alpha.115" || migration.target?.pack_version != "26.2.0-alpha.201" @@ -3461,7 +3461,7 @@ tasks.register("verifyCraftableBannerCape") { def locales = ["fr_fr", "en_us", "ru_ru"].collect { new JsonSlurper().parse(file("src/main/resources/assets/sanctuary/lang/${it}.json")) } - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.modules?.sanctuary != "0.0.0-alpha.130" || migration.white_cape?.crafting_material_count != 6 || migration.white_cape?.maximum_pattern_layers != 6 @@ -3516,7 +3516,7 @@ tasks.register("verifyAlphaIndev") { def locales = ["fr_fr", "en_us", "ru_ru"].collect { new JsonSlurper().parse(file("src/main/resources/assets/sanctuary/lang/${it}.json")) } - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.target?.modules?.sanctuary != "0.0.0-alpha.122" || migration.alpha_world?.dimension != "sanctuary:alpha" || migration.alpha_world?.legacy_dimension != "portals:alpha" @@ -3576,7 +3576,7 @@ tasks.register("verifyBackroom") { def locales = ["fr_fr", "en_us", "ru_ru"].collect { new JsonSlurper().parse(file("src/main/resources/assets/sanctuary/lang/${it}.json")) } - if (project.version.toString() != "0.0.0-alpha.132" + if (project.version.toString() != "0.0.0-alpha.133" || migration.source_data_version != 13 || migration.target_data_version != 14 || migration.integration_modules?.anotherworld?.source != "0.0.0-alpha.56" || migration.integration_modules?.anotherworld?.target != "0.0.0-alpha.57" @@ -3605,13 +3605,15 @@ tasks.register("verifyBackroom") { || !layout.contains("WORLD_MIN_Y = -64") || !layout.contains("WORLD_MAX_Y_EXCLUSIVE = 384") || !layout.contains("LEVEL_0(295, 383)") || !layout.contains("LEVEL_4(-64, 27)") || !layout.contains("mazeConnected") || !layout.contains("RoomCorner") + || !layout.contains("EXIT_BED_CELL_SIZE_CHUNKS = 10") + || !layout.contains("exitBedChunk") || !layout.contains("exitBedFloor") || !materialApi.contains("registerAnomalyMaterial") || locales.any { !it.containsKey("dimension.sanctuary.backroom") || !it.containsKey("message.sanctuary.backroom.bed_entry_only") || !it.containsKey("message.sanctuary.backroom.registry_busy") || !it.containsKey("message.sanctuary.backroom.mailbox_full") || !it.containsKey("message.sanctuary.backroom.exited_with_losses") }) { - throw new GradleException("Sanctuary alpha.132 Backroom contract is incomplete") + throw new GradleException("Sanctuary alpha.133 Backroom contract is incomplete") } } } diff --git a/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/worldgen/feature/BackroomArchitectureFeature.java b/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/worldgen/feature/BackroomArchitectureFeature.java index ca71237..e1eb495 100644 --- a/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/worldgen/feature/BackroomArchitectureFeature.java +++ b/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/worldgen/feature/BackroomArchitectureFeature.java @@ -30,7 +30,6 @@ public final class BackroomArchitectureFeature extends Feature= minimum && coordinate <= maximum; } - private static void placeLootLandmarks(WorldGenLevel level, int x0, int z0, Random random) { + private static void placeLootLandmarks(WorldGenLevel level, long seed, int x0, int z0, + int chunkX, int chunkZ, Random random) { if (random.nextInt(5) == 0) { - int floorY = LANDMARK_FLOORS[random.nextInt(LANDMARK_FLOORS.length)]; + BackroomLevel zone = BackroomLevel.values()[random.nextInt(BackroomLevel.values().length)]; + int floorY = BackroomLayout.exitBedFloor(zone); int x = x0 + 7, y = floorY + 1, z = z0 + 7; - set(level, x, floorY, z, floorMaterial(BackroomLayout.levelAt(floorY))); + set(level, x, floorY, z, floorMaterial(zone)); set(level, x, y, z, Blocks.CHEST.defaultBlockState()); set(level, x, y + 1, z, Blocks.AIR.defaultBlockState()); } - if (random.nextInt(96) == 0) { - int floorY = 272; + for (BackroomLevel zone : BackroomLevel.values()) { + if (!BackroomLayout.exitBedChunk(seed, zone, chunkX, chunkZ)) continue; + int floorY = BackroomLayout.exitBedFloor(zone); int x = x0 + 7, z = z0 + 8; - set(level, x, floorY, z, Blocks.DARK_OAK_PLANKS.defaultBlockState()); - set(level, x + 1, floorY, z, Blocks.DARK_OAK_PLANKS.defaultBlockState()); + set(level, x, floorY, z, floorMaterial(zone)); + set(level, x + 1, floorY, z, floorMaterial(zone)); for (int dx = 0; dx <= 1; dx++) for (int dy = 1; dy <= 2; dy++) { set(level, x + dx, floorY + dy, z, Blocks.AIR.defaultBlockState()); } @@ -439,7 +441,8 @@ public final class BackroomArchitectureFeature extends Feature>> 32), EXIT_BED_CELL_SIZE_CHUNKS); + return chunkX == targetX && chunkZ == targetZ; + } + + /** A traversable authored floor used for exit beds in each of the five levels. */ + public static int exitBedFloor(BackroomLevel level) { + return switch (Objects.requireNonNull(level, "level")) { + case LEVEL_0 -> 349; + case LEVEL_1 -> 250; + case LEVEL_2 -> 117; + case LEVEL_3 -> 64; + case LEVEL_4 -> MAZE_FLOOR_Y; + }; + } + private static boolean isParent(int childX, int childZ, int parentX, int parentZ) { if (childX == 0 && childZ == 0) return false; int expectedX = childX, expectedZ = childZ; diff --git a/sanctuary/src/test/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomModelSmoke.java b/sanctuary/src/test/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomModelSmoke.java index 395d704..10aca2f 100644 --- a/sanctuary/src/test/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomModelSmoke.java +++ b/sanctuary/src/test/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomModelSmoke.java @@ -25,6 +25,7 @@ public final class BackroomModelSmoke { personalRecoveryIsPrioritized(); recentLossesRemainPersonal(); architectureIsDeterministicAndStacked(); + exitBedsCoverEveryLevel(); roomCornersReachEveryVariant(); mazeDoorsStayConnected(); } @@ -126,6 +127,26 @@ public final class BackroomModelSmoke { } } + private static void exitBedsCoverEveryLevel() { + long seed = 26_200_133L; + int cellSize = BackroomLayout.EXIT_BED_CELL_SIZE_CHUNKS; + for (BackroomLevel level : BackroomLevel.values()) { + int floorY = BackroomLayout.exitBedFloor(level); + require(BackroomLayout.levelAt(floorY) == level, + "An exit-bed floor escaped its Backroom level: " + level); + for (int cellX = -2; cellX <= 2; cellX++) for (int cellZ = -2; cellZ <= 2; cellZ++) { + int candidates = 0; + for (int chunkX = cellX * cellSize; chunkX < (cellX + 1) * cellSize; chunkX++) { + for (int chunkZ = cellZ * cellSize; chunkZ < (cellZ + 1) * cellSize; chunkZ++) { + if (BackroomLayout.exitBedChunk(seed, level, chunkX, chunkZ)) candidates++; + } + } + require(candidates == 1, + "A Backroom level lost its single rare exit bed in a generation cell: " + level); + } + } + } + private static void mazeDoorsStayConnected() { long seed = 26_200_132L; for (int x = -16; x <= 16; x++) for (int z = -16; z <= 16; z++) { -- 2.54.0