From 85f102ee1a51ff8b026000a2c118d9e8c97adf36 Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Mon, 2 Jan 2023 22:05:10 +0900 Subject: [PATCH] Object builder API updates (#2798) * Add feature support to FabricEntityTypeBuilder * Use IdentityHashMap for EntityType-keyed maps * Improve tests * Update fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityTypeBuilder.java Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com> * Fix naming of static-final field * Address some reviews * Rebuild * Split gametest * Update fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com> --- .../builder/v1/block/FabricBlockSettings.java | 8 ++++ .../v1/entity/FabricEntityTypeBuilder.java | 24 +++++++---- .../MinecartComparatorLogicRegistry.java | 14 ++++--- .../builder/v1/trade/TradeOfferHelper.java | 2 +- .../DefaultAttributeRegistryMixin.java | 4 +- .../builder/BlockEntityTypeBuilderTest.java | 12 +++--- .../object/builder/ObjectBuilderGameTest.java | 42 +++++++++++++++++++ .../object/builder/VillagerTypeTest1.java | 6 --- .../src/testmod/resources/fabric.mod.json | 3 ++ 9 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/ObjectBuilderGameTest.java diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/FabricBlockSettings.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/FabricBlockSettings.java index f76991d6a..a3478d428 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/FabricBlockSettings.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/FabricBlockSettings.java @@ -48,6 +48,10 @@ public class FabricBlockSettings extends AbstractBlock.Settings { super(material, color); } + protected FabricBlockSettings(Material material, Function<BlockState, MapColor> mapColorProvider) { + super(material, mapColorProvider); + } + protected FabricBlockSettings(AbstractBlock.Settings settings) { super(((AbstractBlockSettingsAccessor) settings).getMaterial(), ((AbstractBlockSettingsAccessor) settings).getMapColorProvider()); // Mostly Copied from vanilla's copy method @@ -97,6 +101,10 @@ public class FabricBlockSettings extends AbstractBlock.Settings { return new FabricBlockSettings(material, color.getMapColor()); } + public static FabricBlockSettings of(Material material, Function<BlockState, MapColor> mapColor) { + return new FabricBlockSettings(material, mapColor); + } + public static FabricBlockSettings copyOf(AbstractBlock block) { return new FabricBlockSettings(((AbstractBlockAccessor) block).getSettings()); } 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 1e0f101cc..843e5bbbf 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 @@ -31,7 +31,9 @@ import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.SpawnRestriction; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.resource.featuretoggle.FeatureFlag; import net.minecraft.resource.featuretoggle.FeatureFlags; +import net.minecraft.resource.featuretoggle.FeatureSet; import net.minecraft.world.Heightmap; import net.minecraft.world.World; @@ -56,6 +58,8 @@ public class FabricEntityTypeBuilder<T extends Entity> { private EntityDimensions dimensions = EntityDimensions.changing(-1.0f, -1.0f); private ImmutableSet<Block> specificSpawnBlocks = ImmutableSet.of(); + private FeatureSet requiredFeatures = FeatureFlags.VANILLA_FEATURES; + protected FabricEntityTypeBuilder(SpawnGroup spawnGroup, EntityType.EntityFactory<T> factory) { this.spawnGroup = spawnGroup; this.factory = factory; @@ -251,20 +255,26 @@ public class FabricEntityTypeBuilder<T extends Entity> { return this; } + /** + * Sets the features this entity requires. If a feature is not enabled, + * the entity cannot be spawned, and existing ones will despawn immediately. + * @param requiredFeatures the features + * @return this builder for chaining + */ + public FabricEntityTypeBuilder<T> requires(FeatureFlag... requiredFeatures) { + this.requiredFeatures = FeatureFlags.FEATURE_MANAGER.featureSetOf(requiredFeatures); + return this; + } + /** * Creates the entity type. * * @return a new {@link EntityType} */ public EntityType<T> build() { - if (this.saveable) { - // SNIP! Modded datafixers are not supported anyway. - // TODO: Flesh out once modded datafixers exist. - } + // Modded DFU is a dream, currently not possible without screwing it up. - EntityType<T> type = new FabricEntityType<>(this.factory, this.spawnGroup, this.saveable, this.summonable, this.fireImmune, this.spawnableFarFromPlayer, this.specificSpawnBlocks, dimensions, trackRange, trackedUpdateRate, forceTrackedVelocityUpdates, FeatureFlags.DEFAULT_ENABLED_FEATURES); - - return type; + return new FabricEntityType<>(this.factory, this.spawnGroup, this.saveable, this.summonable, this.fireImmune, this.spawnableFarFromPlayer, this.specificSpawnBlocks, dimensions, trackRange, trackedUpdateRate, forceTrackedVelocityUpdates, this.requiredFeatures); } /** diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java index cef89dd45..5270229a3 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/MinecartComparatorLogicRegistry.java @@ -16,23 +16,24 @@ package net.fabricmc.fabric.api.object.builder.v1.entity; -import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.Map; +import java.util.Objects; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.minecraft.registry.Registries; import net.minecraft.entity.EntityType; import net.minecraft.entity.vehicle.AbstractMinecartEntity; +import net.minecraft.registry.Registries; /** * A registry for {@linkplain MinecartComparatorLogic custom minecart comparator logic}. */ public final class MinecartComparatorLogicRegistry { private static final Logger LOGGER = LoggerFactory.getLogger(MinecartComparatorLogicRegistry.class); - private static final Map<EntityType<?>, MinecartComparatorLogic<?>> logics = new HashMap<>(); + private static final Map<EntityType<?>, MinecartComparatorLogic<?>> LOGICS = new IdentityHashMap<>(); private MinecartComparatorLogicRegistry() { } @@ -46,7 +47,7 @@ public final class MinecartComparatorLogicRegistry { @Nullable @SuppressWarnings("unchecked") public static MinecartComparatorLogic<AbstractMinecartEntity> getCustomComparatorLogic(EntityType<?> type) { - return (MinecartComparatorLogic<AbstractMinecartEntity>) logics.get(type); + return (MinecartComparatorLogic<AbstractMinecartEntity>) LOGICS.get(type); } /** @@ -59,7 +60,10 @@ public final class MinecartComparatorLogicRegistry { * @param logic the logic to register */ public static <T extends AbstractMinecartEntity> void register(EntityType<T> type, MinecartComparatorLogic<? super T> logic) { - if (logics.put(type, logic) != null) { + Objects.requireNonNull(type, "Entity type cannot be null"); + Objects.requireNonNull(logic, "Logic cannot be null"); + + if (LOGICS.put(type, logic) != null) { LOGGER.warn("Overriding existing minecart comparator logic for entity type {}", Registries.ENTITY_TYPE.getId(type)); } } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java index fc187e2aa..71093f70a 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/trade/TradeOfferHelper.java @@ -59,7 +59,7 @@ public final class TradeOfferHelper { /** * @deprecated This never did anything useful. */ - @Deprecated + @Deprecated(forRemoval = true) public static void refreshOffers() { TradeOfferInternals.printRefreshOffersWarning(); } diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java index 44060041c..09a0bd52a 100644 --- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java +++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/DefaultAttributeRegistryMixin.java @@ -16,7 +16,7 @@ package net.fabricmc.fabric.mixin.object.builder; -import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.Map; import org.spongepowered.asm.mixin.Final; @@ -41,6 +41,6 @@ public abstract class DefaultAttributeRegistryMixin { @Inject(method = "<clinit>*", at = @At("TAIL")) private static void injectAttributes(CallbackInfo ci) { - DEFAULT_ATTRIBUTE_REGISTRY = new HashMap<>(DEFAULT_ATTRIBUTE_REGISTRY); + DEFAULT_ATTRIBUTE_REGISTRY = new IdentityHashMap<>(DEFAULT_ATTRIBUTE_REGISTRY); } } diff --git a/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/BlockEntityTypeBuilderTest.java b/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/BlockEntityTypeBuilderTest.java index 5c79baa5f..fb43e8ee9 100644 --- a/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/BlockEntityTypeBuilderTest.java +++ b/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/BlockEntityTypeBuilderTest.java @@ -27,14 +27,14 @@ import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; import net.minecraft.world.World; import net.fabricmc.api.ModInitializer; @@ -42,16 +42,16 @@ import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityT public class BlockEntityTypeBuilderTest implements ModInitializer { private static final Identifier INITIAL_BETRAYAL_BLOCK_ID = ObjectBuilderTestConstants.id("initial_betrayal_block"); - private static final Block INITIAL_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.BLUE); + static final Block INITIAL_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.BLUE); private static final Identifier ADDED_BETRAYAL_BLOCK_ID = ObjectBuilderTestConstants.id("added_betrayal_block"); - private static final Block ADDED_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.GREEN); + static final Block ADDED_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.GREEN); private static final Identifier FIRST_MULTI_BETRAYAL_BLOCK_ID = ObjectBuilderTestConstants.id("first_multi_betrayal_block"); - private static final Block FIRST_MULTI_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.RED); + static final Block FIRST_MULTI_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.RED); private static final Identifier SECOND_MULTI_BETRAYAL_BLOCK_ID = ObjectBuilderTestConstants.id("second_multi_betrayal_block"); - private static final Block SECOND_MULTI_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.YELLOW); + static final Block SECOND_MULTI_BETRAYAL_BLOCK = new BetrayalBlock(MapColor.YELLOW); private static final Identifier BLOCK_ENTITY_TYPE_ID = ObjectBuilderTestConstants.id("betrayal_block"); public static final BlockEntityType<?> BLOCK_ENTITY_TYPE = FabricBlockEntityTypeBuilder.create(BetrayalBlockEntity::new, INITIAL_BETRAYAL_BLOCK) diff --git a/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/ObjectBuilderGameTest.java b/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/ObjectBuilderGameTest.java new file mode 100644 index 000000000..5cf34149b --- /dev/null +++ b/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/ObjectBuilderGameTest.java @@ -0,0 +1,42 @@ +/* + * 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.object.builder; + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.test.GameTest; +import net.minecraft.test.TestContext; +import net.minecraft.util.math.BlockPos; + +import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; + +public class ObjectBuilderGameTest { + @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + public void testBlockUse(TestContext context) { + List<Block> blocks = List.of(BlockEntityTypeBuilderTest.INITIAL_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.ADDED_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.FIRST_MULTI_BETRAYAL_BLOCK, BlockEntityTypeBuilderTest.SECOND_MULTI_BETRAYAL_BLOCK); + BlockPos.Mutable pos = BlockPos.ORIGIN.mutableCopy(); + + for (Block block : blocks) { + context.setBlockState(pos, block); + context.useBlock(pos); + pos.up(); + } + + context.complete(); + } +} diff --git a/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/VillagerTypeTest1.java b/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/VillagerTypeTest1.java index 4c80c1cbb..6826d8c47 100644 --- a/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/VillagerTypeTest1.java +++ b/fabric-object-builder-api-v1/src/testmod/java/net/fabricmc/fabric/test/object/builder/VillagerTypeTest1.java @@ -49,12 +49,6 @@ public class VillagerTypeTest1 implements ModInitializer { }); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - dispatcher.register(literal("fabric_refreshtrades").executes(context -> { - TradeOfferHelper.refreshOffers(); - context.getSource().sendFeedback(Text.literal("Refreshed trades"), false); - return 1; - })); - dispatcher.register(literal("fabric_applywandering_trades") .then(argument("entity", entity()).executes(context -> { final Entity entity = getEntity(context, "entity"); diff --git a/fabric-object-builder-api-v1/src/testmod/resources/fabric.mod.json b/fabric-object-builder-api-v1/src/testmod/resources/fabric.mod.json index 6aa22767c..a2093ce7b 100644 --- a/fabric-object-builder-api-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-object-builder-api-v1/src/testmod/resources/fabric.mod.json @@ -26,6 +26,9 @@ "net.fabricmc.fabric.test.object.builder.CriterionRegistryTest::init", "net.fabricmc.fabric.test.object.builder.VillagerTypeTest1", "net.fabricmc.fabric.test.object.builder.VillagerTypeTest2" + ], + "fabric-gametest": [ + "net.fabricmc.fabric.test.object.builder.ObjectBuilderGameTest" ] } }