Search in sources :

Example 1 with BitArrayUnstretched

use of com.fastasyncworldedit.core.math.BitArrayUnstretched in project FastAsyncWorldEdit by IntellectualSites.

the class PaperweightPlatformAdapter method newChunkSection.

public static LevelChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastMode, CachedBukkitAdapter adapter) {
    if (set == null) {
        return newChunkSection(layer);
    }
    final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
    final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get();
    final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get();
    final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get();
    try {
        int num_palette;
        final short[] nonEmptyBlockCount = fastMode ? new short[1] : null;
        if (get == null) {
            num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, nonEmptyBlockCount);
        } else {
            num_palette = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, get, set, adapter, nonEmptyBlockCount);
        }
        // BlockStates
        int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
        if (Settings.settings().PROTOCOL_SUPPORT_FIX || num_palette != 1) {
            // Protocol support breaks <4 bits per entry
            bitsPerEntry = Math.max(bitsPerEntry, 4);
        } else {
            // For some reason minecraft needs 4096 bits to store 0 entries
            bitsPerEntry = Math.max(bitsPerEntry, 1);
        }
        if (bitsPerEntry > 8) {
            bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1);
        }
        final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
        final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong);
        if (num_palette == 1) {
            for (int i = 0; i < blockBitArrayEnd; i++) {
                blockStates[i] = 0;
            }
        } else {
            final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates);
            bitArray.fromRaw(blocksCopy);
        }
        LevelChunkSection levelChunkSection = newChunkSection(layer);
        // set palette & data bits
        final PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = levelChunkSection.getStates();
        // private DataPalette<T> h;
        // protected DataBits a;
        final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd);
        final BitStorage nmsBits = new BitStorage(bitsPerEntry, 4096, bits);
        final Palette<net.minecraft.world.level.block.state.BlockState> blockStatePalettedContainer;
        if (bitsPerEntry <= 4) {
            blockStatePalettedContainer = new LinearPalette<>(Block.BLOCK_STATE_REGISTRY, bitsPerEntry, dataPaletteBlocks, NbtUtils::readBlockState);
        } else if (bitsPerEntry < 9) {
            blockStatePalettedContainer = new HashMapPalette<>(Block.BLOCK_STATE_REGISTRY, bitsPerEntry, dataPaletteBlocks, NbtUtils::readBlockState, NbtUtils::writeBlockState);
        } else {
            blockStatePalettedContainer = LevelChunkSection.GLOBAL_BLOCKSTATE_PALETTE;
        }
        // set palette if required
        if (bitsPerEntry < 9) {
            for (int i = 0; i < num_palette; i++) {
                final int ordinal = paletteToBlock[i];
                blockToPalette[ordinal] = Integer.MAX_VALUE;
                final BlockState state = BlockTypesCache.states[ordinal];
                final net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState();
                blockStatePalettedContainer.idFor(blockState);
            }
        }
        try {
            fieldStorage.set(dataPaletteBlocks, nmsBits);
            fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer);
            fieldBits.set(dataPaletteBlocks, bitsPerEntry);
        } catch (final IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        if (!fastMode) {
            levelChunkSection.recalcBlockCounts();
        } else {
            try {
                fieldNonEmptyBlockCount.set(levelChunkSection, nonEmptyBlockCount[0]);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return levelChunkSection;
    } catch (final Throwable e) {
        throw e;
    } finally {
        Arrays.fill(blockToPalette, Integer.MAX_VALUE);
        Arrays.fill(paletteToBlock, Integer.MAX_VALUE);
        Arrays.fill(blockStates, 0);
        Arrays.fill(blocksCopy, 0);
    }
}
Also used : NbtUtils(net.minecraft.nbt.NbtUtils) BitArrayUnstretched(com.fastasyncworldedit.core.math.BitArrayUnstretched) BlockState(com.sk89q.worldedit.world.block.BlockState) HashMapPalette(net.minecraft.world.level.chunk.HashMapPalette) LevelChunkSection(net.minecraft.world.level.chunk.LevelChunkSection) BitStorage(net.minecraft.util.BitStorage)

Aggregations

BitArrayUnstretched (com.fastasyncworldedit.core.math.BitArrayUnstretched)1 BlockState (com.sk89q.worldedit.world.block.BlockState)1 NbtUtils (net.minecraft.nbt.NbtUtils)1 BitStorage (net.minecraft.util.BitStorage)1 HashMapPalette (net.minecraft.world.level.chunk.HashMapPalette)1 LevelChunkSection (net.minecraft.world.level.chunk.LevelChunkSection)1