From 398d94e7d1d54b5c11b0165d4726c662a429370c Mon Sep 17 00:00:00 2001 From: koka Date: Wed, 2 Sep 2026 14:26:51 +0200 Subject: [PATCH 1/2] feat(sanctuary): densifier le butin des Backrooms --- CHANGELOG.md | 8 +++ build.gradle | 63 ++++++++++--------- gradle.properties | 2 +- sanctuary/BACKROOM.md | 17 ++--- sanctuary/build.gradle | 32 +++++----- .../backroom/BackroomChestService.java | 3 + .../feature/BackroomArchitectureFeature.java | 28 ++++++--- .../worldgen/feature/BackroomLayout.java | 15 +++++ .../backroom/BackroomModelSmoke.java | 22 +++++++ 9 files changed, 128 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e3a1b6..82b50a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ 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.137`**. + +- garantit sur chaque niveau de la Backroom un coffre par cellule de 3 × 3 chunks dans les nouveaux chunks, au lieu d’un coffre aléatoire réparti entre les cinq niveaux ; +- encadre chaque coffre généré de deux colonnes de bibliothèques pour former un repère plus facile à reconnaître et fournir des livres à récupérer ; +- ajoute systématiquement un à trois livres au renouvellement de chaque coffre Backroom, sans changer les données Sanctuary v15 ni le protocole réseau 24 ; les chunks déjà générés restent inchangés. + ## `26.2.0-alpha.230` Modules modifiés : **Sanctuary `0.0.0-alpha.136`** et **Red-Stoner `0.0.0-alpha.17`**. diff --git a/build.gradle b/build.gradle index 3057119..16d5873 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.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || rootProject.masterkey_version != "0.0.0-alpha.9" || rootProject.pack_version != "26.2.0-alpha.230" || manifests.itsalive.custom?.sanctuary26?.data_version != 4 @@ -3010,7 +3010,7 @@ tasks.register("verifyMagicCarpet") { if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.iliketomoveit_version != "0.0.0-alpha.18" || rootProject.onlyfun_version != "0.0.0-alpha.27" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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"] @@ -4240,7 +4240,7 @@ project(":redstoner") { "sanctuary/src/main/resources/assets/sanctuary/lang/${it}.json")) } if (rootProject.redstoner_version != "0.0.0-alpha.17" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || redstonerManifest.custom?.sanctuary26?.data_version != 4 || redstonerManifest.custom?.sanctuary26?.network_protocol != 7 || sanctuaryManifest.custom?.sanctuary26?.data_version != 15 @@ -4576,7 +4576,7 @@ tasks.register("verifyShopPricingLayoutRelease") { def index = new JsonSlurper().parse(file("pack/prism/modrinth.index.json")) if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.onlyfun_version != "0.0.0-alpha.27" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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" @@ -4670,7 +4670,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.230" || rootProject.onlyfun_version != "0.0.0-alpha.27" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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"] @@ -4763,7 +4763,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.230" || rootProject.itsalive_version != "0.0.0-alpha.38" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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"] @@ -4863,7 +4863,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.230" || rootProject.itsalive_version != "0.0.0-alpha.38" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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" @@ -4983,7 +4983,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.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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" @@ -5040,7 +5040,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.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.source?.pack_version != "26.2.0-alpha.201" || migration.source?.modules != [ itsalive: "0.0.0-alpha.30", @@ -5198,7 +5198,7 @@ tasks.register("verifySafeVaultFeature") { }.keySet() if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.anotherworld_version != "0.0.0-alpha.57" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.schema_version != 1 || migration.source?.pack_version != "26.2.0-alpha.201" || migration.target?.pack_version != "26.2.0-alpha.202" @@ -6058,7 +6058,7 @@ tasks.register("verifyAlpha210Release") { it.path == "mods/jei-26.2-fabric-30.29.0.199.jar" } if (rootProject.pack_version != "26.2.0-alpha.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || rootProject.onlyfun_version != "0.0.0-alpha.27" || rootProject.iliketomoveit_version != "0.0.0-alpha.18" || rootProject.itsalive_version != "0.0.0-alpha.38" @@ -6160,7 +6160,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.136"] + def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.137"] def expectedDataVersions = [ambiance: 2, itsalive: 3, onlyfun: 2, ouch: 1, sanctuary: 11] def workspaceDataVersions = [ambiance: 2, itsalive: 4, onlyfun: 2, ouch: 1, sanctuary: 15] def expectedProtocols = [ambiance: 6, itsalive: 4, onlyfun: 3, ouch: 1, sanctuary: 22] @@ -6260,7 +6260,7 @@ tasks.register("verifyAlpha212Release") { it.path == "mods/jei-26.2-fabric-30.29.0.199.jar" } if (rootProject.pack_version != "26.2.0-alpha.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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" @@ -6759,7 +6759,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.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.source?.pack_version != "26.2.0-alpha.217" || migration.source?.modules != sourceModules || migration.target?.pack_version != "26.2.0-alpha.218" @@ -6845,7 +6845,7 @@ tasks.register("verifyAlpha219Release") { ambiance: "0.0.0-alpha.22", sanctuary: "0.0.0-alpha.136", 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.136"] + def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.137"] def requiredJars = currentModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } @@ -7170,7 +7170,7 @@ tasks.register("verifyAlpha222Release") { } if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.redstoner_version != "0.0.0-alpha.17" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.source?.pack_version != "26.2.0-alpha.221" || migration.source?.modules != [ redstoner: "0.0.0-alpha.12", sanctuary: "0.0.0-alpha.122"] @@ -7382,7 +7382,7 @@ tasks.register("verifyAlpha223Release") { it.path == "mods/jei-26.2-fabric-30.29.0.199.jar" } if (rootProject.pack_version != "26.2.0-alpha.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || 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" @@ -7503,7 +7503,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.136"] - def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.136"] + def workspaceModules = currentModules + [sanctuary: "0.0.0-alpha.137"] def inventorySort = file( "sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/gameplay/SanctuaryInventorySort.java").text def clientProgress = file( @@ -7625,11 +7625,11 @@ tasks.register("verifyAlpha225Release") { sanctuary: "0.0.0-alpha.129"] def currentModules = targetModules + [sanctuary: "0.0.0-alpha.136"] def currentWorkspaceModules = currentModules + [ - anotherworld: "0.0.0-alpha.57", sanctuary: "0.0.0-alpha.136"] + anotherworld: "0.0.0-alpha.57", sanctuary: "0.0.0-alpha.137"] def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def releasedModules = workspaceModules + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.136"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } @@ -7789,12 +7789,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.136"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } if (rootProject.pack_version != "26.2.0-alpha.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.225" || migration.source?.modules != [sanctuary: "0.0.0-alpha.129"] @@ -7880,13 +7880,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.136"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.anotherworld_version != "0.0.0-alpha.57" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.226" || migration.source?.modules != [ @@ -7978,13 +7978,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.136"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.redstoner_version != "0.0.0-alpha.17" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.227" || migration.source?.modules != [ @@ -8083,7 +8083,7 @@ tasks.register("verifyAlpha229Release") { def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def releasedModules = workspaceModules + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.136"] def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } @@ -8094,7 +8094,7 @@ tasks.register("verifyAlpha229Release") { "screen.redstoner.storage_terminal.sort.count_descending"] if (rootProject.pack_version != "26.2.0-alpha.230" || rootProject.redstoner_version != "0.0.0-alpha.17" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || migration.status != "released" || migration.source?.pack_version != "26.2.0-alpha.228" || migration.source?.modules != [redstoner: "0.0.0-alpha.15"] @@ -8171,13 +8171,14 @@ tasks.register("verifyAlpha230Release") { def workspaceModules = moduleIds.collectEntries { id -> [(id): project(":${id}").version.toString()] } - def requiredJars = workspaceModules.collect { id, version -> + def releasedModules = workspaceModules + [sanctuary: "0.0.0-alpha.136"] + def requiredJars = releasedModules.collect { id, version -> "file = \"mods/${id}-${version}.jar\"" } def indexHash = java.security.MessageDigest.getInstance("SHA-256") .digest(packwizIndexFile.bytes).encodeHex().toString() if (rootProject.pack_version != "26.2.0-alpha.230" - || rootProject.sanctuary_version != "0.0.0-alpha.136" + || rootProject.sanctuary_version != "0.0.0-alpha.137" || rootProject.redstoner_version != "0.0.0-alpha.17" || migration.schema_version != 1 || migration.status != "released" diff --git a/gradle.properties b/gradle.properties index da42b38..213cc74 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.136 +sanctuary_version=0.0.0-alpha.137 sanctuary_lifecycle=active pack_version=26.2.0-alpha.230 maven_group=fr.koka99cab.sanctuary26 diff --git a/sanctuary/BACKROOM.md b/sanctuary/BACKROOM.md index f1707f5..f8eca8d 100644 --- a/sanctuary/BACKROOM.md +++ b/sanctuary/BACKROOM.md @@ -35,13 +35,16 @@ réelle matérialisée reçoit un identifiant persistant : elle peut passer du r Une perte associée à un joueur lui reste réservée pendant 24 000 ticks avant de pouvoir rejoindre les tirages historiques partagés ; une perte sans propriétaire est immédiatement partagée. -Tous les coffres vanilla de la Backroom, générés ou posés, deviennent des nœuds de butin renouvelés -toutes les 12 000 ticks lors de leur prochaine ouverture. Le renouvellement rend au registre les -objets perdus non pris, efface le contenu ordinaire et produit le plus souvent du vide ou des -ressources pauvres : terre, pierre, planches, torches, nourriture et outils simples. Le butin ancien -partagé et les objets de valeur restent rares. Reposer un coffre au même emplacement pendant le -même cycle ne crée pas un nouveau tirage ; multiplier les emplacements donne en revanche bien des -tirages indépendants, au prix des ressources trouvées ou produites sur place. +Chaque niveau génère exactement un coffre par cellule de 3 × 3 chunks dans les nouveaux chunks. +Deux colonnes de bibliothèques encadrent le coffre et forment un repère visible, tout en fournissant +des livres à casser. Tous les coffres vanilla de la Backroom, générés ou posés, deviennent des nœuds +de butin renouvelés toutes les 12 000 ticks lors de leur prochaine ouverture. Chaque renouvellement +garantit aussi un à trois livres, puis produit éventuellement des ressources pauvres : terre, pierre, +planches, torches, nourriture et outils simples. Le renouvellement rend au registre les objets +perdus non pris et efface le contenu ordinaire ; le butin ancien partagé et les objets de valeur +restent rares. Reposer un coffre au même emplacement pendant le même cycle ne crée pas un nouveau +tirage ; multiplier les emplacements donne en revanche bien des tirages indépendants, au prix des +ressources trouvées ou produites sur place. Pendant une expédition, chaque coffre distinct est un essai personnel. Le premier a 75 % de chance de proposer une perte récente du joueur, le deuxième 90 %, le troisième 100 %, puis les suivants diff --git a/sanctuary/build.gradle b/sanctuary/build.gradle index 24be63c..0ead760 100644 --- a/sanctuary/build.gradle +++ b/sanctuary/build.gradle @@ -207,7 +207,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || !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") @@ -2923,7 +2923,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || 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 @@ -3089,7 +3089,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || 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 @@ -3127,7 +3127,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || 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] @@ -3158,7 +3158,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || migration.target?.pack_version != "26.2.0-alpha.195" || migration.target?.modules?.sanctuary != "0.0.0-alpha.111" || migration.compatibility?.sanctuary_data_version != 11 @@ -3189,7 +3189,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || migration.target?.modules?.sanctuary != "0.0.0-alpha.112" || migration.mailbox?.id != "sanctuary:delivery_box" || migration.mailbox?.horizontal_facing != true @@ -3217,7 +3217,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || !transfer.contains("shouldAppendOverflow") || !transfer.contains("isVanillaStorageRange") || !transfer.contains("hotbarStart") @@ -3263,7 +3263,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || migration.target?.modules?.sanctuary != "0.0.0-alpha.113" || migration.quest_requests?.save_key != "quest_requests" || migration.quest_requests?.data_version != 1 @@ -3325,7 +3325,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || 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" @@ -3394,7 +3394,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || 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" @@ -3473,7 +3473,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || migration.target?.modules?.sanctuary != "0.0.0-alpha.130" || migration.white_cape?.crafting_material_count != 6 || migration.white_cape?.maximum_pattern_layers != 6 @@ -3525,7 +3525,7 @@ tasks.register("verifyFinalSanctuaryTickets") { 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.136" + if (project.version.toString() != "0.0.0-alpha.137" || !capeRenderer.contains("SHIELD_PATTERN_X_SCALE = 1.2F") || !capeRenderer.contains("SHIELD_PATTERN_Y_SCALE = 1.375F") || !capeRenderer.contains("model, state, false, appearance.baseColor()") @@ -3574,7 +3574,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || migration.target?.modules?.sanctuary != "0.0.0-alpha.122" || migration.alpha_world?.dimension != "sanctuary:alpha" || migration.alpha_world?.legacy_dimension != "portals:alpha" @@ -3634,7 +3634,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.136" + if (project.version.toString() != "0.0.0-alpha.137" || 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" @@ -3658,11 +3658,15 @@ tasks.register("verifyBackroom") { || !service.contains("MobCategory.MONSTER") || !service.contains("Blocks.TORCH") || !mailbox.contains("MAX_PROCESSED_TRANSACTIONS = 128") || !chest.contains("REFRESH_TICKS = 12_000L") || !chest.contains("ordinal == 3") + || !chest.contains("MIN_BOOKS_PER_REFRESH = 1") + || !chest.contains("MAX_BOOKS_PER_REFRESH = 3") || !chest.contains("Items.BOOK") || !architecture.contains("PLAYABLE_RADIUS = 2_000") || !architecture.contains("BackroomMaterialApi.anomalyMaterial()") + || !architecture.contains("placeLootLandmark") || !architecture.contains("Blocks.BOOKSHELF") || !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("LOOT_CHEST_CELL_SIZE_CHUNKS = 3") || !layout.contains("lootChestChunk") || !layout.contains("EXIT_BED_CELL_SIZE_CHUNKS = 10") || !layout.contains("exitBedChunk") || !layout.contains("exitBedFloor") || !materialApi.contains("registerAnomalyMaterial") diff --git a/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java b/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java index c832355..4c54f3c 100644 --- a/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java +++ b/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java @@ -19,6 +19,8 @@ import net.minecraft.world.level.block.state.properties.ChestType; /** Renewable loot nodes backed by the non-duplicating real-item registry. */ public final class BackroomChestService { public static final long REFRESH_TICKS = 12_000L; + public static final int MIN_BOOKS_PER_REFRESH = 1; + public static final int MAX_BOOKS_PER_REFRESH = 3; private BackroomChestService() {} @@ -63,6 +65,7 @@ public final class BackroomChestService { private static void rollGeneralLoot(ServerLevel level, ChestGroup group, BackroomData data, List assigned, long cycle) { RandomSource random = RandomSource.create(level.getSeed() ^ group.anchor ^ cycle * 0x9E3779B97F4A7C15L); + insert(group, random, Items.BOOK, MIN_BOOKS_PER_REFRESH, MAX_BOOKS_PER_REFRESH); int roll = random.nextInt(100); if (roll < 55) return; if (roll < 74) { 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 e1eb495..50d4cd6 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 @@ -77,7 +77,7 @@ public final class BackroomArchitectureFeature extends Feature>> 32), LOOT_CHEST_CELL_SIZE_CHUNKS); + return chunkX == targetX && chunkZ == targetZ; + } + /** One deterministic, rare exit-bed chunk per grid cell and per vertical level. */ public static boolean exitBedChunk(long seed, BackroomLevel level, int chunkX, int chunkZ) { Objects.requireNonNull(level, "level"); 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 10aca2f..8342c8c 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(); + lootLandmarksCoverEveryLevel(); exitBedsCoverEveryLevel(); roomCornersReachEveryVariant(); mazeDoorsStayConnected(); @@ -70,6 +71,9 @@ public final class BackroomModelSmoke { require(secondHits > 17_500 && secondHits < 18_500, "Second-chest personal chance drifted from 90%"); require(laterHits > 12_500 && laterHits < 13_500, "Later personal chance drifted from 65%"); require(BackroomChestService.REFRESH_TICKS == 12_000L, "Chest renewal is no longer twice per Minecraft day"); + require(BackroomChestService.MIN_BOOKS_PER_REFRESH == 1 + && BackroomChestService.MAX_BOOKS_PER_REFRESH == 3, + "Renewable Backroom chests no longer guarantee one to three books"); } private static void recentLossesRemainPersonal() { @@ -147,6 +151,24 @@ public final class BackroomModelSmoke { } } + private static void lootLandmarksCoverEveryLevel() { + long seed = 26_200_137L; + int cellSize = BackroomLayout.LOOT_CHEST_CELL_SIZE_CHUNKS; + require(cellSize == 3, "Backroom loot landmarks are no longer spaced three chunks apart"); + for (BackroomLevel level : BackroomLevel.values()) { + for (int cellX = -4; cellX <= 4; cellX++) for (int cellZ = -4; cellZ <= 4; 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.lootChestChunk(seed, level, chunkX, chunkZ)) candidates++; + } + } + require(candidates == 1, + "A Backroom level lost its loot landmark in a three-by-three chunk 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 From 5100091b171135d791bdf0dd7bdf633ba7f6b6bf Mon Sep 17 00:00:00 2001 From: koka Date: Wed, 2 Sep 2026 14:36:04 +0200 Subject: [PATCH 2/2] fix(sanctuary): rendre les lits Backroom trouvables --- CHANGELOG.md | 4 ++-- sanctuary/BACKROOM.md | 22 +++++++++---------- sanctuary/build.gradle | 6 ++--- .../backroom/BackroomChestService.java | 3 --- .../feature/BackroomArchitectureFeature.java | 5 +---- .../worldgen/feature/BackroomLayout.java | 4 ++-- .../backroom/BackroomModelSmoke.java | 6 ++--- 7 files changed, 19 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b50a0..a2d2031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,8 @@ Ce journal suit les **versions du modpack**. Lorsqu'un seul module change, sa ve Module modifié : **Sanctuary `0.0.0-alpha.137`**. - garantit sur chaque niveau de la Backroom un coffre par cellule de 3 × 3 chunks dans les nouveaux chunks, au lieu d’un coffre aléatoire réparti entre les cinq niveaux ; -- encadre chaque coffre généré de deux colonnes de bibliothèques pour former un repère plus facile à reconnaître et fournir des livres à récupérer ; -- ajoute systématiquement un à trois livres au renouvellement de chaque coffre Backroom, sans changer les données Sanctuary v15 ni le protocole réseau 24 ; les chunks déjà générés restent inchangés. +- resserre aussi la grille des lits de sortie de 10 × 10 à 3 × 3 chunks sur chacun des cinq niveaux afin qu’ils soient réellement trouvables ; +- ne change ni le butin ordinaire des coffres, ni les données Sanctuary v15, ni le protocole réseau 24 ; les nouveaux coffres et lits apparaissent dans les chunks qui n’ont pas encore été générés. ## `26.2.0-alpha.230` diff --git a/sanctuary/BACKROOM.md b/sanctuary/BACKROOM.md index f8eca8d..ce0e00e 100644 --- a/sanctuary/BACKROOM.md +++ b/sanctuary/BACKROOM.md @@ -36,15 +36,13 @@ Une perte associée à un joueur lui reste réservée pendant 24 000 ticks avant les tirages historiques partagés ; une perte sans propriétaire est immédiatement partagée. Chaque niveau génère exactement un coffre par cellule de 3 × 3 chunks dans les nouveaux chunks. -Deux colonnes de bibliothèques encadrent le coffre et forment un repère visible, tout en fournissant -des livres à casser. Tous les coffres vanilla de la Backroom, générés ou posés, deviennent des nœuds -de butin renouvelés toutes les 12 000 ticks lors de leur prochaine ouverture. Chaque renouvellement -garantit aussi un à trois livres, puis produit éventuellement des ressources pauvres : terre, pierre, -planches, torches, nourriture et outils simples. Le renouvellement rend au registre les objets -perdus non pris et efface le contenu ordinaire ; le butin ancien partagé et les objets de valeur -restent rares. Reposer un coffre au même emplacement pendant le même cycle ne crée pas un nouveau -tirage ; multiplier les emplacements donne en revanche bien des tirages indépendants, au prix des -ressources trouvées ou produites sur place. +Tous les coffres vanilla de la Backroom, générés ou posés, deviennent des nœuds de butin renouvelés +toutes les 12 000 ticks lors de leur prochaine ouverture. Le renouvellement rend au registre les +objets perdus non pris, efface le contenu ordinaire et produit le plus souvent du vide ou des +ressources pauvres : terre, pierre, planches, torches, nourriture et outils simples. Le butin ancien +partagé et les objets de valeur restent rares. Reposer un coffre au même emplacement pendant le +même cycle ne crée pas un nouveau tirage ; multiplier les emplacements donne en revanche bien des +tirages indépendants, au prix des ressources trouvées ou produites sur place. Pendant une expédition, chaque coffre distinct est un essai personnel. Le premier a 75 % de chance de proposer une perte récente du joueur, le deuxième 90 %, le troisième 100 %, puis les suivants @@ -78,9 +76,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 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. +mais les portes des couloirs restent traversables. Chacun des cinq niveaux génère exactement un lit +de sortie par cellule de 3 × 3 chunks, sur un plancher praticable propre à sa zone. Il n’est donc +plus nécessaire de parcourir une centaine de chunks ou 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 0ead760..3f08846 100644 --- a/sanctuary/build.gradle +++ b/sanctuary/build.gradle @@ -3658,16 +3658,14 @@ tasks.register("verifyBackroom") { || !service.contains("MobCategory.MONSTER") || !service.contains("Blocks.TORCH") || !mailbox.contains("MAX_PROCESSED_TRANSACTIONS = 128") || !chest.contains("REFRESH_TICKS = 12_000L") || !chest.contains("ordinal == 3") - || !chest.contains("MIN_BOOKS_PER_REFRESH = 1") - || !chest.contains("MAX_BOOKS_PER_REFRESH = 3") || !chest.contains("Items.BOOK") || !architecture.contains("PLAYABLE_RADIUS = 2_000") || !architecture.contains("BackroomMaterialApi.anomalyMaterial()") - || !architecture.contains("placeLootLandmark") || !architecture.contains("Blocks.BOOKSHELF") + || !architecture.contains("placeLootLandmark") || !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("LOOT_CHEST_CELL_SIZE_CHUNKS = 3") || !layout.contains("lootChestChunk") - || !layout.contains("EXIT_BED_CELL_SIZE_CHUNKS = 10") + || !layout.contains("EXIT_BED_CELL_SIZE_CHUNKS = 3") || !layout.contains("exitBedChunk") || !layout.contains("exitBedFloor") || !materialApi.contains("registerAnomalyMaterial") || locales.any { !it.containsKey("dimension.sanctuary.backroom") diff --git a/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java b/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java index 4c54f3c..c832355 100644 --- a/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java +++ b/sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/backroom/BackroomChestService.java @@ -19,8 +19,6 @@ import net.minecraft.world.level.block.state.properties.ChestType; /** Renewable loot nodes backed by the non-duplicating real-item registry. */ public final class BackroomChestService { public static final long REFRESH_TICKS = 12_000L; - public static final int MIN_BOOKS_PER_REFRESH = 1; - public static final int MAX_BOOKS_PER_REFRESH = 3; private BackroomChestService() {} @@ -65,7 +63,6 @@ public final class BackroomChestService { private static void rollGeneralLoot(ServerLevel level, ChestGroup group, BackroomData data, List assigned, long cycle) { RandomSource random = RandomSource.create(level.getSeed() ^ group.anchor ^ cycle * 0x9E3779B97F4A7C15L); - insert(group, random, Items.BOOK, MIN_BOOKS_PER_REFRESH, MAX_BOOKS_PER_REFRESH); int roll = random.nextInt(100); if (roll < 55) return; if (roll < 74) { 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 50d4cd6..96cd0e1 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 @@ -439,12 +439,9 @@ public final class BackroomArchitectureFeature extends Feature 17_500 && secondHits < 18_500, "Second-chest personal chance drifted from 90%"); require(laterHits > 12_500 && laterHits < 13_500, "Later personal chance drifted from 65%"); require(BackroomChestService.REFRESH_TICKS == 12_000L, "Chest renewal is no longer twice per Minecraft day"); - require(BackroomChestService.MIN_BOOKS_PER_REFRESH == 1 - && BackroomChestService.MAX_BOOKS_PER_REFRESH == 3, - "Renewable Backroom chests no longer guarantee one to three books"); } private static void recentLossesRemainPersonal() { @@ -134,6 +131,7 @@ public final class BackroomModelSmoke { private static void exitBedsCoverEveryLevel() { long seed = 26_200_133L; int cellSize = BackroomLayout.EXIT_BED_CELL_SIZE_CHUNKS; + require(cellSize == 3, "Backroom exit beds are no longer spaced three chunks apart"); for (BackroomLevel level : BackroomLevel.values()) { int floorY = BackroomLayout.exitBedFloor(level); require(BackroomLayout.levelAt(floorY) == level, @@ -146,7 +144,7 @@ public final class BackroomModelSmoke { } } require(candidates == 1, - "A Backroom level lost its single rare exit bed in a generation cell: " + level); + "A Backroom level lost its exit bed in a three-by-three chunk cell: " + level); } } } -- 2.54.0