Skip to content

Commit

Permalink
Finish NBT -> components changes
Browse files Browse the repository at this point in the history
Breaking change: `FabricItem#allowNbtUpdateAnimation` was renamed to
`allowComponentsUpdateAnimation`.
  • Loading branch information
apple502j committed Mar 10, 2024
1 parent 5ff22ae commit 00fc423
Show file tree
Hide file tree
Showing 13 changed files with 44 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import net.fabricmc.fabric.api.item.v1.FabricItem;

/**
* Allow canceling the held item update animation if {@link FabricItem#allowNbtUpdateAnimation} returns false.
* Allow canceling the held item update animation if {@link FabricItem#allowComponentsUpdateAnimation} returns false.
*/
@Mixin(HeldItemRenderer.class)
public class HeldItemRendererMixin {
Expand All @@ -51,7 +51,7 @@ private void modifyProgressAnimation(CallbackInfo ci) {
ItemStack newMainStack = client.player.getMainHandStack();

if (mainHand.getItem() == newMainStack.getItem()) {
if (!mainHand.getItem().allowNbtUpdateAnimation(client.player, Hand.MAIN_HAND, mainHand, newMainStack)) {
if (!mainHand.getItem().allowComponentsUpdateAnimation(client.player, Hand.MAIN_HAND, mainHand, newMainStack)) {
mainHand = newMainStack;
}
}
Expand All @@ -60,7 +60,7 @@ private void modifyProgressAnimation(CallbackInfo ci) {
ItemStack newOffStack = client.player.getOffHandStack();

if (offHand.getItem() == newOffStack.getItem()) {
if (!offHand.getItem().allowNbtUpdateAnimation(client.player, Hand.OFF_HAND, offHand, newOffStack)) {
if (!offHand.getItem().allowComponentsUpdateAnimation(client.player, Hand.OFF_HAND, offHand, newOffStack)) {
offHand = newOffStack;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
*/
public interface FabricItem {
/**
* When the NBT of an item stack in the main hand or off hand changes, vanilla runs an "update animation".
* This function is called on the client side when the NBT or count of the stack has changed, but not the item,
* When the components of an item stack in the main hand or off hand changes, vanilla runs an "update animation".
* This function is called on the client side when the components or count of the stack has changed, but not the item,
* and returning false cancels this animation.
*
* @param player the current player; this may be safely cast to {@link net.minecraft.client.network.ClientPlayerEntity} in client-only code
Expand All @@ -52,13 +52,13 @@ public interface FabricItem {
* @param newStack the new stack, also of this item
* @return true to run the vanilla animation, false to cancel it.
*/
default boolean allowNbtUpdateAnimation(PlayerEntity player, Hand hand, ItemStack oldStack, ItemStack newStack) {
default boolean allowComponentsUpdateAnimation(PlayerEntity player, Hand hand, ItemStack oldStack, ItemStack newStack) {
return true;
}

/**
* When the NBT of the selected stack changes, block breaking progress is reset.
* This function is called when the NBT of the selected stack has changed,
* When the components of the selected stack changes, block breaking progress is reset.
* This function is called when the components of the selected stack has changed,
* and returning true allows the block breaking progress to continue.
*
* @param player the player breaking the block
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void inventoryTick(ItemStack stack, World world, Entity entity, int slot,
}

@Override
public boolean allowNbtUpdateAnimation(PlayerEntity player, Hand hand, ItemStack originalStack, ItemStack updatedStack) {
public boolean allowComponentsUpdateAnimation(PlayerEntity player, Hand hand, ItemStack originalStack, ItemStack updatedStack) {
return allowUpdateAnimation;
}

Expand Down
6 changes: 3 additions & 3 deletions fabric-transfer-api-v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ and combine them with `CombinedStorage`.

## Fluid transfer
A `Storage<FluidVariant>` is any object that can store fluids. It is just a `Storage<T>`, where `T` is
[`FluidVariant`](src/main/java/net/fabricmc/fabric/api/transfer/v1/fluid/FluidVariant.java), the immutable combination of a `Fluid` and additional NBT data.
[`FluidVariant`](src/main/java/net/fabricmc/fabric/api/transfer/v1/fluid/FluidVariant.java), the immutable combination of a `Fluid` and additional components.
Instances can be accessed through the API lookups defined in [`FluidStorage`](src/main/java/net/fabricmc/fabric/api/transfer/v1/fluid/FluidStorage.java).

The unit for fluid transfer is 1/81000ths of a bucket, also known as _droplets_.
[`FluidConstants`](src/main/java/net/fabricmc/fabric/api/transfer/v1/fluid/FluidConstants.java) contains a few helpful constants
to work with droplets.

Client-side [Fluid variant rendering](src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRendering.java) will use regular fluid rendering by default,
ignoring the additional NBT data.
`Fluid`s that wish to render differently depending on the stored NBT data can register a
ignoring the additional components.
`Fluid`s that wish to render differently depending on the stored components can register a
[`FluidVariantRenderHandler`](src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRenderHandler.java).

## Item transfer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* <p>The {@code CauldronFluidContent} itself defines:
* <ul>
* <li>The block of the cauldron.</li>
* <li>The fluid that can be accepted by the cauldron. NBT is discarded when entering the cauldron.</li>
* <li>The fluid that can be accepted by the cauldron. Components are discarded when entering the cauldron.</li>
* <li>Which fluid amounts can be stored in the cauldron, and how they map to the level property of the cauldron.
* If {@code levelProperty} is {@code null}, then {@code maxLevel = 1}, and there is only one level.
* Otherwise, the levels are all the integer values between {@code 1} and {@code maxLevel} (included).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
/**
* Base implementation of a fluid storage for an empty item.
* The empty item can be filled with an exact amount of some fluid to yield a full item instead.
* The default behavior is to copy the NBT from the empty item to the full item,
* The default behavior is to copy the components from the empty item to the full item,
* however there is a second constructor that allows customizing the mapping.
*
* <p>For example, an empty bucket could be registered to accept exactly 81000 droplets of water and turn into a water bucket, like that:
Expand Down Expand Up @@ -67,7 +67,7 @@ public final class EmptyItemFluidStorage implements InsertionOnlyStorage<FluidVa
*
* @param context The current context.
* @param fullItem The new item after a successful fill operation.
* @param insertableFluid The fluid that can be inserted. Fluid variant NBT is ignored.
* @param insertableFluid The fluid that can be inserted. Fluid variant components are ignored.
* @param insertableAmount The amount of fluid that can be inserted.
*/
public EmptyItemFluidStorage(ContainerItemContext context, Item fullItem, Fluid insertableFluid, long insertableAmount) {
Expand All @@ -76,12 +76,12 @@ public EmptyItemFluidStorage(ContainerItemContext context, Item fullItem, Fluid

/**
* Create a new instance, with a custom mapping function.
* The mapping function allows customizing how the NBT of the full item depends on the NBT of the empty item.
* The default behavior with the other constructor is to just copy the full NBT.
* The mapping function allows customizing how the components of the full item depends on the components of the empty item.
* The default behavior with the other constructor is to just copy the full components.
*
* @param context The current context.
* @param emptyToFullMapping A function mapping the empty item variant, to the variant that should be used for the full item.
* @param insertableFluid The fluid that can be inserted. Fluid variant NBT is ignored on insertion.
* @param insertableFluid The fluid that can be inserted. Fluid variant components are ignored on insertion.
* @param insertableAmount The amount of fluid that can be inserted.
* @see #EmptyItemFluidStorage(ContainerItemContext, Item, Fluid, long)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
/**
* Base implementation of a fluid storage for a full item.
* The full item contains some fixed amount of a fluid variant, which can be extracted entirely to yield an empty item.
* The default behavior is to copy the NBT from the full item to the empty item,
* The default behavior is to copy the components from the full item to the empty item,
* however there is a second constructor that allows customizing the mapping.
*
* <p>This is used similarly to {@link EmptyItemFluidStorage}.
Expand All @@ -57,8 +57,8 @@ public FullItemFluidStorage(ContainerItemContext context, Item emptyItem, FluidV

/**
* Create a new instance, with a custom mapping function.
* The mapping function allows customizing how the NBT of the empty item depends on the NBT of the full item.
* The default behavior with the other constructor is to just copy the full NBT.
* The mapping function allows customizing how the components of the empty item depends on the components of the full item.
* The default behavior with the other constructor is to just copy the full components.
*
* @param context The current context.
* @param fullToEmptyMapping A function mapping the full item variant, to the variant that should be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@
*
* <p><h2>Fluid transfer</h2>
* A {@code Storage<FluidVariant>} is any object that can store fluids. It is just a {@code Storage<T>}, where {@code T} is
* {@link net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant FluidVariant}, the immutable combination of a {@code Fluid} and additional NBT data.
* {@link net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant FluidVariant}, the immutable combination of a {@code Fluid} and additional components.
* Instances can be accessed through the API lookups defined in {@link net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage FluidStorage}.
* </p>
*
* <p>The amount for fluid transfer is droplets, that is 1/81000ths of a bucket.
* {@link net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants FluidConstants} contains a few helpful constants to work with droplets.
*
* <p>Client-side {@linkplain net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering fluid variant rendering} will use regular fluid rendering by default,
* ignoring the additional NBT data.
* {@code Fluid}s that wish to render differently depending on the stored NBT data can register a
* ignoring the additional components.
* {@code Fluid}s that wish to render differently depending on the stored components can register a
* {@link net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRenderHandler FluidVariantRenderHandler}.
*
* <p><h2>Item transfer</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* but note that a {@link Storage} is not necessarily bound to {@code TransferVariant}. Its generic parameter can be any immutable object.
*
* <p><b>Transfer variants must always be compared with {@code equals}, never by reference!</b>
* {@code hashCode} is guaranteed to be correct and constant time independently of the size of the NBT.
* {@code hashCode} is guaranteed to be correct and constant time independently of the size of the components.
*
* @param <O> The type of the immutable object instance, for example {@code Item} or {@code Fluid}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@

/**
* Base implementation of a fixed-capacity "continuous" storage for item-provided storage APIs.
* The item may not change, so the data has to be stored in the NBT of the stacks.
* The item may not change, so the data has to be stored in the components of the stacks.
* This can be used for example to implement portable fluid tanks, fluid-containing jetpacks, and so on...
* Continuous here means that they can store any integer amount between 0 and the capacity, unlike buckets or bottles.
*
* <p>To expose the storage API for an item, you need to register a provider for your item, and pass it an instance of this class:
* <ul>
* <li>You must override {@link #getBlankResource()}, for example {@code return FluidVariant.blank();} for fluids.</li>
* <li>You must override {@link #getResource(ItemVariant)} and {@link #getAmount(ItemVariant)}.
* Generally you will read the resource and the amount from the NBT of the item variant.</li>
* Generally you will read the resource and the amount from the components of the item variant.</li>
* <li>You must override {@link #getCapacity(TransferVariant)} to set the capacity of your storage.</li>
* <li>You must override {@link #getUpdatedVariant}. It is used to change the resource and the amount of the item variant.
* Generally you will copy the NBT, modify it, and then create a new variant from that.
* Copying the NBT instead of recreating it from scratch is important to keep custom names or enchantments.</li>
* Generally you will copy the components, modify it, and then create a new variant from that.
* Copying the components instead of recreating it from scratch is important to keep custom names or enchantments.</li>
* <li>You may also override {@link #canInsert} and {@link #canExtract} if you want to restrict insertion and/or extraction.</li>
* </ul>
*
Expand All @@ -66,12 +66,12 @@ public SingleVariantItemStorage(ContainerItemContext context) {
protected abstract T getBlankResource();

/**
* Return the current resource by reading the NBT of the passed variant.
* Return the current resource by reading the components of the passed variant.
*/
protected abstract T getResource(ItemVariant currentVariant);

/**
* Return the current amount by reading the NBT of the passed variant.
* Return the current amount by reading the components of the passed variant.
*/
protected abstract long getAmount(ItemVariant currentVariant);

Expand All @@ -84,11 +84,12 @@ public SingleVariantItemStorage(ContainerItemContext context) {
/**
* Return an updated variant with new resource and amount.
* Implementors should generally convert the passed {@code currentVariant} to a stack,
* then edit the NBT of the stack so it contains the correct resource and amount.
* then edit the components of the stack so it contains the correct resource and amount.
*
* <p>When the new amount is 0, it is recommended that the sub-NBTs corresponding to the resource and amount
* be removed, for example using {@link ItemStack#removeSubNbt}, so that newly-crafted containers can stack with
* emptied containers.
* <p>When the new amount is 0, it is recommended that the components corresponding to the resource and amount
* be removed, so that newly-crafted containers can stack with emptied containers.
* If a custom item is used, this means {@linkplain ItemStack#set setting} it to the default as specified in {@link Item.Settings#component};
* if a vanilla item is used, this means {@linkplain ItemStack#remove removing} the said component.
*
* @param currentVariant Variant to which the modification should be applied.
* @param newResource Resource that should be contained in the returned variant.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public void testSimpleContentsQuery() {
null,
StorageUtil.findExtractableContent(
ContainerItemContext.withConstant(new ItemStack(Items.WATER_BUCKET)).find(FluidStorage.ITEM),
FluidVariant::hasComponents, // Only allow NBT -> won't match anything.
FluidVariant::hasComponents, // Only allow components -> won't match anything.
null
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void testStackReference() {

if (stack != inv.getStack(0)) throw new AssertionError("Stack should have stayed the same.");

// Also edit the stack when the item matches, even when the NBT and the count change.
// Also edit the stack when the item matches, even when the components and the count change.
ItemVariant oldVariant = ItemVariant.of(Items.DIAMOND);
ComponentChanges components = ComponentChanges.builder().add(ENERGY, 42).build();
ItemVariant newVariant = ItemVariant.of(Items.DIAMOND, components);
Expand All @@ -102,7 +102,7 @@ public void testStackReference() {
}

if (stack != inv.getStack(0)) throw new AssertionError("Stack should have stayed the same.");
if (!stackEquals(stack, newVariant, 5)) throw new AssertionError("Failed to update stack NBT or count.");
if (!stackEquals(stack, newVariant, 5)) throw new AssertionError("Failed to update stack components or count.");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void testWaterTank() {
tx.commit();
}

// Make sure custom NBT is kept.
// Make sure other components are kept.
Text customName = Text.literal("Lava-containing diamond!");
inv.getStack(0).set(DataComponentTypes.CUSTOM_NAME, customName);

Expand Down Expand Up @@ -215,7 +215,9 @@ private static void setContents(ItemStack stack, FluidVariant newResource, long
FluidData fluidData = new FluidData(newResource, newAmount);
stack.set(FLUID, fluidData);
} else {
// Make sure emptied tanks can stack with tanks without NBT.
// Make sure emptied tanks can stack with tanks without components.
// Note: because we use a vanilla item (diamond), we need to remove;
// a custom item should instead set the fluid to the default value as specified in the item settings.
stack.remove(FLUID);
}
}
Expand Down Expand Up @@ -258,7 +260,7 @@ protected long getCapacity(FluidVariant variant) {

@Override
protected ItemVariant getUpdatedVariant(ItemVariant currentVariant, FluidVariant newResource, long newAmount) {
// Operate on the stack directly to keep any other NBT data such as a custom name or enchant.
// Operate on the stack directly to keep any other components such as a custom name or enchant.
ItemStack stack = currentVariant.toStack();
setContents(stack, newResource, newAmount);
return ItemVariant.of(stack);
Expand Down

0 comments on commit 00fc423

Please sign in to comment.