Jump to content

[1.14.4] how to stop RightClickEvent being fired for the other hand?


TheOnlyTrueEnte

Recommended Posts

Hi, I created a RightClickEvent to allow the player to strip my modded wood by right-clicking it with an axe.

The problem is that if the player also has an item in their off-hand (e.g. dirt), that one is also used after the wood is stripped (e.g. the dirt is placed).

The cause seems to be that the event is always for both hands even if one has already changed the result. I've tried every combination of setting event.useItem/useBlock/result to ALLOW/DEFAULT/DENY and calling event.setCancelled() but nothing helped.

At the beginning of the method, event.getResult() always returns DEFAULT, so a special case there also doesn't help.

 

My event is defined as:

@SubscribeEvent
public static void centeBlockStripping(PlayerInteractEvent.RightClickBlock event){
	LOGGER.info("Event hand: "+event.getHand());
	if(event.getItemStack().getItem() instanceof AxeItem){
		if(event.getWorld().getBlockState(event.getPos()).getBlock() instanceof CustomLog) {
        	stripWood(...); damageAxe(...);
			event.setResult(Event.Result.ALLOW);
          	event.setUseItem(Event.Result.DENY);
          	event.setUseBlock(Event.Result.DENY);
        }
    }
}

and every time I right click a block, the event is fired twice for each hand.

Log: 

Spoiler

Event hand: MAIN_HAND

Event hand: MAIN_HAND

Event hand: OFF_HAND

Event hand: OFF_HAND

What am I doing wrong?

Cheers

 

Edited by TheOnlyTrueEnte
clarification
Link to comment
Share on other sites

That event is fired on both the server and the client, which is normal behavior. If you need to filter it out, perhaps check if the player's world is on the client or not the event itself has a method to check the logical side, so that would be the best place to check where the event comes from.

Edited by imacatlolol

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

Link to comment
Share on other sites

Just now, imacatlolol said:

That event is fired on both the server and the client, which is normal behavior. You may need to filter them out if desired.

Thank you, that explains why the event is being fired twice from each hand but it doesn't solve the problem.

My problem is that it's being fired for the offhand even if the main hand's event already changed the results.

Link to comment
Share on other sites

1 minute ago, TheOnlyTrueEnte said:

Thank you, that explains why the event is being fired twice from each hand but it doesn't solve the problem.

My problem is that it's being fired for the offhand even if the main hand's event already changed the results.

Oh, my bad. I believe that is normal behavior as well, since both hands can "right click". Perhaps check which hand is holding the item, and then pick the correct hand (I'd recommend choosing the offhand first, if both hands have the item).

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

Link to comment
Share on other sites

4 minutes ago, imacatlolol said:

Oh, my bad. I believe that is normal behavior as well, since both hands can "right click". Perhaps check which hand is holding the item, and then pick the correct hand (I'd recommend choosing the offhand first, if both hands have the item).

But if a vanilla item (or an item from another mod) is in the offhand and an axe is in the main hand, how can I make my event prevent the offhand from using the item?

before right-click:

before rightclick.png

after right-click:

after rightclick.png

Edited by TheOnlyTrueEnte
titles for images
Link to comment
Share on other sites

7 minutes ago, TheOnlyTrueEnte said:

But if a vanilla item (or an item from another mod) is in the offhand and an axe is in the main hand, how can I make my event prevent the offhand from using the item?

Oh, I see what you mean. (I'm not on my A-game today)

I'm sure a more experienced developer can offer a better solution, but you might try storing a temporary "cancel next" variable that cancels the following event in the opposite hand.

Edited by imacatlolol
Typo
  • Thanks 1

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

Link to comment
Share on other sites

One thing to mention, if you want to use my not-too-elegant solution, the main hand event will always fire first (since it's first in the Hand enum) so you'd only need to "cancel next" if the main hand fulfills the conditions.

  • Thanks 1

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

Link to comment
Share on other sites

38 minutes ago, imacatlolol said:

One thing to mention, if you want to use my not-too-elegant solution, the main hand event will always fire first (since it's first in the Hand enum) so you'd only need to "cancel next" if the main hand fulfills the conditions.

That's good to know, thanks. I managed to get it to work!

 

EDIT: The fix (canceling the off-hand's event if the main hand's event stripped a log) now successfully prevents the offhand from placing dirt. If the offhand is holding an Ender Pearl, however, it is thrown regardless. I'll have to do some more testing tomorrow. Also, if another mod registers an event listener for the item in the off-hand and that listener is executed before mine, it will go through and I can't do anything against it.

Edited by TheOnlyTrueEnte
further issue
Link to comment
Share on other sites

4 hours ago, TheOnlyTrueEnte said:

That's good to know, thanks. I managed to get it to work!

 

EDIT: The fix (canceling the off-hand's event if the main hand's event stripped a log) now successfully prevents the offhand from placing dirt. If the offhand is holding an Ender Pearl, however, it is thrown regardless. I'll have to do some more testing tomorrow. Also, if another mod registers an event listener for the item in the off-hand and that listener is executed before mine, it will go through and I can't do anything against it.

Hmm, that's certainly frustrating. When it comes to events, I'm not sure if there's an easy workaround.

However, since the route you want to go may not work out, I do have two other suggestions to consider, just in case:

  • Override onBlockActivated in your block's class and run your code there instead; this is likely the best alternative.
  • Use an access transformer (or use reflection) to make BLOCK_STRIPPING_MAP in AxeItem public, then modify it to include your blocks. Or, since it's only protected, you can technically also add your own axe and modify it there.

I'm eager to learn and am prone to mistakes. Don't hesitate to tell me how I can improve.

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.