Skip to content

Commit

Permalink
Add for 1.21.4
Browse files Browse the repository at this point in the history
  • Loading branch information
dordsor21 committed Dec 26, 2024
1 parent 5face17 commit 03bb783
Show file tree
Hide file tree
Showing 5 changed files with 618 additions and 207 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import com.google.common.util.concurrent.Futures;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Lifecycle;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
Expand Down Expand Up @@ -61,13 +63,16 @@
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.generation.ConfiguredFeatureType;
import com.sk89q.worldedit.world.generation.StructureType;
import com.sk89q.worldedit.world.item.ItemType;
import net.minecraft.SharedConstants;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
Expand All @@ -82,6 +87,7 @@
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.util.RandomSource;
import net.minecraft.util.thread.BlockableEventLoop;
import net.minecraft.world.Clearable;
import net.minecraft.world.InteractionHand;
Expand All @@ -105,6 +111,10 @@
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.WorldOptions;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.PrimaryLevelData;
import net.minecraft.world.phys.BlockHitResult;
Expand Down Expand Up @@ -178,6 +188,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
private final PaperweightDataConverters dataFixer;
private final Watchdog watchdog;

private static final RandomSource random = RandomSource.create();

// ------------------------------------------------------------------------
// Code that may break between versions of Minecraft
// ------------------------------------------------------------------------
Expand Down Expand Up @@ -480,7 +492,6 @@ public BaseEntity getEntity(org.bukkit.entity.Entity entity) {
);
}

@Nullable
@Override
public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) {
checkNotNull(location);
Expand All @@ -489,48 +500,27 @@ public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
ServerLevel worldServer = craftWorld.getHandle();

String entityId = state.getType().id();

LinCompoundTag nativeTag = state.getNbt();
net.minecraft.nbt.CompoundTag tag;
if (nativeTag != null) {
tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag);
removeUnwantedEntityTagsRecursively(tag);
} else {
tag = new net.minecraft.nbt.CompoundTag();
}
Entity createdEntity = createEntityFromId(state.getType().id(), craftWorld.getHandle());

tag.putString("id", entityId);
if (createdEntity != null) {
LinCompoundTag nativeTag = state.getNbt();
if (nativeTag != null) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag);
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
readTagIntoEntity(tag, createdEntity);
}

Entity createdEntity = EntityType.loadEntityRecursive(tag, craftWorld.getHandle(), EntitySpawnReason.COMMAND, (loadedEntity) -> {
loadedEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
return loadedEntity;
});
createdEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());

if (createdEntity != null) {
worldServer.addFreshEntityWithPassengers(createdEntity, SpawnReason.CUSTOM);
worldServer.addFreshEntity(createdEntity, SpawnReason.CUSTOM);
return createdEntity.getBukkitEntity();
} else {
return null;
}
}

// This removes all unwanted tags from the main entity and all its passengers
private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) {
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}

// Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive
if (tag.contains("Passengers", LinTagId.LIST.id())) {
net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", LinTagId.COMPOUND.id());

for (int i = 0; i < nbttaglist.size(); ++i) {
removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i));
}
}
}

@Override
public Component getRichBlockName(BlockType blockType) {
return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId());
Expand Down Expand Up @@ -877,6 +867,20 @@ public void initializeRegistries() {
}
}

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

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

// BiomeCategories
Registry<Biome> biomeRegistry = server.registryAccess().lookupOrThrow(Registries.BIOME);
biomeRegistry.getTags().forEach(tag -> {
Expand Down Expand Up @@ -906,6 +910,60 @@ public void sendBiomeUpdates(World world, Iterable<BlockVector2> chunks) {
originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
}

public boolean generateFeature(ConfiguredFeatureType type, World world, EditSession session, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
ConfiguredFeature<?, ?> feature = originalWorld.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).getValue(ResourceLocation.tryParse(type.id()));
ServerChunkCache chunkManager = originalWorld.getChunkSource();
try (PaperweightServerLevelDelegateProxy.LevelAndProxy proxyLevel =
PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this)) {
return feature != null && feature.place(proxyLevel.level(), chunkManager.getGenerator(), random, new BlockPos(pt.x(), pt.y(), pt.z()));
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
}
}

public boolean generateStructure(StructureType type, World world, EditSession session, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle();
Registry<Structure> structureRegistry = originalWorld.registryAccess().lookupOrThrow(Registries.STRUCTURE);
Structure structure = structureRegistry.getValue(ResourceLocation.tryParse(type.id()));
if (structure == null) {
return false;
}

ServerChunkCache chunkManager = originalWorld.getChunkSource();
try (PaperweightServerLevelDelegateProxy.LevelAndProxy proxyLevel =
PaperweightServerLevelDelegateProxy.newInstance(session, originalWorld, this)) {
ChunkPos chunkPos = new ChunkPos(new BlockPos(pt.x(), pt.y(), pt.z()));
StructureStart structureStart = structure.generate(
structureRegistry.wrapAsHolder(structure), originalWorld.dimension(), originalWorld.registryAccess(),
chunkManager.getGenerator(), chunkManager.getGenerator().getBiomeSource(), chunkManager.randomState(),
originalWorld.getStructureManager(), originalWorld.getSeed(), chunkPos, 0,
proxyLevel.level(), biome -> true
);

if (!structureStart.isValid()) {
return false;
} 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(
proxyLevel.level(), originalWorld.structureManager(), chunkManager.getGenerator(),
originalWorld.getRandom(),
new BoundingBox(
chunkPosx.getMinBlockX(), originalWorld.getMinY(), chunkPosx.getMinBlockZ(),
chunkPosx.getMaxBlockX(), originalWorld.getMaxY(), chunkPosx.getMaxBlockZ()
), chunkPosx
)
);
return true;
}
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
}
}

// ------------------------------------------------------------------------
// Code that is less likely to break
// ------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 03bb783

Please sign in to comment.