diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/BrewingRecipeRegistryBuilderCallback.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/BrewingRecipeRegistryBuilderCallback.java deleted file mode 100644 index f167a7700..000000000 --- a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/BrewingRecipeRegistryBuilderCallback.java +++ /dev/null @@ -1,43 +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.api.registry; - -import net.minecraft.recipe.BrewingRecipeRegistry; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; - -/** - * Use this event to register custom brewing recipes. - */ -public interface BrewingRecipeRegistryBuilderCallback { - /** - * An event that is called when the brewing recipe registry is being built. - */ - Event<BrewingRecipeRegistryBuilderCallback> BUILD = EventFactory.createArrayBacked(BrewingRecipeRegistryBuilderCallback.class, listeners -> builder -> { - for (BrewingRecipeRegistryBuilderCallback listener : listeners) { - listener.build(builder); - } - }); - - /** - * Called when the brewing recipe registry is being built. - * - * @param builder the {@link BrewingRecipeRegistry} instance - */ - void build(BrewingRecipeRegistry.class_9665 builder); -} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/FabricBrewingRecipeRegistryBuilder.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/FabricBrewingRecipeRegistryBuilder.java new file mode 100644 index 000000000..1f8d540a1 --- /dev/null +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/FabricBrewingRecipeRegistryBuilder.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.registry; + +import net.minecraft.item.Item; +import net.minecraft.potion.Potion; +import net.minecraft.recipe.BrewingRecipeRegistry; +import net.minecraft.recipe.Ingredient; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.resource.featuretoggle.FeatureSet; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; + +/** + * An extension of {@link BrewingRecipeRegistry.Builder} to support ingredients. + */ +public interface FabricBrewingRecipeRegistryBuilder { + /** + * An event that is called when the brewing recipe registry is being built. + */ + Event<FabricBrewingRecipeRegistryBuilder.BuildCallback> BUILD = EventFactory.createArrayBacked(FabricBrewingRecipeRegistryBuilder.BuildCallback.class, listeners -> builder -> { + for (FabricBrewingRecipeRegistryBuilder.BuildCallback listener : listeners) { + listener.build(builder); + } + }); + + default void registerItemRecipe(Item input, Ingredient ingredient, Item output) { + throw new AssertionError("Must be implemented via interface injection"); + } + + default void registerPotionRecipe(RegistryEntry<Potion> input, Ingredient ingredient, RegistryEntry<Potion> output) { + throw new AssertionError("Must be implemented via interface injection"); + } + + default void registerRecipes(Ingredient ingredient, RegistryEntry<Potion> potion) { + throw new AssertionError("Must be implemented via interface injection"); + } + + default FeatureSet getEnabledFeatures() { + throw new AssertionError("Must be implemented via interface injection"); + } + + /** + * Use this event to register custom brewing recipes. + */ + @FunctionalInterface + interface BuildCallback { + /** + * Called when the brewing recipe registry is being built. + * + * @param builder the {@link BrewingRecipeRegistry} instance + */ + void build(BrewingRecipeRegistry.Builder builder); + } +} diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/BrewingRecipeRegistryBuilderMixin.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/BrewingRecipeRegistryBuilderMixin.java index cf5c0f0c4..4c8596514 100644 --- a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/BrewingRecipeRegistryBuilderMixin.java +++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/mixin/content/registry/BrewingRecipeRegistryBuilderMixin.java @@ -16,19 +16,74 @@ package net.fabricmc.fabric.mixin.content.registry; +import java.util.List; + +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.CallbackInfoReturnable; +import net.minecraft.item.Item; +import net.minecraft.potion.Potion; +import net.minecraft.potion.Potions; import net.minecraft.recipe.BrewingRecipeRegistry; +import net.minecraft.recipe.Ingredient; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.resource.featuretoggle.FeatureSet; -import net.fabricmc.fabric.api.registry.BrewingRecipeRegistryBuilderCallback; +import net.fabricmc.fabric.api.registry.FabricBrewingRecipeRegistryBuilder; -@Mixin(BrewingRecipeRegistry.class_9665.class) -public class BrewingRecipeRegistryBuilderMixin { - @Inject(method = "method_59701", at = @At("HEAD")) +@Mixin(BrewingRecipeRegistry.Builder.class) +public abstract class BrewingRecipeRegistryBuilderMixin implements FabricBrewingRecipeRegistryBuilder { + @Shadow + @Final + private FeatureSet enabledFeatures; + + @Shadow + private static void assertPotion(Item potionType) { + } + + @Shadow + @Final + private List<BrewingRecipeRegistry.Recipe<Item>> itemRecipes; + + @Shadow + @Final + private List<BrewingRecipeRegistry.Recipe<Potion>> potionRecipes; + + @Inject(method = "build", at = @At("HEAD")) private void build(CallbackInfoReturnable<BrewingRecipeRegistry> cir) { - BrewingRecipeRegistryBuilderCallback.BUILD.invoker().build((BrewingRecipeRegistry.class_9665) (Object) this); + FabricBrewingRecipeRegistryBuilder.BUILD.invoker().build((BrewingRecipeRegistry.Builder) (Object) this); + } + + @Override + public void registerItemRecipe(Item input, Ingredient ingredient, Item output) { + if (input.isEnabled(this.enabledFeatures) && output.isEnabled(this.enabledFeatures)) { + assertPotion(input); + assertPotion(output); + this.itemRecipes.add(new BrewingRecipeRegistry.Recipe<>(input.getRegistryEntry(), ingredient, output.getRegistryEntry())); + } + } + + @Override + public void registerPotionRecipe(RegistryEntry<Potion> input, Ingredient ingredient, RegistryEntry<Potion> output) { + if (input.value().isEnabled(this.enabledFeatures) && output.value().isEnabled(this.enabledFeatures)) { + this.potionRecipes.add(new BrewingRecipeRegistry.Recipe<>(input, ingredient, output)); + } + } + + @Override + public void registerRecipes(Ingredient ingredient, RegistryEntry<Potion> potion) { + if (potion.value().isEnabled(this.enabledFeatures)) { + this.registerPotionRecipe(Potions.WATER, ingredient, Potions.MUNDANE); + this.registerPotionRecipe(Potions.AWKWARD, ingredient, potion); + } + } + + @Override + public FeatureSet getEnabledFeatures() { + return this.enabledFeatures; } } diff --git a/fabric-content-registries-v0/src/main/resources/fabric.mod.json b/fabric-content-registries-v0/src/main/resources/fabric.mod.json index 3b6958e48..8820f2a84 100644 --- a/fabric-content-registries-v0/src/main/resources/fabric.mod.json +++ b/fabric-content-registries-v0/src/main/resources/fabric.mod.json @@ -27,6 +27,9 @@ ], "accessWidener" : "fabric-content-registries-v0.accesswidener", "custom": { - "fabric-api:module-lifecycle": "stable" + "fabric-api:module-lifecycle": "stable", + "loom:injected_interfaces": { + "net/minecraft/class_1845\u0024class_9665": ["net/fabricmc/fabric/api/registry/FabricBrewingRecipeRegistryBuilder"] + } } } diff --git a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java index b42c7772e..ecd347be5 100644 --- a/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java +++ b/fabric-content-registries-v0/src/testmod/java/net/fabricmc/fabric/test/content/registry/ContentRegistryTest.java @@ -30,6 +30,8 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.PotionItem; +import net.minecraft.potion.Potions; +import net.minecraft.recipe.Ingredient; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; @@ -37,6 +39,7 @@ import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.ItemTags; +import net.minecraft.resource.featuretoggle.FeatureFlags; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; @@ -47,8 +50,8 @@ import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.registry.BrewingRecipeRegistryBuilderCallback; import net.fabricmc.fabric.api.registry.CompostingChanceRegistry; +import net.fabricmc.fabric.api.registry.FabricBrewingRecipeRegistryBuilder; import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; import net.fabricmc.fabric.api.registry.FlattenableBlockRegistry; import net.fabricmc.fabric.api.registry.FuelRegistry; @@ -84,6 +87,7 @@ public final class ContentRegistryTest implements ModInitializer { // - assign a loot table to the nitwit villager type // - right-clicking a 'test_event' block will emit a 'test_event' game event, which will have a sculk sensor frequency of 2 // - instant health potions can be brewed from awkward potions with any item in the 'minecraft:small_flowers' tag + // - if Bundle experiment is enabled, luck potions can be brewed from awkward potions with a bundle // - dirty potions can be brewed by adding any item in the 'minecraft:dirt' tag to any standard potion CompostingChanceRegistry.INSTANCE.add(Items.OBSIDIAN, 0.5F); @@ -156,11 +160,14 @@ public final class ContentRegistryTest implements ModInitializer { dirtyPotion); /* Mods should use BrewingRecipeRegistry.registerPotionType(Item), which is access widened by fabric-transitive-access-wideners-v1 * This testmod uses an accessor due to Loom limitations that prevent TAWs from applying across Gradle subproject boundaries */ - BrewingRecipeRegistryBuilderCallback.BUILD.register(builder -> { - builder.method_59702(dirtyPotion); - // TODO 1.20.5 Ingredient.fromTag(ItemTags.DIRT) - builder.method_59703(Items.POTION, Items.DIRT, dirtyPotion); - // registerPotionRecipe(Potions.AWKWARD, Ingredient.fromTag(ItemTags.SMALL_FLOWERS), Potions.HEALING); + FabricBrewingRecipeRegistryBuilder.BUILD.register(builder -> { + builder.registerPotionType(dirtyPotion); + builder.registerItemRecipe(Items.POTION, Ingredient.fromTag(ItemTags.DIRT), dirtyPotion); + builder.registerPotionRecipe(Potions.AWKWARD, Ingredient.fromTag(ItemTags.SMALL_FLOWERS), Potions.HEALING); + + if (builder.getEnabledFeatures().contains(FeatureFlags.BUNDLE)) { + builder.registerPotionRecipe(Potions.AWKWARD, Ingredient.ofItems(Items.BUNDLE), Potions.LUCK); + } }); } diff --git a/fabric-events-interaction-v0/src/client/java/net/fabricmc/fabric/api/event/client/player/ClientPlayerBlockBreakEvents.java b/fabric-events-interaction-v0/src/client/java/net/fabricmc/fabric/api/event/client/player/ClientPlayerBlockBreakEvents.java index d817088c3..ecefa3549 100644 --- a/fabric-events-interaction-v0/src/client/java/net/fabricmc/fabric/api/event/client/player/ClientPlayerBlockBreakEvents.java +++ b/fabric-events-interaction-v0/src/client/java/net/fabricmc/fabric/api/event/client/player/ClientPlayerBlockBreakEvents.java @@ -30,7 +30,10 @@ import net.fabricmc.fabric.api.event.EventFactory; * <p>For preventing block breaking client side and other purposes, see {@link net.fabricmc.fabric.api.event.player.AttackBlockCallback}. * For server side block break events, see {@link net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents}. */ -public class ClientPlayerBlockBreakEvents { +public final class ClientPlayerBlockBreakEvents { + private ClientPlayerBlockBreakEvents() { + } + /** * Callback after a block is broken client side. * diff --git a/fabric-events-interaction-v0/src/main/java/net/fabricmc/fabric/api/event/player/UseEntityCallback.java b/fabric-events-interaction-v0/src/main/java/net/fabricmc/fabric/api/event/player/UseEntityCallback.java index 0a2e73d45..cf892d7fb 100644 --- a/fabric-events-interaction-v0/src/main/java/net/fabricmc/fabric/api/event/player/UseEntityCallback.java +++ b/fabric-events-interaction-v0/src/main/java/net/fabricmc/fabric/api/event/player/UseEntityCallback.java @@ -34,7 +34,7 @@ import net.fabricmc.fabric.api.event.EventFactory; * * <p>On the logical client, the return values have the following meaning: * <ul> - * <li>SUCCESS cancels further processing, causes a hand swing, and sends a packet to the server.</li> + * <li>SUCCESS/SUCCESS_NO_ITEM_USED cancels further processing, causes a hand swing, and sends a packet to the server.</li> * <li>CONSUME cancels further processing, and sends a packet to the server. It does NOT cause a hand swing.</li> * <li>PASS falls back to further processing.</li> * <li>FAIL cancels further processing and does not send a packet to the server.</li> diff --git a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/EnchantingContext.java b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/EnchantingContext.java index 8b5520989..7e139710e 100644 --- a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/EnchantingContext.java +++ b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/EnchantingContext.java @@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.item.v1; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.item.ItemStack; +import net.minecraft.resource.featuretoggle.FeatureSet; import net.minecraft.util.math.random.Random; /* @@ -36,7 +37,7 @@ public enum EnchantingContext { * When generating a random enchantment for the item. This includes the enchanting table, random * mob equipment, and the {@code enchant_with_levels} loot function. * - * @see EnchantmentHelper#generateEnchantments(Random, ItemStack, int, boolean) + * @see EnchantmentHelper#generateEnchantments(FeatureSet, Random, ItemStack, int, boolean) */ RANDOM_ENCHANTMENT, /** diff --git a/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/CustomDamageTest.java b/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/CustomDamageTest.java index 1b39db7f4..80389272f 100644 --- a/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/CustomDamageTest.java +++ b/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/CustomDamageTest.java @@ -26,6 +26,7 @@ import net.minecraft.item.Items; import net.minecraft.item.PickaxeItem; import net.minecraft.item.ToolMaterials; import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.potion.Potions; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.text.Text; @@ -36,6 +37,7 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.item.v1.CustomDamageHandler; import net.fabricmc.fabric.api.item.v1.EnchantingContext; import net.fabricmc.fabric.api.item.v1.EnchantmentEvents; +import net.fabricmc.fabric.api.registry.FabricBrewingRecipeRegistryBuilder; import net.fabricmc.fabric.api.registry.FuelRegistry; import net.fabricmc.fabric.api.util.TriState; @@ -58,8 +60,7 @@ public class CustomDamageTest implements ModInitializer { public void onInitialize() { Registry.register(Registries.ITEM, new Identifier("fabric-item-api-v1-testmod", "weird_pickaxe"), WEIRD_PICK); FuelRegistry.INSTANCE.add(WEIRD_PICK, 200); - // TODO 1.20.5 - // FabricBrewingRecipeRegistry.registerPotionRecipe(Potions.WATER, Ingredient.ofItems(WEIRD_PICK), Potions.AWKWARD); + FabricBrewingRecipeRegistryBuilder.BUILD.register(builder -> builder.registerPotionRecipe(Potions.WATER, WEIRD_PICK, Potions.AWKWARD)); EnchantmentEvents.ALLOW_ENCHANTING.register(((enchantment, target, enchantingContext) -> { if (target.isOf(Items.DIAMOND_PICKAXE) && enchantment == Enchantments.SHARPNESS diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/CommonLifecycleEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/CommonLifecycleEvents.java index 8c3f9a82e..27750b653 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/CommonLifecycleEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/CommonLifecycleEvents.java @@ -21,7 +21,7 @@ import net.minecraft.registry.DynamicRegistryManager; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; -public class CommonLifecycleEvents { +public final class CommonLifecycleEvents { private CommonLifecycleEvents() { } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java index 2da45120a..455382f87 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricDefaultAttributeRegistry.java @@ -71,11 +71,11 @@ public final class FabricDefaultAttributeRegistry { * <p>If a registration overrides another, a debug log message will be emitted. Existing registrations * can be checked at {@link net.minecraft.entity.attribute.DefaultAttributeRegistry#hasDefinitionFor(EntityType)}.</p> * - * <p>For convenience, this can also be done on the {@link FabricEntityTypeBuilder} to simplify the building process. + * <p>For convenience, this can also be done on the {@link FabricEntityType.Builder} to simplify the building process. * * @param type the entity type * @param container the container for the default attribute - * @see FabricEntityTypeBuilder.Living#defaultAttributes(Supplier) + * @see FabricEntityType.Builder.Living#defaultAttributes(Supplier) */ public static void register(EntityType<? extends LivingEntity> type, DefaultAttributeContainer container) { if (DefaultAttributeRegistryAccessor.getRegistry().put(type, container) != null) { diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java index 9c0c93e07..d0bcb2964 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java @@ -115,7 +115,7 @@ public class FabricEntityTypeBuilder<T extends Entity> { * @param <T> the type of entity * * @return a new living entity type builder - * @deprecated use {@link FabricEntityType.Builder#createLiving(UnaryOperator)} + * @deprecated use {@link FabricEntityType.Builder#createLiving(EntityType.EntityFactory, SpawnGroup, UnaryOperator)} */ @Deprecated public static <T extends LivingEntity> FabricEntityTypeBuilder.Living<T> createLiving() { @@ -128,7 +128,7 @@ public class FabricEntityTypeBuilder<T extends Entity> { * @param <T> the type of entity * * @return a new mob entity type builder - * @deprecated use {@link FabricEntityType.Builder#createMob(UnaryOperator)} + * @deprecated use {@link FabricEntityType.Builder#createMob(EntityType.EntityFactory, SpawnGroup, UnaryOperator)} */ public static <T extends MobEntity> FabricEntityTypeBuilder.Mob<T> createMob() { return new FabricEntityTypeBuilder.Mob<>(SpawnGroup.MISC, FabricEntityTypeBuilder::emptyFactory); @@ -203,7 +203,7 @@ public class FabricEntityTypeBuilder<T extends Entity> { * @param dimensions the dimensions representing the entity's size * * @return this builder for chaining - * @deprecated use {@link EntityType.Builder#setDimensions(float, float)} + * @deprecated use {@link EntityType.Builder#dimensions(float, float)} */ @Deprecated public FabricEntityTypeBuilder<T> dimensions(EntityDimensions dimensions) { @@ -347,7 +347,7 @@ public class FabricEntityTypeBuilder<T extends Entity> { * An extended version of {@link FabricEntityTypeBuilder} with support for features on present on {@link LivingEntity living entities}, such as default attributes. * * @param <T> Entity class. - * @deprecated use {@link EntityType.Builder#createLiving(UnaryOperator)} + * @deprecated use {@link EntityType.Builder#createLiving(EntityType.EntityFactory, SpawnGroup, UnaryOperator)} */ @Deprecated public static class Living<T extends LivingEntity> extends FabricEntityTypeBuilder<T> { @@ -606,7 +606,7 @@ public class FabricEntityTypeBuilder<T extends Entity> { * <p>This is used by mobs to determine whether Minecraft should spawn an entity within a certain context. * * @return this builder for chaining. - * @deprecated use {@link FabricEntityType.Builder.Mob#spawnRestriction(SpawnRestriction.Location, Heightmap.Type, SpawnRestriction.SpawnPredicate)} + * @deprecated use {@link FabricEntityType.Builder.Mob#spawnRestriction(SpawnLocation, Heightmap.Type, SpawnRestriction.SpawnPredicate)} */ @Deprecated public FabricEntityTypeBuilder.Mob<T> spawnRestriction(SpawnLocation spawnLocation, Heightmap.Type heightmap, SpawnRestriction.SpawnPredicate<T> spawnPredicate) { diff --git a/fabric-particles-v1/src/client/java/net/fabricmc/fabric/api/client/particle/v1/ParticleFactoryRegistry.java b/fabric-particles-v1/src/client/java/net/fabricmc/fabric/api/client/particle/v1/ParticleFactoryRegistry.java index 7cd96a156..9fa32b16b 100644 --- a/fabric-particles-v1/src/client/java/net/fabricmc/fabric/api/client/particle/v1/ParticleFactoryRegistry.java +++ b/fabric-particles-v1/src/client/java/net/fabricmc/fabric/api/client/particle/v1/ParticleFactoryRegistry.java @@ -16,6 +16,8 @@ package net.fabricmc.fabric.api.client.particle.v1; +import org.jetbrains.annotations.ApiStatus; + import net.minecraft.client.particle.ParticleFactory; import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleType; @@ -29,6 +31,7 @@ import net.fabricmc.fabric.impl.client.particle.ParticleFactoryRegistryImpl; * * @see FabricParticleTypes */ +@ApiStatus.NonExtendable public interface ParticleFactoryRegistry { static ParticleFactoryRegistry getInstance() { return ParticleFactoryRegistryImpl.INSTANCE; diff --git a/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java b/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java index e6258ecca..e39aa1988 100644 --- a/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java +++ b/fabric-particles-v1/src/main/java/net/fabricmc/fabric/api/particle/v1/FabricParticleTypes.java @@ -18,14 +18,13 @@ package net.fabricmc.fabric.api.particle.v1; import java.util.function.Function; -import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; -import net.minecraft.particle.DefaultParticleType; import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleType; +import net.minecraft.particle.SimpleParticleType; /** * Methods for creating particle types, both simple and using an existing attribute factory. @@ -33,8 +32,8 @@ import net.minecraft.particle.ParticleType; * <p>Usage: * <blockquote> * <pre> - * public static final DefaultParticleType SIMPLE_TEST_PARTICLE = FabricParticleTypes.simple(); - * public static final DefaultParticleType CUSTOM_TEST_PARTICLE = FabricParticleTypes.simple(); + * public static final SimpleParticleType SIMPLE_TEST_PARTICLE = FabricParticleTypes.simple(); + * public static final SimpleParticleType CUSTOM_TEST_PARTICLE = FabricParticleTypes.simple(); * * {@literal @}Override * public void onInitialize() { @@ -50,7 +49,7 @@ public final class FabricParticleTypes { /** * Creates a new, default particle type for the given id. */ - public static DefaultParticleType simple() { + public static SimpleParticleType simple() { return simple(false); } @@ -59,31 +58,29 @@ public final class FabricParticleTypes { * * @param alwaysSpawn True to always spawn the particle regardless of distance. */ - public static DefaultParticleType simple(boolean alwaysSpawn) { - return new DefaultParticleType(alwaysSpawn) { }; + public static SimpleParticleType simple(boolean alwaysSpawn) { + return new SimpleParticleType(alwaysSpawn) { }; } /** * Creates a new particle type with a custom factory and codecs for packet/data serialization. * - * @param factory A factory for serializing string command parameters into a particle effect. * @param codec The codec for serialization. * @param packetCodec The packet codec for network serialization. */ - public static <T extends ParticleEffect> ParticleType<T> complex(ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, Codec<T>> codecGetter, final MapCodec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) { - return complex(false, factory, codec, packetCodec); + public static <T extends ParticleEffect> ParticleType<T> complex(final MapCodec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) { + return complex(false, codec, packetCodec); } /** * Creates a new particle type with a custom factory and codecs for packet/data serialization. * * @param alwaysSpawn True to always spawn the particle regardless of distance. - * @param factory A factory for serializing string command parameters into a particle effect. * @param codec The codec for serialization. * @param packetCodec The packet codec for network serialization. */ - public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, ParticleEffect.Factory<T> factory, final MapCodec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) { - return new ParticleType<T>(alwaysSpawn, factory) { + public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, final MapCodec<T> codec, final PacketCodec<? super RegistryByteBuf, T> packetCodec) { + return new ParticleType<>(alwaysSpawn) { @Override public MapCodec<T> getCodec() { return codec; @@ -100,12 +97,11 @@ public final class FabricParticleTypes { * Creates a new particle type with a custom factory and codecs for packet/data serialization. * This method is useful when two different {@link ParticleType}s share the same {@link ParticleEffect} implementation. * - * @param factory A factory for serializing string command parameters into a particle effect. * @param codecGetter A function that, given the newly created type, returns the codec for serialization. * @param packetCodecGetter A function that, given the newly created type, returns the packet codec for network serialization. */ - public static <T extends ParticleEffect> ParticleType<T> complex(ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, MapCodec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) { - return complex(false, factory, codecGetter, packetCodecGetter); + public static <T extends ParticleEffect> ParticleType<T> complex(final Function<ParticleType<T>, MapCodec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) { + return complex(false, codecGetter, packetCodecGetter); } /** @@ -113,12 +109,11 @@ public final class FabricParticleTypes { * This method is useful when two different {@link ParticleType}s share the same {@link ParticleEffect} implementation. * * @param alwaysSpawn True to always spawn the particle regardless of distance. - * @param factory A factory for serializing string command parameters into a particle effect. * @param codecGetter A function that, given the newly created type, returns the codec for serialization. * @param packetCodecGetter A function that, given the newly created type, returns the packet codec for network serialization. */ - public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, ParticleEffect.Factory<T> factory, final Function<ParticleType<T>, MapCodec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) { - return new ParticleType<T>(alwaysSpawn, factory) { + public static <T extends ParticleEffect> ParticleType<T> complex(boolean alwaysSpawn, final Function<ParticleType<T>, MapCodec<T>> codecGetter, final Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter) { + return new ParticleType<>(alwaysSpawn) { @Override public MapCodec<T> getCodec() { return codecGetter.apply(this); diff --git a/fabric-particles-v1/src/testmod/java/net/fabricmc/fabric/test/particle/ParticleTestSetup.java b/fabric-particles-v1/src/testmod/java/net/fabricmc/fabric/test/particle/ParticleTestSetup.java index a6869df03..dc6b92fe1 100644 --- a/fabric-particles-v1/src/testmod/java/net/fabricmc/fabric/test/particle/ParticleTestSetup.java +++ b/fabric-particles-v1/src/testmod/java/net/fabricmc/fabric/test/particle/ParticleTestSetup.java @@ -48,7 +48,7 @@ public final class ParticleTestSetup implements ModInitializer { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { dispatcher.register(CommandManager.literal("addparticletestblocks").executes(context -> { - PlayerInventory inventory = context.getSource().getPlayer().getInventory(); + PlayerInventory inventory = context.getSource().getPlayerOrThrow().getInventory(); inventory.offerOrDrop(new ItemStack(ALWAYS_TINTED)); inventory.offerOrDrop(new ItemStack(TINTED_OVER_WATER)); inventory.offerOrDrop(new ItemStack(NEVER_TINTED)); diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java index b2962f61a..8a8f9786e 100644 --- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java +++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/builtin/CustomDataIngredient.java @@ -19,10 +19,7 @@ package net.fabricmc.fabric.impl.recipe.ingredient.builtin; import java.util.ArrayList; import java.util.List; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -94,17 +91,6 @@ public class CustomDataIngredient implements CustomIngredient { private static class Serializer implements CustomIngredientSerializer<CustomDataIngredient> { private static final Identifier ID = new Identifier("fabric", "custom_data"); - // Supports decoding the NBT as a string as well as the object. - private static final Codec<NbtCompound> NBT_CODEC = Codec.xor( - Codec.STRING, NbtCompound.CODEC - ).flatXmap(either -> either.map(s -> { - try { - return DataResult.success(StringNbtReader.parse(s)); - } catch (CommandSyntaxException e) { - return DataResult.error(e::getMessage); - } - }, DataResult::success), nbtCompound -> DataResult.success(Either.left(nbtCompound.asString()))); - private static final MapCodec<CustomDataIngredient> ALLOW_EMPTY_CODEC = createCodec(Ingredient.ALLOW_EMPTY_CODEC); private static final MapCodec<CustomDataIngredient> DISALLOW_EMPTY_CODEC = createCodec(Ingredient.DISALLOW_EMPTY_CODEC); @@ -118,7 +104,7 @@ public class CustomDataIngredient implements CustomIngredient { return RecordCodecBuilder.mapCodec(instance -> instance.group( ingredientCodec.fieldOf("base").forGetter(CustomDataIngredient::getBase), - NBT_CODEC.fieldOf("nbt").forGetter(CustomDataIngredient::getNbt) + StringNbtReader.NBT_COMPOUND_CODEC.fieldOf("nbt").forGetter(CustomDataIngredient::getNbt) ).apply(instance, CustomDataIngredient::new) ); } diff --git a/fabric-sound-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/sound/client/SineStream.java b/fabric-sound-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/sound/client/SineStream.java index 2d4fd4af4..3bfd628e9 100644 --- a/fabric-sound-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/sound/client/SineStream.java +++ b/fabric-sound-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/sound/client/SineStream.java @@ -39,7 +39,7 @@ class SineStream implements AudioStream { } @Override - public ByteBuffer getBuffer(int capacity) { + public ByteBuffer read(int capacity) { ByteBuffer buffer = BufferUtils.createByteBuffer(capacity); for (int i = 0; i < capacity; i++) { diff --git a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java index 1ec91fa30..f8cc74ced 100644 --- a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java +++ b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/impl/transfer/VariantCodecs.java @@ -17,9 +17,12 @@ package net.fabricmc.fabric.impl.transfer; import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMapImpl; +import net.minecraft.item.ItemStack; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; @@ -32,11 +35,13 @@ import net.fabricmc.fabric.impl.transfer.fluid.FluidVariantImpl; import net.fabricmc.fabric.impl.transfer.item.ItemVariantImpl; public class VariantCodecs { - public static final Codec<ItemVariant> ITEM_CODEC = RecordCodecBuilder.create(instance -> instance.group( + // AIR is valid (for some reason), don't use ItemStack#ITEM_CODEC + private static final Codec<ItemVariant> UNVALIDATED_ITEM_CODEC = RecordCodecBuilder.create(instance -> instance.group( Registries.ITEM.getEntryCodec().fieldOf("item").forGetter(ItemVariant::getRegistryEntry), ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(ItemVariant::getComponents) ).apply(instance, ItemVariantImpl::of) ); + public static final Codec<ItemVariant> ITEM_CODEC = UNVALIDATED_ITEM_CODEC.validate(VariantCodecs::validateComponents); public static final PacketCodec<RegistryByteBuf, ItemVariant> ITEM_PACKET_CODEC = PacketCodec.tuple( PacketCodecs.registryEntry(RegistryKeys.ITEM), ItemVariant::getRegistryEntry, ComponentChanges.PACKET_CODEC, ItemVariant::getComponents, @@ -53,4 +58,8 @@ public class VariantCodecs { ComponentChanges.PACKET_CODEC, FluidVariant::getComponents, FluidVariantImpl::of ); + + private static DataResult<ItemVariant> validateComponents(ItemVariant variant) { + return ItemStack.validateComponents(ComponentMapImpl.create(variant.getItem().getComponents(), variant.getComponents())).map(v -> variant); + } } diff --git a/gradle.properties b/gradle.properties index ed36cce09..17bd06b32 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,9 +4,9 @@ fabric.loom.multiProjectOptimisation=true version=0.96.15 minecraft_version=1.20.5-pre1 -yarn_version=+build.2 +yarn_version=+build.5 loader_version=0.15.6 -installer_version=0.11.1 +installer_version=1.0.1 prerelease=true curseforge_minecraft_version=1.20.5-Snapshot diff --git a/settings.gradle b/settings.gradle index 9be28e117..3e01c0569 100644 --- a/settings.gradle +++ b/settings.gradle @@ -42,7 +42,7 @@ include 'fabric-message-api-v1' include 'fabric-model-loading-api-v1' include 'fabric-networking-api-v1' include 'fabric-object-builder-api-v1' -//include 'fabric-particles-v1' +include 'fabric-particles-v1' include 'fabric-recipe-api-v1' include 'fabric-registry-sync-v0' include 'fabric-renderer-api-v1'