From 74eef1c543fb9e18eb318149748476562025b001 Mon Sep 17 00:00:00 2001 From: IchHabeHunger54 Date: Sat, 16 Nov 2024 00:15:21 +0100 Subject: [PATCH] apply 1.21.3 changes to interactions.md, and fix outdated mention of DeferredSpawnEggItem --- docs/entities/livingentity.md | 26 +++++------ docs/items/interactionpipeline.md | 75 ------------------------------- docs/items/interactions.md | 53 +++++++++++----------- 3 files changed, 39 insertions(+), 115 deletions(-) delete mode 100644 docs/items/interactionpipeline.md diff --git a/docs/entities/livingentity.md b/docs/entities/livingentity.md index 10f81c0ef..3c11827aa 100644 --- a/docs/entities/livingentity.md +++ b/docs/entities/livingentity.md @@ -130,18 +130,14 @@ In addition to the [regular ways of spawning][spawning], `Mob`s can also be spaw ### Spawn Eggs -It is common (though not required) to [register] a spawn egg for mobs. Vanilla uses the `SpawnEggItem` class here, which does some additional setup in the constructor. - -Due to modded registration order, a crash will occur when mods use this class. As a workaround, NeoForge introduces the `DeferredSpawnEggItem` class, which postpones that additional setup to a point where it can be run safely. - -Using `DeferredSpawnEggItem`, our implementation is as simple as this: +It is common (though not required) to [register] a spawn egg for mobs. This is done through the `SpawnEggItem` class, which has been patched by NeoForge to do some extra setup, such as registering the color handler and adding the spawn egg to the internal `SpawnEggItem` -> `EntityType` map. ```java // Assume we have a DeferredRegister.Items called ITEMS -DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.register("my_entity_spawn_egg", - properties -> new DeferredSpawnEggItem( - // The entity type to spawn, as a Supplier>. - MY_ENTITY_TYPE, +DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.register("my_entity_spawn_egg", + properties -> new SpawnEggItem( + // The entity type to spawn. + MY_ENTITY_TYPE.get(), // The colors to use for the spawn egg. The first one is the base/background color, // the second one is the spots/highlight color. 0xff0000, @@ -153,7 +149,7 @@ DeferredItem MY_ENTITY_SPAWN_EGG = ITEMS.register("my_enti As an item like any other, the item should be added to a [creative tab][creative], and a [model] and [translation] should be added. -## Natural Spawning +### Natural Spawning _See [Worldgen/Biome Modifers/Add Spawns][addspawns] and [Worldgen/Biome Modifers/Add Spawn Costs][addspawncosts]._ @@ -181,8 +177,11 @@ This section is a work in progress. This section is a work in progress. ::: +[addspawncosts]: ../worldgen/biomemodifier.md#add-spawn-costs +[addspawns]: ../worldgen/biomemodifier.md#add-spawns [attributes]: attributes.md [containers]: ../blockentities/container.md +[creative]: ../items/index.md#creative-tabs [damage]: index.md#damaging-entities [damagesources]: ../resources/server/damagetypes.md#creating-and-using-damage-sources [damagetypes]: ../resources/server/damagetypes.md @@ -191,12 +190,9 @@ This section is a work in progress. [hurt]: index.md#damaging-entities [logicalsides]: ../concepts/sides.md#the-logical-side [mobeffects]: ../items/mobeffects.md +[model]: ../resources/client/models/index.md [priority]: ../concepts/events.md#priority +[register]: ../concepts/registries.md [spawning]: index.md#spawning-entities [tags]: ../resources/server/tags.md -[creative]: ../items/index.md#creative-tabs -[model]: ../resources/client/models/index.md -[register]: ../concepts/registries.md [translation]: ../resources/client/i18n.md -[addspawns]: ../worldgen/biomemodifier.md#add-spawns -[addspawncosts]: ../worldgen/biomemodifier.md#add-spawn-costs diff --git a/docs/items/interactionpipeline.md b/docs/items/interactionpipeline.md deleted file mode 100644 index 1c3a31122..000000000 --- a/docs/items/interactionpipeline.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -sidebar_position: 1 ---- -# The Interaction Pipeline - -This page aims to make the fairly complex and confusing process of things being right-clicked by the player more understandable, as well as clarifying what result to use where and why. - -## What Happens When I Right-Click? - -When you right-click anywhere in the world, a number of things happen, depending on what you are currently looking at and what `ItemStack`s are in your hands. A number of methods returning one of two result types (see below) are called. Most of these methods cancel the pipeline if an explicit success or an explicit failure is returned. For the sake of readability, this "explicit success or explicit failure" will be called a "definitive result" from now on. - -- `InputEvent.InteractionKeyMappingTriggered` is fired with the right mouse button and the main hand. If the event is canceled, the pipeline ends. -- Several circumstances are checked, for example that you are not in spectator mode or that all required feature flags for the `ItemStack` in your main hand are enabled. If at least one of these checks fails, the pipeline ends. -- Depending on what you are looking at, different things happen: - - If you are looking at an entity that is within your reach and not outside the world border: - - `PlayerInteractEvent.EntityInteractSpecific` is fired. If the event is canceled, the pipeline ends. - - `Entity#interactAt` will be called **on the entity you are looking at**. If it returns a definitive result, the pipeline ends. - - If you want to add behavior for your own entity, override this method. If you want to add behavior for a vanilla entity, use the event. - - If the entity opens an interface (for example a villager trading GUI or a chest minecart GUI), the pipeline ends. - - `PlayerInteractEvent.EntityInteract` is fired. If the event is canceled, the pipeline ends. - - `Entity#interact` is called **on the entity you are looking at**. If it returns a definitive result, the pipeline ends. - - If you want to add behavior for your own entity, override this method. If you want to add behavior for a vanilla entity, use the event. - - For `Mob`s, the override of `Entity#interact` handles things like leashing and spawning babies when the `ItemStack` in your main hand is a spawn egg, and then defers mob-specific handling to `Mob#mobInteract`. The rules for results for `Entity#interact` apply here as well. - - If the entity you are looking at is a `LivingEntity`, `Item#interactLivingEntity` is called on the `ItemStack` in your main hand. If it returns a definitive result, the pipeline ends. - - If you are looking at a block that is within your reach and not outside the world border: - - `PlayerInteractEvent.RightClickBlock` is fired. If the event is canceled, the pipeline ends. You may also specifically deny only block or item usage in this event. - - `IItemExtension#onItemUseFirst` is called. If it returns a definitive result, the pipeline ends. - - If the player is not sneaking and the event does not deny block usage, `UseItemOnBlockEvent` is fired. If the event is canceled, the cancellation result is used. Otherwise, `Block#useItemOn` is called. If it returns a definitive result, the pipeline ends. - - If the `InteractionResult` is `TRY_WITH_EMPTY_HAND` and the executing hand is the main hand, then `Block#useWithoutItem` is called. If it returns a definitive result, the pipeline ends. - - If the event does not deny item usage, `Item#useOn` is called. If it returns a definitive result, the pipeline ends. -- `Item#use` is called. If it returns a definitive result, the pipeline ends. -- The above process runs a second time, this time with the off hand instead of the main hand. - -## `InteractionResult` - -`InteractionResult` is a sealed interface that respresents the result of some interaction between an item or an empty hand and some object (e.g. entities, blocks, etc.). The interface is broken into four records, where there are six potential default states. - -First there is `InteractionResult.Success`, which indicates that the operation should be considered sucessful, ending the pipeline. A successful state has two parameters: the `SwingSource`, which indicates whether the entity should swing on the respective [logical side][side]; and the `InteractionResult.ItemContext`, which holds whether the interaction was caused by a held item, and what the held item transformed into after use. The swing source is determined by one of the default states: `InteractionResult#SUCCESS` for client swing, `InteractionResult#SUCCESS_SERVER` for server swing, and `InteractionResult#CONSUME` for no swing. The item context is set via `Success#heldItemTransformedTo` if the `ItemStack` changed, or `withoutItem` if there wasn't an interaction between the held item and the object. The default sets there was an item interaction but no transformation. - -```java -// In some method that returns an interaction result - -// Item in hand will turn into an apple -return InteractionResult.SUCCESS.heldItemTransformedTo(new ItemStack(Items.APPLE)); -``` - -:::note -`SUCCESS` and `SUCCESS_SERVER` should generally never be used in the same method. If the client has enough information to determine when to swing, then `SUCCESS` should always be used. Otherwise, if it relies on server information not present on the client, `SUCCESS_SERVER` should be used. -::: - -Then there is `InteractionResult.Fail`, implemented by `InteractionResult#FAIL`, which indicates that the operation should be considered failed, allowing no further interaction to occur. The pipeline will end. This can be used anywhere, but it should be used with care outside of `Item#useOn` and `Item#use`. In many cases, using `InteractionResult#PASS` makes more sense. - -Finally, there is `InteractionResult.Pass` and `InteractionResult.TryWithEmptyHandInteraction`, implemented by `InteractionResult#PASS` and `InteractionResult#TRY_WITH_EMPTY_HAND` respectively. These records indicate when an operation should be considered neither successful or failed, and the pipeline should continue. `PASS` is the default behavior for all `InteractionResult` methods except `BlockBehaviour#useItemOn`, which returns `TRY_WITH_EMPTY_HAND`. More specifically, if `BlockBehaviour#useItemOn` returns anything but `TRY_WITH_EMPTY_HAND`, `BlockBehaviour#useWithoutItem` will not be called regardless of if the item is in the main hand. - -Some methods have special behavior or requirements, which are explained in the below chapters. - -## `Item#useOn` - -If you want the operation to be considered successful, but you do not want the arm to swing or an `ITEM_USED` stat point to be awarded, use `InteractionResult#CONSUME` and calling `#withoutItem`. - -```java -// In Item#useOn -return InteractionResult.CONSUME.withoutItem(); -``` - -## `Item#use` - -This is the only instance where the transformed `ItemStack` is used from a `Success` variant (`SUCCESS`, `SUCCESS_SERVER`, `CONSUME`). The resulting `ItemStack` set by `Success#heldItemTransformedTo` replaces the `ItemStack` the usage was initiated with, if it has changed. - -The default implementation of `Item#use` returns `InteractionResult#CONSUME` when the item is edible (has `DataComponents#CONSUMABLE`) and the player can eat the item (because they are hungry, or because the item is always edible) and `InteractionResult#FAIL` when the item is edible (has `DataComponents#CONSUMABLE`) but the player cannot eat the item. If the item is equippable (has `DataComponents#EQUIPPABLE`), then it returns `InteractionResult#SUCCESS` on swap with the held item replaced by the swaped item (via `heldItemTransformedTo`), or `InteractionResult#FAIL` if the enchantment on the armor has the `EnchantmentEffectComponents#PREVENT_ARMOR_CHANGE` component. Otherwise `InteractionResult#PASS` is returned. - -Returning `InteractionResult#FAIL` here while considering the main hand will prevent offhand behavior from running. If you want offhand behavior to run (which you usually want), return `InteractionResult#PASS` instead. - -[itemuseon]: #itemuseon -[side]: ../concepts/sides.md#the-logical-side diff --git a/docs/items/interactions.md b/docs/items/interactions.md index ac8478130..f674d634a 100644 --- a/docs/items/interactions.md +++ b/docs/items/interactions.md @@ -15,7 +15,7 @@ Every frame on the [physical client][physicalside], the `Minecraft` class update ## Left-Clicking an Item -- It is checked that all required feature flags for the [`ItemStack`][itemstack] in your main hand are enabled. If this check fails, the pipeline ends. +- It is checked that all required [feature flags][featureflag] for the [`ItemStack`][itemstack] in your main hand are enabled. If this check fails, the pipeline ends. - `InputEvent.InteractionKeyMappingTriggered` is fired with the left mouse button and the main hand. If the [event][event] is [canceled][cancel], the pipeline ends. - Depending on what you are looking at (using the [`HitResult`][hitresult] in `Minecraft`), different things happen: - If you are looking at an [entity] that is within your reach: @@ -46,7 +46,7 @@ Every frame on the [physical client][physicalside], the `Minecraft` class update During the right-clicking pipeline, a number of methods returning one of two result types (see below) are called. Most of these methods cancel the pipeline if an explicit success or an explicit failure is returned. For the sake of readability, this "explicit success or explicit failure" will be called a "definitive result" from now on. - `InputEvent.InteractionKeyMappingTriggered` is fired with the right mouse button and the main hand. If the [event][event] is [canceled][cancel], the pipeline ends. -- Several circumstances are checked, for example that you are not in spectator mode or that all required feature flags for the [`ItemStack`][itemstack] in your main hand are enabled. If at least one of these checks fails, the pipeline ends. +- Several circumstances are checked, for example that you are not in spectator mode or that all required [feature flags][featureflag] for the [`ItemStack`][itemstack] in your main hand are enabled. If at least one of these checks fails, the pipeline ends. - Depending on what you are looking at (using the [`HitResult`][hitresult] in `Minecraft`), different things happen: - If you are looking at an [entity] that is within your reach and not outside the world border: - `PlayerInteractEvent.EntityInteractSpecific` is fired. If the event is canceled, the pipeline ends. @@ -62,49 +62,50 @@ During the right-clicking pipeline, a number of methods returning one of two res - `PlayerInteractEvent.RightClickBlock` is fired. If the event is canceled, the pipeline ends. You may also specifically deny only block or item usage in this event. - `IItemExtension#onItemUseFirst` is called. If it returns a definitive result, the pipeline ends. - If the player is not sneaking and the event does not deny block usage, `UseItemOnBlockEvent` is fired. If the event is canceled, the cancellation result is used. Otherwise, `Block#useItemOn` is called. If it returns a definitive result, the pipeline ends. - - If the `ItemInteractionResult` is `PASS_TO_DEFAULT_BLOCK_INTERACTION` and the executing hand is the main hand, then `Block#useWithoutItem` is called. If it returns a definitive result, the pipeline ends. + - If the `InteractionResult` is `TRY_WITH_EMPTY_HAND` and the executing hand is the main hand, then `Block#useWithoutItem` is called. If it returns a definitive result, the pipeline ends. - If the event does not deny item usage, `Item#useOn` is called. If it returns a definitive result, the pipeline ends. - `Item#use` is called. If it returns a definitive result, the pipeline ends. - The above process runs a second time, this time with the off hand instead of the main hand. -### Result Types +### `InteractionResult` -There are three different types of results: `InteractionResult`s, `ItemInteractionResult`s, and `InteractionResultHolder`s. `InteractionResult` is used most of the time, only `Item#use` uses `InteractionResultHolder`, and only `BlockBehaviour#useItemOn` and `CauldronInteraction#interact` use `ItemInteractionResult`. +`InteractionResult` is a sealed interface that respresents the result of some interaction between an item or an empty hand and some object (e.g. entities, blocks, etc.). The interface is broken into four records, where there are six potential default states. -`InteractionResult` is an enum consisting of five values: `SUCCESS`, `CONSUME`, `CONSUME_PARTIAL`, `PASS` and `FAIL`. Additionally, the method `InteractionResult#sidedSuccess` is available, which returns `SUCCESS` on the server and `CONSUME` on the client. +First there is `InteractionResult.Success`, which indicates that the operation should be considered sucessful, ending the pipeline. A successful state has two parameters: the `SwingSource`, which indicates whether the entity should swing on the respective [logical side][side]; and the `InteractionResult.ItemContext`, which holds whether the interaction was caused by a held item, and what the held item transformed into after use. The swing source is determined by one of the default states: `InteractionResult#SUCCESS` for client swing, `InteractionResult#SUCCESS_SERVER` for server swing, and `InteractionResult#CONSUME` for no swing. The item context is set via `Success#heldItemTransformedTo` if the `ItemStack` changed, or `withoutItem` if there wasn't an interaction between the held item and the object. The default sets there was an item interaction but no transformation. -`InteractionResultHolder` is a wrapper around `InteractionResult` that adds additional context for `T`. `T` can be anything, but in 99.99 percent of cases, it is an `ItemStack`. `InteractionResultHolder` provides wrapper methods for the enum values (`#success`, `#consume`, `#pass` and `#fail`), as well as `#sidedSuccess`, which calls `#success` on the server and `#consume` on the client. +```java +// In some method that returns an interaction result -`ItemInteractionResult` is a parallel to `InteractionResult` specifically for when an item is used on a block. It is an enum of six values: `SUCCESS`, `CONSUME`, `CONSUME_PARTIAL`, `PASS_TO_DEFAULT_BLOCK_INTERACTION`, `SKIP_DEFAULT_BLOCK_INTERACTION`, and `FAIL`. Each `ItemInteractionResult` can be mapped to a `InteractionResult` via `#result`; `PASS_TO_DEFAULT_BLOCK_INTERACTION`, `SKIP_DEFAULT_BLOCK_INTERACTION` both represent `InteractionResult#PASS`. Similarly, `#sidedSucess` also exists for `ItemInteractionResult`. +// Item in hand will turn into an apple +return InteractionResult.SUCCESS.heldItemTransformedTo(new ItemStack(Items.APPLE)); +``` -Generally, the different values mean the following: +:::note +`SUCCESS` and `SUCCESS_SERVER` should generally never be used in the same method. If the client has enough information to determine when to swing, then `SUCCESS` should always be used. Otherwise, if it relies on server information not present on the client, `SUCCESS_SERVER` should be used. +::: -- `InteractionResult#sidedSuccess` (or `InteractionResultHolder#sidedSuccess` / `ItemInteractionResult#sidedSucess` where needed) should be used if the operation should be considered successful, and you want the arm to swing. The pipeline will end. -- `InteractionResult#SUCCESS` (or `InteractionResultHolder#success` / `ItemInteractionResult#SUCCESS` where needed) should be used if the operation should be considered successful, and you want the arm to swing, but only on one side. Only use this if you want to return a different value on the other logical side for whatever reason. The pipeline will end. -- `InteractionResult#CONSUME` (or `InteractionResultHolder#consume` / `ItemInteractionResult#CONSUME` where needed) should be used if the operation should be considered successful, but you do not want the arm to swing. The pipeline will end. -- `InteractionResult#CONSUME_PARTIAL` is mostly identical to `InteractionResult#CONSUME`, the only difference is in its usage in [`Item#useOn`][itemuseon]. - - `ItemInteractionResult#CONSUME_PARTIAL` is similar within its usage in `BlockBehaviour#useItemOn`. -- `InteractionResult.FAIL` (or `InteractionResultHolder#fail` / `ItemInteractionResult#FAIL` where needed) should be used if the item functionality should be considered failed and no further interaction should be performed. The pipeline will end. This can be used everywhere, but it should be used with care outside of `Item#useOn` and `Item#use`. In many cases, using `InteractionResult.PASS` makes more sense. -- `InteractionResult.PASS` (or `InteractionResultHolder#pass` where needed) should be used if the operation should be considered neither successful nor failed. The pipeline will continue. This is the default behavior (unless otherwise specified). - - `ItemInteractionResult#PASS_TO_DEFAULT_BLOCK_INTERACTION` allows `BlockBehaviour#useWithoutItem` to be called for the mainhand while `#SKIP_DEFAULT_BLOCK_INTERACTION` prevents the method from executing altogether. `#PASS_TO_DEFAULT_BLOCK_INTERACTION` is the default behavior (unless otherwise specified). +Then there is `InteractionResult.Fail`, implemented by `InteractionResult#FAIL`, which indicates that the operation should be considered failed, allowing no further interaction to occur. The pipeline will end. This can be used anywhere, but it should be used with care outside of `Item#useOn` and `Item#use`. In many cases, using `InteractionResult#PASS` makes more sense. -Some methods have special behavior or requirements, which are explained in the below sections. +Finally, there is `InteractionResult.Pass` and `InteractionResult.TryWithEmptyHandInteraction`, implemented by `InteractionResult#PASS` and `InteractionResult#TRY_WITH_EMPTY_HAND` respectively. These records indicate when an operation should be considered neither successful or failed, and the pipeline should continue. `PASS` is the default behavior for all `InteractionResult` methods except `BlockBehaviour#useItemOn`, which returns `TRY_WITH_EMPTY_HAND`. More specifically, if `BlockBehaviour#useItemOn` returns anything but `TRY_WITH_EMPTY_HAND`, `BlockBehaviour#useWithoutItem` will not be called regardless of if the item is in the main hand. -#### `IItemExtension#onItemUseFirst` - -`InteractionResult#sidedSuccess` and `InteractionResult.CONSUME` don't have an effect here. Only `InteractionResult.SUCCESS`, `InteractionResult.FAIL` or `InteractionResult.PASS` should be used here. +Some methods have special behavior or requirements, which are explained in the below chapters. #### `Item#useOn` -If you want the operation to be considered successful, but you do not want the arm to swing or an `ITEM_USED` stat point to be awarded, use `InteractionResult.CONSUME_PARTIAL`. +If you want the operation to be considered successful, but you do not want the arm to swing or an `ITEM_USED` stat point to be awarded, use `InteractionResult#CONSUME` and calling `#withoutItem`. + +```java +// In Item#useOn +return InteractionResult.CONSUME.withoutItem(); +``` #### `Item#use` -This is the only instance where the return type is `InteractionResultHolder`. The resulting `ItemStack` in the `InteractionResultHolder` replaces the `ItemStack` the usage was initiated with, if it has changed. +This is the only instance where the transformed `ItemStack` is used from a `Success` variant (`SUCCESS`, `SUCCESS_SERVER`, `CONSUME`). The resulting `ItemStack` set by `Success#heldItemTransformedTo` replaces the `ItemStack` the usage was initiated with, if it has changed. -The default implementation of `Item#use` returns `InteractionResultHolder#consume` when the item is edible and the player can eat the item (because they are hungry, or because the item is always edible), `InteractionResultHolder#fail` when the item is edible but the player cannot eat the item, and `InteractionResultHolder#pass` if the item is not edible. +The default implementation of `Item#use` returns `InteractionResult#CONSUME` when the item is edible (has `DataComponents#CONSUMABLE`) and the player can eat the item (because they are hungry, or because the item is always edible) and `InteractionResult#FAIL` when the item is edible (has `DataComponents#CONSUMABLE`) but the player cannot eat the item. If the item is equippable (has `DataComponents#EQUIPPABLE`), then it returns `InteractionResult#SUCCESS` on swap with the held item replaced by the swaped item (via `heldItemTransformedTo`), or `InteractionResult#FAIL` if the enchantment on the armor has the `EnchantmentEffectComponents#PREVENT_ARMOR_CHANGE` component. Otherwise `InteractionResult#PASS` is returned. -Returning `InteractionResultHolder#fail` here while considering the main hand will prevent offhand behavior from running. If you want offhand behavior to run (which you usually want), return `InteractionResultHolder#pass` instead. +Returning `InteractionResult#FAIL` here while considering the main hand will prevent offhand behavior from running. If you want offhand behavior to run (which you usually want), return `InteractionResult#PASS` instead. ## Middle-Clicking @@ -131,9 +132,11 @@ Returning `InteractionResultHolder#fail` here while considering the main hand wi [effect]: mobeffects.md [entity]: ../entities/index.md [event]: ../concepts/events.md +[featureflag]: ../advanced/featureflags.md [hitresult]: #hitresults [hurt]: ../entities/index.md#damaging-entities [itemstack]: index.md#itemstacks [itemuseon]: #itemuseon [livingentity]: ../entities/livingentity.md [physicalside]: ../concepts/sides.md#the-physical-side +[side]: ../concepts/sides.md#the-logical-side