fuzzybat23 Posted October 15, 2017 Share Posted October 15, 2017 I found some old code for detecting if the block you're looking at is a door: public boolean isDoor(PlayerInteractEvent event) { BlockDoor door = (BlockDoor)Blocks.wooden_door; BlockLocation loc = BlockLocation.get(event.world, event.x, event.y, event.z); if((event.action == Action.RIGHT_CLICK_BLOCK) && (loc.getBlock() == door)) return true; } Of course this is out dated as BlockLocation is no longer used. That and Blocks.wooden_door doesn't exist anymore either. For an updated version of this, does this look about right? public void onDoorInteract(PlayerInteractEvent event) { Minecraft mc = Minecraft.getMinecraft(); BlockPos blockpos = mc.objectMouseOver.getBlockPos(); Block block = event.getEntityPlayer().getEntityWorld().getBlockState(blockpos).getBlock(); //call return if block isn't a door if((event.action != Action.RIGHT_CLICK_BLOCK) || !(WoodenDoor(block))) return; //Do stuff if it is a door } public boolean WoodenDoor(Block block) { BlockDoor[] doors = {(BlockDoor) Blocks.ACACIA_DOOR, (BlockDoor) Blocks.BIRCH_DOOR, (BlockDoor) Blocks.DARK_OAK_DOOR, (BlockDoor) Blocks.JUNGLE_DOOR, (BlockDoor) Blocks.OAK_DOOR, (BlockDoor) Blocks.SPRUCE_DOOR}; for(BlockDoor door : doors) { if(block == door) return true; } return false; } Also, event.action != Action.RIGHT_CLICK_BLOCK doesn't seem to exist since 1.8, either. Does anyone know how to do this in the current 1.12 environment? Quote Link to comment Share on other sites More sharing options...
JimiIT92 Posted October 15, 2017 Share Posted October 15, 2017 12 hours ago, fuzzybat23 said: Also, event.action != Action.RIGHT_CLICK_BLOCK doesn't seem to exist since 1.8, either. Does anyone know how to do this in the current 1.12 environment? Why don't you catch the RightClickBlock event directly instead and check if the clicked block is a door? Quote Don't blame me if i always ask for your help. I just want to learn to be better Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 Probably because I didn't know about the RIGHTCLICKBLOCK event Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 (edited) Ok.. I managed to find something about PlayerInteractEvent.RightClickBlock after lots of google digging I did managed to get it to register when I right click, but it doesn't seem to want to correctly check if it's a door or not, now. Edited October 15, 2017 by fuzzybat23 Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 @SubscribeEvent public void onDoorInteract(PlayerInteractEvent.RightClickBlock event) { EntityPlayer player = event.getEntityPlayer(); BlockPos blockpos = event.getPos().offset(event.getFace()); Block block = player.getEntityWorld().getBlockState(blockpos).getBlock(); logger.info("Begin check if it's a door..."); if( isWoodenDoor(block)) logger.info("It's a door!"); } public static boolean isWoodenDoor(Block block) { if(block == Blocks.ACACIA_DOOR || block == Blocks.DARK_OAK_DOOR || block == Blocks.BIRCH_DOOR || block == Blocks.JUNGLE_DOOR || block == Blocks.OAK_DOOR || block == Blocks.SPRUCE_DOOR) return true; return false; } Quote Link to comment Share on other sites More sharing options...
JimiIT92 Posted October 15, 2017 Share Posted October 15, 2017 BlockPos blockpos = event.getPos().offset(event.getFace()); What? I don't understand what are you trying to do there. To get the position of where the player right clicked you have the hitVec variable in the event. So to get the block you should do this Block block = event.getWorld().getBlockState(new BlockPos(event.getHitVec().x, event.getHitVec().y, event.getHitVec().z)).getBlock(); Quote Don't blame me if i always ask for your help. I just want to learn to be better Link to comment Share on other sites More sharing options...
Choonster Posted October 15, 2017 Share Posted October 15, 2017 5 minutes ago, JimiIT92 said: BlockPos blockpos = event.getPos().offset(event.getFace()); What? I don't understand what are you trying to do there. To get the position of where the player right clicked you have the hitVec variable in the event. So to get the block you should do this Block block = event.getWorld().getBlockState(new BlockPos(event.getHitVec().x, event.getHitVec().y, event.getHitVec().z)).getBlock(); getHitVec is the position on the block that the player clicked (in the range 0-1), not the position of the block in the world. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 I think I figured this one out. I ended up using this code and tested it and it worked just fine, letting me know if what I clicked on was a door and if it wasn't. I've even gotten it to distinguish between the different kinds of doors. @SubscribeEvent public void onBlockInteract(PlayerInteractEvent.RightClickBlock event) { Minecraft mc = Minecraft.getMinecraft(); EntityPlayer player = event.getEntityPlayer(); BlockPos pos = mc.objectMouseOver.getBlockPos(); Block block = player.getEntityWorld().getBlockState(pos).getBlock(); IBlockState state = player.getEntityWorld().getBlockState(pos); logger.info("Begin check if it's a door..."); if( isWoodenDoor(block)) logger.info("It's a door!" + WoodenDoor.whichDoor(block)); } public static boolean isWoodenDoor(Block block) { if(block == Blocks.ACACIA_DOOR || block == Blocks.BIRCH_DOOR || block == Blocks.DARK_OAK_DOOR || block == Blocks.JUNGLE_DOOR || block == Blocks.OAK_DOOR || block == Blocks.SPRUCE_DOOR) return true; return false; } public static BlockDoor whichDoor(Block block) { if(block == Blocks.ACACIA_DOOR) return Blocks.ACACIA_DOOR; if(block == Blocks.BIRCH_DOOR) return Blocks.BIRCH_DOOR; if(block == Blocks.DARK_OAK_DOOR) return Blocks.DARK_OAK_DOOR; if(block == Blocks.JUNGLE_DOOR) return Blocks.JUNGLE_DOOR; if(block == Blocks.OAK_DOOR) return Blocks.OAK_DOOR; if(block == Blocks.SPRUCE_DOOR) return Blocks.SPRUCE_DOOR; return null; } Quote Link to comment Share on other sites More sharing options...
JimiIT92 Posted October 15, 2017 Share Posted October 15, 2017 (edited) 1 hour ago, Choonster said: getHitVec is the position on the block that the player clicked (in the range 0-1), not the position of the block in the world. Actually i use that in my mod to detect when a player uses a flint and steel on an unlit torch and it returns almost the coordinates of the torch. I've done a test right now, the torch was at {x=-7, y=84, z=19}, the getHitVec returned me this {x=-6.399999976158142, y=84.39314504887278, z=19.46219003009727}. Is this a recent change or i just something that shouldn't happen? By the way you can just do this event.getWorld().getBlockState(event.getPos()).getBlock() And it will tell you what block the player has right clicked Edited October 15, 2017 by JimiIT92 Quote Don't blame me if i always ask for your help. I just want to learn to be better Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 I know almost noth9ing about gethitvec, but based on those different xyz values, the torch will of course be on whole numbers. 7, 84 and 19. The gethitvec is probably returning the exact area within the bounding box that you clicked on, which can't possibly be whole numbers? Quote Link to comment Share on other sites More sharing options...
JimiIT92 Posted October 15, 2017 Share Posted October 15, 2017 Yes, but Choonster said it should return values between 0 and 1, wich is not Quote Don't blame me if i always ask for your help. I just want to learn to be better Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 That's wrong. This is the code directly from PlayerInteractEvent.java /** * @return The hit vector of this click */ public Vec3d getHitVec() { return hitVec; } Unless I'm wrong, a hit vector is the X Y Z coordinates of a hit, right? Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 15, 2017 Author Share Posted October 15, 2017 And yes, event.getWorld().getBlockState(event.getPos()).getBlock() does seem to work a little better as far as getting the block being right clicked. Cleans up my code by five lines at least xD Quote Link to comment Share on other sites More sharing options...
Choonster Posted October 16, 2017 Share Posted October 16, 2017 (edited) I must have confused getHitVec with the hitX/Y/Z arguments of Block#onBlockActivated, which I'm pretty sure are between 0 and 1. I don't have my IDE in front of me, so I might be mistaken (again). Edit: The hitX/Y/Z arguments of Block#onBlockActivated are between 0 and 1. Edited October 16, 2017 by Choonster Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 16, 2017 Author Share Posted October 16, 2017 See, when people say use an instance of BlockDoor, that just confuses the hell out of me -.- I live in a world of examples. Unless an example is given, then something like what you said is completely lost to me Anyway, for what i'm working on, the first step was being able to identify the block being interacted with, in this case by right click, as a door. Not just as a door, but as a wooden door. Since iron doors fall into the category of BlockDoor, I just can't run a generic test to say "Is it a door? Yup." No, it has to be "Is it an Acacia door, a jungle door, a dark oak door, a birch door, an oak door or a spruce door? Yes." A few versions ago, pre 1.9 I think, all you had to check was wooden_door, but now wooden_door only pertains to oak doors, where they should have given oak doors their own name in code and kept wooden_doors as a check for all wood type doors. Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 16, 2017 Author Share Posted October 16, 2017 Second phase of what I'm doing is determining if an adjacent block contains a door. In other words, two doors side by side. Then figure out if those doors are mirror to each other, and when one of the two is right clicked, it will send a door toggle to the other opening it automatically. Say you're standing in the world facing north and you place a door in front of you. It's hinges are facing east. You place a door next to it one block to the west. It's hinges are facing west. You have a set of proper double doors now. Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 16, 2017 Author Share Posted October 16, 2017 Mmmm, so instead of this: public static boolean isWoodenDoor(Block block) { if(block == Blocks.ACACIA_DOOR || block == Blocks.BIRCH_DOOR || block == Blocks.DARK_OAK_DOOR || block == Blocks.JUNGLE_DOOR || block == Blocks.OAK_DOOR || block == Blocks.SPRUCE_DOOR) return true; return false; } Use something like this? public static boolean isWoodenDoor(IBlockState state) { if(state.getBlock() instanceof BlockDoor && state.getMaterial() == Material.WOOD) return true; return false; } Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 16, 2017 Author Share Posted October 16, 2017 Also, does this look about right as far as looping through the enumfacing? Passing in the right click event to generate the new target block, using offset(facing) to offset targetblock from block. public void checkForDoors(PlayerInteractEvent.RightClickBlock event, Block block) { for(EnumFacing facing : EnumFacing.HORIZONTALS) { Block targetblock = event.getWorld().getBlockState(event.getPos().offset(facing)).getBlock(); if(targetblock == block) //Do stuff if block that is offset to original block is same as original block } } Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 17, 2017 Author Share Posted October 17, 2017 You said that the hinge is on the top half of the door, and the hinge side is used to determine if the doors face each other, right? I found this in an older mod, but I'm not sure what the updated code would look like. I know that this is definitely outdated, though, but from what I can tell it did exactly that. Determined if it was the upper or lower part of the door being interacted with and set a door variable to the top portion. Block blockBottom = block.getRelative(BlockFace.DOWN); Block blockTop = block.getRelative(BlockFace.UP); Block blockNearBottom = blockBottom.getRelative(BlockFace.NORTH); Block blockNearTop = blockTop.getRelative(BlockFace.NORTH); Door door = (Door)block.getState().getData(); Door doorTop = (Door)block.getState().getData(); Door doorBottom = (Door)block.getState().getData(); Door doorNearBottom = (Door)block.getState().getData(); Door doorNearTop = (Door)block.getState().getData(); if (door.isTopHalf()) { blockTop = block; doorTop = door; doorBottom = (Door)blockBottom.getState().getData(); } else { blockBottom = block; doorBottom = door; doorTop = (Door)blockTop.getState().getData(); } I don't think getRelative exists anymore, and Door isn't a type anymore, it's now BlockDoor. Quote Link to comment Share on other sites More sharing options...
Choonster Posted October 17, 2017 Share Posted October 17, 2017 That code looks like it's from a Bukkit plugin (or a plugin for a similar system) rather than an old Forge mod. You need to use IBlockState#getValue to get the values of the various properties stored in the BlockDoor class from the state. This will tell you the door's facing and hinge position diesieben07 explained which properties you need and which block to get their values from earlier in the thread. Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 17, 2017 Author Share Posted October 17, 2017 Oh crap, that code is from a bukkit plugin x.x I just decompiled it again and checked the imports. Dunno how I missed that before Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted October 24, 2017 Author Share Posted October 24, 2017 I was rooting around through BlockDoor.java looking for something unrelated and I saw a few snippets that sparked inspiration. Ran and tested this and it seems to work just fine public static boolean isDoubleDoor(World world, BlockPos pos, EnumFacing offsetPos) { String RIGHT = "RIGHT"; String LEFT = "LEFT"; boolean flag = false; IBlockState targetState = world.getBlockState(pos); Block targetBlock = targetState.getBlock(); IBlockState offsetState = world.getBlockState(pos.offset(offsetPos)); Block offsetBlock = offsetState.getBlock(); //Get correct blockState, including hinge, for targeted door. if(targetState.getValue(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER) if(targetState.getBlock() == targetBlock) targetState = world.getBlockState(pos.up()); BlockDoor.EnumHingePosition targetHinge = targetState.getValue(BlockDoor.HINGE); //get correct blockState, including hinge, for offset door. if(offsetState.getValue(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER) if(offsetState.getBlock() == offsetBlock) offsetState = world.getBlockState(pos.offset(offsetPos).up()); BlockDoor.EnumHingePosition offsetHinge = offsetState.getValue(BlockDoor.HINGE); logger.info("(targetHinge)(name)" + targetHinge.name() + "=? (offsetHinge)(name)" + offsetHinge.name() ); if(((targetHinge.name() == RIGHT) && (offsetHinge.name() == LEFT)) || ((targetHinge.name() == LEFT) && (offsetHinge.name() == RIGHT))) flag = true; return flag; } First checks if it's the lower half of the door and if so, resets the blockState to the upper half. Then it grabs the side of the door the hinge is on and checks if hinges on the two doors are on the opposite outer sides. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.