How do I query if a binded key is unpressed and how long it has been pressed?

Started by ahznb on

Topic category: Help with Minecraft modding (Java Edition)

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
How do I query if a binded key is unpressed and how long it has been pressed?
Wed, 11/27/2019 - 04:35 (edited)

Hi,

I've created a new key binding procedure. The generated procedure only activates on key press and does not have the pressed "key" as dependency, and there are no preset procedures to query key state. I'd like the procedure to query the key press state, like if it has been released, how long the key has been pressed, etc. How do I do that with minimal coding, or better yet without coding?

Thanks!

Edited by ahznb on Wed, 11/27/2019 - 04:35
Detecting key unpress is not…
Wed, 11/27/2019 - 13:27

Detecting key unpress is not possible yet without coding. I suggest you open a support ticket requesting this feature and we will consider adding it.

You can count the time between two presses by making a global timer and use the timer variable to count the difference between two checks. Global timer: https://www.youtube.com/watch?v=FtyyMz6rBXc&list=PLAeL-oIFIEngE6jRgFYeFMfuj8WQsO3Ei&index=56&t=1s

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Thanks. I will try to open a…
Wed, 11/27/2019 - 17:19

Thanks. I will try to open a ticket.

Can you give me a simple example how to detect key press time with minimal coding?

I do not have any example…
Wed, 11/27/2019 - 17:39

I do not have any example for this right now as I don't know how to detect key release yet. I have an idea on how one would do this, but it would require Java knowledge to actually implement this for your case.

If you don't know Java, I suggest you open a ticket and wait for us to implement this.

Here is a topic I found for…
Wed, 11/27/2019 - 17:43

Here is a topic I found for 1.7.10, but checking for key binding did not change that much: https://www.minecraftforge.net/forum/topic/33522-1710-keybinding-keyup-method/

Basically you would need to store previous value and current click value on input event and check if the state went from pressed to released and trigger procedure in such case.

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Thanks. But I have another…
Thu, 11/28/2019 - 06:09

Thanks.

But I have another question about the code. Why is keybinding event doing this:

    @SubscribeEvent
    @SideOnly(Side.CLIENT)
    public void onKeyInput(InputEvent.KeyInputEvent event) {
        if (!FMLClientHandler.instance().isGUIOpen(GuiChat.class)) {
            if (org.lwjgl.input.Keyboard.isKeyDown(keys.getKeyCode())) {
                myMod.PACKET_HANDLER.sendToServer(new KeyBindingPressedMessage());
            }
        }
    }

    public static class KeyBindingPressedMessageHandler implements IMessageHandler<KeyBindingPressedMessage, IMessage> {
        @Override
        public IMessage onMessage(KeyBindingPressedMessage message, MessageContext context) {
            EntityPlayerMP entity = context.getServerHandler().player;
            entity.getServerWorld().addScheduledTask(() -> {

 instead of just calling the handler directly in onKeyInput? Can I just call the handler directly? If not, how do I pass on more arguments to onMessage?

Because keypress happens on…
Thu, 11/28/2019 - 09:39

Because keypress happens on the client side, but events need to happen on the server-side to propagate to all clients, otherwise you will have pretty strange things happening.

To pass more data, just adds new fields to KeyBindingPressedMessage and properly store them to NBT data that is passed to the server side.

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
So I basically added a new…
Thu, 11/28/2019 - 10:37

So I basically added a new int "dummy" in KeyBindingPressedMessage, and set it in onKeyInput, like this: 

	public void onKeyInput(InputEvent.KeyInputEvent event) {
		if (!FMLClientHandler.instance().isGUIOpen(GuiChat.class)) {
			int dummy = keys.getKeyCode();
			if (org.lwjgl.input.Keyboard.isKeyDown(dummy)) {
				KeyBindingPressedMessage message = new KeyBindingPressedMessage();
				message.key_processed = dummy;
				jadens_sword.PACKET_HANDLER.sendToServer(message);
			}
		}
	}

	public static class KeyBindingPressedMessage implements IMessage {
		public int dummy;
		
		@Override
		public void toBytes(io.netty.buffer.ByteBuf buf) {
		}

		@Override
		public void fromBytes(io.netty.buffer.ByteBuf buf) {
		}
	}
}

But when I access it here:

	public static class KeyBindingPressedMessageHandler implements IMessageHandler<KeyBindingPressedMessage, IMessage> {
		@Override
		public IMessage onMessage(KeyBindingPressedMessage message, MessageContext context) {
			EntityPlayerMP entity = context.getServerHandler().player;
			entity.getServerWorld().addScheduledTask(() -> {
				World world = entity.world;
				int key = message.dummy;

its value is always 0. What did I do wrong?

and properly store them to…
Thu, 11/28/2019 - 10:39

and properly store them to NBT data that is passed to the server side.

Use toBytes and fromBytes methods to store the data to ByteBuf which is then sent to the server.

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
 Oops, wrong code. This is…
Thu, 11/28/2019 - 10:41

 Oops, wrong code.

This is the "real" code:

	public void onKeyInput(InputEvent.KeyInputEvent event) {
		if (!FMLClientHandler.instance().isGUIOpen(GuiChat.class)) {
			int dummy = keys.getKeyCode();
			if (org.lwjgl.input.Keyboard.isKeyDown(dummy)) {
				KeyBindingPressedMessage message = new KeyBindingPressedMessage();
				message.dummy = dummy;
				jadens_sword.PACKET_HANDLER.sendToServer(message);
			}
		}
	}

	public static class KeyBindingPressedMessage implements IMessage {
		public int dummy;
		
		@Override
		public void toBytes(io.netty.buffer.ByteBuf buf) {
		}

		@Override
		public void fromBytes(io.netty.buffer.ByteBuf buf) {
		}
	}
}

 

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Oh, that's beyond me then…
Thu, 11/28/2019 - 11:29

Oh, that's beyond me then. Do I need to implement toBytes and fromBytes to read/write from buf to dummy? When I create a new KeyBindingPressedMessage do I need to allocate memory for a buffer or can I use dummy as a 4 byte buffer?

Buffer will do all the…
Thu, 11/28/2019 - 14:17

Buffer will do all the allocation. You can check GUI mod element code for button events, as for buttons, button ID is passed in the message.

Joined Nov 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Wow, I just love sample code…
Thu, 11/28/2019 - 15:01

Wow, I just love sample code! Thanks! That did it.