Jump to content

[1.10.2] Multiple copies of item in inventory when registering


Recommended Posts

Posted

Why is it that when I register the item for my block, I get three copies of it in the creative inventory? My block has three variants for different orientations (like a log). It seems like it's registering an item for each variant. Only one has the right texture in inventory. The other two are untextured cubes.

 

public final class PrimalBlockRegistry
{

public static Block logStrippedOak = new PrimalBlockLog("log_stripped_oak");

public static void createBlocks()
{
	register(logStrippedOak);
}

private static <T extends Block> T register(T block)
{
	GameRegistry.register(block);
	ItemBlock itemBlock = new ItemBlock(block);
	itemBlock.setRegistryName(block.getRegistryName());
	if (itemBlock != null)
	{
		GameRegistry.register(itemBlock);
	}
	return block;
}

 

My block class:

 

public class PrimalBlockLog extends BlockRotatedPillar implements IItemModelProvider
{

public static final PropertyEnum<PrimalBlockLog.EnumAxis> LOG_AXIS = PropertyEnum.<PrimalBlockLog.EnumAxis> create("axis", PrimalBlockLog.EnumAxis.class);
protected String blockName;

public PrimalBlockLog(String blockName)
{
	super(Material.WOOD);
	this.blockName = blockName;
	setBlockName(this, blockName);
	this.setCreativeTab(PrimalCreativeTabs.tabPrimalcraft);
      this.setHardness(2.0F);
      this.setSoundType(SoundType.WOOD);
	this.setDefaultState(this.blockState.getBaseState().withProperty(LOG_AXIS, PrimalBlockLog.EnumAxis.X));
}

public static void setBlockName(Block block, String blockName)
{
	block.setRegistryName(blockName);
	block.setUnlocalizedName(blockName);
}

@Override
public void registerItemModel(Item item)
{
	Primalcraft.proxy.registerItemRenderer(item, 0, blockName);
}

@Override
protected BlockStateContainer createBlockState()
{
	return new BlockStateContainer(this, LOG_AXIS);
}

@Override
public IBlockState getStateFromMeta(int meta)
{
	return getDefaultState().withProperty(LOG_AXIS, EnumAxis.byMetadata(meta));
}

@Override
public int getMetaFromState(IBlockState state) {
	return state.getValue(LOG_AXIS).getMeta();
}

@Override
public int damageDropped(IBlockState state) {
	return getMetaFromState(state);
}

@Override
public void getSubBlocks(Item itemIn, CreativeTabs tab, List<ItemStack> list) {
	for (final EnumAxis axis : EnumAxis.values()) {
		list.add(new ItemStack(this, 1, axis.getMeta()));
	}
}

   public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
   {
       int i = 4;
       int j = 5;

       if (worldIn.isAreaLoaded(pos.add(-5, -5, -5), pos.add(5, 5, 5)))
       {
           for (BlockPos blockpos : BlockPos.getAllInBox(pos.add(-4, -4, -4), pos.add(4, 4, 4)))
           {
               IBlockState iblockstate = worldIn.getBlockState(blockpos);

               if (iblockstate.getBlock().isLeaves(iblockstate, worldIn, blockpos))
               {
                   iblockstate.getBlock().beginLeavesDecay(iblockstate, worldIn, blockpos);
               }
           }
       }
   }

   /**
    * Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
    * IBlockstate
    */
   public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
   {
       return this.getStateFromMeta(meta).withProperty(LOG_AXIS, PrimalBlockLog.EnumAxis.fromFacingAxis(facing.getAxis()));
   }

   /**
    * Returns the blockstate with the given rotation from the passed blockstate. If inapplicable, returns the passed
    * blockstate.
    */
   public IBlockState withRotation(IBlockState state, Rotation rot)
   {
       switch (rot)
       {
           case COUNTERCLOCKWISE_90:
           case CLOCKWISE_90:

               switch ((PrimalBlockLog.EnumAxis)state.getValue(LOG_AXIS))
               {
                   case X:
                       return state.withProperty(LOG_AXIS, PrimalBlockLog.EnumAxis.Z);
                   case Z:
                       return state.withProperty(LOG_AXIS, PrimalBlockLog.EnumAxis.X);
                   default:
                       return state;
               }

           default:
               return state;
       }
   }

   @Override public boolean canSustainLeaves(IBlockState state, net.minecraft.world.IBlockAccess world, BlockPos pos){ return true; }
   @Override public boolean isWood(net.minecraft.world.IBlockAccess world, BlockPos pos){ return true; }

public static enum EnumAxis implements IStringSerializable
{
	X(0, "x"), 
	Y(1, "y"), 
	Z(2, "z");

	private final int meta;
	private final String name;
	private static final PrimalBlockLog.EnumAxis[]	META_LOOKUP	= new PrimalBlockLog.EnumAxis[values().length];
	//private static final EnumAxis[] META_LOOKUP = Stream.of(values()).sorted(Comparator.comparing(EnumAxis::getMeta)).toArray(EnumAxis[]::new);

	private EnumAxis(int meta, String name)
	{
		this.meta = meta;
		this.name = name;
	}

	public int getMeta()
	{
		return meta;
	}

	public String getName()
	{
		return this.name;
	}

	public String toString()
	{
		return this.name;
	}

	public static PrimalBlockLog.EnumAxis byMetadata(int meta)
	{
		if (meta < 0 || meta >= META_LOOKUP.length)
		{
			meta = 0;
		}

		return META_LOOKUP[meta];
	}

	public static PrimalBlockLog.EnumAxis fromFacingAxis(EnumFacing.Axis axis)
	{
		switch (axis)
		{
			case X:
				return X;
			case Y:
				return Y;
			case Z:
				return Z;
			default:
				return Y;
		}
	}

	static
	{
		for (PrimalBlockLog.EnumAxis axis : values())
		{
			META_LOOKUP[axis.getMeta()] = axis;
		}
	}		


}

}

 

Posted

HMM.

 

	public void getSubBlocks(Item itemIn, CreativeTabs tab, List<ItemStack> list) {
	for (final EnumAxis axis : EnumAxis.values()) {
		list.add(new ItemStack(this, 1, axis.getMeta()));
	}
}

 

I wonder what THIS does...

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Oh. Embarrassingly copied from another class (an old attempt at custom logs) without realizing. Thanks for the reminder.

 

Second problem is the textures. The two untextured variants I saw in the creative inventory are following me around in the world. Everything is fine until I break the blocks. Those on the X axis are fine, but those on the Y and Z axis drop with no texture. As soon as I pick them up, they are fine.

Posted

Where should I even look to try to debug this problem with missing textures when the block is broken? One variant is fine, the other two are not. I suspected that perhaps damageDropped was getting the wrong meta somehow, but it seems to be fine. Any ideas?

Posted

It's now working correctly. In my registerItemModel method in the block class, I was only registering an item model for one of the variants. So I looped through each of the variants in my enum and registered an item model for each one, and it finally worked as expected.

 

Problem method:

@Override
public void registerItemModel(Item item)
{
	Primalcraft.proxy.registerItemRenderer(item, 0, blockName);
}

 

Fixed method:

@Override
public void registerItemModel(Item item)
{
	for (PrimalBlockLog.EnumAxis axis : EnumAxis.values())
	{
		Primalcraft.proxy.registerItemRenderer(item, axis.getMeta(), blockName);
	}
}

 

To be honest, I'm still not sure why this fixed the problem. I was only registering an item model for one variant before, because I only need one variant for the item version of my block.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hi! I'm trying to add my custom models/textures renderer like this: public class PonyPlayerWrapperRenderer extends EntityRenderer<Player> { // wrapper class under my LivingEntityRenderer class implementation private final PonyPlayerRenderer innerRenderer; private final PonyPlayerRenderer innerSlimRenderer; public PonyPlayerWrapperRenderer(final EntityRendererProvider.Context context) { super(context); System.out.println("creating new PonyPlayerWrapperRenderer"); this.innerRenderer = new PonyPlayerRenderer(context, false); this.innerSlimRenderer = new PonyPlayerRenderer(context, true); } @Override public void render(final Player entity, final float yaw, final float partialTicks, final PoseStack poseStack, final MultiBufferSource bufferSource, final int packedLight) { System.out.println("PonyPlayerWrapperRenderer render: " + entity.toString()); if (entity instanceof AbstractClientPlayer clientPlayer) { if (clientPlayer.getModelName().contains("slim")) { innerSlimRenderer.render(clientPlayer, yaw, partialTicks, poseStack, bufferSource, packedLight); } else { innerRenderer.render(clientPlayer, yaw, partialTicks, poseStack, bufferSource, packedLight); } } } @Override public ResourceLocation getTextureLocation(final Player player) { System.out.println("PonyPlayerWrapperRenderer getTextureLocation"); if (player instanceof AbstractClientPlayer clientPlayer) { return clientPlayer.getSkinTextureLocation(); } System.out.println("player instanceof AbstractClientPlayer is false"); return getDefaultSkin(player.getUUID()); } } public class PonyPlayerRenderer extends LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> { private final PlayerModel<AbstractClientPlayer> earthModel; private final PlayerModel<AbstractClientPlayer> pegasusModel; private final PlayerModel<AbstractClientPlayer> unicornModel; public PonyPlayerRenderer(final EntityRendererProvider.Context context, final boolean slim) { super( context, slim ? new PonyModelSlim(context.bakeLayer(PonyModelSlim.LAYER_LOCATION)) : new PonyModel(context.bakeLayer(PonyModel.LAYER_LOCATION)), 0.5f ); System.out.println("creating new PonyPlayerRenderer"); this.earthModel = slim ? new PonyModelSlim(context.bakeLayer(PonyModelSlim.LAYER_LOCATION)) : new PonyModel(context.bakeLayer(PonyModel.LAYER_LOCATION)); this.pegasusModel = new PegasusModel(context.bakeLayer(PegasusModel.LAYER_LOCATION)); this.unicornModel = new UnicornModel(context.bakeLayer(UnicornModel.LAYER_LOCATION)); } @Override public void render(final AbstractClientPlayer player, final float entityYaw, final float partialTicks, final PoseStack poseStack, final MultiBufferSource buffer, final int packedLight) { final PonyRace race = player.getCapability(PONY_DATA) .map(data -> ofNullable(data.getRace()).orElse(PonyRace.EARTH)) .orElse(PonyRace.EARTH); this.model = switch (race) { case PEGASUS -> pegasusModel; case UNICORN -> unicornModel; case EARTH -> earthModel; }; super.render(player, entityYaw, partialTicks, poseStack, buffer, packedLight); } @Override public ResourceLocation getTextureLocation(final AbstractClientPlayer player) { final PonyRace race = player.getCapability(PONY_DATA) .map(data -> ofNullable(data.getRace()).orElse(PonyRace.EARTH)) .orElse(PonyRace.EARTH); return switch (race) { case EARTH -> fromNamespaceAndPath(MODID, "textures/entity/earth_pony.png"); case PEGASUS -> fromNamespaceAndPath(MODID, "textures/entity/pegasus.png"); case UNICORN -> fromNamespaceAndPath(MODID, "textures/entity/unicorn.png"); }; } } @Mod.EventBusSubscriber(modid = MODID, bus = MOD, value = CLIENT) public class ClientRenderers { // mod bus render registration config @SubscribeEvent public static void onRegisterLayerDefinitions(final EntityRenderersEvent.RegisterLayerDefinitions event) { event.registerLayerDefinition(PonyModel.LAYER_LOCATION, PonyModel::createBodyLayer); event.registerLayerDefinition(PonyModelSlim.LAYER_LOCATION, PonyModelSlim::createBodyLayer); event.registerLayerDefinition(PegasusModel.LAYER_LOCATION, PegasusModel::createBodyLayer); event.registerLayerDefinition(UnicornModel.LAYER_LOCATION, UnicornModel::createBodyLayer); event.registerLayerDefinition(InnerPonyArmorModel.LAYER_LOCATION, InnerPonyArmorModel::createBodyLayer); event.registerLayerDefinition(OuterPonyArmorModel.LAYER_LOCATION, OuterPonyArmorModel::createBodyLayer); } @SubscribeEvent public static void onRegisterRenderers(final EntityRenderersEvent.RegisterRenderers event) { event.registerEntityRenderer(EntityType.PLAYER, PonyPlayerWrapperRenderer::new); System.out.println("onRegisterRenderers end"); } } Method onRegisterRenderers() is called and I can see it being logged. But when I enter the world, my PonyWrapperRenderer render() method doesn't ever seem to be called. I also tried to put my renderer to EntityRenderDispatcher's playerRenderers via reflection: @Mod.EventBusSubscriber(modid = MODID, bus = MOD, value = CLIENT) public class ClientRenderers { @SubscribeEvent public static void onRegisterLayerDefinitions(final EntityRenderersEvent.RegisterLayerDefinitions event) { event.registerLayerDefinition(PonyModel.LAYER_LOCATION, PonyModel::createBodyLayer); event.registerLayerDefinition(PonyModelSlim.LAYER_LOCATION, PonyModelSlim::createBodyLayer); event.registerLayerDefinition(PegasusModel.LAYER_LOCATION, PegasusModel::createBodyLayer); event.registerLayerDefinition(UnicornModel.LAYER_LOCATION, UnicornModel::createBodyLayer); event.registerLayerDefinition(InnerPonyArmorModel.LAYER_LOCATION, InnerPonyArmorModel::createBodyLayer); event.registerLayerDefinition(OuterPonyArmorModel.LAYER_LOCATION, OuterPonyArmorModel::createBodyLayer); } @SubscribeEvent public static void onClientSetup(final FMLClientSetupEvent event) { event.enqueueWork(() -> { try { final EntityRenderDispatcher dispatcher = Minecraft.getInstance().getEntityRenderDispatcher(); final Field renderersField = getEntityRenderDispatcherField("playerRenderers"); final Field itemInHandRenderer = getEntityRenderDispatcherField("itemInHandRenderer"); @SuppressWarnings("unchecked") final Map<String, EntityRenderer<? extends Player>> playerRenderers = (Map<String, EntityRenderer<? extends Player>>)renderersField.get(dispatcher); final PonyPlayerWrapperRenderer renderer = new PonyPlayerWrapperRenderer( new EntityRendererProvider.Context( dispatcher, Minecraft.getInstance().getItemRenderer(), Minecraft.getInstance().getBlockRenderer(), (ItemInHandRenderer)itemInHandRenderer.get(dispatcher), Minecraft.getInstance().getResourceManager(), Minecraft.getInstance().getEntityModels(), Minecraft.getInstance().font ) ); playerRenderers.put("default", renderer); playerRenderers.put("slim", renderer); System.out.println("Player renderers replaced"); } catch (final Exception e) { throw new RuntimeException("Failed to replace player renderers", e); } }); } private static Field getEntityRenderDispatcherField(final String fieldName) throws NoSuchFieldException { final Field field = EntityRenderDispatcher.class.getDeclaredField(fieldName); field.setAccessible(true); return field; } } But I receive the error before Minecraft Client appears (RuntimeException: Failed to replace player renderers - from ClientRenderers onClientSetup() method - and its cause below): java.lang.IllegalArgumentException: No model for layer anotherlittlepony:earth_pony#main at net.minecraft.client.model.geom.EntityModelSet.bakeLayer(EntityModelSet.java:18) ~[forge-1.20.1-47.4.0_mapped_official_1.20.1-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at net.minecraft.client.renderer.entity.EntityRendererProvider$Context.bakeLayer(EntityRendererProvider.java:69) ~[forge-1.20.1-47.4.0_mapped_official_1.20.1-recomp.jar:?] {re:classloading,pl:runtimedistcleaner:A} at com.thuggeelya.anotherlittlepony.client.renderer.pony.PonyPlayerRenderer.<init>(PonyPlayerRenderer.java:32) ~[main/:?] {re:classloading} at com.thuggeelya.anotherlittlepony.client.renderer.pony.PonyPlayerWrapperRenderer.<init>(PonyPlayerWrapperRenderer.java:24) ~[main/:?] {re:classloading} at com.thuggeelya.anotherlittlepony.client.renderer.ClientRenderers.lambda$onClientSetup$0(ClientRenderers.java:79) ~[main/:?] {re:classloading} ... 33 more Problem appears when EntityRendererProvider context tries to bakeLayer with my model layer location: new PonyModel(context.bakeLayer(PonyModel.LAYER_LOCATION)); // PonyPlayerRenderer.java:32 public class PonyModel extends PlayerModel<AbstractClientPlayer> { // the model class itself public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation( ResourceLocation.fromNamespaceAndPath(MODID, "earth_pony"), "main" ); public PonyModel(final ModelPart root) { super(root, false); } public static LayerDefinition createBodyLayer() { // some CubeListBuilder stuff for model appearance } } Textures PNGs are placed at: resources/assets/[my mod id]/textures/entity. My forge version is 1.20.1. Would appreciate any help.
    • Well, a bit more information about what you're trying to do would be helpful. e.g. why you're trying to use "INVOKE_ASSIGN" instead of "INVOKE". "INVOKE_ASSIGN" calls your code after the "target" is called and its value is stored, if applicable. "INVOKE" calls your code before the target is called. "target" expects a fully qualified name, as per the SpongePowered docs, if that name is going to be remapped (which it will be if your injecting into Minecraft itself and not another mod). For more information on fully qualified names versus canonical names, see the Java specifications. Here's an example of a working "@At" from my own code that targets the "getClosestsVulnerablePlayerToEntity" call inside a mob's logic: @At(value = "INVOKE_ASSIGN", target = "net.minecraft.world.World.getClosestVulnerablePlayerToEntity(Lnet/minecraft/entity/Entity;D)Lnet/minecraft/entity/player/EntityPlayer;") Hope this helps!
    • Ran it one more time just to check, and there's no errors this time on the log??? Log : https://mclo.gs/LnuaAiu I tried allocating more memory to the modpack, around 8000MB and it's still the same; stopping at "LOAD_REGISTRIES". Are some of the mods clashing, maybe? I have no clue what to do LOL
    • Tried removing some biome generation mods and test ran it again, but it's still the same; still not responding as soon as it gets to "LOAD_REGISTRIES". This time with more errors though. Log : https://mclo.gs/uygZzD8 Is there too little memory allocated to the modpack maybe? Can someone help please.    (T.T)💔
    • This is sad. Over 3300 people have checked the thread and no one is able to help or give any ideas :(.
  • Topics

  • Who's Online (See full list)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.