mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-21 03:10:54 -04:00
24w12a (#3658)
# 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:
parent
3a09d40a83
commit
e9d2a72b4f
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
api/datagen/v1/provider
impl/datagen/loot
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
main
java/net/fabricmc/fabric
api/item/v1
mixin/item
resources
testmod
java/net/fabricmc/fabric/test/item
resources
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
java/net/fabricmc/fabric/mixin/resource/conditions
resources
testmod/java/net/fabricmc/fabric/test/resource/conditions
fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric
api/resource
mixin/resource/loader
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
"DataPackContentsMixin",
|
||||
"DataProviderMixin",
|
||||
"JsonDataLoaderMixin",
|
||||
"LootManagerMixin",
|
||||
"SinglePreparationResourceReloaderMixin",
|
||||
"TagManagerLoaderMixin"
|
||||
],
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -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() { }
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue