mirror of
https://github.com/FabricMC/fabric.git
synced 2025-05-17 08:40:47 -04:00
Add FabricItemSettings and an API for custom item equipment slots (#956)
* Add FabricItemSettings and an API for custom item equipment slots Closes #952. * Bump module version * Rename duck method to have fabric_ prefix and add Unique to mixin field * Switch to FabricItemInternals + ExtraData like in FabricBlockSettings
This commit is contained in:
parent
db9ee7acda
commit
eb1e5e8520
10 changed files with 348 additions and 1 deletions
fabric-item-api-v1
|
@ -1,5 +1,5 @@
|
||||||
archivesBaseName = "fabric-item-api-v1"
|
archivesBaseName = "fabric-item-api-v1"
|
||||||
version = getSubprojectVersion(project, "1.0.0")
|
version = getSubprojectVersion(project, "1.1.0")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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.api.item.v1;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A provider for the preferred equipment slot of an item.
|
||||||
|
* This can be used to give non-armor items, such as blocks,
|
||||||
|
* an armor slot that they can go in.
|
||||||
|
*
|
||||||
|
* <p>Equipment slot providers can be set with {@link FabricItemSettings#equipmentSlot(EquipmentSlotProvider)}.
|
||||||
|
*
|
||||||
|
* <p>Note that items extending {@link net.minecraft.item.ArmorItem} don't need to use this
|
||||||
|
* as there's {@link net.minecraft.item.ArmorItem#getSlotType()}.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface EquipmentSlotProvider {
|
||||||
|
/**
|
||||||
|
* Gets the preferred equipment slot for an item stack.
|
||||||
|
*
|
||||||
|
* <p>If there is no preferred armor equipment slot for the stack,
|
||||||
|
* {@link EquipmentSlot#MAINHAND} can be returned.
|
||||||
|
*
|
||||||
|
* @param stack the item stack
|
||||||
|
* @return the preferred equipment slot
|
||||||
|
*/
|
||||||
|
EquipmentSlot getPreferredEquipmentSlot(ItemStack stack);
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* 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.api.item.v1;
|
||||||
|
|
||||||
|
import net.minecraft.item.FoodComponent;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.util.Rarity;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.impl.item.FabricItemInternals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fabric's version of Item.Settings. Adds additional methods and hooks
|
||||||
|
* not found in the original class.
|
||||||
|
*
|
||||||
|
* <p>To use it, simply replace {@code new Item.Settings()} with
|
||||||
|
* {@code new FabricItemSettings()}.
|
||||||
|
*/
|
||||||
|
public class FabricItemSettings extends Item.Settings {
|
||||||
|
/**
|
||||||
|
* Sets the equipment slot provider of the item.
|
||||||
|
*
|
||||||
|
* @param equipmentSlotProvider the equipment slot provider
|
||||||
|
* @return this builder
|
||||||
|
*/
|
||||||
|
public FabricItemSettings equipmentSlot(EquipmentSlotProvider equipmentSlotProvider) {
|
||||||
|
FabricItemInternals.computeExtraData(this).equipmentSlot(equipmentSlotProvider);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overrides of vanilla methods
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings food(FoodComponent foodComponent) {
|
||||||
|
super.food(foodComponent);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings maxCount(int maxCount) {
|
||||||
|
super.maxCount(maxCount);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings maxDamageIfAbsent(int maxDamage) {
|
||||||
|
super.maxDamageIfAbsent(maxDamage);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings maxDamage(int maxDamage) {
|
||||||
|
super.maxDamage(maxDamage);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings recipeRemainder(Item recipeRemainder) {
|
||||||
|
super.recipeRemainder(recipeRemainder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings group(ItemGroup group) {
|
||||||
|
super.group(group);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings rarity(Rarity rarity) {
|
||||||
|
super.rarity(rarity);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FabricItemSettings fireproof() {
|
||||||
|
super.fireproof();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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.impl.item;
|
||||||
|
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider;
|
||||||
|
|
||||||
|
public final class FabricItemInternals {
|
||||||
|
private static final WeakHashMap<Item.Settings, ExtraData> extraData = new WeakHashMap<>();
|
||||||
|
|
||||||
|
private FabricItemInternals() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtraData computeExtraData(Item.Settings settings) {
|
||||||
|
return extraData.computeIfAbsent(settings, s -> new ExtraData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onBuild(Item.Settings settings, Item item) {
|
||||||
|
ExtraData data = extraData.get(settings);
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
((ItemExtensions) item).fabric_setEquipmentSlotProvider(data.equipmentSlotProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ExtraData {
|
||||||
|
private /* @Nullable */ EquipmentSlotProvider equipmentSlotProvider;
|
||||||
|
|
||||||
|
public void equipmentSlot(EquipmentSlotProvider equipmentSlotProvider) {
|
||||||
|
this.equipmentSlotProvider = equipmentSlotProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.impl.item;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider;
|
||||||
|
|
||||||
|
public interface ItemExtensions {
|
||||||
|
EquipmentSlotProvider fabric_getEquipmentSlotProvider();
|
||||||
|
void fabric_setEquipmentSlotProvider(EquipmentSlotProvider equipmentSlotProvider);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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.mixin.item;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider;
|
||||||
|
import net.fabricmc.fabric.impl.item.FabricItemInternals;
|
||||||
|
import net.fabricmc.fabric.impl.item.ItemExtensions;
|
||||||
|
|
||||||
|
@Mixin(Item.class)
|
||||||
|
abstract class ItemMixin implements ItemExtensions {
|
||||||
|
@Unique
|
||||||
|
private EquipmentSlotProvider equipmentSlotProvider;
|
||||||
|
|
||||||
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
|
private void onConstruct(Item.Settings settings, CallbackInfo info) {
|
||||||
|
FabricItemInternals.onBuild(settings, (Item) (Object) this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EquipmentSlotProvider fabric_getEquipmentSlotProvider() {
|
||||||
|
return equipmentSlotProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fabric_setEquipmentSlotProvider(EquipmentSlotProvider equipmentSlotProvider) {
|
||||||
|
this.equipmentSlotProvider = equipmentSlotProvider;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.mixin.item;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider;
|
||||||
|
import net.fabricmc.fabric.impl.item.ItemExtensions;
|
||||||
|
|
||||||
|
@Mixin(MobEntity.class)
|
||||||
|
abstract class MobEntityMixin {
|
||||||
|
@Inject(method = "getPreferredEquipmentSlot", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
|
private static void onGetPreferredEquipmentSlot(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> info, Item item) {
|
||||||
|
EquipmentSlotProvider equipmentSlotProvider = ((ItemExtensions) item).fabric_getEquipmentSlotProvider();
|
||||||
|
|
||||||
|
if (equipmentSlotProvider != null) {
|
||||||
|
info.setReturnValue(equipmentSlotProvider.getPreferredEquipmentSlot(stack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,10 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"package": "net.fabricmc.fabric.mixin.item",
|
"package": "net.fabricmc.fabric.mixin.item",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"mixins": [
|
||||||
|
"ItemMixin",
|
||||||
|
"MobEntityMixin"
|
||||||
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.ItemStackMixin"
|
"client.ItemStackMixin"
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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 net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
|
|
||||||
|
public class FabricItemSettingsTests implements ModInitializer {
|
||||||
|
@Override
|
||||||
|
public void onInitialize() {
|
||||||
|
// Registers an item with a custom equipment slot.
|
||||||
|
Item testItem = new Item(new FabricItemSettings().group(ItemGroup.MISC).equipmentSlot(stack -> EquipmentSlot.CHEST));
|
||||||
|
Registry.register(Registry.ITEM, new Identifier("fabric-item-api-v1-testmod", "test_item"), testItem);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,9 @@
|
||||||
"fabric-item-api-v1": "*"
|
"fabric-item-api-v1": "*"
|
||||||
},
|
},
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
|
"main": [
|
||||||
|
"net.fabricmc.fabric.test.item.FabricItemSettingsTests"
|
||||||
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"net.fabricmc.fabric.test.item.client.TooltipTests"
|
"net.fabricmc.fabric.test.item.client.TooltipTests"
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue