papermc/patches/server/0714-Add-Feature-Generation-API.patch

123 lines
5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: dfsek <dfsek@protonmail.com>
Date: Sat, 19 Jun 2021 20:15:59 -0700
Subject: [PATCH] Add Feature Generation API
diff --git a/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java b/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java
new file mode 100644
index 0000000000000000000000000000000000000000..90a7c87d859d5d4f948a416eda0afbdf802e86ed
--- /dev/null
+++ b/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java
@@ -0,0 +1,94 @@
+package io.papermc.paper.world.generation;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.server.level.WorldGenRegion;
+import net.minecraft.world.entity.Mob;
+import net.minecraft.world.entity.MobSpawnType;
+import net.minecraft.world.entity.SpawnGroupData;
+import org.bukkit.World;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.craftbukkit.block.data.CraftBlockData;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+
+public class CraftProtoWorld implements ProtoWorld {
+ private WorldGenRegion region;
+
+ public CraftProtoWorld(WorldGenRegion region) {
+ this.region = region;
+ }
+
+ public void clearReference() {
+ region = null;
+ }
+
+ @Override
+ public void setBlockData(int x, int y, int z, @NotNull BlockData data) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().setBlock(position, ((CraftBlockData) data).getState(), 3);
+ }
+
+ @Override
+ public void scheduleBlockUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().getBlockTicks().scheduleTick(position, getDelegate().getBlockIfLoaded(position), 0);
+ }
+
+ @Override
+ public void scheduleFluidUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().getLiquidTicks().scheduleTick(position, getDelegate().getFluidState(position).getType(), 0);
+ }
+
+ @Override
+ public @NotNull World getWorld() {
+ // reading/writing the returned Minecraft world causes a deadlock.
+ // By implementing this, and covering it in warnings, we're assuming people won't be stupid, and
+ // if they are stupid, they'll figure it out pretty fast.
+ return getDelegate().getMinecraftWorld().getWorld();
+ }
+
+ @Override
+ public @NotNull BlockData getBlockData(int x, int y, int z) {
+ return CraftBlockData.fromData(getDelegate().getBlockState(new BlockPos(x, y, z)));
+ }
+
+ @Override
+ public int getCenterChunkX() {
+ return getDelegate().getCenter().x;
+ }
+
+ @Override
+ public int getCenterChunkZ() {
+ return getDelegate().getCenter().z;
+ }
+
+ @SuppressWarnings({"unchecked", "deprecation"})
+ @Override
+ public <T extends Entity> @NotNull T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @Nullable Consumer<T> function, CreatureSpawnEvent.@NotNull SpawnReason reason) throws IllegalArgumentException {
+ net.minecraft.world.entity.Entity entity = getDelegate().getMinecraftWorld().getWorld().createEntity(location.toLocation(getWorld()), clazz);
+ Objects.requireNonNull(entity, "Cannot spawn null entity");
+ if (entity instanceof Mob) {
+ ((Mob) entity).finalizeSpawn(getDelegate(), getDelegate().getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, (SpawnGroupData) null, null);
+ }
+
+ if (function != null) {
+ function.accept((T) entity.getBukkitEntity());
+ }
+
+ getDelegate().addEntity(entity, reason);
+ return (T) entity.getBukkitEntity();
+ }
+
+ @NotNull
+ private WorldGenRegion getDelegate() {
+ return Objects.requireNonNull(region, "Cannot access ProtoWorld after generation!");
+ }
+}
+
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
index 46ce973ca68420825316352ad4df907edf52bfec..65e9ecda0df8a22f93f5979a8c9ac74e9f0ba042 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
@@ -191,6 +191,12 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
if (this.generator.shouldGenerateDecorations()) {
this.delegate.applyBiomeDecoration(region, accessor);
}
+
+ // Paper start
+ io.papermc.paper.world.generation.CraftProtoWorld protoWorld = new io.papermc.paper.world.generation.CraftProtoWorld(region);
+ generator.generateDecorations(protoWorld);
+ protoWorld.clearReference(); // make sure people dont try to use the ProtoWorld after we're done with it.
+ // Paper end
}
@Override