diff --git a/build.gradle b/build.gradle
index 861bbf523b..ddcc981b79 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,7 +4,7 @@ plugins {
id "idea"
id "maven-publish"
id 'jacoco'
- id "fabric-loom" version "1.6.3" apply false
+ id "fabric-loom" version "1.6.5" apply false
id "com.diffplug.spotless" version "6.20.0"
id "org.ajoberstar.grgit" version "3.1.0"
id "me.modmuss50.remotesign" version "0.4.0" apply false
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityType.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityType.java
new file mode 100644
index 0000000000..7aeba75362
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityType.java
@@ -0,0 +1,43 @@
+/*
+ * 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.object.builder.v1.block.entity;
+
+import com.mojang.datafixers.types.Type;
+
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.block.entity.BlockEntityType;
+
+/**
+ * General-purpose Fabric-provided extensions for {@link BlockEntityType}.
+ */
+public interface FabricBlockEntityType {
+ /**
+ * General-purpose Fabric-provided extensions for {@link BlockEntityType.Builder}.
+ *
+ *
Note: This interface is automatically implemented on {@link BlockEntityType.Builder} via Mixin and interface injection.
+ */
+ interface Builder {
+ /**
+ * Builds the {@link BlockEntityType}, see {@link BlockEntityType.Builder#build(Type)}.
+ *
+ * @return the built {@link BlockEntityType}
+ */
+ default BlockEntityType build() {
+ throw new AssertionError("Implemented in Mixin");
+ }
+ }
+}
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder.java
index 1229c3d11c..898afc17ef 100644
--- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder.java
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityTypeBuilder.java
@@ -33,7 +33,10 @@
*
* Alternatively, use the access widener for {@link BlockEntityType.BlockEntityFactory}
* in Fabric Transitive Access Wideners (v1).
+ *
+ * @deprecated Use {@link BlockEntityType.Builder} directly.
*/
+@Deprecated
public final class FabricBlockEntityTypeBuilder {
private final Factory extends T> factory;
private final List blocks;
@@ -43,6 +46,10 @@ private FabricBlockEntityTypeBuilder(Factory extends T> factory, List b
this.blocks = blocks;
}
+ /**
+ * @deprecated Use {@link BlockEntityType.Builder#create(BlockEntityType.BlockEntityFactory, Block...)}.
+ */
+ @Deprecated
public static FabricBlockEntityTypeBuilder create(Factory extends T> factory, Block... blocks) {
List blocksList = new ArrayList<>(blocks.length);
Collections.addAll(blocksList, blocks);
@@ -55,7 +62,9 @@ public static FabricBlockEntityTypeBuilder create(Fac
*
* @param block the supported block
* @return this builder
+ * @deprecated Use {@link BlockEntityType.Builder#create(BlockEntityType.BlockEntityFactory, Block...)}.
*/
+ @Deprecated
public FabricBlockEntityTypeBuilder addBlock(Block block) {
this.blocks.add(block);
return this;
@@ -66,22 +75,36 @@ public FabricBlockEntityTypeBuilder addBlock(Block block) {
*
* @param blocks the supported blocks
* @return this builder
+ * @deprecated Use {@link BlockEntityType.Builder#create(BlockEntityType.BlockEntityFactory, Block...)}.
*/
+ @Deprecated
public FabricBlockEntityTypeBuilder addBlocks(Block... blocks) {
Collections.addAll(this.blocks, blocks);
return this;
}
+ /**
+ * @deprecated Use {@link BlockEntityType.Builder#build()}.
+ */
+ @Deprecated
public BlockEntityType build() {
return build(null);
}
+ /**
+ * @deprecated Use {@link BlockEntityType.Builder#build(Type)}.
+ */
+ @Deprecated
public BlockEntityType build(Type> type) {
return BlockEntityType.Builder.create(factory::create, blocks.toArray(new Block[0]))
.build(type);
}
+ /**
+ * @deprecated Use {@link BlockEntityType.BlockEntityFactory}.
+ */
@FunctionalInterface
+ @Deprecated
public interface Factory {
T create(BlockPos blockPos, BlockState blockState);
}
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityType.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityType.java
new file mode 100644
index 0000000000..7f60377ac3
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityType.java
@@ -0,0 +1,126 @@
+/*
+ * 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.object.builder.v1.entity;
+
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.LivingEntity;
+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.world.Heightmap;
+
+import net.fabricmc.fabric.impl.object.builder.FabricEntityTypeImpl;
+
+/**
+ * General-purpose Fabric-provided extensions for {@link EntityType}.
+ */
+public interface FabricEntityType {
+ /**
+ * General-purpose Fabric-provided extensions for {@link EntityType.Builder}.
+ *
+ * Note: This interface is automatically implemented on {@link EntityType.Builder} via Mixin and interface injection.
+ */
+ interface Builder {
+ /**
+ * Sets whether the entity's velocity should always be updated.
+ *
+ * @param alwaysUpdateVelocity whether the entity's velocity should always be updated
+ * @return this builder
+ */
+ default EntityType.Builder alwaysUpdateVelocity(boolean alwaysUpdateVelocity) {
+ throw new AssertionError("Implemented in Mixin");
+ }
+
+ /**
+ * Build the entity type from the builder. Same as {@link EntityType.Builder#build(String)} but without an id.
+ *
+ * @return the entity type instance
+ */
+ default EntityType build() {
+ throw new AssertionError("Implemented in Mixin");
+ }
+
+ /**
+ * Creates an entity type builder for a living entity.
+ *
+ * This entity's spawn group will automatically be set to {@link SpawnGroup#MISC}.
+ *
+ * @param the type of entity
+ * @param livingBuilder a function to configure living entity specific properties
+ *
+ * @return a new living entity type builder
+ */
+ static EntityType.Builder createLiving(EntityType.EntityFactory factory, SpawnGroup spawnGroup, UnaryOperator> livingBuilder) {
+ return FabricEntityTypeImpl.Builder.createLiving(factory, spawnGroup, livingBuilder);
+ }
+
+ /**
+ * Creates an entity type builder for a mob entity.
+ *
+ * @param the type of entity
+ * @param mobBuilder a function to configure mob entity specific properties
+ *
+ * @return a new mob entity type builder
+ */
+ static EntityType.Builder createMob(EntityType.EntityFactory factory, SpawnGroup spawnGroup, UnaryOperator> mobBuilder) {
+ return FabricEntityTypeImpl.Builder.createMob(factory, spawnGroup, mobBuilder);
+ }
+
+ /**
+ * A builder for additional properties of a living entity, use via {@link #createLiving(EntityType.EntityFactory, SpawnGroup, UnaryOperator)}.
+ * @param the type of living entity
+ */
+ interface Living {
+ /**
+ * Sets the default attributes for a type of living entity.
+ *
+ * @param defaultAttributeBuilder a function to generate the default attribute builder from the entity type
+ * @return this builder for chaining
+ */
+ Living defaultAttributes(Supplier defaultAttributeBuilder);
+ }
+
+ /**
+ * A builder for additional properties of a mob entity, use via {@link #createMob(EntityType.EntityFactory, SpawnGroup, UnaryOperator)}.
+ * @param the type of mob entity
+ */
+ interface Mob extends Living {
+ /**
+ * Registers a spawn restriction for this entity.
+ *
+ * This is used by mobs to determine whether Minecraft should spawn an entity within a certain context.
+ *
+ * @return this builder for chaining.
+ */
+ Mob spawnRestriction(SpawnRestriction.Location location, Heightmap.Type heightmap, SpawnRestriction.SpawnPredicate spawnPredicate);
+
+ /**
+ * Sets the default attributes for a type of mob entity.
+ *
+ * @param defaultAttributeBuilder a function to generate the default attribute builder from the entity type
+ * @return this builder for chaining
+ */
+ @Override
+ Mob defaultAttributes(Supplier defaultAttributeBuilder);
+ }
+ }
+}
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 d8d1b02f43..da52194975 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
@@ -18,6 +18,7 @@
import java.util.Objects;
import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.Nullable;
@@ -33,19 +34,13 @@
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;
-import net.fabricmc.fabric.impl.object.builder.FabricEntityType;
-
/**
- * Extended version of {@link EntityType.Builder} with added registration for
- * server->client entity tracking values.
- *
- * @param Entity class.
+ * @deprecated replace with {@link EntityType.Builder}
*/
+@Deprecated
public class FabricEntityTypeBuilder {
private SpawnGroup spawnGroup;
private EntityType.EntityFactory factory;
@@ -59,7 +54,8 @@ public class FabricEntityTypeBuilder {
private EntityDimensions dimensions = EntityDimensions.changing(-1.0f, -1.0f);
private ImmutableSet specificSpawnBlocks = ImmutableSet.of();
- private FeatureSet requiredFeatures = FeatureFlags.VANILLA_FEATURES;
+ @Nullable
+ private FeatureFlag[] requiredFeatures = null;
protected FabricEntityTypeBuilder(SpawnGroup spawnGroup, EntityType.EntityFactory factory) {
this.spawnGroup = spawnGroup;
@@ -75,7 +71,9 @@ protected FabricEntityTypeBuilder(SpawnGroup spawnGroup, EntityType.EntityFactor
* @param the type of entity
*
* @return a new entity type builder
+ * @deprecated use {@link EntityType.Builder#create(SpawnGroup)}
*/
+ @Deprecated
public static FabricEntityTypeBuilder create() {
return create(SpawnGroup.MISC);
}
@@ -87,7 +85,9 @@ public static FabricEntityTypeBuilder create() {
* @param the type of entity
*
* @return a new entity type builder
+ * @deprecated use {@link EntityType.Builder#create(SpawnGroup)}
*/
+ @Deprecated
public static FabricEntityTypeBuilder create(SpawnGroup spawnGroup) {
return create(spawnGroup, FabricEntityTypeBuilder::emptyFactory);
}
@@ -100,7 +100,9 @@ public static FabricEntityTypeBuilder create(SpawnGroup sp
* @param the type of entity
*
* @return a new entity type builder
+ * @deprecated use {@link EntityType.Builder#create(EntityType.EntityFactory, SpawnGroup)}
*/
+ @Deprecated
public static FabricEntityTypeBuilder create(SpawnGroup spawnGroup, EntityType.EntityFactory factory) {
return new FabricEntityTypeBuilder<>(spawnGroup, factory);
}
@@ -113,7 +115,9 @@ public static FabricEntityTypeBuilder create(SpawnGroup sp
* @param the type of entity
*
* @return a new living entity type builder
+ * @deprecated use {@link FabricEntityType.Builder#createLiving(UnaryOperator)}
*/
+ @Deprecated
public static FabricEntityTypeBuilder.Living createLiving() {
return new FabricEntityTypeBuilder.Living<>(SpawnGroup.MISC, FabricEntityTypeBuilder::emptyFactory);
}
@@ -124,6 +128,7 @@ public static FabricEntityTypeBuilder.Living createL
* @param the type of entity
*
* @return a new mob entity type builder
+ * @deprecated use {@link FabricEntityType.Builder#createMob(UnaryOperator)}
*/
public static FabricEntityTypeBuilder.Mob createMob() {
return new FabricEntityTypeBuilder.Mob<>(SpawnGroup.MISC, FabricEntityTypeBuilder::emptyFactory);
@@ -133,12 +138,14 @@ private static T emptyFactory(EntityType type, World world
return null;
}
+ @Deprecated
public FabricEntityTypeBuilder spawnGroup(SpawnGroup group) {
Objects.requireNonNull(group, "Spawn group cannot be null");
this.spawnGroup = group;
return this;
}
+ @Deprecated
public FabricEntityTypeBuilder entityFactory(EntityType.EntityFactory factory) {
Objects.requireNonNull(factory, "Entity Factory cannot be null");
this.factory = (EntityType.EntityFactory) factory;
@@ -149,12 +156,18 @@ public FabricEntityTypeBuilder entityFactory(EntityType.EntityF
* Whether this entity type is summonable using the {@code /summon} command.
*
* @return this builder for chaining
+ * @deprecated use {@link EntityType.Builder#disableSummon()}
*/
+ @Deprecated
public FabricEntityTypeBuilder disableSummon() {
this.summonable = false;
return this;
}
+ /**
+ * @deprecated use {@link EntityType.Builder#disableSaving()}
+ */
+ @Deprecated
public FabricEntityTypeBuilder disableSaving() {
this.saveable = false;
return this;
@@ -164,7 +177,9 @@ public FabricEntityTypeBuilder disableSaving() {
* Sets this entity type to be fire immune.
*
* @return this builder for chaining
+ * @deprecated use {@link EntityType.Builder#makeFireImmune()}
*/
+ @Deprecated
public FabricEntityTypeBuilder fireImmune() {
this.fireImmune = true;
return this;
@@ -174,7 +189,9 @@ public FabricEntityTypeBuilder fireImmune() {
* Sets whether this entity type can be spawned far away from a player.
*
* @return this builder for chaining
+ * @deprecated use {@link EntityType.Builder#spawnableFarFromPlayer()}
*/
+ @Deprecated
public FabricEntityTypeBuilder spawnableFarFromPlayer() {
this.spawnableFarFromPlayer = true;
return this;
@@ -186,7 +203,9 @@ public FabricEntityTypeBuilder spawnableFarFromPlayer() {
* @param dimensions the dimensions representing the entity's size
*
* @return this builder for chaining
+ * @deprecated use {@link EntityType.Builder#setDimensions(float, float)}
*/
+ @Deprecated
public FabricEntityTypeBuilder dimensions(EntityDimensions dimensions) {
Objects.requireNonNull(dimensions, "Cannot set null dimensions");
this.dimensions = dimensions;
@@ -218,7 +237,9 @@ public FabricEntityTypeBuilder trackable(int trackRangeBlocks, int trackedUpd
* @param range the tracking range in chunks
*
* @return this builder for chaining
+ * @deprecated use {@link FabricEntityTypeBuilder#trackRangeBlocks(int)}
*/
+ @Deprecated
public FabricEntityTypeBuilder trackRangeChunks(int range) {
this.trackRange = range;
return this;
@@ -230,16 +251,26 @@ public FabricEntityTypeBuilder trackRangeChunks(int range) {
* @param range the tracking range in blocks
*
* @return this builder for chaining
+ * @deprecated use {@link FabricEntityTypeBuilder#trackRangeChunks(int)}
*/
+ @Deprecated
public FabricEntityTypeBuilder trackRangeBlocks(int range) {
return trackRangeChunks((range + 15) / 16);
}
+ /**
+ * @deprecated use {@link FabricEntityTypeBuilder#trackRangeBlocks(int)}
+ */
+ @Deprecated
public FabricEntityTypeBuilder trackedUpdateRate(int rate) {
this.trackedUpdateRate = rate;
return this;
}
+ /**
+ * @deprecated use {@link FabricEntityTypeBuilder#trackRangeBlocks(int)}
+ */
+ @Deprecated
public FabricEntityTypeBuilder forceTrackedVelocityUpdates(boolean forceTrackedVelocityUpdates) {
this.forceTrackedVelocityUpdates = forceTrackedVelocityUpdates;
return this;
@@ -250,7 +281,9 @@ public FabricEntityTypeBuilder forceTrackedVelocityUpdates(boolean forceTrack
*
* @param blocks the blocks the entity can spawn on
* @return this builder for chaining
+ * @deprecated use {@link EntityType.Builder#allowSpawningInside(Block...)}
*/
+ @Deprecated
public FabricEntityTypeBuilder specificSpawnBlocks(Block... blocks) {
this.specificSpawnBlocks = ImmutableSet.copyOf(blocks);
return this;
@@ -261,9 +294,11 @@ public FabricEntityTypeBuilder specificSpawnBlocks(Block... blocks) {
* the entity cannot be spawned, and existing ones will despawn immediately.
* @param requiredFeatures the features
* @return this builder for chaining
+ * @deprecated use {@link EntityType.Builder#requires(FeatureFlag...)}
*/
+ @Deprecated
public FabricEntityTypeBuilder requires(FeatureFlag... requiredFeatures) {
- this.requiredFeatures = FeatureFlags.FEATURE_MANAGER.featureSetOf(requiredFeatures);
+ this.requiredFeatures = requiredFeatures;
return this;
}
@@ -271,19 +306,50 @@ public FabricEntityTypeBuilder requires(FeatureFlag... requiredFeatures) {
* Creates the entity type.
*
* @return a new {@link EntityType}
+ * @deprecated use {@link EntityType.Builder#build()}
*/
+ @Deprecated
public EntityType build() {
- // Modded DFU is a dream, currently not possible without screwing it up.
+ EntityType.Builder builder = EntityType.Builder.create(this.factory, this.spawnGroup)
+ .allowSpawningInside(specificSpawnBlocks.toArray(Block[]::new))
+ .maxTrackingRange(this.trackRange)
+ .trackingTickInterval(this.trackedUpdateRate)
+ .setDimensions(this.dimensions.width, this.dimensions.height);
+
+ if (!this.saveable) {
+ builder = builder.disableSaving();
+ }
- //TODO 1.20.5, new field
- return new FabricEntityType<>(this.factory, this.spawnGroup, this.saveable, this.summonable, this.fireImmune, this.spawnableFarFromPlayer, this.specificSpawnBlocks, dimensions, 1, trackRange, trackedUpdateRate, forceTrackedVelocityUpdates, this.requiredFeatures);
+ if (!this.summonable) {
+ builder = builder.disableSummon();
+ }
+
+ if (this.fireImmune) {
+ builder = builder.makeFireImmune();
+ }
+
+ if (this.spawnableFarFromPlayer) {
+ builder = builder.spawnableFarFromPlayer();
+ }
+
+ if (this.requiredFeatures != null) {
+ builder = builder.requires(this.requiredFeatures);
+ }
+
+ if (this.forceTrackedVelocityUpdates != null) {
+ builder = builder.alwaysUpdateVelocity(this.forceTrackedVelocityUpdates);
+ }
+
+ return builder.build(null);
}
/**
* An extended version of {@link FabricEntityTypeBuilder} with support for features on present on {@link LivingEntity living entities}, such as default attributes.
*
* @param Entity class.
+ * @deprecated use {@link EntityType.Builder#createLiving(UnaryOperator)}
*/
+ @Deprecated
public static class Living extends FabricEntityTypeBuilder {
@Nullable
private Supplier defaultAttributeBuilder;
@@ -399,13 +465,16 @@ public FabricEntityTypeBuilder.Living specificSpawnBlocks(Block... blocks) {
*
* @param defaultAttributeBuilder a function to generate the default attribute builder from the entity type
* @return this builder for chaining
+ * @deprecated use {@link FabricEntityType.Builder.Living#defaultAttributes(Supplier)}
*/
+ @Deprecated
public FabricEntityTypeBuilder.Living defaultAttributes(Supplier defaultAttributeBuilder) {
Objects.requireNonNull(defaultAttributeBuilder, "Cannot set null attribute builder");
this.defaultAttributeBuilder = defaultAttributeBuilder;
return this;
}
+ @Deprecated
@Override
public EntityType build() {
final EntityType type = super.build();
@@ -423,6 +492,7 @@ public EntityType build() {
*
* @param Entity class.
*/
+ @Deprecated
public static class Mob extends FabricEntityTypeBuilder.Living {
private SpawnLocation spawnLocation;
private Heightmap.Type restrictionHeightmap;
@@ -536,7 +606,9 @@ public FabricEntityTypeBuilder.Mob defaultAttributes(SupplierThis 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
public FabricEntityTypeBuilder.Mob spawnRestriction(SpawnLocation spawnLocation, Heightmap.Type heightmap, SpawnRestriction.SpawnPredicate spawnPredicate) {
this.spawnLocation = Objects.requireNonNull(spawnLocation, "Spawn location cannot be null.");
this.restrictionHeightmap = Objects.requireNonNull(heightmap, "Heightmap type cannot be null.");
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java
deleted file mode 100644
index dde18eec8c..0000000000
--- a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityType.java
+++ /dev/null
@@ -1,44 +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.impl.object.builder;
-
-import com.google.common.collect.ImmutableSet;
-
-import net.minecraft.block.Block;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.EntityDimensions;
-import net.minecraft.entity.EntityType;
-import net.minecraft.entity.SpawnGroup;
-import net.minecraft.resource.featuretoggle.FeatureSet;
-
-public class FabricEntityType extends EntityType {
- private final Boolean alwaysUpdateVelocity;
-
- public FabricEntityType(EntityType.EntityFactory factory, SpawnGroup spawnGroup, boolean bl, boolean summonable, boolean fireImmune, boolean spawnableFarFromPlayer, ImmutableSet spawnBlocks, EntityDimensions entityDimensions, float field_50125, int maxTrackDistance, int trackTickInterval, Boolean alwaysUpdateVelocity, FeatureSet featureSet) {
- super(factory, spawnGroup, bl, summonable, fireImmune, spawnableFarFromPlayer, spawnBlocks, entityDimensions, field_50125, maxTrackDistance, trackTickInterval, featureSet);
- this.alwaysUpdateVelocity = alwaysUpdateVelocity;
- }
-
- @Override
- public boolean alwaysUpdateVelocity() {
- if (alwaysUpdateVelocity != null) {
- return alwaysUpdateVelocity;
- }
-
- return super.alwaysUpdateVelocity();
- }
-}
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityTypeImpl.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityTypeImpl.java
new file mode 100644
index 0000000000..3a563912b6
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/impl/object/builder/FabricEntityTypeImpl.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.impl.object.builder;
+
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import org.jetbrains.annotations.Nullable;
+
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.LivingEntity;
+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.world.Heightmap;
+
+import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
+import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityType;
+
+public interface FabricEntityTypeImpl {
+ void fabric_setAlwaysUpdateVelocity(Boolean alwaysUpdateVelocity);
+
+ interface Builder {
+ void fabric_setLivingEntityBuilder(Living extends LivingEntity> livingBuilder);
+
+ void fabric_setMobEntityBuilder(Mob extends MobEntity> mobBuilder);
+
+ static EntityType.Builder createLiving(EntityType.EntityFactory factory, SpawnGroup spawnGroup, UnaryOperator> livingBuilder) {
+ EntityType.Builder builder = EntityType.Builder.create(factory, spawnGroup);
+ Living builderImpl = new Living<>();
+ livingBuilder.apply(builderImpl);
+ ((Builder) builder).fabric_setLivingEntityBuilder(builderImpl);
+ return builder;
+ }
+
+ static EntityType.Builder createMob(EntityType.EntityFactory factory, SpawnGroup spawnGroup, UnaryOperator> mobBuilder) {
+ EntityType.Builder builder = EntityType.Builder.create(factory, spawnGroup);
+ Mob builderImpl = new Mob<>();
+ mobBuilder.apply(builderImpl);
+ ((Builder) builder).fabric_setMobEntityBuilder(builderImpl);
+ return builder;
+ }
+
+ sealed class Living implements FabricEntityType.Builder.Living permits Mob {
+ @Nullable
+ private Supplier defaultAttributeBuilder;
+
+ @Override
+ public FabricEntityType.Builder.Living defaultAttributes(Supplier defaultAttributeBuilder) {
+ Objects.requireNonNull(defaultAttributeBuilder, "Cannot set null attribute builder");
+ this.defaultAttributeBuilder = defaultAttributeBuilder;
+ return this;
+ }
+
+ public void onBuild(EntityType type) {
+ if (this.defaultAttributeBuilder != null) {
+ FabricDefaultAttributeRegistry.register(type, this.defaultAttributeBuilder.get());
+ }
+ }
+ }
+
+ final class Mob extends Living implements FabricEntityType.Builder.Mob {
+ private SpawnRestriction.Location restrictionLocation;
+ private Heightmap.Type restrictionHeightmap;
+ private SpawnRestriction.SpawnPredicate spawnPredicate;
+
+ @Override
+ public FabricEntityType.Builder.Mob spawnRestriction(SpawnRestriction.Location location, Heightmap.Type heightmap, SpawnRestriction.SpawnPredicate spawnPredicate) {
+ this.restrictionLocation = Objects.requireNonNull(location, "Location cannot be null.");
+ this.restrictionHeightmap = Objects.requireNonNull(heightmap, "Heightmap type cannot be null.");
+ this.spawnPredicate = Objects.requireNonNull(spawnPredicate, "Spawn predicate cannot be null.");
+ return this;
+ }
+
+ @Override
+ public FabricEntityType.Builder.Mob defaultAttributes(Supplier defaultAttributeBuilder) {
+ super.defaultAttributes(defaultAttributeBuilder);
+ return this;
+ }
+
+ public void onBuild(EntityType type) {
+ super.onBuild(type);
+
+ if (this.spawnPredicate != null) {
+ SpawnRestriction.register(type, this.restrictionLocation, this.restrictionHeightmap, this.spawnPredicate);
+ }
+ }
+ }
+ }
+}
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/BlockEntityTypeBuilderMixin.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/BlockEntityTypeBuilderMixin.java
new file mode 100644
index 0000000000..5d9342ec1f
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/BlockEntityTypeBuilderMixin.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.object.builder;
+
+import com.mojang.datafixers.types.Type;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.block.entity.BlockEntityType;
+
+import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityType;
+
+@Mixin(BlockEntityType.Builder.class)
+public abstract class BlockEntityTypeBuilderMixin implements FabricBlockEntityType.Builder {
+ @Shadow
+ public abstract BlockEntityType build(Type> type);
+
+ @Override
+ public BlockEntityType build() {
+ return build(null);
+ }
+}
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/EntityTypeBuilderMixin.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/EntityTypeBuilderMixin.java
new file mode 100644
index 0000000000..286dfdde15
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/EntityTypeBuilderMixin.java
@@ -0,0 +1,114 @@
+/*
+ * 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.object.builder;
+
+import java.util.Objects;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.mojang.datafixers.DSL;
+import com.mojang.datafixers.types.Type;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+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.CallbackInfoReturnable;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.mob.MobEntity;
+
+import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityType;
+import net.fabricmc.fabric.impl.object.builder.FabricEntityTypeImpl;
+
+@Mixin(EntityType.Builder.class)
+public abstract class EntityTypeBuilderMixin implements FabricEntityType.Builder, FabricEntityTypeImpl.Builder {
+ @Shadow
+ public abstract EntityType build(String id);
+
+ @Unique
+ private Boolean alwaysUpdateVelocity = null;
+
+ @Unique
+ private FabricEntityTypeImpl.Builder.Living extends LivingEntity> livingBuilder = null;
+ @Unique
+ private FabricEntityTypeImpl.Builder.Mob extends MobEntity> mobBuilder = null;
+
+ @Override
+ public EntityType.Builder alwaysUpdateVelocity(boolean forceTrackedVelocityUpdates) {
+ alwaysUpdateVelocity = forceTrackedVelocityUpdates;
+ return (EntityType.Builder) (Object) this;
+ }
+
+ @Override
+ public EntityType build() {
+ return build(null);
+ }
+
+ @Inject(method = "build", at = @At("RETURN"))
+ private void applyChildBuilders(String id, CallbackInfoReturnable> cir) {
+ if (!(cir.getReturnValue() instanceof FabricEntityTypeImpl entityType)) {
+ throw new IllegalStateException();
+ }
+
+ entityType.fabric_setAlwaysUpdateVelocity(alwaysUpdateVelocity);
+
+ if (livingBuilder != null) {
+ livingBuilder.onBuild(castLiving(cir.getReturnValue()));
+ }
+
+ if (mobBuilder != null) {
+ mobBuilder.onBuild(castMob(cir.getReturnValue()));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Unique
+ private static EntityType castLiving(EntityType> type) {
+ return (EntityType) type;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Unique
+ private static EntityType castMob(EntityType> type) {
+ return (EntityType) type;
+ }
+
+ @WrapOperation(method = "build", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;getChoiceType(Lcom/mojang/datafixers/DSL$TypeReference;Ljava/lang/String;)Lcom/mojang/datafixers/types/Type;"))
+ private @Nullable Type> allowNullId(DSL.TypeReference typeReference, String id, Operation> original) {
+ if (id == null) {
+ return null;
+ }
+
+ return original.call(typeReference, id);
+ }
+
+ @Override
+ public void fabric_setLivingEntityBuilder(FabricEntityTypeImpl.Builder.Living extends LivingEntity> livingBuilder) {
+ Objects.requireNonNull(livingBuilder, "Cannot set null living entity builder");
+ this.livingBuilder = livingBuilder;
+ }
+
+ @Override
+ public void fabric_setMobEntityBuilder(FabricEntityTypeImpl.Builder.Mob extends MobEntity> mobBuilder) {
+ Objects.requireNonNull(mobBuilder, "Cannot set null mob entity builder");
+ this.mobBuilder = mobBuilder;
+ }
+}
diff --git a/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/EntityTypeMixin.java b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/EntityTypeMixin.java
new file mode 100644
index 0000000000..4d493d6d61
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/main/java/net/fabricmc/fabric/mixin/object/builder/EntityTypeMixin.java
@@ -0,0 +1,45 @@
+/*
+ * 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.object.builder;
+
+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.CallbackInfoReturnable;
+
+import net.minecraft.entity.EntityType;
+
+import net.fabricmc.fabric.impl.object.builder.FabricEntityTypeImpl;
+
+@Mixin(EntityType.class)
+public abstract class EntityTypeMixin implements FabricEntityTypeImpl {
+ @Unique
+ private Boolean alwaysUpdateVelocity;
+
+ @Inject(method = "alwaysUpdateVelocity", at = @At("HEAD"), cancellable = true)
+ public void alwaysUpdateVelocity(CallbackInfoReturnable cir) {
+ if (alwaysUpdateVelocity != null) {
+ cir.setReturnValue(alwaysUpdateVelocity);
+ }
+ }
+
+ @Override
+ public void fabric_setAlwaysUpdateVelocity(Boolean alwaysUpdateVelocity) {
+ this.alwaysUpdateVelocity = alwaysUpdateVelocity;
+ }
+}
diff --git a/fabric-object-builder-api-v1/src/main/resources/fabric-object-builder-v1.mixins.json b/fabric-object-builder-api-v1/src/main/resources/fabric-object-builder-v1.mixins.json
index a5c4f877c0..22d799f1ed 100644
--- a/fabric-object-builder-api-v1/src/main/resources/fabric-object-builder-v1.mixins.json
+++ b/fabric-object-builder-api-v1/src/main/resources/fabric-object-builder-v1.mixins.json
@@ -5,9 +5,12 @@
"mixins": [
"AbstractBlockAccessor",
"AbstractBlockSettingsAccessor",
+ "BlockEntityTypeBuilderMixin",
"DefaultAttributeRegistryAccessor",
"DefaultAttributeRegistryMixin",
"DetectorRailBlockMixin",
+ "EntityTypeBuilderMixin",
+ "EntityTypeMixin",
"PersistentStateManagerMixin",
"TradeOffersTypeAwareBuyForOneEmeraldFactoryMixin"
],
diff --git a/fabric-object-builder-api-v1/src/main/resources/fabric.mod.json b/fabric-object-builder-api-v1/src/main/resources/fabric.mod.json
index 940c46c6d7..8aa8fb234f 100644
--- a/fabric-object-builder-api-v1/src/main/resources/fabric.mod.json
+++ b/fabric-object-builder-api-v1/src/main/resources/fabric.mod.json
@@ -29,6 +29,10 @@
],
"accessWidener" : "fabric-object-builder-api-v1.accesswidener",
"custom": {
- "fabric-api:module-lifecycle": "stable"
+ "fabric-api:module-lifecycle": "stable",
+ "loom:injected_interfaces": {
+ "net/minecraft/class_1299\u0024class_1300": ["net/fabricmc/fabric/api/object/builder/v1/entity/FabricEntityType\u0024Builder"],
+ "net/minecraft/class_2591\u0024class_2592": ["net/fabricmc/fabric/api/object/builder/v1/block/entity/FabricBlockEntityType\u0024Builder"]
+ }
}
}
diff --git a/fabric-object-builder-api-v1/src/test/java/net/fabricmc/fabric/test/object/builder/FabricEntityTypeTest.java b/fabric-object-builder-api-v1/src/test/java/net/fabricmc/fabric/test/object/builder/FabricEntityTypeTest.java
new file mode 100644
index 0000000000..f3f477518c
--- /dev/null
+++ b/fabric-object-builder-api-v1/src/test/java/net/fabricmc/fabric/test/object/builder/FabricEntityTypeTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import net.minecraft.Bootstrap;
+import net.minecraft.SharedConstants;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.SpawnGroup;
+import net.minecraft.entity.SpawnRestriction;
+import net.minecraft.entity.attribute.DefaultAttributeContainer;
+import net.minecraft.entity.attribute.DefaultAttributeRegistry;
+import net.minecraft.entity.attribute.EntityAttributes;
+import net.minecraft.entity.mob.MobEntity;
+import net.minecraft.entity.passive.PigEntity;
+import net.minecraft.world.Heightmap;
+
+import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityType;
+
+public class FabricEntityTypeTest {
+ @BeforeAll
+ static void beforeAll() {
+ SharedConstants.createGameVersion();
+ Bootstrap.initialize();
+ }
+
+ @Test
+ void buildEntityType() {
+ EntityType type = EntityType.Builder.create(SpawnGroup.MISC)
+ .alwaysUpdateVelocity(true)
+ .build();
+
+ assertNotNull(type);
+ assertTrue(type.alwaysUpdateVelocity());
+ }
+
+ @Test
+ void buildLivingEntityType() {
+ EntityType type = FabricEntityType.Builder.createLiving((t, w) -> null, SpawnGroup.MISC, living -> living
+ .defaultAttributes(FabricEntityTypeTest::createAttributes)
+ ).build();
+
+ assertNotNull(type);
+ assertNotNull(DefaultAttributeRegistry.get(type));
+ }
+
+ @Test
+ void buildMobEntityType() {
+ EntityType type = FabricEntityType.Builder.createMob((t, w) -> null, SpawnGroup.MISC, mob -> mob
+ .spawnRestriction(SpawnRestriction.Location.ON_GROUND, Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, PigEntity::canMobSpawn)
+ .defaultAttributes(FabricEntityTypeTest::createAttributes)
+ ).build();
+
+ assertNotNull(type);
+ assertEquals(SpawnRestriction.Location.ON_GROUND, SpawnRestriction.getLocation(type));
+ assertNotNull(DefaultAttributeRegistry.get(type));
+ }
+
+ private static DefaultAttributeContainer.Builder createAttributes() {
+ return MobEntity.createMobAttributes()
+ .add(EntityAttributes.GENERIC_MAX_HEALTH, 10.0)
+ .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25);
+ }
+}