Basic items can only go so far - eventually you will need an item that interacts with the world when it is used.
There are some key classes you must understand before taking a look at the vanilla item events.
InteractionResultHolder
For items, the most common InteractionResultHolder you'll see is for ItemStacks - this class tells the game what to replace the item stack (or not to replace) after the event has occured.
If nothing has occured in the event, you should use the InteractionResultHolder#pass(stack) method where stack is the current item stack.
You can get the current item stack by getting the stack in the player's hand. Usually events that require a InteractionResultHolder pass the hand to the event method.
java
InteractionResultHolder.pass(user.getStackInHand(hand))1
If you pass the current stack - nothing will change, regardless of if you declare the event as failed, passed/ignored or successful.
If you want to delete the current stack, you should pass an empty one. The same can be said about decrementing, you fetch the current stack and decrement it by the amount you want:
java
ItemStack heldStack = user.getStackInHand(hand);
heldStack.decrement(1);
InteractionResultHolder.success(heldStack);1
2
3
2
3
InteractionResult
Similarly, an InteractionResult tells the game the status of the event, whether it was passed/ignored, failed or successful.
Overridable Events
Luckily, the Item class has many methods that can be overriden to add extra functionality to your items.
INFO
A great example of these events being used can be found in the Playing SoundEvents page, which uses the useOn event to play a sound when the player right clicks a block.
| Method | Information |
|---|---|
hurtEnemy | Ran when the player hits an entity. |
mineBlock | Ran when the player mines a block. |
inventoryTick | Ran every tick whilst the item is in an inventory. |
onCraftedPostProcess | Ran when the item is crafted. |
useOn | Ran when the player right clicks a block with the item. |
use | Ran when the player right clicks the item. |
The use() Event
Let's say you want to make an item that summons a lightning bolt infront of the player - you would need to create a custom class.
java
public class LightningStick extends Item {
public LightningStick(Properties settings) {
super(settings);
}
}1
2
3
4
5
6
2
3
4
5
6
The use event is probably the most useful out of them all - you can use this event to spawn our lightning bolt, you should spawn it 10 blocks in front of the players facing direction.
java
@Override
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
// Ensure we don't spawn the lightning only on the client.
// This is to prevent desync.
if (world.isClientSide) {
return InteractionResultHolder.pass(user.getItemInHand(hand));
}
BlockPos frontOfPlayer = user.blockPosition().relative(user.getDirection(), 10);
// Spawn the lightning bolt.
LightningBolt lightningBolt = new LightningBolt(EntityType.LIGHTNING_BOLT, world);
lightningBolt.setPos(frontOfPlayer.getCenter());
world.addFreshEntity(lightningBolt);
// Nothing has changed to the item stack,
// so we just return it how it was.
return InteractionResultHolder.success(user.getItemInHand(hand));
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
As usual, you should register your item, add a model and texture.
As you can see, the lightning bolt should spawn 10 blocks infront of you - the player.

