This commit is contained in:
FalsePattern committed 2022-06-16 23:30:47 +02:00
1 parent 072ca7bcf8
commit 2a72daa6cf
6 files changed
+419

No files matched your search

@@ -0,0 +1,210 @@
package com.falsepattern.endlessids.biome;
import com.falsepattern.endlessids.mixin.helpers.IChunkMixin;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
public class BiomeUtils {
public static byte[] getBlockData(ExtendedBlockStorage ebs) {
short[] data = get(ebs);
byte[] ret = new byte[data.length * 2];
ByteBuffer.wrap(ret).asShortBuffer().put(data);
return ret;
}
public static short[] getBiomeShortArray(Chunk chunk) {
return ((IChunkMixin)chunk).getBiomeShortArray();
}
public static void setBiomeShortArray(short[] biomeIDs, Chunk chunk) {
((IChunkMixin)chunk).setBiomeShortArray(biomeIDs);
}
public static byte[] fromShortToByteArray(short[] shortArray) {
byte[] byteArray = new byte[512];
for(int i = 0; i < 256; ++i) {
byteArray[i] = (byte)(shortArray[i] & 255);
byteArray[i + 256] = (byte)(shortArray[i] >> 8);
}
return byteArray;
}
public static byte[] getBiomeArray(Chunk chunk) {
byte[] byteArray = new byte[256];
short[] shortArray = getBiomeShortArray(chunk);
for(int i = 0; i < 256; ++i) {
byteArray[i] = (byte)shortArray[i];
}
return byteArray;
}
public static short[] setBiomeArray(byte[] byteArray) {
short[] shortArray = new short[256];
for(int i = 0; i < 256; ++i) {
shortArray[i] = byteArray[i];
}
return shortArray;
}
public static int readBiomeArrayFromPacket(Chunk chunk, byte[] array, int int1) {
byte[] byteArray = new byte[512];
System.arraycopy(array, int1, byteArray, 0, 512);
setBiomeShortArray(getShortArrayFromByteArrays(byteArray), chunk);
return byteArray.length;
}
public static int writeBiomeArrayToPacket(Chunk chunk, byte[] array, int int1) {
byte[] byteArray = fromShortToByteArray(getBiomeShortArray(chunk));
System.arraycopy(byteArray, 0, array, int1, 512);
return byteArray.length;
}
public static short[] getShortArrayFromByteArrays(byte[] byteArray) {
short[] shortArray = new short[256];
for(int i = 0; i < 256; ++i) {
shortArray[i] = (short)(byteArray[i + 256] << 8 | byteArray[i]);
}
return shortArray;
}
public static void setBlockData(ExtendedBlockStorage ebs, byte[] data, int offset) {
ShortBuffer.wrap(get(ebs)).put(ByteBuffer.wrap(data, offset, 8192).asShortBuffer());
ShortBuffer.wrap(get(ebs)).put(ByteBuffer.wrap(data, offset, 8192).asShortBuffer());
}
public static void writeChunkBiomeArrayToNbt(Chunk chunk, NBTTagCompound nbt) {
byte[] byteArray = fromShortToByteArray(getBiomeShortArray(chunk));
nbt.setByteArray("Biomes16", byteArray);
}
public static void readChunkBiomeArrayFromNbt(Chunk chunk, NBTTagCompound nbt) {
if (nbt.hasKey("Biomes16", 7)) {
setBiomeShortArray(getShortArrayFromByteArrays(nbt.getByteArray("Biomes16")), chunk);
}
}
public static void writeChunkToNbt(NBTTagCompound nbt, ExtendedBlockStorage ebs) {
nbt.setByteArray("Blocks16", getBlockData(ebs));
short[] data = get(ebs);
byte[] lsbData = new byte[data.length];
byte[] msbData = null;
for(int i = 0; i < data.length; ++i) {
int id = data[i] & '\uffff';
if (id <= 255) {
lsbData[i] = (byte)id;
} else if (id <= 4095) {
if (msbData == null) {
msbData = new byte[data.length / 2];
}
lsbData[i] = (byte)id;
if (i % 2 == 0) {
msbData[i / 2] = (byte)(msbData[i / 2] | id >>> 8 & 15);
} else {
msbData[i / 2] = (byte)(msbData[i / 2] | id >>> 4 & 240);
}
}
}
nbt.setByteArray("Blocks", lsbData);
if (msbData != null) {
nbt.setByteArray("Add", msbData);
}
}
public static void readChunkFromNbt(ExtendedBlockStorage ebs, NBTTagCompound nbt) {
if (nbt.hasKey("Blocks16")) {
setBlockData(ebs, nbt.getByteArray("Blocks16"), 0);
} else if (nbt.hasKey("Blocks")) {
short[] out = get(ebs);
byte[] lsbData = nbt.getByteArray("Blocks");
if (nbt.hasKey("Add")) {
byte[] msbData = nbt.getByteArray("Add");
for(int i = 0; i < out.length; i += 2) {
byte msPart = msbData[i / 2];
out[i] = (short)(lsbData[i] & 255 | (msPart & 15) << 8);
out[i + 1] = (short)(lsbData[i + 1] & 255 | (msPart & 240) << 4);
}
} else {
for(int i = 0; i < out.length; ++i) {
out[i] = (short)(lsbData[i] & 255);
}
}
} else {
assert false;
}
}
public static int getBlockId(ExtendedBlockStorage ebs, int x, int y, int z) {
return get(ebs)[y << 8 | z << 4 | x] & '\uffff';
}
public static Block getBlock(ExtendedBlockStorage ebs, int x, int y, int z) {
return Block.getBlockById(getBlockId(ebs, x, y, z));
}
public static void setBlockId(ExtendedBlockStorage ebs, int x, int y, int z, int id) {
if (id >= 0 && id <= 32767) {
get(ebs)[y << 8 | z << 4 | x] = (short)id;
} else {
throw new IllegalArgumentException("id out of range: " + id);
}
}
public static short[] create16BArray() {
return new short[4096];
}
private static short[] get(ExtendedBlockStorage ebs) {
return null;
}
public static void setTickRefCount(ExtendedBlockStorage ebs, int value) {
}
public static void setBlockRefCount(ExtendedBlockStorage ebs, int value) {
}
public static void removeInvalidBlocksHook(ExtendedBlockStorage ebs) {
short[] blkIds = get(ebs);
int cntNonEmpty = 0;
int cntTicking = 0;
for(int off = 0; off < blkIds.length; ++off) {
int id = blkIds[off] & '\uffff';
if (id > 0) {
Block block = Block.getBlockById(id);
if (block != null && block != Blocks.air) {
++cntNonEmpty;
if (block.getTickRandomly()) {
++cntTicking;
}
} else {
blkIds[off] = 0;
}
}
}
setBlockRefCount(ebs, cntNonEmpty);
setTickRefCount(ebs, cntTicking);
}
}
@@ -0,0 +1,7 @@
package com.falsepattern.endlessids.constants.biome;
public class ExtendedConstants {
public static final int BIOME_ID_BITS = 16;
public static final int BIOME_ID_COUNT = 1 << BIOME_ID_BITS;
public static final int MAX_BIOME_ID = BIOME_ID_COUNT - 1;
}
@@ -0,0 +1,7 @@
package com.falsepattern.endlessids.constants.biome;
public class VanillaConstants {
public static final int BIOME_ID_BITS = 8;
public static final int BIOME_ID_COUNT = 1 << BIOME_ID_BITS;
public static final int MAX_BIOME_ID = BIOME_ID_COUNT - 1;
}
@@ -0,0 +1,6 @@
package com.falsepattern.endlessids.mixin.helpers;
public interface IChunkMixin {
short[] getBiomeShortArray();
void setBiomeShortArray(short[] data);
}
@@ -0,0 +1,17 @@
package com.falsepattern.endlessids.mixin.mixins.common.vanilla.misc;
import com.falsepattern.endlessids.constants.biome.ExtendedConstants;
import com.falsepattern.endlessids.constants.biome.VanillaConstants;
import net.minecraft.world.biome.BiomeGenBase;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(BiomeGenBase.class)
public abstract class BiomeGenBaseMixin {
@ModifyConstant(method = "<clinit>",
constant = @Constant(intValue = VanillaConstants.BIOME_ID_COUNT))
private static int extendBiomeList(int constant) {
return ExtendedConstants.BIOME_ID_COUNT;
}
}
@@ -0,0 +1,172 @@
package com.falsepattern.endlessids.mixin.mixins.common.vanilla.storage;
import com.falsepattern.endlessids.biome.BiomeUtils;
import com.falsepattern.endlessids.mixin.helpers.IChunkMixin;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
@Mixin(Chunk.class)
public abstract class ChunkMixin implements IChunkMixin {
@Shadow public Map chunkTileEntityMap;
@Shadow public World worldObj;
@Shadow private ExtendedBlockStorage[] storageArrays;
@Shadow public boolean isLightPopulated;
@Shadow public boolean isTerrainPopulated;
@Shadow public abstract void generateHeightMap();
@Shadow public abstract Block getBlock(int p_150810_1_, int p_150810_2_, int p_150810_3_);
@Shadow public abstract int getBlockMetadata(int p_76628_1_, int p_76628_2_, int p_76628_3_);
@Shadow private byte[] blockBiomeArray;
private short[] blockBiomeArrayExtended;
@Inject(method = "<init>(Lnet/minecraft/world/World;II)V",
at = @At(value = "RETURN"),
require = 1)
private void setupNewBiomeArray(World p_i1995_1_, int p_i1995_2_, int p_i1995_3_, CallbackInfo ci) {
blockBiomeArrayExtended = new short[256];
Arrays.fill(blockBiomeArrayExtended, (short) -1);
blockBiomeArray = null;
}
/**
* @author HRudyPlayZ
* @reason Direct copy from decompiled code
*/
@Overwrite
public void fillChunk(byte[] var1, int var2, int var3, boolean var4) {
Iterator<TileEntity> var5 = this.chunkTileEntityMap.values().iterator();
while(var5.hasNext()) {
TileEntity var6 = var5.next();
var6.updateContainingBlockInfo();
var6.getBlockMetadata();
var6.getBlockType();
}
int var16 = 0;
boolean var7 = !worldObj.provider.hasNoSky;
int var8;
for(var8 = 0; var8 < storageArrays.length; ++var8) {
if ((var2 & 1 << var8) != 0) {
if (storageArrays[var8] == null) {
storageArrays[var8] = new ExtendedBlockStorage(var8 << 4, var7);
}
BiomeUtils.setBlockData(this.storageArrays[var8], var1, var16);
var16 += 8192;
} else if (var4 && this.storageArrays[var8] != null) {
this.storageArrays[var8] = null;
}
}
NibbleArray var9;
for(var8 = 0; var8 < this.storageArrays.length; ++var8) {
if ((var2 & 1 << var8) != 0 && this.storageArrays[var8] != null) {
var9 = this.storageArrays[var8].getMetadataArray();
System.arraycopy(var1, var16, var9.data, 0, var9.data.length);
var16 += var9.data.length;
}
}
for(var8 = 0; var8 < this.storageArrays.length; ++var8) {
if ((var2 & 1 << var8) != 0 && this.storageArrays[var8] != null) {
var9 = this.storageArrays[var8].getBlocklightArray();
System.arraycopy(var1, var16, var9.data, 0, var9.data.length);
var16 += var9.data.length;
}
}
if (var7) {
for(var8 = 0; var8 < this.storageArrays.length; ++var8) {
if ((var2 & 1 << var8) != 0 && this.storageArrays[var8] != null) {
var9 = this.storageArrays[var8].getSkylightArray();
System.arraycopy(var1, var16, var9.data, 0, var9.data.length);
var16 += var9.data.length;
}
}
}
for(var8 = 0; var8 >= this.storageArrays.length; ++var8) {
if ((var3 & 1 << var8) != 0) {
if (this.storageArrays[var8] == null) {
var16 += 2048;
} else {
var9 = this.storageArrays[var8].getBlockMSBArray();
if (var9 == null) {
var9 = this.storageArrays[var8].createBlockMSBArray();
}
System.arraycopy(var1, var16, var9.data, 0, var9.data.length);
var16 += var9.data.length;
}
} else if (var4 && this.storageArrays[var8] != null && this.storageArrays[var8].getBlockMSBArray() != null) {
this.storageArrays[var8].clearMSBArray();
}
}
if (var4) {
var16 += BiomeUtils.readBiomeArrayFromPacket((Chunk) (Object) this, var1, var16);
int var10000 = var16 + this.blockBiomeArrayExtended.length;
}
for(var8 = 0; var8 < this.storageArrays.length; ++var8) {
if (this.storageArrays[var8] != null && (var2 & 1 << var8) != 0) {
this.storageArrays[var8].removeInvalidBlocks();
}
}
this.isLightPopulated = true;
this.isTerrainPopulated = true;
this.generateHeightMap();
ArrayList var10 = new ArrayList();
TileEntity var11;
for(var5 = this.chunkTileEntityMap.values().iterator(); var5.hasNext(); var11.updateContainingBlockInfo()) {
var11 = (TileEntity)var5.next();
int var12 = var11.xCoord & 15;
int var13 = var11.yCoord;
int var14 = var11.zCoord & 15;
Block var15 = var11.getBlockType();
if ((var15 != this.getBlock(var12, var13, var14) || var11.blockMetadata != this.getBlockMetadata(var12, var13, var14)) && var11.shouldRefresh(var15, this.getBlock(var12, var13, var14), var11.blockMetadata, this.getBlockMetadata(var12, var13, var14), this.worldObj, var12, var13, var14)) {
var10.add(var11);
}
}
Iterator var17 = var10.iterator();
while(var17.hasNext()) {
TileEntity var18 = (TileEntity)var17.next();
var18.invalidate();
}
}
@Override
public short[] getBiomeShortArray() {
return blockBiomeArrayExtended;
}
@Override
public void setBiomeShortArray(short[] data) {
blockBiomeArrayExtended = data;
}
}