diff --git a/build.gradle b/build.gradle index a0ee97f9..6a0531d6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.6-SNAPSHOT' + id 'fabric-loom' version '1.7-SNAPSHOT' id 'maven-publish' } diff --git a/gradle.properties b/gradle.properties index d45b02f9..b86a651c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,17 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx2G -minecraft_version=1.21 -yarn_mappings=1.21+build.9 -loader_version=0.15.11 +minecraft_version=1.21.4 +yarn_mappings=1.21.4+build.1 +loader_version=0.16.9 -mod_version = 3.10.0 +mod_version = 3.11.0 maven_group = dev.emi archives_base_name = trinkets -fabric_version=0.100.0+1.21 -cca_version=6.1.0 -mod_menu_version=10.0.0-beta.1 -emi_version=1.1.10+1.21 -rei_version=15.0.728 -cloth_config_version=14.0.126 +fabric_version=0.112.2+1.21.4 +cca_version=6.2.2 +mod_menu_version=13.0.0 +emi_version=1.1.16+1.21.1 +rei_version=18.0.796 +cloth_config_version=17.0.144 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a..a4413138 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/dev/emi/trinkets/SurvivalTrinketSlot.java b/src/main/java/dev/emi/trinkets/SurvivalTrinketSlot.java index ed92075e..d18f621e 100644 --- a/src/main/java/dev/emi/trinkets/SurvivalTrinketSlot.java +++ b/src/main/java/dev/emi/trinkets/SurvivalTrinketSlot.java @@ -5,6 +5,7 @@ import dev.emi.trinkets.api.SlotType; import dev.emi.trinkets.api.TrinketInventory; import dev.emi.trinkets.api.TrinketsApi; +import dev.emi.trinkets.mixin.accessor.RecipeBookScreenAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; @@ -55,7 +56,7 @@ public boolean isEnabled() { MinecraftClient client = MinecraftClient.getInstance(); Screen s = client.currentScreen; if (s instanceof InventoryScreen screen) { - if (screen.getRecipeBookWidget().isOpen()) { + if (((RecipeBookScreenAccessor) screen).getRecipeBook().isOpen()) { return false; } } diff --git a/src/main/java/dev/emi/trinkets/TrinketEntityRenderState.java b/src/main/java/dev/emi/trinkets/TrinketEntityRenderState.java new file mode 100644 index 00000000..6a1cdd84 --- /dev/null +++ b/src/main/java/dev/emi/trinkets/TrinketEntityRenderState.java @@ -0,0 +1,12 @@ +package dev.emi.trinkets; + +import dev.emi.trinkets.api.SlotReference; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Pair; + +import java.util.List; + +public interface TrinketEntityRenderState { + void trinkets$setState(List> items); + List> trinkets$getState(); +} diff --git a/src/main/java/dev/emi/trinkets/TrinketFeatureRenderer.java b/src/main/java/dev/emi/trinkets/TrinketFeatureRenderer.java index 734f6b24..13207da3 100644 --- a/src/main/java/dev/emi/trinkets/TrinketFeatureRenderer.java +++ b/src/main/java/dev/emi/trinkets/TrinketFeatureRenderer.java @@ -1,31 +1,49 @@ package dev.emi.trinkets; +import dev.emi.trinkets.api.SlotReference; +import dev.emi.trinkets.api.TrinketComponent; import dev.emi.trinkets.api.TrinketsApi; import dev.emi.trinkets.api.client.TrinketRendererRegistry; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Pair; -public class TrinketFeatureRenderer> extends FeatureRenderer { +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class TrinketFeatureRenderer> extends FeatureRenderer { public TrinketFeatureRenderer(FeatureRendererContext context) { super(context); } + public static void update(LivingEntity livingEntity, LivingEntityRenderState entityState, float tickDelta, TrinketEntityRenderState state) { + Optional component = TrinketsApi.getTrinketComponent(livingEntity); + if (component.isEmpty()) { + state.trinkets$setState(List.of()); + } else { + List> items = new ArrayList<>(); + component.get().forEach((slotReference, stack) -> items.add(new Pair<>(stack, slotReference))); + state.trinkets$setState(items); + } + } + @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { - TrinketsApi.getTrinketComponent(entity).ifPresent(component -> - component.forEach((slotReference, stack) -> - TrinketRendererRegistry.getRenderer(stack.getItem()).ifPresent(renderer -> { - matrices.push(); - renderer.render(stack, slotReference, this.getContextModel(), matrices, vertexConsumers, - light, entity, limbAngle, limbDistance, tickDelta, animationProgress, headYaw, headPitch); - matrices.pop(); - }) - ) - ); + public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T state, float limbAngle, float limbDistance) { + ((TrinketEntityRenderState) state).trinkets$getState().forEach(pair -> { + TrinketRendererRegistry.getRenderer(pair.getLeft().getItem()).ifPresent(renderer -> { + matrices.push(); + renderer.render(pair.getLeft(), pair.getRight(), this.getContextModel(), matrices, vertexConsumers, + light, state, limbAngle, limbDistance); + matrices.pop(); + }); + }); } } diff --git a/src/main/java/dev/emi/trinkets/TrinketScreenManager.java b/src/main/java/dev/emi/trinkets/TrinketScreenManager.java index c14ac248..060edd83 100644 --- a/src/main/java/dev/emi/trinkets/TrinketScreenManager.java +++ b/src/main/java/dev/emi/trinkets/TrinketScreenManager.java @@ -9,6 +9,7 @@ import dev.emi.trinkets.api.TrinketsApi; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.util.math.Rect2i; import net.minecraft.screen.slot.Slot; import net.minecraft.util.Identifier; @@ -196,13 +197,13 @@ public static void drawGroup(DrawContext context, SlotGroup group, SlotType type int x = r.getX() - 4 - (slotsWidth - 1) / 2 * 18; int y = r.getY() - 4; if (slotsWidth > 1 || type != null) { - context.drawTexture(MORE_SLOTS, x, y, 0, 0, 4, 26); + drawTexture(context, MORE_SLOTS, x, y, 0, 0, 4, 26); for (int i = 0; i < slotsWidth; i++) { - context.drawTexture(MORE_SLOTS, x + i * 18 + 4, y, 4, 0, 18, 26); + drawTexture(context, MORE_SLOTS, x + i * 18 + 4, y, 4, 0, 18, 26); } - context.drawTexture(MORE_SLOTS, x + slotsWidth * 18 + 4, y, 22, 0, 4, 26); + drawTexture(context, MORE_SLOTS, x + slotsWidth * 18 + 4, y, 22, 0, 4, 26); for (int s = 0; s < slotHeights.size() && s < slotTypes.size(); s++) { if (slotTypes.get(s) != type) { continue; @@ -214,18 +215,18 @@ public static void drawGroup(DrawContext context, SlotGroup group, SlotType type int bottom = height / 2; int slotX = slotHeight.x() - 4 + r.getX(); if (height > 2) { - context.drawTexture(MORE_SLOTS, slotX, y - top * 18, 0, 0, 26, 4); + drawTexture(context, MORE_SLOTS, slotX, y - top * 18, 0, 0, 26, 4); } for (int i = 1; i < top + 1; i++) { - context.drawTexture(MORE_SLOTS, slotX, y - i * 18 + 4, 0, 4, 26, 18); + drawTexture(context, MORE_SLOTS, slotX, y - i * 18 + 4, 0, 4, 26, 18); } for (int i = 1; i < bottom + 1; i++) { - context.drawTexture(MORE_SLOTS, slotX, y + i * 18 + 4, 0, 4, 26, 18); + drawTexture(context, MORE_SLOTS, slotX, y + i * 18 + 4, 0, 4, 26, 18); } - context.drawTexture(MORE_SLOTS, slotX, y + 18 + bottom * 18 + 4, 0, 22, 26, 4); + drawTexture(context, MORE_SLOTS, slotX, y + 18 + bottom * 18 + 4, 0, 22, 26, 4); } } @@ -241,23 +242,27 @@ public static void drawGroup(DrawContext context, SlotGroup group, SlotType type int slotX = slotHeight.x() + r.getX() + 1; int top = (height - 1) / 2; int bottom = height / 2; - context.drawTexture(MORE_SLOTS, slotX, y - top * 18 + 1, 4, 1, 16, 3); - context.drawTexture(MORE_SLOTS, slotX, y + (bottom + 1) * 18 + 4, 4, 22, 16, 3); + drawTexture(context, MORE_SLOTS, slotX, y - top * 18 + 1, 4, 1, 16, 3); + drawTexture(context, MORE_SLOTS, slotX, y + (bottom + 1) * 18 + 4, 4, 22, 16, 3); } // Because pre-existing slots are not part of the slotHeights list if (group.getSlotId() != -1) { - context.drawTexture(MORE_SLOTS, r.getX() + 1, y + 1, 4, 1, 16, 3); - context.drawTexture(MORE_SLOTS, r.getX() + 1, y + 22, 4, 22, 16, 3); + drawTexture(context, MORE_SLOTS, r.getX() + 1, y + 1, 4, 1, 16, 3); + drawTexture(context, MORE_SLOTS, r.getX() + 1, y + 22, 4, 22, 16, 3); } } else { - context.drawTexture(MORE_SLOTS, x + 4, y + 4, 4, 4, 18, 18); + drawTexture(context, MORE_SLOTS, x + 4, y + 4, 4, 4, 18, 18); } context.getMatrices().pop(); RenderSystem.disableDepthTest(); } + private static void drawTexture(DrawContext context, Identifier texture, int x, int y, int u, int v, int width, int height) { + context.drawTexture(RenderLayer::getGuiTextured, texture, x, y, u, v, width, height, 256, 256); + } + public static void drawActiveGroup(DrawContext context) { if (TrinketsClient.activeGroup != null) { TrinketScreenManager.drawGroup(context, TrinketsClient.activeGroup, TrinketsClient.activeType); @@ -280,41 +285,45 @@ public static void drawExtraGroups(DrawContext context) { height = 4; width--; } - context.drawTexture(MORE_SLOTS, x + 3, y, 7, 26, 1, 7); + drawTexture(context, MORE_SLOTS, x + 3, y, 7, 26, 1, 7); // Repeated tops and bottoms for (int i = 0; i < width; i++) { - context.drawTexture(MORE_SLOTS, x - 15 - 18 * i, y, 7, 26, 18, 7); - context.drawTexture(MORE_SLOTS, x - 15 - 18 * i, y + 79, 7, 51, 18, 7); + drawTexture(context, MORE_SLOTS, x - 15 - 18 * i, y, 7, 26, 18, 7); + drawTexture(context, MORE_SLOTS, x - 15 - 18 * i, y + 79, 7, 51, 18, 7); } // Top and bottom - context.drawTexture(MORE_SLOTS, x - 15 - 18 * width, y, 7, 26, 18, 7); - context.drawTexture(MORE_SLOTS, x - 15 - 18 * width, y + 7 + 18 * height, 7, 51, 18, 7); + drawTexture(context, MORE_SLOTS, x - 15 - 18 * width, y, 7, 26, 18, 7); + drawTexture(context, MORE_SLOTS, x - 15 - 18 * width, y + 7 + 18 * height, 7, 51, 18, 7); // Corners - context.drawTexture(MORE_SLOTS, x - 22 - 18 * width, y, 0, 26, 7, 7); - context.drawTexture(MORE_SLOTS, x - 22 - 18 * width, y + 7 + 18 * height, 0, 51, 7, 7); + drawTexture(context, MORE_SLOTS, x - 22 - 18 * width, y, 0, 26, 7, 7); + drawTexture(context, MORE_SLOTS, x - 22 - 18 * width, y + 7 + 18 * height, 0, 51, 7, 7); // Outer sides for (int i = 0; i < height; i++) { - context.drawTexture(MORE_SLOTS, x - 22 - 18 * width, y + 7 + 18 * i, 0, 34, 7, 18); + drawTexture(context, MORE_SLOTS, x - 22 - 18 * width, y + 7 + 18 * i, 0, 34, 7, 18); } // Inner sides if (width > 0) { for (int i = height; i < 4; i++) { - context.drawTexture(MORE_SLOTS, x - 4 - 18 * width, y + 7 + 18 * i, 0, 34, 7, 18); + drawTexture(context, MORE_SLOTS, x - 4 - 18 * width, y + 7 + 18 * i, 0, 34, 7, 18); } } if (width > 0 && height < 4) { // Bottom corner - context.drawTexture(MORE_SLOTS, x - 4 - 18 * width, y + 79, 0, 51, 7, 7); + drawTexture(context, MORE_SLOTS, x - 4 - 18 * width, y + 79, 0, 51, 7, 7); // Inner corner - context.drawTexture(MORE_SLOTS, x - 4 - 18 * width, y + 7 + 18 * height, 0, 58, 7, 7); + drawTexture(context, MORE_SLOTS, x - 4 - 18 * width, y + 7 + 18 * height, 0, 58, 7, 7); } if (width > 0 || height == 4) { // Inner corner - context.drawTexture(MORE_SLOTS, x, y + 79, 0, 58, 3, 7); + drawTexture(context, MORE_SLOTS, x, y + 79, 0, 58, 3, 7); } } public static boolean isClickInsideTrinketBounds(double mouseX, double mouseY) { + if (currentScreen == null || MinecraftClient.getInstance().currentScreen != currentScreen) { + return false; + } + TrinketPlayerScreenHandler handler = currentScreen.trinkets$getHandler(); int x = currentScreen.trinkets$getX(); int y = currentScreen.trinkets$getY(); diff --git a/src/main/java/dev/emi/trinkets/TrinketsMain.java b/src/main/java/dev/emi/trinkets/TrinketsMain.java index 7a0af59d..315db7a2 100644 --- a/src/main/java/dev/emi/trinkets/TrinketsMain.java +++ b/src/main/java/dev/emi/trinkets/TrinketsMain.java @@ -14,8 +14,8 @@ import net.minecraft.item.ItemStack; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; -import net.minecraft.util.TypedActionResult; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -59,10 +59,10 @@ public void onInitialize() { Trinket trinket = TrinketsApi.getTrinket(stack.getItem()); if (trinket.canEquipFromUse(stack, player)) { if (TrinketItem.equipItem(player, stack)) { - return TypedActionResult.success(stack); + return ActionResult.SUCCESS; } } - return TypedActionResult.pass(stack); + return ActionResult.PASS; }); Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(MOD_ID, "attribute_modifiers"), TrinketsAttributeModifiersComponent.TYPE); PayloadTypeRegistry.playS2C().register(TrinketsNetwork.BREAK, BreakPayload.CODEC); diff --git a/src/main/java/dev/emi/trinkets/api/LivingEntityTrinketComponent.java b/src/main/java/dev/emi/trinkets/api/LivingEntityTrinketComponent.java index d3b80bf6..d3339926 100644 --- a/src/main/java/dev/emi/trinkets/api/LivingEntityTrinketComponent.java +++ b/src/main/java/dev/emi/trinkets/api/LivingEntityTrinketComponent.java @@ -19,6 +19,7 @@ import net.minecraft.network.RegistryByteBuf; import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import org.ladysnake.cca.api.v3.component.sync.AutoSyncedComponent; import net.minecraft.entity.LivingEntity; @@ -87,8 +88,8 @@ public void update() { } else { if (this.entity instanceof PlayerEntity player) { player.getInventory().offerOrDrop(stack); - } else { - this.entity.dropStack(stack); + } else if (this.entity.getWorld() instanceof ServerWorld serverWorld) { + this.entity.dropStack(serverWorld, stack); } } } @@ -230,8 +231,10 @@ public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup lookup) { } } } - for (ItemStack itemStack : dropped) { - this.entity.dropStack(itemStack); + if (this.entity.getWorld() instanceof ServerWorld serverWorld) { + for (ItemStack itemStack : dropped) { + this.entity.dropStack(serverWorld, itemStack); + } } Multimap slotMap = HashMultimap.create(); this.forEach((ref, stack) -> { @@ -309,7 +312,7 @@ public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup lookup) { NbtList list = new NbtList(); TrinketInventory inv = slot.getValue(); for (int i = 0; i < inv.size(); i++) { - NbtCompound c = (NbtCompound) inv.getStack(i).encodeAllowEmpty(lookup); + NbtCompound c = (NbtCompound) inv.getStack(i).toNbtAllowEmpty(lookup); list.add(c); } slotTag.put("Metadata", this.syncing ? inv.getSyncTag() : inv.toTag()); diff --git a/src/main/java/dev/emi/trinkets/api/Trinket.java b/src/main/java/dev/emi/trinkets/api/Trinket.java index 51146f1c..64648f68 100644 --- a/src/main/java/dev/emi/trinkets/api/Trinket.java +++ b/src/main/java/dev/emi/trinkets/api/Trinket.java @@ -9,18 +9,21 @@ import dev.emi.trinkets.mixin.accessor.LivingEntityAccessor; import java.util.function.Consumer; +import net.minecraft.component.DataComponentTypes; import net.minecraft.component.EnchantmentEffectComponentTypes; +import net.minecraft.component.type.EquippableComponent; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeModifier; -import net.minecraft.item.Equipment; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; public interface Trinket { @@ -100,7 +103,11 @@ default boolean canEquipFromUse(ItemStack stack, LivingEntity entity) { * @return The {@link SoundEvent} to play for equipping */ default RegistryEntry getEquipSound(ItemStack stack, SlotReference slot, LivingEntity entity) { - return stack.getItem() instanceof Equipment eq ? eq.getEquipSound() : null; + EquippableComponent component = stack.get(DataComponentTypes.EQUIPPABLE); + if (component != null) { + return component.equipSound(); + } + return Registries.SOUND_EVENT.getEntry(SoundEvents.INTENTIONALLY_EMPTY); } /** diff --git a/src/main/java/dev/emi/trinkets/api/TrinketInventory.java b/src/main/java/dev/emi/trinkets/api/TrinketInventory.java index 44ce7b78..87eec4ed 100644 --- a/src/main/java/dev/emi/trinkets/api/TrinketInventory.java +++ b/src/main/java/dev/emi/trinkets/api/TrinketInventory.java @@ -10,6 +10,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.collection.DefaultedList; @@ -178,7 +179,9 @@ public void update() { if (i < newStacks.size()) { newStacks.set(i, stack); } else { - entity.dropStack(stack); + if (entity.getWorld() instanceof ServerWorld serverWorld) { + entity.dropStack(serverWorld, stack); + } } } diff --git a/src/main/java/dev/emi/trinkets/api/TrinketItem.java b/src/main/java/dev/emi/trinkets/api/TrinketItem.java index 4fd9318e..f8671284 100644 --- a/src/main/java/dev/emi/trinkets/api/TrinketItem.java +++ b/src/main/java/dev/emi/trinkets/api/TrinketItem.java @@ -7,8 +7,8 @@ import net.minecraft.item.ItemStack; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.sound.SoundEvent; +import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; @@ -27,10 +27,10 @@ public TrinketItem(Item.Settings settings) { } @Override - public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + public ActionResult use(World world, PlayerEntity user, Hand hand) { ItemStack stack = user.getStackInHand(hand); if (equipItem(user, stack)) { - return TypedActionResult.success(stack, world.isClient()); + return ActionResult.SUCCESS; } return super.use(world, user, hand); } diff --git a/src/main/java/dev/emi/trinkets/api/TrinketsAttributeModifiersComponent.java b/src/main/java/dev/emi/trinkets/api/TrinketsAttributeModifiersComponent.java index 3746b96b..0a3d2c35 100644 --- a/src/main/java/dev/emi/trinkets/api/TrinketsAttributeModifiersComponent.java +++ b/src/main/java/dev/emi/trinkets/api/TrinketsAttributeModifiersComponent.java @@ -32,7 +32,7 @@ public record TrinketsAttributeModifiersComponent(List modifiers, boolean public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( Entry.PACKET_CODEC.collect(PacketCodecs.toList()), TrinketsAttributeModifiersComponent::modifiers, - PacketCodecs.BOOL, + PacketCodecs.BOOLEAN, TrinketsAttributeModifiersComponent::showInTooltip, TrinketsAttributeModifiersComponent::new); diff --git a/src/main/java/dev/emi/trinkets/api/client/TrinketRenderer.java b/src/main/java/dev/emi/trinkets/api/client/TrinketRenderer.java index 3df10428..2134c955 100644 --- a/src/main/java/dev/emi/trinkets/api/client/TrinketRenderer.java +++ b/src/main/java/dev/emi/trinkets/api/client/TrinketRenderer.java @@ -8,8 +8,13 @@ import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.model.ModelWithHead; import net.minecraft.client.render.entity.model.PlayerEntityModel; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.EntityRenderState; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.RotationAxis; @@ -23,51 +28,39 @@ public interface TrinketRenderer { * @param slotReference The exact slot for the item being rendered * @param contextModel The model this Trinket is being rendered on */ - void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, LivingEntity entity, - float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, - float headPitch); + void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, + MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, LivingEntityRenderState state, + float limbAngle, float limbDistance); /** * Rotates the rendering for the models based on the entity's poses and movements. This will do * nothing if the entity render object does not implement {@link LivingEntityRenderer} or if the * model does not implement {@link BipedEntityModel}). * - * @param entity The wearer of the trinket + * @param entityModel The model of wearer of the trinket * @param model The model to align to the body movement */ @SuppressWarnings("unchecked") - static void followBodyRotations(final LivingEntity entity, final BipedEntityModel model) { - - EntityRenderer render = MinecraftClient.getInstance() - .getEntityRenderDispatcher().getRenderer(entity); - - if (render instanceof LivingEntityRenderer) { - //noinspection unchecked - LivingEntityRenderer> livingRenderer = - (LivingEntityRenderer>) render; - EntityModel entityModel = livingRenderer.getModel(); - - if (entityModel instanceof BipedEntityModel) { - BipedEntityModel bipedModel = (BipedEntityModel) entityModel; - bipedModel.copyBipedStateTo(model); - } + static void followBodyRotations(final EntityModel entityModel, final BipedEntityModel model) { + if (entityModel instanceof BipedEntityModel bipedModel) { + //noinspection rawtypes + bipedModel.copyTransforms((BipedEntityModel) model); } } /** * Translates the rendering context to the center of the player's face */ - static void translateToFace(MatrixStack matrices, PlayerEntityModel model, - AbstractClientPlayerEntity player, float headYaw, float headPitch) { + static void translateToFace(MatrixStack matrices, ModelWithHead model, + BipedEntityRenderState state, float headYaw, float headPitch) { - if (player.isInSwimmingPose() || player.isFallFlying()) { - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(model.head.roll)); + if (state.isSwimming || state.isGliding) { + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(model.getHead().roll)); matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(headYaw)); matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-45.0F)); } else { - if (player.isInSneakingPose() && !model.riding) { + if (state.isInSneakingPose || state.isInPose(EntityPose.SITTING)) { matrices.translate(0.0F, 0.25F, 0.0F); } matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(headYaw)); @@ -79,10 +72,10 @@ static void translateToFace(MatrixStack matrices, PlayerEntityModel model, - AbstractClientPlayerEntity player) { + static void translateToChest(MatrixStack matrices, BipedEntityModel model, + BipedEntityRenderState state) { - if (player.isInSneakingPose() && !model.riding && !player.isSwimming()) { + if (state.isInSneakingPose && !state.isInPose(EntityPose.SITTING) && !state.isSwimming) { matrices.translate(0.0F, 0.2F, 0.0F); matrices.multiply(RotationAxis.POSITIVE_X.rotation(model.body.pitch)); } @@ -93,10 +86,10 @@ static void translateToChest(MatrixStack matrices, PlayerEntityModel model, - AbstractClientPlayerEntity player) { + static void translateToRightArm(MatrixStack matrices, BipedEntityModel model, + BipedEntityRenderState state) { - if (player.isInSneakingPose() && !model.riding && !player.isSwimming()) { + if (state.isInSneakingPose && !state.isInPose(EntityPose.SITTING) && !state.isSwimming) { matrices.translate(0.0F, 0.2F, 0.0F); } matrices.multiply(RotationAxis.POSITIVE_Y.rotation(model.body.yaw)); @@ -110,10 +103,10 @@ static void translateToRightArm(MatrixStack matrices, PlayerEntityModel model, - AbstractClientPlayerEntity player) { + static void translateToLeftArm(MatrixStack matrices, BipedEntityModel model, + BipedEntityRenderState state) { - if (player.isInSneakingPose() && !model.riding && !player.isSwimming()) { + if (state.isInSneakingPose && !state.isInPose(EntityPose.SITTING) && !state.isSwimming) { matrices.translate(0.0F, 0.2F, 0.0F); } matrices.multiply(RotationAxis.POSITIVE_Y.rotation(model.body.yaw)); @@ -127,10 +120,10 @@ static void translateToLeftArm(MatrixStack matrices, PlayerEntityModel model, - AbstractClientPlayerEntity player) { + static void translateToRightLeg(MatrixStack matrices, BipedEntityModel model, + BipedEntityRenderState state) { - if (player.isInSneakingPose() && !model.riding && !player.isSwimming()) { + if (state.isInSneakingPose && !state.isInPose(EntityPose.SITTING) && !state.isSwimming) { matrices.translate(0.0F, 0.0F, 0.25F); } matrices.translate(-0.125F, 0.75F, 0.0F); @@ -143,10 +136,9 @@ static void translateToRightLeg(MatrixStack matrices, PlayerEntityModel model, - AbstractClientPlayerEntity player) { - - if (player.isInSneakingPose() && !model.riding && !player.isSwimming()) { + static void translateToLeftLeg(MatrixStack matrices, BipedEntityModel model, + BipedEntityRenderState state) { + if (state.isInSneakingPose && !state.isInPose(EntityPose.SITTING) && !state.isSwimming) { matrices.translate(0.0F, 0.0F, 0.25F); } matrices.translate(0.125F, 0.75F, 0.0F); diff --git a/src/main/java/dev/emi/trinkets/data/EntitySlotLoader.java b/src/main/java/dev/emi/trinkets/data/EntitySlotLoader.java index 7aa185ba..c5875953 100644 --- a/src/main/java/dev/emi/trinkets/data/EntitySlotLoader.java +++ b/src/main/java/dev/emi/trinkets/data/EntitySlotLoader.java @@ -145,7 +145,7 @@ protected void apply(Map>> loader, ResourceManag types.addAll(entityTypes);*/ } else { - types.add(Registries.ENTITY_TYPE.getOrEmpty(Identifier.of(entityName)) + types.add(Registries.ENTITY_TYPE.getOptionalValue(Identifier.of(entityName)) .orElseThrow(() -> new IllegalArgumentException("Unknown entity '" + entityName + "'"))); } } catch (IllegalArgumentException e) { @@ -212,6 +212,6 @@ public Identifier getFabricId() { @Override public Collection getFabricDependencies() { - return Lists.newArrayList(SlotLoader.ID, ResourceReloadListenerKeys.TAGS); + return Lists.newArrayList(SlotLoader.ID); } } \ No newline at end of file diff --git a/src/main/java/dev/emi/trinkets/mixin/CreativeInventoryScreenMixin.java b/src/main/java/dev/emi/trinkets/mixin/CreativeInventoryScreenMixin.java index d50fe2b4..a299782a 100644 --- a/src/main/java/dev/emi/trinkets/mixin/CreativeInventoryScreenMixin.java +++ b/src/main/java/dev/emi/trinkets/mixin/CreativeInventoryScreenMixin.java @@ -1,6 +1,7 @@ package dev.emi.trinkets.mixin; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.HandledScreen; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -18,7 +19,6 @@ import dev.emi.trinkets.TrinketsClient; import dev.emi.trinkets.api.SlotGroup; import dev.emi.trinkets.api.TrinketsApi; -import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen.CreativeScreenHandler; import net.minecraft.client.util.math.Rect2i; @@ -33,7 +33,7 @@ * @author Emi */ @Mixin(CreativeInventoryScreen.class) -public abstract class CreativeInventoryScreenMixin extends AbstractInventoryScreen implements TrinketScreen { +public abstract class CreativeInventoryScreenMixin extends HandledScreen implements TrinketScreen { @Shadow private static ItemGroup selectedTab; @Shadow diff --git a/src/main/java/dev/emi/trinkets/mixin/EnchantmentHelperMixin.java b/src/main/java/dev/emi/trinkets/mixin/EnchantmentHelperMixin.java index 92cce259..9a5794cc 100644 --- a/src/main/java/dev/emi/trinkets/mixin/EnchantmentHelperMixin.java +++ b/src/main/java/dev/emi/trinkets/mixin/EnchantmentHelperMixin.java @@ -63,7 +63,7 @@ private static void forEachTrinket(LivingEntity entity, EnchantmentHelper.Contex } } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EquipmentSlot;values()[Lnet/minecraft/entity/EquipmentSlot;"), method = "chooseEquipmentWith") + @Inject(at = @At(value = "INVOKE", target = "Ljava/util/List;iterator()Ljava/util/Iterator;", ordinal = 0), method = "chooseEquipmentWith") private static void addTrinketsAsChoices(ComponentType componentType, LivingEntity entity, Predicate stackPredicate, CallbackInfoReturnable> info, @Local List list) { Optional optional = TrinketsApi.getTrinketComponent(entity); if (optional.isPresent()) { diff --git a/src/main/java/dev/emi/trinkets/mixin/HandledScreenMixin.java b/src/main/java/dev/emi/trinkets/mixin/HandledScreenMixin.java index 1f871ee9..d3a6c4c5 100644 --- a/src/main/java/dev/emi/trinkets/mixin/HandledScreenMixin.java +++ b/src/main/java/dev/emi/trinkets/mixin/HandledScreenMixin.java @@ -1,11 +1,17 @@ package dev.emi.trinkets.mixin; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.mojang.blaze3d.systems.RenderSystem; import dev.emi.trinkets.TrinketScreenManager; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.InventoryScreen; +import net.minecraft.client.render.RenderLayer; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -21,6 +27,8 @@ import net.minecraft.screen.slot.Slot; import net.minecraft.util.Identifier; +import java.util.function.Function; + /** * Draws trinket slot backs, adjusts z location of draw calls, and makes non-trinket slots un-interactable while a trinket slot group is focused * @@ -28,6 +36,8 @@ */ @Mixin(HandledScreen.class) public abstract class HandledScreenMixin extends Screen { + @Shadow @Nullable protected Slot focusedSlot; + @Shadow @Final private static Identifier SLOT_HIGHLIGHT_BACK_TEXTURE; @Unique private static final Identifier MORE_SLOTS = Identifier.of("trinkets", "textures/gui/more_slots.png"); @Unique @@ -58,22 +68,39 @@ private void changeZ(DrawContext context, Slot slot, CallbackInfo info) { slotTextureId = BLANK_BACK; } - RenderSystem.enableDepthTest(); - if (ts.isTrinketFocused()) { // Thus, I need to draw trinket slot backs over normal items at z 300 (310 was chosen) - context.drawTexture(slotTextureId, slot.x, slot.y, 310, 0, 0, 16, 16, 16, 16); + context.getMatrices().translate(0, 0, 310); + context.drawTexture(RenderLayer::getGuiTextured, slotTextureId, slot.x, slot.y, 0, 0, 16, 16, 16, 16); + if (this.focusedSlot == slot && this.focusedSlot.canBeHighlighted()) { + context.drawGuiTexture(RenderLayer::getGuiTextured, SLOT_HIGHLIGHT_BACK_TEXTURE, this.focusedSlot.x - 4, this.focusedSlot.y - 4, 24, 24); + } + context.getMatrices().translate(0, 0, -310); // I also need to draw items in trinket slots *above* 310 but *below* 400, (320 for items and 370 for tooltips was chosen) context.getMatrices().translate(0, 0, 70); } else { - context.drawTexture(slotTextureId, slot.x, slot.y, 0, 0, 0, 16, 16, 16, 16); - context.drawTexture(MORE_SLOTS, slot.x - 1, slot.y - 1, 0, 4, 4, 18, 18, 256, 256); + context.drawTexture(RenderLayer::getGuiTextured, slotTextureId, slot.x, slot.y, 0, 0, 16, 16, 16, 16); + context.drawTexture(RenderLayer::getGuiTextured, MORE_SLOTS, slot.x - 1, slot.y - 1, 4, 4, 18, 18, 256, 256); } } - if (TrinketsClient.activeGroup != null && TrinketsClient.activeGroup.getSlotId() == slot.id) { - context.getMatrices().translate(0, 0, 70); - } + } + @WrapOperation(method = "drawSlotHighlightFront", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIII)V")) + private void changeZForHighlightFront(DrawContext context, Function renderLayers, Identifier sprite, int x, int y, int width, int height, Operation original) { + assert this.focusedSlot != null; + if (this.focusedSlot instanceof TrinketSlot) { + context.getMatrices().push(); + context.getMatrices().translate(0, 0, 100 + 310 + 70 + 70 + 1); + original.call(context, renderLayers, sprite, x, y, width, height); + context.getMatrices().pop(); + } else if (this.focusedSlot instanceof TrinketSlot) { + context.getMatrices().push(); + context.getMatrices().translate(0, 0, 100 + 310 + 70 + 70 + 1); + original.call(context, renderLayers, sprite, x, y, width, height); + context.getMatrices().pop(); + } else { + original.call(context, renderLayers, sprite, x, y, width, height); + } } @Inject(at = @At("HEAD"), method = "isPointOverSlot", cancellable = true) diff --git a/src/main/java/dev/emi/trinkets/mixin/InventoryScreenMixin.java b/src/main/java/dev/emi/trinkets/mixin/InventoryScreenMixin.java index aed37fd6..5af6b2c7 100644 --- a/src/main/java/dev/emi/trinkets/mixin/InventoryScreenMixin.java +++ b/src/main/java/dev/emi/trinkets/mixin/InventoryScreenMixin.java @@ -1,18 +1,18 @@ package dev.emi.trinkets.mixin; +import dev.emi.trinkets.mixin.accessor.RecipeBookScreenAccessor; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.RecipeBookScreen; 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import dev.emi.trinkets.Point; import dev.emi.trinkets.TrinketPlayerScreenHandler; import dev.emi.trinkets.TrinketScreen; import dev.emi.trinkets.TrinketScreenManager; import dev.emi.trinkets.api.SlotGroup; -import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; import net.minecraft.client.gui.screen.ingame.InventoryScreen; import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; import net.minecraft.client.util.math.Rect2i; @@ -25,9 +25,10 @@ * @author Emi */ @Mixin(InventoryScreen.class) -public abstract class InventoryScreenMixin extends AbstractInventoryScreen implements RecipeBookProvider, TrinketScreen { - - private InventoryScreenMixin() { super(null, null, null); } +public abstract class InventoryScreenMixin extends RecipeBookScreen implements RecipeBookProvider, TrinketScreen { + public InventoryScreenMixin() { + super(null, null, null, null); + } @Inject(at = @At("HEAD"), method = "init") private void init(CallbackInfo info) { @@ -53,13 +54,7 @@ private void drawBackground(DrawContext context, float delta, int mouseX, int mo private void drawForeground(DrawContext context, int mouseX, int mouseY, CallbackInfo info) { TrinketScreenManager.drawActiveGroup(context); } - - @Inject(at = @At("HEAD"), method = "isClickOutsideBounds", cancellable = true) - private void isClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button, CallbackInfoReturnable info) { - if (TrinketScreenManager.isClickInsideTrinketBounds(mouseX, mouseY)) { - info.setReturnValue(false); - } - } + @Override public TrinketPlayerScreenHandler trinkets$getHandler() { @@ -92,6 +87,6 @@ private void isClickOutsideBounds(double mouseX, double mouseY, int left, int to @Override public boolean trinkets$isRecipeBookOpen() { - return this.getRecipeBookWidget().isOpen(); + return ((RecipeBookScreenAccessor) this).getRecipeBook().isOpen(); } } diff --git a/src/main/java/dev/emi/trinkets/mixin/ItemStackMixin.java b/src/main/java/dev/emi/trinkets/mixin/ItemStackMixin.java index 3d94ea8f..361e0483 100644 --- a/src/main/java/dev/emi/trinkets/mixin/ItemStackMixin.java +++ b/src/main/java/dev/emi/trinkets/mixin/ItemStackMixin.java @@ -163,7 +163,7 @@ private void addAttributes(List list, Multimap cir) { } @Inject(at = @At("TAIL"), method = "dropInventory") - private void dropInventory(CallbackInfo info) { + private void dropInventory(ServerWorld world, CallbackInfo info) { LivingEntity entity = (LivingEntity) (Object) this; - boolean keepInv = entity.getWorld().getGameRules().getBoolean(GameRules.KEEP_INVENTORY); + boolean keepInv = world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY); TrinketsApi.getTrinketComponent(entity).ifPresent(trinkets -> trinkets.forEach((ref, stack) -> { if (stack.isEmpty()) { return; @@ -136,8 +136,8 @@ private void dropFromEntity(ItemStack stack) { // Mimic player drop behavior for only players if (((Entity) this) instanceof PlayerEntity player) { ItemEntity entity = player.dropItem(stack, true, false); - } else { - ItemEntity entity = dropStack(stack); + } else if (this.getWorld() instanceof ServerWorld serverWorld) { + ItemEntity entity = dropStack(serverWorld, stack); } } diff --git a/src/main/java/dev/emi/trinkets/mixin/LivingEntityRendererMixin.java b/src/main/java/dev/emi/trinkets/mixin/LivingEntityRendererMixin.java index 68a2a0c9..0210ed39 100644 --- a/src/main/java/dev/emi/trinkets/mixin/LivingEntityRendererMixin.java +++ b/src/main/java/dev/emi/trinkets/mixin/LivingEntityRendererMixin.java @@ -1,12 +1,16 @@ package dev.emi.trinkets.mixin; +import dev.emi.trinkets.TrinketEntityRenderState; import dev.emi.trinkets.TrinketFeatureRenderer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; +import net.minecraft.entity.LivingEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.injection.At; @@ -27,6 +31,12 @@ public abstract class LivingEntityRendererMixin { @Inject(at = @At("RETURN"), method = "") public void init(EntityRendererFactory.Context ctx, EntityModel model, float shadowRadius, CallbackInfo info) { - this.invokeAddFeature(new TrinketFeatureRenderer<>((LivingEntityRenderer) (Object) this)); + this.invokeAddFeature(new TrinketFeatureRenderer<>((FeatureRendererContext) (Object) this)); } + + @Inject(method = "updateRenderState(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/client/render/entity/state/LivingEntityRenderState;F)V", at = @At("TAIL")) + private void updateTrinketsRenderState(LivingEntity livingEntity, LivingEntityRenderState livingEntityRenderState, float f, CallbackInfo ci) { + var state = (TrinketEntityRenderState) livingEntityRenderState; + TrinketFeatureRenderer.update(livingEntity, livingEntityRenderState, f, state); + } } diff --git a/src/main/java/dev/emi/trinkets/mixin/LivingEntityStateRenderMixin.java b/src/main/java/dev/emi/trinkets/mixin/LivingEntityStateRenderMixin.java new file mode 100644 index 00000000..615c7639 --- /dev/null +++ b/src/main/java/dev/emi/trinkets/mixin/LivingEntityStateRenderMixin.java @@ -0,0 +1,31 @@ +package dev.emi.trinkets.mixin; + +import dev.emi.trinkets.TrinketEntityRenderState; +import dev.emi.trinkets.api.SlotReference; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Pair; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import java.util.List; + +@Environment(EnvType.CLIENT) +@Mixin(LivingEntityRenderState.class) +public class LivingEntityStateRenderMixin implements TrinketEntityRenderState { + + @Unique + private List> trinketsState; + + @Override + public void trinkets$setState(List> items) { + this.trinketsState = items; + } + + @Override + public List> trinkets$getState() { + return this.trinketsState; + } +} diff --git a/src/main/java/dev/emi/trinkets/mixin/RecipeBookScreenMixin.java b/src/main/java/dev/emi/trinkets/mixin/RecipeBookScreenMixin.java new file mode 100644 index 00000000..fe8814f2 --- /dev/null +++ b/src/main/java/dev/emi/trinkets/mixin/RecipeBookScreenMixin.java @@ -0,0 +1,18 @@ +package dev.emi.trinkets.mixin; + +import dev.emi.trinkets.TrinketScreenManager; +import net.minecraft.client.gui.screen.ingame.RecipeBookScreen; +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.CallbackInfoReturnable; + +@Mixin(RecipeBookScreen.class) +public class RecipeBookScreenMixin { + @Inject(at = @At("HEAD"), method = "isClickOutsideBounds", cancellable = true) + private void isClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button, CallbackInfoReturnable info) { + if (TrinketScreenManager.isClickInsideTrinketBounds(mouseX, mouseY)) { + info.setReturnValue(false); + } + } +} diff --git a/src/main/java/dev/emi/trinkets/mixin/accessor/RecipeBookScreenAccessor.java b/src/main/java/dev/emi/trinkets/mixin/accessor/RecipeBookScreenAccessor.java new file mode 100644 index 00000000..32db7547 --- /dev/null +++ b/src/main/java/dev/emi/trinkets/mixin/accessor/RecipeBookScreenAccessor.java @@ -0,0 +1,12 @@ +package dev.emi.trinkets.mixin.accessor; + +import net.minecraft.client.gui.screen.ingame.RecipeBookScreen; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(RecipeBookScreen.class) +public interface RecipeBookScreenAccessor { + @Accessor + RecipeBookWidget getRecipeBook(); +} diff --git a/src/main/resources/trinkets.mixins.json b/src/main/resources/trinkets.mixins.json index e6563ad3..38ecd063 100644 --- a/src/main/resources/trinkets.mixins.json +++ b/src/main/resources/trinkets.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "dev.emi.trinkets.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ "accessor.ScreenHandlerAccessor", "datafixer.Schema1460Mixin", @@ -15,13 +15,16 @@ "client": [ "accessor.CreativeSlotAccessor", "accessor.LivingEntityAccessor", + "accessor.RecipeBookScreenAccessor", "ClickableWidgetMixin", "ClientPlayNetworkHandlerMixin", "CreativeInventoryScreenMixin", "HandledScreenMixin", "InventoryScreenMixin", "ItemStackMixin", - "LivingEntityRendererMixin" + "LivingEntityRendererMixin", + "LivingEntityStateRenderMixin", + "RecipeBookScreenMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/testmod/java/dev/emi/trinkets/TestTrinket.java b/src/testmod/java/dev/emi/trinkets/TestTrinket.java index a1595419..ed20b345 100644 --- a/src/testmod/java/dev/emi/trinkets/TestTrinket.java +++ b/src/testmod/java/dev/emi/trinkets/TestTrinket.java @@ -14,6 +14,8 @@ import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttribute; @@ -28,7 +30,7 @@ public class TestTrinket extends TrinketItem implements TrinketRenderer { private static final Identifier TEXTURE = Identifier.of(TrinketsTest.MOD_ID, "textures/entity/trinket/hat.png"); - private BipedEntityModel model; + private BipedEntityModel model; public TestTrinket(Settings settings) { super(settings); @@ -46,7 +48,7 @@ public Multimap, EntityAttributeModifier> getModi Multimap, EntityAttributeModifier> modifiers = super.getModifiers(stack, slot, entity, id); EntityAttributeModifier speedModifier = new EntityAttributeModifier(id.withSuffixedPath("trinkets-testmod/movement_speed"), 0.4, EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL); - modifiers.put(EntityAttributes.GENERIC_MOVEMENT_SPEED, speedModifier); + modifiers.put(EntityAttributes.MOVEMENT_SPEED, speedModifier); SlotAttributes.addSlotModifier(modifiers, "offhand/ring", id.withSuffixedPath("trinkets-testmod/ring_slot"), 6, EntityAttributeModifier.Operation.ADD_VALUE); SlotAttributes.addSlotModifier(modifiers, "hand/glove", id.withSuffixedPath("trinkets-testmod/glove_slot"), 1, EntityAttributeModifier.Operation.ADD_VALUE); return modifiers; @@ -54,17 +56,18 @@ public Multimap, EntityAttributeModifier> getModi @Override @Environment(EnvType.CLIENT) - public void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, LivingEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { - BipedEntityModel model = this.getModel(); - model.setAngles(entity, limbAngle, limbDistance, animationProgress, animationProgress, headPitch); - model.animateModel(entity, limbAngle, limbDistance, tickDelta); - TrinketRenderer.followBodyRotations(entity, model); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(model.getLayer(TEXTURE)); - model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 1); + public void render(ItemStack stack, SlotReference slotReference, EntityModel contextModel, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, LivingEntityRenderState state, float limbAngle, float limbDistance) { + if (state instanceof BipedEntityRenderState bipedEntityRenderState) { + BipedEntityModel model = this.getModel(); + model.setAngles(bipedEntityRenderState); + TrinketRenderer.followBodyRotations(contextModel, model); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(model.getLayer(TEXTURE)); + model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 1); + } } @Environment(EnvType.CLIENT) - private BipedEntityModel getModel() { + private BipedEntityModel getModel() { if (this.model == null) { // Vanilla 1.17 uses EntityModels, EntityModelLoader and EntityModelLayers this.model = new TrinketModel(TrinketModel.getTexturedModelData().createModel()); diff --git a/src/testmod/java/dev/emi/trinkets/TestTrinket2.java b/src/testmod/java/dev/emi/trinkets/TestTrinket2.java index 5f437e78..84e31f64 100644 --- a/src/testmod/java/dev/emi/trinkets/TestTrinket2.java +++ b/src/testmod/java/dev/emi/trinkets/TestTrinket2.java @@ -40,7 +40,7 @@ public Multimap, EntityAttributeModifier> getModi Multimap, EntityAttributeModifier> modifiers = Multimaps.newMultimap(Maps.newLinkedHashMap(), ArrayList::new); EntityAttributeModifier speedModifier = new EntityAttributeModifier(id.withSuffixedPath("trinkets-testmod/movement_speed"), 0.1, EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL); - modifiers.put(EntityAttributes.GENERIC_MOVEMENT_SPEED, speedModifier); + modifiers.put(EntityAttributes.MOVEMENT_SPEED, speedModifier); return modifiers; } } \ No newline at end of file diff --git a/src/testmod/java/dev/emi/trinkets/TrinketsTest.java b/src/testmod/java/dev/emi/trinkets/TrinketsTest.java index b8c92322..9924c80b 100644 --- a/src/testmod/java/dev/emi/trinkets/TrinketsTest.java +++ b/src/testmod/java/dev/emi/trinkets/TrinketsTest.java @@ -6,6 +6,8 @@ import net.minecraft.item.Item; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; @@ -22,8 +24,8 @@ public class TrinketsTest implements ModInitializer { @Override public void onInitialize() { LOGGER.info("[Trinkets Testmod] test mod was initialized!"); - TEST_TRINKET = Registry.register(Registries.ITEM, identifier("test"), new TestTrinket(new Item.Settings().maxCount(1).maxDamage(100))); - TEST_TRINKET_2 = Registry.register(Registries.ITEM, identifier("test2"), new TestTrinket2(new Item.Settings().maxCount(1))); + TEST_TRINKET = Registry.register(Registries.ITEM, identifier("test"), new TestTrinket(new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, identifier("test"))).maxCount(1).maxDamage(100))); + TEST_TRINKET_2 = Registry.register(Registries.ITEM, identifier("test2"), new TestTrinket2(new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, identifier("test2"))).maxCount(1))); TrinketEquipCallback.EVENT.register(((stack, slot, entity) -> { if(stack.isOf(TEST_TRINKET_2)){ entity.getWorld().playSound(null, entity.getBlockPos(), SoundEvents.ENTITY_ARROW_HIT, SoundCategory.PLAYERS, 1f, 1f); diff --git a/src/testmod/java/dev/emi/trinkets/client/TrinketModel.java b/src/testmod/java/dev/emi/trinkets/client/TrinketModel.java index 866a2fe5..135f9522 100644 --- a/src/testmod/java/dev/emi/trinkets/client/TrinketModel.java +++ b/src/testmod/java/dev/emi/trinkets/client/TrinketModel.java @@ -4,10 +4,10 @@ import net.fabricmc.api.Environment; import net.minecraft.client.model.*; import net.minecraft.client.render.entity.model.BipedEntityModel; -import net.minecraft.entity.LivingEntity; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; @Environment(EnvType.CLIENT) -public class TrinketModel extends BipedEntityModel { +public class TrinketModel extends BipedEntityModel { public TrinketModel(ModelPart root) { super(root); diff --git a/src/testmod/resources/assets/trinkets-testmod/items/test.json b/src/testmod/resources/assets/trinkets-testmod/items/test.json new file mode 100644 index 00000000..f4fc57f8 --- /dev/null +++ b/src/testmod/resources/assets/trinkets-testmod/items/test.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "model", + "model": "trinkets-testmod:item/test" + } +} \ No newline at end of file diff --git a/src/testmod/resources/assets/trinkets-testmod/items/test2.json b/src/testmod/resources/assets/trinkets-testmod/items/test2.json new file mode 100644 index 00000000..5bff5482 --- /dev/null +++ b/src/testmod/resources/assets/trinkets-testmod/items/test2.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "model", + "model": "trinkets-testmod:item/test2" + } +} \ No newline at end of file