Skip to content

Commit

Permalink
FAWE-inate
Browse files Browse the repository at this point in the history
  • Loading branch information
dordsor21 committed Oct 24, 2023
1 parent f2f01eb commit 594527f
Show file tree
Hide file tree
Showing 28 changed files with 1,948 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import org.bukkit.craftbukkit.v1_17_R1.util.BlockStateListPopulator;
import org.jetbrains.annotations.Nullable;

public class FaweBlockStateListPopulator extends BlockStateListPopulator {

private final ServerLevel world;

public FaweBlockStateListPopulator(ServerLevel world) {
super(world);
this.world = world;
}

@Override
public long getSeed() {
return world.getSeed();
}

@Override
public ServerLevel getLevel() {
return world.getLevel();
}

@Override
public MinecraftServer getServer() {
return world.getServer();
}

@Override
public ChunkSource getChunkSource() {
return world.getChunkSource();
}

@Override
public ChunkAccess getChunk(final int chunkX, final int chunkZ, final ChunkStatus leastStatus, final boolean create) {
return world.getChunk(chunkX, chunkZ, leastStatus, create);
}

@Override
public BiomeManager getBiomeManager() {
return world.getBiomeManager();
}

@Override
public Biome getUncachedNoiseBiome(final int biomeX, final int biomeY, final int biomeZ) {
return world.getUncachedNoiseBiome(biomeX, biomeY, biomeZ);
}

@Override
public int getSeaLevel() {
return world.getSeaLevel();
}

@Override
public float getShade(final Direction direction, final boolean shaded) {
return world.getShade(direction, shaded);
}

@Override
public LevelLightEngine getLightEngine() {
return world.getLightEngine();
}

@Nullable
@Override
public ChunkAccess getChunkIfLoadedImmediately(final int x, final int z) {
return world.getChunkIfLoadedImmediately(x, z);
}

@Override
public FluidState getFluidIfLoaded(final BlockPos blockposition) {
return world.getFluidIfLoaded(blockposition);
}

@Override
public WorldBorder getWorldBorder() {
return world.getWorldBorder();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.blocks.BaseItemStack;
Expand Down Expand Up @@ -53,35 +54,48 @@
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.generation.ConfiguredFeatureType;
import com.sk89q.worldedit.world.generation.StructureType;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.core.WritableRegistry;
import net.minecraft.nbt.IntTag;
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
import net.minecraft.world.level.levelgen.feature.configurations.StructureFeatureConfiguration;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_17_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
Expand All @@ -105,6 +119,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.Random;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -589,6 +604,164 @@ public boolean generateTree(
return true;
}

@Override
public boolean generateFeature(ConfiguredFeatureType feature, World world, EditSession editSession, BlockVector3 pt) {
ServerLevel serverLevel = ((CraftWorld) world).getHandle();
ChunkGenerator generator = serverLevel.getMinecraftWorld().getChunkSource().getGenerator();
FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel);
ConfiguredFeature<?, ?> configuredFeature = serverLevel
.registryAccess()
.registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY)
.get(ResourceLocation.tryParse(feature.getId()));

Map<BlockPos, CraftBlockState> placed = TaskManager.taskManager().sync(() -> {
serverLevel.captureTreeGeneration = true;
serverLevel.captureBlockStates = true;
try {
if (!configuredFeature.place(
populator,
generator,
serverLevel.random,
new BlockPos(pt.getX(), pt.getY(), pt.getZ())
)) {
return null;
}
return populator.getList().stream().collect(Collectors.toMap(CraftBlockState::getPosition,
craftBlockState -> craftBlockState
));
} finally {
serverLevel.captureBlockStates = false;
serverLevel.captureTreeGeneration = false;
serverLevel.capturedBlockStates.clear();
}
});

return placeFeatureIntoSession(editSession, populator, placed);
//FAWE end
}

@Override
public boolean generateStructure(StructureType type, World world, EditSession editSession, BlockVector3 pt) {
ServerLevel serverLevel = ((CraftWorld) world).getHandle();
ConfiguredStructureFeature k = serverLevel
.registryAccess()
.registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY)
.get(ResourceLocation.tryParse(type.getId()));
if (k == null) {
return false;
}

ServerChunkCache chunkManager = serverLevel.getChunkSource();

BlockPos pos = new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
ChunkPos chunkPos = new ChunkPos(pos);

//FAWE start
FaweBlockStateListPopulator populator = new FaweBlockStateListPopulator(serverLevel);
Map<BlockPos, CraftBlockState> placed = TaskManager.taskManager().sync(() -> {
serverLevel.captureTreeGeneration = true;
serverLevel.captureBlockStates = true;
try {
StructureStart structureStart = k.generate(
serverLevel.registryAccess(),
chunkManager.getGenerator(),
chunkManager.getGenerator().getBiomeSource(),
serverLevel.getStructureManager(),
serverLevel.getSeed(),
chunkPos,
serverLevel.getBiome(pos),
0,
(StructureFeatureConfiguration) k.config,
serverLevel
);
if (!structureStart.isValid()) {
return null;
} else {
BoundingBox boundingBox = structureStart.getBoundingBox();
ChunkPos min = new ChunkPos(
SectionPos.blockToSectionCoord(boundingBox.minX()),
SectionPos.blockToSectionCoord(boundingBox.minZ())
);
ChunkPos max = new ChunkPos(
SectionPos.blockToSectionCoord(boundingBox.maxX()),
SectionPos.blockToSectionCoord(boundingBox.maxZ())
);
ChunkPos.rangeClosed(min, max).forEach((chunkPosx) -> structureStart.placeInChunk(
serverLevel,
serverLevel.structureFeatureManager(),
chunkManager.getGenerator(),
serverLevel.getRandom(),
new BoundingBox(
chunkPosx.getMinBlockX(),
serverLevel.getMinBuildHeight(),
chunkPosx.getMinBlockZ(),
chunkPosx.getMaxBlockX(),
serverLevel.getMaxBuildHeight(),
chunkPosx.getMaxBlockZ()
),
chunkPosx
));
return populator.getList().stream().collect(Collectors.toMap(
CraftBlockState::getPosition,
craftBlockState -> craftBlockState
));
}
} finally {
serverLevel.captureBlockStates = false;
serverLevel.captureTreeGeneration = false;
serverLevel.capturedBlockStates.clear();
}
});

return placeFeatureIntoSession(editSession, populator, placed);
//FAWE end
}

private boolean placeFeatureIntoSession(
final EditSession editSession,
final FaweBlockStateListPopulator populator,
final Map<BlockPos, CraftBlockState> placed
) {
if (placed == null || placed.isEmpty()) {
return false;
}

for (Map.Entry<BlockPos, CraftBlockState> entry : placed.entrySet()) {
CraftBlockState craftBlockState = entry.getValue();
if (entry.getValue() == null) {
continue;
}
BlockPos pos = entry.getKey();
editSession.setBlock(pos.getX(), pos.getY(), pos.getZ(), BukkitAdapter.adapt(craftBlockState.getBlockData()));
BlockEntity blockEntity = populator.getBlockEntity(pos);
if (blockEntity != null) {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
blockEntity.save(tag);
editSession.setTile(pos.getX(), pos.getY(), pos.getZ(), (CompoundTag) toNative(tag));
}
}
return true;
}

@Override
public void setupFeatures() {
DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer();

// Features
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY).keySet()) {
if (ConfiguredFeatureType.REGISTRY.get(name.toString()) == null) {
ConfiguredFeatureType.REGISTRY.register(name.toString(), new ConfiguredFeatureType(name.toString()));
}
}

// Structures
for (ResourceLocation name : server.registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY).keySet()) {
if (StructureType.REGISTRY.get(name.toString()) == null) {
StructureType.REGISTRY.register(name.toString(), new StructureType(name.toString()));
}
}
}

@Override
public List<org.bukkit.entity.Entity> getEntities(org.bukkit.World world) {
// Quickly add each entity to a list copy.
Expand Down
Loading

0 comments on commit 594527f

Please sign in to comment.