Jump to content

Need to get block Data Value


TastyCake

Recommended Posts

So in an event, I need to get the block that gets left-clicked and then drop it and make it disappear from the world. This works but when I left-click, on, for example, a log of a type other than oak, it just drops oak. This happens with stone and andesite too. So what I need is to get the Data Value that determines the block sub-type. Here is my code

Thanks for any help you can provide!

My username elsewhere is Fluoride

Link to comment
Share on other sites

Just now, TastyCake said:

So in an event, I need to get the block that gets left-clicked and then drop it and make it disappear from the world. This works but when I left-click, on, for example, a log of a type other than oak, it just drops oak. This happens with stone and andesite too. So what I need is to get the Data Value that determines the block sub-type. Here is my code

Thanks for any help you can provide!

Block#getPickBlock(IBlockState, RayTraceResult, World, BlockPos, EntityPlayer)

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

The easier fix is just to use the right constructor.  In your code you have

 

ItemStack(event.getBlockState().getBlock)

 

But instead you should replace it with something like:

 

ItemStack(event.getBlockState().getBlock(), 1, event.getBlockState().getBlock().getMetaFromBlockState(event.getBlockState()))

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

1 minute ago, TastyCake said:

Sorry for my ignorance but how am I supposed to use this?

First off, are you trying to get the full drops of the block, or just the block itself?

If the later Block#getPickBlock will return the block as an itemstack as it's respective type, IE oak to oak, spruce to spruce. You can get the raytrace result by creating a new instance from the data passed into the event.

 

If it is the former then you should call Block#getDrops(NonNullList<ItemStack>, IBlockAccess, BlockPos, int) which will add the blocks drops to the NonNullList you pass in.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

1 minute ago, jabelar said:

ItemStack(event.getBlockState().getBlock(), 1, event.getBlockState().getBlock().getMetaFromBlockState(event.getBlockState()))

This is not true, this will not work in all cases, blocks and items may have different metadata, and there are blocks that have more metadata than items, IE logs.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

7 minutes ago, Animefan8888 said:

This is not true, this will not work in all cases, blocks and items may have different metadata, and there are blocks that have more metadata than items, IE logs.

Okay, then it should be:

 

        ItemStack(Item.getItemFromBlock(event.getBlockState().getBlock()), 1, this.damageDropped(event.getBlockState()));
 

I guess you're right the damageDropped can be different than the blocks meta. 

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Jabelar's method seems to work with logs and stone types but leaves have no texture when broken and have incorrect data values. Also, everything seems to drop twice, but only one instance can be picked up and the other instance is removed on re-login

 

Edit: I missed Jabelar's new reply. Will try it and report back

Edited by TastyCake

My username elsewhere is Fluoride

Link to comment
Share on other sites

18 minutes ago, jabelar said:

But instead you should replace it with something like:

 

ItemStack(event.getBlockState().getBlock(), 1, event.getBlockState().getBlock().getMetaFromBlockState(event.getBlockState()))

No. Use this:

 

ItemStack stack = event.getBlockState().getPickBlock(state, null, world, pos, player)

Pass a raytraceresult if you can, but no vanilla blocks use it and its highly unlikely that any mod block will either.

8 minutes ago, TastyCake said:

but leaves have no texture

That's because you should never be calling getMetaFromState() yourself. Leaves have data values that are for decay that are not relevant to the resulting item. Similarly wool blocks have metadata values that are backwards from their item form.

Edited by Draco18s

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.

Link to comment
Share on other sites

getPickBlock() uses the same code I posted in my corrected suggestion. That is the function that sorts out which metadata should be passed to item. For some blocks like flowers it might be the same for both damage dropped and metadata, but for others like logs the orientation doesn't need to pass into the item.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

4 minutes ago, TastyCake said:

The problem with the block dropping twice is still there and still, only one instance of the drop can be picked up.

Only spawn the entity on the server, !world.isRemote

Also,

4 minutes ago, Draco18s said:

ItemStack stack = event.getBlockState().getPickBlock(state, null, world, pos, player)

Pass a raytraceresult if you can, but no vanilla blocks use it and its highly unlikely that any mod block will either. 

Or,

35 minutes ago, Animefan8888 said:

Block#getPickBlock(IBlockState, RayTraceResult, World, BlockPos, EntityPlayer)

 

22 minutes ago, Animefan8888 said:

If the later Block#getPickBlock will return the block as an itemstack as it's respective type, IE oak to oak, spruce to spruce. You can get the raytrace result by creating a new instance from the data passed into the event.

 

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

1 minute ago, jabelar said:

getPickBlock() uses the same code I posted in my corrected suggestion. That is the function that sorts out which metadata should be passed to item. For some blocks like flowers it might be the same for both damage dropped and metadata, but for others like logs the orientation doesn't need to pass into the item.

But there are also modded blocks.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

17 minutes ago, diesieben07 said:

This is BS.

The only way to obtain the drops of a block is to call getDrops. Do not call any other method.

The only way to obtain a "exact representation" of a block as an item is getPickBlock. Do not call any other method.

Do not interact with other people's metadata. Do not pass go, do not collect $200.

It is not BS at all. 

 

The getPickBlock() relies on damage dropped method. The code I posted is from that actual method. I didn't make it up. If you don't override the damage dropped method in your modded block, getPickBlock() will not work for you.

 

Here's the code calls directly from source:

    public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player)
    {
        return getItem(world, pos, state);
    }
    public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state)
    {
        return new ItemStack(Item.getItemFromBlock(this), 1, this.damageDropped(state));
    }

 

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

1 minute ago, diesieben07 said:

getPickBlock is a forge-added method. The default implementation is suitable for vanilla blocks, so that not all vanilla blocks need to implement it. Mods can override this method to do whatever they want. Completely independent of any other methods. damageDropped is a vanilla-legacy crap thing.

 

The reality is a lot of modders are going to copy vanilla blocks or extend them. They will see that the getDrops() methods call the damageDropped() method. I feel that people will continue to use damageDropped() because the same logic (of converting select properties to metadata) is needed in two places - for getDrops() and for getPickBlock(). If you have code/logic needed in two places isn't it good practice to have a common method to contain it?

 

You're right though that the recommended way should be to use getDrops() and getPickBlock(). But I don't think damage dropped is legacy crap -- it is a legitimate place to put the state conversion.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

1 hour ago, diesieben07 said:

You as a caller should not care about this.

This. Always this.

You, as a caller, should not care what the implementation is, only that it does what it says it does. You cannot, and should not ever, "take shortcuts" because of what the implementation 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.

Link to comment
Share on other sites

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

    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
    • It is an issue with quark - update it to this build: https://www.curseforge.com/minecraft/mc-mods/quark/files/3642325
    • Remove Instant Massive Structures Mod from your server     Add new crash-reports with sites like https://paste.ee/  
    • Update your drivers: https://www.amd.com/en/support/graphics/amd-radeon-r9-series/amd-radeon-r9-200-series/amd-radeon-r9-280x
  • Topics

×
×
  • Create New...

Important Information

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