Files
Postea/src/main/java/com/colen/postea/API/ChunkFixerUtility.java
T

186 lines
7.2 KiB
Java
Raw Normal View History

2023-10-23 15:37:55 +01:00
package com.colen.postea.API;
2023-10-29 23:53:12 +00:00
import akka.japi.Pair;
import net.minecraft.block.Block;
2023-10-29 01:06:18 +01:00
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
2023-10-29 01:37:24 +00:00
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
2023-10-29 18:40:08 +00:00
import java.util.stream.Collectors;
2023-10-29 01:37:24 +00:00
2023-10-23 15:37:55 +01:00
public class ChunkFixerUtility {
2023-10-29 01:06:18 +01:00
2023-10-29 20:40:26 +00:00
public static void processChunkNBT(NBTTagCompound compound) {
2023-10-30 01:28:47 +00:00
transformTileEntities(compound);
transformNormalBlocks(compound);
}
private static void transformNormalBlocks(NBTTagCompound compound) {
NBTTagCompound level = compound.getCompoundTag("Level");
NBTTagList sections = level.getTagList("Sections", 10);
for (int i = 0; i < sections.tagCount(); i++) {
NBTTagCompound section = sections.getCompoundTagAt(i);
byte[] blockArray = section.getByteArray("Blocks16");
byte[] metadataArray = section.getByteArray("Data");
for (int index = 0; index < blockArray.length / 2; index++) {
int blockId = ((blockArray[index * 2] & 0xFF) << 8) | (blockArray[index * 2 + 1] & 0xFF);
byte metadata = (byte) ((index & 1) == 0 ? (metadataArray[index / 2] & 0x0F) : ((metadataArray[index / 2] & 0xF0) >> 4));
Pair<Integer, Integer> output = BlockReplacementManager.getBlockReplacement(blockId, metadata);
if (output != null) {
setBlockInfo(Block.getBlockById(output.first()), index, blockArray);
setMetadata(output.second(), index, metadataArray);
}
}
}
2023-10-29 01:06:18 +01:00
}
2023-10-29 01:37:24 +00:00
/**
* Replaces specified tile entities with a block in the chunk NBT data.
*
* @param chunkNBT The chunk's NBT data.
*/
2023-10-30 01:28:47 +00:00
public static void transformTileEntities(NBTTagCompound chunkNBT) {
2023-10-29 20:20:12 +00:00
NBTTagCompound level = chunkNBT.getCompoundTag("Level");
2023-10-29 23:53:12 +00:00
Pair<List<ConversionInfo>, NBTTagList> output = adjustTileEntities(level.getTagList("TileEntities", 10));
List<ConversionInfo> conversionInfoList = output.first();
NBTTagList tileEntities = output.second();
if (tileEntities.tagCount() > 0) {
level.setTag("TileEntities", tileEntities);
}
2023-10-29 01:37:24 +00:00
2023-10-29 18:40:08 +00:00
int chunkXPos = level.getInteger("xPos") * 16; // Assuming each chunk is 16 blocks along x-axis
int chunkZPos = level.getInteger("zPos") * 16; // Assuming each chunk is 16 blocks along z-axis
2023-10-29 20:20:12 +00:00
NBTTagList sections = level.getTagList("Sections", 10);
2023-10-29 18:40:08 +00:00
for (int i = 0; i < sections.tagCount(); i++) {
NBTTagCompound section = sections.getCompoundTagAt(i);
2023-10-29 20:20:12 +00:00
processSection(section, conversionInfoList, chunkXPos, chunkZPos);
}
}
2023-10-29 18:40:08 +00:00
2023-10-29 20:20:12 +00:00
private static void processSection(NBTTagCompound section, List<ConversionInfo> conversionInfoList, int chunkXPos, int chunkZPos) {
byte[] blockArray = section.getByteArray("Blocks16");
byte[] metadataArray = section.getByteArray("Data");
byte y = section.getByte("Y");
List<ConversionInfo> filteredList = filterConversionInfosByY(conversionInfoList, y);
for (ConversionInfo info : filteredList) {
int[] localCoords = convertToChunkLocalCoordinates(info, y, chunkXPos, chunkZPos);
int index = computeBlockIndex(localCoords);
2023-10-29 20:40:26 +00:00
setBlockInfo(info.blockInfo.block, index, blockArray);
setMetadata(info.blockInfo.metadata, index, metadataArray);
2023-10-29 20:20:12 +00:00
}
}
private static List<ConversionInfo> filterConversionInfosByY(List<ConversionInfo> conversionInfoList, byte y) {
return conversionInfoList.stream()
.filter(info -> info.y >= y * 16 && info.y < (y + 1) * 16)
.collect(Collectors.toList());
}
private static int[] convertToChunkLocalCoordinates(ConversionInfo info, byte y, int chunkXPos, int chunkZPos) {
int tileX = info.x - chunkXPos;
int tileY = info.y - y * 16;
int tileZ = info.z - chunkZPos;
return new int[]{tileX, tileY, tileZ};
}
private static int computeBlockIndex(int[] localCoords) {
return localCoords[1] * 256 + localCoords[2] * 16 + localCoords[0];
}
2023-10-29 20:40:26 +00:00
private static void setBlockInfo(Block block, int index, byte[] blockArray) {
int blockID = Block.getIdFromBlock(block);
2023-10-29 20:20:12 +00:00
blockArray[index * 2] = (byte) ((blockID >> 8) & 0xFF);
blockArray[index * 2 + 1] = (byte) (blockID & 0xFF);
}
2023-10-29 20:40:26 +00:00
private static void setMetadata(int metadata, int index, byte[] metadataArray) {
2023-10-29 20:20:12 +00:00
int metadataIndex = index / 2;
byte currentMetadataByte = metadataArray[metadataIndex];
2023-10-29 18:40:08 +00:00
2023-10-29 20:20:12 +00:00
if ((index & 1) == 0) { // Even
currentMetadataByte &= 0xF0;
2023-10-29 20:40:26 +00:00
currentMetadataByte |= (metadata & 0x0F);
2023-10-29 20:20:12 +00:00
} else { // Odd
currentMetadataByte &= 0x0F;
2023-10-29 20:40:26 +00:00
currentMetadataByte |= ((metadata << 4) & 0xF0);
2023-10-29 18:40:08 +00:00
}
2023-10-29 20:20:12 +00:00
metadataArray[metadataIndex] = currentMetadataByte;
2023-10-29 18:40:08 +00:00
}
2023-10-29 23:53:12 +00:00
private static Pair<List<ConversionInfo>, NBTTagList> adjustTileEntities(NBTTagList tileEntities) {
2023-10-29 18:40:08 +00:00
List<ConversionInfo> conversionInfo = new ArrayList<>();
2023-10-29 23:53:12 +00:00
NBTTagList tileEntitiesCopy = new NBTTagList();
2023-10-29 18:40:08 +00:00
2023-10-29 01:37:24 +00:00
for (int i = 0; i < tileEntities.tagCount(); i++) {
NBTTagCompound tileEntity = tileEntities.getCompoundTagAt(i);
String tileEntityId = tileEntity.getString("id");
2023-10-29 21:18:26 +00:00
// Check if we have a transformer registered for this tile entity ID
Function<NBTTagCompound, BlockInfo> transformationFunction = TileEntityReplacementManager.getTileEntityToNormalBlockTransformerFunction(tileEntityId);
if (transformationFunction != null) {
2023-10-29 01:37:24 +00:00
int x = tileEntity.getInteger("x");
int y = tileEntity.getInteger("y");
int z = tileEntity.getInteger("z");
BlockInfo blockInfo = transformationFunction.apply(tileEntity);
2023-10-29 23:53:12 +00:00
if (blockInfo.tileTransformer != null) {
tileEntitiesCopy.appendTag(blockInfo.tileTransformer.apply(tileEntity));
} // Otherwise they are removed, therefore not appended.
2023-10-29 18:40:08 +00:00
conversionInfo.add(new ConversionInfo(x, y, z, blockInfo));
2023-10-29 01:37:24 +00:00
}
}
2023-10-29 18:40:08 +00:00
2023-10-29 23:53:12 +00:00
return new Pair<>(conversionInfo, tileEntitiesCopy);
2023-10-29 01:37:24 +00:00
}
2023-10-29 01:37:24 +00:00
public static class ConversionInfo {
public final int x;
public final int y;
public final int z;
public final BlockInfo blockInfo;
2023-10-29 01:37:24 +00:00
public ConversionInfo(int x, int y, int z, BlockInfo blockInfo) {
this.x = x;
this.y = y;
this.z = z;
this.blockInfo = blockInfo;
}
}
public static class BlockInfo {
public final Block block;
public final int metadata;
2023-10-29 23:53:12 +00:00
public final Function<NBTTagCompound, NBTTagCompound> tileTransformer;
public BlockInfo(Block block, int metadata, Function<NBTTagCompound, NBTTagCompound> tileTransformer) {
this.block = block;
this.metadata = metadata;
this.tileTransformer = tileTransformer;
}
2023-10-29 01:06:18 +01:00
2023-10-29 01:37:24 +00:00
public BlockInfo(Block block, int metadata) {
this.block = block;
this.metadata = metadata;
2023-10-29 23:53:12 +00:00
this.tileTransformer = null;
2023-10-29 01:06:18 +01:00
}
}
2023-10-29 18:40:08 +00:00
}