Compare commits

..
Author SHA1 Message Date
koka fe491c0ebd chore(anotherworld): version safe vault fix
Verification 26.2 / check (pull_request) Canceled after 0s
2026-08-27 16:09:04 +02:00
koka 64b54c9b44 Merge remote-tracking branch 'origin/main' into feature/safe-vault-interface 2026-08-27 16:06:04 +02:00
koka 6b01d8f2f1 fix(anotherworld): finish safe vault formation 2026-08-27 16:03:59 +02:00
koka fd9fd1435b Merge pull request 'release: Sanctuary 26.2.0-alpha.203' (#20) from release/26.2.0-alpha.203 into main
Verification 26.2 / check (push) Canceled after 0s
Reviewed-on: koka/sanctuary#20
2026-08-27 13:23:35 +00:00
12 changed files with 104 additions and 13 deletions
+9
View File
@@ -6,6 +6,15 @@ 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.
## En développement — correction finale du Safe Block
Module modifié : **Another World `0.0.0-alpha.52`**. Le pack distribué reste en **`26.2.0-alpha.203`**.
- charge la texture 16×16 du Safe Block depuis l’atlas de blocs afin de supprimer la texture manquante avant formation ;
- refuse explicitement les lignes horizontales ou verticales de 3 × 1 et n’active le CTM 48×48 qu’après validation des neuf blocs du mur 3 × 3 ;
- décale le panneau d’inventaire étendu sous les trois lignes monétaires afin de rendre l’émeraude visible et laisse Sanctuary afficher un seul libellé d’inventaire ;
- conserve les données v3, le protocole 1, les IDs et les soldes existants sans migration de sauvegarde.
## `26.2.0-alpha.203`
Module modifié : **Another World `0.0.0-alpha.51`**. Les neuf autres modules conservent leur version issue de l’alpha.202.
+1 -1
View File
@@ -22,7 +22,7 @@ Licence : **GNU GPL 3.0 or Later** (`GPL-3.0-or-later`)
Les descriptions FR/EN/RU sont déclarées dans chaque `fabric.mod.json` et dans les fichiers de langue. Les images fournies servent d'icônes Fabric de leur module.
Version courante du pack local : **`26.2.0-alpha.203`**. Another World passe en **`0.0.0-alpha.51`** ; les neuf autres modules conservent leur version de l’alpha.202.
Version courante du pack distribué : **`26.2.0-alpha.203`**. Dans le workspace, le correctif du Safe Block porte Another World en développement à **`0.0.0-alpha.52`** sans produire une nouvelle version du pack.
L’alpha.203 porte Another World en **`0.0.0-alpha.51`** et JEI en **`30.27.0.187`**. Le Safe Block forme désormais un mur vertical exact de 3 × 3 : ses blocs restent des cubes individuels avant validation, puis les neuf segments composent les textures connectées 48×48. Son interface affiche trois soldes centrés — rubis, saphirs et émeraudes — avec les transferts serveur `− ×64`, `− ×1`, `+ ×1` et `+ ×64`.
+3 -3
View File
@@ -194,7 +194,7 @@ tasks.register("generateAnotherWorldResources") {
}
writeJson("assets/anotherworld/blockstates/safe_block.json", [multipart: safeMultipart])
writeJson("assets/anotherworld/models/block/safe_block_unformed.json", [
parent: "minecraft:block/cube_all", textures: [all: "anotherworld:item/safe_block"]
parent: "minecraft:block/cube_all", textures: [all: "anotherworld:block/safe_block"]
])
def third = 16.0D / 3.0D
def segmentUv = { int column, int row ->
@@ -1938,7 +1938,7 @@ tasks.register("verifyAnotherWorldCatalog") {
"src/main/resources/assets/redstoner/textures/item/weather_gauge.png",
"src/main/resources/data/redstoner/recipe/weather_gauge.json"
]
if (project.version.toString() != "0.0.0-alpha.51"
if (project.version.toString() != "0.0.0-alpha.52"
|| sulfurMigration.target?.modules?.anotherworld != "0.0.0-alpha.44"
|| sulfurMigration.sulfur_caves?.sanctuary?.dripstone_cell_period != 2
|| !javaText.contains('Identifier.parse("sanctuary:sulfur_caves")')
@@ -3255,7 +3255,7 @@ tasks.register("verifyClimateBiomeMixer") {
"pack/migrations/26.2.0-alpha.188-beta-climate-provinces-to-alpha.189.json"))
def mixer = file(
"src/main/java/fr/koka99cab/sanctuary26/anotherworld/mixin/MultiNoiseBiomeSourceParameterListPresetMixin.java").text
if (project.version.toString() != "0.0.0-alpha.51"
if (project.version.toString() != "0.0.0-alpha.52"
|| migration.source?.pack_version != "26.2.0-alpha.188"
|| migration.target?.pack_version != "26.2.0-alpha.189"
|| migration.target?.modules?.anotherworld != "0.0.0-alpha.48"
@@ -30,7 +30,6 @@ public final class SafeVaultScreen extends AbstractContainerScreen<SafeVaultMenu
protected void init() {
super.init();
titleLabelX = (imageWidth - font.width(title)) / 2;
inventoryLabelY = 72;
for (int currency = 0; currency < VaultRules.CURRENCY_SLOTS; currency++) {
int y = topPos + FIRST_ROW_Y + currency * ROW_HEIGHT;
for (int action = 0; action < VaultRules.BUTTONS_PER_CURRENCY; action++) {
@@ -20,6 +20,7 @@ import net.minecraft.world.item.Items;
/** Server-authoritative three-currency vault controls backed by the existing saved account. */
public final class SafeVaultMenu extends AbstractContainerMenu {
private static final int PLAYER_INVENTORY_Y = 108;
private static final List<Item> CURRENCIES = List.of(
AnotherWorldItems.RUBY,
AnotherWorldItems.SAPPHIRE,
@@ -52,7 +53,8 @@ public final class SafeVaultMenu extends AbstractContainerMenu {
this.serverLevel = serverLevel;
this.center = center;
this.owner = owner;
addStandardInventorySlots(inventory, 8, 84);
// Leave all three currency rows visible above Sanctuary's extended inventory panel.
addStandardInventorySlots(inventory, 8, PLAYER_INVENTORY_Y);
addDataSlots(balances);
}
@@ -5,6 +5,7 @@ public final class VaultRules {
public static final int STRUCTURE_WIDTH = 3;
public static final int STRUCTURE_RADIUS = 1;
public static final int STRUCTURE_BLOCKS = STRUCTURE_WIDTH * STRUCTURE_WIDTH;
public static final int COMPLETE_STRUCTURE_MASK = (1 << STRUCTURE_BLOCKS) - 1;
public static final int STORAGE_SLOTS = 27;
public static final int CURRENCY_SLOTS = 3;
public static final int BUTTONS_PER_CURRENCY = 4;
@@ -25,6 +26,10 @@ public final class VaultRules {
return Math.clamp((int) ((long) Math.max(0, elapsedTicks) * 100L / RAID_DURATION_TICKS), 0, 100);
}
public static boolean isCompleteStructureMask(int partMask) {
return partMask == COMPLETE_STRUCTURE_MASK;
}
public static int buttonCurrency(int buttonId) {
return validButton(buttonId) ? buttonId / BUTTONS_PER_CURRENCY : -1;
}
@@ -41,6 +41,7 @@ public final class VaultStructure {
private static Formed validate(Level level, BlockPos center, Direction facing) {
UUID owner = null;
List<BlockPos> members = new ArrayList<>(VaultRules.STRUCTURE_BLOCKS);
int partMask = 0;
Direction width = facing.getClockWise();
for (int column = 0; column < VaultRules.STRUCTURE_WIDTH; column++) {
for (int row = 0; row < VaultRules.STRUCTURE_WIDTH; row++) {
@@ -52,8 +53,10 @@ public final class VaultStructure {
if (owner == null) owner = blockEntity.owner();
else if (!owner.equals(blockEntity.owner())) return null;
members.add(pos.immutable());
partMask |= 1 << (row * VaultRules.STRUCTURE_WIDTH + column);
}
}
if (!VaultRules.isCompleteStructureMask(partMask)) return null;
// Reject ambiguous 3x4/4x3 walls: a vault is one discrete upright 3x3 structure.
for (int widthOffset = -2; widthOffset <= 2; widthOffset++) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

@@ -7,6 +7,12 @@ public final class VaultRulesSmoke {
public static void main(String[] args) {
require(VaultRules.STRUCTURE_WIDTH == 3, "vault width");
require(VaultRules.STRUCTURE_BLOCKS == 9, "upright vault wall");
require(!VaultRules.isCompleteStructureMask(0b000_000_111),
"horizontal 3x1 must stay unformed");
require(!VaultRules.isCompleteStructureMask(0b001_001_001),
"vertical 3x1 must stay unformed");
require(VaultRules.isCompleteStructureMask(0b111_111_111),
"only all nine parts form the vault");
require(VaultRules.STORAGE_SLOTS == 27, "vault capacity");
require(VaultRules.CURRENCY_SLOTS == 3, "currency controls");
require(VaultPart.at(0, 0) == VaultPart.BOTTOM_LEFT, "bottom-left CTM part");
+36 -6
View File
@@ -3478,7 +3478,7 @@ tasks.register("verifyMirrorLavenderDrawerRelease") {
"redstoner/src/main/java/fr/koka99cab/sanctuary26/redstoner/registry/RedStonerRegistries.java").text
def drawerRecipe = file("redstoner/src/main/resources/data/redstoner/recipe/drawer.json")
if (rootProject.pack_version != "26.2.0-alpha.203"
|| rootProject.anotherworld_version != "0.0.0-alpha.51"
|| rootProject.anotherworld_version != "0.0.0-alpha.52"
|| rootProject.redstoner_version != "0.0.0-alpha.10"
|| release.pack_version != rootProject.pack_version || index.versionId != rootProject.pack_version
|| migration.source?.pack_version != "26.2.0-alpha.191"
@@ -4585,7 +4585,7 @@ tasks.register("verifyWaystoneShopCulinaryAlpha202Release") {
def sanctuaryManifest = new JsonSlurper().parse(file(
"sanctuary/src/main/resources/fabric.mod.json"))
if (rootProject.pack_version != "26.2.0-alpha.203"
|| rootProject.anotherworld_version != "0.0.0-alpha.51"
|| rootProject.anotherworld_version != "0.0.0-alpha.52"
|| rootProject.itsalive_version != "0.0.0-alpha.31"
|| rootProject.iliketomoveit_version != "0.0.0-alpha.14"
|| rootProject.sanctuary_version != "0.0.0-alpha.117"
@@ -4643,17 +4643,20 @@ tasks.register("verifySafeVaultFeature") {
dependsOn ":anotherworld:generateAnotherWorldResources"
inputs.file(file("pack/migrations/anotherworld-safe-vault-data-v2.json"))
inputs.file(file("pack/migrations/anotherworld-safe-vault-data-v3.json"))
inputs.file(file("pack/migrations/anotherworld-safe-vault-fix-alpha52.json"))
inputs.file(file("anotherworld/src/main/resources/fabric.mod.json"))
inputs.file(file("sanctuary/src/main/java/fr/koka99cab/sanctuary26/sanctuary/api/inventory/SanctuaryCurrencyStorage.java"))
inputs.files(fileTree("anotherworld/src/main/java/fr/koka99cab/sanctuary26/anotherworld/vault") { include "*.java" })
inputs.file(file("anotherworld/src/main/java/fr/koka99cab/sanctuary26/anotherworld/block/SafeVaultBlock.java"))
inputs.file(file("anotherworld/src/main/java/fr/koka99cab/sanctuary26/anotherworld/client/SafeVaultScreen.java"))
inputs.files(fileTree("anotherworld/src/main/resources/assets/anotherworld/textures/block/safe_vault") { include "*.png" })
inputs.file(file("anotherworld/src/main/resources/assets/anotherworld/textures/block/safe_block.png"))
inputs.file(file("anotherworld/src/main/resources/assets/anotherworld/textures/item/safe_block.png"))
inputs.file(file("anotherworld/src/main/resources/assets/anotherworld/textures/item/titanium_drill.png"))
doLast {
def migration = new JsonSlurper().parse(file("pack/migrations/anotherworld-safe-vault-data-v2.json"))
def interfaceMigration = new JsonSlurper().parse(file("pack/migrations/anotherworld-safe-vault-data-v3.json"))
def fixMigration = new JsonSlurper().parse(file("pack/migrations/anotherworld-safe-vault-fix-alpha52.json"))
def manifest = new JsonSlurper().parse(file("anotherworld/src/main/resources/fabric.mod.json"))
def rules = file("anotherworld/src/main/java/fr/koka99cab/sanctuary26/anotherworld/vault/VaultRules.java").text
def data = file("anotherworld/src/main/java/fr/koka99cab/sanctuary26/anotherworld/vault/VaultData.java").text
@@ -4666,18 +4669,20 @@ tasks.register("verifySafeVaultFeature") {
def safeRecipe = new JsonSlurper().parse(new File(generated, "data/anotherworld/recipe/safe_block.json"))
def drillRecipe = new JsonSlurper().parse(new File(generated, "data/anotherworld/recipe/titanium_drill.json"))
def safeBlockState = new JsonSlurper().parse(new File(generated, "assets/anotherworld/blockstates/safe_block.json"))
def safeUnformedModel = new JsonSlurper().parse(new File(generated, "assets/anotherworld/models/block/safe_block_unformed.json"))
def safeItemModel = new JsonSlurper().parse(new File(generated, "assets/anotherworld/models/item/safe_block.json"))
def requiredTextures = [
"block/safe_vault/bottom.png": [48, 48], "block/safe_vault/front.png": [48, 48],
"block/safe_vault/side.png": [48, 48], "block/safe_vault/top.png": [48, 48],
"item/safe_block.png": [16, 16], "item/titanium_drill.png": [16, 16]
"block/safe_block.png": [16, 16], "item/safe_block.png": [16, 16],
"item/titanium_drill.png": [16, 16]
]
def invalidTextures = requiredTextures.findAll { path, size ->
def image = javax.imageio.ImageIO.read(file("anotherworld/src/main/resources/assets/anotherworld/textures/${path}"))
image == null || image.width != size[0] || image.height != size[1]
}.keySet()
if (rootProject.pack_version != "26.2.0-alpha.203"
|| rootProject.anotherworld_version != "0.0.0-alpha.51"
|| rootProject.anotherworld_version != "0.0.0-alpha.52"
|| rootProject.sanctuary_version != "0.0.0-alpha.117"
|| migration.schema_version != 1
|| migration.source?.pack_version != "26.2.0-alpha.201"
@@ -4710,21 +4715,46 @@ tasks.register("verifySafeVaultFeature") {
|| interfaceMigration.compatibility?.vault_target_data_version != 2
|| interfaceMigration.compatibility?.saved_currency_balances_preserved != true
|| interfaceMigration.compatibility?.pack_release_updated != true
|| fixMigration.source?.pack_version != "26.2.0-alpha.203"
|| fixMigration.source?.modules != [anotherworld: "0.0.0-alpha.51"]
|| fixMigration.target?.pack_version != "26.2.0-alpha.203"
|| fixMigration.target?.modules != [anotherworld: "0.0.0-alpha.52"]
|| fixMigration.safe_vault_structure_fix?.unformed_block_texture != "anotherworld:block/safe_block"
|| fixMigration.safe_vault_structure_fix?.horizontal_3x1_rejected != true
|| fixMigration.safe_vault_structure_fix?.vertical_3x1_rejected != true
|| fixMigration.safe_vault_structure_fix?.complete_3x3_mask_required != true
|| fixMigration.safe_vault_structure_fix?.connected_texture_parts != 9
|| fixMigration.safe_vault_interface_fix?.currency_slots != 3
|| fixMigration.safe_vault_interface_fix?.emerald_row_visible != true
|| fixMigration.safe_vault_interface_fix?.extended_inventory_starts_below_currency_controls != true
|| fixMigration.safe_vault_interface_fix?.native_inventory_label_suppressed != true
|| fixMigration.compatibility?.anotherworld_data_version != 3
|| fixMigration.compatibility?.vault_data_version != 2
|| fixMigration.compatibility?.anotherworld_network_protocol != 1
|| fixMigration.compatibility?.save_migration_required != false
|| fixMigration.compatibility?.registry_ids_changed != false
|| fixMigration.compatibility?.saved_currency_balances_preserved != true
|| fixMigration.compatibility?.pack_release_updated != false
|| manifest.depends?.sanctuary != ">=0.0.0-alpha.117"
|| manifest.custom?.sanctuary26?.data_version != 3
|| !file("build.gradle").text.contains('implementation project(":sanctuary")')
|| !currencyApi.contains("public interface Provider")
|| !currencyApi.contains("countAdditional") || !currencyApi.contains("removeAdditional")
|| !rules.contains("STRUCTURE_WIDTH = 3") || !rules.contains("CURRENCY_SLOTS = 3")
|| !rules.contains("STRUCTURE_WIDTH = 3") || !rules.contains("COMPLETE_STRUCTURE_MASK")
|| !rules.contains("CURRENCY_SLOTS = 3")
|| !rules.contains("BUTTONS_PER_CURRENCY = 4") || !rules.contains("RAID_DURATION_TICKS = 60 * 20")
|| !rules.contains("RAID_LOOT_PERCENT = 20") || !rules.contains("24L * 60L * 60L * 20L")
|| !data.contains('SAVE_KEY = "safe_vaults"') || !data.contains("DATA_VERSION = 2")
|| !structure.contains("upright 3x3") || !structure.contains(".above(row - VaultRules.STRUCTURE_RADIUS)")
|| !structure.contains("isCompleteStructureMask(partMask)")
|| !block.contains("BooleanProperty FORMED") || !block.contains("EnumProperty<VaultPart> PART")
|| !menu.contains("clickMenuButton") || !menu.contains("SanctuaryPlayerInventoryView.unlockedRows")
|| !menu.contains("PLAYER_INVENTORY_Y = 108")
|| !screen.contains("handleInventoryButtonClick") || !screen.contains('"− ×64", "− ×1", "+ ×1", "+ ×64"')
|| screen.contains("inventoryLabelY =")
|| safeBlockState.multipart?.size() != 37
|| safeBlockState.multipart?.count { it.when?.formed == "true" } != 36
|| safeUnformedModel.textures?.all != "anotherworld:block/safe_block"
|| safeItemModel.parent != "anotherworld:block/safe_block_unformed"
|| safeRecipe.pattern != ["GGG", "GCG", "GGG"]
|| drillRecipe.pattern != ["TTT", "RPR", "FDF"]
@@ -4750,7 +4780,7 @@ tasks.register("verifySafeVaultInterfaceAlpha203Release") {
def packwizIndex = file("pack/packwiz/index.toml").text
def jeiFiles = prism.files.findAll { it.path == "mods/jei-26.2-fabric-30.27.0.187.jar" }
if (rootProject.pack_version != "26.2.0-alpha.203"
|| rootProject.anotherworld_version != "0.0.0-alpha.51"
|| rootProject.anotherworld_version != "0.0.0-alpha.52"
|| migration.source?.pack_version != "26.2.0-alpha.202"
|| migration.source?.modules != [anotherworld: "0.0.0-alpha.50"]
|| migration.target?.pack_version != "26.2.0-alpha.203"
+1 -1
View File
@@ -16,7 +16,7 @@ ambiance_version=0.0.0-alpha.12
ambiance_lifecycle=active
redstoner_version=0.0.0-alpha.10
redstoner_lifecycle=active
anotherworld_version=0.0.0-alpha.51
anotherworld_version=0.0.0-alpha.52
anotherworld_lifecycle=active
itsalive_version=0.0.0-alpha.31
itsalive_lifecycle=active
@@ -0,0 +1,37 @@
{
"schema_version": 1,
"source": {
"pack_version": "26.2.0-alpha.203",
"modules": {
"anotherworld": "0.0.0-alpha.51"
}
},
"target": {
"pack_version": "26.2.0-alpha.203",
"modules": {
"anotherworld": "0.0.0-alpha.52"
}
},
"safe_vault_structure_fix": {
"unformed_block_texture": "anotherworld:block/safe_block",
"horizontal_3x1_rejected": true,
"vertical_3x1_rejected": true,
"complete_3x3_mask_required": true,
"connected_texture_parts": 9
},
"safe_vault_interface_fix": {
"currency_slots": 3,
"emerald_row_visible": true,
"extended_inventory_starts_below_currency_controls": true,
"native_inventory_label_suppressed": true
},
"compatibility": {
"anotherworld_data_version": 3,
"vault_data_version": 2,
"anotherworld_network_protocol": 1,
"save_migration_required": false,
"registry_ids_changed": false,
"saved_currency_balances_preserved": true,
"pack_release_updated": false
}
}