Posted November 16, 201311 yr Hi, I'm one of the modders of the Crafting Pillars mod and I'm working on a better interraction handling system. My problem is that the client side doesn't call the onClick method with LEFT_CLICK_BLOCK event. I want to cancel that event and send a custom packet to the server. My event handler: @ForgeSubscribe public void onClick(PlayerInteractEvent event) { if(event.entityPlayer.worldObj.isRemote) { if(event.action == Action.LEFT_CLICK_BLOCK) // Never true { if(doClick(0, event)) event.setCanceled(true); } else if(event.action == Action.RIGHT_CLICK_BLOCK) // Works perfectly { if(doClick(2, event)) event.setCanceled(true); } else if(event.action == Action.RIGHT_CLICK_AIR) // Works perfectly { if(doClick(2, event)) event.setCanceled(true); } } } Thanks for your help! Sorry for my bad English! FBalazs
November 16, 201311 yr Hi I have created something similar to let you intercept the left and right clicks, it works pretty well for me. https://gist.github.com/TheGreyGhost/7033821 Some background info too that might be helpful http://greyminecraftcoder.blogspot.com.au/2013/10/user-input.html -TGG
November 16, 201311 yr Author How are you using this? With a tick handler? Am I right? protected void copyClickInfoFromOriginal() { this.pressTime += interceptedKeyBinding.pressTime; this.interceptedPressTime += interceptedKeyBinding.pressTime; interceptedKeyBinding.pressTime = 0; // this line clears the data from the original binding if I don't do that LEFT_CLICK_BLOCK will be called else it won't be called this.pressed = interceptedKeyBinding.pressed; } Sorry for my bad English! FBalazs
November 16, 201311 yr Hi Yes that's right, I was using this class to capture the left & right clicks when a certain item is being held, and the tick handler was checking the intercepted keyhandler once per tick using .retrieveClick But just to be clear, your code doesn't need to call copyClickInfoFromOriginal itself. Is is called by the vanilla code (the vanilla code calls isPressed(), which calls copyClickInfoFromOriginal) I'm not sure that the comment you've added in the code is correct. The vanilla code never sees interceptedKeyBinding.pressTime because the GameSettings.keyBindAttack is pointing to the KeyBindingInterceptor. To stop the code from receiving left clicks, turn interception on and check for the clicks in your tickhandler using retrieveClick. When you turn interception off, the clicks go through to the vanilla code again. -TGG
November 17, 201311 yr Author Hi I can't get your code to work. I don't think it can clear any key presses. Here's the code. The commented lines are my try. package me.dawars.CraftingPillars.handlers; import java.util.EnumSet; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import me.dawars.CraftingPillars.CraftingPillars; import me.dawars.CraftingPillars.blocks.BasePillar; import me.dawars.CraftingPillars.client.KeyBindingInterceptor; import me.dawars.CraftingPillars.network.packets.PacketClick; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.settings.GameSettings; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; public class TickHandler implements ITickHandler { public boolean doClick(int button) { World world = Minecraft.getMinecraft().theWorld; EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; for(int x = (int)player.posX-5; x <= (int)player.posX+5; x++) for(int y = (int)player.posY-5; y <= (int)player.posY+5; y++) for(int z = (int)player.posZ-5; z <= (int)player.posZ+5; z++) if(Block.blocksList[world.getBlockId(x, y, z)] instanceof BasePillar) { int id = ((BasePillar)Block.blocksList[world.getBlockId(x, y, z)]).getClickedButtonId(world, x, y, z, button, player); if(id > -1) { //System.out.println("Packet sent! "+button+" "+id+" "+x+" "+y+" "+z); CraftingPillars.proxy.sendToServer(new PacketClick(button, id, x, y, z).pack()); return true; } } return false; } boolean pleft, pright; GameSettings gs; KeyBindingInterceptor intLeft, intRight; public TickHandler() { gs = Minecraft.getMinecraft().gameSettings; intLeft = new KeyBindingInterceptor(gs.keyBindAttack); intRight = new KeyBindingInterceptor(gs.keyBindUseItem); intLeft.setInterceptionActive(true); intRight.setInterceptionActive(true); } @Override public void tickStart(EnumSet<TickType> type, Object... tickData) { // This code doesn't clear any presses if(intLeft.isKeyDown()) { if(!pleft) { if(doClick(0)) pleft = true; } if(pleft) intLeft.retrieveClick(); } else pleft = false; if(intRight.isKeyDown()) { if(!pright) { if(doClick(2)) pright = true; } if(pright) intRight.retrieveClick(); } else pright = false; // This is my code, it works fine expect the first tick of click /*if(gs.keyBindAttack.pressed) { if(!pleft && doClick(0)) { pleft = true; gs.keyBindAttack.pressed = false; } } else { pleft = false; } if(gs.keyBindUseItem.pressed) { System.out.println("right"); if(!pright && doClick(2)) { pright = true; gs.keyBindUseItem.pressed = false; } } else { pright = false; }*/ } @Override public void tickEnd(EnumSet<TickType> type, Object... tickData) { } @Override public EnumSet<TickType> ticks() { return EnumSet.of(TickType.CLIENT); } @Override public String getLabel() { return CraftingPillars.name+" TickHandler"; } } I want to clear the keypress when i can handle it so no vanilla click packets will be send to the server. In my code it is done but the first tick. What am i doing wrong? Sorry for my bad English! FBalazs
November 17, 201311 yr Hi Try this.... public TickHandler() { gs = Minecraft.getMinecraft().gameSettings; intLeft = new KeyBindingInterceptor(gs.keyBindAttack); intRight = new KeyBindingInterceptor(gs.keyBindUseItem); gs.keyBindAttack = intLeft; gs.keyBindUseItem = intRight; intLeft.setInterceptionActive(true); intRight.setInterceptionActive(true); } This replaces the vanilla key bindings with the interceptor, which will stop the vanilla code from receiving any keypresses while the interception is active, and will also keep the intLeft and intRight updated with the latest keypresses. If you're just interested in clicks (rather than the user holding the button down), then all you need is if (intLeft.retrieveClick()) { // left was clicked you don't need to use isKeyDown(). But just to be clear - do you need to stop the vanilla code from receiving the clicks? or do you just want to tell when the user has clicked so you can do something extra? -TGG
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.