Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.modificationstation.stationapi.impl.world.chunk.FlattenedChunk;

import java.nio.ByteBuffer;
import java.util.Arrays;

public class FlattenedClientPlayNetworkHandler extends StationFlatteningPacketHandler {

Expand All @@ -31,6 +32,9 @@ public void onMapChunk(FlattenedChunkDataS2CPacket packet) {
world.clearBlockResets(fromX, world.getBottomY(), fromZ, fromX + 15, world.getTopY() - 1, fromZ + 15);
Chunk chunk = world.getChunk(packet.chunkX, packet.chunkZ);
if (chunk instanceof FlattenedChunk flatteningChunk) {
if (flatteningChunk.blockIdCache != null) {
Arrays.fill(flatteningChunk.blockIdCache, (short) -1);
}
ByteBuffer buf = ByteBuffer.wrap(packet.sectionsData);
for (int i = 0; i < world.countVerticalSections(); i++)
flatteningChunk.getOrCreateSection(world.sectionIndexToCoord(i) << 4, true).readDataPacket(buf);
Expand Down Expand Up @@ -89,6 +93,9 @@ public void onChunkSection(FlattenedChunkSectionDataS2CPacket packet) {
world.clearBlockResets(fromX, fromY, fromZ, fromX + 15, fromY + 15, fromZ + 15);
Chunk chunk = world.getChunk(packet.chunkX, packet.chunkZ);
if (chunk instanceof FlattenedChunk flatteningChunk) {
if (flatteningChunk.blockIdCache != null) {
Arrays.fill(flatteningChunk.blockIdCache, (short) -1);
}
ByteBuffer buf = ByteBuffer.wrap(packet.sectionData);
flatteningChunk.getOrCreateSection(fromY, true).readDataPacket(buf);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public class ChunkSection {
private final NibbleArray skyLightArray = new NibbleArray(4096);
private final NibbleArray blockLightArray = new NibbleArray(4096);

// Used for Block ID Cache
public int worldBottomY = 0;
public short[] blockIdCache = null;

public ChunkSection(int chunkPos, PalettedContainer<BlockState> blockStateContainer) {
this.yOffset = (short) ChunkSection.blockCoordFromChunkCoord(chunkPos);
this.blockStateContainer = blockStateContainer;
Expand All @@ -50,6 +54,10 @@ public BlockState getBlockState(int x, int y, int z) {
// }

public BlockState setBlockState(int x, int y, int z, BlockState state) {
if (blockIdCache != null) {
blockIdCache[x | (z << 4) | ((y - worldBottomY) + this.yOffset << 8)] = -1;
}

BlockState blockState = this.blockStateContainer.swap(x, y, z, state);

// FluidState fluidState = blockState2.getFluidState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import net.modificationstation.stationapi.api.event.block.BlockEvent;
import net.modificationstation.stationapi.api.event.world.BlockSetEvent;
import net.modificationstation.stationapi.api.event.world.MetaSetEvent;
import net.modificationstation.stationapi.api.registry.BlockRegistry;
import net.modificationstation.stationapi.api.util.math.MutableBlockPos;
import net.modificationstation.stationapi.mixin.flattening.ChunkAccessor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class FlattenedChunk extends Chunk {
Expand All @@ -31,6 +33,14 @@ public class FlattenedChunk extends Chunk {
public final short lastBlock;
private final short[] stationHeightmap = new short[256];

/**
* short cache will only be able to address 32767 IDs
* If the block registry next id is larger than that, it will be disabled
*/
private static final boolean canUseShortBlockIdCache = BlockRegistry.INSTANCE.getNextId() < 32767;
public final short[] blockIdCache;
public final int bottomY;

public FlattenedChunk(World world, int xPos, int zPos) {
super(world, xPos, zPos);
int countSections = world.countVerticalSections();
Expand All @@ -41,6 +51,14 @@ public FlattenedChunk(World world, int xPos, int zPos) {
for(short i = 0; i < entities.length; i++) {
this.entities[i] = new ArrayList<>();
}

bottomY = world.getBottomY();
if (canUseShortBlockIdCache) {
blockIdCache = new short[16 * 16 * world.getHeight()];
Arrays.fill(blockIdCache, (short) -1);
} else {
blockIdCache = null;
}
}

public void fromLegacy(byte[] tiles) {
Expand Down Expand Up @@ -99,10 +117,11 @@ public boolean isAboveMaxHeight(int relX, int y, int relZ) {
return y >= getShortHeight(relX, relZ);
}

private ChunkSection getSection(int y) {
protected ChunkSection getSection(int y) {
if (y < firstBlock || y > lastBlock) {
return null;
}

return sections[world.sectionCoordToIndex(y >> 4)];
}

Expand All @@ -129,6 +148,10 @@ public ChunkSection getOrCreateSection(int y, boolean fillSkyLight) {
}
sections[index] = section;
}

section.blockIdCache = blockIdCache;
section.worldBottomY = bottomY;

return section;
}

Expand Down Expand Up @@ -313,7 +336,24 @@ private void updateHeightMap(int x, int y, int z) {

@Override
public int getBlockId(int x, int y, int z) {
return getBlockState(x, y, z).getBlock().id;
if (blockIdCache == null) {
// TODO: Change to .block field access once various things gets merged
return getBlockState(x, y, z).getBlock().id;
}

int key = x | (z << 4) | ((y - bottomY) << 8);

if (key < 0 || key >= blockIdCache.length) {
System.err.println("x = " + x + ", y = " + y + ", z = " + z);
return 0;
}

if (blockIdCache[key] == -1) {
// TODO: Change to .block field access once various things gets merged
blockIdCache[key] = (short) getBlockState(x, y, z).getBlock().id;
}

return blockIdCache[key];
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ public int size() {
return this.keyToEntry.size();
}

public int getNextId() {
return this.nextId;
}

@Override
public Lifecycle getEntryLifecycle(T entry) {
return this.entryToLifecycle.get(entry);
Expand Down