diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java index 0bb3637d..8d6b9af6 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java @@ -9,6 +9,7 @@ import org.bukkit.damage.DamageEffect; import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageType; import org.bukkit.entity.EntityType; +import org.bukkit.entity.PoiType; import org.bukkit.inventory.CreativeCategory; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -132,4 +133,7 @@ public interface UnsafeValues { @ApiStatus.Internal B get(Registry registry, NamespacedKey key); + + @ApiStatus.Internal + PoiType.Occupancy getOccupancy(String key); } diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java index e82e4d49..5bc6783e 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -20,6 +20,7 @@ import org.bukkit.entity.Item; import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.entity.PoiType; import org.bukkit.entity.SpawnCategory; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.generator.BiomeProvider; @@ -37,6 +38,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.messaging.PluginMessageRecipient; import org.bukkit.util.BiomeSearchResult; import org.bukkit.util.BoundingBox; +import org.bukkit.util.PoiSearchResult; import org.bukkit.util.RayTraceResult; import org.bukkit.util.StructureSearchResult; import org.bukkit.util.Vector; @@ -2881,6 +2883,20 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @Nullable BiomeSearchResult locateNearestBiome(@NotNull Location origin, int radius, int horizontalInterval, int verticalInterval, @NotNull Biome... biomes); + /** + * Finds the nearest point of interest closes to the given location. + * + * @param origin where to start looking for a new point of interest at + * @param poiType the poi type to find + * @param radius the radius + * @param occupancy the current required occupancy of the point of interest + * @return a PoiSearchResult containing the closes {@link Location}, + * {@link PoiType} and {@link PoiType.Occupancy}, or null if no poi + * was found. + */ + @Nullable + PoiSearchResult locateNearestPoi(@NotNull Location origin, @NotNull PoiType poiType, int radius, @NotNull PoiType.Occupancy occupancy); + /** * Finds the nearest raid close to the given location. * diff --git a/src/main/java/org/bukkit/entity/PoiType.java b/src/main/java/org/bukkit/entity/PoiType.java index 383c4673..b6e9e8a1 100644 --- a/src/main/java/org/bukkit/entity/PoiType.java +++ b/src/main/java/org/bukkit/entity/PoiType.java @@ -1,6 +1,9 @@ package org.bukkit.entity; +import org.bukkit.Bukkit; import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.block.BlockState; import org.jetbrains.annotations.NotNull; @@ -9,6 +12,87 @@ import org.jetbrains.annotations.NotNull; */ public interface PoiType extends Keyed { + /** + * An armorer's point of interests. + */ + PoiType ARMORER = get("armorer"); + /** + * A butcher's point of interests. + */ + PoiType BUTCHER = get("butcher"); + /** + * A cartographer's point of interests. + */ + PoiType CARTOGRAPHER = get("cartographer"); + /** + * A cleric's point of interests. + */ + PoiType CLERIC = get("cleric"); + /** + * A farmer's point of interests. + */ + PoiType FARMER = get("farmer"); + /** + * A fisherman's point of interests. + */ + PoiType FISHERMAN = get("fisherman"); + /** + * A fletcher's point of interests. + */ + PoiType FLETCHER = get("fletcher"); + /** + * A leatherworker's point of interests. + */ + PoiType LEATHERWORKER = get("leatherworker"); + /** + * A librarian's point of interests. + */ + PoiType LIBRARIAN = get("librarian"); + /** + * A mason's point of interests. + */ + PoiType MASON = get("mason"); + /** + * A shepherd's point of interests. + */ + PoiType SHEPHERD = get("shepherd"); + /** + * A toolsmithr's point of interests. + */ + PoiType TOOLSMITH = get("toolsmith"); + /** + * A weaponsmith's point of interests. + */ + PoiType WEAPONSMITH = get("weaponsmith"); + /** + * A home point of interest. + */ + PoiType HOME = get("home"); + /** + * A meeting point of interest. + */ + PoiType MEETING = get("meeting"); + /** + * A beehive point of interests. + */ + PoiType BEEHIVE = get("beehive"); + /** + * A bee nest point of interests. + */ + PoiType BEE_NEST = get("bee_nest"); + /** + * A nether portal point of interest. + */ + PoiType NETHER_PORTAL = get("nether_portal"); + /** + * A lodestone point of interest. + */ + PoiType LODESTONE = get("lodestone"); + /** + * A lightning rod point of interest. + */ + PoiType LIGHTNING_ROD = get("lightning_rod"); + /** * Determines whether or not the provided BlockState is relevant to this * point of interest. @@ -17,4 +101,32 @@ public interface PoiType extends Keyed { * @return true if the BlockState is relevant, otherwise false */ boolean is(@NotNull final BlockState state); + + @NotNull + private static PoiType get(@NotNull final String key) { + return Registry.POINT_OF_INTEREST_TYPE.getOrThrow(NamespacedKey.minecraft(key)); + } + + /** + * Determines the type of occupancy the point of interest has. + */ + interface Occupancy { + + /** + * The poi has space + */ + Occupancy HAS_SPACE = getOccupancy("HAS_SPACE"); + /** + * The poi is occupied + */ + Occupancy IS_OCCUPIED = getOccupancy("IS_OCCUPIED"); + /** + * The poi is either occupied or has space + */ + Occupancy ANY = getOccupancy("ANY"); + + private static Occupancy getOccupancy(String enumEntryName) { + return Bukkit.getUnsafe().getOccupancy(enumEntryName); + } + } } diff --git a/src/main/java/org/bukkit/util/PoiSearchResult.java b/src/main/java/org/bukkit/util/PoiSearchResult.java index b6901a87..2566f746 100644 --- a/src/main/java/org/bukkit/util/PoiSearchResult.java +++ b/src/main/java/org/bukkit/util/PoiSearchResult.java @@ -1,4 +1,30 @@ package org.bukkit.util; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.PoiType; +import org.jetbrains.annotations.NotNull; + +/** + * Holds the result of searching for a biome. + * + * @see World#locateNearestPoi(Location, PoiType, int, PoiType.Occupancy) + */ public interface PoiSearchResult { + + /** + * Returns the {@link PoiType} + * + * @return the {@link PoiType} + */ + @NotNull + PoiType getPoiType(); + + /** + * Return the location of the {@link PoiType}. + * + * @return the location the {@link PoiType} was found at + */ + @NotNull + Location getLocation(); }