aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/api/0243-Add-StructuresLocateEvent.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/api/0243-Add-StructuresLocateEvent.patch')
-rw-r--r--patches/api/0243-Add-StructuresLocateEvent.patch534
1 files changed, 534 insertions, 0 deletions
diff --git a/patches/api/0243-Add-StructuresLocateEvent.patch b/patches/api/0243-Add-StructuresLocateEvent.patch
new file mode 100644
index 0000000000..10ef586cce
--- /dev/null
+++ b/patches/api/0243-Add-StructuresLocateEvent.patch
@@ -0,0 +1,534 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: dfsek <[email protected]>
+Date: Tue, 15 Sep 2020 21:59:16 -0700
+Subject: [PATCH] Add StructuresLocateEvent
+
+Co-authored-by: Jake Potrebic <[email protected]>
+
+diff --git a/src/main/java/io/papermc/paper/event/world/StructureLocateEvent.java b/src/main/java/io/papermc/paper/event/world/StructureLocateEvent.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..1ac3369455972aeb1ade5dc023d1f818cd3535fa
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/event/world/StructureLocateEvent.java
+@@ -0,0 +1,163 @@
++package io.papermc.paper.event.world;
++
++import org.bukkit.Location;
++import org.bukkit.StructureType;
++import org.bukkit.World;
++import org.bukkit.event.Cancellable;
++import org.bukkit.event.HandlerList;
++import org.bukkit.event.world.WorldEvent;
++import org.jetbrains.annotations.ApiStatus;
++import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.Nullable;
++
++/**
++ * Called <b>before</b> a structure/feature is located.
++ * This happens when:
++ * <ul>
++ * <li>The /locate command is used.<br></li>
++ * <li>An Eye of Ender is used.</li>
++ * <li>An Explorer/Treasure Map is activated.</li>
++ * <li>{@link World#locateNearestStructure(Location, StructureType, int, boolean)} is invoked.</li>
++ * </ul>
++ *
++ * @deprecated no longer used, see {@link StructuresLocateEvent}
++ */
++@Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21")
++public class StructureLocateEvent extends WorldEvent implements Cancellable {
++
++ private static final HandlerList HANDLER_LIST = new HandlerList();
++
++ private final Location origin;
++ private Location result = null;
++ private StructureType type;
++ private int radius;
++ private boolean findUnexplored;
++
++ private boolean cancelled;
++
++ @ApiStatus.Internal
++ public StructureLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull StructureType structureType, int radius, boolean findUnexplored) {
++ super(world);
++ this.origin = origin;
++ this.type = structureType;
++ this.radius = radius;
++ this.findUnexplored = findUnexplored;
++ }
++
++ /**
++ * Gets the location set as the structure location, if it was defined.
++ * <p>
++ * Returns {@code null} if it has not been set by {@link StructureLocateEvent#setResult(Location)}.
++ * Since this event fires <i>before</i> the search is done, the actual location is unknown at this point.
++ *
++ * @return The result location, if it has been set. {@code null} if it has not.
++ * @see World#locateNearestStructure(Location, StructureType, int, boolean)
++ */
++ @Nullable
++ public Location getResult() {
++ return this.result;
++ }
++
++ /**
++ * Sets the result {@link Location}. This causes the search to be skipped, and the location passed here to be used as the result.
++ *
++ * @param result the {@link Location} of the structure.
++ */
++ public void setResult(@Nullable Location result) {
++ this.result = result;
++ }
++
++ /**
++ * Gets the {@link StructureType} that is to be located.
++ *
++ * @return the structure type.
++ */
++ @NotNull
++ public StructureType getType() {
++ return this.type;
++ }
++
++ /**
++ * Sets the {@link StructureType} that is to be located.
++ *
++ * @param type the structure type.
++ */
++ public void setType(@NotNull StructureType type) {
++ this.type = type;
++ }
++
++ /**
++ * Gets the {@link Location} from which the search is to be conducted.
++ *
++ * @return {@link Location} where search begins
++ */
++ @NotNull
++ public Location getOrigin() {
++ return this.origin;
++ }
++
++ /**
++ * Gets the search radius in which to attempt locating the structure.
++ * <p>
++ * This radius may not always be obeyed during the structure search!
++ *
++ * @return the search radius.
++ */
++ public int getRadius() {
++ return this.radius;
++ }
++
++ /**
++ * Sets the search radius in which to attempt locating the structure.
++ * <p>
++ * This radius may not always be obeyed during the structure search!
++ *
++ * @param radius the search radius.
++ */
++ public void setRadius(int radius) {
++ this.radius = radius;
++ }
++
++ /**
++ * Gets whether to search exclusively for unexplored structures.
++ * <p>
++ * 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.
++ * <p>
++ * As with the search radius, this value is not always obeyed.
++ *
++ * @param findUnexplored Whether to search for only unexplored structures.
++ */
++ public void setFindUnexplored(boolean findUnexplored) {
++ this.findUnexplored = findUnexplored;
++ }
++
++ @Override
++ public boolean isCancelled() {
++ return this.cancelled;
++ }
++
++ @Override
++ public void setCancelled(boolean cancel) {
++ this.cancelled = cancel;
++ }
++
++ @NotNull
++ public static HandlerList getHandlerList() {
++ return HANDLER_LIST;
++ }
++
++ @NotNull
++ @Override
++ public HandlerList getHandlers() {
++ return HANDLER_LIST;
++ }
++}
+diff --git a/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java b/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..582af444b058708638683e7d6f9b79685c04c061
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/event/world/StructuresLocateEvent.java
+@@ -0,0 +1,213 @@
++package io.papermc.paper.event.world;
++
++import io.papermc.paper.math.Position;
++import io.papermc.paper.util.TransformingRandomAccessList;
++import io.papermc.paper.world.structure.ConfiguredStructure;
++import java.util.Collections;
++import java.util.List;
++import java.util.Objects;
++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.NotNull;
++import org.jetbrains.annotations.Nullable;
++import org.jetbrains.annotations.UnmodifiableView;
++
++/**
++ * Called <b>before</b> a set of configured structures is located.
++ * This happens when:
++ * <ul>
++ * <li>The /locate command is used.<br></li>
++ * <li>An Eye of Ender is used.</li>
++ * <li>An Explorer/Treasure Map is activated.</li>
++ * <li>A dolphin swims to a treasure location.</li>
++ * <li>A trade is done with a villager for a map.</li>
++ * <li>{@link World#locateNearestStructure(Location, StructureType, int, boolean)} is invoked.</li>
++ * <li>{@link World#locateNearestStructure(Location, Structure, int, boolean)} is invoked.</li>
++ * </ul>
++ */
++public class StructuresLocateEvent extends WorldEvent implements Cancellable {
++
++ private static final HandlerList HANDLER_LIST = new HandlerList();
++
++ private final Location origin;
++ private Result result;
++ private List<Structure> structures;
++ private List<ConfiguredStructure> legacy$structures;
++ private int radius;
++ private boolean findUnexplored;
++
++ private boolean cancelled;
++
++ @ApiStatus.Internal
++ public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List<Structure> structures, int radius, boolean findUnexplored) {
++ super(world);
++ this.origin = origin;
++ this.setStructures(structures);
++ this.radius = radius;
++ this.findUnexplored = findUnexplored;
++ }
++
++ /**
++ * Gets the {@link Location} from which the search is to be conducted.
++ *
++ * @return {@link Location} where search begins
++ */
++ public @NotNull Location getOrigin() {
++ return this.origin.clone();
++ }
++
++ /**
++ * Gets the {@link Location} and {@link Structure} set as the result, if it was defined.
++ * <p>
++ * Returns {@code null} if it has not been set by {@link StructuresLocateEvent#setResult(Result)}.
++ * Since this event fires <i>before</i> 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(@Nullable Result result) {
++ this.result = result;
++ }
++
++ /**
++ * Gets a mutable list of ConfiguredStructures that are valid targets for the search.
++ *
++ * @return a mutable list of ConfiguredStructures
++ * @deprecated use {@link #getStructures()}
++ */
++ @Deprecated(forRemoval = true)
++ public @NotNull List<ConfiguredStructure> getConfiguredStructures() {
++ return this.legacy$structures;
++ }
++
++ /**
++ * Sets the list of ConfiguredStructures that are valid targets for the search.
++ *
++ * @param configuredStructures a list of ConfiguredStructure targets
++ * @deprecated use {@link #setStructures(List)}
++ */
++ @Deprecated(forRemoval = true)
++ public void setConfiguredStructures(@NotNull List<ConfiguredStructure> configuredStructures) {
++ this.setStructures(configuredStructures.stream().map(ConfiguredStructure::toModern).toList());
++ }
++
++ /**
++ * Gets an unmodifiable list of Structures that are valid targets for the search.
++ *
++ * @return an unmodifiable list of Structures
++ */
++ public @NotNull @UnmodifiableView List<Structure> getStructures() {
++ return Collections.unmodifiableList(this.structures);
++ }
++
++ /**
++ * Sets the list of Structures that are valid targets for the search.
++ *
++ * @param structures a list of Structures targets
++ */
++ public void setStructures(final @NotNull List<Structure> structures) {
++ this.structures = structures;
++ this.legacy$structures = new TransformingRandomAccessList<>(this.structures, ConfiguredStructure::fromModern, ConfiguredStructure::toModern);
++ }
++
++ /**
++ * Gets the search radius in which to attempt locating the structure.
++ * <p>
++ * 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.
++ * <p>
++ * This radius may not always be obeyed during the structure search!
++ *
++ * @param radius the search radius (in chunks)
++ */
++ public void setRadius(int radius) {
++ this.radius = radius;
++ }
++
++ /**
++ * Gets whether to search exclusively for unexplored structures.
++ * <p>
++ * 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.
++ * <p>
++ * As with the search radius, this value is not always obeyed.
++ *
++ * @param findUnexplored Whether to search for only unexplored structures.
++ */
++ public void setFindUnexplored(boolean findUnexplored) {
++ this.findUnexplored = findUnexplored;
++ }
++
++ @Override
++ public boolean isCancelled() {
++ return this.cancelled;
++ }
++
++ @Override
++ public void setCancelled(boolean cancel) {
++ this.cancelled = cancel;
++ }
++
++ @Override
++ public @NotNull HandlerList getHandlers() {
++ return HANDLER_LIST;
++ }
++
++ public static @NotNull HandlerList getHandlerList() {
++ return HANDLER_LIST;
++ }
++
++ /**
++ * Result for {@link StructuresLocateEvent}.
++ */
++ public record Result(@NotNull Position pos, @NotNull Structure structure) {
++
++ @Deprecated(forRemoval = true)
++ public Result(final @NotNull Location position, @NotNull ConfiguredStructure configuredStructure) {
++ this(position, configuredStructure.toModern());
++ }
++
++ @Deprecated(forRemoval = true)
++ public @NotNull ConfiguredStructure configuredStructure() {
++ return Objects.requireNonNull(ConfiguredStructure.fromModern(this.structure), "Please use the newer Structure API");
++ }
++
++ @Deprecated(forRemoval = true)
++ public @NotNull Location position() {
++ //noinspection DataFlowIssue
++ return this.pos.toLocation(null);
++ }
++ }
++}
+diff --git a/src/main/java/io/papermc/paper/world/structure/ConfiguredStructure.java b/src/main/java/io/papermc/paper/world/structure/ConfiguredStructure.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..1e7b53f9bc13dcd5a0a4a40004591e4f850496a0
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/world/structure/ConfiguredStructure.java
+@@ -0,0 +1,113 @@
++package io.papermc.paper.world.structure;
++
++import io.papermc.paper.registry.Reference;
++import java.util.Objects;
++import org.bukkit.Keyed;
++import org.bukkit.NamespacedKey;
++import org.bukkit.Registry;
++import org.bukkit.StructureType;
++import org.bukkit.generator.structure.Structure;
++import org.jetbrains.annotations.ApiStatus;
++import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.Nullable;
++
++/**
++ * Represents a configured structure each with a
++ * {@link StructureType}. Multiple ConfiguredStructures can have
++ * the same {@link StructureType}.
++ * @deprecated use {@link Structure}
++ */
++@Deprecated(forRemoval = true)
[email protected](inVersion = "1.21")
++public final class ConfiguredStructure implements Keyed {
++
++ public static final Reference<ConfiguredStructure> PILLAGER_OUTPOST = create("pillager_outpost");
++ public static final Reference<ConfiguredStructure> MINESHAFT = create("mineshaft");
++ public static final Reference<ConfiguredStructure> MINESHAFT_MESA = create("mineshaft_mesa");
++ public static final Reference<ConfiguredStructure> WOODLAND_MANSION = create("mansion");
++ public static final Reference<ConfiguredStructure> JUNGLE_TEMPLE = create("jungle_pyramid");
++ public static final Reference<ConfiguredStructure> DESERT_PYRAMID = create("desert_pyramid");
++ public static final Reference<ConfiguredStructure> IGLOO = create("igloo");
++ public static final Reference<ConfiguredStructure> SHIPWRECK = create("shipwreck");
++ public static final Reference<ConfiguredStructure> SHIPWRECK_BEACHED = create("shipwreck_beached");
++ public static final Reference<ConfiguredStructure> SWAMP_HUT = create("swamp_hut");
++ public static final Reference<ConfiguredStructure> STRONGHOLD = create("stronghold");
++ public static final Reference<ConfiguredStructure> OCEAN_MONUMENT = create("monument");
++ public static final Reference<ConfiguredStructure> OCEAN_RUIN_COLD = create("ocean_ruin_cold");
++ public static final Reference<ConfiguredStructure> OCEAN_RUIN_WARM = create("ocean_ruin_warm");
++ public static final Reference<ConfiguredStructure> FORTRESS = create("fortress");
++ public static final Reference<ConfiguredStructure> NETHER_FOSSIL = create("nether_fossil");
++ public static final Reference<ConfiguredStructure> END_CITY = create("end_city");
++ public static final Reference<ConfiguredStructure> BURIED_TREASURE = create("buried_treasure");
++ public static final Reference<ConfiguredStructure> BASTION_REMNANT = create("bastion_remnant");
++ public static final Reference<ConfiguredStructure> VILLAGE_PLAINS = create("village_plains");
++ public static final Reference<ConfiguredStructure> VILLAGE_DESERT = create("village_desert");
++ public static final Reference<ConfiguredStructure> VILLAGE_SAVANNA = create("village_savanna");
++ public static final Reference<ConfiguredStructure> VILLAGE_SNOWY = create("village_snowy");
++ public static final Reference<ConfiguredStructure> VILLAGE_TAIGA = create("village_taiga");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_STANDARD = create("ruined_portal");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_DESERT = create("ruined_portal_desert");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_JUNGLE = create("ruined_portal_jungle");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_SWAMP = create("ruined_portal_swamp");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_MOUNTAIN = create("ruined_portal_mountain");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_OCEAN = create("ruined_portal_ocean");
++ public static final Reference<ConfiguredStructure> RUINED_PORTAL_NETHER = create("ruined_portal_nether");
++ // public static final Reference<ConfiguredStructure> ANCIENT_CITY = create("ancient_city"); // TODO remove when upstream adds "jigsaw" StructureType
++
++ private final NamespacedKey key;
++ private final StructureType structureType;
++
++ ConfiguredStructure(@NotNull NamespacedKey key, @NotNull StructureType structureType) {
++ this.key = key;
++ this.structureType = structureType;
++ }
++
++ @Override
++ public @NotNull NamespacedKey getKey() {
++ return this.key;
++ }
++
++ /**
++ * Gets the structure type for this configure structure.
++ *
++ * @return the structure type
++ */
++ public @NotNull StructureType getStructureType() {
++ return this.structureType;
++ }
++
++ @Override
++ public boolean equals(Object o) {
++ if (this == o) return true;
++ if (o == null || getClass() != o.getClass()) return false;
++ ConfiguredStructure structure = (ConfiguredStructure) o;
++ return this.key.equals(structure.key) && this.structureType.equals(structure.structureType);
++ }
++
++ @Override
++ public int hashCode() {
++ return Objects.hash(this.key, this.structureType);
++ }
++
++ @Override
++ public String toString() {
++ return "ConfiguredStructure{" +
++ "key=" + this.key +
++ ", structureType=" + this.structureType +
++ '}';
++ }
++
++ private static @NotNull Reference<ConfiguredStructure> create(@NotNull String name) {
++ return Reference.create(Registry.CONFIGURED_STRUCTURE, NamespacedKey.minecraft(name));
++ }
++
++ @ApiStatus.Internal
++ public @NotNull Structure toModern() {
++ return Objects.requireNonNull(Registry.STRUCTURE.get(this.key));
++ }
++
++ @ApiStatus.Internal
++ public static @Nullable ConfiguredStructure fromModern(@NotNull Structure structure) {
++ return Registry.CONFIGURED_STRUCTURE.get(structure.getKey());
++ }
++}
+diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java
+index 91117cad12eee0bdaac8e0398a0f7f288ba27a40..43f410326d6d68242113e2fefe31af256889ed9c 100644
+--- a/src/main/java/org/bukkit/Registry.java
++++ b/src/main/java/org/bukkit/Registry.java
+@@ -292,6 +292,15 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
+ * @see GameEvent
+ */
+ Registry<GameEvent> GAME_EVENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.GAME_EVENT); // Paper
++ // Paper start
++ /**
++ * Configured structures.
++ * @see io.papermc.paper.world.structure.ConfiguredStructure
++ * @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#STRUCTURE}
++ */
++ @Deprecated(forRemoval = true)
++ Registry<io.papermc.paper.world.structure.ConfiguredStructure> CONFIGURED_STRUCTURE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.world.structure.ConfiguredStructure.class), "No registry present for ConfiguredStructure. This is a bug.");
++ // Paper end
+ /**
+ * Get the object by its key.
+ *