### Note on `InteractionResult` - `consume` implies one of `SUCCESS`, `SUCCESS_NO_ITEM_USED`, `CONSUME`, `CONSUME_PARTIAL` - `swing` implies one of `SUCCESS`, `SUCCESS_NO_ITEM_USED` ### The current interaction events - `LivingEntityUseItemEvent` - *not abstract⚠*: * `Start` - `LivingEntity#startUsingItem` - **C**, fired in `LivingEntity#startUsingItem`, can modify the use duration (or cancel with a value < 0) * `Tick` - `LivingEntity#updateUsingItem`: - we have a patch for `IItemExtension#canContinueUsing`, that provides more control over whether items can still be used, even after having been changed - event fired in `LivingEntity#updateUsingItem`, only allows changing the remaining duration (or cancelling -> -1, triggering a completion) - does not allow preventing `Item#onUseTick` from being called, unless the reamining ticks are set to `0` or less, which also causes completion * `Stop` - `LivingEntity#releaseUsingItem` - **C**, fired before `Item#releaseUsing` and `EH#onPlayerDestroyItem`; does not affect `Item#useOnRelease` (which may trigger another use, in the case of crossbows) * `Finish` - `LivingEntity#completeUsingItem` - **NC**, can change result stack, but fired after `triggerItemUseEffects` (sounds); if changed, calls `setItemInHand`, but the `useItem` isn't changed so `Item#onStopUsing` is still called on the original item in `stopUsingItem` - `ArrowNockEvent` - *⚠ pls remove*; **C**, fired in `BowItem#use`, provides `player.getProjectile(itemstack).isEmpty()` over any other interaction events. If cancelled, or with a non-null `InteractionResultHolder`, it will exit with it. - `FillBucketEvent` - **C**, fired in `BucketItem#use` early, if cancelled it will `FAIL` the interaction, can modify the result item stack - `PlayerInteractEvent` - brace yourselves: * `EntityInteractSpecific` - **C**, earliest, fired in - `ServerGamePacketListenerImpl$handleInteract$onInteraction`, a cancellation result will prevent `Entity#interactAt`; a consumed action will trigger `PLAYER_INTERACTED_WITH_ENTITY`, and a success will also triger a `swing` - on the clientside, fired in `MultiPlayerGameMode#interactAt`, after the packet was sent, and after spectator checks; a cancellation result will prevent `Entity#interactAt`; if consumed, item, block or `Entity#interact` interactions will be aborted; swing is triggered by a success **AND** the `InteractionKeyMappingTriggered` event setting `shouldSwingHand` (`true` by default), which always takes effect, regardless of cancellation - `EntityInteract` - **C**, fired in `Player#interactOn`, but **not** when in spectator as that only allows opening menu entities; triggered only if `interactAt` (see above) is **NOT** consumed; result implies: - server side: `PLAYER_INTERACTED_WITH_ENTITY` if consumed, swing if success - client side: same effect as above - `RightClickBlock` - **C**, after entity interactions, fired in: - server side: `SPGM#useItemOn`, success triggering swing, consume triggering `ANY_BLOCK_USE` - client side: `MPGM#performUseItemOn`, will stil send packet to the server; consumed action prevents further item interaction, success action and `InteractionKeyMappingTriggered#shouldSwingHand` implies a swing, with a client-side use item animation if on creative or item count has decreased; - common, if not cancelled: - a non-deny of `useItem` will call `ItemStack#onItemUseFirst` (triggering `ITEM_BEFORE_BLOCK@UseItemOnBlockEvent`) - explicit `ALLOW` or `DEFAULT` with met conditions (!(`doesSneakBypassUse` && `isSecondaryUseActive`)) will proceed to call `Block#useItemOn` (which fires `BLOCK@UseItemOnBlockEvent`): - a consumed result will have the effects described above, triggering `ITEM_USED_ON_BLOCK` - `ItemInteractionResult#PASS_TO_DEFAULT_BLOCK_INTERACTION` and main hand will trigger `Block#useWithoutItem`, and a consumed result will have the effects described above, triggering `DEFAULT_BLOCK_USE` - `DENY` of `useItem` will return `InteractionResult.PASS` - `ALLOW` / `DEFAULT` (stack not empty or not on cooldown) and conditions met of `useItem` will trigger `Item#useOn` (firing `ITEM_AFTER_BLOCK@UseItemOnBlockEvent`, with effects described above, and triggering `ITEM_USED_ON_BLOCK` (creative will restore the count) - otherwise, returns `InteractionResult.PASS` `RightClickEmpty` - **NC**, after block interactions, **ONLY ON THE CLIENT**, if use stack is empty and interaction was a miss (no block, no entity, i.e. "empty space") - `RightClickItem` - **C**, after block interactions, if use stack is not empty: - server side: `SPGM#useItem`, success triggering swing; only fired after cooldown and spectator checks, before `Item#use` - client side: `MPGM#useItem`, after the cooldown check, before `Item#use`, cancellation does not prevent packet; consumed action triggers client-side use animation, success triggers swing - `LeftClickBlock` - **C**, fired when a block is left clicked: - server side: `SPGM#handleBlockBreakAction` (triggered by `START_DESTROY_BLOCK`, `ABORT_DESTROY_BLOCK`, `STOP_DESTROY_BLOCK`), cancelled event or `DENY` in survival mode prevents further processing; - `START_DESTROY_BLOCK`: if `useBlock` is not `DENY`, `Block#attack` will be called - client side: `MPGM#startDestroyBlock`: - creative mode: fires as `START_DESTROY_BLOCK`, if cancelled, block will not be broken (but packet sent) - if the player has already started destroying, and continues to in this interaction, fires as `CLIENT_HOLD`, and a `DENY` of `useItem` prevents the block from actually being destroyed, but does not prevent destruction progress from being incremented - if the player starts destroying a new block, fires as `START_DESTROY_BLOCK`; `useBlock` of `DENY` prevents `Block#attack` from being called; `useItem` of `DENY` prevents destruction from starting - `LeftClickEmpty` - **NC**, last punch action, fired only if the left click was a miss (i.e. "empty space"), with a 10 tick cooldown #### Client-side events - `InputEvent.InteractionKeyMappingTriggered`: - triggers with `0` as left click, cancellation prevents destruction (progress) - triggers with `1` as right click, cancellation prevents entity/block/item/empty interactions - triggers with `2` as pick block, cancellation prevents the block from being picked, no swing ### Issues found In `SPGM#useItemOn`, `useItem == DENY -> PASS` is misaligned in an `if`