diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/StrippableBlockRegistry.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/StrippableBlockRegistry.java index ed4ea6aac..1723daf96 100644 --- a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/StrippableBlockRegistry.java +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/StrippableBlockRegistry.java @@ -16,7 +16,6 @@ package net.fabricmc.fabric.api.registry; -import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -27,6 +26,7 @@ import net.minecraft.block.Block; import net.minecraft.state.property.Properties; import net.fabricmc.fabric.mixin.content.registry.AxeItemAccessor; +import net.fabricmc.fabric.impl.content.registry.util.ImmutableCollectionUtils; /** * A registry for axe stripping interactions. A vanilla example is turning logs to stripped logs. @@ -49,14 +49,8 @@ public final class StrippableBlockRegistry { public static void register(Block input, Block stripped) { requireNonNullAndAxisProperty(input, "input block"); requireNonNullAndAxisProperty(stripped, "stripped block"); - Map<Block, Block> strippedBlocks = AxeItemAccessor.getStrippedBlocks(); - if (!(strippedBlocks instanceof HashMap<?, ?>)) { - strippedBlocks = new HashMap<>(strippedBlocks); - AxeItemAccessor.setStrippedBlocks(strippedBlocks); - } - - Block old = strippedBlocks.put(input, stripped); + Block old = getRegistry().put(input, stripped); if (old != null) { LOGGER.debug("Replaced old stripping mapping from {} to {} with {}", input, old, stripped); @@ -70,4 +64,8 @@ public final class StrippableBlockRegistry { throw new IllegalArgumentException(name + " must have the 'axis' property"); } } + + private static Map<Block, Block> getRegistry() { + return ImmutableCollectionUtils.getAsMutableMap(AxeItemAccessor::getStrippedBlocks, AxeItemAccessor::setStrippedBlocks); + } } diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/VillagerInteractionRegistries.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/VillagerInteractionRegistries.java new file mode 100644 index 000000000..2940b9cf6 --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/VillagerInteractionRegistries.java @@ -0,0 +1,110 @@ +/* + * 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.registry; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.entity.passive.VillagerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.util.Identifier; +import net.minecraft.village.VillagerProfession; + +import net.fabricmc.fabric.impl.content.registry.util.ImmutableCollectionUtils; +import net.fabricmc.fabric.mixin.content.registry.VillagerEntityAccessor; +import net.fabricmc.fabric.mixin.content.registry.FarmerWorkTaskAccessor; +import net.fabricmc.fabric.mixin.content.registry.GiveGiftsToHeroTaskAccessor; + +/** + * Registries for modifying villager interactions that + * villagers have with the world. + * @see VillagerPlantableRegistry for registering plants that farmers can plant + */ +public class VillagerInteractionRegistries { + private static final Logger LOGGER = LoggerFactory.getLogger(VillagerInteractionRegistries.class); + + private VillagerInteractionRegistries() { + } + + /** + * Registers an item to be collectable (picked up from item entity) + * by any profession villagers. + * + * @param item the item to register + */ + public static void registerCollectable(ItemConvertible item) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + getCollectableRegistry().add(item.asItem()); + } + + /** + * Registers an item to be use in a composter by farmer villagers. + * @param item the item to register + */ + public static void registerCompostable(ItemConvertible item) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + getCompostableRegistry().add(item.asItem()); + } + + /** + * Registers an item to be edible by villagers. + * @param item the item to register + * @param foodValue the amount of breeding power the item has (1 = normal food item, 4 = bread) + */ + public static void registerFood(ItemConvertible item, int foodValue) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + Objects.requireNonNull(foodValue, "Food value cannot be null!"); + Integer oldValue = getFoodRegistry().put(item.asItem(), foodValue); + + if (oldValue != null) { + LOGGER.info("Overriding previous food value of {}, was: {}, now: {}", item.asItem().toString(), oldValue, foodValue); + } + } + + /** + * Registers a hero of the village gifts loot table to a profession. + * @param profession the profession to modify + * @param lootTable the loot table to associate with the profession + */ + public static void registerGiftLootTable(VillagerProfession profession, Identifier lootTable) { + Objects.requireNonNull(profession, "Profession cannot be null!"); + Objects.requireNonNull(lootTable, "Loot table identifier cannot be null!"); + Identifier oldValue = GiveGiftsToHeroTaskAccessor.fabric_getGifts().put(profession, lootTable); + + if (oldValue != null) { + LOGGER.info("Overriding previous gift loot table of {} profession, was: {}, now: {}", profession.getId(), oldValue, lootTable); + } + } + + private static Set<Item> getCollectableRegistry() { + return ImmutableCollectionUtils.getAsMutableSet(VillagerEntityAccessor::fabric_getGatherableItems, VillagerEntityAccessor::fabric_setGatherableItems); + } + + private static List<Item> getCompostableRegistry() { + return ImmutableCollectionUtils.getAsMutableList(FarmerWorkTaskAccessor::fabric_getCompostable, FarmerWorkTaskAccessor::fabric_setCompostables); + } + + private static Map<Item, Integer> getFoodRegistry() { + return ImmutableCollectionUtils.getAsMutableMap(() -> VillagerEntity.ITEM_FOOD_VALUES, VillagerEntityAccessor::fabric_setItemFoodValues); + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/VillagerPlantableRegistry.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/VillagerPlantableRegistry.java new file mode 100644 index 000000000..6f8aa4ced --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/VillagerPlantableRegistry.java @@ -0,0 +1,113 @@ +/* + * 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.registry; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Objects; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.block.BlockState; +import net.minecraft.block.CropBlock; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.Items; +import net.minecraft.util.registry.Registry; + +/** + * Registry of items that farmer villagers can plant on farmland. + */ +public class VillagerPlantableRegistry { + private static final Logger LOGGER = LoggerFactory.getLogger(VillagerPlantableRegistry.class); + private static final HashMap<Item, BlockState> PLANTABLES = new HashMap<>(); + static { + register(Items.WHEAT_SEEDS); + register(Items.CARROT); + register(Items.POTATO); + register(Items.BEETROOT_SEEDS); + } + + private VillagerPlantableRegistry() { + } + + /** + * Registers a BlockItem to be plantable by farmer villagers. + * This will use the default state of the associated block. + * For the crop to be harvestable, the block should extend CropBlock, so the + * farmer can test the {@link CropBlock#isMature(BlockState)} method. + * @param item the BlockItem to register + */ + public static void register(ItemConvertible item) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + + if (!(item.asItem() instanceof BlockItem)) { + throw new IllegalArgumentException("item is not a BlockItem"); + } + + register(item, ((BlockItem) item.asItem()).getBlock().getDefaultState()); + } + + /** + * Register an item with an associated to be plantable by farmer villagers. + * For the crop to be harvestable, the block should extend CropBlock, so the + * farmer can test the {@link CropBlock#isMature(BlockState)} method. + * @param item the seed item + * @param plantState the state that will be planted + */ + public static void register(ItemConvertible item, BlockState plantState) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + Objects.requireNonNull(plantState, "Plant block state cannot be null!"); + + PLANTABLES.put(item.asItem(), plantState); + + if (!(plantState.getBlock() instanceof CropBlock)) { + LOGGER.info("Registered a block ({}) that does not extend CropBlock, this block will not be villager harvestable by default.", Registry.BLOCK.getId(plantState.getBlock())); + } + } + + /** + * Tests if the item is a registered seed item. + * @param item the item to test + * @return true if the item is registered as a seed + */ + public static boolean contains(ItemConvertible item) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + return PLANTABLES.containsKey(item.asItem()); + } + + /** + * Get the state that is associated with the provided seed item. + * @param item the seed item + * @return the state associated with the seed item + */ + public static BlockState getPlantState(ItemConvertible item) { + Objects.requireNonNull(item.asItem(), "Item cannot be null!"); + return PLANTABLES.get(item.asItem()); + } + + /** + * Get all currently registered seed items. + * @return all currently registered seed items. + */ + public static Set<Item> getItems() { + return Collections.unmodifiableSet(PLANTABLES.keySet()); + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/util/ImmutableCollectionUtils.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/util/ImmutableCollectionUtils.java new file mode 100644 index 000000000..dd0c6207a --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/content/registry/util/ImmutableCollectionUtils.java @@ -0,0 +1,58 @@ +/* + * 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.content.registry.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class ImmutableCollectionUtils { + public static <T> Set<T> getAsMutableSet(Supplier<Set<T>> getter, Consumer<Set<T>> setter) { + Set<T> set = getter.get(); + + if (!(set instanceof HashSet)) { + setter.accept(set = new HashSet<>(set)); + } + + return set; + } + + public static <T> List<T> getAsMutableList(Supplier<List<T>> getter, Consumer<List<T>> setter) { + List<T> set = getter.get(); + + if (!(set instanceof ArrayList)) { + setter.accept(set = new ArrayList<>(set)); + } + + return set; + } + + public static <K, V> Map<K, V> getAsMutableMap(Supplier<Map<K, V>> getter, Consumer<Map<K, V>> setter) { + Map<K, V> map = getter.get(); + + if (!(map instanceof HashMap)) { + setter.accept(map = new HashMap<>(map)); + } + + return map; + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/FarmerVillagerTaskMixin.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/FarmerVillagerTaskMixin.java new file mode 100644 index 000000000..85f3dbb80 --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/FarmerVillagerTaskMixin.java @@ -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.mixin.content.registry; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import net.minecraft.entity.ai.brain.task.FarmerVillagerTask; +import net.minecraft.entity.passive.VillagerEntity; +import net.minecraft.inventory.SimpleInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; + +import net.fabricmc.fabric.api.registry.VillagerPlantableRegistry; + +@Mixin(FarmerVillagerTask.class) +public class FarmerVillagerTaskMixin { + @Nullable + @Shadow private BlockPos currentTarget; + + private int fabric_currentInventorySlot = -1; + + @ModifyArg(method = "keepRunning", at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/SimpleInventory;getStack(I)Lnet/minecraft/item/ItemStack;"), index = 0) + private int fabric_storeCurrentSlot(int slot) { + return this.fabric_currentInventorySlot = slot; + } + + @ModifyVariable(method = "keepRunning", at = @At("LOAD")) + private boolean fabric_useRegistryForPlace(boolean current, ServerWorld serverWorld, VillagerEntity villagerEntity, long l) { + if (current) { + return true; + } + + SimpleInventory simpleInventory = villagerEntity.getInventory(); + ItemStack currentStack = simpleInventory.getStack(this.fabric_currentInventorySlot); + + if (!currentStack.isEmpty() && VillagerPlantableRegistry.contains(currentStack.getItem())) { + serverWorld.setBlockState(this.currentTarget, VillagerPlantableRegistry.getPlantState(currentStack.getItem()), 3); + return true; + } + + return false; + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/FarmerWorkTaskAccessor.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/FarmerWorkTaskAccessor.java new file mode 100644 index 000000000..04e4c0115 --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/FarmerWorkTaskAccessor.java @@ -0,0 +1,40 @@ +/* + * 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.content.registry; + +import java.util.List; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.entity.ai.brain.task.FarmerWorkTask; +import net.minecraft.item.Item; + +@Mixin(FarmerWorkTask.class) +public interface FarmerWorkTaskAccessor { + @Mutable + @Accessor("COMPOSTABLES") + static void fabric_setCompostables(List<Item> items) { + throw new AssertionError("Untransformed @Accessor"); + } + + @Accessor("COMPOSTABLES") + static List<Item> fabric_getCompostable() { + throw new AssertionError("Untransformed @Accessor"); + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/GiveGiftsToHeroTaskAccessor.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/GiveGiftsToHeroTaskAccessor.java new file mode 100644 index 000000000..86acc618d --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/GiveGiftsToHeroTaskAccessor.java @@ -0,0 +1,34 @@ +/* + * 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.content.registry; + +import java.util.Map; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.entity.ai.brain.task.GiveGiftsToHeroTask; +import net.minecraft.util.Identifier; +import net.minecraft.village.VillagerProfession; + +@Mixin(GiveGiftsToHeroTask.class) +public interface GiveGiftsToHeroTaskAccessor { + @Accessor("GIFTS") + static Map<VillagerProfession, Identifier> fabric_getGifts() { + throw new AssertionError("Untransformed @Accessor"); + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/VillagerEntityAccessor.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/VillagerEntityAccessor.java new file mode 100644 index 000000000..5766ef523 --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/VillagerEntityAccessor.java @@ -0,0 +1,47 @@ +/* + * 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.content.registry; + +import java.util.Map; +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.entity.passive.VillagerEntity; +import net.minecraft.item.Item; + +@Mixin(VillagerEntity.class) +public interface VillagerEntityAccessor { + @Mutable + @Accessor("ITEM_FOOD_VALUES") + static void fabric_setItemFoodValues(Map<Item, Integer> items) { + throw new AssertionError("Untransformed @Accessor"); + } + + @Mutable + @Accessor("GATHERABLE_ITEMS") + static void fabric_setGatherableItems(Set<Item> items) { + throw new AssertionError("Untransformed @Accessor"); + } + + @Accessor("GATHERABLE_ITEMS") + static Set<Item> fabric_getGatherableItems() { + throw new AssertionError("Untransformed @Accessor"); + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/VillagerEntityMixin.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/VillagerEntityMixin.java new file mode 100644 index 000000000..eb24c3528 --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/VillagerEntityMixin.java @@ -0,0 +1,37 @@ +/* + * 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.content.registry; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import net.minecraft.entity.passive.VillagerEntity; +import net.minecraft.inventory.SimpleInventory; +import net.minecraft.item.Item; + +import net.fabricmc.fabric.api.registry.VillagerPlantableRegistry; + +@Mixin(VillagerEntity.class) +public class VillagerEntityMixin { + @Redirect(method = "hasSeedToPlant", at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/SimpleInventory;containsAny(Ljava/util/Set;)Z")) + private boolean fabric_useRegistry(SimpleInventory inventory, Set<Item> items) { + return inventory.containsAny(VillagerPlantableRegistry.getItems()); + } +} diff --git a/fabric-content-registries-v0/src/main/resources/fabric-content-registries-v0.mixins.json b/fabric-content-registries-v0/src/main/resources/fabric-content-registries-v0.mixins.json index 5c6ccd3c0..4bfadd6b1 100644 --- a/fabric-content-registries-v0/src/main/resources/fabric-content-registries-v0.mixins.json +++ b/fabric-content-registries-v0/src/main/resources/fabric-content-registries-v0.mixins.json @@ -4,12 +4,17 @@ "compatibilityLevel": "JAVA_16", "mixins": [ "AxeItemAccessor", + "FarmerVillagerTaskMixin", + "FarmerWorkTaskAccessor", + "GiveGiftsToHeroTaskAccessor", "HoeItemAccessor", "HoneycombItemMixin", "MixinAbstractFurnaceBlockEntity", "MixinFireBlock", "OxidizableMixin", - "ShovelItemAccessor" + "ShovelItemAccessor", + "VillagerEntityAccessor", + "VillagerEntityMixin" ], "injectors": { "defaultRequire": 1 diff --git a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java index d492963ee..f5a6b53ba 100644 --- a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java +++ b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java @@ -16,17 +16,22 @@ package net.fabricmc.fabric.test.content.registry; -import org.slf4j.LoggerFactory; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.minecraft.block.Blocks; import net.minecraft.item.HoeItem; +import net.minecraft.item.Items; +import net.minecraft.util.Identifier; +import net.minecraft.village.VillagerProfession; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.registry.FlattenableBlockRegistry; import net.fabricmc.fabric.api.registry.OxidizableBlocksRegistry; import net.fabricmc.fabric.api.registry.StrippableBlockRegistry; import net.fabricmc.fabric.api.registry.TillableBlockRegistry; +import net.fabricmc.fabric.api.registry.VillagerInteractionRegistries; +import net.fabricmc.fabric.api.registry.VillagerPlantableRegistry; public final class ContentRegistryTest implements ModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger(ContentRegistryTest.class); @@ -39,6 +44,9 @@ public final class ContentRegistryTest implements ModInitializer { // - green wool is tillable to lime wool // - copper ore, iron ore, gold ore, and diamond ore can be waxed into their deepslate variants and scraped back again // - aforementioned ores can be scraped from diamond -> gold -> iron -> copper + // - villagers can now collect, consume (at the same level of bread) and compost apples + // - villagers can now collect and plant oak saplings + // - assign a loot table to the nitwit villager type FlattenableBlockRegistry.register(Blocks.RED_WOOL, Blocks.YELLOW_WOOL.getDefaultState()); StrippableBlockRegistry.register(Blocks.QUARTZ_PILLAR, Blocks.HAY_BLOCK); @@ -77,5 +85,24 @@ public final class ContentRegistryTest implements ModInitializer { // expected behavior LOGGER.info("OxidizableBlocksRegistry test passed!"); } + + VillagerInteractionRegistries.registerCollectable(Items.APPLE); + VillagerInteractionRegistries.registerFood(Items.APPLE, 4); + VillagerInteractionRegistries.registerCompostable(Items.APPLE); + + VillagerInteractionRegistries.registerCollectable(Items.OAK_SAPLING); + VillagerPlantableRegistry.register(Items.OAK_SAPLING); + + // assert that VillagerPlantablesRegistry throws when getting a non-BlockItem + try { + VillagerPlantableRegistry.register(Items.STICK); + + throw new AssertionError("VillagerPlantablesRegistry didn't throw when item is not BlockItem!"); + } catch (Exception e) { + // expected behavior + LOGGER.info("VillagerPlantablesRegistry test passed!"); + } + + VillagerInteractionRegistries.registerGiftLootTable(VillagerProfession.NITWIT, new Identifier("fake_loot_table")); } }