mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-21 03:10:54 -04:00
24w10a porting fixes (#3638)
* Rename mixin using unmapped name * Fix potential crash in item API testmod * Improve custom ingredient javadoc * More javadoc improvements * Add more tests * whoops * Fix typos * Remove test for strict NBT matching * another whoopsie * Finish NBT -> components changes Breaking change: `FabricItem#allowNbtUpdateAnimation` was renamed to `allowComponentsUpdateAnimation`. * Fix broken javadoc links * Fix broken screen handler testmod
This commit is contained in:
parent
031f0cf067
commit
42c290b4ca
29 changed files with 128 additions and 87 deletions
fabric-content-registries-v0/src/main
java/net/fabricmc/fabric/mixin/content/registry
resources
fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/api/attachment/v1
fabric-data-generation-api-v1/src
main/java/net/fabricmc/fabric/api/datagen/v1/provider
testmod/java/net/fabricmc/fabric/test/datagen
fabric-item-api-v1/src
client/java/net/fabricmc/fabric/mixin/item/client
main/java/net/fabricmc/fabric/api/item/v1
testmod/java/net/fabricmc/fabric/test/item
fabric-item-group-api-v1/src/main/java/net/fabricmc/fabric/api/itemgroup/v1
fabric-networking-api-v1/src
client/java/net/fabricmc/fabric/api/client/networking/v1
main/java/net/fabricmc/fabric/api/networking/v1
fabric-recipe-api-v1/src
main/java/net/fabricmc/fabric/api/recipe/v1/ingredient
testmod/java/net/fabricmc/fabric/test/recipe/ingredient
fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1
fabric-screen-handler-api-v1/src/testmod/java/net/fabricmc/fabric/test/screenhandler/item
fabric-transfer-api-v1
README.md
src
main/java/net/fabricmc/fabric/api/transfer/v1
test/java/net/fabricmc/fabric/test/transfer/unittests
|
@ -32,19 +32,19 @@ import net.minecraft.world.CollisionView;
|
|||
import net.fabricmc.fabric.api.registry.LandPathNodeTypesRegistry;
|
||||
|
||||
@Mixin(PathContext.class)
|
||||
public abstract class class_9316Mixin {
|
||||
public abstract class PathContextMixin {
|
||||
@Shadow
|
||||
public abstract BlockState method_57623(BlockPos blockPos);
|
||||
public abstract BlockState getBlockState(BlockPos blockPos);
|
||||
|
||||
@Shadow
|
||||
public abstract CollisionView method_57621();
|
||||
public abstract CollisionView getWorld();
|
||||
|
||||
/**
|
||||
* Overrides the node type for the specified position, if the position is found as neighbor block in a path.
|
||||
*/
|
||||
@Inject(method = "getNodeType", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/math/BlockPos$Mutable;set(III)Lnet/minecraft/util/math/BlockPos$Mutable;"), cancellable = true)
|
||||
private void method_57622(int x, int y, int z, CallbackInfoReturnable<PathNodeType> cir, @Local BlockPos pos) {
|
||||
final PathNodeType neighborNodeType = LandPathNodeTypesRegistry.getPathNodeType(method_57623(pos), method_57621(), pos, true);
|
||||
private void onGetNodeType(int x, int y, int z, CallbackInfoReturnable<PathNodeType> cir, @Local BlockPos pos) {
|
||||
final PathNodeType neighborNodeType = LandPathNodeTypesRegistry.getPathNodeType(getBlockState(pos), getWorld(), pos, true);
|
||||
|
||||
if (neighborNodeType != null) {
|
||||
cir.setReturnValue(neighborNodeType);
|
|
@ -4,7 +4,7 @@
|
|||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"AxeItemAccessor",
|
||||
"class_9316Mixin",
|
||||
"PathContextMixin",
|
||||
"FarmerWorkTaskAccessor",
|
||||
"GiveGiftsToHeroTaskAccessor",
|
||||
"HoeItemAccessor",
|
||||
|
|
|
@ -51,7 +51,7 @@ import net.minecraft.world.chunk.ChunkStatus;
|
|||
* <p>
|
||||
* Note about {@link BlockEntity} targets: by default, many block entities use their NBT to synchronize with the client.
|
||||
* That would mean persistent attachments are automatically synced with the client for those block entities. As this is
|
||||
* undesirable behavior, the API completely removes attachments from the result of {@link BlockEntity#toInitialChunkDataNbt()},
|
||||
* undesirable behavior, the API completely removes attachments from the result of {@link BlockEntity#toInitialChunkDataNbt},
|
||||
* which takes care of all vanilla types. However, modded block entities may be coded differently, so be wary of this
|
||||
* when attaching data to modded block entities.
|
||||
* </p>
|
||||
|
|
|
@ -52,8 +52,8 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
|||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
|
||||
/**
|
||||
* Extend this class and implement {@link FabricLanguageProvider#generateTranslations(TranslationBuilder)}.
|
||||
* Make sure to use {@link FabricLanguageProvider#FabricLanguageProvider(FabricDataOutput, String, CompletableFuture)} FabricLanguageProvider} to declare what language code is being generated if it isn't {@code en_us}.
|
||||
* Extend this class and implement {@link FabricLanguageProvider#generateTranslations}.
|
||||
* Make sure to use {@link FabricLanguageProvider#FabricLanguageProvider(FabricDataOutput, String, CompletableFuture) FabricLanguageProvider} to declare what language code is being generated if it isn't {@code en_us}.
|
||||
*
|
||||
* <p>Register an instance of the class with {@link FabricDataGenerator.Pack#addProvider} in a {@link net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint}.
|
||||
*/
|
||||
|
@ -117,7 +117,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* A consumer used by {@link FabricLanguageProvider#generateTranslations(TranslationBuilder)}.
|
||||
* A consumer used by {@link FabricLanguageProvider#generateTranslations}.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
@FunctionalInterface
|
||||
|
|
|
@ -53,7 +53,6 @@ import net.minecraft.data.server.recipe.RecipeExporter;
|
|||
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
|
@ -189,7 +188,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
|
|||
// - 9 damaged pickaxes should not match.
|
||||
// - 9 undamaged pickaxes should match.
|
||||
// - 1 undamaged pickaxe + 8 damaged pickaxes should match (regardless of the position).
|
||||
// - 1 undamaged renamed pickaxe + 8 damaged pickaxes should match (NBT is not strictly matched here).
|
||||
// - 1 undamaged renamed pickaxe + 8 damaged pickaxes should match (components are not strictly matched here).
|
||||
ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.DIAMOND_BLOCK)
|
||||
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
|
||||
.input(Ingredient.ofItems(Items.DIAMOND_PICKAXE))
|
||||
|
@ -209,17 +208,6 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
|
|||
.criterion("has_pickaxe", conditionsFromItem(Items.DIAMOND_PICKAXE))
|
||||
.offerTo(exporter);
|
||||
|
||||
// Test strict NBT
|
||||
// To test: try renaming an apple to "Golden Apple" in creative with an anvil.
|
||||
// That should match the recipe and give a golden apple. Any other NBT should not match.
|
||||
ItemStack appleWithGoldenName = new ItemStack(Items.APPLE);
|
||||
appleWithGoldenName.set(DataComponentTypes.CUSTOM_NAME, Text.literal("Golden Apple"));
|
||||
appleWithGoldenName.set(DataComponentTypes.REPAIR_COST, 0);
|
||||
ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.GOLDEN_APPLE)
|
||||
.input(DefaultCustomIngredients.components(appleWithGoldenName))
|
||||
.criterion("has_apple", conditionsFromItem(Items.APPLE))
|
||||
.offerTo(exporter);
|
||||
|
||||
// Test AND
|
||||
// To test: charcoal should give a torch, but coal should not.
|
||||
ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.TORCH)
|
||||
|
|
|
@ -31,7 +31,7 @@ import net.minecraft.util.Hand;
|
|||
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 {
|
||||
|
@ -51,7 +51,7 @@ public class HeldItemRendererMixin {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public class HeldItemRendererMixin {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ import net.fabricmc.fabric.impl.item.FabricItemInternals;
|
|||
*/
|
||||
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
|
||||
|
@ -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
|
||||
|
|
|
@ -52,7 +52,7 @@ public class CustomDamageTest implements ModInitializer {
|
|||
if (entity.isSneaking()) {
|
||||
return amount;
|
||||
} else {
|
||||
stack.set(WEIRD, stack.getOrDefault(WEIRD, 0) + 1);
|
||||
stack.set(WEIRD, Math.max(0, stack.getOrDefault(WEIRD, 0) + 1));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -46,12 +46,12 @@ public class UpdatingItem extends Item {
|
|||
@Override
|
||||
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
|
||||
if (!world.isClient) {
|
||||
stack.set(ItemUpdateAnimationTest.TICKS, stack.getOrDefault(ItemUpdateAnimationTest.TICKS, 0) + 1);
|
||||
stack.set(ItemUpdateAnimationTest.TICKS, Math.max(0, stack.getOrDefault(ItemUpdateAnimationTest.TICKS, 0) + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ public class FabricItemGroupEntries implements ItemGroup.Entries {
|
|||
/**
|
||||
* Adds stacks after an existing stack in the group, or at the end, if the stack isn't in the group.
|
||||
*
|
||||
* @param afterLast Add {@code newStacks} after the last group entry matching this stack (compared using {@link ItemStack#areItemsAndNbtEqual}).
|
||||
* @param afterLast Add {@code newStacks} after the last group entry matching this stack (compared using {@link ItemStack#areItemsAndComponentsEqual}).
|
||||
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
|
||||
* @param visibility Determines whether the stack will be shown in the tab itself, returned
|
||||
* for searches, or both.
|
||||
|
@ -331,7 +331,7 @@ public class FabricItemGroupEntries implements ItemGroup.Entries {
|
|||
/**
|
||||
* Adds stacks before an existing stack to the group, or at the end, if the stack isn't in the group.
|
||||
*
|
||||
* @param beforeFirst Add {@code newStacks} before the first group entry matching this stack (compared using {@link ItemStack#areItemsAndNbtEqual}).
|
||||
* @param beforeFirst Add {@code newStacks} before the first group entry matching this stack (compared using {@link ItemStack#areItemsAndComponentsEqual}).
|
||||
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
|
||||
* @param visibility Determines whether the stack will be shown in the tab itself, returned
|
||||
* for searches, or both.
|
||||
|
|
|
@ -18,7 +18,7 @@ package net.fabricmc.fabric.api.client.networking.v1;
|
|||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientConfigurationNetworkHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
@ -30,7 +30,7 @@ public final class ClientConfigurationConnectionEvents {
|
|||
/**
|
||||
* Event indicating a connection entering the CONFIGURATION state, ready for registering channel handlers.
|
||||
*
|
||||
* @see ClientConfigurationNetworking#registerReceiver(Identifier, ClientConfigurationNetworking.ConfigurationChannelHandler)
|
||||
* @see ClientConfigurationNetworking#registerReceiver(CustomPayload.Id, ClientConfigurationNetworking.ConfigurationPayloadHandler)
|
||||
*/
|
||||
public static final Event<ClientConfigurationConnectionEvents.Init> INIT = EventFactory.createArrayBacked(ClientConfigurationConnectionEvents.Init.class, callbacks -> (handler, client) -> {
|
||||
for (ClientConfigurationConnectionEvents.Init callback : callbacks) {
|
||||
|
|
|
@ -18,7 +18,7 @@ package net.fabricmc.fabric.api.client.networking.v1;
|
|||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
@ -31,7 +31,7 @@ public final class ClientPlayConnectionEvents {
|
|||
/**
|
||||
* Event indicating a connection entered the PLAY state, ready for registering channel handlers.
|
||||
*
|
||||
* @see ClientPlayNetworking#registerReceiver(Identifier, ClientPlayNetworking.PlayChannelHandler)
|
||||
* @see ClientPlayNetworking#registerReceiver(CustomPayload.Id, ClientPlayNetworking.PlayPayloadHandler)
|
||||
*/
|
||||
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> {
|
||||
for (Init callback : callbacks) {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.api.networking.v1;
|
||||
|
||||
import net.minecraft.network.packet.CustomPayload;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
@ -30,7 +30,7 @@ public final class ServerPlayConnectionEvents {
|
|||
/**
|
||||
* Event indicating a connection entered the PLAY state, ready for registering channel handlers.
|
||||
*
|
||||
* @see ServerPlayNetworking#registerReceiver(ServerPlayNetworkHandler, Identifier, ServerPlayNetworking.PlayChannelHandler)
|
||||
* @see ServerPlayNetworking#registerReceiver(ServerPlayNetworkHandler, CustomPayload.Id, ServerPlayNetworking.PlayPayloadHandler)
|
||||
*/
|
||||
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, server) -> {
|
||||
for (Init callback : callbacks) {
|
||||
|
|
|
@ -102,10 +102,21 @@ public final class DefaultCustomIngredients {
|
|||
* Creates an ingredient that wraps another ingredient to also check for matching components.
|
||||
*
|
||||
* <p>Use {@link ComponentChanges#builder()} to add or remove components.
|
||||
* Added components are checked to match on the target stack.
|
||||
* Removed components are checked to not exist in the target stack
|
||||
* Added components are checked to match on the target stack, either as the default or
|
||||
* the item stack-specific override.
|
||||
* Removed components are checked to not exist in the target stack.
|
||||
* The check is "non-strict"; components that are neither added nor removed are ignored.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@link ComponentChanges#isEmpty} is true
|
||||
* <p>The JSON format is as follows:
|
||||
* <pre>{@code
|
||||
* {
|
||||
* "fabric:type": "fabric:components",
|
||||
* "base": // base ingredient,
|
||||
* "components": // components to be checked
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @throws IllegalArgumentException if there are no components to check
|
||||
*/
|
||||
public static Ingredient components(Ingredient base, ComponentChanges components) {
|
||||
Objects.requireNonNull(base, "Base ingredient cannot be null");
|
||||
|
@ -122,10 +133,17 @@ public final class DefaultCustomIngredients {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates an ingredient that matches the passed template stack, including {@link ItemStack#getComponentChanges()}.
|
||||
* Creates an ingredient that matches the components specified in the passed item stack.
|
||||
* Note that the count of the stack is ignored.
|
||||
*
|
||||
* <p>This does not check for the default component of the item stack that remains unchanged.
|
||||
* For example, an undamaged pickaxe matches any pickaxes (regardless of damage), because having
|
||||
* zero damage is the default, but a pickaxe with 1 damage would only match another pickaxe
|
||||
* with 1 damage. To only match the default value, use the other methods and explicitly specify
|
||||
* the default value.
|
||||
*
|
||||
* @see #components(Ingredient, ComponentChanges)
|
||||
* @throws IllegalArgumentException if {@code stack} has no changed components
|
||||
*/
|
||||
public static Ingredient components(ItemStack stack) {
|
||||
Objects.requireNonNull(stack, "Stack cannot be null");
|
||||
|
|
|
@ -20,8 +20,10 @@ import java.util.Objects;
|
|||
|
||||
import net.minecraft.component.ComponentChanges;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.NbtComponent;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.test.GameTest;
|
||||
import net.minecraft.test.GameTestException;
|
||||
|
@ -90,7 +92,7 @@ public class IngredientMatchTests {
|
|||
|
||||
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
|
||||
public void testComponentIngredient(TestContext context) {
|
||||
final Ingredient baseIngredient = Ingredient.ofItems(Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE);
|
||||
final Ingredient baseIngredient = Ingredient.ofItems(Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE, Items.STICK);
|
||||
final Ingredient undamagedIngredient = DefaultCustomIngredients.components(
|
||||
baseIngredient,
|
||||
builder -> builder.add(DataComponentTypes.DAMAGE, 0)
|
||||
|
@ -107,7 +109,7 @@ public class IngredientMatchTests {
|
|||
assertEquals(true, undamagedIngredient.test(renamedUndamagedDiamondPickaxe));
|
||||
assertEquals(false, noNameUndamagedIngredient.test(renamedUndamagedDiamondPickaxe));
|
||||
|
||||
assertEquals(2, undamagedIngredient.getMatchingStacks().length);
|
||||
assertEquals(3, undamagedIngredient.getMatchingStacks().length);
|
||||
ItemStack result0 = undamagedIngredient.getMatchingStacks()[0];
|
||||
ItemStack result1 = undamagedIngredient.getMatchingStacks()[1];
|
||||
|
||||
|
@ -126,6 +128,33 @@ public class IngredientMatchTests {
|
|||
damagedDiamondPickaxe.setDamage(10);
|
||||
assertEquals(false, undamagedIngredient.test(damagedDiamondPickaxe));
|
||||
|
||||
// Checking for DAMAGE component requires the item is damageable in the first place
|
||||
assertEquals(false, undamagedIngredient.test(new ItemStack(Items.STICK)));
|
||||
|
||||
// Custom data is strictly matched, like any other component with multiple fields
|
||||
final NbtCompound requiredData = new NbtCompound();
|
||||
requiredData.putInt("keyA", 1);
|
||||
final NbtCompound extraData = requiredData.copy();
|
||||
extraData.putInt("keyB", 2);
|
||||
|
||||
final Ingredient customDataIngredient = DefaultCustomIngredients.components(
|
||||
baseIngredient,
|
||||
builder -> builder.add(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredData))
|
||||
);
|
||||
ItemStack requiredDataStack = new ItemStack(Items.DIAMOND_PICKAXE);
|
||||
requiredDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(requiredData));
|
||||
ItemStack extraDataStack = new ItemStack(Items.DIAMOND_PICKAXE);
|
||||
extraDataStack.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraData));
|
||||
assertEquals(true, customDataIngredient.test(requiredDataStack));
|
||||
assertEquals(false, customDataIngredient.test(extraDataStack));
|
||||
|
||||
// Default value is ignored in components(ItemStack)
|
||||
final Ingredient damagedPickaxeIngredient = DefaultCustomIngredients.components(renamedUndamagedDiamondPickaxe);
|
||||
ItemStack renamedDamagedDiamondPickaxe = renamedUndamagedDiamondPickaxe.copy();
|
||||
renamedDamagedDiamondPickaxe.setDamage(10);
|
||||
assertEquals(true, damagedPickaxeIngredient.test(renamedUndamagedDiamondPickaxe));
|
||||
assertEquals(true, damagedPickaxeIngredient.test(renamedDamagedDiamondPickaxe));
|
||||
|
||||
context.complete();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import net.minecraft.util.profiler.Profiler;
|
|||
|
||||
/**
|
||||
* Except as noted below, the properties exposed here match the parameters passed to
|
||||
* {@link WorldRenderer#render(MatrixStack, float, long, boolean, Camera, GameRenderer, LightmapTextureManager, Matrix4f)}.
|
||||
* {@link WorldRenderer#render}.
|
||||
*/
|
||||
public interface WorldRenderContext {
|
||||
/**
|
||||
|
|
|
@ -19,6 +19,7 @@ package net.fabricmc.fabric.api.client.rendering.v1;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
|
||||
|
@ -27,7 +28,7 @@ import net.fabricmc.fabric.api.event.Event;
|
|||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
||||
/**
|
||||
* Mods should use these events to introduce custom rendering during {@link WorldRenderer#render(net.minecraft.client.util.math.MatrixStack, float, long, boolean, net.minecraft.client.render.Camera, net.minecraft.client.render.GameRenderer, net.minecraft.client.render.LightmapTextureManager, net.minecraft.util.math.Matrix4f)}
|
||||
* Mods should use these events to introduce custom rendering during {@link WorldRenderer#render}
|
||||
* without adding complicated and conflict-prone injections there. Using these events also enables 3rd-party renderers
|
||||
* that make large-scale changes to rendering maintain compatibility by calling any broken event invokers directly.
|
||||
*
|
||||
|
@ -107,7 +108,7 @@ public final class WorldRenderEvents {
|
|||
*
|
||||
* <p>Use for global block entity render setup, or
|
||||
* to append block-related quads to the entity consumers using the
|
||||
* {@VertexConsumerProvider} from the provided context. This
|
||||
* {@link VertexConsumerProvider} from the provided context. This
|
||||
* will generally give better (if not perfect) results
|
||||
* for non-terrain translucency vs. drawing directly later on.
|
||||
*/
|
||||
|
|
|
@ -27,7 +27,9 @@ final class BagInventory implements ImplementedInventory {
|
|||
|
||||
BagInventory(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
stack.getOrDefault(DataComponentTypes.CONTAINER, ContainerComponent.fromStacks(items));
|
||||
ContainerComponent container = stack.get(DataComponentTypes.CONTAINER);
|
||||
|
||||
if (container != null) container.copyTo(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,7 +23,7 @@ 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_.
|
||||
|
@ -31,8 +31,8 @@ The unit for fluid transfer is 1/81000ths of a bucket, also known as _droplets_.
|
|||
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
|
||||
|
|
|
@ -39,7 +39,7 @@ import net.fabricmc.fabric.impl.transfer.fluid.CauldronStorage;
|
|||
* <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).
|
||||
|
|
|
@ -35,7 +35,7 @@ import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
|
|||
/**
|
||||
* 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:
|
||||
|
@ -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) {
|
||||
|
@ -76,12 +76,12 @@ public final class EmptyItemFluidStorage implements InsertionOnlyStorage<FluidVa
|
|||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,7 @@ import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
|
|||
/**
|
||||
* 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}.
|
||||
|
@ -57,8 +57,8 @@ public final class FullItemFluidStorage implements ExtractionOnlyStorage<FluidVa
|
|||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
*
|
||||
* <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>
|
||||
*
|
||||
|
@ -53,8 +53,8 @@
|
|||
* {@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>
|
||||
|
|
|
@ -27,7 +27,7 @@ import net.minecraft.component.ComponentChanges;
|
|||
* 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}.
|
||||
*/
|
||||
|
|
|
@ -27,7 +27,7 @@ import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
|
|||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -35,11 +35,11 @@ import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
|
|||
* <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>
|
||||
*
|
||||
|
@ -66,12 +66,12 @@ public abstract class SingleVariantItemStorage<T extends TransferVariant<?>> imp
|
|||
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);
|
||||
|
||||
|
@ -84,11 +84,12 @@ public abstract class SingleVariantItemStorage<T extends TransferVariant<?>> imp
|
|||
/**
|
||||
* 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.
|
||||
|
|
|
@ -189,7 +189,7 @@ class FluidItemTests extends AbstractTransferApiTest {
|
|||
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
|
||||
)
|
||||
);
|
||||
|
|
|
@ -90,7 +90,7 @@ class ItemTests extends AbstractTransferApiTest {
|
|||
|
||||
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);
|
||||
|
@ -102,7 +102,7 @@ class ItemTests extends AbstractTransferApiTest {
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -45,7 +45,7 @@ public class PlayerInventoryStorageTests extends AbstractTransferApiTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testStackingInser() {
|
||||
public void testStackingInsert() {
|
||||
// Also test that the behavior of insert matches that of offer.
|
||||
testStacking(playerInv -> playerInv::insert);
|
||||
}
|
||||
|
@ -69,14 +69,14 @@ public class PlayerInventoryStorageTests extends AbstractTransferApiTest {
|
|||
try (Transaction tx = Transaction.openOuter()) {
|
||||
assertEquals(1L, inserter.insert(stone, 1, tx));
|
||||
|
||||
// Should have went into the main stack
|
||||
// Should have gone into the main stack
|
||||
assertEquals(64, inv.main.get(3).getCount());
|
||||
}
|
||||
|
||||
try (Transaction tx = Transaction.openOuter()) {
|
||||
assertEquals(2L, inserter.insert(stone, 2, tx));
|
||||
|
||||
// Should have went into the main and offhand stacks.
|
||||
// Should have gone into the main and offhand stacks.
|
||||
assertEquals(64, inv.main.get(3).getCount());
|
||||
assertEquals(63, inv.offHand.get(0).getCount());
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public class SingleVariantItemStorageTests extends AbstractTransferApiTest {
|
|||
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);
|
||||
|
||||
|
@ -215,7 +215,9 @@ public class SingleVariantItemStorageTests extends AbstractTransferApiTest {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +260,7 @@ public class SingleVariantItemStorageTests extends AbstractTransferApiTest {
|
|||
|
||||
@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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue