diff --git a/Spigot-API-Patches/Add-StructureLocateEvent.patch b/Spigot-API-Patches/Add-StructureLocateEvent.patch new file mode 100644 index 0000000000..786e859e43 --- /dev/null +++ b/Spigot-API-Patches/Add-StructureLocateEvent.patch @@ -0,0 +1,167 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: dfsek +Date: Tue, 15 Sep 2020 21:59:16 -0700 +Subject: [PATCH] Add StructureLocateEvent + + +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..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/world/StructureLocateEvent.java +@@ -0,0 +0,0 @@ ++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.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * Called before a structure/feature is located. ++ * This happens when: ++ * ++ */ ++public class StructureLocateEvent extends WorldEvent implements Cancellable { ++ private static final HandlerList handlers = new HandlerList(); ++ private final Location origin; ++ private Location result = null; ++ private StructureType type; ++ private int radius; ++ private boolean findUnexplored; ++ private boolean cancelled = false; ++ ++ 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; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ /** ++ * Gets the location set as the structure location, if it was defined. ++ *

++ * Returns {@code null} if it has not been set by {@link StructureLocateEvent#setResult(Location)}. ++ * Since this event fires before the search is done, the actual location is unknown at this point. ++ * ++ * @return The result location, if it has been set. null if it has not. ++ * @see World#locateNearestStructure(Location, StructureType, int, boolean) ++ */ ++ @Nullable ++ public Location getResult() { ++ return 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 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 origin; ++ } ++ ++ /** ++ * Gets the search radius in which to attempt locating the structure. ++ *

++ * This radius may not always be obeyed during the structure search! ++ * ++ * @return the search radius. ++ */ ++ public int getRadius() { ++ return 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. ++ */ ++ public void setRadius(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 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(boolean findUnexplored) { ++ this.findUnexplored = findUnexplored; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++} diff --git a/Spigot-Server-Patches/Add-StructureLocateEvent.patch b/Spigot-Server-Patches/Add-StructureLocateEvent.patch new file mode 100644 index 0000000000..b8f85c6922 --- /dev/null +++ b/Spigot-Server-Patches/Add-StructureLocateEvent.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: dfsek +Date: Wed, 16 Sep 2020 01:12:29 -0700 +Subject: [PATCH] Add StructureLocateEvent + + +diff --git a/src/main/java/net/minecraft/server/ChunkGenerator.java b/src/main/java/net/minecraft/server/ChunkGenerator.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/ChunkGenerator.java ++++ b/src/main/java/net/minecraft/server/ChunkGenerator.java +@@ -0,0 +0,0 @@ package net.minecraft.server; + + import com.google.common.collect.Lists; + import com.mojang.serialization.Codec; ++import io.papermc.paper.event.world.StructureLocateEvent; // Paper - Add import due to naming conflict. + import java.util.BitSet; + import java.util.Iterator; + import java.util.List; +@@ -0,0 +0,0 @@ public abstract class ChunkGenerator { + + @Nullable + public BlockPosition findNearestMapFeature(WorldServer worldserver, StructureGenerator structuregenerator, BlockPosition blockposition, int i, boolean flag) { ++ // Paper start ++ org.bukkit.World world = worldserver.getWorld(); ++ org.bukkit.Location originLocation = new org.bukkit.Location(world, blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ StructureLocateEvent event = new StructureLocateEvent(world, originLocation, org.bukkit.StructureType.getStructureTypes().get(structuregenerator.i()), i, flag); ++ if(!event.callEvent()) return null; ++ // If event call set a final location, skip structure finding and just return set result. ++ if(event.getResult() != null) return new BlockPosition(event.getResult().getBlockX(), event.getResult().getBlockY(), event.getResult().getBlockZ()); ++ // Get origin location (re)defined by event call. ++ blockposition = new BlockPosition(event.getOrigin().getBlockX(), event.getOrigin().getBlockY(), event.getOrigin().getBlockZ()); ++ // Get world (re)defined by event call. ++ worldserver = ((org.bukkit.craftbukkit.CraftWorld) event.getOrigin().getWorld()).getHandle(); ++ // Get radius and whether to find unexplored structures (re)defined by event call. ++ i = event.getRadius(); ++ flag = event.shouldFindUnexplored(); ++ structuregenerator = StructureGenerator.a.get(event.getType().getName()); ++ // Paper end + if (!this.b.a(structuregenerator)) { + return null; + } else if (structuregenerator == StructureGenerator.STRONGHOLD) {