diff --git a/src/main/java/org/betterx/bclib/client/models/CustomModelBakery.java b/src/main/java/org/betterx/bclib/client/models/CustomModelBakery.java index 58abd0c4..f820c5f8 100644 --- a/src/main/java/org/betterx/bclib/client/models/CustomModelBakery.java +++ b/src/main/java/org/betterx/bclib/client/models/CustomModelBakery.java @@ -4,6 +4,7 @@ import org.betterx.bclib.api.v2.ModIntegrationAPI; import org.betterx.bclib.client.render.EmissiveTextureInfo; import org.betterx.bclib.interfaces.BlockModelProvider; import org.betterx.bclib.interfaces.ItemModelProvider; +import org.betterx.bclib.models.RecordItemModelProvider; import com.mojang.datafixers.util.Pair; import net.minecraft.client.renderer.block.BlockModelShaper; @@ -58,16 +59,23 @@ public class CustomModelBakery { } }); - Registry.ITEM.stream().parallel().filter(item -> item instanceof ItemModelProvider).forEach(item -> { - ResourceLocation registryID = Registry.ITEM.getKey(item); - ResourceLocation storageID = new ResourceLocation( - registryID.getNamespace(), - "models/item/" + registryID.getPath() + ".json" - ); - if (resourceManager.getResource(storageID).isEmpty()) { - addItemModel(registryID, (ItemModelProvider) item); - } - }); + Registry.ITEM.stream() + .parallel() + .filter(item -> item instanceof ItemModelProvider || RecordItemModelProvider.has(item)) + .forEach(item -> { + ResourceLocation registryID = Registry.ITEM.getKey(item); + ResourceLocation storageID = new ResourceLocation( + registryID.getNamespace(), + "models/item/" + registryID.getPath() + ".json" + ); + final ItemModelProvider provider = (item instanceof ItemModelProvider) + ? (ItemModelProvider) item + : RecordItemModelProvider.get(item); + + if (resourceManager.getResource(storageID).isEmpty()) { + addItemModel(registryID, provider); + } + }); } private void addBlockModel(ResourceLocation blockID, Block block) { diff --git a/src/main/java/org/betterx/bclib/items/BaseDiscItem.java b/src/main/java/org/betterx/bclib/items/BaseDiscItem.java index fecf586c..623f27db 100644 --- a/src/main/java/org/betterx/bclib/items/BaseDiscItem.java +++ b/src/main/java/org/betterx/bclib/items/BaseDiscItem.java @@ -1,17 +1,75 @@ package org.betterx.bclib.items; -import org.betterx.bclib.interfaces.ItemModelProvider; +import org.betterx.bclib.BCLib; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.item.RecordItem; -public class BaseDiscItem extends RecordItem implements ItemModelProvider { +import java.lang.reflect.Constructor; + +public class BaseDiscItem extends RecordItem { + /** + * @param comparatorOutput + * @param sound + * @param settings + * @deprecated Please use {@link BaseDiscItem#create(int, SoundEvent, Properties, int)} instead + */ @Deprecated(forRemoval = true) public BaseDiscItem(int comparatorOutput, SoundEvent sound, Properties settings) { this(comparatorOutput, sound, settings, 30); } + + /** + * @param comparatorOutput + * @param sound + * @param settings + * @param lengthInSeconds + * @deprecated Please use {@link BaseDiscItem#create(int, SoundEvent, Properties, int)} instead + */ + @Deprecated(forRemoval = true) public BaseDiscItem(int comparatorOutput, SoundEvent sound, Properties settings, int lengthInSeconds) { super(comparatorOutput, sound, settings); } + + public static RecordItem create(int comparatorOutput, SoundEvent sound, Properties settings, int lengthInSeconds) { + for (Constructor> c : RecordItem.class.getConstructors()) { + if (c.getParameterCount() == 4) { + var types = c.getParameterTypes(); + if (types.length == 4) { //1.19.1 Constructor + if ( + types[0].isAssignableFrom(int.class) + && types[1].isAssignableFrom(SoundEvent.class) + && types[2].isAssignableFrom(Properties.class) + && types[3].isAssignableFrom(int.class) + ) { + c.setAccessible(true); + try { + return (RecordItem) c.newInstance(comparatorOutput, sound, settings, lengthInSeconds); + } catch (Exception e) { + BCLib.LOGGER.error("Failed to instantiate RecordItem", e); + } + } + } + } else if (c.getParameterCount() == 3) { + var types = c.getParameterTypes(); + if (types.length == 3) { //1.19 constructor + if ( + types[0].isAssignableFrom(int.class) + && types[1].isAssignableFrom(SoundEvent.class) + && types[2].isAssignableFrom(Properties.class) + ) { + c.setAccessible(true); + try { + return (RecordItem) c.newInstance(comparatorOutput, sound, settings); + } catch (Exception e) { + BCLib.LOGGER.error("Failed to instantiate RecordItem", e); + } + } + } + } + } + BCLib.LOGGER.error("No Constructor for RecordItems found."); + return null; + } } diff --git a/src/main/java/org/betterx/bclib/models/RecordItemModelProvider.java b/src/main/java/org/betterx/bclib/models/RecordItemModelProvider.java new file mode 100644 index 00000000..34d33e53 --- /dev/null +++ b/src/main/java/org/betterx/bclib/models/RecordItemModelProvider.java @@ -0,0 +1,48 @@ +package org.betterx.bclib.models; + +import org.betterx.bclib.interfaces.ItemModelProvider; + +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.RecordItem; + +import java.util.HashMap; +import java.util.Map; +import org.jetbrains.annotations.ApiStatus; + +/** + * This was just added because the constructor of a RecordItem from 1.19 to 1.19.1 changed + * and we only need to add the {@link ItemModelProvider} interface. + *
+ * In order to keep cross version compat for bclib we choose to use reflection to instanciate + * RecordItem, but we need an additional registry that will provide the {@link ItemModelProvider} + * for RecordItems. + *
+ * This class (and and all according changes in
+ * {@link org.betterx.bclib.client.models.CustomModelBakery#loadCustomModels(ResourceManager)} can
+ * be abandoned when we drop support for 1.19.
+ */
+@ApiStatus.Internal
+public class RecordItemModelProvider {
+ @ApiStatus.Internal
+ public static final ItemModelProvider DEFAULT_PROVIDER = new ItemModelProvider() {
+ };
+ private static final Map