mirror of
https://github.com/GTMEGA/EndlessIDs.git
synced 2026-11-12 04:57:31 +00:00
begin porting over BIDE code (https://github.com/TCLProject/Biome-ID-Extender)
This commit is contained in:
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);
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
}
|
||||
+172
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user