diff --git a/paper-api/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java b/paper-api/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java new file mode 100644 index 0000000000..d39b3dc480 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java @@ -0,0 +1,177 @@ +package io.papermc.paper.event.world; + +import io.papermc.paper.math.Position; +import java.util.Collections; +import java.util.List; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.world.WorldEvent; +import org.bukkit.generator.structure.Structure; +import org.bukkit.generator.structure.StructureType; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.UnmodifiableView; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * Called before a set of configured structures is located. + * This happens when: + *
+ * Returns {@code null} if it has not been set by {@link StructuresLocateEvent#setResult(Result)}.
+ * Since this event fires before the search is done, the actual result is unknown at this point.
+ *
+ * @return The result location and structure, if it has been set. {@code null} if it has not.
+ * @see World#locateNearestStructure(Location, StructureType, int, boolean)
+ */
+ public @Nullable Result getResult() {
+ return this.result;
+ }
+
+ /**
+ * Sets the result {@link Location} and {@link Structure}. This causes the search to be
+ * skipped, and the result object passed here to be used as the result.
+ *
+ * @param result the {@link Location} and {@link Structure} of the search.
+ */
+ public void setResult(final @Nullable Result result) {
+ this.result = result;
+ }
+
+ /**
+ * Gets an unmodifiable list of Structures that are valid targets for the search.
+ *
+ * @return an unmodifiable list of Structures
+ */
+ public @UnmodifiableView List
+ * This radius may not always be obeyed during the structure search!
+ *
+ * @return the search radius (in chunks)
+ */
+ public int getRadius() {
+ return this.radius;
+ }
+
+ /**
+ * Sets the search radius in which to attempt locating the structure.
+ *
+ * This radius may not always be obeyed during the structure search!
+ *
+ * @param radius the search radius (in chunks)
+ */
+ public void setRadius(final int radius) {
+ this.radius = radius;
+ }
+
+ /**
+ * Gets whether to search exclusively for unexplored structures.
+ *
+ * As with the search radius, this value is not always obeyed.
+ *
+ * @return Whether to search for only unexplored structures.
+ */
+ public boolean shouldFindUnexplored() {
+ return this.findUnexplored;
+ }
+
+ /**
+ * Sets whether to search exclusively for unexplored structures.
+ *
+ * As with the search radius, this value is not always obeyed.
+ *
+ * @param findUnexplored Whether to search for only unexplored structures.
+ */
+ public void setFindUnexplored(final boolean findUnexplored) {
+ this.findUnexplored = findUnexplored;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
+ @Override
+ public void setCancelled(final boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+
+ /**
+ * Result for {@link StructuresLocateEvent}.
+ */
+ public record Result(Position pos, Structure structure) {
+
+ @Deprecated(forRemoval = true)
+ public Location position() {
+ //noinspection DataFlowIssue
+ return this.pos.toLocation(null);
+ }
+ }
+}