diff --git a/src/main/java/net/minestom/server/entity/ai/EntityAI.java b/src/main/java/net/minestom/server/entity/ai/EntityAI.java index a886352ac..914e34bb0 100644 --- a/src/main/java/net/minestom/server/entity/ai/EntityAI.java +++ b/src/main/java/net/minestom/server/entity/ai/EntityAI.java @@ -44,6 +44,15 @@ public interface EntityAI { addAIGroup(group); } + /** + * Creates new {@link EntityAIGroup} builder. + * + * @return a builder to create and add an {@link EntityAIGroup}. + */ + default EntityAIGroupBuilder newAIGroupBuilder() { + return new EntityAIGroupBuilder(this); + } + default void aiTick(long time) { getAIGroups().forEach(group -> group.tick(time)); } diff --git a/src/main/java/net/minestom/server/entity/ai/EntityAIGroupBuilder.java b/src/main/java/net/minestom/server/entity/ai/EntityAIGroupBuilder.java new file mode 100644 index 000000000..7bc492704 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/ai/EntityAIGroupBuilder.java @@ -0,0 +1,47 @@ +package net.minestom.server.entity.ai; + +import java.util.ArrayList; +import java.util.List; + +public class EntityAIGroupBuilder { + + private final EntityAI ai; + private final List goalSelectors = new ArrayList<>(); + private final List targetSelectors = new ArrayList<>(); + + EntityAIGroupBuilder(EntityAI ai) { + this.ai = ai; + } + + /** + * Adds {@link GoalSelector} to the list of goal selectors of the building {@link EntityAIGroup}. + * Addition order is also a priority: priority the higher the earlier selector was added. + * + * @param goalSelector goal selector to be added. + * @return this builder. + */ + public EntityAIGroupBuilder addGoalSelector(GoalSelector goalSelector) { + this.goalSelectors.add(goalSelector); + return this; + } + + /** + * Adds {@link TargetSelector} to the list of target selectors of the building {@link EntityAIGroup}. + * Addition order is also a priority: priority the higher the earlier selector was added. + * + * @param targetSelector target selector to be added. + * @return this builder. + */ + public EntityAIGroupBuilder addTargetSelector(TargetSelector targetSelector) { + this.targetSelectors.add(targetSelector); + return this; + } + + /** + * Creates new {@link EntityAIGroup} and adds it to the owning {@link EntityAI} of this builder. + */ + public void build() { + this.ai.addAIGroup(this.goalSelectors, this.targetSelectors); + } + +} diff --git a/src/test/java/demo/entity/ChickenCreature.java b/src/test/java/demo/entity/ChickenCreature.java index a11df6c03..12a15c9c9 100644 --- a/src/test/java/demo/entity/ChickenCreature.java +++ b/src/test/java/demo/entity/ChickenCreature.java @@ -3,12 +3,17 @@ package demo.entity; import com.google.common.collect.ImmutableList; import net.minestom.server.attribute.Attributes; import net.minestom.server.entity.LivingEntity; +import net.minestom.server.entity.ai.goal.DoNothingGoal; +import net.minestom.server.entity.ai.goal.MeleeAttackGoal; import net.minestom.server.entity.ai.goal.RandomStrollGoal; +import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.server.entity.ai.target.LastEntityDamagerTarget; import net.minestom.server.entity.damage.DamageType; import net.minestom.server.entity.type.animal.EntityChicken; import net.minestom.server.event.entity.EntityAttackEvent; import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; +import net.minestom.server.utils.time.TimeUnit; public class ChickenCreature extends EntityChicken { @@ -27,6 +32,15 @@ public class ChickenCreature extends EntityChicken { ) ); + // Another way to register previously added EntityAIGroup, using specialized builder: +// newAIGroupBuilder() +// .addGoalSelector(new DoNothingGoal(this, 500, .1F)) +// .addGoalSelector(new MeleeAttackGoal(this, 500, 2, TimeUnit.MILLISECOND)) +// .addGoalSelector(new RandomStrollGoal(this, 2)) +// .addTargetSelector(new LastEntityDamagerTarget(this, 15)) +// .addTargetSelector(new ClosestEntityTarget(this, 15, LivingEntity.class)) +// .build(); + getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.1f); addEventCallback(EntityAttackEvent.class, event -> { diff --git a/src/test/java/demo/entity/ZombieCreature.java b/src/test/java/demo/entity/ZombieCreature.java index 80bd2d930..1b7ff500f 100644 --- a/src/test/java/demo/entity/ZombieCreature.java +++ b/src/test/java/demo/entity/ZombieCreature.java @@ -11,11 +11,8 @@ public class ZombieCreature extends EntityZombie { public ZombieCreature(Position spawnPosition) { super(spawnPosition); - addAIGroup( - ImmutableList.of( - new RandomLookAroundGoal(this, 20) - ), - Collections.emptyList() - ); + newAIGroupBuilder() + .addGoalSelector(new RandomLookAroundGoal(this, 20)) + .build(); } }