Skip to content

Commit 0009970

Browse files
dordsor21me4502
andauthored
feat: allow placement of minecraft gen features and structures (#2364)
Co-authored-by: Maddy Miller <[email protected]>
1 parent d68afb5 commit 0009970

File tree

59 files changed

+6550
-550
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+6550
-550
lines changed

worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.mojang.datafixers.util.Either;
3030
import com.mojang.serialization.Lifecycle;
3131
import com.sk89q.jnbt.NBTConstants;
32+
import com.sk89q.worldedit.EditSession;
3233
import com.sk89q.worldedit.WorldEditException;
3334
import com.sk89q.worldedit.blocks.BaseItem;
3435
import com.sk89q.worldedit.blocks.BaseItemStack;
@@ -65,12 +66,15 @@
6566
import com.sk89q.worldedit.world.block.BlockStateHolder;
6667
import com.sk89q.worldedit.world.block.BlockType;
6768
import com.sk89q.worldedit.world.block.BlockTypes;
69+
import com.sk89q.worldedit.world.generation.ConfiguredFeatureType;
70+
import com.sk89q.worldedit.world.generation.StructureType;
6871
import com.sk89q.worldedit.world.item.ItemType;
6972
import net.minecraft.Util;
7073
import net.minecraft.core.BlockPos;
7174
import net.minecraft.core.Holder;
7275
import net.minecraft.core.HolderSet;
7376
import net.minecraft.core.Registry;
77+
import net.minecraft.core.SectionPos;
7478
import net.minecraft.core.registries.Registries;
7579
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
7680
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
@@ -95,6 +99,7 @@
9599
import net.minecraft.world.item.context.UseOnContext;
96100
import net.minecraft.world.level.ChunkPos;
97101
import net.minecraft.world.level.LevelSettings;
102+
import net.minecraft.world.level.WorldGenLevel;
98103
import net.minecraft.world.level.biome.Biome;
99104
import net.minecraft.world.level.block.Block;
100105
import net.minecraft.world.level.block.Blocks;
@@ -107,6 +112,10 @@
107112
import net.minecraft.world.level.chunk.LevelChunk;
108113
import net.minecraft.world.level.dimension.LevelStem;
109114
import net.minecraft.world.level.levelgen.WorldOptions;
115+
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
116+
import net.minecraft.world.level.levelgen.structure.BoundingBox;
117+
import net.minecraft.world.level.levelgen.structure.Structure;
118+
import net.minecraft.world.level.levelgen.structure.StructureStart;
110119
import net.minecraft.world.level.storage.LevelStorageSource;
111120
import net.minecraft.world.level.storage.PrimaryLevelData;
112121
import net.minecraft.world.phys.BlockHitResult;
@@ -644,7 +653,7 @@ public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
644653
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
645654

646655
@Override
647-
public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
656+
public boolean simulateItemUse(World world, BlockVector3 position, BaseItem item, Direction face) {
648657
CraftWorld craftWorld = (CraftWorld) world;
649658
ServerLevel worldServer = craftWorld.getHandle();
650659
ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack
@@ -894,6 +903,20 @@ public void initializeRegistries() {
894903
}
895904
}
896905

906+
// Features
907+
for (ResourceLocation name: server.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).keySet()) {
908+
if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) {
909+
ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString()));
910+
}
911+
}
912+
913+
// Structures
914+
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.STRUCTURE).keySet()) {
915+
if (StructureType.REGISTRY.get(name.toString()) == null) {
916+
StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString()));
917+
}
918+
}
919+
897920
// BiomeCategories
898921
Registry<Biome> biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME);
899922
biomeRegistry.getTagNames().forEach(tagKey -> {
@@ -923,6 +946,39 @@ public void sendBiomeUpdates(World world, Iterable<BlockVector2> chunks) {
923946
originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
924947
}
925948

949+
@Override
950+
public boolean generateFeature(ConfiguredFeatureType type, World world, EditSession session, BlockVector3 pt) {
951+
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
952+
ConfiguredFeature<?, ?> k = originalWorld.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(ResourceLocation.tryParse(type.id()));
953+
ServerChunkCache chunkManager = originalWorld.getChunkSource();
954+
WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this);
955+
return k != null && k.place(proxyLevel, chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z()));
956+
}
957+
958+
@Override
959+
public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) {
960+
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
961+
Structure k = originalWorld.registryAccess().registryOrThrow(Registries.STRUCTURE).get(ResourceLocation.tryParse(type.id()));
962+
if (k == null) {
963+
return false;
964+
}
965+
966+
ServerChunkCache chunkManager = originalWorld.getChunkSource();
967+
WorldGenLevel proxyLevel = PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this);
968+
ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.x(), pt.y(), pt.z()));
969+
StructureStart structureStart = k.generate(originalWorld.registryAccess(), chunkManager.getGenerator(), chunkManager.getGenerator().getBiomeSource(), chunkManager.randomState(), originalWorld.getStructureManager(), originalWorld.getSeed(), chunkPos, 0, proxyLevel, biome -> true);
970+
971+
if (!structureStart.isValid()) {
972+
return false;
973+
} else {
974+
BoundingBox boundingBox = structureStart.getBoundingBox();
975+
ChunkPos min = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.minX()), SectionPos.blockToSectionCoord(boundingBox.minZ()));
976+
ChunkPos max = new ChunkPos(SectionPos.blockToSectionCoord(boundingBox.maxX()), SectionPos.blockToSectionCoord(boundingBox.maxZ()));
977+
ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(proxyLevel, originalWorld.structureManager(), chunkManager.getGenerator(), originalWorld.getRandom(), new BoundingBox(chunkPosx.getMinBlockX(), originalWorld.getMinBuildHeight(), chunkPosx.getMinBlockZ(), chunkPosx.getMaxBlockX(), originalWorld.getMaxBuildHeight(), chunkPosx.getMaxBlockZ()), chunkPosx));
978+
return true;
979+
}
980+
}
981+
926982
// ------------------------------------------------------------------------
927983
// Code that is less likely to break
928984
// ------------------------------------------------------------------------
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
5+
import net.minecraft.core.Holder;
6+
import net.minecraft.server.MinecraftServer;
7+
import net.minecraft.server.level.ServerLevel;
8+
import net.minecraft.util.RandomSource;
9+
import net.minecraft.world.DifficultyInstance;
10+
import net.minecraft.world.entity.Entity;
11+
import net.minecraft.world.flag.FeatureFlagSet;
12+
import net.minecraft.world.level.biome.Biome;
13+
import net.minecraft.world.level.biome.BiomeManager;
14+
import net.minecraft.world.level.block.state.BlockState;
15+
import net.minecraft.world.level.border.WorldBorder;
16+
import net.minecraft.world.level.chunk.ChunkAccess;
17+
import net.minecraft.world.level.chunk.ChunkSource;
18+
import net.minecraft.world.level.chunk.ChunkStatus;
19+
import net.minecraft.world.level.lighting.LevelLightEngine;
20+
import net.minecraft.world.level.material.FluidState;
21+
import org.bukkit.craftbukkit.v1_20_R2.util.BlockStateListPopulator;
22+
import org.jetbrains.annotations.Nullable;
23+
24+
import javax.annotation.Nonnull;
25+
26+
public class FaweBlockStateListPopulator extends BlockStateListPopulator {
27+
28+
private final ServerLevel world;
29+
30+
public FaweBlockStateListPopulator(ServerLevel world) {
31+
super(world);
32+
this.world = world;
33+
}
34+
35+
@Override
36+
public long getSeed() {
37+
return world.getSeed();
38+
}
39+
40+
@Override
41+
@Nonnull
42+
public ServerLevel getLevel() {
43+
return world.getLevel();
44+
}
45+
46+
@Override
47+
@Nonnull
48+
public DifficultyInstance getCurrentDifficultyAt(final BlockPos pos) {
49+
return world.getCurrentDifficultyAt(pos);
50+
}
51+
52+
@Override
53+
public MinecraftServer getServer() {
54+
return world.getServer();
55+
}
56+
57+
@Override
58+
@Nonnull
59+
public ChunkSource getChunkSource() {
60+
return world.getChunkSource();
61+
}
62+
63+
@Override
64+
@Nonnull
65+
public RandomSource getRandom() {
66+
return world.getRandom();
67+
}
68+
69+
@Override
70+
public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) {
71+
return world.getChunk(chunkX, chunkZ, leastStatus, create);
72+
}
73+
74+
@Override
75+
@Nonnull
76+
public BiomeManager getBiomeManager() {
77+
return world.getBiomeManager();
78+
}
79+
80+
@Override
81+
@Nonnull
82+
public Holder<Biome> getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) {
83+
return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ);
84+
}
85+
86+
@Override
87+
public int getSeaLevel() {
88+
return world.getSeaLevel();
89+
}
90+
91+
@Override
92+
@Nonnull
93+
public FeatureFlagSet enabledFeatures() {
94+
return world.enabledFeatures();
95+
}
96+
97+
@Override
98+
public float getShade(final Direction direction, final boolean shaded) {
99+
return world.getShade(direction, shaded);
100+
}
101+
102+
@Override
103+
@Nonnull
104+
public LevelLightEngine getLightEngine() {
105+
return world.getLightEngine();
106+
}
107+
108+
@Nullable
109+
@Override
110+
public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) {
111+
return world.getChunkIfLoadedImmediately(x, z);
112+
}
113+
114+
@Override
115+
public BlockState getBlockStateIfLoaded(final BlockPos blockposition) {
116+
return world.getBlockStateIfLoaded(blockposition);
117+
}
118+
119+
@Override
120+
public FluidState getFluidIfLoaded(final BlockPos blockposition) {
121+
return world.getFluidIfLoaded(blockposition);
122+
}
123+
124+
@Override
125+
@Nonnull
126+
public WorldBorder getWorldBorder() {
127+
return world.getWorldBorder();
128+
}
129+
130+
@Override
131+
public boolean setBlock(final BlockPos pos, final BlockState state, final int flags, final int maxUpdateDepth) {
132+
return world.setBlock(pos, state, flags, maxUpdateDepth);
133+
}
134+
135+
@Override
136+
public boolean removeBlock(final BlockPos pos, final boolean move) {
137+
return world.removeBlock(pos, move);
138+
}
139+
140+
@Override
141+
public boolean destroyBlock(final BlockPos pos, final boolean drop, final Entity breakingEntity, final int maxUpdateDepth) {
142+
return world.destroyBlock(pos, drop, breakingEntity, maxUpdateDepth);
143+
}
144+
145+
@Override
146+
@Nonnull
147+
public BlockState getBlockState(final BlockPos pos) {
148+
return world.getBlockState(pos);
149+
}
150+
151+
@Override
152+
public boolean setBlock(final BlockPos pos, final BlockState state, final int flags) {
153+
return world.setBlock(pos, state, flags);
154+
}
155+
156+
}

0 commit comments

Comments
 (0)