Jump to content

How to know what side a block was broke from?


American2050

Recommended Posts

I need to know, when an special tool I'm making calls the "onBlockDestroyed" how can I know from what side the player broke it.

 

onBlockDestroyed(ItemStack stack, World worldIn, Block blockIn, BlockPos pos, EntityLivingBase playerIn)

 

I basically need to know North or South // East or West // Top or Bottom

 

Thanks for the help.

Link to comment
Share on other sites

Well you could take the position of the entity that broke the block and the position of the block and calculate it

 

I thought that would be a possibility, but I discard it as them I thought I can be at the same position and I can see 3 faces of the block. Now if we consider the direction the player is looking at (Was this the VEC3 or something like that?) maybe then I could be able to know what side he broke.

 

Isn't there any method to get that on an easier way? Does anyone has an example on how that would be done?

 

Thanks a lot.

Link to comment
Share on other sites

Unfortunately there isn't a direct way, at least none that I am aware of, but you can use the current rotation and pitch of the entity that broke the block to approximate which direction they broke it from:

EnumFacing face = EnumFacing.fromAngle(entity.rotationYaw);
if (entity.rotationPitch < -45.0F) {
face = EnumFacing.UP;
} else if (entity.rotationPitch > 45.0F) {
face = EnumFacing.DOWN;
}

That's the same code (or essentially the same) that is used in the placement logic for directional blocks, so you probably need to use the opposite facing instead.

Link to comment
Share on other sites

Question:

What is your goal?

 

By which I mean: what are you going to do with that information?

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

Thanks Coolalias, I will look into that. I saw about EnumFacing on the Flint and Steel code. Will see how to implement that.

 

Draco18s I need it so, once the player break the block I need to break the 8 that are around it but I need to know where those 8 are, so if he hit the block, on the "North" face of the block (or South), then I break the 1 above and below, the one to the east and west and all the corresponding corners.

 

Now if he hit it from Top or Bottom, I remove all the surrounding ones on the same Y level.

 

That would be the final goal.

Link to comment
Share on other sites

Unfortunately there isn't a direct way, at least none that I am aware of, but you can use the current rotation and pitch of the entity that broke the block to approximate which direction they broke it from:

EnumFacing face = EnumFacing.fromAngle(entity.rotationYaw);
if (entity.rotationPitch < -45.0F) {
face = EnumFacing.UP;
} else if (entity.rotationPitch > 45.0F) {
face = EnumFacing.DOWN;
}

That's the same code (or essentially the same) that is used in the placement logic for directional blocks, so you probably need to use the opposite facing instead.

 

Will give it a try, but in my head I think something will fail here, as this is only considering the rotation pitch but even having those angles I bet player still can see 3 sides of any block.

 

The EnumFacing that is for example on Flint and Steel would be great to have here, but not sure how to acomplish that yet.

 

public boolean onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ)

Link to comment
Share on other sites

How is that 'only considering the rotation pitch?'

 

Look at the very first line:

EnumFacing face = EnumFacing.fromAngle(entity.rotationYaw);

 

Which has its value overwritten by the if statement. Imagine looking down and mining the side of a block. Your code there days the top was mined.

 

Anyway, you actually might want to look at World#doRaytrace() and EntityPlayer#lookVec()

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

@Draco No, it is not immediately overwritten. Look at the code more carefully - it only assigns TOP or BOTTOM if the pitch angle is greater than 45 or less than 45, so that whole 90 degrees in between is given to the cardinal facings.

 

Again, it is what vanilla uses somewhere for placing blocks, and I've used it in my own code with much success. If you want to go with a ray trace or something else, that's probably fine, too, provided the block is still in the world to be traced against.

Link to comment
Share on other sites

CoolAlias this is why that wont work for what I need.

 

See how I here get to break 3 different block and however the data is always the same.

 

I bet it does work to know where the "empty" block is (The air that share faces with the other 3) but not to know what side I hit the other blocks from.

 

w0C3YK9.png

 

PS: I should have represent it, poiting that I can also break the same block hitting it on any of the 3 faces I can see.

Link to comment
Share on other sites

The only way to be completely 100% accurate is to use raytracing, but that is probably not an option because the block is already broken, so the best you can is get a rough approximation which is what that code does.

 

In your case, you are looking down at the block (meaning you hit the top, which is why I suggested using #opposite [or don't use opposite if you are]). Try breaking a block not below your feet and you should get a cardinal direction.

 

If it absolutely MUST be accurate, you are going to have to do some extra work BEFORE the block breaks. Subscribe to PlayerInteractEvent and listen for LEFT_CLICK_BLOCK; from here, figure out the face clicked and store it along with the block position; when the block is broken, check if its position is the last one the player clicked and fetch the side hit from there.

Link to comment
Share on other sites

The only way to be completely 100% accurate is to use raytracing, but that is probably not an option because the block is already broken, so the best you can is get a rough approximation which is what that code does.

 

In your case, you are looking down at the block (meaning you hit the top, which is why I suggested using #opposite [or don't use opposite if you are]). Try breaking a block not below your feet and you should get a cardinal direction.

 

If it absolutely MUST be accurate, you are going to have to do some extra work BEFORE the block breaks. Subscribe to PlayerInteractEvent and listen for LEFT_CLICK_BLOCK; from here, figure out the face clicked and store it along with the block position; when the block is broken, check if its position is the last one the player clicked and fetch the side hit from there.

 

Yes I need it to be accurate. Even if Im looking down, it doesnt necesarily mean I hit the block on his top, I could have hit it on any of the 4 faces (sides) too.

 

Thanks for the suggestion about using events, I think that will have to be the way to go for this.

 

PS: I was just playing around with the RayTrace that Draco suggested and also came to my mind the same, that I will look for a block, once the block isn't there anymore, so I'm not sure I can make that work neither.

 

I'm also not sure, what the second vec3 that "worldIn.rayTraceBlocks" needs is? Anyone know? As for first vec3 I think it needs "playerIn.getLookVec();" but I'm not sure what the 2nd one is.

Link to comment
Share on other sites

Apparently this is gonna work.

 

       
        MovingObjectPosition movingobjectposition = this.getMovingObjectPositionFromPlayer(worldIn, (EntityPlayer) playerIn, false);

        if (movingobjectposition == null)
        {
            return false;
        }
        else
        {
        	System.out.println(movingobjectposition);
        }

 

Now time to create the switch statement :) but that's the easy part.

 

Let me know if you see anything wrong in here guys, thanks a lot once again, as always you are great. ;)

Link to comment
Share on other sites

@Draco No, it is not immediately overwritten. Look at the code more carefully - it only assigns TOP or BOTTOM if the pitch angle is greater than 45 or less than 45, so that whole 90 degrees in between is given to the cardinal facings.

 

While true, it is not 100% accurate, as the player may still mine the sides of the block from this position. Or the top, from a less inclined angle.

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

Item#getMovingObjectPositionFromPlayer still uses a ray trace, so if the block is not there, you will find the wrong block. However, you will probably be looking at the same face on the returned block as on the one you just broke, since that block is 'behind' it. Still, it won't be 100% accurate, just as my original solution is not 100% accurate - merely an approximation for when it's not application-critical.

 

If you want 100% accuracy, I suggest you use events like I mentioned earlier.

Link to comment
Share on other sites

Item#getMovingObjectPositionFromPlayer still uses a ray trace, so if the block is not there, you will find the wrong block. However, you will probably be looking at the same face on the returned block as on the one you just broke, since that block is 'behind' it. Still, it won't be 100% accurate, just as my original solution is not 100% accurate - merely an approximation for when it's not application-critical.

 

If you want 100% accuracy, I suggest you use events like I mentioned earlier.

Thanks, well thats what I thought, but... don't ask me why, it's returning the correct side, even when after breaking a block from one of its sides I end up watching the top face of a block, the method still return the correct side and not top.

 

I intentionally did those test, thinking the same way, that it will do the raytrace once the block is not there anymore and it will return the face of the next block I will be looking at, but no, it returns the right face.

Link to comment
Share on other sites

That happens because the raycast is occurring before the block is actually removed.

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



×
×
  • Create New...

Important Information

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