From 114fa96b7c58cab066e8b7514a85a43726d87447 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Sat, 15 Nov 2025 15:41:10 +0100 Subject: [PATCH 1/7] feat: initial 1.21.1 support --- README.md | 2 +- build.gradle.kts | 15 +- common.gradle.kts | 9 +- settings.json | 6 +- .../LifecycledResourceManagerImplMixin.java | 27 ++ .../inventorio/mixin/PlayerEntityMixin.java | 4 +- .../inventorio/mixin/PlayerManagerMixin.java | 9 +- .../mixin/RegistryEntryListCodecMixin.java | 44 ++ .../CraftingScreenHandlerAccessor.java | 9 + .../mixin/client/InGameHudMixinHP.java | 16 +- .../mixin/client/InGameHudMixinLP.java | 24 +- .../optional/bowfix/PlayerEntityMixin.java | 23 +- .../configscreen/GlobalSettingsScreen.kt | 8 +- .../configscreen/PlayerSettingsScreen.kt | 10 +- .../client/control/InventorioKeyHandler.kt | 4 +- .../inventorio/client/ui/InventorioScreen.kt | 7 +- .../inventorio/config/GlobalSettings.kt | 14 +- .../inventorio/config/PlayerSettings.kt | 2 +- .../enchantment/DeepPocketsBookRecipe.kt | 39 +- .../enchantment/DeepPocketsEnchantment.kt | 49 +-- .../inventorio/pack/InventorioResources.kt | 80 ++++ .../inventorio/pack/RuntimeResourcePack.kt | 407 ++++++++++++++++++ .../player/InventorioScreenHandler.kt | 54 ++- .../inventory/PlayerInventoryExtension.kt | 25 +- .../inventory/PlayerInventoryExtraStuff.kt | 11 +- .../inventory/PlayerInventoryInjects.kt | 11 +- .../de/rubixdev/inventorio/slot/ArmorSlot.kt | 58 ++- .../inventorio/util/GeneralConstants.kt | 2 + .../rubixdev/inventorio/util/PlatformApi.kt | 1 + .../rubixdev/inventorio/util/RandomStuff.kt | 63 ++- .../assets/inventorio/lang/de_de.yml | 7 +- .../assets/inventorio/lang/en_us.yml | 5 +- .../assets/inventorio/lang/fr_fr.yml | 1 + .../assets/inventorio/lang/pt_br.yml | 1 + .../inventorio/recipes/deep_pockets_book.json | 3 - .../unlock_deep_pockets_book.json | 18 - src/main/resources/inventorio.mixins.json | 2 + versions/1.20.6-fabric/gradle.properties | 4 +- versions/1.20.6-neoforge/gradle.properties | 6 +- .../gradle.properties | 16 +- versions/1.21.1-fabric/gradle.properties | 30 ++ .../InventorioScreenHandlerMixin.java | 0 .../trinkets/InventorioScreenMixin.java | 0 .../mixin/fabric/trinkets/SlotGroupMixin.java | 0 .../rubixdev/inventorio/InventorioFabric.kt | 9 +- .../inventorio/ScreenTypeProviderFabric.kt | 0 .../integration/ClumpsIntegration.kt | 0 .../integration/ModMenuIntegration.kt | 0 .../InventorioScreenHandlerMixinHelper.kt | 0 .../packet/InventorioNetworkingFabric.kt | 0 .../rubixdev/inventorio/util/PlatformApi.kt | 1 + .../src/main/resources/fabric.mod.json | 0 .../resources/inventorio-fabric.mixins.json | 0 versions/1.21.1-neoforge/gradle.properties | 30 ++ .../curios/CuriosClientPacketsMixin.java | 0 .../CuriosServerPayloadHandlerMixin.java | 0 .../neoforge/curios/HandledScreenMixin.java | 0 .../curios/InventorioScreenHandlerMixin.java | 20 +- .../curios/InventorioScreenMixin.java | 0 .../InventorioScreenMixin_alternative.java | 0 .../rubixdev/inventorio/InventorioNeoForge.kt | 34 +- .../de/rubixdev/inventorio/NeoForgeEvents.kt | 0 .../inventorio/ScreenTypeProviderNeoForge.kt | 3 +- .../integration/ClumpsIntegration.kt | 0 .../integration/CuriosIntegration.kt | 0 .../curios/CustomCosmeticButton.kt | 0 .../integration/curios/CustomCuriosButton.kt | 0 .../integration/curios/CustomPageButton.kt | 0 .../integration/curios/ICuriosContainer.kt | 0 .../integration/curios/ICuriosScreen.kt | 0 .../InventorioScreenHandlerMixinHelper.kt | 1 + .../curios/InventorioScreenMixinHelper.kt | 0 .../packet/InventorioNetworkingNeoForge.kt | 2 +- .../rubixdev/inventorio/util/PlatformApi.kt | 1 + .../resources/META-INF/neoforge.mods.toml | 0 .../resources/inventorio-neoforge.mixins.json | 0 versions/mainProject | 2 +- versions/mappings-neoforge-1.21.1-1.20.6.txt | 2 + 78 files changed, 1063 insertions(+), 168 deletions(-) create mode 100644 src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java create mode 100644 src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java create mode 100644 src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt create mode 100644 src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt delete mode 100644 src/main/resources/data/inventorio/recipes/deep_pockets_book.json delete mode 100644 src/main/resources/data/minecraft/advancements/unlock_deep_pockets_book.json rename versions/{1.20.6-common => 1.21.1-common}/gradle.properties (70%) create mode 100644 versions/1.21.1-fabric/gradle.properties rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenHandlerMixin.java (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenMixin.java (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/SlotGroupMixin.java (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt (93%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderFabric.kt (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/integration/ModMenuIntegration.kt (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/integration/trinkets/InventorioScreenHandlerMixinHelper.kt (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingFabric.kt (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt (69%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/resources/fabric.mod.json (100%) rename versions/{1.20.6-fabric => 1.21.1-fabric}/src/main/resources/inventorio-fabric.mixins.json (100%) create mode 100644 versions/1.21.1-neoforge/gradle.properties rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosClientPacketsMixin.java (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosServerPayloadHandlerMixin.java (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java (86%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin_alternative.java (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt (80%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/NeoForgeEvents.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt (95%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/CuriosIntegration.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCosmeticButton.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCuriosButton.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomPageButton.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosContainer.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosScreen.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt (99%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt (97%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt (69%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/resources/META-INF/neoforge.mods.toml (100%) rename versions/{1.20.6-neoforge => 1.21.1-neoforge}/src/main/resources/inventorio-neoforge.mixins.json (100%) create mode 100644 versions/mappings-neoforge-1.21.1-1.20.6.txt diff --git a/README.md b/README.md index 3eef49b..0a0c476 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This is my vision of the Inventory Update for Minecraft. Of [features](#Features) I believe are in line with Mojang's vision and could be potentially added to the game. -Available for both Fabric and (Neo)Forge. +Available for both Fabric and NeoForge. ## Installation diff --git a/build.gradle.kts b/build.gradle.kts index 039ec8b..87d9000 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -31,13 +31,19 @@ preprocess { // which we would need for strict mappings to work strictExtraMappings = false - val mc12006_common = createNode("1.20.6-common", 1_20_06, "yarn") val mc12006_fabric = createNode("1.20.6-fabric", 1_20_06, "yarn") val mc12006_neoforge = createNode("1.20.6-neoforge", 1_20_06, "yarn") + val mc12101_common = createNode("1.21.1-common", 1_21_01, "yarn") + val mc12101_fabric = createNode("1.21.1-fabric", 1_21_01, "yarn") + val mc12101_neoforge = createNode("1.21.1-neoforge", 1_21_01, "yarn") + // 1.20.6 - mc12006_common.link(mc12006_fabric, null) - mc12006_common.link(mc12006_neoforge, file("versions/mappings-common-neoforge.txt")) + mc12101_fabric.link(mc12006_fabric, null) + mc12101_neoforge.link(mc12006_neoforge, file("versions/mappings-neoforge-1.21.1-1.20.6.txt")) + // 1.21.1 + mc12101_common.link(mc12101_fabric, null) + mc12101_common.link(mc12101_neoforge, file("versions/mappings-common-neoforge.txt")) } spotless { @@ -46,12 +52,13 @@ spotless { "ktlint_standard_no-wildcard-imports" to "disabled", "ktlint_standard_blank-line-before-declaration" to "disabled", "ktlint_standard_spacing-between-declarations-with-annotations" to "disabled", + "ktlint_standard_no-empty-file" to "disabled", // these are replaced by the custom rule set "ktlint_standard_import-ordering" to "disabled", "ktlint_standard_comment-spacing" to "disabled", "ktlint_standard_chain-wrapping" to "disabled", ), - ).customRuleSets(listOf("com.github.RubixDev:ktlint-ruleset-mc-preprocessor:2c5a3687bb")) + ).customRuleSets(listOf("com.github.RubixDev:ktlint-ruleset-mc-preprocessor:54d81aa9b4")) kotlinGradle { target("**/*.gradle.kts") diff --git a/common.gradle.kts b/common.gradle.kts index 828576c..fd56b7e 100644 --- a/common.gradle.kts +++ b/common.gradle.kts @@ -227,7 +227,14 @@ tasks.named("processResources") { // See https://minecraft.wiki/w/Pack_format#List_of_resource_pack_formats val resourcePackVersions = mapOf( - 12006 to 32, + 12006 to "32", + 12101 to "34", + 12103 to "42", + 12104 to "46", + 12105 to "55", + 12106 to "63", + 12108 to "64", + 12110 to "69.0", ) val replaceProperties = mapOf( diff --git a/settings.json b/settings.json index d251a77..0730f19 100644 --- a/settings.json +++ b/settings.json @@ -1,7 +1,9 @@ { "versions": [ - "1.20.6-common", "1.20.6-fabric", - "1.20.6-neoforge" + "1.20.6-neoforge", + "1.21.1-common", + "1.21.1-fabric", + "1.21.1-neoforge" ] } diff --git a/src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java new file mode 100644 index 0000000..6386ea1 --- /dev/null +++ b/src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java @@ -0,0 +1,27 @@ +package de.rubixdev.inventorio.mixin; + +import de.rubixdev.inventorio.pack.InventorioResources; +import net.minecraft.resource.LifecycledResourceManager; +import net.minecraft.resource.LifecycledResourceManagerImpl; +import net.minecraft.resource.ResourcePack; +import net.minecraft.resource.ResourceType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(LifecycledResourceManagerImpl.class) +public abstract class LifecycledResourceManagerImplMixin implements LifecycledResourceManager { + @ModifyVariable(method = "", at = @At("HEAD"), argsOnly = true) + private static List injectRuntimePacks(List packs, ResourceType type) { + var copy = new ArrayList<>(packs); + + if (type == ResourceType.SERVER_DATA) { + copy.add(InventorioResources.PACK); + } + + return copy; + } +} diff --git a/src/main/java/de/rubixdev/inventorio/mixin/PlayerEntityMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/PlayerEntityMixin.java index 4b69393..9744d35 100644 --- a/src/main/java/de/rubixdev/inventorio/mixin/PlayerEntityMixin.java +++ b/src/main/java/de/rubixdev/inventorio/mixin/PlayerEntityMixin.java @@ -61,7 +61,7 @@ private void inventorioDisplayOffhand(EquipmentSlot slot, CallbackInfoReturnable * hands. First, the offhand is attached to the utility belt, rather than a * vanilla slot. Second, a player can swap the main hand and the offhand. */ - @SuppressWarnings({ "unchecked", "MixinExtrasOperationParameters" }) + @SuppressWarnings("unchecked") @WrapOperation( method = "equipStack", at = @At( @@ -102,7 +102,7 @@ private E inventorioEquipOffhand(DefaultedList defaultedList, int index, */ @Inject(method = "equipStack", at = @At(value = "RETURN")) private void inventorioOnEquipArmor(EquipmentSlot slot, ItemStack stack, CallbackInfo ci) { - if (slot.getType() == EquipmentSlot.Type.ARMOR) MixinHelpers + if (slot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) MixinHelpers .withScreenHandler((PlayerEntity) (Object) this, InventorioScreenHandler::updateDeepPocketsCapacity); } diff --git a/src/main/java/de/rubixdev/inventorio/mixin/PlayerManagerMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/PlayerManagerMixin.java index db2bd74..ca086e8 100644 --- a/src/main/java/de/rubixdev/inventorio/mixin/PlayerManagerMixin.java +++ b/src/main/java/de/rubixdev/inventorio/mixin/PlayerManagerMixin.java @@ -12,6 +12,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +//#if MC >= 12101 +import net.minecraft.entity.Entity; +//#endif + @Mixin(PlayerManager.class) public class PlayerManagerMixin { /** @@ -34,9 +38,12 @@ private void inventorioSetPlayerSettings( * server to the client */ @Inject(method = "respawnPlayer", at = @At(value = "RETURN"), require = 0) - private void inventorioSetPlayerSettings( + private void inventorioSetPlayerSettings(/* #if <- hack around formatter */ ServerPlayerEntity oldPlayer, boolean alive, + //#if MC >= 12101 + Entity.RemovalReason removalReason, + //#endif CallbackInfoReturnable cir ) { ServerPlayerEntity newPlayer = cir.getReturnValue(); diff --git a/src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java new file mode 100644 index 0000000..58e7c99 --- /dev/null +++ b/src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java @@ -0,0 +1,44 @@ +package de.rubixdev.inventorio.mixin; + +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import de.rubixdev.inventorio.pack.DummyRegistryEntryList; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.entry.RegistryEntryListCodec; +import net.minecraft.registry.tag.TagKey; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(RegistryEntryListCodec.class) +public abstract class RegistryEntryListCodecMixin implements Codec> { + @Shadow + @Final + private Codec, List>>> entryListStorageCodec; + + @Inject( + method = "encode(Lnet/minecraft/registry/entry/RegistryEntryList;Lcom/mojang/serialization/DynamicOps;Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;", + at = @At("HEAD"), + cancellable = true + ) + public void encodeDummyList( + RegistryEntryList registryEntryList, + DynamicOps dynamicOps, + T object, + CallbackInfoReturnable> cir + ) { + if (registryEntryList instanceof DummyRegistryEntryList) { + cir.setReturnValue( + entryListStorageCodec.encode(registryEntryList.getStorage().mapRight(List::copyOf), dynamicOps, object) + ); + } + } +} diff --git a/src/main/java/de/rubixdev/inventorio/mixin/accessor/CraftingScreenHandlerAccessor.java b/src/main/java/de/rubixdev/inventorio/mixin/accessor/CraftingScreenHandlerAccessor.java index a7a5a6d..cbcd8dc 100644 --- a/src/main/java/de/rubixdev/inventorio/mixin/accessor/CraftingScreenHandlerAccessor.java +++ b/src/main/java/de/rubixdev/inventorio/mixin/accessor/CraftingScreenHandlerAccessor.java @@ -9,6 +9,12 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; +//#if MC >= 12101 +import net.minecraft.recipe.CraftingRecipe; +import net.minecraft.recipe.RecipeEntry; +import org.jetbrains.annotations.Nullable; +//#endif + @Mixin(CraftingScreenHandler.class) public interface CraftingScreenHandlerAccessor { @Invoker("updateResult") @@ -18,5 +24,8 @@ static void updateTheResult( PlayerEntity player, RecipeInputInventory craftingInventory, CraftingResultInventory resultInventory + //#if MC >= 12101 + , @Nullable RecipeEntry recipe + //#endif ) {} } diff --git a/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinHP.java b/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinHP.java index 016d3c8..cbb9c81 100644 --- a/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinHP.java +++ b/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinHP.java @@ -13,15 +13,27 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//#if MC >= 12101 +import net.minecraft.client.render.RenderTickCounter; +//#endif + @Mixin(value = InGameHud.class, priority = 1500) @Environment(EnvType.CLIENT) public class InGameHudMixinHP { /** * This mixin calls the renderer of hotbar addons. Note: this mixin doesn't - * work in (Neo)Forge and is substituted with a (Neo)Forge event. + * work in NeoForge and is substituted with a NeoForge event. */ @Inject(method = "render", at = @At(value = "RETURN")) - private void inventorioRenderHotbarAddons(DrawContext context, float tickDelta, CallbackInfo ci) { + private void inventorioRenderHotbarAddons(/* #if <- hack around formatter */ + DrawContext context, + //#if MC >= 12101 + RenderTickCounter tickCounter, + //#else + //$$ float tickDelta, + //#endif + CallbackInfo ci + ) { HotbarHUDRenderer.INSTANCE.renderHotbarAddons(context); } diff --git a/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinLP.java b/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinLP.java index 4e227d4..4f0c059 100644 --- a/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinLP.java +++ b/src/main/java/de/rubixdev/inventorio/mixin/client/InGameHudMixinLP.java @@ -14,6 +14,10 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//#if MC >= 12101 +import net.minecraft.client.render.RenderTickCounter; +//#endif + @Mixin(value = InGameHud.class, priority = 99) @Environment(EnvType.CLIENT) public class InGameHudMixinLP { @@ -22,12 +26,28 @@ public class InGameHudMixinLP { * is selected. */ @Inject(method = "renderHotbar", at = @At(value = "HEAD"), cancellable = true, require = 0) - private void inventorioRenderSegmentedHotbar(DrawContext context, float tickDelta, CallbackInfo ci) { + private void inventorioRenderSegmentedHotbar(/* #if <- hack around formatter */ + DrawContext context, + //#if MC >= 12101 + RenderTickCounter tickCounter, + //#else + //$$ float tickDelta, + //#endif + CallbackInfo ci + ) { if (HotbarHUDRenderer.INSTANCE.renderSegmentedHotbar(context)) ci.cancel(); } @Inject(method = "renderHotbar", at = @At(value = "RETURN"), require = 0) - private void inventorioRenderFunctionOnlySelector(DrawContext context, float tickDelta, CallbackInfo ci) { + private void inventorioRenderFunctionOnlySelector(/* #if <- hack around formatter */ + DrawContext context, + //#if MC >= 12101 + RenderTickCounter tickCounter, + //#else + //$$ float tickDelta, + //#endif + CallbackInfo ci + ) { HotbarHUDRenderer.INSTANCE.renderFunctionOnlySelector(context); } diff --git a/src/main/java/de/rubixdev/inventorio/mixin/optional/bowfix/PlayerEntityMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/optional/bowfix/PlayerEntityMixin.java index 55245f8..3c269d1 100644 --- a/src/main/java/de/rubixdev/inventorio/mixin/optional/bowfix/PlayerEntityMixin.java +++ b/src/main/java/de/rubixdev/inventorio/mixin/optional/bowfix/PlayerEntityMixin.java @@ -6,22 +6,39 @@ import me.fallenbreath.conditionalmixin.api.annotation.Condition; import me.fallenbreath.conditionalmixin.api.annotation.Restriction; import net.minecraft.enchantment.Enchantments; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @Restriction(require = @Condition(type = Condition.Type.TESTER, tester = BowTester.class)) @Mixin(PlayerEntity.class) -public class PlayerEntityMixin { +public abstract class PlayerEntityMixin extends LivingEntity { + protected PlayerEntityMixin(EntityType entityType, World world) { + super(entityType, world); + } + /** * This fixes a bug that an Infinity Bow requires an arrow to shoot. */ @ModifyExpressionValue( method = "getProjectileType", - at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerAbilities;creativeMode:Z") + at = @At( + value = "FIELD", + target = "Lnet/minecraft/entity/player/PlayerAbilities;creativeMode:Z", + opcode = Opcodes.GETFIELD + ) ) private boolean inventorioFixInfinityBow(boolean original, ItemStack bow) { - return original || RandomStuff.getLevelOn(Enchantments.INFINITY, bow) > 0; + //#if MC >= 12101 + var infinity = RandomStuff.getEnchantment(this, Enchantments.INFINITY); + //#else + //$$ var infinity = Enchantments.INFINITY; + //#endif + return original || RandomStuff.getLevelOn(infinity, bow) > 0; } } diff --git a/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/GlobalSettingsScreen.kt b/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/GlobalSettingsScreen.kt index bc4172c..bcac3cc 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/GlobalSettingsScreen.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/GlobalSettingsScreen.kt @@ -3,7 +3,6 @@ package de.rubixdev.inventorio.client.configscreen import de.rubixdev.inventorio.client.configscreen.PlayerSettingsScreen.addBoolEntry import de.rubixdev.inventorio.client.configscreen.PlayerSettingsScreen.addEnumEntry import de.rubixdev.inventorio.config.GlobalSettings -import de.rubixdev.inventorio.util.PlatformApi import de.rubixdev.inventorio.util.ToolBeltMode import me.shedaniel.clothconfig2.api.ConfigBuilder import net.fabricmc.api.EnvType @@ -35,9 +34,9 @@ object GlobalSettingsScreen { addBoolEntry(category, entryBuilder, GlobalSettings.allowSwappedHands, true, isNotLocal) addBoolEntry(category, entryBuilder, GlobalSettings.allow2x2CraftingGrid, true, isNotLocal) //#if FABRIC - addBoolEntry(category, entryBuilder, GlobalSettings.trinketsIntegration, true, isNotLocal) { PlatformApi.isModLoaded("trinkets") } + addBoolEntry(category, entryBuilder, GlobalSettings.trinketsIntegration, true, isNotLocal) //#elseif NEOFORGE - addBoolEntry(category, entryBuilder, GlobalSettings.curiosIntegration, true, isNotLocal) { PlatformApi.isModLoaded("curios") } + addBoolEntry(category, entryBuilder, GlobalSettings.curiosIntegration, true, isNotLocal) //#endif addEnumEntry(category, entryBuilder, GlobalSettings.toolBeltMode, true, isNotLocal, ToolBeltMode::class.java, ToolBeltMode.ENABLED) @@ -45,6 +44,9 @@ object GlobalSettingsScreen { addBoolEntry(category, entryBuilder, GlobalSettings.deepPocketsBookCraft, true, isNotLocal) addBoolEntry(category, entryBuilder, GlobalSettings.deepPocketsInTrades, true, isNotLocal) addBoolEntry(category, entryBuilder, GlobalSettings.deepPocketsInRandomSelection, true, isNotLocal) + //#if MC >= 12101 + addBoolEntry(category, entryBuilder, GlobalSettings.deepPocketsInEnchantingTable, true, isNotLocal) + //#endif return builder.build() } diff --git a/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/PlayerSettingsScreen.kt b/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/PlayerSettingsScreen.kt index 309f41b..7d8e4ac 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/PlayerSettingsScreen.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/client/configscreen/PlayerSettingsScreen.kt @@ -55,7 +55,15 @@ object PlayerSettingsScreen { } @Suppress("UNCHECKED_CAST") - fun > addEnumEntry(category: ConfigCategory, entryBuilder: ConfigEntryBuilder, settingsEntry: SettingsEntry, requireRestart: Boolean, blocked: Boolean, enumClass: Class, defaultValue: T) { + fun > addEnumEntry( + category: ConfigCategory, + entryBuilder: ConfigEntryBuilder, + settingsEntry: SettingsEntry, + requireRestart: Boolean, + blocked: Boolean, + enumClass: Class, + defaultValue: T, + ) { if (blocked) { category.addEntry( entryBuilder diff --git a/src/main/kotlin/de/rubixdev/inventorio/client/control/InventorioKeyHandler.kt b/src/main/kotlin/de/rubixdev/inventorio/client/control/InventorioKeyHandler.kt index f53afb9..c4dcb08 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/client/control/InventorioKeyHandler.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/client/control/InventorioKeyHandler.kt @@ -23,8 +23,8 @@ object InventorioKeyHandler { // Some items which can be used as a tool (e.g. trident) would REPLACE a selected hotbar stack upon use. // But something like VANILLA axes and shovels work fine. // Some modded stuff breaks it tho. - var useMainHand = canRMBItem(player.getStackInHand(Hand.MAIN_HAND)) - var useOffHand = canRMBItem(player.getStackInHand(Hand.OFF_HAND)) + var useMainHand = canRMBItem(player.getStackInHand(Hand.MAIN_HAND), player.registryManager) + var useOffHand = canRMBItem(player.getStackInHand(Hand.OFF_HAND), player.registryManager) if (PlayerInventoryAddon.Client.triesToUseUtility) { useMainHand = false diff --git a/src/main/kotlin/de/rubixdev/inventorio/client/ui/InventorioScreen.kt b/src/main/kotlin/de/rubixdev/inventorio/client/ui/InventorioScreen.kt index a229acc..3a188ca 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/client/ui/InventorioScreen.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/client/ui/InventorioScreen.kt @@ -35,7 +35,12 @@ import net.minecraft.util.Identifier @Environment(EnvType.CLIENT) class InventorioScreen(handler: InventorioScreenHandler, internal val inventory: PlayerInventory) : - AbstractInventoryScreen(handler, inventory, Text.translatable("container.crafting")), RecipeBookProvider { + AbstractInventoryScreen( + handler, + inventory, + Text.translatable("container.crafting"), + ), + RecipeBookProvider { private var mouseX = 0f private var mouseY = 0f private val recipeBook = RecipeBookWidget() diff --git a/src/main/kotlin/de/rubixdev/inventorio/config/GlobalSettings.kt b/src/main/kotlin/de/rubixdev/inventorio/config/GlobalSettings.kt index 876c70b..ac9a386 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/config/GlobalSettings.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/config/GlobalSettings.kt @@ -82,6 +82,14 @@ object GlobalSettings : AbstractSettings() { "inventorio.settings.global.deep_pockets_in_random_selection", ) + //#if MC >= 12101 + @JvmField val deepPocketsInEnchantingTable = SettingsEntryBoolean( + true, + "DeepPocketsInEnchantingTable", + "inventorio.settings.global.deep_pockets_in_enchanting_table", + ) + //#endif + init { entries = listOf( expandedEnderChest, @@ -100,13 +108,15 @@ object GlobalSettings : AbstractSettings() { deepPocketsBookCraft, deepPocketsInTrades, deepPocketsInRandomSelection, + //#if MC >= 12101 + deepPocketsInEnchantingTable, + //#endif ) load(File(".").resolve("config/inventorio_shared.json")) } - @Suppress("unused") // used in non-common package fun syncFromServer(newSettingsJson: JsonObject) { - if (GlobalSettings.anyChanges(newSettingsJson)) { + if (anyChanges(newSettingsJson)) { MinecraftClient.getInstance()?.setScreen(GlobalSettingsSyncPrompt.get(newSettingsJson)) } } diff --git a/src/main/kotlin/de/rubixdev/inventorio/config/PlayerSettings.kt b/src/main/kotlin/de/rubixdev/inventorio/config/PlayerSettings.kt index a586315..ef7d86e 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/config/PlayerSettings.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/config/PlayerSettings.kt @@ -86,7 +86,7 @@ object PlayerSettings : AbstractSettings() { @JvmField val centeredScreen = SettingsEntryBoolean( - false, + true, "CenteredScreen", "inventorio.settings.player.centered_screen", "inventorio.settings.player.centered_screen.tooltip", diff --git a/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt b/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt index 9e770db..9441c1a 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt @@ -2,7 +2,6 @@ package de.rubixdev.inventorio.enchantment import de.rubixdev.inventorio.config.GlobalSettings import net.minecraft.enchantment.EnchantmentLevelEntry -import net.minecraft.inventory.RecipeInputInventory import net.minecraft.item.EnchantedBookItem import net.minecraft.item.ItemStack import net.minecraft.item.Items @@ -15,16 +14,33 @@ import net.minecraft.registry.RegistryWrapper import net.minecraft.util.collection.DefaultedList import net.minecraft.world.World +//#if MC >= 12101 +import de.rubixdev.inventorio.pack.InventorioResources +import de.rubixdev.inventorio.util.getEnchantment +import net.minecraft.recipe.input.CraftingRecipeInput +//#else +//$$ import net.minecraft.inventory.RecipeInputInventory +//#endif + class DeepPocketsBookRecipe(category: CraftingRecipeCategory) : SpecialCraftingRecipe(category) { - override fun matches(craftingInventory: RecipeInputInventory, world: World): Boolean { + //#if MC >= 12101 + override fun matches(input: CraftingRecipeInput, world: World): Boolean { + //#else + //$$ override fun matches(input: RecipeInputInventory, world: World): Boolean { + //#endif if (!GlobalSettings.deepPocketsBookCraft.boolValue) { return false } var shells = 0 var books = 0 - for (i in 0..= 12101 + for (i in 0..= 12101 + override fun craft(input: CraftingRecipeInput, lookup: RegistryWrapper.WrapperLookup): ItemStack = + EnchantedBookItem.forEnchantment(EnchantmentLevelEntry(lookup.getEnchantment(InventorioResources.DEEP_POCKETS), 1)) + //#else + //$$ override fun craft(inventory: RecipeInputInventory, lookup: RegistryWrapper.WrapperLookup): ItemStack = + //$$ EnchantedBookItem.forEnchantment(EnchantmentLevelEntry(DeepPocketsEnchantment, 1)) + //#endif override fun fits(width: Int, height: Int): Boolean { return width >= 2 && height >= 2 @@ -55,7 +76,11 @@ class DeepPocketsBookRecipe(category: CraftingRecipeCategory) : SpecialCraftingR } override fun getResult(lookup: RegistryWrapper.WrapperLookup): ItemStack = when (GlobalSettings.deepPocketsBookCraft.boolValue) { - true -> EnchantedBookItem.forEnchantment(EnchantmentLevelEntry(DeepPocketsEnchantment, 1)) + //#if MC >= 12101 + true -> EnchantedBookItem.forEnchantment(EnchantmentLevelEntry(lookup.getEnchantment(InventorioResources.DEEP_POCKETS), 1)) + //#else + //$$ true -> EnchantedBookItem.forEnchantment(EnchantmentLevelEntry(DeepPocketsEnchantment, 1)) + //#endif false -> ItemStack.EMPTY } diff --git a/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsEnchantment.kt b/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsEnchantment.kt index 4ac546f..8762107 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsEnchantment.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsEnchantment.kt @@ -1,27 +1,28 @@ package de.rubixdev.inventorio.enchantment -import de.rubixdev.inventorio.config.GlobalSettings -import de.rubixdev.inventorio.util.DEEP_POCKETS_MAX_LEVEL -import net.minecraft.enchantment.Enchantment -import net.minecraft.entity.EquipmentSlot -import net.minecraft.registry.tag.ItemTags +//#if MC < 12101 +//$$ import de.rubixdev.inventorio.config.GlobalSettings +//$$ import de.rubixdev.inventorio.util.DEEP_POCKETS_MAX_LEVEL +//$$ import net.minecraft.enchantment.Enchantment +//$$ import net.minecraft.entity.EquipmentSlot +//$$ import net.minecraft.registry.tag.ItemTags +//#endif -object DeepPocketsEnchantment : Enchantment( - properties( - ItemTags.LEG_ARMOR_ENCHANTABLE, - 5, - DEEP_POCKETS_MAX_LEVEL, - leveledCost(5, 8), - leveledCost(55, 8), - 2, - EquipmentSlot.LEGS, - ), -) { - override fun isAvailableForEnchantedBookOffer(): Boolean { - return GlobalSettings.deepPocketsInTrades.boolValue - } - - override fun isAvailableForRandomSelection(): Boolean { - return GlobalSettings.deepPocketsInRandomSelection.boolValue - } -} +//#if MC < 12101 +//$$ object DeepPocketsEnchantment : Enchantment( +//$$ properties( +//$$ ItemTags.LEG_ARMOR_ENCHANTABLE, +//$$ 5, +//$$ DEEP_POCKETS_MAX_LEVEL, +//$$ leveledCost(5, 8), +//$$ leveledCost(55, 8), +//$$ 2, +//$$ EquipmentSlot.LEGS, +//$$ ), +//$$ ) { +//$$ override fun isAvailableForEnchantedBookOffer(): Boolean = +//$$ GlobalSettings.deepPocketsInTrades.boolValue +//$$ override fun isAvailableForRandomSelection(): Boolean = +//$$ GlobalSettings.deepPocketsInRandomSelection.boolValue +//$$ } +//#endif diff --git a/src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt b/src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt new file mode 100644 index 0000000..b707857 --- /dev/null +++ b/src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt @@ -0,0 +1,80 @@ +package de.rubixdev.inventorio.pack + +import de.rubixdev.inventorio.config.GlobalSettings +import de.rubixdev.inventorio.enchantment.DeepPocketsBookRecipe +import de.rubixdev.inventorio.util.MOD_ID +import de.rubixdev.inventorio.util.PlatformApi +import de.rubixdev.inventorio.util.id +import net.minecraft.advancement.criterion.TickCriterion +import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder +import net.minecraft.text.Text + +//#if MC >= 12101 +import de.rubixdev.inventorio.util.DEEP_POCKETS_MAX_LEVEL +import net.minecraft.component.type.AttributeModifierSlot +import net.minecraft.enchantment.Enchantment +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.tag.EnchantmentTags +import net.minecraft.registry.tag.ItemTags +//#endif + +object InventorioResources { + @JvmField + val PACK = RuntimeResourcePack( + RuntimeResourcePack.createInfo( + "inventorio_runtime".id, + Text.of("Inventorio Runtime Data"), + PlatformApi.modVersion(MOD_ID)!!, + ), + RuntimeResourcePack.createMetadata(Text.of("Runtime generated data used by Inventorio")), + ) + + //#if MC >= 12101 + val DEEP_POCKETS: RegistryKey = PACK.addEnchantment( + "deep_pockets".id, + Enchantment.definition( + DummyRegistryEntryList(ItemTags.LEG_ARMOR_ENCHANTABLE), + 5, + DEEP_POCKETS_MAX_LEVEL, + Enchantment.leveledCost(5, 8), + Enchantment.leveledCost(55, 8), + 2, + AttributeModifierSlot.LEGS, + ), + ) + //#endif + + init { + //#if MC >= 12101 + if (GlobalSettings.deepPocketsInTrades.boolValue + && GlobalSettings.deepPocketsInRandomSelection.boolValue + && GlobalSettings.deepPocketsInEnchantingTable.boolValue + ) { + PACK.addItemsToTag(EnchantmentTags.NON_TREASURE) { add(DEEP_POCKETS) } + } else { + if (GlobalSettings.deepPocketsInTrades.boolValue) { + PACK.addItemsToTag(EnchantmentTags.TRADEABLE) { add(DEEP_POCKETS) } + PACK.addItemsToTag(EnchantmentTags.ON_TRADED_EQUIPMENT) { add(DEEP_POCKETS) } + } + if (GlobalSettings.deepPocketsInRandomSelection.boolValue) { + PACK.addItemsToTag(EnchantmentTags.ON_RANDOM_LOOT) { add(DEEP_POCKETS) } + } + if (GlobalSettings.deepPocketsInEnchantingTable.boolValue) { + PACK.addItemsToTag(EnchantmentTags.IN_ENCHANTING_TABLE) { add(DEEP_POCKETS) } + } + } + //#endif + + if (GlobalSettings.deepPocketsBookCraft.boolValue) { + val deepPocketsRecipe = PACK.addRecipe( + "deep_pockets_book".id, + ComplexRecipeJsonBuilder.create(::DeepPocketsBookRecipe), + ) + PACK.addAdvancement( + "unlock_deep_pockets_book".id(), + PACK.advancementBuilderForRecipe(deepPocketsRecipe) + .criterion("tick", TickCriterion.Conditions.createTick()), + ) + } + } +} diff --git a/src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt b/src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt new file mode 100644 index 0000000..37bb372 --- /dev/null +++ b/src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt @@ -0,0 +1,407 @@ +package de.rubixdev.inventorio.pack + +import com.google.gson.Gson +import com.mojang.datafixers.util.Either +import com.mojang.serialization.Codec +import com.mojang.serialization.JsonOps +import de.rubixdev.inventorio.util.logger +import java.io.InputStream +import java.util.Optional +import java.util.stream.Stream +import net.minecraft.SharedConstants +import net.minecraft.advancement.Advancement +import net.minecraft.advancement.AdvancementEntry +import net.minecraft.advancement.AdvancementRequirements +import net.minecraft.advancement.AdvancementRewards +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion +import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder +import net.minecraft.data.server.recipe.RecipeExporter +import net.minecraft.data.server.recipe.SmithingTransformRecipeJsonBuilder +import net.minecraft.data.server.recipe.SmithingTrimRecipeJsonBuilder +import net.minecraft.recipe.Recipe +import net.minecraft.registry.Registry +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.VersionedIdentifier +import net.minecraft.registry.entry.RegistryEntry +import net.minecraft.registry.entry.RegistryEntryList +import net.minecraft.registry.entry.RegistryEntryOwner +import net.minecraft.registry.tag.TagEntry +import net.minecraft.registry.tag.TagFile +import net.minecraft.registry.tag.TagKey +import net.minecraft.resource.InputSupplier +import net.minecraft.resource.ResourcePack +import net.minecraft.resource.ResourcePackInfo +import net.minecraft.resource.ResourcePackSource +import net.minecraft.resource.ResourceType +import net.minecraft.resource.metadata.PackFeatureSetMetadata +import net.minecraft.resource.metadata.PackOverlaysMetadata +import net.minecraft.resource.metadata.PackResourceMetadata +import net.minecraft.resource.metadata.ResourceFilter +import net.minecraft.resource.metadata.ResourceMetadataReader +import net.minecraft.text.Text +import net.minecraft.util.Identifier +import net.minecraft.util.math.random.Random + +//#if NEOFORGE +//$$ import net.neoforged.neoforge.common.conditions.ICondition +//#endif + +//#if MC >= 12101 +import net.minecraft.enchantment.Enchantment +import net.minecraft.registry.RegistryKeys +//#else +//$$ import net.minecraft.registry.tag.TagManagerLoader +//#endif + +private typealias Resource = InputSupplier +private typealias DirectoryMap = MutableMap +private data class ResourceEntry(val resource: Resource) : PackEntry() +private data class DirectoryEntry(val nested: DirectoryMap = mutableMapOf()) : PackEntry() + +private sealed class PackEntry { + fun asResource(): Resource? = (this as? ResourceEntry)?.resource + fun asDirectory(): DirectoryMap? = (this as? DirectoryEntry)?.nested + + fun find(path: List): PackEntry? = + path.fold(this as PackEntry?) { entry, segment -> entry?.asDirectory()?.get(segment) } + + fun findAllResources(path: List = listOf(), consumer: (path: List, resource: Resource) -> Unit): Unit = + asDirectory()?.entries?.forEach { (name, entry) -> + when (entry) { + is ResourceEntry -> consumer(path + name, entry.resource) + is DirectoryEntry -> entry.findAllResources(path + name, consumer) + } + } ?: Unit +} + +class RuntimeResourcePack( + private val info: ResourcePackInfo, + val metadata: PackResourceMetadata, + val features: PackFeatureSetMetadata? = null, + val filter: ResourceFilter? = null, + val overlays: PackOverlaysMetadata? = null, + // TODO: client-only metadata (LanguageResourceMetadata, GuiResourceMetadata, VillagerResourceMetadata, AnimationResourceMetadata, TextureResourceMetadata) + private val extraFiles: Map, InputSupplier> = mapOf(), +) : ResourcePack { + companion object { + private val GSON = Gson() + + //#if MC >= 12101 + private val RegistryKey>.path get() = RegistryKeys.getPath(this).split("/") + private val RegistryKey>.tagPath get() = RegistryKeys.getTagPath(this).split("/") + //#else + //$$ private val RegistryKey>.path get() = value.splitPath + //$$ private val RegistryKey>.tagPath get() = TagManagerLoader.getPath(this).split("/") + //#endif + private val Identifier.splitPath get() = path.split("/") + private val List.withJsonExt get() = dropLast(1) + "${last()}.json" + + val SOURCE = object : ResourcePackSource { + override fun decorate(packDisplayName: Text): Text = + Text.translatable("pack.nameAndSource", packDisplayName, Text.of("Runtime generated")) + override fun canBeEnabledLater(): Boolean = true + } + + fun createInfo(id: Identifier, title: Text, version: String) = ResourcePackInfo( + id.path, + title, + SOURCE, + Optional.of(VersionedIdentifier(id.namespace, id.path, version)), + ) + + fun createMetadata(description: Text, type: ResourceType = ResourceType.SERVER_DATA) = PackResourceMetadata( + description, + SharedConstants.getGameVersion().getResourceVersion(type), + Optional.empty(), + ) + } + + private val root = DirectoryEntry() + + // TODO: is this needed for anything but a pack.png + override fun openRoot(vararg segments: String): InputSupplier? = + extraFiles[segments.toList()] + + override fun open( + type: ResourceType, + id: Identifier, + ): InputSupplier? { + val path = listOf(type.directory, id.namespace) + id.path.split("/") + return root.find(path)?.asResource() + } + + override fun findResources( + type: ResourceType, + namespace: String, + prefix: String, + consumer: ResourcePack.ResultConsumer, + ) { + val basePath = listOf(type.directory, namespace) + prefix.split("/") + root.find(basePath)?.findAllResources { path, resource -> + val id = Identifier.tryParse(namespace, (basePath.drop(2) + path).joinToString("/")) ?: run { + logger.error("Invalid path in pack: {}:{}, ignoring", namespace, path.joinToString("/")) + return@findAllResources + } + consumer.accept(id, resource) + } + } + + override fun getNamespaces(type: ResourceType): Set = + root.nested[type.directory]?.asDirectory()?.keys ?: setOf() + + override fun parseMetadata(metaReader: ResourceMetadataReader): T? = + @Suppress("UNCHECKED_CAST") + when (metaReader.key) { + PackResourceMetadata.SERIALIZER.key -> metadata as T + PackFeatureSetMetadata.SERIALIZER.key -> features as T? + ResourceFilter.SERIALIZER.key -> filter as T? + PackOverlaysMetadata.SERIALIZER.key -> overlays as T? + else -> null + } + + override fun getInfo(): ResourcePackInfo = info + + override fun close() {} + + fun addResource( + type: ResourceType, + registry: RegistryKey>, + codec: Codec, + id: Identifier, + value: T, + ): RegistryKey = RegistryKey.of(registry, id).also { + addResource(type, registry.path, codec, id, value) + } + + fun addResource( + type: ResourceType, + path: List, + codec: Codec, + id: Identifier, + value: T, + ) { + val path = listOf(id.namespace) + path + id.splitPath.withJsonExt + val json = GSON.toJson(codec.encodeStart(JsonOps.INSTANCE, value).getOrThrow()) + logger.debug("adding resource:\n{}\n{}", path.joinToString("/"), json) + addResource(type, path, json) + } + + fun addResource(type: ResourceType, path: List, resource: String) = + addResource(type, path) { resource.byteInputStream() } + + fun addResource(type: ResourceType, path: List, resource: Resource) { + val fullPath = listOf(type.directory) + path + + // ensure directory exists + val dirPath = fullPath.dropLast(1) + val dir = dirPath.fold(root as PackEntry) { entry, segment -> + when (entry) { + is ResourceEntry -> throw IllegalArgumentException("Part of resource path is already stored as a resource") + is DirectoryEntry -> entry.nested.getOrPut(segment, ::DirectoryEntry) + } + }.asDirectory() ?: throw IllegalArgumentException("Part of resource path is already stored as a resource") + + // insert (or overwrite) resource entry + dir[path.last()] = ResourceEntry(resource) + } + + ////// Tags ////// + + inline fun addItemsToTag(tagKey: TagKey, tagBuilder: TagBuilder.() -> Unit) = + addItemsToTag(tagKey, TagBuilder().apply(tagBuilder)) + + fun addItemsToTag(tagKey: TagKey, tagBuilder: TagBuilder) = + addItemsToTag(tagKey, tagBuilder.build()) + + fun addItemsToTag(tagKey: TagKey, tagEntries: List, replace: Boolean = false) = + addItemsToTag(tagKey, TagFile(tagEntries, replace)) + + fun addItemsToTag(tagKey: TagKey, tagFile: TagFile): TagKey { + val path = mutableListOf().apply { + add(tagKey.id.namespace) + addAll(tagKey.registry.tagPath) + addAll(tagKey.id.splitPath.withJsonExt) + } + val json = GSON.toJson(TagFile.CODEC.encodeStart(JsonOps.INSTANCE, tagFile).getOrThrow()) + logger.debug("adding tag:\n{}\n{}", path.joinToString("/"), json) + addResource(ResourceType.SERVER_DATA, path, json) + return tagKey + } + + ////// Enchantments ////// + + //#if MC >= 12101 + fun addEnchantment(id: Identifier, enchantment: Enchantment.Definition) = + addEnchantment(id, Enchantment.builder(enchantment)) + + fun addEnchantment(id: Identifier, enchantment: Enchantment.Builder) = + addEnchantment(id, enchantment.build(id)) + + fun addEnchantment(id: Identifier, enchantment: Enchantment) = + addResource(ResourceType.SERVER_DATA, RegistryKeys.ENCHANTMENT, Enchantment.CODEC, id, enchantment) + //#endif + + ////// Recipes and Advancements ////// + + fun addRecipe(id: Identifier, recipe: Recipe<*>) = + //#if MC >= 12101 + addResource(ResourceType.SERVER_DATA, RegistryKeys.RECIPE, Recipe.CODEC, id, recipe) + //#else + //$$ addResource(ResourceType.SERVER_DATA, listOf("recipes"), Recipe.CODEC, id, recipe) + //#endif + + fun addAdvancement(id: Identifier, advancementBuilder: Advancement.Builder) = + addAdvancement(advancementBuilder.build(id)) + + fun addAdvancement(entry: AdvancementEntry) = + addAdvancement(entry.id, entry.value) + + fun addAdvancement(id: Identifier, advancement: Advancement) = + //#if MC >= 12101 + addResource(ResourceType.SERVER_DATA, RegistryKeys.ADVANCEMENT, Advancement.CODEC, id, advancement) + //#else + //$$ addResource(ResourceType.SERVER_DATA, listOf("advancements"), Advancement.CODEC, id, advancement) + //#endif + + val recipeExporter by lazy { + object : RecipeExporter { + override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?) { + addRecipe(recipeId, recipe) + if (advancement != null) addAdvancement(advancement) + } + + override fun getAdvancementBuilder(): Advancement.Builder = + Advancement.Builder.createUntelemetered().parent(AdvancementEntry(CraftingRecipeJsonBuilder.ROOT, null)) + + //#if NEOFORGE + //$$ override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?, vararg conditions: ICondition) = + //$$ accept(recipeId, recipe, advancement) + //#endif + } + } + + val recipeExporterOnlyRecipe by lazy { + object : RecipeExporter { + override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?) { + addRecipe(recipeId, recipe) + } + + override fun getAdvancementBuilder(): Advancement.Builder = Advancement.Builder.createUntelemetered() + + //#if NEOFORGE + //$$ override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?, vararg conditions: ICondition) = + //$$ accept(recipeId, recipe, advancement) + //#endif + } + } + + val recipeExporterOnlyAdvancement by lazy { + object : RecipeExporter { + override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?) { + if (advancement != null) addAdvancement(advancement) + } + + override fun getAdvancementBuilder(): Advancement.Builder = + Advancement.Builder.createUntelemetered().parent(AdvancementEntry(CraftingRecipeJsonBuilder.ROOT, null)) + + //#if NEOFORGE + //$$ override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?, vararg conditions: ICondition) = + //$$ accept(recipeId, recipe, advancement) + //#endif + } + } + + fun addRecipeAndAdvancement(recipeId: Identifier, builder: CraftingRecipeJsonBuilder) = + builder.offerTo(recipeExporter, recipeId) + + fun addRecipeAndAdvancement(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder) = + builder.offerTo(recipeExporter, recipeId) + + fun addRecipeAndAdvancement(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder) = + builder.offerTo(recipeExporter, recipeId) + + fun addRecipeAndAdvancement(recipeId: Identifier, builder: ComplexRecipeJsonBuilder) = + builder.offerTo(recipeExporter, recipeId) + + //#if MC >= 12101 + fun addRecipe(recipeId: Identifier, builder: CraftingRecipeJsonBuilder): RegistryKey> = + builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } + + fun addRecipe(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder): RegistryKey> = + builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } + + fun addRecipe(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder): RegistryKey> = + builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } + + fun addRecipe(recipeId: Identifier, builder: ComplexRecipeJsonBuilder): RegistryKey> = + builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } + //#else + //$$ fun addRecipe(recipeId: Identifier, builder: CraftingRecipeJsonBuilder) = + //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } + //$$ + //$$ fun addRecipe(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder) = + //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } + //$$ + //$$ fun addRecipe(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder) = + //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } + //$$ + //$$ fun addRecipe(recipeId: Identifier, builder: ComplexRecipeJsonBuilder) = + //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } + //#endif + + fun addAdvancement(recipeId: Identifier, builder: CraftingRecipeJsonBuilder) = + builder.offerTo(recipeExporterOnlyAdvancement, recipeId) + + fun addAdvancement(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder) = + builder.offerTo(recipeExporterOnlyAdvancement, recipeId) + + fun addAdvancement(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder) = + builder.offerTo(recipeExporterOnlyAdvancement, recipeId) + + fun addAdvancement(recipeId: Identifier, builder: ComplexRecipeJsonBuilder) = + builder.offerTo(recipeExporterOnlyAdvancement, recipeId) + + fun advancementBuilderForRecipe(recipe: RegistryKey>): Advancement.Builder = + advancementBuilderForRecipe(recipe.value) + + fun advancementBuilderForRecipe(recipeId: Identifier): Advancement.Builder = + recipeExporterOnlyAdvancement.advancementBuilder + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(recipeId)) + .rewards(AdvancementRewards.Builder.recipe(recipeId)) + .criteriaMerger(AdvancementRequirements.CriterionMerger.OR) +} + +class TagBuilder { + private val builder = net.minecraft.registry.tag.TagBuilder() + private var replace = false + + fun setReplace(replace: Boolean) = also { this.replace = replace } + + fun add(entry: TagEntry) = also { builder.add(entry) } + fun add(id: Identifier) = also { builder.add(id) } + fun add(key: RegistryKey) = also { builder.add(key.value) } + + fun addOptional(id: Identifier) = also { builder.addOptional(id) } + fun addOptional(key: RegistryKey) = also { builder.addOptional(key.value) } + + fun addTag(id: Identifier) = also { builder.addTag(id) } + fun addTag(key: TagKey) = also { builder.addTag(key.id) } + + fun addOptionalTag(id: Identifier) = also { builder.addOptionalTag(id) } + fun addOptionalTag(key: TagKey) = also { builder.addOptionalTag(key.id) } + + fun build() = TagFile(builder.build(), replace) +} + +class DummyRegistryEntryList(val tag: TagKey) : RegistryEntryList { + override fun stream(): Stream> = Stream.empty() + override fun size(): Int = 0 + override fun getStorage(): Either, List>> = Either.left(tag) + override fun getRandom(random: Random): Optional> = Optional.empty() + override fun get(index: Int): RegistryEntry? = null + override fun contains(entry: RegistryEntry): Boolean = false + override fun ownerEquals(owner: RegistryEntryOwner): Boolean = true + override fun getTagKey(): Optional> = Optional.of(tag) + override fun iterator(): MutableIterator> = mutableListOf>().iterator() +} diff --git a/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt b/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt index c660503..77d8c96 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt @@ -18,14 +18,12 @@ import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.minecraft.client.MinecraftClient import net.minecraft.entity.EquipmentSlot -import net.minecraft.entity.mob.MobEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.CraftingInventory import net.minecraft.inventory.CraftingResultInventory import net.minecraft.inventory.Inventory import net.minecraft.item.ItemStack -import net.minecraft.recipe.Recipe import net.minecraft.recipe.RecipeEntry import net.minecraft.recipe.RecipeMatcher import net.minecraft.recipe.book.RecipeBookCategory @@ -37,8 +35,21 @@ import net.minecraft.screen.slot.SlotActionType import net.minecraft.text.Text import net.minecraft.util.Identifier +//#if MC >= 12101 +import net.minecraft.recipe.CraftingRecipe +import net.minecraft.recipe.input.CraftingRecipeInput +//#else +//$$ import net.minecraft.entity.mob.MobEntity +//$$ import net.minecraft.recipe.Recipe +//#endif + class InventorioScreenHandler(syncId: Int, val inventory: PlayerInventory) : - AbstractRecipeScreenHandler(ScreenTypeProvider.INSTANCE.getScreenHandlerType(), syncId) { + //#if MC >= 12101 + AbstractRecipeScreenHandler + //#else + //$$ AbstractRecipeScreenHandler + //#endif + (ScreenTypeProvider.INSTANCE.getScreenHandlerType(), syncId) { val inventoryAddon = inventory.player.inventoryAddon!! private val craftingInput = CraftingInventory(this, 2, 2) @@ -61,7 +72,7 @@ class InventorioScreenHandler(syncId: Int, val inventory: PlayerInventory) : // Armor for ((_, relativeIndex) in armorSlotsRange.withRelativeIndex()) - addSlot(ArmorSlot(inventory, 39 - relativeIndex, 8, 8 + relativeIndex * 18, armorSlots[relativeIndex])) + addSlot(ArmorSlot(inventory, inventory.player, armorSlots[relativeIndex], 39 - relativeIndex, 8, 8 + relativeIndex * 18)) // Main Inventory for ((_, relativeIndex) in mainInventoryWithoutHotbarRange.withRelativeIndex()) @@ -123,7 +134,7 @@ class InventorioScreenHandler(syncId: Int, val inventory: PlayerInventory) : val stackDynamic = sourceSlot.stack // fix for #191, issue where "Origins: Classes" copies the crafting result stack each time it is accessed, // so we have to pass the same `stackDynamic` to the inner function instead of re-getting it - val stackStatic = quickMoveInner(sourceIndex, stackDynamic) + val stackStatic = quickMoveInner(player, sourceIndex, stackDynamic) if (stackStatic.isNotEmpty) { if (stackDynamic.isEmpty) { sourceSlot.stack = ItemStack.EMPTY @@ -140,14 +151,19 @@ class InventorioScreenHandler(syncId: Int, val inventory: PlayerInventory) : return stackStatic } - private fun quickMoveInner(sourceIndex: Int, stackDynamic: ItemStack): ItemStack { + private fun quickMoveInner(player: PlayerEntity, sourceIndex: Int, stackDynamic: ItemStack): ItemStack { val stackStatic = stackDynamic.copy() val availableDeepPocketsRange = getAvailableDeepPocketsRange() // First, we want to transfer armor or tools into their respective slots from any other section if (sourceIndex in mainInventoryRange || sourceIndex in availableDeepPocketsRange) { // Try to send an item into the armor slots - if (MobEntity.getPreferredEquipmentSlot(stackStatic).type == EquipmentSlot.Type.ARMOR + if ( + //#if MC >= 12101 + player.getPreferredEquipmentSlot(stackStatic).type == EquipmentSlot.Type.HUMANOID_ARMOR + //#else + //$$ MobEntity.getPreferredEquipmentSlot(stackStatic).type == EquipmentSlot.Type.ARMOR + //#endif && insertItem(stackDynamic, armorSlotsRange) ) { updateDeepPocketsCapacity() @@ -335,15 +351,25 @@ class InventorioScreenHandler(syncId: Int, val inventory: PlayerInventory) : craftingInput.clear() } - override fun matches(recipe: RecipeEntry>?): Boolean { - if (recipe != null) { - return recipe.value.matches(craftingInput, inventory.player.world) - } - return false - } + //#if MC >= 12101 + override fun matches(recipe: RecipeEntry?): Boolean = + recipe?.value?.matches(craftingInput.createRecipeInput(), inventory.player.world) ?: false + //#else + //$$ override fun matches(recipe: RecipeEntry>?): Boolean = + //$$ recipe?.value?.matches(craftingInput, inventory.player.world) ?: false + //#endif override fun onContentChanged(inventory: Inventory) { - CraftingScreenHandlerAccessor.updateTheResult(this, this.inventory.player.world, this.inventory.player, this.craftingInput, this.craftingResult) + CraftingScreenHandlerAccessor.updateTheResult( + this, + this.inventory.player.world, + this.inventory.player, + this.craftingInput, + this.craftingResult, + //#if MC >= 12101 + null, + //#endif + ) } override fun onClosed(player: PlayerEntity) { diff --git a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt index d8f0146..cbe12b6 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt @@ -1,7 +1,6 @@ package de.rubixdev.inventorio.player.inventory import de.rubixdev.inventorio.config.GlobalSettings -import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment import de.rubixdev.inventorio.mixin.accessor.SimpleInventoryAccessor import de.rubixdev.inventorio.packet.InventorioNetworking import de.rubixdev.inventorio.player.PlayerInventoryAddon @@ -18,6 +17,13 @@ import net.minecraft.registry.tag.TagKey import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.collection.DefaultedList +//#if MC >= 12101 +import de.rubixdev.inventorio.pack.InventorioResources +import net.minecraft.component.EnchantmentEffectComponentTypes +//#else +//$$ import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment +//#endif + abstract class PlayerInventoryExtension protected constructor(val player: PlayerEntity) : SimpleInventory(DEEP_POCKETS_MAX_SIZE + UTILITY_BELT_FULL_SIZE + PlayerInventoryAddon.toolBeltTemplates.size) { /** Warning! The length of [toolBelt], and thus [stacks], may differ across play sessions depending on the mods installed @@ -75,7 +81,12 @@ abstract class PlayerInventoryExtension protected constructor(val player: Player fun dropAll() { for ((index, itemStack) in stacks.withIndex()) { - if (!EnchantmentHelper.hasVanishingCurse(itemStack)) { + //#if MC >= 12101 + val shouldDrop = !EnchantmentHelper.hasAnyEnchantmentsWith(itemStack, EnchantmentEffectComponentTypes.PREVENT_EQUIPMENT_DROP) + //#else + //$$ val shouldDrop = !EnchantmentHelper.hasVanishingCurse(itemStack) + //#endif + if (shouldDrop) { player.dropItem(itemStack, true, false) } stacks[index] = ItemStack.EMPTY @@ -178,9 +189,13 @@ abstract class PlayerInventoryExtension protected constructor(val player: Player return getAvailableDeepPocketsRange().last + 1..INVENTORY_ADDON_DEEP_POCKETS_RANGE.last } - fun getDeepPocketsRowCount(): Int { - return EnchantmentHelper.getEquipmentLevel(DeepPocketsEnchantment, player).coerceIn(0, 3) - } + //#if MC >= 12101 + fun getDeepPocketsRowCount(): Int = + EnchantmentHelper.getEquipmentLevel(player.getEnchantment(InventorioResources.DEEP_POCKETS), player).coerceIn(0, 3) + //#else + //$$ fun getDeepPocketsRowCount(): Int = + //$$ EnchantmentHelper.getEquipmentLevel(DeepPocketsEnchantment, player).coerceIn(0, 3) + //#endif protected fun areItemsSimilar(stack1: ItemStack, stack2: ItemStack): Boolean { return stack1.isNotEmpty && ItemStack.areItemsAndComponentsEqual(stack1, stack2) diff --git a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtraStuff.kt b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtraStuff.kt index a49a506..f59bf6e 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtraStuff.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtraStuff.kt @@ -18,6 +18,10 @@ import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.item.ToolItem +//#if MC >= 12101 +import de.rubixdev.inventorio.util.getEnchantment +//#endif + abstract class PlayerInventoryExtraStuff protected constructor(player: PlayerEntity) : PlayerInventoryHandFeatures(player) { /** * Returns the block breaking speed based on the return of [getMostPreferredTool] @@ -46,7 +50,12 @@ abstract class PlayerInventoryExtraStuff protected constructor(player: PlayerEnt } val isGlass = block.block is StainedGlassBlock || block.isOf(Blocks.GLASS) if (isGlass) { - return toolBelt.firstOrNull { Enchantments.SILK_TOUCH.getLevelOn(it) > 0 } ?: ItemStack.EMPTY + //#if MC >= 12101 + val silkTouch = player.getEnchantment(Enchantments.SILK_TOUCH) + //#else + //$$ val silkTouch = Enchantments.SILK_TOUCH + //#endif + return toolBelt.firstOrNull { silkTouch.getLevelOn(it) > 0 } ?: ItemStack.EMPTY } return ItemStack.EMPTY } diff --git a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryInjects.kt b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryInjects.kt index bfd65ef..86b771f 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryInjects.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryInjects.kt @@ -9,11 +9,20 @@ import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.item.RangedWeaponItem +//#if MC >= 12101 +import de.rubixdev.inventorio.util.getEnchantment +//#endif + abstract class PlayerInventoryInjects protected constructor(player: PlayerEntity) : PlayerInventoryExtension(player) { fun mendToolBeltItems(xpAmount: Int): Int { var xpLeft = xpAmount for (itemStack in toolBelt) { - if (itemStack.isNotEmpty && itemStack.isDamaged && Enchantments.MENDING.getLevelOn(itemStack) > 0) { + //#if MC >= 12101 + val mending = player.getEnchantment(Enchantments.MENDING) + //#else + //$$ val mending = Enchantments.MENDING + //#endif + if (itemStack.isNotEmpty && itemStack.isDamaged && mending.getLevelOn(itemStack) > 0) { val damageRestored = min(xpAmount * 2, itemStack.damage) itemStack.damage -= damageRestored xpLeft = xpAmount - damageRestored / 2 diff --git a/src/main/kotlin/de/rubixdev/inventorio/slot/ArmorSlot.kt b/src/main/kotlin/de/rubixdev/inventorio/slot/ArmorSlot.kt index f12d59f..7ed567d 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/slot/ArmorSlot.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/slot/ArmorSlot.kt @@ -3,7 +3,7 @@ package de.rubixdev.inventorio.slot import com.mojang.datafixers.util.Pair import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.EquipmentSlot -import net.minecraft.entity.mob.MobEntity +import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.Inventory import net.minecraft.item.ItemStack @@ -11,30 +11,60 @@ import net.minecraft.screen.PlayerScreenHandler import net.minecraft.screen.slot.Slot import net.minecraft.util.Identifier -class ArmorSlot(inventory: Inventory, index: Int, x: Int, y: Int, private val equipmentSlot: EquipmentSlot) : Slot(inventory, index, x, y) { - override fun getMaxItemCount(): Int { - return 1 - } +//#if MC >= 12101 +import net.minecraft.component.EnchantmentEffectComponentTypes +//#else +//$$ import net.minecraft.entity.mob.MobEntity +//#endif - override fun canInsert(stack: ItemStack): Boolean { - return equipmentSlot == MobEntity.getPreferredEquipmentSlot(stack) +class ArmorSlot( + inventory: Inventory, + private val entity: LivingEntity, + private val equipmentSlot: EquipmentSlot, + index: Int, + x: Int, + y: Int, +) : Slot(inventory, index, x, y) { + //#if MC >= 12101 + override fun setStack(stack: ItemStack?, previousStack: ItemStack?) { + entity.onEquipStack(equipmentSlot, previousStack, stack) + super.setStack(stack, previousStack) + // TODO: update deep pockets? } + //#endif + + override fun getMaxItemCount(): Int = 1 + + override fun canInsert(stack: ItemStack): Boolean = + //#if MC >= 12101 + equipmentSlot == entity.getPreferredEquipmentSlot(stack) + //#else + //$$ equipmentSlot == MobEntity.getPreferredEquipmentSlot(stack) + //#endif override fun canTakeItems(playerEntity: PlayerEntity): Boolean { val itemStack = this.stack - return if (!itemStack.isEmpty && !playerEntity.isCreative && EnchantmentHelper.hasBindingCurse(itemStack)) false else super.canTakeItems(playerEntity) + return !( + !itemStack.isEmpty + && !playerEntity.isCreative + //#if MC >= 12101 + && EnchantmentHelper.hasAnyEnchantmentsWith(itemStack, EnchantmentEffectComponentTypes.PREVENT_ARMOR_CHANGE) + //#else + //$$ && EnchantmentHelper.hasBindingCurse(itemStack) + //#endif + ) && super.canTakeItems(playerEntity) } override fun getBackgroundSprite(): Pair? { - return Pair.of(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, EMPTY_ARMOR_SLOT_TEXTURES[equipmentSlot.entitySlotId]) + return Pair.of(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, EMPTY_ARMOR_SLOT_TEXTURES[equipmentSlot]) } companion object { - private val EMPTY_ARMOR_SLOT_TEXTURES = arrayOf( - PlayerScreenHandler.EMPTY_BOOTS_SLOT_TEXTURE, - PlayerScreenHandler.EMPTY_LEGGINGS_SLOT_TEXTURE, - PlayerScreenHandler.EMPTY_CHESTPLATE_SLOT_TEXTURE, - PlayerScreenHandler.EMPTY_HELMET_SLOT_TEXTURE, + private val EMPTY_ARMOR_SLOT_TEXTURES = mapOf( + EquipmentSlot.FEET to PlayerScreenHandler.EMPTY_BOOTS_SLOT_TEXTURE, + EquipmentSlot.LEGS to PlayerScreenHandler.EMPTY_LEGGINGS_SLOT_TEXTURE, + EquipmentSlot.CHEST to PlayerScreenHandler.EMPTY_CHESTPLATE_SLOT_TEXTURE, + EquipmentSlot.HEAD to PlayerScreenHandler.EMPTY_HELMET_SLOT_TEXTURE, ) } } diff --git a/src/main/kotlin/de/rubixdev/inventorio/util/GeneralConstants.kt b/src/main/kotlin/de/rubixdev/inventorio/util/GeneralConstants.kt index 70df030..a779ce3 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/util/GeneralConstants.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/util/GeneralConstants.kt @@ -2,6 +2,8 @@ package de.rubixdev.inventorio.util +const val MOD_ID = "inventorio" + const val DEEP_POCKETS_MAX_LEVEL = 3 const val VANILLA_ROW_LENGTH = 9 diff --git a/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt b/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt index 8df8257..f461f71 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt @@ -4,4 +4,5 @@ package de.rubixdev.inventorio.util object PlatformApi { fun isModLoaded(modId: String): Boolean = throw IllegalStateException() fun modDisplayname(modId: String): String? = throw IllegalStateException() + fun modVersion(modId: String): String? = throw IllegalStateException() } diff --git a/src/main/kotlin/de/rubixdev/inventorio/util/RandomStuff.kt b/src/main/kotlin/de/rubixdev/inventorio/util/RandomStuff.kt index 773979b..cca6d39 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/util/RandomStuff.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/util/RandomStuff.kt @@ -13,10 +13,20 @@ import net.minecraft.enchantment.Enchantment import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.item.ItemStack import net.minecraft.item.TridentItem +import net.minecraft.registry.DynamicRegistryManager import net.minecraft.screen.ScreenHandler import net.minecraft.util.Identifier import org.apache.logging.log4j.LogManager +//#if MC >= 12101 +import net.minecraft.enchantment.Enchantments +import net.minecraft.entity.Entity +import net.minecraft.registry.RegistryKey +import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.RegistryWrapper +import net.minecraft.registry.entry.RegistryEntry +//#endif + data class Point2I(@JvmField val x: Int, @JvmField val y: Int) data class Point2F(@JvmField val x: Float, @JvmField val y: Float) data class Rectangle(@JvmField val x: Int, @JvmField val y: Int, @JvmField val width: Int, @JvmField val height: Int) @@ -51,20 +61,24 @@ val logger = LogManager.getLogger("Inventorio")!! val ItemStack.isNotEmpty get() = !this.isEmpty -fun canRMBItem(itemStack: ItemStack): Boolean { +fun canRMBItem(itemStack: ItemStack, registries: DynamicRegistryManager): Boolean { return PlayerSettings.canThrowUnloyalTrident.boolValue || itemStack.item !is TridentItem - || EnchantmentHelper.getLoyalty(itemStack) > 0 - || EnchantmentHelper.getRiptide(itemStack) > 0 + //#if MC >= 12101 + || EnchantmentHelper.getLevel(registries.getEnchantment(Enchantments.LOYALTY), itemStack) > 0 + || EnchantmentHelper.getLevel(registries.getEnchantment(Enchantments.RIPTIDE), itemStack) > 0 + //#else + //$$ || EnchantmentHelper.getLoyalty(itemStack) > 0 + //$$ || EnchantmentHelper.getRiptide(itemStack) > 0 + //#endif } -fun Enchantment.getLevelOn(stack: ItemStack): Int { - //#if NEOFORGE - //$$ return stack.getEnchantmentLevel(this) - //#else - return EnchantmentHelper.getLevel(this, stack) - //#endif -} +//#if MC >= 12101 +fun RegistryEntry.getLevelOn(stack: ItemStack): Int = +//#else +//$$ fun Enchantment.getLevelOn(stack: ItemStack): Int = +//#endif + EnchantmentHelper.getLevel(this, stack) fun MutableList.subList(indices: IntRange) = subList(indices.first, indices.last + 1) @@ -80,10 +94,33 @@ class MixinDelegate( } /** Turn this String into an [Identifier] in this mod's namespace */ -val String.id get() = Identifier("inventorio", this) +//#if MC >= 12101 +val String.id get() = Identifier.of(MOD_ID, this)!! +//#else +//$$ val String.id get() = Identifier(MOD_ID, this) +//#endif /** Turn this String into an [Identifier] in the vanilla namespace */ -fun String.id() = Identifier(this) +//#if MC >= 12101 +fun String.id() = Identifier.ofVanilla(this)!! +//#else +//$$ fun String.id() = Identifier(this) +//#endif /** Turn this String into an [Identifier] in the given namespace */ -fun String.id(namespace: String) = Identifier(namespace, this) +//#if MC >= 12101 +fun String.id(namespace: String) = Identifier.of(namespace, this)!! +//#else +//$$ fun String.id(namespace: String) = Identifier(namespace, this) +//#endif + +//#if MC >= 12101 +fun DynamicRegistryManager.getEnchantment(key: RegistryKey) = + get(RegistryKeys.ENCHANTMENT).entryOf(key)!! + +fun RegistryWrapper.WrapperLookup.getEnchantment(key: RegistryKey) = + getWrapperOrThrow(RegistryKeys.ENCHANTMENT).getOrThrow(key)!! + +fun Entity.getEnchantment(key: RegistryKey) = + registryManager.getEnchantment(key) +//#endif diff --git a/src/main/resources/assets/inventorio/lang/de_de.yml b/src/main/resources/assets/inventorio/lang/de_de.yml index d0a906e..0074a83 100644 --- a/src/main/resources/assets/inventorio/lang/de_de.yml +++ b/src/main/resources/assets/inventorio/lang/de_de.yml @@ -67,7 +67,7 @@ inventorio: swapped_hands.disabled.tooltip: |- Weisen Sie die Hotbar der Zweithand und den Utensiliengürtel der Haupthand zu. - §cAktuell deaktiviert in den gloabalen Einstellungen! + §cAktuell deaktiviert in den globalen Einstellungen! global: title: Inventorio (Globale Einstellungen) @@ -117,9 +117,10 @@ inventorio: tool_belt_mode.NO_VANILLA_SLOTS_ONLY: §dNur modifizierte Slots tool_belt_mode.DISABLED: §cNein - deep_pockets_in_trades: '"Tiefe Taschen" Buch bei Villager Handel' + deep_pockets_in_trades: '"Tiefe Taschen" bei Villager Handel' deep_pockets_book_craft: '"Tiefe Taschen" Buch Handwerksrezept' - deep_pockets_in_random_selection: '"Tiefe Taschen" Buch in zufälliger Auswahl' + deep_pockets_in_random_selection: '"Tiefe Taschen" Buch in zufälliger Beute' + deep_pockets_in_enchanting_table: '"Tiefe Taschen" im Zaubertisch' sync_restart_prompt: |- §eWarnung! diff --git a/src/main/resources/assets/inventorio/lang/en_us.yml b/src/main/resources/assets/inventorio/lang/en_us.yml index 8bdc4a0..28ad311 100644 --- a/src/main/resources/assets/inventorio/lang/en_us.yml +++ b/src/main/resources/assets/inventorio/lang/en_us.yml @@ -115,9 +115,10 @@ inventorio: tool_belt_mode.NO_VANILLA_SLOTS_ONLY: §dModded Slots Only tool_belt_mode.DISABLED: §cNo - deep_pockets_in_trades: Deep Pockets Book in Villager Trades + deep_pockets_in_trades: Deep Pockets in Villager Trades deep_pockets_book_craft: Deep Pockets Book Crafting Recipe - deep_pockets_in_random_selection: Deep Pockets Book in Random Selection + deep_pockets_in_random_selection: Deep Pockets Book in Random Loot + deep_pockets_in_enchanting_table: Deep Pockets in Enchanting Table sync_restart_prompt: |- §eWarning! diff --git a/src/main/resources/assets/inventorio/lang/fr_fr.yml b/src/main/resources/assets/inventorio/lang/fr_fr.yml index 87d1da1..46b9901 100644 --- a/src/main/resources/assets/inventorio/lang/fr_fr.yml +++ b/src/main/resources/assets/inventorio/lang/fr_fr.yml @@ -120,6 +120,7 @@ inventorio: deep_pockets_in_trades: Livre enchanté Grandes Poches dans les échanges avec villageois deep_pockets_book_craft: Recette de fabrication pour un Livre enchanté Grandes Poches deep_pockets_in_random_selection: Livre enchanté Grandes Poches dans une sélection aléatoire + # deep_pockets_in_enchanting_table: Deep Pockets in Enchanting Table sync_restart_prompt: |- §eAttention! diff --git a/src/main/resources/assets/inventorio/lang/pt_br.yml b/src/main/resources/assets/inventorio/lang/pt_br.yml index a172d07..c7c2acf 100644 --- a/src/main/resources/assets/inventorio/lang/pt_br.yml +++ b/src/main/resources/assets/inventorio/lang/pt_br.yml @@ -118,6 +118,7 @@ inventorio: deep_pockets_in_trades: Livros encatnados com Bolsos fundos em trocas com aldeões # deep_pockets_book_craft: Deep Pockets Book Crafting Recipe deep_pockets_in_random_selection: Livros encantados com Bolsos fundos em seleções automáticas + # deep_pockets_in_enchanting_table: Deep Pockets in Enchanting Table sync_restart_prompt: |- Atenção! diff --git a/src/main/resources/data/inventorio/recipes/deep_pockets_book.json b/src/main/resources/data/inventorio/recipes/deep_pockets_book.json deleted file mode 100644 index 9ac36e0..0000000 --- a/src/main/resources/data/inventorio/recipes/deep_pockets_book.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "inventorio:deep_pockets_book" -} \ No newline at end of file diff --git a/src/main/resources/data/minecraft/advancements/unlock_deep_pockets_book.json b/src/main/resources/data/minecraft/advancements/unlock_deep_pockets_book.json deleted file mode 100644 index 5bbb926..0000000 --- a/src/main/resources/data/minecraft/advancements/unlock_deep_pockets_book.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "inventorio:deep_pockets_book" - ] - }, - "criteria": { - "exists": { - "trigger": "minecraft:tick" - } - }, - "requirements": [ - [ - "exists" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/inventorio.mixins.json b/src/main/resources/inventorio.mixins.json index e41a481..ba78238 100644 --- a/src/main/resources/inventorio.mixins.json +++ b/src/main/resources/inventorio.mixins.json @@ -6,9 +6,11 @@ "plugin": "de.rubixdev.inventorio.InventorioMixinPlugin", "mixins": [ "ExperienceOrbEntityMixin", + "LifecycledResourceManagerImplMixin", "PlayerEntityMixin", "PlayerInventoryMixin", "PlayerManagerMixin", + "RegistryEntryListCodecMixin", "ServerPlayerEntity_ScreenHandlerSyncHandlerMixin", "ServerPlayNetworkHandlerMixin", "accessor.CraftingScreenHandlerAccessor", diff --git a/versions/1.20.6-fabric/gradle.properties b/versions/1.20.6-fabric/gradle.properties index 755e463..54d3519 100644 --- a/versions/1.20.6-fabric/gradle.properties +++ b/versions/1.20.6-fabric/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings_patch=1.20.6+build.6 game_versions=1.20.5\n1.20.6 -# (Neo)Forge and dependency version ranges +# NeoForge and dependency version ranges minecraft_version_range_fabric=>=1.20.5 minecraft_version_range_forge= neoforge_version= @@ -25,6 +25,6 @@ # https://modrinth.com/mod/trinkets/versions?l=fabric trinkets_version=3.9.0 -# (Neo)Forge Dependencies +# NeoForge Dependencies # https://maven.theillusivec4.top/top/theillusivec4/curios/curios-forge/ curios_version= diff --git a/versions/1.20.6-neoforge/gradle.properties b/versions/1.20.6-neoforge/gradle.properties index f80a540..db17268 100644 --- a/versions/1.20.6-neoforge/gradle.properties +++ b/versions/1.20.6-neoforge/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings_patch=1.20.6+build.6 game_versions=1.20.5\n1.20.6 -# (Neo)Forge and dependency version ranges +# NeoForge and dependency version ranges minecraft_version_range_fabric= minecraft_version_range_forge=[1.20.5,) neoforge_version=20.6.139 @@ -25,6 +25,6 @@ # https://modrinth.com/mod/trinkets/versions?l=fabric trinkets_version= -# (Neo)Forge Dependencies - # https://maven.theillusivec4.top/top/theillusivec4/curios/curios-forge/ +# NeoForge Dependencies + # https://maven.theillusivec4.top/top/theillusivec4/curios/curios-neoforge/ curios_version=8.1.0+1.20.6 diff --git a/versions/1.20.6-common/gradle.properties b/versions/1.21.1-common/gradle.properties similarity index 70% rename from versions/1.20.6-common/gradle.properties rename to versions/1.21.1-common/gradle.properties index 06ea5f1..d8337af 100644 --- a/versions/1.20.6-common/gradle.properties +++ b/versions/1.21.1-common/gradle.properties @@ -1,20 +1,20 @@ # General Properties - minecraft_version=1.20.6 - yarn_mappings=1.20.6+build.3 + minecraft_version=1.21.1 + yarn_mappings=1.21.1+build.3 # https://maven.architectury.dev/dev/architectury/yarn-mappings-patch-neoforge/ - yarn_mappings_patch=1.20.6+build.6 - game_versions=1.20.5\n1.20.6 + yarn_mappings_patch=1.21+build.6 + game_versions=1.21\n1.21.1 -# (Neo)Forge and dependency version ranges +# NeoForge and dependency version ranges minecraft_version_range_fabric= minecraft_version_range_forge= neoforge_version= neoforge_version_range= # Common Dependencies - cloth_version=14.0.139 + cloth_version=15.0.140 # https://modrinth.com/mod/clumps/versions - clumps_version=17.0.0.1-fabric,1.20.6 + clumps_version=19.0.0.1-fabric,1.21.1 # Fabric Dependencies # https://modrinth.com/mod/early-loading-screen/versions @@ -24,6 +24,6 @@ # https://modrinth.com/mod/trinkets/versions?l=fabric trinkets_version= -# (Neo)Forge Dependencies +# NeoForge Dependencies # https://maven.theillusivec4.top/top/theillusivec4/curios/curios-forge/ curios_version= diff --git a/versions/1.21.1-fabric/gradle.properties b/versions/1.21.1-fabric/gradle.properties new file mode 100644 index 0000000..5bfc9f7 --- /dev/null +++ b/versions/1.21.1-fabric/gradle.properties @@ -0,0 +1,30 @@ +# General Properties + loom.platform=fabric + minecraft_version=1.21.1 + yarn_mappings=1.21.1+build.3 + # https://maven.architectury.dev/dev/architectury/yarn-mappings-patch-neoforge/ + yarn_mappings_patch=1.21+build.6 + game_versions=1.21\n1.21.1 + +# NeoForge and dependency version ranges + minecraft_version_range_fabric=>=1.21 + minecraft_version_range_forge= + neoforge_version= + neoforge_version_range= + +# Common Dependencies + cloth_version=15.0.140 + # https://modrinth.com/mod/clumps/versions + clumps_version=19.0.0.1-fabric,1.21.1 + +# Fabric Dependencies + # https://modrinth.com/mod/early-loading-screen/versions + early_loading_screen_version=0.1.5 + fabric_api_version=0.116.7+1.21.1 + modmenu_version=11.0.3 + # https://modrinth.com/mod/trinkets/versions?l=fabric + trinkets_version=3.10.0 + +# NeoForge Dependencies + # https://maven.theillusivec4.top/top/theillusivec4/curios/curios-forge/ + curios_version= diff --git a/versions/1.20.6-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenHandlerMixin.java b/versions/1.21.1-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenHandlerMixin.java similarity index 100% rename from versions/1.20.6-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenHandlerMixin.java rename to versions/1.21.1-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenHandlerMixin.java diff --git a/versions/1.20.6-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenMixin.java b/versions/1.21.1-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenMixin.java similarity index 100% rename from versions/1.20.6-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenMixin.java rename to versions/1.21.1-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/InventorioScreenMixin.java diff --git a/versions/1.20.6-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/SlotGroupMixin.java b/versions/1.21.1-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/SlotGroupMixin.java similarity index 100% rename from versions/1.20.6-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/SlotGroupMixin.java rename to versions/1.21.1-fabric/src/main/java/de/rubixdev/inventorio/mixin/fabric/trinkets/SlotGroupMixin.java diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt similarity index 93% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt index 25f70ba..5079905 100644 --- a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt +++ b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt @@ -5,7 +5,6 @@ import de.rubixdev.inventorio.client.control.InventorioControls import de.rubixdev.inventorio.client.control.InventorioKeyHandler import de.rubixdev.inventorio.config.PlayerSettings import de.rubixdev.inventorio.enchantment.DeepPocketsBookRecipe -import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment import de.rubixdev.inventorio.integration.ClumpsIntegration import de.rubixdev.inventorio.integration.InventorioModIntegration import de.rubixdev.inventorio.integration.ModIntegration @@ -21,13 +20,19 @@ import net.minecraft.recipe.SpecialRecipeSerializer import net.minecraft.registry.Registries import net.minecraft.registry.Registry +//#if MC < 12101 +//$$ import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment +//#endif + open class InventorioFabric : ModInitializer { private val fabricModIntegrations = listOf(ClumpsIntegration) override fun onInitialize() { ScreenTypeProvider.INSTANCE = ScreenTypeProviderFabric InventorioNetworking.INSTANCE = InventorioNetworkingFabric - Registry.register(Registries.ENCHANTMENT, "deep_pockets".id, DeepPocketsEnchantment) + //#if MC < 12101 + //$$ Registry.register(Registries.ENCHANTMENT, "deep_pockets".id, DeepPocketsEnchantment) + //#endif DeepPocketsBookRecipe.SERIALIZER = Registry.register( Registries.RECIPE_SERIALIZER, "deep_pockets_book".id, diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderFabric.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderFabric.kt similarity index 100% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderFabric.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderFabric.kt diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt similarity index 100% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ModMenuIntegration.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ModMenuIntegration.kt similarity index 100% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ModMenuIntegration.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/ModMenuIntegration.kt diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/trinkets/InventorioScreenHandlerMixinHelper.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/trinkets/InventorioScreenHandlerMixinHelper.kt similarity index 100% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/trinkets/InventorioScreenHandlerMixinHelper.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/integration/trinkets/InventorioScreenHandlerMixinHelper.kt diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingFabric.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingFabric.kt similarity index 100% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingFabric.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingFabric.kt diff --git a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt similarity index 69% rename from versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt rename to versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt index 34755aa..7d00977 100644 --- a/versions/1.20.6-fabric/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt +++ b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt @@ -5,4 +5,5 @@ import net.fabricmc.loader.api.FabricLoader object PlatformApi { fun isModLoaded(modId: String): Boolean = FabricLoader.getInstance().isModLoaded(modId) fun modDisplayname(modId: String): String? = FabricLoader.getInstance().getModContainer(modId).orElse(null)?.metadata?.name + fun modVersion(modId: String): String? = FabricLoader.getInstance().getModContainer(modId).orElse(null)?.metadata?.version?.friendlyString } diff --git a/versions/1.20.6-fabric/src/main/resources/fabric.mod.json b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json similarity index 100% rename from versions/1.20.6-fabric/src/main/resources/fabric.mod.json rename to versions/1.21.1-fabric/src/main/resources/fabric.mod.json diff --git a/versions/1.20.6-fabric/src/main/resources/inventorio-fabric.mixins.json b/versions/1.21.1-fabric/src/main/resources/inventorio-fabric.mixins.json similarity index 100% rename from versions/1.20.6-fabric/src/main/resources/inventorio-fabric.mixins.json rename to versions/1.21.1-fabric/src/main/resources/inventorio-fabric.mixins.json diff --git a/versions/1.21.1-neoforge/gradle.properties b/versions/1.21.1-neoforge/gradle.properties new file mode 100644 index 0000000..47bdbb1 --- /dev/null +++ b/versions/1.21.1-neoforge/gradle.properties @@ -0,0 +1,30 @@ +# General Properties + loom.platform=neoforge + minecraft_version=1.21.1 + yarn_mappings=1.21.1+build.3 + # https://maven.architectury.dev/dev/architectury/yarn-mappings-patch-neoforge/ + yarn_mappings_patch=1.21+build.6 + game_versions=1.21\n1.21.1 + +# NeoForge and dependency version ranges + minecraft_version_range_fabric= + minecraft_version_range_forge=[1.21,) + neoforge_version=21.1.215 + neoforge_version_range=[21.1,) + +# Common Dependencies + cloth_version=15.0.140 + # https://modrinth.com/mod/clumps/versions + clumps_version=19.0.0.1-neoforge,1.21.1 + +# Fabric Dependencies + # https://modrinth.com/mod/early-loading-screen/versions + early_loading_screen_version= + fabric_api_version= + modmenu_version= + # https://modrinth.com/mod/trinkets/versions?l=fabric + trinkets_version= + +# NeoForge Dependencies + # https://maven.theillusivec4.top/top/theillusivec4/curios/curios-neoforge/ + curios_version=9.5.1+1.21.1 diff --git a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosClientPacketsMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosClientPacketsMixin.java similarity index 100% rename from versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosClientPacketsMixin.java rename to versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosClientPacketsMixin.java diff --git a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosServerPayloadHandlerMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosServerPayloadHandlerMixin.java similarity index 100% rename from versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosServerPayloadHandlerMixin.java rename to versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/CuriosServerPayloadHandlerMixin.java diff --git a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java similarity index 100% rename from versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java rename to versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java diff --git a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java similarity index 86% rename from versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java rename to versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java index ebe52e9..7c8cc9b 100644 --- a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java +++ b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java @@ -8,7 +8,6 @@ import me.fallenbreath.conditionalmixin.api.annotation.Restriction; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.CraftingInventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.AbstractRecipeScreenHandler; import net.minecraft.screen.ScreenHandlerType; @@ -23,19 +22,34 @@ import java.util.List; +//#if MC > 12101 +import net.minecraft.recipe.CraftingRecipe; +import net.minecraft.recipe.input.CraftingRecipeInput; +//#else +//$$ import net.minecraft.inventory.CraftingInventory; +//#endif + @SuppressWarnings("UnresolvedMixinReference") // the Minecraft Dev plugin // doesn't seem to like Kotlin // target classes @Restriction(require = { @Condition("curios"), @Condition(type = Condition.Type.TESTER, tester = CuriosTester.class) }) @Mixin(InventorioScreenHandler.class) -public abstract class InventorioScreenHandlerMixin extends AbstractRecipeScreenHandler +//#if MC > 12101 +public abstract class InventorioScreenHandlerMixin extends AbstractRecipeScreenHandler +//#else +//$$ public abstract class InventorioScreenHandlerMixin extends AbstractRecipeScreenHandler +//#endif implements ICuriosContainer, ICuriosMenu { public InventorioScreenHandlerMixin(ScreenHandlerType arg, int i) { super(arg, i); } @SuppressWarnings("DataFlowIssue") - @Unique private final InventorioScreenHandler thiz = (InventorioScreenHandler) (AbstractRecipeScreenHandler) this; + //#if MC > 12101 + @Unique private final InventorioScreenHandler thiz = (InventorioScreenHandler) (AbstractRecipeScreenHandler) this; + //#else + //$$ @Unique private final InventorioScreenHandler thiz = (InventorioScreenHandler) (AbstractRecipeScreenHandler) this; + //#endif @Unique private InventorioScreenHandlerMixinHelper helper; diff --git a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java similarity index 100% rename from versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java rename to versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java diff --git a/versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin_alternative.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin_alternative.java similarity index 100% rename from versions/1.20.6-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin_alternative.java rename to versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin_alternative.java diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt similarity index 80% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt index 2773548..02c37d7 100644 --- a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt @@ -5,12 +5,12 @@ import de.rubixdev.inventorio.client.configscreen.PlayerSettingsScreen import de.rubixdev.inventorio.client.control.InventorioControls import de.rubixdev.inventorio.config.PlayerSettings import de.rubixdev.inventorio.enchantment.DeepPocketsBookRecipe -import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment import de.rubixdev.inventorio.integration.ClumpsIntegration import de.rubixdev.inventorio.integration.CuriosIntegration import de.rubixdev.inventorio.integration.InventorioModIntegration import de.rubixdev.inventorio.packet.InventorioNetworking import de.rubixdev.inventorio.packet.InventorioNetworkingNeoForge +import de.rubixdev.inventorio.util.MOD_ID import net.minecraft.client.MinecraftClient import net.minecraft.item.ItemStack import net.minecraft.recipe.SpecialRecipeSerializer @@ -21,13 +21,17 @@ import net.neoforged.fml.common.Mod import net.neoforged.fml.loading.FMLEnvironment import net.neoforged.fml.loading.FMLPaths import net.neoforged.neoforge.client.gui.IConfigScreenFactory +import net.neoforged.neoforge.common.ItemAbilities +import net.neoforged.neoforge.common.ItemAbility import net.neoforged.neoforge.common.NeoForge -import net.neoforged.neoforge.common.ToolAction -import net.neoforged.neoforge.common.ToolActions import net.neoforged.neoforge.registries.DeferredRegister import thedarkcolour.kotlinforforge.neoforge.KotlinModLoadingContext -@Mod("inventorio") +//#if MC < 12101 +//$$ import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment +//#endif + +@Mod(MOD_ID) class InventorioNeoForge { private val neoForgeModIntegrations = listOf(ClumpsIntegration, CuriosIntegration) @@ -35,11 +39,13 @@ class InventorioNeoForge { ScreenTypeProvider.INSTANCE = ScreenTypeProviderNeoForge InventorioNetworking.INSTANCE = InventorioNetworkingNeoForge - val enchantmentRegistry = DeferredRegister.create(Registries.ENCHANTMENT, "inventorio") - enchantmentRegistry.register(KotlinModLoadingContext.get().getKEventBus()) - enchantmentRegistry.register("deep_pockets") { -> DeepPocketsEnchantment } + //#if MC < 12101 + //$$ val enchantmentRegistry = DeferredRegister.create(Registries.ENCHANTMENT, MOD_ID) + //$$ enchantmentRegistry.register(KotlinModLoadingContext.get().getKEventBus()) + //$$ enchantmentRegistry.register("deep_pockets") { -> DeepPocketsEnchantment } + //#endif - val recipeRegistry = DeferredRegister.create(Registries.RECIPE_SERIALIZER, "inventorio") + val recipeRegistry = DeferredRegister.create(Registries.RECIPE_SERIALIZER, MOD_ID) recipeRegistry.register(KotlinModLoadingContext.get().getKEventBus()) val serializer = SpecialRecipeSerializer { category -> DeepPocketsBookRecipe(category) } DeepPocketsBookRecipe.SERIALIZER = serializer @@ -67,22 +73,22 @@ class InventorioNeoForge { // The reason why we do it this way is that we can't guarantee that other mods // won't call [InventorioAPI] BEFORE [InventorioNeoForge#onInitialize] has been invoked InventorioAPI.getToolBeltSlotTemplate(InventorioAPI.SLOT_PICKAXE)?.addAllowingCondition { itemStack, _ -> - testToolType(itemStack, ToolActions.PICKAXE_DIG) + testToolType(itemStack, ItemAbilities.PICKAXE_DIG) } InventorioAPI.getToolBeltSlotTemplate(InventorioAPI.SLOT_SWORD)?.addAllowingCondition { itemStack, _ -> - testToolType(itemStack, ToolActions.SWORD_SWEEP) // todo sword + testToolType(itemStack, ItemAbilities.SWORD_SWEEP) // todo sword } InventorioAPI.getToolBeltSlotTemplate(InventorioAPI.SLOT_AXE)?.addAllowingCondition { itemStack, _ -> - testToolType(itemStack, ToolActions.AXE_DIG) + testToolType(itemStack, ItemAbilities.AXE_DIG) } InventorioAPI.getToolBeltSlotTemplate(InventorioAPI.SLOT_SHOVEL)?.addAllowingCondition { itemStack, _ -> - testToolType(itemStack, ToolActions.SHOVEL_DIG) + testToolType(itemStack, ItemAbilities.SHOVEL_DIG) } InventorioAPI.getToolBeltSlotTemplate(InventorioAPI.SLOT_HOE)?.addAllowingCondition { itemStack, _ -> - testToolType(itemStack, ToolActions.HOE_DIG) + testToolType(itemStack, ItemAbilities.HOE_DIG) } } - private fun testToolType(itemStack: ItemStack, vararg toolActions: ToolAction): Boolean { + private fun testToolType(itemStack: ItemStack, vararg toolActions: ItemAbility): Boolean { return toolActions.any { itemStack.canPerformAction(it) } } } diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/NeoForgeEvents.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/NeoForgeEvents.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/NeoForgeEvents.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/NeoForgeEvents.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt similarity index 95% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt index c96df88..ffb2b12 100644 --- a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/ScreenTypeProviderNeoForge.kt @@ -2,6 +2,7 @@ package de.rubixdev.inventorio import de.rubixdev.inventorio.client.ui.InventorioScreen import de.rubixdev.inventorio.player.InventorioScreenHandler +import de.rubixdev.inventorio.util.MOD_ID import net.minecraft.registry.Registries import net.minecraft.screen.ScreenHandlerType import net.neoforged.bus.api.SubscribeEvent @@ -16,7 +17,7 @@ object ScreenTypeProviderNeoForge : ScreenTypeProvider { } init { - val registry = DeferredRegister.create(Registries.SCREEN_HANDLER, "inventorio") + val registry = DeferredRegister.create(Registries.SCREEN_HANDLER, MOD_ID) registry.register(KotlinModLoadingContext.get().getKEventBus()) registry.register("player_screen") { -> handlerProvider } } diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/ClumpsIntegration.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/CuriosIntegration.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/CuriosIntegration.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/CuriosIntegration.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/CuriosIntegration.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCosmeticButton.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCosmeticButton.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCosmeticButton.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCosmeticButton.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCuriosButton.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCuriosButton.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCuriosButton.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomCuriosButton.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomPageButton.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomPageButton.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomPageButton.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/CustomPageButton.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosContainer.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosContainer.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosContainer.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosContainer.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosScreen.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosScreen.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosScreen.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/ICuriosScreen.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt similarity index 99% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt index 40eceb1..feec618 100644 --- a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt @@ -189,6 +189,7 @@ class InventorioScreenHandlerMixinHelper( fun InventorioScreenHandler.`curios$quickMove`(player: PlayerEntity, sourceIndex: Int, cir: CallbackInfoReturnable) { // TODO: quick move also works while the client has the curios stuff closed, but to fix that I'd have to sync the // open status using custom packets which is a bit too much for just mod compat + // TODO: open curios when quick moving there val slot = slots[sourceIndex] if (slot.hasStack()) { val stack = slot.stack diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt similarity index 100% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt similarity index 97% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt index c4fbe07..5e40701 100644 --- a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/packet/InventorioNetworkingNeoForge.kt @@ -26,7 +26,7 @@ object InventorioNetworkingNeoForge : InventorioNetworking { @SubscribeEvent fun registerPayloads(event: RegisterPayloadHandlersEvent) { - val registrar = event.registrar("inventorio").versioned(PROTOCOL_VERSION) + val registrar = event.registrar(PROTOCOL_VERSION) registrar.playBidirectional( SelectUtilitySlotPacket.ID, diff --git a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt similarity index 69% rename from versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt rename to versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt index dc56643..ab7ed73 100644 --- a/versions/1.20.6-neoforge/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/util/PlatformApi.kt @@ -5,4 +5,5 @@ import net.neoforged.fml.ModList object PlatformApi { fun isModLoaded(modId: String): Boolean = ModList.get().isLoaded(modId) fun modDisplayname(modId: String): String? = ModList.get().getModContainerById(modId).orElse(null)?.modInfo?.displayName + fun modVersion(modId: String): String? = ModList.get().getModContainerById(modId).orElse(null)?.modInfo?.version?.toString() } diff --git a/versions/1.20.6-neoforge/src/main/resources/META-INF/neoforge.mods.toml b/versions/1.21.1-neoforge/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from versions/1.20.6-neoforge/src/main/resources/META-INF/neoforge.mods.toml rename to versions/1.21.1-neoforge/src/main/resources/META-INF/neoforge.mods.toml diff --git a/versions/1.20.6-neoforge/src/main/resources/inventorio-neoforge.mixins.json b/versions/1.21.1-neoforge/src/main/resources/inventorio-neoforge.mixins.json similarity index 100% rename from versions/1.20.6-neoforge/src/main/resources/inventorio-neoforge.mixins.json rename to versions/1.21.1-neoforge/src/main/resources/inventorio-neoforge.mixins.json diff --git a/versions/mainProject b/versions/mainProject index 4e0be95..d7fd395 100644 --- a/versions/mainProject +++ b/versions/mainProject @@ -1 +1 @@ -1.20.6-common \ No newline at end of file +1.21.1-common diff --git a/versions/mappings-neoforge-1.21.1-1.20.6.txt b/versions/mappings-neoforge-1.21.1-1.20.6.txt new file mode 100644 index 0000000..5ff659c --- /dev/null +++ b/versions/mappings-neoforge-1.21.1-1.20.6.txt @@ -0,0 +1,2 @@ +net.neoforged.neoforge.common.ItemAbilities net.neoforged.neoforge.common.ToolActions +net.neoforged.neoforge.common.ItemAbility net.neoforged.neoforge.common.ToolAction From 4fc84dcd42a7f0ec0b85b98e2b2fcf6477b433a8 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Mon, 17 Nov 2025 21:56:29 +0100 Subject: [PATCH 2/7] chore: move rrp logic into new library mod (YARRP) --- .github/workflows/release.yml | 1 + common.gradle.kts | 9 +- .../LifecycledResourceManagerImplMixin.java | 27 -- .../mixin/RegistryEntryListCodecMixin.java | 44 -- .../{pack => }/InventorioResources.kt | 23 +- .../enchantment/DeepPocketsBookRecipe.kt | 2 +- .../inventorio/pack/RuntimeResourcePack.kt | 407 ------------------ .../inventory/PlayerInventoryExtension.kt | 2 +- src/main/resources/inventorio.mixins.json | 2 - versions/1.20.6-fabric/gradle.properties | 2 + versions/1.20.6-neoforge/gradle.properties | 2 + versions/1.21.1-common/gradle.properties | 2 + versions/1.21.1-fabric/gradle.properties | 2 + .../rubixdev/inventorio/InventorioFabric.kt | 1 + .../src/main/resources/fabric.mod.json | 3 +- versions/1.21.1-neoforge/gradle.properties | 2 + .../rubixdev/inventorio/InventorioNeoForge.kt | 2 + .../resources/META-INF/neoforge.mods.toml | 7 + 18 files changed, 48 insertions(+), 492 deletions(-) delete mode 100644 src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java delete mode 100644 src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java rename src/main/kotlin/de/rubixdev/inventorio/{pack => }/InventorioResources.kt (74%) delete mode 100644 src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 65d6017..c339357 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -172,6 +172,7 @@ jobs: run: | echo 'value<> "$GITHUB_OUTPUT" echo 'cloth-config(required){modrinth:9s6osm5g}{curseforge:348521}' >> "$GITHUB_OUTPUT" + echo 'yarrp(required){modrinth:Z2RtCqwR}{curseforge:1385339}' >> "$GITHUB_OUTPUT" if [ "${{ endsWith(matrix.subproject, '-fabric') }}" = "true" ]; then # shellcheck disable=SC2129 echo 'fabric-api(required){modrinth:P7dR8mSH}{curseforge:306612}' >> "$GITHUB_OUTPUT" diff --git a/common.gradle.kts b/common.gradle.kts index fd56b7e..572c9fc 100644 --- a/common.gradle.kts +++ b/common.gradle.kts @@ -86,6 +86,7 @@ class Props { val neoforge_version_range: String by prop val cloth_version: String by prop + val yarrp_version: String by prop val clumps_version: String by prop val early_loading_screen_version: String by prop @@ -135,11 +136,12 @@ repositories { // Mixin maven("https://repo.spongepowered.org/maven/") + // Conditional Mixin + maven("https://maven.fallenbreath.me/releases") // Cloth Config maven("https://maven.shedaniel.me/") - // Conditional Mixin + // YARRP maven("https://jitpack.io") - maven("https://maven.fallenbreath.me/releases") // Other mods from Modrinth maven("https://api.modrinth.com/maven") } @@ -171,6 +173,7 @@ dependencies { exclude(group = "net.fabricmc.fabric-api") } modCompileOnly("me.fallenbreath:conditional-mixin-common:${props.conditional_mixin_version}") + modCompileOnly("com.github.RubixDev.YARRP:yarrp-mc${props.minecraft_version}-fabric:${props.yarrp_version}") } Loader.FABRIC -> { modLocalRuntime("maven.modrinth:early-loading-screen:${props.early_loading_screen_version}") @@ -185,6 +188,7 @@ dependencies { modImplementation("me.shedaniel.cloth:cloth-config-fabric:${props.cloth_version}") { exclude(group = "net.fabricmc.fabric-api") } + modImplementation("com.github.RubixDev.YARRP:yarrp-mc${props.minecraft_version}-fabric:${props.yarrp_version}") // other mods we do integration with // - Trinkets @@ -200,6 +204,7 @@ dependencies { exclude(group = "net.neoforged.fancymodloader", module = "loader") } modImplementation("me.shedaniel.cloth:cloth-config-neoforge:${props.cloth_version}") + modImplementation("com.github.RubixDev.YARRP:yarrp-mc${props.minecraft_version}-neoforge:${props.yarrp_version}") // other mods we do integration with // - Curios API diff --git a/src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java deleted file mode 100644 index 6386ea1..0000000 --- a/src/main/java/de/rubixdev/inventorio/mixin/LifecycledResourceManagerImplMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.rubixdev.inventorio.mixin; - -import de.rubixdev.inventorio.pack.InventorioResources; -import net.minecraft.resource.LifecycledResourceManager; -import net.minecraft.resource.LifecycledResourceManagerImpl; -import net.minecraft.resource.ResourcePack; -import net.minecraft.resource.ResourceType; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import java.util.ArrayList; -import java.util.List; - -@Mixin(LifecycledResourceManagerImpl.class) -public abstract class LifecycledResourceManagerImplMixin implements LifecycledResourceManager { - @ModifyVariable(method = "", at = @At("HEAD"), argsOnly = true) - private static List injectRuntimePacks(List packs, ResourceType type) { - var copy = new ArrayList<>(packs); - - if (type == ResourceType.SERVER_DATA) { - copy.add(InventorioResources.PACK); - } - - return copy; - } -} diff --git a/src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java b/src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java deleted file mode 100644 index 58e7c99..0000000 --- a/src/main/java/de/rubixdev/inventorio/mixin/RegistryEntryListCodecMixin.java +++ /dev/null @@ -1,44 +0,0 @@ -package de.rubixdev.inventorio.mixin; - -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.DynamicOps; -import de.rubixdev.inventorio.pack.DummyRegistryEntryList; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryEntryList; -import net.minecraft.registry.entry.RegistryEntryListCodec; -import net.minecraft.registry.tag.TagKey; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.List; - -@Mixin(RegistryEntryListCodec.class) -public abstract class RegistryEntryListCodecMixin implements Codec> { - @Shadow - @Final - private Codec, List>>> entryListStorageCodec; - - @Inject( - method = "encode(Lnet/minecraft/registry/entry/RegistryEntryList;Lcom/mojang/serialization/DynamicOps;Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;", - at = @At("HEAD"), - cancellable = true - ) - public void encodeDummyList( - RegistryEntryList registryEntryList, - DynamicOps dynamicOps, - T object, - CallbackInfoReturnable> cir - ) { - if (registryEntryList instanceof DummyRegistryEntryList) { - cir.setReturnValue( - entryListStorageCodec.encode(registryEntryList.getStorage().mapRight(List::copyOf), dynamicOps, object) - ); - } - } -} diff --git a/src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt b/src/main/kotlin/de/rubixdev/inventorio/InventorioResources.kt similarity index 74% rename from src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt rename to src/main/kotlin/de/rubixdev/inventorio/InventorioResources.kt index b707857..214565d 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/pack/InventorioResources.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/InventorioResources.kt @@ -1,12 +1,17 @@ -package de.rubixdev.inventorio.pack +package de.rubixdev.inventorio import de.rubixdev.inventorio.config.GlobalSettings import de.rubixdev.inventorio.enchantment.DeepPocketsBookRecipe import de.rubixdev.inventorio.util.MOD_ID import de.rubixdev.inventorio.util.PlatformApi import de.rubixdev.inventorio.util.id +import de.rubixdev.yarrp.api.DummyHolderSet +import de.rubixdev.yarrp.api.PackPosition +import de.rubixdev.yarrp.api.RuntimeResourcePack +import de.rubixdev.yarrp.api.YarrpCallbacks import net.minecraft.advancement.criterion.TickCriterion import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder +import net.minecraft.resource.ResourceType import net.minecraft.text.Text //#if MC >= 12101 @@ -19,6 +24,10 @@ import net.minecraft.registry.tag.ItemTags //#endif object InventorioResources { + fun register() { + YarrpCallbacks.register(PackPosition.AFTER_VANILLA, ResourceType.SERVER_DATA) { add(PACK) } + } + @JvmField val PACK = RuntimeResourcePack( RuntimeResourcePack.createInfo( @@ -33,7 +42,7 @@ object InventorioResources { val DEEP_POCKETS: RegistryKey = PACK.addEnchantment( "deep_pockets".id, Enchantment.definition( - DummyRegistryEntryList(ItemTags.LEG_ARMOR_ENCHANTABLE), + DummyHolderSet(ItemTags.LEG_ARMOR_ENCHANTABLE), 5, DEEP_POCKETS_MAX_LEVEL, Enchantment.leveledCost(5, 8), @@ -50,17 +59,17 @@ object InventorioResources { && GlobalSettings.deepPocketsInRandomSelection.boolValue && GlobalSettings.deepPocketsInEnchantingTable.boolValue ) { - PACK.addItemsToTag(EnchantmentTags.NON_TREASURE) { add(DEEP_POCKETS) } + PACK.addTag(EnchantmentTags.NON_TREASURE) { add(DEEP_POCKETS) } } else { if (GlobalSettings.deepPocketsInTrades.boolValue) { - PACK.addItemsToTag(EnchantmentTags.TRADEABLE) { add(DEEP_POCKETS) } - PACK.addItemsToTag(EnchantmentTags.ON_TRADED_EQUIPMENT) { add(DEEP_POCKETS) } + PACK.addTag(EnchantmentTags.TRADEABLE) { add(DEEP_POCKETS) } + PACK.addTag(EnchantmentTags.ON_TRADED_EQUIPMENT) { add(DEEP_POCKETS) } } if (GlobalSettings.deepPocketsInRandomSelection.boolValue) { - PACK.addItemsToTag(EnchantmentTags.ON_RANDOM_LOOT) { add(DEEP_POCKETS) } + PACK.addTag(EnchantmentTags.ON_RANDOM_LOOT) { add(DEEP_POCKETS) } } if (GlobalSettings.deepPocketsInEnchantingTable.boolValue) { - PACK.addItemsToTag(EnchantmentTags.IN_ENCHANTING_TABLE) { add(DEEP_POCKETS) } + PACK.addTag(EnchantmentTags.IN_ENCHANTING_TABLE) { add(DEEP_POCKETS) } } } //#endif diff --git a/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt b/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt index 9441c1a..bb7e786 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/enchantment/DeepPocketsBookRecipe.kt @@ -15,7 +15,7 @@ import net.minecraft.util.collection.DefaultedList import net.minecraft.world.World //#if MC >= 12101 -import de.rubixdev.inventorio.pack.InventorioResources +import de.rubixdev.inventorio.InventorioResources import de.rubixdev.inventorio.util.getEnchantment import net.minecraft.recipe.input.CraftingRecipeInput //#else diff --git a/src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt b/src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt deleted file mode 100644 index 37bb372..0000000 --- a/src/main/kotlin/de/rubixdev/inventorio/pack/RuntimeResourcePack.kt +++ /dev/null @@ -1,407 +0,0 @@ -package de.rubixdev.inventorio.pack - -import com.google.gson.Gson -import com.mojang.datafixers.util.Either -import com.mojang.serialization.Codec -import com.mojang.serialization.JsonOps -import de.rubixdev.inventorio.util.logger -import java.io.InputStream -import java.util.Optional -import java.util.stream.Stream -import net.minecraft.SharedConstants -import net.minecraft.advancement.Advancement -import net.minecraft.advancement.AdvancementEntry -import net.minecraft.advancement.AdvancementRequirements -import net.minecraft.advancement.AdvancementRewards -import net.minecraft.advancement.criterion.RecipeUnlockedCriterion -import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder -import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder -import net.minecraft.data.server.recipe.RecipeExporter -import net.minecraft.data.server.recipe.SmithingTransformRecipeJsonBuilder -import net.minecraft.data.server.recipe.SmithingTrimRecipeJsonBuilder -import net.minecraft.recipe.Recipe -import net.minecraft.registry.Registry -import net.minecraft.registry.RegistryKey -import net.minecraft.registry.VersionedIdentifier -import net.minecraft.registry.entry.RegistryEntry -import net.minecraft.registry.entry.RegistryEntryList -import net.minecraft.registry.entry.RegistryEntryOwner -import net.minecraft.registry.tag.TagEntry -import net.minecraft.registry.tag.TagFile -import net.minecraft.registry.tag.TagKey -import net.minecraft.resource.InputSupplier -import net.minecraft.resource.ResourcePack -import net.minecraft.resource.ResourcePackInfo -import net.minecraft.resource.ResourcePackSource -import net.minecraft.resource.ResourceType -import net.minecraft.resource.metadata.PackFeatureSetMetadata -import net.minecraft.resource.metadata.PackOverlaysMetadata -import net.minecraft.resource.metadata.PackResourceMetadata -import net.minecraft.resource.metadata.ResourceFilter -import net.minecraft.resource.metadata.ResourceMetadataReader -import net.minecraft.text.Text -import net.minecraft.util.Identifier -import net.minecraft.util.math.random.Random - -//#if NEOFORGE -//$$ import net.neoforged.neoforge.common.conditions.ICondition -//#endif - -//#if MC >= 12101 -import net.minecraft.enchantment.Enchantment -import net.minecraft.registry.RegistryKeys -//#else -//$$ import net.minecraft.registry.tag.TagManagerLoader -//#endif - -private typealias Resource = InputSupplier -private typealias DirectoryMap = MutableMap -private data class ResourceEntry(val resource: Resource) : PackEntry() -private data class DirectoryEntry(val nested: DirectoryMap = mutableMapOf()) : PackEntry() - -private sealed class PackEntry { - fun asResource(): Resource? = (this as? ResourceEntry)?.resource - fun asDirectory(): DirectoryMap? = (this as? DirectoryEntry)?.nested - - fun find(path: List): PackEntry? = - path.fold(this as PackEntry?) { entry, segment -> entry?.asDirectory()?.get(segment) } - - fun findAllResources(path: List = listOf(), consumer: (path: List, resource: Resource) -> Unit): Unit = - asDirectory()?.entries?.forEach { (name, entry) -> - when (entry) { - is ResourceEntry -> consumer(path + name, entry.resource) - is DirectoryEntry -> entry.findAllResources(path + name, consumer) - } - } ?: Unit -} - -class RuntimeResourcePack( - private val info: ResourcePackInfo, - val metadata: PackResourceMetadata, - val features: PackFeatureSetMetadata? = null, - val filter: ResourceFilter? = null, - val overlays: PackOverlaysMetadata? = null, - // TODO: client-only metadata (LanguageResourceMetadata, GuiResourceMetadata, VillagerResourceMetadata, AnimationResourceMetadata, TextureResourceMetadata) - private val extraFiles: Map, InputSupplier> = mapOf(), -) : ResourcePack { - companion object { - private val GSON = Gson() - - //#if MC >= 12101 - private val RegistryKey>.path get() = RegistryKeys.getPath(this).split("/") - private val RegistryKey>.tagPath get() = RegistryKeys.getTagPath(this).split("/") - //#else - //$$ private val RegistryKey>.path get() = value.splitPath - //$$ private val RegistryKey>.tagPath get() = TagManagerLoader.getPath(this).split("/") - //#endif - private val Identifier.splitPath get() = path.split("/") - private val List.withJsonExt get() = dropLast(1) + "${last()}.json" - - val SOURCE = object : ResourcePackSource { - override fun decorate(packDisplayName: Text): Text = - Text.translatable("pack.nameAndSource", packDisplayName, Text.of("Runtime generated")) - override fun canBeEnabledLater(): Boolean = true - } - - fun createInfo(id: Identifier, title: Text, version: String) = ResourcePackInfo( - id.path, - title, - SOURCE, - Optional.of(VersionedIdentifier(id.namespace, id.path, version)), - ) - - fun createMetadata(description: Text, type: ResourceType = ResourceType.SERVER_DATA) = PackResourceMetadata( - description, - SharedConstants.getGameVersion().getResourceVersion(type), - Optional.empty(), - ) - } - - private val root = DirectoryEntry() - - // TODO: is this needed for anything but a pack.png - override fun openRoot(vararg segments: String): InputSupplier? = - extraFiles[segments.toList()] - - override fun open( - type: ResourceType, - id: Identifier, - ): InputSupplier? { - val path = listOf(type.directory, id.namespace) + id.path.split("/") - return root.find(path)?.asResource() - } - - override fun findResources( - type: ResourceType, - namespace: String, - prefix: String, - consumer: ResourcePack.ResultConsumer, - ) { - val basePath = listOf(type.directory, namespace) + prefix.split("/") - root.find(basePath)?.findAllResources { path, resource -> - val id = Identifier.tryParse(namespace, (basePath.drop(2) + path).joinToString("/")) ?: run { - logger.error("Invalid path in pack: {}:{}, ignoring", namespace, path.joinToString("/")) - return@findAllResources - } - consumer.accept(id, resource) - } - } - - override fun getNamespaces(type: ResourceType): Set = - root.nested[type.directory]?.asDirectory()?.keys ?: setOf() - - override fun parseMetadata(metaReader: ResourceMetadataReader): T? = - @Suppress("UNCHECKED_CAST") - when (metaReader.key) { - PackResourceMetadata.SERIALIZER.key -> metadata as T - PackFeatureSetMetadata.SERIALIZER.key -> features as T? - ResourceFilter.SERIALIZER.key -> filter as T? - PackOverlaysMetadata.SERIALIZER.key -> overlays as T? - else -> null - } - - override fun getInfo(): ResourcePackInfo = info - - override fun close() {} - - fun addResource( - type: ResourceType, - registry: RegistryKey>, - codec: Codec, - id: Identifier, - value: T, - ): RegistryKey = RegistryKey.of(registry, id).also { - addResource(type, registry.path, codec, id, value) - } - - fun addResource( - type: ResourceType, - path: List, - codec: Codec, - id: Identifier, - value: T, - ) { - val path = listOf(id.namespace) + path + id.splitPath.withJsonExt - val json = GSON.toJson(codec.encodeStart(JsonOps.INSTANCE, value).getOrThrow()) - logger.debug("adding resource:\n{}\n{}", path.joinToString("/"), json) - addResource(type, path, json) - } - - fun addResource(type: ResourceType, path: List, resource: String) = - addResource(type, path) { resource.byteInputStream() } - - fun addResource(type: ResourceType, path: List, resource: Resource) { - val fullPath = listOf(type.directory) + path - - // ensure directory exists - val dirPath = fullPath.dropLast(1) - val dir = dirPath.fold(root as PackEntry) { entry, segment -> - when (entry) { - is ResourceEntry -> throw IllegalArgumentException("Part of resource path is already stored as a resource") - is DirectoryEntry -> entry.nested.getOrPut(segment, ::DirectoryEntry) - } - }.asDirectory() ?: throw IllegalArgumentException("Part of resource path is already stored as a resource") - - // insert (or overwrite) resource entry - dir[path.last()] = ResourceEntry(resource) - } - - ////// Tags ////// - - inline fun addItemsToTag(tagKey: TagKey, tagBuilder: TagBuilder.() -> Unit) = - addItemsToTag(tagKey, TagBuilder().apply(tagBuilder)) - - fun addItemsToTag(tagKey: TagKey, tagBuilder: TagBuilder) = - addItemsToTag(tagKey, tagBuilder.build()) - - fun addItemsToTag(tagKey: TagKey, tagEntries: List, replace: Boolean = false) = - addItemsToTag(tagKey, TagFile(tagEntries, replace)) - - fun addItemsToTag(tagKey: TagKey, tagFile: TagFile): TagKey { - val path = mutableListOf().apply { - add(tagKey.id.namespace) - addAll(tagKey.registry.tagPath) - addAll(tagKey.id.splitPath.withJsonExt) - } - val json = GSON.toJson(TagFile.CODEC.encodeStart(JsonOps.INSTANCE, tagFile).getOrThrow()) - logger.debug("adding tag:\n{}\n{}", path.joinToString("/"), json) - addResource(ResourceType.SERVER_DATA, path, json) - return tagKey - } - - ////// Enchantments ////// - - //#if MC >= 12101 - fun addEnchantment(id: Identifier, enchantment: Enchantment.Definition) = - addEnchantment(id, Enchantment.builder(enchantment)) - - fun addEnchantment(id: Identifier, enchantment: Enchantment.Builder) = - addEnchantment(id, enchantment.build(id)) - - fun addEnchantment(id: Identifier, enchantment: Enchantment) = - addResource(ResourceType.SERVER_DATA, RegistryKeys.ENCHANTMENT, Enchantment.CODEC, id, enchantment) - //#endif - - ////// Recipes and Advancements ////// - - fun addRecipe(id: Identifier, recipe: Recipe<*>) = - //#if MC >= 12101 - addResource(ResourceType.SERVER_DATA, RegistryKeys.RECIPE, Recipe.CODEC, id, recipe) - //#else - //$$ addResource(ResourceType.SERVER_DATA, listOf("recipes"), Recipe.CODEC, id, recipe) - //#endif - - fun addAdvancement(id: Identifier, advancementBuilder: Advancement.Builder) = - addAdvancement(advancementBuilder.build(id)) - - fun addAdvancement(entry: AdvancementEntry) = - addAdvancement(entry.id, entry.value) - - fun addAdvancement(id: Identifier, advancement: Advancement) = - //#if MC >= 12101 - addResource(ResourceType.SERVER_DATA, RegistryKeys.ADVANCEMENT, Advancement.CODEC, id, advancement) - //#else - //$$ addResource(ResourceType.SERVER_DATA, listOf("advancements"), Advancement.CODEC, id, advancement) - //#endif - - val recipeExporter by lazy { - object : RecipeExporter { - override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?) { - addRecipe(recipeId, recipe) - if (advancement != null) addAdvancement(advancement) - } - - override fun getAdvancementBuilder(): Advancement.Builder = - Advancement.Builder.createUntelemetered().parent(AdvancementEntry(CraftingRecipeJsonBuilder.ROOT, null)) - - //#if NEOFORGE - //$$ override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?, vararg conditions: ICondition) = - //$$ accept(recipeId, recipe, advancement) - //#endif - } - } - - val recipeExporterOnlyRecipe by lazy { - object : RecipeExporter { - override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?) { - addRecipe(recipeId, recipe) - } - - override fun getAdvancementBuilder(): Advancement.Builder = Advancement.Builder.createUntelemetered() - - //#if NEOFORGE - //$$ override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?, vararg conditions: ICondition) = - //$$ accept(recipeId, recipe, advancement) - //#endif - } - } - - val recipeExporterOnlyAdvancement by lazy { - object : RecipeExporter { - override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?) { - if (advancement != null) addAdvancement(advancement) - } - - override fun getAdvancementBuilder(): Advancement.Builder = - Advancement.Builder.createUntelemetered().parent(AdvancementEntry(CraftingRecipeJsonBuilder.ROOT, null)) - - //#if NEOFORGE - //$$ override fun accept(recipeId: Identifier, recipe: Recipe<*>, advancement: AdvancementEntry?, vararg conditions: ICondition) = - //$$ accept(recipeId, recipe, advancement) - //#endif - } - } - - fun addRecipeAndAdvancement(recipeId: Identifier, builder: CraftingRecipeJsonBuilder) = - builder.offerTo(recipeExporter, recipeId) - - fun addRecipeAndAdvancement(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder) = - builder.offerTo(recipeExporter, recipeId) - - fun addRecipeAndAdvancement(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder) = - builder.offerTo(recipeExporter, recipeId) - - fun addRecipeAndAdvancement(recipeId: Identifier, builder: ComplexRecipeJsonBuilder) = - builder.offerTo(recipeExporter, recipeId) - - //#if MC >= 12101 - fun addRecipe(recipeId: Identifier, builder: CraftingRecipeJsonBuilder): RegistryKey> = - builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } - - fun addRecipe(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder): RegistryKey> = - builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } - - fun addRecipe(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder): RegistryKey> = - builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } - - fun addRecipe(recipeId: Identifier, builder: ComplexRecipeJsonBuilder): RegistryKey> = - builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { RegistryKey.of(RegistryKeys.RECIPE, recipeId) } - //#else - //$$ fun addRecipe(recipeId: Identifier, builder: CraftingRecipeJsonBuilder) = - //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } - //$$ - //$$ fun addRecipe(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder) = - //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } - //$$ - //$$ fun addRecipe(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder) = - //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } - //$$ - //$$ fun addRecipe(recipeId: Identifier, builder: ComplexRecipeJsonBuilder) = - //$$ builder.offerTo(recipeExporterOnlyRecipe, recipeId).let { recipeId } - //#endif - - fun addAdvancement(recipeId: Identifier, builder: CraftingRecipeJsonBuilder) = - builder.offerTo(recipeExporterOnlyAdvancement, recipeId) - - fun addAdvancement(recipeId: Identifier, builder: SmithingTransformRecipeJsonBuilder) = - builder.offerTo(recipeExporterOnlyAdvancement, recipeId) - - fun addAdvancement(recipeId: Identifier, builder: SmithingTrimRecipeJsonBuilder) = - builder.offerTo(recipeExporterOnlyAdvancement, recipeId) - - fun addAdvancement(recipeId: Identifier, builder: ComplexRecipeJsonBuilder) = - builder.offerTo(recipeExporterOnlyAdvancement, recipeId) - - fun advancementBuilderForRecipe(recipe: RegistryKey>): Advancement.Builder = - advancementBuilderForRecipe(recipe.value) - - fun advancementBuilderForRecipe(recipeId: Identifier): Advancement.Builder = - recipeExporterOnlyAdvancement.advancementBuilder - .criterion("has_the_recipe", RecipeUnlockedCriterion.create(recipeId)) - .rewards(AdvancementRewards.Builder.recipe(recipeId)) - .criteriaMerger(AdvancementRequirements.CriterionMerger.OR) -} - -class TagBuilder { - private val builder = net.minecraft.registry.tag.TagBuilder() - private var replace = false - - fun setReplace(replace: Boolean) = also { this.replace = replace } - - fun add(entry: TagEntry) = also { builder.add(entry) } - fun add(id: Identifier) = also { builder.add(id) } - fun add(key: RegistryKey) = also { builder.add(key.value) } - - fun addOptional(id: Identifier) = also { builder.addOptional(id) } - fun addOptional(key: RegistryKey) = also { builder.addOptional(key.value) } - - fun addTag(id: Identifier) = also { builder.addTag(id) } - fun addTag(key: TagKey) = also { builder.addTag(key.id) } - - fun addOptionalTag(id: Identifier) = also { builder.addOptionalTag(id) } - fun addOptionalTag(key: TagKey) = also { builder.addOptionalTag(key.id) } - - fun build() = TagFile(builder.build(), replace) -} - -class DummyRegistryEntryList(val tag: TagKey) : RegistryEntryList { - override fun stream(): Stream> = Stream.empty() - override fun size(): Int = 0 - override fun getStorage(): Either, List>> = Either.left(tag) - override fun getRandom(random: Random): Optional> = Optional.empty() - override fun get(index: Int): RegistryEntry? = null - override fun contains(entry: RegistryEntry): Boolean = false - override fun ownerEquals(owner: RegistryEntryOwner): Boolean = true - override fun getTagKey(): Optional> = Optional.of(tag) - override fun iterator(): MutableIterator> = mutableListOf>().iterator() -} diff --git a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt index cbe12b6..2159e8f 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/player/inventory/PlayerInventoryExtension.kt @@ -18,7 +18,7 @@ import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.collection.DefaultedList //#if MC >= 12101 -import de.rubixdev.inventorio.pack.InventorioResources +import de.rubixdev.inventorio.InventorioResources import net.minecraft.component.EnchantmentEffectComponentTypes //#else //$$ import de.rubixdev.inventorio.enchantment.DeepPocketsEnchantment diff --git a/src/main/resources/inventorio.mixins.json b/src/main/resources/inventorio.mixins.json index ba78238..e41a481 100644 --- a/src/main/resources/inventorio.mixins.json +++ b/src/main/resources/inventorio.mixins.json @@ -6,11 +6,9 @@ "plugin": "de.rubixdev.inventorio.InventorioMixinPlugin", "mixins": [ "ExperienceOrbEntityMixin", - "LifecycledResourceManagerImplMixin", "PlayerEntityMixin", "PlayerInventoryMixin", "PlayerManagerMixin", - "RegistryEntryListCodecMixin", "ServerPlayerEntity_ScreenHandlerSyncHandlerMixin", "ServerPlayNetworkHandlerMixin", "accessor.CraftingScreenHandlerAccessor", diff --git a/versions/1.20.6-fabric/gradle.properties b/versions/1.20.6-fabric/gradle.properties index 54d3519..3f6546d 100644 --- a/versions/1.20.6-fabric/gradle.properties +++ b/versions/1.20.6-fabric/gradle.properties @@ -14,6 +14,8 @@ # Common Dependencies cloth_version=14.0.139 + # https://jitpack.io/#RubixDev/YARRP + yarrp_version=v0.2.0 # https://modrinth.com/mod/clumps/versions clumps_version=17.0.0.1-fabric,1.20.6 diff --git a/versions/1.20.6-neoforge/gradle.properties b/versions/1.20.6-neoforge/gradle.properties index db17268..01a4ef2 100644 --- a/versions/1.20.6-neoforge/gradle.properties +++ b/versions/1.20.6-neoforge/gradle.properties @@ -14,6 +14,8 @@ # Common Dependencies cloth_version=14.0.139 + # https://jitpack.io/#RubixDev/YARRP + yarrp_version=v0.2.0 # https://modrinth.com/mod/clumps/versions clumps_version=17.0.0.1-neoforge,1.20.6 diff --git a/versions/1.21.1-common/gradle.properties b/versions/1.21.1-common/gradle.properties index d8337af..025b6e9 100644 --- a/versions/1.21.1-common/gradle.properties +++ b/versions/1.21.1-common/gradle.properties @@ -13,6 +13,8 @@ # Common Dependencies cloth_version=15.0.140 + # https://jitpack.io/#RubixDev/YARRP + yarrp_version=v0.2.0 # https://modrinth.com/mod/clumps/versions clumps_version=19.0.0.1-fabric,1.21.1 diff --git a/versions/1.21.1-fabric/gradle.properties b/versions/1.21.1-fabric/gradle.properties index 5bfc9f7..a5d1a11 100644 --- a/versions/1.21.1-fabric/gradle.properties +++ b/versions/1.21.1-fabric/gradle.properties @@ -14,6 +14,8 @@ # Common Dependencies cloth_version=15.0.140 + # https://jitpack.io/#RubixDev/YARRP + yarrp_version=v0.2.0 # https://modrinth.com/mod/clumps/versions clumps_version=19.0.0.1-fabric,1.21.1 diff --git a/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt index 5079905..926a693 100644 --- a/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt +++ b/versions/1.21.1-fabric/src/main/kotlin/de/rubixdev/inventorio/InventorioFabric.kt @@ -38,6 +38,7 @@ open class InventorioFabric : ModInitializer { "deep_pockets_book".id, SpecialRecipeSerializer { category -> DeepPocketsBookRecipe(category) }, ) + InventorioResources.register() initToolBelt() diff --git a/versions/1.21.1-fabric/src/main/resources/fabric.mod.json b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json index b591e5f..c755ebd 100644 --- a/versions/1.21.1-fabric/src/main/resources/fabric.mod.json +++ b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json @@ -31,7 +31,8 @@ "fabricloader": ">=${fabric_loader_version}", "fabric-api": "*", "fabric-language-kotlin": ">=${fabric_kotlin_version}", - "cloth-config": "*" + "cloth-config": "*", + "yarrp": "*" }, "suggests": { "modmenu": "*" diff --git a/versions/1.21.1-neoforge/gradle.properties b/versions/1.21.1-neoforge/gradle.properties index 47bdbb1..a7c12b7 100644 --- a/versions/1.21.1-neoforge/gradle.properties +++ b/versions/1.21.1-neoforge/gradle.properties @@ -14,6 +14,8 @@ # Common Dependencies cloth_version=15.0.140 + # https://jitpack.io/#RubixDev/YARRP + yarrp_version=v0.2.0 # https://modrinth.com/mod/clumps/versions clumps_version=19.0.0.1-neoforge,1.21.1 diff --git a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt index 02c37d7..25b91fd 100644 --- a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt @@ -51,6 +51,8 @@ class InventorioNeoForge { DeepPocketsBookRecipe.SERIALIZER = serializer recipeRegistry.register("deep_pockets_book") { -> serializer } + InventorioResources.register() + initToolBelt() KotlinModLoadingContext.get().getKEventBus().register(InventorioNetworkingNeoForge) diff --git a/versions/1.21.1-neoforge/src/main/resources/META-INF/neoforge.mods.toml b/versions/1.21.1-neoforge/src/main/resources/META-INF/neoforge.mods.toml index b2ea07e..95ad239 100644 --- a/versions/1.21.1-neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/versions/1.21.1-neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -37,3 +37,10 @@ type = "required" versionRange = "[14,)" ordering = "NONE" side = "CLIENT" + +[[dependencies.${mod_id}]] +modId = "yarrp" +type = "required" +versionRange = "[0,)" +ordering = "NONE" +side = "BOTH" From ffc5d5c15c0aa090e3248f2957d710c86dbe713c Mon Sep 17 00:00:00 2001 From: RubixDev Date: Mon, 17 Nov 2025 21:57:23 +0100 Subject: [PATCH 3/7] feat: add more links to modmenu --- versions/1.21.1-fabric/src/main/resources/fabric.mod.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/versions/1.21.1-fabric/src/main/resources/fabric.mod.json b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json index c755ebd..cb126dd 100644 --- a/versions/1.21.1-fabric/src/main/resources/fabric.mod.json +++ b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json @@ -40,7 +40,12 @@ "custom": { "modmenu": { "links": { - "modmenu.discord": "https://discord.gg/Etq9EBYU7Q" + "modmenu.discord": "https://discord.gg/Etq9EBYU7Q", + "modmenu.kofi": "https://ko-fi.com/rubixdev", + "modmenu.paypal": "https://paypal.me/RubixDev42", + "modmenu.github_releases": "https://github.com/RubixDev/Inventorio/releases", + "modmenu.modrinth": "https://modrinth.com/project/inventorio", + "modmenu.curseforge": "https://www.curseforge.com/minecraft/mc-mods/inventorio" } } } From c046e3863f1d53a98f3e84666184592fbbdda627 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Mon, 17 Nov 2025 21:59:28 +0100 Subject: [PATCH 4/7] chore: add json formatter --- build.gradle.kts | 4 + .../src/main/resources/fabric.mod.json | 102 +++++++++--------- 2 files changed, 58 insertions(+), 48 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 87d9000..109ae18 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -80,6 +80,10 @@ spotless { eclipse("4.31").configFile("eclipse-prefs.xml") formatAnnotations() } + json { + target("**/*.json") + gson().indentWithSpaces(2) + } } tasks.register("buildAndGather") { diff --git a/versions/1.21.1-fabric/src/main/resources/fabric.mod.json b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json index cb126dd..125622c 100644 --- a/versions/1.21.1-fabric/src/main/resources/fabric.mod.json +++ b/versions/1.21.1-fabric/src/main/resources/fabric.mod.json @@ -1,52 +1,58 @@ { - "schemaVersion": 1, - "id": "${mod_id}", - "version": "${version}", - "name": "${mod_name}", - "description": "${description}", - "authors": ["${authors}"], - "contact": { - "homepage": "${homepage_url}", - "sources": "${sources_url}", - "issues": "${issues_url}" - }, - "license": "${license}", - "icon": "icon.png", - "entrypoints": { - "main": [{ - "value": "de.rubixdev.inventorio.InventorioFabric", - "adapter": "kotlin" - }], - "modmenu": [{ - "value": "de.rubixdev.inventorio.integration.ModMenuIntegration", - "adapter": "kotlin" - }] - }, - "mixins": [ - "${mod_id}.mixins.json", - "${mod_id}-fabric.mixins.json" + "schemaVersion": 1, + "id": "${mod_id}", + "version": "${version}", + "name": "${mod_name}", + "description": "${description}", + "authors": [ + "${authors}" + ], + "contact": { + "homepage": "${homepage_url}", + "sources": "${sources_url}", + "issues": "${issues_url}" + }, + "license": "${license}", + "icon": "icon.png", + "entrypoints": { + "main": [ + { + "value": "de.rubixdev.inventorio.InventorioFabric", + "adapter": "kotlin" + } ], - "depends": { - "minecraft": "${minecraft_version_range_fabric}", - "fabricloader": ">=${fabric_loader_version}", - "fabric-api": "*", - "fabric-language-kotlin": ">=${fabric_kotlin_version}", - "cloth-config": "*", - "yarrp": "*" - }, - "suggests": { - "modmenu": "*" - }, - "custom": { - "modmenu": { - "links": { - "modmenu.discord": "https://discord.gg/Etq9EBYU7Q", - "modmenu.kofi": "https://ko-fi.com/rubixdev", - "modmenu.paypal": "https://paypal.me/RubixDev42", - "modmenu.github_releases": "https://github.com/RubixDev/Inventorio/releases", - "modmenu.modrinth": "https://modrinth.com/project/inventorio", - "modmenu.curseforge": "https://www.curseforge.com/minecraft/mc-mods/inventorio" - } - } + "modmenu": [ + { + "value": "de.rubixdev.inventorio.integration.ModMenuIntegration", + "adapter": "kotlin" + } + ] + }, + "mixins": [ + "${mod_id}.mixins.json", + "${mod_id}-fabric.mixins.json" + ], + "depends": { + "minecraft": "${minecraft_version_range_fabric}", + "fabricloader": ">=${fabric_loader_version}", + "fabric-api": "*", + "fabric-language-kotlin": ">=${fabric_kotlin_version}", + "cloth-config": "*", + "yarrp": "*" + }, + "suggests": { + "modmenu": "*" + }, + "custom": { + "modmenu": { + "links": { + "modmenu.discord": "https://discord.gg/Etq9EBYU7Q", + "modmenu.kofi": "https://ko-fi.com/rubixdev", + "modmenu.paypal": "https://paypal.me/RubixDev42", + "modmenu.github_releases": "https://github.com/RubixDev/Inventorio/releases", + "modmenu.modrinth": "https://modrinth.com/project/inventorio", + "modmenu.curseforge": "https://www.curseforge.com/minecraft/mc-mods/inventorio" + } } + } } From 297b9b7d7365e4a9404f2e8eb87f5fba129919a0 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Tue, 18 Nov 2025 20:27:06 +0100 Subject: [PATCH 5/7] fix: crash on NeoForge startup --- .../de/rubixdev/inventorio/InventorioNeoForge.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt index 25b91fd..b99ae2c 100644 --- a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/InventorioNeoForge.kt @@ -18,6 +18,7 @@ import net.minecraft.registry.Registries import net.neoforged.api.distmarker.Dist import net.neoforged.fml.ModLoadingContext import net.neoforged.fml.common.Mod +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent import net.neoforged.fml.loading.FMLEnvironment import net.neoforged.fml.loading.FMLPaths import net.neoforged.neoforge.client.gui.IConfigScreenFactory @@ -36,32 +37,33 @@ class InventorioNeoForge { private val neoForgeModIntegrations = listOf(ClumpsIntegration, CuriosIntegration) init { + val modBus = KotlinModLoadingContext.get().getKEventBus() + ScreenTypeProvider.INSTANCE = ScreenTypeProviderNeoForge InventorioNetworking.INSTANCE = InventorioNetworkingNeoForge //#if MC < 12101 //$$ val enchantmentRegistry = DeferredRegister.create(Registries.ENCHANTMENT, MOD_ID) - //$$ enchantmentRegistry.register(KotlinModLoadingContext.get().getKEventBus()) + //$$ enchantmentRegistry.register(modBus) //$$ enchantmentRegistry.register("deep_pockets") { -> DeepPocketsEnchantment } //#endif val recipeRegistry = DeferredRegister.create(Registries.RECIPE_SERIALIZER, MOD_ID) - recipeRegistry.register(KotlinModLoadingContext.get().getKEventBus()) + recipeRegistry.register(modBus) val serializer = SpecialRecipeSerializer { category -> DeepPocketsBookRecipe(category) } DeepPocketsBookRecipe.SERIALIZER = serializer recipeRegistry.register("deep_pockets_book") { -> serializer } - InventorioResources.register() - initToolBelt() - KotlinModLoadingContext.get().getKEventBus().register(InventorioNetworkingNeoForge) + modBus.register(InventorioNetworkingNeoForge) + modBus.addListener { InventorioResources.register() } if (FMLEnvironment.dist == Dist.CLIENT) { NeoForge.EVENT_BUS.register(NeoForgeEvents) - KotlinModLoadingContext.get().getKEventBus().register(NeoForgeModEvents) + modBus.register(NeoForgeModEvents) MinecraftClient.getInstance().options.allKeys += InventorioControls.keys PlayerSettings.load(FMLPaths.CONFIGDIR.get().resolve("inventorio.json").toFile()) - KotlinModLoadingContext.get().getKEventBus().register(ScreenTypeProviderNeoForge) + modBus.register(ScreenTypeProviderNeoForge) ModLoadingContext.get().registerExtensionPoint(IConfigScreenFactory::class.java) { IConfigScreenFactory { _, parent -> PlayerSettingsScreen.get(parent) } } From b7a3e1e893a76594d2e72a5bf0e913ec3d13e3d7 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Sat, 22 Nov 2025 19:35:18 +0100 Subject: [PATCH 6/7] fix: compat with curios --- .../neoforge/curios/HandledScreenMixin.java | 27 +++++++- .../curios/InventorioScreenHandlerMixin.java | 14 +++- .../curios/InventorioScreenMixin.java | 2 +- .../InventorioScreenHandlerMixinHelper.kt | 33 ++++++++- .../curios/InventorioScreenMixinHelper.kt | 67 +++++++++++++++++-- 5 files changed, 133 insertions(+), 10 deletions(-) diff --git a/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java index 1b8538e..205d64b 100644 --- a/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java +++ b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/HandledScreenMixin.java @@ -16,9 +16,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import top.theillusivec4.curios.common.inventory.CurioSlot; +//#if MC >= 12101 +import de.rubixdev.inventorio.client.ui.InventorioScreen; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +//#endif + @Restriction(require = { @Condition("curios"), @Condition(type = Condition.Type.TESTER, tester = CuriosTester.class) }) @Mixin(HandledScreen.class) -public class HandledScreenMixin extends Screen { +public abstract class HandledScreenMixin extends Screen { protected HandledScreenMixin(Text title) { super(title); } @@ -45,4 +51,23 @@ private void dontRenderCuriosWhenClosed(DrawContext context, Slot slot, Callback ci.cancel(); } } + + //#if MC >= 12101 + @ModifyVariable( + method = "drawSlot", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/screen/ScreenHandler;getCursorStack()Lnet/minecraft/item/ItemStack;", + ordinal = 0 + ) + ) + protected ItemStack drawSlot(ItemStack itemstack, DrawContext drawContext, Slot slot) { + // noinspection ConstantValue + if ((Screen) this instanceof InventorioScreen && slot instanceof CurioSlot curioSlot) { + return curioSlot.getSlotExtension().getDisplayStack(curioSlot.getSlotContext(), itemstack); + } + + return itemstack; + } + //#endif } diff --git a/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java index 7c8cc9b..fc25c39 100644 --- a/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java +++ b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenHandlerMixin.java @@ -22,9 +22,10 @@ import java.util.List; -//#if MC > 12101 +//#if MC >= 12101 import net.minecraft.recipe.CraftingRecipe; import net.minecraft.recipe.input.CraftingRecipeInput; +import net.minecraft.screen.slot.SlotActionType; //#else //$$ import net.minecraft.inventory.CraftingInventory; //#endif @@ -34,7 +35,7 @@ // target classes @Restriction(require = { @Condition("curios"), @Condition(type = Condition.Type.TESTER, tester = CuriosTester.class) }) @Mixin(InventorioScreenHandler.class) -//#if MC > 12101 +//#if MC >= 12101 public abstract class InventorioScreenHandlerMixin extends AbstractRecipeScreenHandler //#else //$$ public abstract class InventorioScreenHandlerMixin extends AbstractRecipeScreenHandler @@ -45,7 +46,7 @@ public InventorioScreenHandlerMixin(ScreenHandlerType arg, int i) { } @SuppressWarnings("DataFlowIssue") - //#if MC > 12101 + //#if MC >= 12101 @Unique private final InventorioScreenHandler thiz = (InventorioScreenHandler) (AbstractRecipeScreenHandler) this; //#else //$$ @Unique private final InventorioScreenHandler thiz = (InventorioScreenHandler) (AbstractRecipeScreenHandler) this; @@ -121,4 +122,11 @@ public void resetSlots() { private void curios$quickMove(PlayerEntity player, int sourceIndex, CallbackInfoReturnable cir) { helper.curios$quickMove(thiz, player, sourceIndex, cir); } + + //#if MC >= 12101 + @Inject(method = "onSlotClick", at = @At("HEAD"), cancellable = true) + private void curios$onSlotClick(int slotIndex, int clickDelta, SlotActionType actionType, PlayerEntity player, CallbackInfo ci) { + helper.curios$onSlotClick(thiz, slotIndex, actionType, player, ci); + } + //#endif } diff --git a/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java index 5da667e..7ecda40 100644 --- a/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java +++ b/versions/1.21.1-neoforge/src/main/java/de/rubixdev/inventorio/mixin/neoforge/curios/InventorioScreenMixin.java @@ -62,7 +62,7 @@ public InventorioScreenMixin(InventorioScreenHandler arg, PlayerInventory arg2, @Inject(method = "drawMouseoverTooltip", at = @At("RETURN")) private void curios$drawMouseoverTooltip(DrawContext context, int x, int y, CallbackInfo ci) { - helper.drawMouseoverTooltip(context, x, y); + helper.curios$drawMouseoverTooltip(thiz, context, x, y); } @Inject(method = "drawBackground", at = @At("RETURN")) diff --git a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt index feec618..28842ea 100644 --- a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenHandlerMixinHelper.kt @@ -25,9 +25,16 @@ import top.theillusivec4.curios.common.inventory.CurioSlot import top.theillusivec4.curios.common.network.server.SPacketPage import top.theillusivec4.curios.common.network.server.SPacketQuickMove +//#if MC >= 12101 +import net.minecraft.screen.slot.SlotActionType +//#endif + /** - * This is basically a re-implementation of https://github.com/TheIllusiveC4/Curios/blob/ab847aab52213afd87c78f48ad9382212846f1b7/neoforge/src/main/java/top/theillusivec4/curios/common/inventory/container/CuriosContainer.java + * This is basically a re-implementation of `CuriosContainer` * with adjustments for the Inventorio screen (and in Kotlin). + * + * - [1.20.6](https://github.com/TheIllusiveC4/Curios/blob/ab847aab52213afd87c78f48ad9382212846f1b7/neoforge/src/main/java/top/theillusivec4/curios/common/inventory/container/CuriosContainer.java) + * - [1.21.1](https://github.com/TheIllusiveC4/Curios/blob/6b122c8a7e2b514fd94197459ade11f19a0bfb09/neoforge/src/main/java/top/theillusivec4/curios/common/inventory/container/CuriosContainer.java) */ @Suppress("FunctionName") class InventorioScreenHandlerMixinHelper( @@ -53,6 +60,7 @@ class InventorioScreenHandlerMixinHelper( private set var panelWidth = 0 + @Suppress("CAST_NEVER_SUCCEEDS") private val thiss = thiz as ScreenHandlerAccessor fun InventorioScreenHandler.`curios$init`() { @@ -121,6 +129,9 @@ class InventorioScreenHandlerMixinHelper( (currentColumn - 1) * 18 + 7 - panelWidth, yOffset + (currentRow - 1) * 18, stacksHandler.renders, + //#if MC >= 12101 + stacksHandler.activeStates, + //#endif stacksHandler.canToggleRendering(), isCosmetic, isCosmetic, @@ -151,6 +162,9 @@ class InventorioScreenHandlerMixinHelper( (currentColumn - 1) * 18 + 7 - panelWidth, yOffset + (currentRow - 1) * 18, stacksHandler.renders, + //#if MC >= 12101 + stacksHandler.activeStates, + //#endif stacksHandler.canToggleRendering(), isCosmetic, isCosmetic, @@ -270,5 +284,22 @@ class InventorioScreenHandlerMixinHelper( } } + //#if MC >= 12101 + // i guess we don't actually need this, cos the inventorio screen can't be accessed from creative anyway, + // but it shouldn't hurt to have either + fun InventorioScreenHandler.`curios$onSlotClick`(slotId: Int, clickType: SlotActionType, player: PlayerEntity, ci: CallbackInfo) { + val slot = getSlot(slotId) + + if (slot is CurioSlot && clickType == SlotActionType.CLONE && player.isInCreativeMode && cursorStack.isEmpty) { + val stack = slot.slotExtension.getCloneStack(slot.slotContext, slot.stack) + + if (stack.isNotEmpty) { + cursorStack = stack.copyWithCount(stack.maxCount) + } + ci.cancel() + } + } + //#endif + private data class ProxySlot(val page: Int, val slot: Slot) } diff --git a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt index 4e8824b..937d0a8 100644 --- a/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt +++ b/versions/1.21.1-neoforge/src/main/kotlin/de/rubixdev/inventorio/integration/curios/InventorioScreenMixinHelper.kt @@ -23,9 +23,20 @@ import top.theillusivec4.curios.common.inventory.CurioSlot import top.theillusivec4.curios.common.network.client.CPacketPage import top.theillusivec4.curios.common.network.client.CPacketToggleRender +//#if MC >= 12101 +import de.rubixdev.inventorio.util.isNotEmpty +import net.minecraft.client.gui.screen.Screen +import net.minecraft.item.tooltip.TooltipType +import net.minecraft.util.Formatting +import net.neoforged.neoforge.client.ClientTooltipFlag +//#endif + /** - * This is basically a re-implementation of https://github.com/TheIllusiveC4/Curios/blob/ab847aab52213afd87c78f48ad9382212846f1b7/neoforge/src/main/java/top/theillusivec4/curios/client/gui/CuriosScreen.java + * This is basically a re-implementation of `CuriosScreen` * for the Inventorio screen (and in Kotlin). + * + * - [1.20.6](https://github.com/TheIllusiveC4/Curios/blob/ab847aab52213afd87c78f48ad9382212846f1b7/neoforge/src/main/java/top/theillusivec4/curios/client/gui/CuriosScreen.java) + * - [1.21.1](https://github.com/TheIllusiveC4/Curios/blob/6b122c8a7e2b514fd94197459ade11f19a0bfb09/neoforge/src/main/java/top/theillusivec4/curios/client/gui/CuriosScreen.java) */ @Suppress("FunctionName") class InventorioScreenMixinHelper( @@ -167,18 +178,66 @@ class InventorioScreenMixinHelper( val clientPlayer = MinecraftClient.getInstance().player if (!isRenderButtonHovered && clientPlayer != null && clientPlayer.playerScreenHandler.cursorStack.isEmpty) { slotUnderMouse?.let { slot -> - if (slot is CurioSlot && !slot.hasStack()) { - context.drawTooltip(thiss.textRenderer, Text.literal(slot.slotName), mouseX, mouseY) + //#if MC >= 12101 + if (slot is CurioSlot && minecraft != null) { + val stack = slot.slotExtension.getDisplayStack(slot.slotContext, slot.stack) + + if (stack.isEmpty) { + val slotTooltips = + slot.slotExtension.getSlotTooltip( + slot.slotContext, + ClientTooltipFlag.of( + when (minecraft.options.advancedItemTooltips) { + true -> TooltipType.ADVANCED + false -> TooltipType.BASIC + }, + ), + ).toMutableList() + + if (slotTooltips.isEmpty()) { + slotTooltips.add(Text.literal(slot.slotName)) + } + + if (!slot.isActiveState) { + slotTooltips.add(Text.translatable("curios.tooltip.inactive").formatted(Formatting.RED)) + } + + context.drawTooltip(thiss.textRenderer, slotTooltips, mouseX, mouseY) + } } + //#else + //$$ if (slot is CurioSlot && !slot.hasStack()) { + //$$ context.drawTooltip(thiss.textRenderer, Text.literal(slot.slotName), mouseX, mouseY) + //$$ } + //#endif } } } - fun drawMouseoverTooltip(context: DrawContext, x: Int, y: Int) { + fun InventorioScreen.`curios$drawMouseoverTooltip`(context: DrawContext, x: Int, y: Int) { thiss.client?.player?.let { player -> if (player.playerScreenHandler.cursorStack.isEmpty && isRenderButtonHovered) { context.drawTooltip(thiss.textRenderer, Text.translatable("gui.curios.toggle"), x, y) } + //#if MC >= 12101 + else slotUnderMouse?.let { slot -> + var stack = slot.stack + + if (slot is CurioSlot) { + stack = slot.slotExtension.getDisplayStack(slot.slotContext, stack) + } + + if (stack.isNotEmpty) { + val components = Screen.getTooltipFromItem(minecraft, stack) + + if (slot is CurioSlot && slot.isActiveState) { + components.add(Text.empty()) + components.add(Text.translatable("curios.tooltip.inactive").formatted(Formatting.RED)) + } + context.drawTooltip(thiss.textRenderer, components, stack.tooltipData, x, y) + } + } + //#endif } } From 3f265b0cf93f1a17581a924d0f0b288d27e1e1e3 Mon Sep 17 00:00:00 2001 From: RubixDev Date: Tue, 25 Nov 2025 18:50:41 +0100 Subject: [PATCH 7/7] fix(curios): make sure slot is always within range --- .../de/rubixdev/inventorio/player/InventorioScreenHandler.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt b/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt index 77d8c96..b7b9ab5 100644 --- a/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt +++ b/src/main/kotlin/de/rubixdev/inventorio/player/InventorioScreenHandler.kt @@ -408,6 +408,11 @@ class InventorioScreenHandler(syncId: Int, val inventory: PlayerInventory) : return RecipeBookCategory.CRAFTING } + // required for curios integration because curios does the same + override fun getSlot(index: Int): Slot { + return super.getSlot(index.coerceIn(slots.indices)) + } + @Suppress("RedundantOverride") // this makes it easier to add functionality for mod compat via mixin override fun setStackInSlot(slot: Int, revision: Int, stack: ItemStack?) { super.setStackInSlot(slot, revision, stack)