mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
103 lines
3.2 KiB
Java
103 lines
3.2 KiB
Java
package com.hbm.util;
|
||
|
||
import net.minecraft.block.Block;
|
||
import net.minecraft.init.Blocks;
|
||
import net.minecraft.world.World;
|
||
import net.minecraft.world.chunk.Chunk;
|
||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* A snapshot of a 16×16×16 sub-chunk.
|
||
* @author mlbv
|
||
*/
|
||
public class SubChunkSnapshot {
|
||
/**
|
||
* A sub-chunk that contains only air.
|
||
*/
|
||
public static final SubChunkSnapshot EMPTY = new SubChunkSnapshot(new Block[]{Blocks.air}, null);
|
||
private final Block[] palette;
|
||
private final short[] data;
|
||
|
||
private SubChunkSnapshot(Block[] p, short[] d) {
|
||
this.palette = p;
|
||
this.data = d;
|
||
}
|
||
|
||
/**
|
||
* Creates a SubChunkSnapshot.
|
||
*
|
||
* @param world
|
||
* The World instance from which to retrieve the chunk.
|
||
* @param key
|
||
* The SubChunkKey identifying the sub-chunk.
|
||
* @param allowGeneration
|
||
* Whether to generate chunks. If false, attempting to retrieve a snapshot of a chunk that does not exist will return {@link SubChunkSnapshot#EMPTY}.
|
||
* @return
|
||
* A SubChunkSnapshot containing the palette and block data for the sub-chunk,
|
||
* or {@link SubChunkSnapshot#EMPTY} if the region contains only air.
|
||
*/
|
||
public static SubChunkSnapshot getSnapshot(World world, SubChunkKey key, boolean allowGeneration){
|
||
if (!world.getChunkProvider().chunkExists(key.getChunkXPos(), key.getChunkZPos()) && !allowGeneration) {
|
||
return SubChunkSnapshot.EMPTY;
|
||
}
|
||
Chunk chunk = world.getChunkProvider().provideChunk(key.getChunkXPos(), key.getChunkZPos());
|
||
ExtendedBlockStorage ebs = chunk.getBlockStorageArray()[key.getSubY()];
|
||
if (ebs == null || ebs.isEmpty()) return SubChunkSnapshot.EMPTY;
|
||
|
||
short[] data = new short[16 * 16 * 16];
|
||
List<Block> palette = new ArrayList<>();
|
||
palette.add(Blocks.air);
|
||
Map<Block, Short> idxMap = new HashMap<>();
|
||
idxMap.put(Blocks.air, (short) 0);
|
||
boolean allAir = true;
|
||
|
||
for (int ly = 0; ly < 16; ly++) {
|
||
for (int lz = 0; lz < 16; lz++) {
|
||
for (int lx = 0; lx < 16; lx++) {
|
||
Block block = ebs.getBlockByExtId(lx, ly, lz);
|
||
int idx;
|
||
if (block == Blocks.air) {
|
||
idx = 0;
|
||
} else {
|
||
allAir = false;
|
||
Short e = idxMap.get(block);
|
||
if (e == null) {
|
||
idxMap.put(block, (short) palette.size());
|
||
palette.add(block);
|
||
idx = palette.size() - 1;
|
||
} else {
|
||
idx = e;
|
||
}
|
||
}
|
||
data[(ly << 8) | (lz << 4) | lx] = (short) idx;
|
||
}
|
||
}
|
||
}
|
||
if (allAir) return SubChunkSnapshot.EMPTY;
|
||
return new SubChunkSnapshot(palette.toArray(new Block[0]), data);
|
||
}
|
||
|
||
/**
|
||
* Retrieves the Block at the specified local coordinates within this sub-chunk snapshot.
|
||
*
|
||
* @param x
|
||
* The local x-coordinate within the sub-chunk (0–15).
|
||
* @param y
|
||
* The local y-coordinate within the sub-chunk (0–15).
|
||
* @param z
|
||
* The local z-coordinate within the sub-chunk (0–15).
|
||
* @return
|
||
* The Block instance at the given position.
|
||
*/
|
||
public Block getBlock(int x, int y, int z) {
|
||
if (this == EMPTY || data == null) return Blocks.air;
|
||
short idx = data[(y << 8) | (z << 4) | x];
|
||
return (idx >= 0 && idx < palette.length) ? palette[idx] : Blocks.air;
|
||
}
|
||
}
|