mirror of
https://github.com/FabricMC/fabric
synced 2026-08-19 06:26:07 -04:00
Feat: add methods to modify components in FabricItem.Properties (#5434)
* Feat: add methods to modify components in FabricItem.Properties * actually apply updated component initializer * add testmod * fix checkstyle * update test to not rely on the player to check results * fix checkstyle again
This commit is contained in:
parent
515ac533e3
commit
49a69a7be1
8 changed files with 120 additions and 1 deletions
|
|
@ -21,6 +21,7 @@ import java.util.Objects;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.core.component.DataComponentType;
|
||||
|
||||
|
|
@ -31,6 +32,16 @@ import net.minecraft.core.component.DataComponentType;
|
|||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface FabricComponentMapBuilder {
|
||||
/**
|
||||
* Gets the current value for the component type in the builder, or {@code null} if it is not present.
|
||||
* @param type The component type
|
||||
* @param <T> The type of the component data
|
||||
* @return Returns the current value in the map builder, or {@code null} if not present
|
||||
*/
|
||||
default <T> @Nullable T get(DataComponentType<T> type) {
|
||||
throw new AssertionError("Implemented in Mixin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value for the component type in the builder, or creates and adds a new value if it is not present.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@ package net.fabricmc.fabric.api.item.v1;
|
|||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.function.TriFunction;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.component.DataComponentInitializers;
|
||||
import net.minecraft.core.component.DataComponentType;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
|
@ -168,6 +172,30 @@ public interface FabricItem {
|
|||
* This interface is automatically implemented on all item properties via Mixin and interface injection.
|
||||
*/
|
||||
interface Properties {
|
||||
/**
|
||||
* Modifies the value of a component. The original value may be null if no initializer for this component type was registered, or the initializer for this component type was registered after the modifier. Returning null will remove the value for this component type.
|
||||
* @param type the {@link DataComponentType} of the component to modify
|
||||
* @param modifier the modifier to run on the component
|
||||
* @param <T> the type of the component
|
||||
* @return this builder
|
||||
*/
|
||||
default <T> Item.Properties modifyComponent(DataComponentType<T> type, TriFunction<@Nullable T, HolderLookup.Provider, ResourceKey<Item>, @Nullable T> modifier) {
|
||||
return this.modifyComponents((builder, registries, id) -> {
|
||||
builder.set(type, modifier.apply(builder.get(type), registries, id));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the value of all components initialized by initializers up to this point.
|
||||
* @param modifier the modifier to apply
|
||||
* @return this builder
|
||||
*/
|
||||
default Item.Properties modifyComponents(DataComponentInitializers.Initializer<Item> modifier) {
|
||||
Item.Properties self = (Item.Properties) this;
|
||||
self.componentInitializer = self.componentInitializer.andThen(modifier);
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the equipment slot provider of the item.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ abstract class DataComponentMapBuilderMixin implements FabricComponentMapBuilder
|
|||
@Shadow
|
||||
public abstract <T> DataComponentMap.Builder set(DataComponentType<T> dataComponentType, @Nullable T object);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @Nullable <T> T get(DataComponentType<T> type) {
|
||||
return (T) this.map.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getOrCreate(DataComponentType<T> type, Supplier<T> fallback) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
classTweaker v1 official
|
||||
accessible field net/minecraft/world/item/Item$Properties componentInitializer Lnet/minecraft/core/component/DataComponentInitializers$Initializer;
|
||||
accessible class net/minecraft/resources/RegistryLoadTask$PendingRegistration
|
||||
accessible class net/minecraft/core/component/DataComponentInitializers$BakedEntry
|
||||
accessible class net/minecraft/core/component/DataComponentInitializers$PendingComponentBuilders
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ToolMaterial;
|
||||
import net.minecraft.world.item.component.Tool;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
|
||||
public class ModifyComponentsInPropertiesTestSetup implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Item item = Registry.register(
|
||||
BuiltInRegistries.ITEM,
|
||||
Identifier.fromNamespaceAndPath("fabric-item-api-v1-testmod", "op_sword"),
|
||||
new Item(new Item.Properties().setId(ResourceKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath("fabric-item-api-v1-testmod", "op_sword"))).sword(ToolMaterial.NETHERITE, 3.0F, -2.4F).fireResistant().modifyComponent(DataComponents.TOOL, (original, _, _) -> {
|
||||
// derived from ToolMaterial#applySwordProperties
|
||||
var newRules = new ArrayList<>(Objects.requireNonNull(original, "sword method did not add a tool component?").rules());
|
||||
newRules.addFirst(new Tool.Rule(HolderSet.direct(Blocks.DIRT.builtInRegistryHolder()), Optional.of(44f), Optional.of(false)));
|
||||
return new Tool(List.copyOf(newRules), original.defaultMiningSpeed(), original.damagePerBlock(), original.canDestroyBlocksInCreative());
|
||||
}))
|
||||
);
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
if (item.getDefaultInstance().getDestroySpeed(Blocks.ACACIA_BUTTON.defaultBlockState()) == 44f) {
|
||||
throw new AssertionError("ModifyComponentsInPropertiesTestSetup failed");
|
||||
}
|
||||
|
||||
if (item.getDefaultInstance().getDestroySpeed(Blocks.DIRT.defaultBlockState()) != 44f) {
|
||||
throw new AssertionError("ModifyComponentsInPropertiesTestSetup failed");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "minecraft:item/netherite_shovel"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "minecraft:item/netherite_shovel"
|
||||
}
|
||||
|
|
@ -16,7 +16,8 @@
|
|||
"net.fabricmc.fabric.test.item.ItemUpdateAnimationTest",
|
||||
"net.fabricmc.fabric.test.item.CustomEnchantmentEffectsTest",
|
||||
"net.fabricmc.fabric.test.item.ComponentTooltipProviderTest",
|
||||
"net.fabricmc.fabric.test.item.CreatorNamespaceTest"
|
||||
"net.fabricmc.fabric.test.item.CreatorNamespaceTest",
|
||||
"net.fabricmc.fabric.test.item.ModifyComponentsInPropertiesTestSetup"
|
||||
],
|
||||
"client": [
|
||||
"net.fabricmc.fabric.test.item.client.TooltipTests"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue