package net.minestom.server.instance; import net.minestom.server.Viewable; import net.minestom.server.coordinate.Point; import net.minestom.server.entity.Entity; import net.minestom.server.entity.ExperienceOrb; import net.minestom.server.entity.ItemEntity; import net.minestom.server.entity.Player; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Consumer; /** * Defines how {@link Entity entities} are tracked within an {@link Instance instance}. *

* Implementations are expected to be thread-safe. */ @ApiStatus.Experimental public sealed interface EntityTracker permits EntityTrackerImpl { static @NotNull EntityTracker newTracker() { return new EntityTrackerImpl(); } /** * Register an entity to be tracked. */ void register(@NotNull Entity entity, @NotNull Point point, @NotNull Target target, @Nullable Update update); /** * Unregister an entity tracking. */ void unregister(@NotNull Entity entity, @NotNull Target target, @Nullable Update update); /** * Called every time an entity move, you may want to verify if the new * position is in a different chunk. */ void move(@NotNull Entity entity, @NotNull Point newPoint, @NotNull Target target, @Nullable Update update); @UnmodifiableView Collection chunkEntities(int chunkX, int chunkZ, @NotNull Target target); @UnmodifiableView default @NotNull Collection chunkEntities(@NotNull Point point, @NotNull Target target) { return chunkEntities(point.chunkX(), point.chunkZ(), target); } /** * Gets the entities within a chunk range. */ void nearbyEntitiesByChunkRange(@NotNull Point point, int chunkRange, @NotNull Target target, @NotNull Consumer query); /** * Gets the entities within a range. */ void nearbyEntities(@NotNull Point point, double range, @NotNull Target target, @NotNull Consumer query); /** * Gets all the entities tracked by this class. */ @UnmodifiableView @NotNull Set<@NotNull T> entities(@NotNull Target target); @UnmodifiableView default @NotNull Set<@NotNull Entity> entities() { return entities(Target.ENTITIES); } @NotNull Viewable viewable(@NotNull List<@NotNull SharedInstance> sharedInstances, int chunkX, int chunkZ); default @NotNull Viewable viewable(int chunkX, int chunkZ) { return viewable(List.of(), chunkX, chunkZ); } /** * Represents the type of entity you want to retrieve. * * @param the entity type */ @ApiStatus.NonExtendable interface Target { Target ENTITIES = create(Entity.class); Target PLAYERS = create(Player.class); Target ITEMS = create(ItemEntity.class); Target EXPERIENCE_ORBS = create(ExperienceOrb.class); List> TARGETS = List.of(EntityTracker.Target.ENTITIES, EntityTracker.Target.PLAYERS, EntityTracker.Target.ITEMS, EntityTracker.Target.EXPERIENCE_ORBS); Class type(); int ordinal(); private static EntityTracker.Target create(Class type) { final int ordinal = EntityTrackerImpl.TARGET_COUNTER.getAndIncrement(); return new Target<>() { @Override public Class type() { return type; } @Override public int ordinal() { return ordinal; } }; } } /** * Callback to know the newly visible entities and those to remove. */ interface Update { void add(@NotNull E entity); void remove(@NotNull E entity); default void referenceUpdate(@NotNull Point point, @Nullable EntityTracker tracker) { // Empty } } }