From 18c787153c9642d46e4ac073666112972cabd8a6 Mon Sep 17 00:00:00 2001 From: Jason Mitchell Date: Sat, 15 Aug 2026 15:43:01 -0700 Subject: [PATCH] Fixes for [Client thread/ERROR]: Couldn't render entity (#104) --- .../client/core/proxy/TTClientProxy.java | 10 +-- .../client/render/item/RenderMobDisplay.java | 64 +++++++++++++++---- .../common/core/helper/EnumMobAspect.java | 45 +++---------- .../common/core/proxy/TTCommonProxy.java | 5 -- .../tinkerer/common/item/ItemMobDisplay.java | 3 +- 5 files changed, 63 insertions(+), 64 deletions(-) diff --git a/src/main/java/thaumic/tinkerer/client/core/proxy/TTClientProxy.java b/src/main/java/thaumic/tinkerer/client/core/proxy/TTClientProxy.java index 1cc3afec..fd78501b 100644 --- a/src/main/java/thaumic/tinkerer/client/core/proxy/TTClientProxy.java +++ b/src/main/java/thaumic/tinkerer/client/core/proxy/TTClientProxy.java @@ -61,7 +61,6 @@ import thaumic.tinkerer.common.block.tile.tablet.TileAnimationTablet; import thaumic.tinkerer.common.compat.FumeTool; import thaumic.tinkerer.common.compat.LoadedMods; import thaumic.tinkerer.common.core.handler.ConfigHandler; -import thaumic.tinkerer.common.core.helper.EnumMobAspect; import thaumic.tinkerer.common.core.proxy.TTCommonProxy; import thaumic.tinkerer.common.item.ItemInfusedSeeds; import thaumic.tinkerer.common.item.ItemMobDisplay; @@ -155,9 +154,11 @@ public final class TTClientProxy extends TTCommonProxy { RenderingRegistry.registerBlockHandler(new RenderMagnet()); RenderingRegistry.registerBlockHandler(new RenderRepairer()); + RenderMobDisplay mobDisplayRenderer = new RenderMobDisplay(); + MinecraftForge.EVENT_BUS.register(mobDisplayRenderer); MinecraftForgeClient.registerItemRenderer( ThaumicTinkerer.registry.getFirstItemFromClass(ItemMobDisplay.class), - new RenderMobDisplay()); + mobDisplayRenderer); MinecraftForgeClient.registerItemRenderer( ThaumicTinkerer.registry.getFirstItemFromClass(ItemInfusedSeeds.class), new RenderGenericSeeds()); @@ -220,9 +221,4 @@ public final class TTClientProxy extends TTCommonProxy { public EntityPlayer getClientPlayer() { return ClientHelper.clientPlayer(); } - - @Override - public String getMobDisplayName(EnumMobAspect aspect) { - return aspect.getEntity(Minecraft.getMinecraft().theWorld).getCommandSenderName(); - } } diff --git a/src/main/java/thaumic/tinkerer/client/render/item/RenderMobDisplay.java b/src/main/java/thaumic/tinkerer/client/render/item/RenderMobDisplay.java index 889f23bb..cf2210b6 100644 --- a/src/main/java/thaumic/tinkerer/client/render/item/RenderMobDisplay.java +++ b/src/main/java/thaumic/tinkerer/client/render/item/RenderMobDisplay.java @@ -1,19 +1,43 @@ package thaumic.tinkerer.client.render.item; +import java.util.EnumMap; + import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.item.ItemStack; +import net.minecraft.world.World; import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.event.world.WorldEvent; import org.lwjgl.opengl.GL11; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; import thaumic.tinkerer.common.core.helper.EnumMobAspect; import thaumic.tinkerer.common.item.ItemMobDisplay; public class RenderMobDisplay implements IItemRenderer { + private static final int ATTRIB_MASK = GL11.GL_ENABLE_BIT | GL11.GL_CURRENT_BIT + | GL11.GL_DEPTH_BUFFER_BIT + | GL11.GL_COLOR_BUFFER_BIT + | GL11.GL_LIGHTING_BIT + | GL11.GL_TEXTURE_BIT; + + private final EnumMap cache = new EnumMap<>(EnumMobAspect.class); + private World cachedWorld; + + private void setCachedWorld(World world) { + cache.clear(); + cachedWorld = world; + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + if (event.world == cachedWorld) setCachedWorld(null); + } + @Override public boolean handleRenderType(ItemStack itemStack, ItemRenderType itemRenderType) { return true; @@ -30,19 +54,31 @@ public class RenderMobDisplay implements IItemRenderer { if (!(itemStack.getItem() instanceof ItemMobDisplay item)) return; EnumMobAspect aspect = item.getEntityType(itemStack); if (aspect == null) return; - Entity entity = EnumMobAspect.getEntityFromCache(aspect, Minecraft.getMinecraft().theWorld); - float scale = aspect.getScale(); - float offset = aspect.getVerticalOffset(); - GL11.glPushMatrix(); - GL11.glRotatef(-30.0F, 1.0F, 0.0F, 0.0F); - GL11.glScalef(scale, scale, scale); - GL11.glTranslatef(0, (-entity.height / 2) + offset, 0.0F); - Render renderer = RenderManager.instance.getEntityRenderObject(entity); - if (renderer != null && renderer.getFontRendererFromRenderManager() != null) { - GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); - renderer.doRender(entity, 0, 0, 0, 0, 0); - GL11.glPopAttrib(); + + final World world = Minecraft.getMinecraft().theWorld; + if (world != cachedWorld) setCachedWorld(world); + if (world == null) return; + + EntityLiving entity = cache.get(aspect); + if (entity == null || entity.worldObj != world) { + entity = aspect.createEntity(world); + cache.put(aspect, entity); + } + + final Render renderer = RenderManager.instance.getEntityRenderObject(entity); + if (renderer == null || renderer.getFontRendererFromRenderManager() == null) return; + + float scale = aspect.getScale(); + GL11.glPushMatrix(); + GL11.glPushAttrib(ATTRIB_MASK); + try { + GL11.glRotatef(-30.0F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(scale, scale, scale); + GL11.glTranslatef(0, (-entity.height / 2) + aspect.getVerticalOffset(), 0.0F); + renderer.doRender(entity, 0, 0, 0, 0, 0); + } finally { + GL11.glPopAttrib(); + GL11.glPopMatrix(); } - GL11.glPopMatrix(); } } diff --git a/src/main/java/thaumic/tinkerer/common/core/helper/EnumMobAspect.java b/src/main/java/thaumic/tinkerer/common/core/helper/EnumMobAspect.java index 36db661c..ca916217 100644 --- a/src/main/java/thaumic/tinkerer/common/core/helper/EnumMobAspect.java +++ b/src/main/java/thaumic/tinkerer/common/core/helper/EnumMobAspect.java @@ -8,7 +8,7 @@ import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; -import net.minecraft.client.Minecraft; +import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.monster.EntityBlaze; @@ -37,15 +37,9 @@ import net.minecraft.entity.passive.EntitySheep; import net.minecraft.entity.passive.EntitySquid; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.passive.EntityWolf; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.world.WorldEvent; -import com.google.common.collect.Maps; - -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import thaumcraft.api.aspects.Aspect; import thaumcraft.common.entities.monster.EntityBrainyZombie; import thaumcraft.common.entities.monster.EntityFireBat; @@ -125,7 +119,6 @@ public enum EnumMobAspect { Enderman(EntityEnderman.class, new Aspect[] { Aspect.ELDRITCH, Aspect.ELDRITCH, Aspect.MAN }, 0.7f), Wisp(EntityWisp.class, new Aspect[] { Aspect.AIR, Aspect.MAGIC, Aspect.MAGIC }); - public static final Map entityCache = Maps.newHashMap(); private static final Map LOOKUP = Arrays.stream(values()) .collect(Collectors.toMap(Enum::name, Function.identity())); public final Aspect[] aspects; @@ -133,6 +126,7 @@ public enum EnumMobAspect { private final float scale; private final float offset; private final MethodHandle ctor; + private String langKey; EnumMobAspect(Class entity, Aspect[] aspects, float scale) { this(entity, aspects, scale, 0); @@ -159,15 +153,6 @@ public enum EnumMobAspect { return LOOKUP.get(name); } - public static EntityLiving getEntityFromCache(EnumMobAspect ent, World worldObj) { - EntityLiving entity = entityCache.get(ent); - if (entity == null) { - entity = ent.createEntity(worldObj); - entityCache.put(ent, entity); - } - return entity; - } - private static EntityLiving setSlimeSize(EntityLiving entity, int size) { if (entity instanceof EntitySlime slime) { slime.setSlimeSize(size); @@ -206,8 +191,12 @@ public enum EnumMobAspect { return scale; } - public EntityLiving getEntity(World worldObj) { - return getEntityFromCache(this, worldObj); + public String getDisplayName() { + if (langKey == null) { + String name = EntityList.classToStringMapping.get(entity); + langKey = "entity." + (name == null ? "generic" : name) + ".name"; + } + return StatCollector.translateToLocal(langKey); } public EntityLiving createEntity(World worldObj) { @@ -217,20 +206,4 @@ public enum EnumMobAspect { throw new RuntimeException(e); } } - - static { - MinecraftForge.EVENT_BUS.register(new EventHandler()); - } - - public static class EventHandler { - - @SideOnly(Side.CLIENT) - @SubscribeEvent - public void onWorldUnload(WorldEvent.Unload event) { - Minecraft mc = Minecraft.getMinecraft(); - if (event.world == mc.theWorld) { - entityCache.clear(); - } - } - } } diff --git a/src/main/java/thaumic/tinkerer/common/core/proxy/TTCommonProxy.java b/src/main/java/thaumic/tinkerer/common/core/proxy/TTCommonProxy.java index 4ed30595..4813a37d 100644 --- a/src/main/java/thaumic/tinkerer/common/core/proxy/TTCommonProxy.java +++ b/src/main/java/thaumic/tinkerer/common/core/proxy/TTCommonProxy.java @@ -77,7 +77,6 @@ import thaumic.tinkerer.common.core.handler.kami.KamiDimensionHandler; import thaumic.tinkerer.common.core.handler.kami.SoulHeartHandler; import thaumic.tinkerer.common.core.helper.AspectCropLootManager; import thaumic.tinkerer.common.core.helper.BonemealEventHandler; -import thaumic.tinkerer.common.core.helper.EnumMobAspect; import thaumic.tinkerer.common.core.helper.NumericAspectHelper; import thaumic.tinkerer.common.enchantment.ModEnchantments; import thaumic.tinkerer.common.enchantment.core.EnchantmentManager; @@ -276,10 +275,6 @@ public class TTCommonProxy { // NO-OP } - public String getMobDisplayName(EnumMobAspect aspect) { - return aspect.getEntity(MinecraftServer.getServer().getEntityWorld()).getCommandSenderName(); - } - public static class NEIEventHandler { @SubscribeEvent diff --git a/src/main/java/thaumic/tinkerer/common/item/ItemMobDisplay.java b/src/main/java/thaumic/tinkerer/common/item/ItemMobDisplay.java index b73b5703..49fd7037 100644 --- a/src/main/java/thaumic/tinkerer/common/item/ItemMobDisplay.java +++ b/src/main/java/thaumic/tinkerer/common/item/ItemMobDisplay.java @@ -6,7 +6,6 @@ import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import thaumic.tinkerer.common.ThaumicTinkerer; import thaumic.tinkerer.common.core.helper.EnumMobAspect; import thaumic.tinkerer.common.core.helper.ItemNBTHelper; import thaumic.tinkerer.common.lib.LibItemNames; @@ -64,6 +63,6 @@ public class ItemMobDisplay extends ItemBase { if (mob == null || mob.isEmpty()) return super.getItemStackDisplayName(stack); EnumMobAspect aspect = EnumMobAspect.get(mob); if (aspect == null) return super.getItemStackDisplayName(stack); - return ThaumicTinkerer.proxy.getMobDisplayName(aspect); + return aspect.getDisplayName(); } }