From 618d9f74bb1cf2a9b39c61aa16f3c99f5893482d Mon Sep 17 00:00:00 2001 From: PinkGoosik Date: Tue, 23 Jan 2024 13:57:09 +0500 Subject: [PATCH] make trinkets and curios optional dependencies --- .../resources/assets/winterly/lang/en_us.json | 6 ++ .../resources/assets/winterly/lang/ru_ru.json | 6 ++ .../resources/assets/winterly/lang/zh_cn.json | 6 ++ fabric/build.gradle | 4 +- .../fabric/client/WinterlyFabricClient.java | 20 ++++-- .../compat/WinterlyTrinketsIntegration.java | 71 +++++++++++++++++++ .../winterly/fabric/item/SantaHatItem.java | 60 +++++++++------- .../java/winterly/fabric/item/ScarfItem.java | 60 +++++++++------- .../mixin/client/ArmorRendererMixin.java | 23 ++---- fabric/src/main/resources/fabric.mod.json | 1 - gradle.properties | 2 +- neoforge/build.gradle | 3 +- .../winterly/neoforge/WinterlyNeoforge.java | 45 +----------- .../client/WinterlyNeoforgeClient.java | 65 +++++++++++++++++ .../compat/WinterlyCuriosIntegration.java | 60 ++++++++++++++++ .../winterly/neoforge/item/SantaHatItem.java | 61 +++++++--------- .../winterly/neoforge/item/ScarfItem.java | 61 +++++++--------- 17 files changed, 362 insertions(+), 192 deletions(-) create mode 100644 fabric/src/main/java/winterly/fabric/compat/WinterlyTrinketsIntegration.java create mode 100644 neoforge/src/main/java/winterly/neoforge/client/WinterlyNeoforgeClient.java create mode 100644 neoforge/src/main/java/winterly/neoforge/compat/WinterlyCuriosIntegration.java diff --git a/common/src/main/resources/assets/winterly/lang/en_us.json b/common/src/main/resources/assets/winterly/lang/en_us.json index 2dced3f..cc0312d 100644 --- a/common/src/main/resources/assets/winterly/lang/en_us.json +++ b/common/src/main/resources/assets/winterly/lang/en_us.json @@ -5,6 +5,12 @@ "modmenu.descriptionTranslation.winterly": "Winter expansion mod adding cold and sloppy stuff.", + "tip.winterly.requires_trinkets.0": "Requires Trinkets mod to be installed", + "tip.winterly.requires_trinkets.1": "in order to be wearable.", + + "tip.winterly.requires_curios.0": "Requires Curios API to be installed", + "tip.winterly.requires_curios.1": "in order to be wearable.", + "item.winterly.red_candy_cane": "Red Candy Cane", "item.winterly.green_candy_cane": "Green Candy Cane", "item.winterly.blue_candy_cane": "Blue Candy Cane", diff --git a/common/src/main/resources/assets/winterly/lang/ru_ru.json b/common/src/main/resources/assets/winterly/lang/ru_ru.json index 28671b7..1f79440 100644 --- a/common/src/main/resources/assets/winterly/lang/ru_ru.json +++ b/common/src/main/resources/assets/winterly/lang/ru_ru.json @@ -5,6 +5,12 @@ "modmenu.descriptionTranslation.winterly": "Мод расширяющий зиму и добавляющий праздничные предметы.", + "tip.winterly.requires_trinkets.0": "Для ношения требуется", + "tip.winterly.requires_trinkets.1": "установка мода Trinkets.", + + "tip.winterly.requires_curios.0": "Для ношения требуется", + "tip.winterly.requires_curios.1": "установка мода Curios API.", + "item.winterly.red_candy_cane": "Красный леденец", "item.winterly.green_candy_cane": "Зеленый леденец", "item.winterly.blue_candy_cane": "Синий леденец", diff --git a/common/src/main/resources/assets/winterly/lang/zh_cn.json b/common/src/main/resources/assets/winterly/lang/zh_cn.json index af23a78..117c243 100644 --- a/common/src/main/resources/assets/winterly/lang/zh_cn.json +++ b/common/src/main/resources/assets/winterly/lang/zh_cn.json @@ -5,6 +5,12 @@ "modmenu.descriptionTranslation.winterly": "Winter expansion mod adding cold and sloppy stuff.", + "tip.winterly.requires_trinkets.0": "Requires Trinkets mod to be installed", + "tip.winterly.requires_trinkets.1": "in order to be wearable.", + + "tip.winterly.requires_curios.0": "Requires Curios API to be installed", + "tip.winterly.requires_curios.1": "in order to be wearable.", + "item.winterly.red_candy_cane": "红色条纹拐杖糖", "item.winterly.green_candy_cane": "绿色条纹拐杖糖", "item.winterly.blue_candy_cane": "蓝色条纹拐杖糖", diff --git a/fabric/build.gradle b/fabric/build.gradle index 8a3b154..a52dc56 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -39,9 +39,9 @@ dependencies { modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" // Remove the next line if you don't want to depend on the API //modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" - + modImplementation "dev.emi:trinkets:${project.trinkets_version}" - modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cca_version}" + modImplementation include("dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cca_version}") modImplementation "dev.onyxstudios.cardinal-components-api:cardinal-components-entity:${project.cca_version}" modImplementation include("dev.onyxstudios.cardinal-components-api:cardinal-components-world:${project.cca_version}") modApi "io.wispforest:owo-lib:${project.owo_lib}" diff --git a/fabric/src/main/java/winterly/fabric/client/WinterlyFabricClient.java b/fabric/src/main/java/winterly/fabric/client/WinterlyFabricClient.java index b14e4fb..6f12b5b 100644 --- a/fabric/src/main/java/winterly/fabric/client/WinterlyFabricClient.java +++ b/fabric/src/main/java/winterly/fabric/client/WinterlyFabricClient.java @@ -1,10 +1,9 @@ package winterly.fabric.client; -import dev.emi.trinkets.api.client.TrinketRenderer; -import dev.emi.trinkets.api.client.TrinketRendererRegistry; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRendererRegistrationCallback; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.DrownedRenderer; import net.minecraft.client.renderer.entity.SkeletonRenderer; @@ -15,6 +14,9 @@ import winterly.client.model.ScarfModel; import winterly.client.render.DecorationFeatureRenderer; import winterly.client.render.MobDecorationRenderers; +import winterly.fabric.compat.WinterlyTrinketsIntegration; +import winterly.item.CommonSantaHatItem; +import winterly.item.CommonScarfItem; import winterly.registry.CommonWinterlyBlocks; import winterly.registry.CommonWinterlyItems; @@ -42,9 +44,16 @@ public void onInitializeClient() { map.putBlock(CommonWinterlyBlocks.ICICLE_PANE, RenderType.translucent()); map.putBlock(CommonWinterlyBlocks.ICICLE_BARS, RenderType.cutout()); - CommonWinterlyItems.ITEMS.forEach((id, item) -> { - if(item instanceof TrinketRenderer renderer) TrinketRendererRegistry.registerRenderer(item, renderer); - }); + if(FabricLoader.getInstance().isModLoaded("trinkets")) { + CommonWinterlyItems.ITEMS.forEach((id, item) -> { + if(item instanceof CommonScarfItem scarf) { + WinterlyTrinketsIntegration.registerScarfRenderer(scarf); + } + if(item instanceof CommonSantaHatItem hat) { + WinterlyTrinketsIntegration.registerSantaHatRenderer(hat); + } + }); + } LivingEntityFeatureRendererRegistrationCallback.EVENT.register((entityType, entityRenderer, registrationHelper, context) -> { if(entityRenderer instanceof ZombieRenderer renderer) { @@ -57,7 +66,6 @@ public void onInitializeClient() { registrationHelper.register(new DecorationFeatureRenderer<>(renderer)); } }); - } } diff --git a/fabric/src/main/java/winterly/fabric/compat/WinterlyTrinketsIntegration.java b/fabric/src/main/java/winterly/fabric/compat/WinterlyTrinketsIntegration.java new file mode 100644 index 0000000..f5911c7 --- /dev/null +++ b/fabric/src/main/java/winterly/fabric/compat/WinterlyTrinketsIntegration.java @@ -0,0 +1,71 @@ +package winterly.fabric.compat; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import dev.emi.trinkets.api.SlotReference; +import dev.emi.trinkets.api.Trinket; +import dev.emi.trinkets.api.TrinketComponent; +import dev.emi.trinkets.api.TrinketsApi; +import dev.emi.trinkets.api.client.TrinketRenderer; +import dev.emi.trinkets.api.client.TrinketRendererRegistry; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.util.Tuple; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import winterly.Winterly; +import winterly.client.model.WinterlyModels; +import winterly.fabric.item.SantaHatItem; +import winterly.item.CommonSantaHatItem; +import winterly.item.CommonScarfItem; + +import java.util.Optional; + +public class WinterlyTrinketsIntegration { + + + public static void registerTrinket(Item item) { + TrinketsApi.registerTrinket(item, new Trinket() {}); + } + + public static boolean hasHatOn(Player player) { + Optional component = TrinketsApi.getTrinketComponent(player); + if(component.isPresent()) { + for(Tuple pair : component.get().getAllEquipped()) { + if(pair.getB().getItem() instanceof SantaHatItem) return true; + } + } + return false; + } + + public static void registerScarfRenderer(CommonScarfItem scarf) { + TrinketRendererRegistry.registerRenderer(scarf, new TrinketRenderer() { + @Override + public void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, PoseStack matrices, MultiBufferSource vertexConsumers, int light, LivingEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { + if(contextModel instanceof HumanoidModel biped){ + WinterlyModels.SCARF_MODEL.scarf.copyFrom(biped.body); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + scarf.color + "_scarf.png"))); + WinterlyModels.SCARF_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + } + } + }); + } + + public static void registerSantaHatRenderer(CommonSantaHatItem hat) { + TrinketRendererRegistry.registerRenderer(hat, new TrinketRenderer() { + @Override + public void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, PoseStack matrices, MultiBufferSource vertexConsumers, int light, LivingEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { + if(contextModel instanceof HumanoidModel biped) { + WinterlyModels.SANTA_HAT_MODEL.hat.copyFrom(biped.head); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + hat.color + "_santa_hat.png"))); + WinterlyModels.SANTA_HAT_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + } + } + }); + } +} diff --git a/fabric/src/main/java/winterly/fabric/item/SantaHatItem.java b/fabric/src/main/java/winterly/fabric/item/SantaHatItem.java index dd49cd2..730cdee 100644 --- a/fabric/src/main/java/winterly/fabric/item/SantaHatItem.java +++ b/fabric/src/main/java/winterly/fabric/item/SantaHatItem.java @@ -1,39 +1,49 @@ package winterly.fabric.item; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import dev.emi.trinkets.api.SlotReference; -import dev.emi.trinkets.api.Trinket; -import dev.emi.trinkets.api.TrinketsApi; -import dev.emi.trinkets.api.client.TrinketRenderer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.world.entity.LivingEntity; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.ChatFormatting; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import winterly.Winterly; -import winterly.client.model.WinterlyModels; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; +import winterly.fabric.compat.WinterlyTrinketsIntegration; import winterly.item.CommonSantaHatItem; -public class SantaHatItem extends CommonSantaHatItem implements Trinket, TrinketRenderer { +import java.util.List; + +public class SantaHatItem extends CommonSantaHatItem { public SantaHatItem(Item.Properties settings, String color) { super(settings, color); - TrinketsApi.registerTrinket(this, this); + if(FabricLoader.getInstance().isModLoaded("trinkets")) { + WinterlyTrinketsIntegration.registerTrinket(this); + } } - @Environment(EnvType.CLIENT) - @Override - public void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, PoseStack matrices, MultiBufferSource vertexConsumers, int light, LivingEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { - if(contextModel instanceof HumanoidModel biped) { - WinterlyModels.SANTA_HAT_MODEL.hat.copyFrom(biped.head); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + color + "_santa_hat.png"))); - WinterlyModels.SANTA_HAT_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); - } - } + @Environment(EnvType.CLIENT) + @Override + public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag context) { + tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); + tooltip.add(Component.nullToEmpty(" ")); + + if(!FabricLoader.getInstance().isModLoaded("trinkets")) { + Language lang = Language.getInstance(); + String key = "tip.winterly.requires_trinkets."; + + for(int i = 0; i <= 32; i++) { + if(lang.has(key + i)) { + tooltip.add(Component.translatable(key + i).toFlatList(Style.EMPTY.withColor(ChatFormatting.GRAY)).get(0)); + } + if(!lang.has(key + (i + 1))) { + break; + } + } + } + } } diff --git a/fabric/src/main/java/winterly/fabric/item/ScarfItem.java b/fabric/src/main/java/winterly/fabric/item/ScarfItem.java index f1682c1..d1a8630 100644 --- a/fabric/src/main/java/winterly/fabric/item/ScarfItem.java +++ b/fabric/src/main/java/winterly/fabric/item/ScarfItem.java @@ -1,39 +1,49 @@ package winterly.fabric.item; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import dev.emi.trinkets.api.SlotReference; -import dev.emi.trinkets.api.Trinket; -import dev.emi.trinkets.api.TrinketsApi; -import dev.emi.trinkets.api.client.TrinketRenderer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.world.entity.LivingEntity; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.ChatFormatting; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import winterly.Winterly; -import winterly.client.model.WinterlyModels; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; +import winterly.fabric.compat.WinterlyTrinketsIntegration; import winterly.item.CommonScarfItem; -public class ScarfItem extends CommonScarfItem implements Trinket, TrinketRenderer { +import java.util.List; + +public class ScarfItem extends CommonScarfItem { public ScarfItem(Item.Properties settings, String color) { super(settings, color); - TrinketsApi.registerTrinket(this, this); + if(FabricLoader.getInstance().isModLoaded("trinkets")) { + WinterlyTrinketsIntegration.registerTrinket(this); + } } - @Environment(EnvType.CLIENT) - @Override - public void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, PoseStack matrices, MultiBufferSource vertexConsumers, int light, LivingEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { - if(contextModel instanceof HumanoidModel biped){ - WinterlyModels.SCARF_MODEL.scarf.copyFrom(biped.body); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + color + "_scarf.png"))); - WinterlyModels.SCARF_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); - } - } + @Environment(EnvType.CLIENT) + @Override + public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag context) { + tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); + tooltip.add(Component.nullToEmpty(" ")); + + if(!FabricLoader.getInstance().isModLoaded("trinkets")) { + Language lang = Language.getInstance(); + String key = "tip.winterly.requires_trinkets."; + + for(int i = 0; i <= 32; i++) { + if(lang.has(key + i)) { + tooltip.add(Component.translatable(key + i).toFlatList(Style.EMPTY.withColor(ChatFormatting.GRAY)).get(0)); + } + if(!lang.has(key + (i + 1))) { + break; + } + } + } + } } diff --git a/fabric/src/main/java/winterly/fabric/mixin/client/ArmorRendererMixin.java b/fabric/src/main/java/winterly/fabric/mixin/client/ArmorRendererMixin.java index e03210f..75c7f28 100644 --- a/fabric/src/main/java/winterly/fabric/mixin/client/ArmorRendererMixin.java +++ b/fabric/src/main/java/winterly/fabric/mixin/client/ArmorRendererMixin.java @@ -1,25 +1,20 @@ package winterly.fabric.mixin.client; import com.mojang.blaze3d.vertex.PoseStack; -import dev.emi.trinkets.api.SlotReference; -import dev.emi.trinkets.api.TrinketComponent; -import dev.emi.trinkets.api.TrinketsApi; +import net.fabricmc.loader.api.FabricLoader; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import winterly.fabric.item.SantaHatItem; -import java.util.Optional; +import winterly.fabric.compat.WinterlyTrinketsIntegration; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.RenderLayerParent; import net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer; import net.minecraft.client.renderer.entity.layers.RenderLayer; -import net.minecraft.util.Tuple; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; @Mixin(HumanoidArmorLayer.class) public abstract class ArmorRendererMixin , A extends HumanoidModel> extends RenderLayer { @@ -31,19 +26,9 @@ public ArmorRendererMixin(RenderLayerParent context) { @Inject(method = "renderArmorPiece", at = @At("HEAD"), cancellable = true) void render(PoseStack matrices, MultiBufferSource vertexConsumers, T entity, EquipmentSlot armorSlot, int light, A model, CallbackInfo ci) { if(entity instanceof Player player) { - if(armorSlot.equals(EquipmentSlot.HEAD)) { - if(winterly$hasHatOn(player)) ci.cancel(); + if(FabricLoader.getInstance().isModLoaded("trinkets") && armorSlot.equals(EquipmentSlot.HEAD)) { + if(WinterlyTrinketsIntegration.hasHatOn(player)) ci.cancel(); } } } - - boolean winterly$hasHatOn(Player player) { - Optional component = TrinketsApi.getTrinketComponent(player); - if(component.isPresent()) { - for(Tuple pair : component.get().getAllEquipped()) { - if(pair.getB().getItem() instanceof SantaHatItem) return true; - } - } - return false; - } } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 10afb19..5b5ff99 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -50,7 +50,6 @@ "fabricloader": "*", "fabric-api": "*", "cloth-config": "*", - "trinkets": "*", "minecraft": "${minecraft_version_range_fabric}", "java": ">=17" } diff --git a/gradle.properties b/gradle.properties index 9056614..1e033ce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ maven_group = ru.pinkgoosik # Mod Properties mod_name = Winterly -mod_version = 0.10.0+1.20.4 +mod_version = 0.10.1+1.20.4 mod_description = Winter expansion mod adding cold and sloppy stuff. mod_id = winterly homepage_url = https://github.com/tyap-lyap/winterly diff --git a/neoforge/build.gradle b/neoforge/build.gradle index e56651a..cb097c6 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -36,7 +36,7 @@ dependencies { // Remove the next line if you don't want to depend on the API // modApi "dev.architectury:architectury-neoforge:${rootProject.architectury_version}" - + modCompileOnly("top.theillusivec4.curios:curios-neoforge:${rootProject.curios_version}:api") // Use the full Curios API jar at runtime modRuntimeOnly("top.theillusivec4.curios:curios-neoforge:${rootProject.curios_version}") @@ -47,7 +47,6 @@ dependencies { shadowCommon(project(path: ":common", configuration: "transformProductionNeoForge")) { transitive = false } } - processResources { inputs.property "version", project.version diff --git a/neoforge/src/main/java/winterly/neoforge/WinterlyNeoforge.java b/neoforge/src/main/java/winterly/neoforge/WinterlyNeoforge.java index 252e0ed..a1edb5e 100644 --- a/neoforge/src/main/java/winterly/neoforge/WinterlyNeoforge.java +++ b/neoforge/src/main/java/winterly/neoforge/WinterlyNeoforge.java @@ -1,28 +1,16 @@ package winterly.neoforge; -import net.minecraft.client.renderer.entity.*; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.ModLoadingContext; import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.neoforge.client.ConfigScreenHandler; -import net.neoforged.neoforge.client.event.EntityRenderersEvent; import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; import net.neoforged.neoforge.registries.DeferredRegister; -import top.theillusivec4.curios.api.client.CuriosRendererRegistry; -import top.theillusivec4.curios.api.client.ICurioRenderer; import winterly.Winterly; -import winterly.client.WinterlyModelLayers; -import winterly.client.model.SantaHatModel; -import winterly.client.model.ScarfModel; -import winterly.client.render.DecorationFeatureRenderer; -import winterly.client.render.MobDecorationRenderers; -import winterly.config.WinterlyClientConfig; +import winterly.neoforge.client.WinterlyNeoforgeClient; import winterly.neoforge.data.WinterlyDataAttachments; import winterly.neoforge.registry.WinterlyBlockEntities; import winterly.neoforge.registry.WinterlyBlocks; @@ -50,13 +38,10 @@ public WinterlyNeoforge(IEventBus bus) { WinterlyDataAttachments.init(bus); bus.addListener(this::buildCreativeTab); - bus.addListener(this::registerModelLayers); - bus.addListener(this::registerRenderLayers); - bus.addListener(this::clientSetup); bus.addListener(this::commonSetup); if(FMLEnvironment.dist.isClient()) { - ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> WinterlyClientConfig.buildScreen(parent))); + new WinterlyNeoforgeClient().init(bus); } } @@ -67,32 +52,6 @@ private void buildCreativeTab(BuildCreativeModeTabContentsEvent event) { } } - private void registerModelLayers(EntityRenderersEvent.RegisterLayerDefinitions event) { - event.registerLayerDefinition(WinterlyModelLayers.SANTA_HAT_LAYER, SantaHatModel::getTexturedModelData); - event.registerLayerDefinition(WinterlyModelLayers.SCARF_LAYER, ScarfModel::getTexturedModelData); - } - - private void registerRenderLayers(EntityRenderersEvent.AddLayers event) { - event.getContext().getEntityRenderDispatcher().renderers.forEach((entityType, entityRenderer) -> { - if(entityRenderer instanceof ZombieRenderer renderer) { - renderer.addLayer(new DecorationFeatureRenderer<>(renderer)); - } - if(entityRenderer instanceof DrownedRenderer renderer) { - renderer.addLayer(new DecorationFeatureRenderer<>(renderer)); - } - if(entityRenderer instanceof SkeletonRenderer renderer) { - renderer.addLayer(new DecorationFeatureRenderer<>(renderer)); - } - }); - } - - private void clientSetup(FMLClientSetupEvent event) { - CommonWinterlyItems.ITEMS.forEach((resourceLocation, item) -> { - if(item instanceof ICurioRenderer renderer) CuriosRendererRegistry.register(item, () -> renderer); - }); - MobDecorationRenderers.init(); - } - private void commonSetup(FMLCommonSetupEvent event) { } diff --git a/neoforge/src/main/java/winterly/neoforge/client/WinterlyNeoforgeClient.java b/neoforge/src/main/java/winterly/neoforge/client/WinterlyNeoforgeClient.java new file mode 100644 index 0000000..2ed92bf --- /dev/null +++ b/neoforge/src/main/java/winterly/neoforge/client/WinterlyNeoforgeClient.java @@ -0,0 +1,65 @@ +package winterly.neoforge.client; + +import net.minecraft.client.renderer.entity.DrownedRenderer; +import net.minecraft.client.renderer.entity.SkeletonRenderer; +import net.minecraft.client.renderer.entity.ZombieRenderer; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModList; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.ConfigScreenHandler; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import winterly.client.WinterlyModelLayers; +import winterly.client.model.SantaHatModel; +import winterly.client.model.ScarfModel; +import winterly.client.render.DecorationFeatureRenderer; +import winterly.client.render.MobDecorationRenderers; +import winterly.config.WinterlyClientConfig; +import winterly.item.CommonSantaHatItem; +import winterly.item.CommonScarfItem; +import winterly.neoforge.compat.WinterlyCuriosIntegration; +import winterly.registry.CommonWinterlyItems; + +@OnlyIn(Dist.CLIENT) +public class WinterlyNeoforgeClient { + + public void init(IEventBus bus) { + bus.addListener(this::clientSetup); + bus.addListener(this::registerModelLayers); + bus.addListener(this::registerRenderLayers); + } + + private void registerModelLayers(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(WinterlyModelLayers.SANTA_HAT_LAYER, SantaHatModel::getTexturedModelData); + event.registerLayerDefinition(WinterlyModelLayers.SCARF_LAYER, ScarfModel::getTexturedModelData); + } + + private void registerRenderLayers(EntityRenderersEvent.AddLayers event) { + event.getContext().getEntityRenderDispatcher().renderers.forEach((entityType, entityRenderer) -> { + if(entityRenderer instanceof ZombieRenderer renderer) { + renderer.addLayer(new DecorationFeatureRenderer<>(renderer)); + } + if(entityRenderer instanceof DrownedRenderer renderer) { + renderer.addLayer(new DecorationFeatureRenderer<>(renderer)); + } + if(entityRenderer instanceof SkeletonRenderer renderer) { + renderer.addLayer(new DecorationFeatureRenderer<>(renderer)); + } + }); + } + + private void clientSetup(FMLClientSetupEvent event) { + if(ModList.get().isLoaded("curios")) { + CommonWinterlyItems.ITEMS.forEach((resourceLocation, item) -> { + if(item instanceof CommonScarfItem scarf) WinterlyCuriosIntegration.registerScarfRenderer(scarf); + if(item instanceof CommonSantaHatItem hat) WinterlyCuriosIntegration.registerSantaHatRenderer(hat); + }); + } + + MobDecorationRenderers.init(); + + ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> WinterlyClientConfig.buildScreen(parent))); + } +} diff --git a/neoforge/src/main/java/winterly/neoforge/compat/WinterlyCuriosIntegration.java b/neoforge/src/main/java/winterly/neoforge/compat/WinterlyCuriosIntegration.java new file mode 100644 index 0000000..4c5f71e --- /dev/null +++ b/neoforge/src/main/java/winterly/neoforge/compat/WinterlyCuriosIntegration.java @@ -0,0 +1,60 @@ +package winterly.neoforge.compat; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import top.theillusivec4.curios.api.CuriosApi; +import top.theillusivec4.curios.api.SlotContext; +import top.theillusivec4.curios.api.client.CuriosRendererRegistry; +import top.theillusivec4.curios.api.client.ICurioRenderer; +import top.theillusivec4.curios.api.type.capability.ICurioItem; +import winterly.Winterly; +import winterly.client.model.WinterlyModels; +import winterly.item.CommonSantaHatItem; +import winterly.item.CommonScarfItem; + +public class WinterlyCuriosIntegration { + + public static void registerCurio(Item item) { + CuriosApi.registerCurio(item, new ICurioItem() {}); + } + + public static void registerScarfRenderer(CommonScarfItem scarf) { + CuriosRendererRegistry.register(scarf, () -> { + return new ICurioRenderer() { + @Override + public > void render(ItemStack stack, SlotContext slotContext, PoseStack matrices, RenderLayerParent renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) { + if(renderLayerParent.getModel() instanceof HumanoidModel biped){ + WinterlyModels.SCARF_MODEL.scarf.copyFrom(biped.body); + VertexConsumer vertexConsumer = renderTypeBuffer.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + scarf.color + "_scarf.png"))); + WinterlyModels.SCARF_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + } + } + }; + }); + } + + public static void registerSantaHatRenderer(CommonSantaHatItem hat) { + CuriosRendererRegistry.register(hat, () -> { + return new ICurioRenderer() { + @Override + public > void render(ItemStack stack, SlotContext slotContext, PoseStack matrices, RenderLayerParent renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) { + if(renderLayerParent.getModel() instanceof HumanoidModel biped) { + WinterlyModels.SANTA_HAT_MODEL.hat.copyFrom(biped.head); + VertexConsumer vertexConsumer = renderTypeBuffer.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + hat.color + "_santa_hat.png"))); + WinterlyModels.SANTA_HAT_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + } + } + }; + }); + } + +} diff --git a/neoforge/src/main/java/winterly/neoforge/item/SantaHatItem.java b/neoforge/src/main/java/winterly/neoforge/item/SantaHatItem.java index 9be059c..db9dd97 100644 --- a/neoforge/src/main/java/winterly/neoforge/item/SantaHatItem.java +++ b/neoforge/src/main/java/winterly/neoforge/item/SantaHatItem.java @@ -1,57 +1,50 @@ package winterly.neoforge.item; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.ChatFormatting; -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.LivingEntity; +import net.minecraft.network.chat.Style; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; +import net.neoforged.fml.ModList; import org.jetbrains.annotations.Nullable; -import top.theillusivec4.curios.api.CuriosApi; -import top.theillusivec4.curios.api.SlotContext; -import top.theillusivec4.curios.api.client.ICurioRenderer; -import top.theillusivec4.curios.api.type.capability.ICurioItem; -import winterly.Winterly; -import winterly.client.model.WinterlyModels; import winterly.item.CommonSantaHatItem; +import winterly.neoforge.compat.WinterlyCuriosIntegration; import java.util.List; -public class SantaHatItem extends CommonSantaHatItem implements ICurioRenderer { +public class SantaHatItem extends CommonSantaHatItem { public SantaHatItem(Item.Properties settings, String color) { super(settings, color); - CuriosApi.registerCurio(this, new ICurioItem() { - - @Override - public boolean canEquip(SlotContext slotContext, ItemStack stack) { - return true; - } - }); + if(ModList.get().isLoaded("curios")) { + WinterlyCuriosIntegration.registerCurio(this); + } } @Override public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag context) { - tooltip.add(Component.nullToEmpty(" ")); - tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); - } - - @Override - public > void render(ItemStack stack, SlotContext slotContext, PoseStack matrices, RenderLayerParent renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) { - if(renderLayerParent.getModel() instanceof HumanoidModel biped) { - WinterlyModels.SANTA_HAT_MODEL.hat.copyFrom(biped.head); - VertexConsumer vertexConsumer = renderTypeBuffer.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + color + "_santa_hat.png"))); - WinterlyModels.SANTA_HAT_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); - } + if(!ModList.get().isLoaded("curios")) { + tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); + tooltip.add(Component.nullToEmpty(" ")); + Language lang = Language.getInstance(); + String key = "tip.winterly.requires_curios."; + + for(int i = 0; i <= 32; i++) { + if(lang.has(key + i)) { + tooltip.add(Component.translatable(key + i).toFlatList(Style.EMPTY.withColor(ChatFormatting.GRAY)).get(0)); + } + if(!lang.has(key + (i + 1))) { + break; + } + } + } + else { + tooltip.add(Component.nullToEmpty(" ")); + tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); + } } } diff --git a/neoforge/src/main/java/winterly/neoforge/item/ScarfItem.java b/neoforge/src/main/java/winterly/neoforge/item/ScarfItem.java index c359d90..d838c67 100644 --- a/neoforge/src/main/java/winterly/neoforge/item/ScarfItem.java +++ b/neoforge/src/main/java/winterly/neoforge/item/ScarfItem.java @@ -1,57 +1,50 @@ package winterly.neoforge.item; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.ChatFormatting; -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.model.HumanoidModel; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.LivingEntity; +import net.minecraft.network.chat.Style; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; +import net.neoforged.fml.ModList; import org.jetbrains.annotations.Nullable; -import top.theillusivec4.curios.api.CuriosApi; -import top.theillusivec4.curios.api.SlotContext; -import top.theillusivec4.curios.api.client.ICurioRenderer; -import top.theillusivec4.curios.api.type.capability.ICurioItem; -import winterly.Winterly; -import winterly.client.model.WinterlyModels; import winterly.item.CommonScarfItem; +import winterly.neoforge.compat.WinterlyCuriosIntegration; import java.util.List; -public class ScarfItem extends CommonScarfItem implements ICurioRenderer { +public class ScarfItem extends CommonScarfItem { public ScarfItem(Item.Properties settings, String color) { super(settings, color); - CuriosApi.registerCurio(this, new ICurioItem() { - - @Override - public boolean canEquip(SlotContext slotContext, ItemStack stack) { - return true; - } - }); + if(ModList.get().isLoaded("curios")) { + WinterlyCuriosIntegration.registerCurio(this); + } } @Override public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag context) { - tooltip.add(Component.nullToEmpty(" ")); - tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); - } - - @Override - public > void render(ItemStack stack, SlotContext slotContext, PoseStack matrices, RenderLayerParent renderLayerParent, MultiBufferSource renderTypeBuffer, int light, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) { - if(renderLayerParent.getModel() instanceof HumanoidModel biped){ - WinterlyModels.SCARF_MODEL.scarf.copyFrom(biped.body); - VertexConsumer vertexConsumer = renderTypeBuffer.getBuffer(RenderType.entityCutout(Winterly.id("textures/entity/" + color + "_scarf.png"))); - WinterlyModels.SCARF_MODEL.renderToBuffer(matrices, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); - } + if(!ModList.get().isLoaded("curios")) { + tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); + tooltip.add(Component.nullToEmpty(" ")); + Language lang = Language.getInstance(); + String key = "tip.winterly.requires_curios."; + + for(int i = 0; i <= 32; i++) { + if(lang.has(key + i)) { + tooltip.add(Component.translatable(key + i).toFlatList(Style.EMPTY.withColor(ChatFormatting.GRAY)).get(0)); + } + if(!lang.has(key + (i + 1))) { + break; + } + } + } + else { + tooltip.add(Component.nullToEmpty(" ")); + tooltip.add(Component.translatable("tag.winterly.cosmetic").withStyle(ChatFormatting.GRAY)); + } } }