# Removed
- FabricItemStack.isSuitableFor (replaced with vanilla component)
- FabricItemStack.getFoodComponent (replaced with vanilla component)
- ResourceReloadListenerKeys.LOOT_TABLES
- fabric-resource-conditions-api-v1 support for loot tables

# Disabled modules
- fabric-loot-api-v2
- fabric-mining-level-api-v1
This commit is contained in:
modmuss 2024-03-20 19:08:34 +00:00 committed by GitHub
parent 3a09d40a83
commit e9d2a72b4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 74 additions and 702 deletions
fabric-api-lookup-api-v1/src/testmod/java/net/fabricmc/fabric/test/lookup/item
fabric-convention-tags-v1/src/datagen/java/net/fabricmc/fabric/impl/tag/convention/datagen/generators
fabric-data-generation-api-v1/src
main/java/net/fabricmc/fabric
testmod/java/net/fabricmc/fabric/test/datagen
fabric-entity-events-v1/src/main/java/net/fabricmc/fabric/mixin/entity/event/elytra
fabric-item-api-v1/src
fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle
fabric-object-builder-api-v1/src
main/java/net/fabricmc/fabric
api/object/builder/v1/block
mixin/object/builder
testmod/java/net/fabricmc/fabric/test/object/builder
fabric-resource-conditions-api-v1/src
main
testmod/java/net/fabricmc/fabric/test/resource/conditions
fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric
gradle.propertiessettings.gradle

View file

@ -55,7 +55,7 @@ public class FabricItemApiLookupTest {
Item item = stack.getItem();
if (item instanceof ToolItem) {
return () -> Text.literal("Tool mining level: " + ((ToolItem) item).getMaterial().getMiningLevel());
return () -> Text.literal("Tool mining level: " + ((ToolItem) item).getMaterial());
} else {
return null;
}

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
import java.util.concurrent.CompletableFuture;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.registry.Registries;
@ -142,7 +143,7 @@ public class ItemTagGenerator extends FabricTagProvider.ItemTagProvider {
private void generateConsumableTags() {
Registries.ITEM.forEach(item -> {
if (item.getFoodComponent() != null) {
if (item.getDefaultStack().contains(DataComponentTypes.FOOD)) {
getOrCreateTagBuilder(ConventionalItemTags.FOODS).add(item);
}
});

View file

@ -32,6 +32,7 @@ import net.minecraft.loot.LootTable;
import net.minecraft.loot.LootTables;
import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.resource.featuretoggle.FeatureFlags;
import net.minecraft.util.Identifier;
@ -72,17 +73,17 @@ public abstract class FabricBlockLootTableProvider extends BlockLootTableGenerat
}
@Override
public void accept(RegistryWrapper.WrapperLookup registryLookup, BiConsumer<Identifier, LootTable.Builder> biConsumer) {
public void accept(RegistryWrapper.WrapperLookup registryLookup, BiConsumer<RegistryKey<LootTable>, LootTable.Builder> biConsumer) {
generate();
for (Map.Entry<Identifier, LootTable.Builder> entry : lootTables.entrySet()) {
Identifier identifier = entry.getKey();
for (Map.Entry<RegistryKey<LootTable>, LootTable.Builder> entry : lootTables.entrySet()) {
RegistryKey<LootTable> registryKey = entry.getKey();
if (identifier.equals(LootTables.EMPTY)) {
if (registryKey.equals(LootTables.EMPTY)) {
continue;
}
biConsumer.accept(identifier, entry.getValue());
biConsumer.accept(registryKey, entry.getValue());
}
if (output.isStrictValidationEnabled()) {
@ -90,9 +91,9 @@ public abstract class FabricBlockLootTableProvider extends BlockLootTableGenerat
for (Identifier blockId : Registries.BLOCK.getIds()) {
if (blockId.getNamespace().equals(output.getModId())) {
Identifier blockLootTableId = Registries.BLOCK.get(blockId).getLootTableId();
RegistryKey<LootTable> blockLootTableId = Registries.BLOCK.get(blockId).getLootTableId();
if (blockLootTableId.getNamespace().equals(output.getModId())) {
if (blockLootTableId.getValue().getNamespace().equals(output.getModId())) {
if (!lootTables.containsKey(blockLootTableId)) {
missing.add(blockId);
}

View file

@ -24,7 +24,7 @@ import org.jetbrains.annotations.ApiStatus;
import net.minecraft.data.DataProvider;
import net.minecraft.data.server.loottable.LootTableGenerator;
import net.minecraft.loot.LootTable;
import net.minecraft.util.Identifier;
import net.minecraft.registry.RegistryKey;
import net.fabricmc.fabric.api.datagen.v1.loot.FabricBlockLootTableGenerator;
import net.fabricmc.fabric.api.resource.conditions.v1.ConditionJsonProvider;
@ -44,7 +44,7 @@ public interface FabricLootTableProvider extends LootTableGenerator, DataProvide
*
* <p>For block loot tables, use {@link FabricBlockLootTableGenerator#withConditions} instead.
*/
default BiConsumer<Identifier, LootTable.Builder> withConditions(BiConsumer<Identifier, LootTable.Builder> exporter, ConditionJsonProvider... conditions) {
default BiConsumer<RegistryKey<LootTable>, LootTable.Builder> withConditions(BiConsumer<RegistryKey<LootTable>, LootTable.Builder> exporter, ConditionJsonProvider... conditions) {
Preconditions.checkArgument(conditions.length > 0, "Must add at least one condition.");
return (id, table) -> {
FabricDataGenHelper.addConditions(table, conditions);

View file

@ -59,12 +59,12 @@ public final class FabricLootTableProviderImpl {
HashMap<Identifier, ConditionJsonProvider[]> conditionMap = new HashMap<>();
return registryLookup.thenCompose(lookup -> {
provider.accept(lookup, (identifier, builder) -> {
provider.accept(lookup, (registryKey, builder) -> {
ConditionJsonProvider[] conditions = FabricDataGenHelper.consumeConditions(builder);
conditionMap.put(identifier, conditions);
conditionMap.put(registryKey.getValue(), conditions);
if (builders.put(identifier, builder.type(lootContextType).build()) != null) {
throw new IllegalStateException("Duplicate loot table " + identifier);
if (builders.put(registryKey.getValue(), builder.type(lootContextType).build()) != null) {
throw new IllegalStateException("Duplicate loot table " + registryKey.getValue());
}
});
@ -72,7 +72,7 @@ public final class FabricLootTableProviderImpl {
final List<CompletableFuture<?>> futures = new ArrayList<>();
for (Map.Entry<Identifier, LootTable> entry : builders.entrySet()) {
JsonObject tableJson = (JsonObject) Util.getResult(LootTable.CODEC.encodeStart(ops, entry.getValue()), IllegalStateException::new);
JsonObject tableJson = (JsonObject) Util.getResult(LootTable.field_50021.encodeStart(ops, entry.getValue()), IllegalStateException::new);
ConditionJsonProvider.write(tableJson, conditionMap.remove(entry.getKey()));
futures.add(DataProvider.writeToPath(writer, tableJson, getOutputPath(fabricDataOutput, entry.getKey())));
}

View file

@ -68,6 +68,7 @@ import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.Registerable;
import net.minecraft.registry.RegistryBuilder;
import net.minecraft.registry.RegistryEntryLookup;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.entry.RegistryEntry;
@ -402,7 +403,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
}
@Override
public void accept(RegistryWrapper.WrapperLookup registryLookup, BiConsumer<Identifier, LootTable.Builder> consumer) {
public void accept(RegistryWrapper.WrapperLookup registryLookup, BiConsumer<RegistryKey<LootTable>, LootTable.Builder> consumer) {
withConditions(consumer, ALWAYS_LOADED).accept(
LootTables.PIGLIN_BARTERING_GAMEPLAY,
LootTable.builder().pool(
@ -434,7 +435,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
private static class TestPredicateProvider extends FabricCodecDataProvider<LootCondition> {
private TestPredicateProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(dataOutput, registriesFuture, DataOutput.OutputType.DATA_PACK, "predicates", LootConditionTypes.CODEC);
super(dataOutput, registriesFuture, DataOutput.OutputType.DATA_PACK, "predicates", LootConditionTypes.field_50031);
}
@Override

View file

@ -16,7 +16,6 @@
package net.fabricmc.fabric.mixin.entity.event.elytra;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -41,10 +40,6 @@ abstract class PlayerEntityMixin extends LivingEntity {
@Shadow
public abstract void startFallFlying();
@Shadow
@Nullable
public Double ignoreFallDamageAboveY;
/**
* Allow the server-side and client-side elytra checks to fail when {@link EntityElytraEvents#ALLOW} blocks flight,
* and otherwise to succeed for elytra flight through {@link EntityElytraEvents#CUSTOM}.
@ -61,7 +56,6 @@ abstract class PlayerEntityMixin extends LivingEntity {
if (EntityElytraEvents.CUSTOM.invoker().useCustomElytra(self, false)) {
startFallFlying();
this.ignoreFallDamageAboveY = null;
cir.setReturnValue(true);
}
}

View file

@ -17,14 +17,11 @@
package net.fabricmc.fabric.api.item.v1;
import com.google.common.collect.Multimap;
import org.jetbrains.annotations.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.entry.RegistryEntry;
@ -84,18 +81,6 @@ public interface FabricItem {
return ((Item) this).getAttributeModifiers(slot);
}
/**
* Determines if mining with this item allows drops to be harvested from the specified block state.
* Stack-aware version of {@link Item#isSuitableFor(BlockState)}.
*
* @param stack the current stack
* @param state the block state of the targeted block
* @return true if drops can be harvested
*/
default boolean isSuitableFor(ItemStack stack, BlockState state) {
return ((Item) this).isSuitableFor(state);
}
/**
* Returns a leftover item stack after {@code stack} is consumed in a recipe.
* (This is also known as "recipe remainder".)
@ -128,17 +113,6 @@ public interface FabricItem {
return ((Item) this).hasRecipeRemainder() ? ((Item) this).getRecipeRemainder().getDefaultStack() : ItemStack.EMPTY;
}
/**
* This is a stack-aware version of {@link Item#getFoodComponent()}.
* Note that simple food component can also be set via {@link Item.Settings#food(FoodComponent)}.
* If you want to get a food component for a stack, is <strong>recommended</strong> to use the stack version of this method: {@link FabricItemStack#getFoodComponent()}.
*
* @return this item's {@link FoodComponent}, or {@code null} if none was set
*/
default @Nullable FoodComponent getFoodComponent(ItemStack stack) {
return ((Item) this).getFoodComponent();
}
/**
* Fabric-provided extensions for {@link Item.Settings}.
* This interface is automatically implemented on all item settings via Mixin and interface injection.

View file

@ -16,9 +16,6 @@
package net.fabricmc.fabric.api.item.v1;
import org.jetbrains.annotations.Nullable;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -39,14 +36,4 @@ public interface FabricItemStack {
default ItemStack getRecipeRemainder() {
return ((ItemStack) this).getItem().getRecipeRemainder((ItemStack) this);
}
/**
* Stack-aware version of {@link Item#getFoodComponent()}.
* See {@link FabricItem#getFoodComponent(ItemStack)} for a more in depth description.
*
* @return this item stack's {@link FoodComponent}, or {@code null} if none was set
*/
default @Nullable FoodComponent getFoodComponent() {
return ((ItemStack) this).getItem().getFoodComponent(((ItemStack) this));
}
}

View file

@ -1,32 +0,0 @@
/*
* 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.Redirect;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemUsageContext;
@Mixin(BlockItem.class)
class BlockItemMixin {
@Redirect(method = "useOnBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;isFood()Z"))
private boolean isStackAwareFood(BlockItem instance, ItemUsageContext context) {
return context.getStack().isFood();
}
}

View file

@ -1,41 +0,0 @@
/*
* 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.jetbrains.annotations.Nullable;
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.CatEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.util.Hand;
@Mixin(CatEntity.class)
class CatEntityMixin {
@Redirect(method = "interactMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, PlayerEntity player, Hand hand) {
return player.getStackInHand(hand).getFoodComponent();
}
@Redirect(method = "interactMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean isStackAwareFood(Item instance, PlayerEntity player, Hand hand) {
return player.getStackInHand(hand).isFood();
}
}

View file

@ -1,32 +0,0 @@
/*
* 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.Redirect;
import net.minecraft.data.server.recipe.CookingRecipeJsonBuilder;
import net.minecraft.item.Item;
@Mixin(CookingRecipeJsonBuilder.class)
class CookingRecipeJsonBuilderMixin {
@Redirect(method = "getSmeltingRecipeCategory", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private static boolean isStackAwareFood(Item instance) {
return instance.getDefaultStack().isFood();
}
}

View file

@ -1,46 +0,0 @@
/*
* 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.Redirect;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.passive.FoxEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
@Mixin(FoxEntity.class)
abstract class FoxEntityMixin extends AnimalEntity {
protected FoxEntityMixin(EntityType<? extends AnimalEntity> entityType, World world) {
super(entityType, world);
}
@Redirect(method = {"canEat", "canPickupItem"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z", ordinal = 0))
private boolean isStackAwareFood(Item instance, ItemStack stack) {
return stack.isFood();
}
@Redirect(method = {"canPickupItem"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z", ordinal = 1))
private boolean isEquippedStackAwareFood(Item instance) {
return this.getEquippedStack(EquipmentSlot.MAINHAND).isFood();
}
}

View file

@ -1,40 +0,0 @@
/*
* 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.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.entity.player.HungerManager;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@Mixin(HungerManager.class)
class HungerManagerMixin {
@Redirect(method = "eat", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, Item item, ItemStack stack) {
return stack.getFoodComponent();
}
@Redirect(method = "eat", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean isStackAwareFood(Item instance, Item item, ItemStack stack) {
return stack.isFood();
}
}

View file

@ -21,16 +21,9 @@ 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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.item.v1.CustomDamageHandler;
import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider;
@ -74,29 +67,4 @@ abstract class ItemMixin implements ItemExtensions, FabricItem {
public void fabric_setCustomDamageHandler(@Nullable CustomDamageHandler handler) {
this.customDamageHandler = handler;
}
@Redirect(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, World world, PlayerEntity user, Hand hand) {
return user.getStackInHand(hand).getFoodComponent();
}
@Redirect(method = "getMaxUseTime", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, ItemStack stack) {
return stack.getFoodComponent();
}
@Redirect(method = {"getMaxUseTime", "getUseAction"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean isStackAwareFood(Item instance, ItemStack stack) {
return stack.isFood();
}
@Redirect(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean isStackAwareFood(Item instance, World world, PlayerEntity user, Hand hand) {
return user.getStackInHand(hand).isFood();
}
@Redirect(method = "finishUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean isStackAwareFood(Item instance, ItemStack stack, World world, LivingEntity user) {
return stack.isFood();
}
}

View file

@ -23,11 +23,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
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.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.BlockState;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -60,20 +56,4 @@ public abstract class ItemStackMixin implements FabricItemStack {
original.call(instance, amount, random, serverPlayerEntity, runnable);
}
@Redirect(
method = "isSuitableFor",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/item/Item;isSuitableFor(Lnet/minecraft/block/BlockState;)Z"
)
)
public boolean hookIsSuitableFor(Item item, BlockState state) {
return item.isSuitableFor((ItemStack) (Object) this, state);
}
@Inject(method = "isFood", at = @At("HEAD"), cancellable = true)
public void isStackAwareFood(CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(this.getFoodComponent() != null);
}
}

View file

@ -16,29 +16,20 @@
package net.fabricmc.fabric.mixin.item;
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.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.item.v1.EquipmentSlotProvider;
import net.fabricmc.fabric.impl.item.ItemExtensions;
@Mixin(LivingEntity.class)
abstract class LivingEntityMixin {
@Shadow
protected ItemStack activeItemStack;
@Inject(method = "getPreferredEquipmentSlot", at = @At(value = "HEAD"), cancellable = true)
private static void onGetPreferredEquipmentSlot(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> info) {
EquipmentSlotProvider equipmentSlotProvider = ((ItemExtensions) stack.getItem()).fabric_getEquipmentSlotProvider();
@ -47,19 +38,4 @@ abstract class LivingEntityMixin {
info.setReturnValue(equipmentSlotProvider.getPreferredEquipmentSlot(stack));
}
}
@Redirect(method = "shouldSpawnConsumptionEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance) {
return this.activeItemStack.getFoodComponent();
}
@Redirect(method = "applyFoodEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, ItemStack stack, World world, LivingEntity targetEntity) {
return stack.getFoodComponent();
}
@Redirect(method = "applyFoodEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean isStackAwareFood(Item instance, ItemStack stack, World world, LivingEntity targetEntity) {
return stack.isFood();
}
}

View file

@ -1,57 +0,0 @@
/*
* 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 com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import org.jetbrains.annotations.Nullable;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.passive.WolfEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
@Mixin(WolfEntity.class)
class WolfEntityMixin {
@Inject(method = "interactMob", at = @At("HEAD"))
private void storeCopy(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir, @Share("interaction_stack") LocalRef<ItemStack> stackRef) {
stackRef.set(player.getStackInHand(hand).copy());
}
@Redirect(method = "interactMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, PlayerEntity player, Hand hand, @Share("interaction_stack") LocalRef<ItemStack> stackRef) {
return stackRef.get().getFoodComponent();
}
@Redirect(method = "isBreedingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;getFoodComponent()Lnet/minecraft/item/FoodComponent;"))
private @Nullable FoodComponent getStackAwareFoodComponent(Item instance, ItemStack stack) {
return stack.getFoodComponent();
}
@Redirect(method = "isBreedingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z", ordinal = 0))
private boolean isStackAwareFood(Item instance, ItemStack stack) {
return stack.isFood();
}
}

View file

@ -4,18 +4,12 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"AbstractFurnaceBlockEntityMixin",
"BlockItemMixin",
"BrewingStandBlockEntityMixin",
"CatEntityMixin",
"CookingRecipeJsonBuilderMixin",
"FoxEntityMixin",
"HungerManagerMixin",
"ItemMixin",
"ItemSettingsMixin",
"ItemStackMixin",
"LivingEntityMixin",
"RecipeMixin",
"WolfEntityMixin"
"RecipeMixin"
],
"injectors": {
"defaultRequire": 1

View file

@ -1,62 +0,0 @@
/*
* 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 org.jetbrains.annotations.Nullable;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import net.fabricmc.api.ModInitializer;
public final class FoodGameInitializer implements ModInitializer {
public static final Item DAMAGE = Registry.register(Registries.ITEM, new Identifier("fabric-item-api-v1-testmod", "damage_food"), new DamageFood(new Item.Settings().maxDamage(20)));
public static final Item NAME = Registry.register(Registries.ITEM, new Identifier("fabric-item-api-v1-testmod", "name_food"), new NameFood(new Item.Settings()));
@Override
public void onInitialize() {
}
public static class DamageFood extends Item {
public DamageFood(Settings settings) {
super(settings);
}
@Override
public @Nullable FoodComponent getFoodComponent(ItemStack stack) {
return new FoodComponent.Builder()
.hunger(20 - 20 * stack.getDamage() / stack.getMaxDamage())
.saturationModifier(0.5f)
.build();
}
}
public static class NameFood extends Item {
public NameFood(Settings settings) {
super(settings);
}
@Override
public @Nullable FoodComponent getFoodComponent(ItemStack stack) {
return Registries.ITEM.get(new Identifier(stack.getName().getString())).getFoodComponent(stack);
}
}
}

View file

@ -76,13 +76,7 @@ public class UpdatingItem extends Item {
}
@Override
public boolean isSuitableFor(ItemStack stack, BlockState state) {
// Suitable for everything for 15 seconds every 30 seconds.
return isEnabled(stack);
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
return isEnabled(stack) ? 20 : super.getMiningSpeedMultiplier(stack, state);
public float method_58404(ItemStack stack, BlockState state) {
return isEnabled(stack) ? 20 : super.method_58404(stack, state);
}
}

View file

@ -1,97 +0,0 @@
/*
* 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.gametest;
import java.util.Objects;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.passive.WolfEntity;
import net.minecraft.entity.player.HungerManager;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FoodComponent;
import net.minecraft.item.FoodComponents;
import net.minecraft.item.ItemStack;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameMode;
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest;
import net.fabricmc.fabric.test.item.FoodGameInitializer;
public final class FoodGameTest implements FabricGameTest {
@GameTest(templateName = EMPTY_STRUCTURE)
public void damageFoodTest(TestContext context) {
PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL);
HungerManager hungerManager = player.getHungerManager();
for (int damage : new int[]{0, 1, 10, 19}) {
hungerManager.setFoodLevel(0);
hungerManager.setSaturationLevel(0);
ItemStack foodStack = FoodGameInitializer.DAMAGE.getDefaultStack();
foodStack.setDamage(damage);
player.eatFood(player.getWorld(), foodStack.copy());
FoodComponent fc = Objects.requireNonNull(foodStack.getFoodComponent());
int foodActual = hungerManager.getFoodLevel();
int foodExpect = Math.min(20, fc.getHunger());
context.assertTrue(foodActual == foodExpect, "damage=%d, food actual %d, expect %d".formatted(damage, foodActual, foodExpect));
float satActual = hungerManager.getSaturationLevel();
float satExpect = Math.min(foodExpect, fc.getHunger() * fc.getSaturationModifier() * 2);
context.assertTrue(satActual == satExpect, "damage=%d, sat actual %f, expect %f".formatted(damage, satActual, satExpect));
}
context.complete();
}
@GameTest(templateName = EMPTY_STRUCTURE)
public void nameFoodTest(TestContext context) {
PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL);
HungerManager hungerManager = player.getHungerManager();
hungerManager.setFoodLevel(0);
hungerManager.setSaturationLevel(0);
ItemStack foodStack = FoodGameInitializer.NAME.getDefaultStack();
foodStack.set(DataComponentTypes.CUSTOM_NAME, Text.literal("enchanted_golden_apple"));
player.eatFood(player.getWorld(), foodStack.copy());
FoodComponent fc = FoodComponents.ENCHANTED_GOLDEN_APPLE;
int foodActual = hungerManager.getFoodLevel();
int foodExpect = Math.min(20, fc.getHunger());
context.assertTrue(foodActual == foodExpect, "enchanted_golden_apple, food actual %d, expect %d".formatted(foodActual, foodExpect));
float satActual = hungerManager.getSaturationLevel();
float satExpect = Math.min(foodExpect, fc.getHunger() * fc.getSaturationModifier() * 2);
context.assertTrue(satActual == satExpect, "enchanted_golden_apple, sat actual %f, expect %f".formatted(satActual, satExpect));
context.complete();
}
@GameTest(templateName = EMPTY_STRUCTURE)
public void nameMeatTest(TestContext context) {
PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL);
WolfEntity wolf = context.spawnEntity(EntityType.WOLF, context.getRelative(Vec3d.ZERO));
wolf.setTamed(true, true);
wolf.setOwner(player);
wolf.setHealth(1f);
ItemStack meat = FoodGameInitializer.NAME.getDefaultStack();
meat.set(DataComponentTypes.CUSTOM_NAME, Text.literal("mutton"));
player.setStackInHand(Hand.MAIN_HAND, meat);
player.interact(wolf, Hand.MAIN_HAND);
float wolfHealth = wolf.getHealth();
context.assertTrue(wolfHealth > 0, "actual %f, expect > 0".formatted(wolfHealth));
context.complete();
}
}

View file

@ -22,7 +22,7 @@ import net.minecraft.item.Items;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.RecipeType;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.test.GameTest;
import net.minecraft.test.GameTestException;
import net.minecraft.test.TestContext;
@ -79,7 +79,7 @@ public class RecipeGameTest implements FabricGameTest {
}
@Override
public ItemStack craft(SimpleInventory inventory, DynamicRegistryManager dynamicRegistryManager) {
public ItemStack craft(SimpleInventory inventory, RegistryWrapper.WrapperLookup wrapperLookup) {
return null;
}
@ -89,7 +89,7 @@ public class RecipeGameTest implements FabricGameTest {
}
@Override
public ItemStack getResult(DynamicRegistryManager registryManager) {
public ItemStack getResult(RegistryWrapper.WrapperLookup wrapperLookup) {
return null;
}

View file

@ -12,8 +12,7 @@
"main": [
"net.fabricmc.fabric.test.item.CustomDamageTest",
"net.fabricmc.fabric.test.item.ItemUpdateAnimationTest",
"net.fabricmc.fabric.test.item.ArmorKnockbackResistanceTest",
"net.fabricmc.fabric.test.item.FoodGameInitializer"
"net.fabricmc.fabric.test.item.ArmorKnockbackResistanceTest"
],
"client": [
"net.fabricmc.fabric.test.item.client.TooltipTests"
@ -21,8 +20,7 @@
"fabric-gametest" : [
"net.fabricmc.fabric.test.item.gametest.BrewingStandGameTest",
"net.fabricmc.fabric.test.item.gametest.FurnaceGameTest",
"net.fabricmc.fabric.test.item.gametest.RecipeGameTest",
"net.fabricmc.fabric.test.item.gametest.FoodGameTest"
"net.fabricmc.fabric.test.item.gametest.RecipeGameTest"
]
}
}

View file

@ -16,20 +16,26 @@
package net.fabricmc.fabric.mixin.event.lifecycle;
import org.spongepowered.asm.mixin.Final;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.class_9383;
import net.minecraft.server.DataPackContents;
import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents;
@Mixin(DataPackContents.class)
public class DataPackContentsMixin {
@Shadow
@Final
private class_9383.class_9385 field_49921;
@Inject(method = "refresh", at = @At("TAIL"))
private void hookRefresh(DynamicRegistryManager registries, CallbackInfo ci) {
CommonLifecycleEvents.TAGS_LOADED.invoker().onTagsLoaded(registries, false);
private void hookRefresh(CallbackInfo ci) {
CommonLifecycleEvents.TAGS_LOADED.invoker().onTagsLoaded(field_49921.method_58289(), false);
}
}

View file

@ -26,10 +26,11 @@ import net.minecraft.block.MapColor;
import net.minecraft.block.enums.Instrument;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.EntityType;
import net.minecraft.loot.LootTable;
import net.minecraft.registry.RegistryKey;
import net.minecraft.resource.featuretoggle.FeatureFlag;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.mixin.object.builder.AbstractBlockAccessor;
import net.fabricmc.fabric.mixin.object.builder.AbstractBlockSettingsAccessor;
@ -407,7 +408,7 @@ public class FabricBlockSettings extends AbstractBlock.Settings {
}
@Deprecated
public FabricBlockSettings drops(Identifier dropTableId) {
public FabricBlockSettings drops(RegistryKey<LootTable> dropTableId) {
((AbstractBlockSettingsAccessor) this).setLootTableId(dropTableId);
return this;
}

View file

@ -29,9 +29,10 @@ import net.minecraft.block.MapColor;
import net.minecraft.block.enums.Instrument;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.EntityType;
import net.minecraft.loot.LootTable;
import net.minecraft.registry.RegistryKey;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
@Mixin(AbstractBlock.Settings.class)
public interface AbstractBlockSettingsAccessor {
@ -100,7 +101,7 @@ public interface AbstractBlockSettingsAccessor {
Optional<AbstractBlock.Offsetter> getOffsetter();
@Accessor
Identifier getLootTableId();
RegistryKey<LootTable> getLootTableId();
@Accessor
boolean getBlockBreakParticles();
@ -149,7 +150,7 @@ public interface AbstractBlockSettingsAccessor {
void setIsAir(boolean isAir);
@Accessor
void setLootTableId(Identifier lootTableId);
void setLootTableId(RegistryKey<LootTable> lootTableId);
@Accessor
void setToolRequired(boolean toolRequired);

View file

@ -25,6 +25,7 @@ import java.util.Optional;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.WanderingTraderEntity;
import net.minecraft.item.Item;
@ -67,7 +68,7 @@ public class VillagerTypeTest1 implements ModInitializer {
builder.pool(
FOOD_POOL_ID,
5,
Registries.ITEM.stream().filter(item -> item.getFoodComponent() != null).map(
Registries.ITEM.stream().filter(item -> item.getDefaultStack().contains(DataComponentTypes.FOOD)).map(
item -> new SimpleTradeFactory(new TradeOffer(new TradedItem(Items.NETHERITE_INGOT), new ItemStack(item), 3, 4, 0.15F))
).toList()
);

View file

@ -25,7 +25,8 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.CombinedDynamicRegistries;
import net.minecraft.registry.ServerDynamicRegistryType;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.server.DataPackContents;
@ -43,7 +44,7 @@ public class DataPackContentsMixin {
method = "refresh",
at = @At("HEAD")
)
public void hookRefresh(DynamicRegistryManager dynamicRegistryManager, CallbackInfo ci) {
public void hookRefresh(CallbackInfo ci) {
ResourceConditionsImpl.LOADED_TAGS.remove();
ResourceConditionsImpl.CURRENT_REGISTRIES.remove();
}
@ -52,8 +53,8 @@ public class DataPackContentsMixin {
method = "reload",
at = @At("HEAD")
)
private static void hookReload(ResourceManager manager, DynamicRegistryManager.Immutable dynamicRegistryManager, FeatureSet enabledFeatures, CommandManager.RegistrationEnvironment environment, int functionPermissionLevel, Executor prepareExecutor, Executor applyExecutor, CallbackInfoReturnable<CompletableFuture<DataPackContents>> cir) {
private static void hookReload(ResourceManager manager, CombinedDynamicRegistries<ServerDynamicRegistryType> combinedDynamicRegistries, FeatureSet enabledFeatures, CommandManager.RegistrationEnvironment environment, int functionPermissionLevel, Executor prepareExecutor, Executor applyExecutor, CallbackInfoReturnable<CompletableFuture<DataPackContents>> cir) {
ResourceConditionsImpl.CURRENT_FEATURES.set(enabledFeatures);
ResourceConditionsImpl.CURRENT_REGISTRIES.set(dynamicRegistryManager);
ResourceConditionsImpl.CURRENT_REGISTRIES.set(combinedDynamicRegistries.getCombinedRegistryManager());
}
}

View file

@ -1,93 +0,0 @@
/*
* 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.resource.conditions;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.loot.LootDataType;
import net.minecraft.loot.LootManager;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions;
import net.fabricmc.fabric.impl.resource.conditions.ResourceConditionsImpl;
/**
* Starting with 1.20, LootManager directly implements ResourceReloader.
*/
@Mixin(LootManager.class)
public class LootManagerMixin {
// Keep track of the DynamicRegistryManager instance by assgining it to the map that is passed to the async runnable.
@Unique
private static final Map<Object, DynamicRegistryManager.Immutable> dynamicRegistryManagerMap = Collections.synchronizedMap(new IdentityHashMap<>());
@Inject(method = "load", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;runAsync(Ljava/lang/Runnable;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"))
private static void load(LootDataType type, RegistryWrapper.WrapperLookup wrapperLookup, ResourceManager resourceManager, Executor executor, Map<LootDataType<?>, Map<Identifier, ?>> results, CallbackInfoReturnable<CompletableFuture<?>> cir) {
dynamicRegistryManagerMap.put(results.get(type), ResourceConditionsImpl.CURRENT_REGISTRIES.get());
}
// runAsync Runnable in load method
@Inject(method = "method_51189", at = @At("HEAD"))
private static void runAsync(ResourceManager resourceManager, LootDataType lootDataType, RegistryOps registryOps, Map map, CallbackInfo ci) {
assert ResourceConditionsImpl.CURRENT_REGISTRIES.get() == null;
ResourceConditionsImpl.CURRENT_REGISTRIES.set(Objects.requireNonNull(dynamicRegistryManagerMap.remove(map)));
}
// forEach in load method
@Inject(method = "method_51195", at = @At("HEAD"), cancellable = true)
private static void applyResourceConditions(LootDataType lootDataType, RegistryOps registryOps, Map map, Identifier id, JsonElement json, CallbackInfo ci) {
if (json.isJsonObject()) {
JsonObject obj = json.getAsJsonObject();
if (obj.has(ResourceConditions.CONDITIONS_KEY)) {
boolean matched = ResourceConditions.objectMatchesConditions(obj);
if (!matched) {
ci.cancel();
}
if (ResourceConditionsImpl.LOGGER.isDebugEnabled()) {
String verdict = matched ? "Allowed" : "Rejected";
ResourceConditionsImpl.LOGGER.debug("{} resource of type {} with id {}", verdict, lootDataType.getId(), id);
}
}
}
}
// runAsync Runnable in load method
@Inject(method = "method_51189", at = @At("RETURN"))
private static void runAsyncEnd(ResourceManager resourceManager, LootDataType lootDataType, RegistryOps registryOps, Map map, CallbackInfo ci) {
ResourceConditionsImpl.CURRENT_REGISTRIES.remove();
}
}

View file

@ -6,7 +6,6 @@
"DataPackContentsMixin",
"DataProviderMixin",
"JsonDataLoaderMixin",
"LootManagerMixin",
"SinglePreparationResourceReloaderMixin",
"TagManagerLoaderMixin"
],

View file

@ -16,8 +16,6 @@
package net.fabricmc.fabric.test.resource.conditions;
import net.minecraft.loot.LootDataType;
import net.minecraft.loot.LootManager;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.test.GameTest;
import net.minecraft.test.TestContext;
@ -70,6 +68,7 @@ public class ConditionalResourcesTest {
context.complete();
}
/* TODO 1.20.5
@GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE)
public void conditionalPredicates(TestContext context) {
// Predicates are internally handled as a kind of loot data,
@ -101,5 +100,5 @@ public class ConditionalResourcesTest {
}
context.complete();
}
}*/
}

View file

@ -36,7 +36,6 @@ public final class ResourceReloadListenerKeys {
public static final Identifier RECIPES = new Identifier("minecraft:recipes");
public static final Identifier ADVANCEMENTS = new Identifier("minecraft:advancements");
public static final Identifier FUNCTIONS = new Identifier("minecraft:functions");
public static final Identifier LOOT_TABLES = new Identifier("minecraft:loot_tables");
private ResourceReloadListenerKeys() { }
}

View file

@ -22,7 +22,6 @@ import java.util.Locale;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.loot.LootManager;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.registry.tag.TagManagerLoader;
import net.minecraft.server.ServerAdvancementLoader;
@ -34,7 +33,7 @@ import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys;
@Mixin({
/* public */
RecipeManager.class, ServerAdvancementLoader.class, FunctionLoader.class, LootManager.class, TagManagerLoader.class
RecipeManager.class, ServerAdvancementLoader.class, FunctionLoader.class, TagManagerLoader.class
/* private */
})
public abstract class KeyedResourceReloadListenerMixin implements IdentifiableResourceReloadListener {
@ -53,8 +52,6 @@ public abstract class KeyedResourceReloadListenerMixin implements IdentifiableRe
this.fabric$id = ResourceReloadListenerKeys.ADVANCEMENTS;
} else if (self instanceof FunctionLoader) {
this.fabric$id = ResourceReloadListenerKeys.FUNCTIONS;
} else if (self instanceof LootManager) {
this.fabric$id = ResourceReloadListenerKeys.LOOT_TABLES;
} else if (self instanceof TagManagerLoader) {
this.fabric$id = ResourceReloadListenerKeys.TAGS;
} else {

View file

@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx2560M
org.gradle.parallel=true
fabric.loom.multiProjectOptimisation=true
version=0.96.11
minecraft_version=24w11a
version=0.96.12
minecraft_version=24w12a
yarn_version=+build.2
loader_version=0.15.6
installer_version=0.11.1
@ -13,7 +13,7 @@ curseforge_minecraft_version=1.20.5-Snapshot
# Do not manually update, use the bumpversions task:
fabric-api-base-version=0.4.38
fabric-api-lookup-api-v1-version=1.6.55
fabric-api-lookup-api-v1-version=1.6.56
fabric-biome-api-v1-version=13.0.20
fabric-block-api-v1-version=1.0.18
fabric-block-view-api-v2-version=1.0.6
@ -21,28 +21,28 @@ fabric-blockrenderlayer-v1-version=1.1.48
fabric-command-api-v1-version=1.2.43
fabric-command-api-v2-version=2.2.22
fabric-commands-v0-version=0.2.60
fabric-content-registries-v0-version=6.0.13
fabric-content-registries-v0-version=6.0.14
fabric-crash-report-info-v1-version=0.2.25
fabric-data-attachment-api-v1-version=1.1.8
fabric-data-generation-api-v1-version=17.0.5
fabric-data-attachment-api-v1-version=1.1.9
fabric-data-generation-api-v1-version=18.0.0
fabric-dimensions-v1-version=2.1.64
fabric-entity-events-v1-version=1.6.5
fabric-entity-events-v1-version=1.6.6
fabric-events-interaction-v0-version=0.7.4
fabric-events-lifecycle-v0-version=0.2.83
fabric-events-lifecycle-v0-version=0.2.84
fabric-game-rule-api-v1-version=1.0.48
fabric-gametest-api-v1-version=1.3.10
fabric-item-api-v1-version=5.0.3
fabric-item-group-api-v1-version=4.0.32
fabric-gametest-api-v1-version=1.3.11
fabric-item-api-v1-version=6.0.0
fabric-item-group-api-v1-version=4.0.33
fabric-key-binding-api-v1-version=1.0.43
fabric-keybindings-v0-version=0.2.41
fabric-lifecycle-events-v1-version=2.3.0
fabric-lifecycle-events-v1-version=2.3.1
fabric-loot-api-v2-version=2.1.13
fabric-message-api-v1-version=6.0.8
fabric-mining-level-api-v1-version=2.1.69
fabric-model-loading-api-v1-version=1.0.10
fabric-models-v0-version=0.4.9
fabric-networking-api-v1-version=4.0.5
fabric-object-builder-api-v1-version=14.0.9
fabric-object-builder-api-v1-version=15.0.0
fabric-particles-v1-version=2.0.0
fabric-recipe-api-v1-version=4.1.1
fabric-registry-sync-v0-version=5.0.10
@ -53,12 +53,12 @@ fabric-rendering-data-attachment-v1-version=0.3.44
fabric-rendering-fluids-v1-version=3.1.1
fabric-rendering-v0-version=1.1.61
fabric-rendering-v1-version=4.2.1
fabric-resource-conditions-api-v1-version=2.3.18
fabric-resource-loader-v0-version=0.11.24
fabric-resource-conditions-api-v1-version=3.0.0
fabric-resource-loader-v0-version=1.0.0
fabric-screen-api-v1-version=2.0.19
fabric-screen-handler-api-v1-version=1.3.67
fabric-sound-api-v1-version=1.0.19
fabric-transfer-api-v1-version=5.1.1
fabric-transfer-api-v1-version=5.1.2
fabric-transitive-access-wideners-v1-version=6.0.6
fabric-convention-tags-v1-version=1.5.13
fabric-convention-tags-v1-version=1.5.14
fabric-client-tags-api-v1-version=1.1.9

View file

@ -37,9 +37,9 @@ include 'fabric-item-api-v1'
include 'fabric-item-group-api-v1'
include 'fabric-key-binding-api-v1'
include 'fabric-lifecycle-events-v1'
include 'fabric-loot-api-v2'
//include 'fabric-loot-api-v2'
include 'fabric-message-api-v1'
include 'fabric-mining-level-api-v1'
//include 'fabric-mining-level-api-v1'
include 'fabric-model-loading-api-v1'
include 'fabric-networking-api-v1'
include 'fabric-object-builder-api-v1'