2022-03-17 15:21:30 +01:00
|
|
|
package com.falsepattern.endlessids;
|
|
|
|
|
|
2022-03-17 20:13:02 +01:00
|
|
|
import com.falsepattern.endlessids.constants.ExtendedConstants;
|
2022-06-17 21:53:59 +02:00
|
|
|
import com.falsepattern.endlessids.mixin.helpers.IChunkMixin;
|
2022-03-17 15:21:30 +01:00
|
|
|
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
|
2022-03-17 22:24:32 +01:00
|
|
|
import lombok.val;
|
2022-07-02 20:21:50 +02:00
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
import net.minecraft.block.Block;
|
2022-07-02 20:21:50 +02:00
|
|
|
import net.minecraft.init.Blocks;
|
2022-03-17 15:21:30 +01:00
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
2022-06-17 21:53:59 +02:00
|
|
|
import net.minecraft.world.chunk.Chunk;
|
|
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
import java.nio.ByteBuffer;
|
2022-07-02 20:21:50 +02:00
|
|
|
import java.nio.ShortBuffer;
|
2022-03-17 15:21:30 +01:00
|
|
|
|
2022-03-17 22:24:32 +01:00
|
|
|
public class Hooks {
|
|
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
public static byte[] getBlockData(final IExtendedBlockStorageMixin ebs) {
|
2022-03-17 22:24:32 +01:00
|
|
|
val lsb = ebs.getLSB();
|
|
|
|
|
val msb = ebs.getMSB();
|
|
|
|
|
final byte[] ret = new byte[lsb.length * 3];
|
|
|
|
|
ByteBuffer.wrap(ret).asShortBuffer().put(lsb);
|
|
|
|
|
System.arraycopy(msb, 0, ret, lsb.length * 2, lsb.length);
|
2022-03-17 15:21:30 +01:00
|
|
|
return ret;
|
|
|
|
|
}
|
2022-07-02 20:21:50 +02:00
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
public static void setBlockData(final IExtendedBlockStorageMixin ebs, final byte[] data, final int offset) {
|
2022-03-17 22:24:32 +01:00
|
|
|
val lsb = ebs.getLSB();
|
|
|
|
|
val msb = ebs.getMSB();
|
|
|
|
|
val lsbBytes = lsb.length * 2;
|
|
|
|
|
ShortBuffer.wrap(ebs.getLSB()).put(ByteBuffer.wrap(data, offset, lsbBytes).asShortBuffer());
|
|
|
|
|
System.arraycopy(data, offset + lsbBytes, msb, 0, msb.length);
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
public static void writeChunkToNbt(final NBTTagCompound nbt, final IExtendedBlockStorageMixin ebs) {
|
2022-03-17 22:24:32 +01:00
|
|
|
val ebsLSB = ebs.getLSB();
|
|
|
|
|
val ebsMSB = ebs.getMSB();
|
|
|
|
|
|
|
|
|
|
val byte1Data = new byte[ebsLSB.length];
|
|
|
|
|
byte[] byte2BottomNibbleData = null;
|
|
|
|
|
byte[] byte2TopNibbleData = null;
|
|
|
|
|
byte[] byte3Data = null;
|
|
|
|
|
for (int i = 0; i < ebsLSB.length; ++i) {
|
|
|
|
|
if (ebsMSB[i] != 0) {
|
|
|
|
|
if (byte3Data == null) {
|
|
|
|
|
byte3Data = new byte[ebsLSB.length];
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
byte3Data[i] = ebsMSB[i];
|
|
|
|
|
}
|
|
|
|
|
val idLSB = (ebsLSB[i] & 0xFFFF);
|
2022-07-02 20:21:50 +02:00
|
|
|
byte1Data[i] = (byte) (idLSB & 0xFF);
|
2022-03-17 22:24:32 +01:00
|
|
|
|
2022-07-02 20:21:50 +02:00
|
|
|
if (idLSB <= 0xFF) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
val nibbleIndex = i >> 1;
|
|
|
|
|
val nibbleShift = (i & 1) * 4;
|
|
|
|
|
if (byte2BottomNibbleData == null) {
|
|
|
|
|
byte2BottomNibbleData = new byte[ebsLSB.length / 2];
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
byte2BottomNibbleData[nibbleIndex] |= ((idLSB >>> 8) & 0xF) << nibbleShift;
|
|
|
|
|
|
2022-07-02 20:21:50 +02:00
|
|
|
if (idLSB <= 0xFFF) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
if (byte2TopNibbleData == null) {
|
|
|
|
|
byte2TopNibbleData = new byte[ebsLSB.length / 2];
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
byte2TopNibbleData[nibbleIndex] |= ((idLSB >>> 12) & 0xF) << nibbleShift;
|
|
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
nbt.setByteArray("Blocks", byte1Data);
|
2022-07-02 20:21:50 +02:00
|
|
|
if (byte2BottomNibbleData != null) {
|
2022-03-17 22:24:32 +01:00
|
|
|
nbt.setByteArray("Add", byte2BottomNibbleData);
|
2022-07-02 20:21:50 +02:00
|
|
|
}
|
|
|
|
|
if (byte2TopNibbleData != null) {
|
2022-03-17 22:24:32 +01:00
|
|
|
nbt.setByteArray("BlocksB2Hi", byte2TopNibbleData);
|
2022-07-02 20:21:50 +02:00
|
|
|
}
|
|
|
|
|
if (byte3Data != null) {
|
2022-03-17 22:24:32 +01:00
|
|
|
nbt.setByteArray("BlocksB3", byte3Data);
|
2022-07-02 20:21:50 +02:00
|
|
|
}
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
public static void readChunkFromNbt(final IExtendedBlockStorageMixin ebs, final NBTTagCompound nbt) {
|
2022-03-17 22:24:32 +01:00
|
|
|
assert nbt.hasKey("Blocks");
|
|
|
|
|
val byte1Data = nbt.getByteArray("Blocks");
|
|
|
|
|
val byte2BottomNibbleData = nbt.hasKey("Add") ? nbt.getByteArray("Add") : null;
|
|
|
|
|
val byte2TopNibbleData = nbt.hasKey("BlocksB2Hi") ? nbt.getByteArray("BlocksB2Hi") : null;
|
|
|
|
|
val byte3Data = nbt.hasKey("BlocksB3") ? nbt.getByteArray("BlocksB3") : null;
|
|
|
|
|
|
|
|
|
|
val lsb = ebs.getLSB();
|
|
|
|
|
val msb = ebs.getMSB();
|
|
|
|
|
for (int i = 0; i < lsb.length; i++) {
|
|
|
|
|
if (byte3Data != null) {
|
|
|
|
|
msb[i] = byte3Data[i];
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
int nibbleShift = (i & 1) * 4;
|
|
|
|
|
int id = byte1Data[i] & 0xFF;
|
|
|
|
|
if (byte2BottomNibbleData != null) {
|
|
|
|
|
id |= ((byte2BottomNibbleData[i >> 1] >> nibbleShift) & 0xF) << 8;
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 22:24:32 +01:00
|
|
|
if (byte2TopNibbleData != null) {
|
|
|
|
|
id |= ((byte2TopNibbleData[i >> 1] >> nibbleShift) & 0xF) << 12;
|
|
|
|
|
}
|
2022-07-02 20:21:50 +02:00
|
|
|
lsb[i] = (short) id;
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 20:13:02 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
public static void removeInvalidBlocksHook(final IExtendedBlockStorageMixin ebs) {
|
2022-03-17 22:24:32 +01:00
|
|
|
val blkIdsLSB = ebs.getLSB();
|
|
|
|
|
val blkIdsMSB = ebs.getMSB();
|
2022-03-17 15:21:30 +01:00
|
|
|
int cntNonEmpty = 0;
|
|
|
|
|
int cntTicking = 0;
|
2022-03-17 22:24:32 +01:00
|
|
|
for (int off = 0; off < blkIdsLSB.length; ++off) {
|
2022-07-02 20:21:50 +02:00
|
|
|
final int id =
|
|
|
|
|
((blkIdsLSB[off] & 0xFFFF) | ((blkIdsMSB[off] & 0xFF) << 16)) & ExtendedConstants.blockIDMask;
|
2022-03-17 15:21:30 +01:00
|
|
|
if (id > 0) {
|
2022-07-02 20:21:50 +02:00
|
|
|
final Block block = (Block) Block.blockRegistry.getObjectById(id);
|
2022-03-17 15:21:30 +01:00
|
|
|
if (block == null) {
|
|
|
|
|
if (IEConfig.removeInvalidBlocks) {
|
2022-03-17 22:24:32 +01:00
|
|
|
blkIdsLSB[off] = 0;
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-07-02 20:21:50 +02:00
|
|
|
} else if (block != Blocks.air) {
|
2022-03-17 15:21:30 +01:00
|
|
|
++cntNonEmpty;
|
|
|
|
|
if (block.getTickRandomly()) {
|
|
|
|
|
++cntTicking;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ebs.setBlockRefCount(cntNonEmpty);
|
|
|
|
|
ebs.setTickRefCount(cntTicking);
|
|
|
|
|
}
|
2022-07-02 20:21:50 +02:00
|
|
|
|
2022-03-17 15:21:30 +01:00
|
|
|
public static int getIdFromBlockWithCheck(final Block block, final Block oldBlock) {
|
|
|
|
|
final int id = Block.getIdFromBlock(block);
|
|
|
|
|
if (IEConfig.catchUnregisteredBlocks && id == -1) {
|
2022-07-02 20:21:50 +02:00
|
|
|
throw new IllegalArgumentException("Block " + block +
|
|
|
|
|
" is not registered. <-- Say about this to the author of this mod, or you can try to enable \"RemoveInvalidBlocks\" option in EID config.");
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|
2022-03-17 20:13:02 +01:00
|
|
|
if (id >= 0 && id <= ExtendedConstants.maxBlockID) {
|
2022-03-17 15:21:30 +01:00
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
if (id == -1) {
|
|
|
|
|
return Block.getIdFromBlock(oldBlock);
|
|
|
|
|
}
|
|
|
|
|
throw new IllegalArgumentException("id out of range: " + id);
|
|
|
|
|
}
|
2022-06-17 21:53:59 +02:00
|
|
|
|
|
|
|
|
//Biome ID Extender Code
|
|
|
|
|
|
|
|
|
|
public static byte[] shortToByteArray(short[] shortArray) {
|
|
|
|
|
byte[] byteArray = new byte[512];
|
|
|
|
|
|
2022-07-02 20:21:50 +02:00
|
|
|
for (int i = 0; i < 256; ++i) {
|
|
|
|
|
byteArray[i] = (byte) (shortArray[i] & 255);
|
|
|
|
|
byteArray[i + 256] = (byte) (shortArray[i] >>> 8);
|
2022-06-17 21:53:59 +02:00
|
|
|
}
|
|
|
|
|
return byteArray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static short[] byteToShortArray(byte[] byteArray) {
|
|
|
|
|
short[] shortArray = new short[256];
|
|
|
|
|
|
2022-07-02 20:21:50 +02:00
|
|
|
for (int i = 0; i < 256; ++i) {
|
|
|
|
|
shortArray[i] = (short) (byteArray[i + 256] << 8 | byteArray[i]);
|
2022-06-17 21:53:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return shortArray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static short[] oldBiomeByteToNewShortArray(byte[] byteArray) {
|
|
|
|
|
short[] shortArray = new short[256];
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 256; i++) {
|
2022-07-02 20:21:50 +02:00
|
|
|
shortArray[i] = (short) (byteArray[i] & 0xff);
|
2022-06-17 21:53:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return shortArray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int readBiomeArrayFromPacket(Chunk chunk, byte[] array, int offset) {
|
|
|
|
|
byte[] byteArray = new byte[512];
|
|
|
|
|
System.arraycopy(array, offset, byteArray, 0, 512);
|
2022-07-02 20:21:50 +02:00
|
|
|
((IChunkMixin) chunk).setBiomeShortArray(byteToShortArray(byteArray));
|
2022-06-17 21:53:59 +02:00
|
|
|
return byteArray.length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int writeBiomeArrayToPacket(Chunk chunk, byte[] array, int offset) {
|
2022-07-02 20:21:50 +02:00
|
|
|
byte[] byteArray = shortToByteArray(((IChunkMixin) chunk).getBiomeShortArray());
|
2022-06-17 21:53:59 +02:00
|
|
|
System.arraycopy(byteArray, 0, array, offset, 512);
|
|
|
|
|
return byteArray.length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void writeChunkBiomeArrayToNbt(Chunk chunk, NBTTagCompound nbt) {
|
2022-07-02 20:21:50 +02:00
|
|
|
byte[] byteArray = shortToByteArray(((IChunkMixin) chunk).getBiomeShortArray());
|
2022-06-17 21:53:59 +02:00
|
|
|
nbt.setByteArray("Biomes16", byteArray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void readChunkBiomeArrayFromNbt(Chunk chunk, NBTTagCompound nbt) {
|
|
|
|
|
short[] data = null;
|
|
|
|
|
if (nbt.hasKey("Biomes16", 7)) {
|
|
|
|
|
data = byteToShortArray(nbt.getByteArray("Biomes16"));
|
|
|
|
|
} else if (nbt.hasKey("Biomes", 7)) {
|
|
|
|
|
data = oldBiomeByteToNewShortArray(nbt.getByteArray("Biomes"));
|
|
|
|
|
}
|
|
|
|
|
if (data != null) {
|
2022-07-02 20:21:50 +02:00
|
|
|
((IChunkMixin) chunk).setBiomeShortArray(data);
|
2022-06-17 21:53:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-17 15:21:30 +01:00
|
|
|
}
|