mirror of
https://github.com/GTNewHorizons/Postea.git
synced 2026-11-12 16:37:38 +00:00
Compat patches for Vanilla/ChunkAPI/EndlessIDs (#8)
This commit is contained in:
1 parent
0999b44caf
commit
46877823aa
9 files changed
+270
-68
No files matched your search
@@ -0,0 +1,25 @@
|
||||
package com.gtnewhorizons.postea.api;
|
||||
|
||||
import static net.minecraftforge.common.util.Constants.NBT.TAG_INT;
|
||||
import static net.minecraftforge.common.util.Constants.NBT.TAG_SHORT;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class IDExtenderCompat {
|
||||
|
||||
public static int getItemStackID(NBTTagCompound tag) {
|
||||
if (tag.hasKey("idExt", TAG_INT)) return tag.getInteger("idExt");
|
||||
else if (tag.hasKey("id", TAG_INT)) return tag.getInteger("id");
|
||||
else if (tag.hasKey("id", TAG_SHORT)) return tag.getShort("id");
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public static void setItemStackID(NBTTagCompound tag, int id) {
|
||||
if (id < 32000) {
|
||||
tag.setShort("id", (short) id);
|
||||
} else {
|
||||
tag.setShort("id", (short) 0);
|
||||
tag.setInteger("idExt", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.gtnewhorizons.postea.compat;
|
||||
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.world.chunk.NibbleArray;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import com.falsepattern.endlessids.mixin.helpers.SubChunkBlockHook;
|
||||
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
|
||||
|
||||
public class Compat {
|
||||
|
||||
private static Boolean chunkapi = null;
|
||||
private static Boolean endlessids = null;
|
||||
private static Boolean neid = null;
|
||||
|
||||
public static boolean chunkapiPresent() {
|
||||
if (chunkapi == null) {
|
||||
boolean present = false;
|
||||
try {
|
||||
present = Launch.classLoader.getClassBytes("com.falsepattern.chunk.internal.core.CoreLoadingPlugin")
|
||||
!= null;
|
||||
} catch (Throwable ignored) {}
|
||||
chunkapi = present;
|
||||
}
|
||||
return chunkapi;
|
||||
}
|
||||
|
||||
public static boolean endlessidsPresent() {
|
||||
if (endlessids == null) {
|
||||
boolean present = false;
|
||||
try {
|
||||
present = Launch.classLoader.getClassBytes("com.falsepattern.endlessids.asm.EndlessIDsCore") != null;
|
||||
} catch (Throwable ignored) {}
|
||||
endlessids = present;
|
||||
}
|
||||
return endlessids;
|
||||
}
|
||||
|
||||
public static boolean neidPresent() {
|
||||
if (neid == null) {
|
||||
boolean present = false;
|
||||
try {
|
||||
present = Launch.classLoader.getClassBytes("com.gtnewhorizons.neid.core.NEIDCore") != null;
|
||||
} catch (Throwable ignored) {}
|
||||
neid = present;
|
||||
}
|
||||
return neid;
|
||||
}
|
||||
|
||||
public static SubChunkAccess getSubChunkAccess(ExtendedBlockStorage subChunk) {
|
||||
if (endlessidsPresent()) {
|
||||
return EndlessIDSCompat.getSubChunkAccess(subChunk);
|
||||
} else if (neidPresent()) {
|
||||
return NEIDCompat.getSubChunkAccess(subChunk);
|
||||
} else {
|
||||
return VanillaCompat.getSubChunkAccess(subChunk);
|
||||
}
|
||||
}
|
||||
|
||||
private static class VanillaCompat {
|
||||
|
||||
public static SubChunkAccess getSubChunkAccess(ExtendedBlockStorage subChunk) {
|
||||
final byte[] lsb = subChunk.getBlockLSBArray();
|
||||
return new SubChunkAccess() {
|
||||
|
||||
private NibbleArray msb = subChunk.getBlockMSBArray();
|
||||
|
||||
@Override
|
||||
public int getBlockId(int x, int y, int z) {
|
||||
int i = toIndex(x, y, z);
|
||||
int id = lsb[i] & 0xFF;
|
||||
if (msb != null) {
|
||||
id |= msb.get(x, y, z) << 8;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockId(int x, int y, int z, int id) {
|
||||
int i = toIndex(x, y, z);
|
||||
int l = id & 0xFF;
|
||||
int h = (id >>> 8) & 0xF;
|
||||
lsb[i] = (byte) l;
|
||||
if (h == 0 && msb == null) return;
|
||||
if (msb == null) {
|
||||
msb = new NibbleArray(lsb.length, 4);
|
||||
subChunk.setBlockMSBArray(msb);
|
||||
}
|
||||
msb.set(x, y, z, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMeta(int x, int y, int z) {
|
||||
return subChunk.getExtBlockMetadata(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMeta(int x, int y, int z, int meta) {
|
||||
subChunk.setExtBlockMetadata(x, y, z, meta);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class EndlessIDSCompat {
|
||||
|
||||
public static SubChunkAccess getSubChunkAccess(ExtendedBlockStorage subChunk) {
|
||||
final SubChunkBlockHook bh = (SubChunkBlockHook) subChunk;
|
||||
return new SubChunkAccess() {
|
||||
|
||||
@Override
|
||||
public int getBlockId(int x, int y, int z) {
|
||||
return bh.eid$getID(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockId(int x, int y, int z, int id) {
|
||||
bh.eid$setID(x, y, z, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMeta(int x, int y, int z) {
|
||||
return bh.eid$getMetadata(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMeta(int x, int y, int z, int meta) {
|
||||
bh.eid$setMetadata(x, y, z, meta);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class NEIDCompat {
|
||||
|
||||
public static SubChunkAccess getSubChunkAccess(ExtendedBlockStorage subChunk) {
|
||||
final IExtendedBlockStorageMixin bh = (IExtendedBlockStorageMixin) subChunk;
|
||||
final short[] blockArray = bh.getBlock16BArray();
|
||||
final short[] metaArray = bh.getBlock16BMetaArray();
|
||||
return new SubChunkAccess() {
|
||||
|
||||
@Override
|
||||
public int getBlockId(int x, int y, int z) {
|
||||
return blockArray[toIndex(x, y, z)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockId(int x, int y, int z, int id) {
|
||||
blockArray[toIndex(x, y, z)] = (short) id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMeta(int x, int y, int z) {
|
||||
return metaArray[toIndex(x, y, z)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMeta(int x, int y, int z, int meta) {
|
||||
metaArray[toIndex(x, y, z)] = (short) meta;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static int toIndex(int x, int y, int z) {
|
||||
return y << 8 | z << 4 | x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.gtnewhorizons.postea.compat;
|
||||
|
||||
public interface SubChunkAccess {
|
||||
|
||||
int getBlockId(int x, int y, int z);
|
||||
|
||||
void setBlockId(int x, int y, int z, int id);
|
||||
|
||||
int getMeta(int x, int y, int z);
|
||||
|
||||
void setMeta(int x, int y, int z, int meta);
|
||||
}
|
||||
@@ -16,39 +16,26 @@ import com.gtnewhorizons.postea.mixins.interfaces.IChunkMixin;
|
||||
import com.gtnewhorizons.postea.utility.ChunkFixerUtility;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
|
||||
@Mixin(AnvilChunkLoader.class)
|
||||
@Mixin(value = AnvilChunkLoader.class, priority = 1100)
|
||||
public abstract class MixinAnvilChunkLoader {
|
||||
|
||||
@Inject(
|
||||
method = "readChunkFromNBT",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/nbt/NBTTagCompound;getIntArray(Ljava/lang/String;)[I",
|
||||
ordinal = 0),
|
||||
require = 1)
|
||||
private void postea$readPosteaChunkCode(CallbackInfoReturnable<Chunk> cir, @Local Chunk chunk,
|
||||
@Local(ordinal = 0) NBTTagCompound tag) {
|
||||
// This hook is compatible with Vanilla/NEID/EIDs
|
||||
@Inject(method = "readChunkFromNBT", at = @At("RETURN"), require = 1)
|
||||
private void postea$chunkHook(CallbackInfoReturnable<Chunk> cir, @Local Chunk chunk,
|
||||
@Local(argsOnly = true) World world, @Local(ordinal = 0, argsOnly = true) NBTTagCompound tag) {
|
||||
IChunkMixin chunkMixin = (IChunkMixin) chunk;
|
||||
chunkMixin.Postea$setPosteaCode(-1);
|
||||
if (tag.hasKey("POSTEA")) {
|
||||
chunkMixin.Postea$setPosteaCode(tag.getLong("POSTEA"));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "readChunkFromNBT",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;setBlockMetadataArray(Lnet/minecraft/world/chunk/NibbleArray;)V",
|
||||
shift = At.Shift.AFTER),
|
||||
require = 1)
|
||||
private void postea$transformBlocks(CallbackInfoReturnable<Chunk> cir, @Local World world, @Local Chunk chunk,
|
||||
@Local ExtendedBlockStorage ebs) {
|
||||
IChunkMixin chunkMixin = (IChunkMixin) chunk;
|
||||
// This checks if the chunk has been run with the current POSTEA_UPDATE_CODE and skips it if so.
|
||||
if (chunkMixin.Postea$getPosteaCode() == ChunkFixerUtility.POSTEA_UPDATE_CODE) return;
|
||||
|
||||
ChunkFixerUtility.transformNormalBlocks(chunk, ebs, world);
|
||||
for (ExtendedBlockStorage ebs : chunk.getBlockStorageArray()) {
|
||||
if (ebs == null) {
|
||||
continue;
|
||||
}
|
||||
ChunkFixerUtility.transformNormalBlocks(chunk, ebs, world);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
|
||||
@@ -16,9 +16,10 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
|
||||
import com.gtnewhorizons.postea.api.BlockReplacementManager;
|
||||
import com.gtnewhorizons.postea.api.TileEntityReplacementManager;
|
||||
import com.gtnewhorizons.postea.compat.Compat;
|
||||
import com.gtnewhorizons.postea.compat.SubChunkAccess;
|
||||
|
||||
import akka.japi.Pair;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
@@ -38,46 +39,45 @@ public class ChunkFixerUtility {
|
||||
|
||||
int sectionY = ebs.getYLocation();
|
||||
|
||||
IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs;
|
||||
short[] blockArray = ebsMixin.getBlock16BArray();
|
||||
short[] metadataArray = ebsMixin.getBlock16BMetaArray();
|
||||
SubChunkAccess access = Compat.getSubChunkAccess(ebs);
|
||||
|
||||
for (int index = 0; index < blockArray.length; index++) {
|
||||
int blockId = blockArray[index];
|
||||
int metadata = metadataArray[index];
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int blockId = access.getBlockId(x, y, z);
|
||||
int metadata = access.getMeta(x, y, z);
|
||||
|
||||
// Skip air.
|
||||
if (blockId == AIR_ID) continue;
|
||||
// If this block has no registered Postea conversion, skip it.
|
||||
if (blockNotConvertible(blockId)) continue;
|
||||
// Skip air.
|
||||
if (blockId == AIR_ID) continue;
|
||||
// If this block has no registered Postea conversion, skip it.
|
||||
if (blockNotConvertible(blockId)) continue;
|
||||
|
||||
// Cache block names to improve performance, as findUniqueIdentifierFor is expensive.
|
||||
Block block = Block.getBlockById(blockId);
|
||||
String blockName = loadedBlocks.computeIfAbsent(
|
||||
block,
|
||||
b -> GameRegistry.findUniqueIdentifierFor(b)
|
||||
.toString());
|
||||
// Cache block names to improve performance, as findUniqueIdentifierFor is expensive.
|
||||
Block block = Block.getBlockById(blockId);
|
||||
String blockName = loadedBlocks.computeIfAbsent(
|
||||
block,
|
||||
b -> GameRegistry.findUniqueIdentifierFor(b)
|
||||
.toString());
|
||||
|
||||
BlockConversionInfo blockConversionInfo = new BlockConversionInfo();
|
||||
blockConversionInfo.blockName = blockName;
|
||||
blockConversionInfo.blockID = blockId;
|
||||
blockConversionInfo.metadata = (byte) metadata; // Updated
|
||||
BlockConversionInfo blockConversionInfo = new BlockConversionInfo();
|
||||
blockConversionInfo.blockName = blockName;
|
||||
blockConversionInfo.blockID = blockId;
|
||||
blockConversionInfo.metadata = (byte) metadata; // Updated
|
||||
|
||||
blockConversionInfo.world = world;
|
||||
blockConversionInfo.world = world;
|
||||
|
||||
int x = index % 16;
|
||||
int y = (index / 256) + sectionY;
|
||||
int z = (index / 16) % 16;
|
||||
blockConversionInfo.x = x + chunkXPos + 1;
|
||||
blockConversionInfo.y = y + sectionY;
|
||||
blockConversionInfo.z = z + chunkZPos + 1;
|
||||
|
||||
blockConversionInfo.x = x + chunkXPos + 1;
|
||||
blockConversionInfo.y = y;
|
||||
blockConversionInfo.z = z + chunkZPos + 1;
|
||||
BlockConversionInfo output = BlockReplacementManager
|
||||
.getBlockReplacement(blockConversionInfo, world);
|
||||
|
||||
BlockConversionInfo output = BlockReplacementManager.getBlockReplacement(blockConversionInfo, world);
|
||||
|
||||
if (output != null) {
|
||||
blockArray[index] = (short) output.blockID;
|
||||
metadataArray[index] = (short) output.metadata;
|
||||
if (output != null) {
|
||||
access.setBlockId(x, y, z, output.blockID);
|
||||
access.setMeta(x, y, z, output.metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,25 +95,24 @@ public class ChunkFixerUtility {
|
||||
}
|
||||
|
||||
for (ExtendedBlockStorage ebs : chunk.getBlockStorageArray()) {
|
||||
if (ebs == null) continue;
|
||||
processSection(ebs, conversionInfoList);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processSection(ExtendedBlockStorage ebs, List<ConversionInfo> conversionInfoList) {
|
||||
if (ebs instanceof final IExtendedBlockStorageMixin ebsMixin) {
|
||||
int sectionY = ebs.getYLocation();
|
||||
|
||||
List<ConversionInfo> filteredList = conversionInfoList.stream()
|
||||
.filter(info -> info.y >= sectionY && info.y < (sectionY + 16))
|
||||
.filter(info -> info.y >= sectionY && info.y < (sectionY + 16))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (ConversionInfo info : filteredList) {
|
||||
int localX = info.x & 15;
|
||||
int localY = info.y & 15;
|
||||
int localZ = info.z & 15;
|
||||
ebs.func_150818_a(localX, localY, localZ, info.blockInfo.block);
|
||||
ebs.setExtBlockMetadata(localX, localY, localZ, info.blockInfo.metadata);
|
||||
}
|
||||
int localX = info.x & 15;
|
||||
int localY = info.y & 15;
|
||||
int localZ = info.z & 15;
|
||||
ebs.func_150818_a(localX, localY, localZ, info.blockInfo.block);
|
||||
ebs.setExtBlockMetadata(localX, localY, localZ, info.blockInfo.metadata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.function.Function;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import com.gtnewhorizons.postea.api.IDExtenderCompat;
|
||||
import com.gtnewhorizons.postea.api.ItemStackReplacementManager;
|
||||
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
@@ -16,7 +17,7 @@ public abstract class ItemFixerUtility {
|
||||
if (tag.hasNoTags()) return;
|
||||
|
||||
if (tag.hasKey("id")) {
|
||||
short id = tag.getShort("id");
|
||||
int id = IDExtenderCompat.getItemStackID(tag);
|
||||
Item item = Item.getItemById(id);
|
||||
if (item == null) return;
|
||||
String itemNameInternal = GameRegistry.findUniqueIdentifierFor(item).modId + ":"
|
||||
|
||||
Reference in new issue
Block a user