Added ForgeMultipart rotation support
This includes microblocks and Wireless redstone (Chickenbones edition) Other parts will not rotate and may corrupt your world, use at your own risk.
This commit is contained in:
parent
41a8dfafea
commit
6752ec16e5
3 changed files with 177 additions and 28 deletions
171
src/main/java/cr0s/warpdrive/compat/CompatForgeMultipart.java
Normal file
171
src/main/java/cr0s/warpdrive/compat/CompatForgeMultipart.java
Normal file
|
@ -0,0 +1,171 @@
|
|||
package cr0s.warpdrive.compat;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
|
||||
public class CompatForgeMultipart implements IBlockTransformer {
|
||||
|
||||
public static Method methodMultipartHelper_createTileFromNBT = null;
|
||||
public static Method methodMultipartHelper_sendDescPacket = null;
|
||||
public static Method tileMultipart_onChunkLoad = null;
|
||||
|
||||
private static Class<?> classBlockMultipart;
|
||||
|
||||
public static boolean register() {
|
||||
try {
|
||||
Class forgeMultipart_helper = Class.forName("codechicken.multipart.MultipartHelper");
|
||||
methodMultipartHelper_createTileFromNBT = forgeMultipart_helper.getDeclaredMethod("createTileFromNBT", World.class, NBTTagCompound.class);
|
||||
methodMultipartHelper_sendDescPacket = forgeMultipart_helper.getDeclaredMethod("sendDescPacket", World.class, TileEntity.class);
|
||||
Class forgeMultipart_tileMultipart = Class.forName("codechicken.multipart.TileMultipart");
|
||||
tileMultipart_onChunkLoad = forgeMultipart_tileMultipart.getDeclaredMethod("onChunkLoad");
|
||||
|
||||
classBlockMultipart = Class.forName("codechicken.multipart.BlockMultipart");
|
||||
WarpDriveConfig.registerBlockTransformer("ForgeMultipart", new CompatForgeMultipart());
|
||||
} catch(ClassNotFoundException | SecurityException | NoSuchMethodException exception) {
|
||||
exception.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) {
|
||||
return classBlockMultipart.isInstance(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJumpReady(final Block block, final int metadata, final TileEntity tileEntity, StringBuilder reason) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTBase saveExternals(final TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(TileEntity tileEntity) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
private static final byte NBTTagCompoundId = 10; // new NBTTagCompound().getId();
|
||||
|
||||
// Microblocks shape is bits 0-3 for shape/slot, bits 4-7 for size:
|
||||
// - mcr_cnr (nook, corner, notch): 16 20 22 18 / 17 21 23 19 => shape/slot: 0 4 6 2 / 1 5 7 3
|
||||
// - mcr_face (cover, panel, slab): 16 / 17 / 18 21 19 20 => shape/slot: 0 / 1 / 2 5 3 4
|
||||
// - mcr_hllw (hollow cover, panel, slab): same as mcr_face
|
||||
// - mcr_edge (strip, post, pillar): 16 18 19 17 / 20 24 21 26 / 22 25 23 27 => shape/slot: 0 2 3 1 / 4 8 5 10 / 6 9 7 11
|
||||
// - mcr_post (post, pillar): 32 / 33 34 => shape/slot: 0 / 1 2
|
||||
|
||||
// = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
private static final byte[] rotMicroblockCorner = { 4, 5, 0, 1, 6, 7, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
private static final byte[] rotMicroblockFace = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
private static final byte[] rotMicroblockEdge = { 2, 0, 3, 1, 8, 10, 9, 11, 5, 7, 4, 6, 12, 13, 14, 15 };
|
||||
private static final byte[] rotMicroblockPost = { 0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
|
||||
// WRCBE state is bits 0-1 for rotation, bits 2-4 for face:
|
||||
// - wrcbe-recv, wrcbe-tran, wrcbe-jamm: 0 1 2 3 / 4 7 6 5 / 8 20 12 16 / 9 21 13 17 / 10 22 14 18 / 11 23 15 19
|
||||
private static final byte[] rotWRCBEstate = { 1, 2, 3, 0, 7, 4, 5, 6,
|
||||
20, 21, 22, 23, 16, 17, 18, 19, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
24, 25, 26, 27, 28, 29, 30, 31 };
|
||||
|
||||
private NBTTagCompound rotate_part(final byte rotationSteps, NBTTagCompound nbtPart) {
|
||||
NBTTagCompound nbtNewPart = (NBTTagCompound) nbtPart.copy();
|
||||
|
||||
if (!nbtNewPart.hasKey("id")) {
|
||||
WarpDrive.logger.error("Ignoring ForgeMultipart with missing id: " + nbtPart);
|
||||
} else {
|
||||
String id = nbtPart.getString("id");
|
||||
String propertyName = null;
|
||||
byte mask = (byte) 0xFF;
|
||||
byte[] rot = null;
|
||||
// microblocks
|
||||
if (id.equals("mcr_cnr")) {
|
||||
propertyName = "shape";
|
||||
mask = (byte) 0x0F;
|
||||
rot = rotMicroblockCorner;
|
||||
} else if (id.equals("mcr_face") || id.equals("mcr_hllw")) {
|
||||
propertyName = "shape";
|
||||
mask = (byte) 0x0F;
|
||||
rot = rotMicroblockFace;
|
||||
} else if (id.equals("mcr_edge")) {
|
||||
propertyName = "shape";
|
||||
mask = (byte) 0x0F;
|
||||
rot = rotMicroblockEdge;
|
||||
} else if (id.equals("mcr_post")) {
|
||||
propertyName = "shape";
|
||||
mask = (byte) 0x0F;
|
||||
rot = rotMicroblockPost;
|
||||
// wireless redstone
|
||||
} else if (id.equals("wrcbe-recv") || id.equals("wrcbe-tran") || id.equals("wrcbe-jamm")) {
|
||||
propertyName = "state";
|
||||
mask = (byte) 0x1F;
|
||||
rot = rotWRCBEstate;
|
||||
} else {
|
||||
WarpDrive.logger.error("Ignoring part of ForgeMultipart with unknown id: " + nbtPart);
|
||||
}
|
||||
// actual rotation
|
||||
if (propertyName != null && rot != null) {
|
||||
if (nbtPart.hasKey(propertyName)) {
|
||||
byte value = nbtPart.getByte(propertyName);
|
||||
byte masked = (byte) (value & mask);
|
||||
byte notmasked = (byte) (value - masked);
|
||||
switch (rotationSteps) {
|
||||
case 1:
|
||||
nbtNewPart.setByte(propertyName, (byte) (notmasked | rot[masked]));
|
||||
break;
|
||||
case 2:
|
||||
nbtNewPart.setByte(propertyName, (byte) (notmasked | rot[rot[masked]]));
|
||||
break;
|
||||
case 3:
|
||||
nbtNewPart.setByte(propertyName, (byte) (notmasked | rot[rot[rot[masked]]]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbtNewPart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final ITransformation transformation) {
|
||||
byte rotationSteps = transformation.getRotationSteps();
|
||||
if (rotationSteps == 0 || nbtTileEntity == null) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
// Parts
|
||||
if (nbtTileEntity.hasKey("parts")) {
|
||||
NBTTagList nbtParts = nbtTileEntity.getTagList("parts", NBTTagCompoundId);
|
||||
NBTTagList nbtNewParts = new NBTTagList();
|
||||
for (int index = 0; index < nbtParts.tagCount(); index++) {
|
||||
NBTTagCompound nbtPart = nbtParts.getCompoundTagAt(index);
|
||||
NBTTagCompound nbtNewPart = rotate_part(rotationSteps, nbtPart);
|
||||
nbtNewParts.appendTag(nbtNewPart);
|
||||
}
|
||||
nbtTileEntity.setTag("parts", nbtNewParts);
|
||||
} else {
|
||||
WarpDrive.logger.error("Ignoring ForgeMultipart with no 'parts': " + nbtTileEntity);
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase) {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import java.io.File;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
@ -29,6 +28,7 @@ import cr0s.warpdrive.compat.CompatBotania;
|
|||
import cr0s.warpdrive.compat.CompatComputerCraft;
|
||||
import cr0s.warpdrive.compat.CompatEnderIO;
|
||||
import cr0s.warpdrive.compat.CompatEvilCraft;
|
||||
import cr0s.warpdrive.compat.CompatForgeMultipart;
|
||||
import cr0s.warpdrive.compat.CompatImmersiveEngineering;
|
||||
import cr0s.warpdrive.compat.CompatIndustrialCraft2;
|
||||
import cr0s.warpdrive.compat.CompatJABBA;
|
||||
|
@ -47,9 +47,6 @@ import cr0s.warpdrive.data.Planet;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.config.ConfigCategory;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
|
||||
|
@ -83,11 +80,6 @@ public class WarpDriveConfig {
|
|||
public static boolean isEnderIOloaded = false;
|
||||
public static boolean isAdvancedRepulsionSystemLoaded = false;
|
||||
|
||||
// ForgeMultipart (microblocks) support
|
||||
public static Method forgeMultipart_helper_createTileFromNBT = null;
|
||||
public static Method forgeMultipart_helper_sendDescPacket = null;
|
||||
public static Method forgeMultipart_tileMultipart_onChunkLoad = null;
|
||||
|
||||
public static ItemStack IC2_compressedAir;
|
||||
public static ItemStack IC2_emptyCell;
|
||||
public static Block IC2_rubberWood;
|
||||
|
@ -761,7 +753,7 @@ public class WarpDriveConfig {
|
|||
public static void onFMLInitialization() {
|
||||
isForgeMultipartLoaded = Loader.isModLoaded("ForgeMultipart");
|
||||
if (isForgeMultipartLoaded) {
|
||||
loadForgeMultipart();
|
||||
isForgeMultipartLoaded = CompatForgeMultipart.register();
|
||||
}
|
||||
|
||||
isIndustrialCraft2Loaded = Loader.isModLoaded("IC2");
|
||||
|
@ -876,20 +868,6 @@ public class WarpDriveConfig {
|
|||
Dictionary.apply();
|
||||
}
|
||||
|
||||
private static void loadForgeMultipart() {
|
||||
try {
|
||||
Class forgeMultipart_helper = Class.forName("codechicken.multipart.MultipartHelper");
|
||||
forgeMultipart_helper_createTileFromNBT = forgeMultipart_helper.getDeclaredMethod("createTileFromNBT", World.class, NBTTagCompound.class);
|
||||
forgeMultipart_helper_sendDescPacket = forgeMultipart_helper.getDeclaredMethod("sendDescPacket", World.class, TileEntity.class);
|
||||
Class forgeMultipart_tileMultipart = Class.forName("codechicken.multipart.TileMultipart");
|
||||
forgeMultipart_tileMultipart_onChunkLoad = forgeMultipart_tileMultipart.getDeclaredMethod("onChunkLoad");
|
||||
} catch (Exception exception) {
|
||||
isForgeMultipartLoaded = false;
|
||||
WarpDrive.logger.error("Error loading ForgeMultipart classes");
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadIC2() {
|
||||
try {
|
||||
IC2_emptyCell = getModItemStack("IC2", "itemCellEmpty", -1);
|
||||
|
|
|
@ -43,11 +43,11 @@ import net.minecraft.util.ChunkCoordinates;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import cr0s.warpdrive.WarpDrive;
|
||||
import cr0s.warpdrive.api.IBlockTransformer;
|
||||
import cr0s.warpdrive.api.ITransformation;
|
||||
import cr0s.warpdrive.block.detection.BlockMonitor;
|
||||
import cr0s.warpdrive.compat.CompatForgeMultipart;
|
||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||
import cr0s.warpdrive.config.filler.Filler;
|
||||
|
||||
|
@ -299,7 +299,7 @@ public class JumpBlock {
|
|||
boolean isForgeMultipart = false;
|
||||
if (WarpDriveConfig.isForgeMultipartLoaded && nbtToDeploy.hasKey("id") && nbtToDeploy.getString("id") == "savedMultipart") {
|
||||
isForgeMultipart = true;
|
||||
newTileEntity = (TileEntity) WarpDriveConfig.forgeMultipart_helper_createTileFromNBT.invoke(null, targetWorld, nbtToDeploy);
|
||||
newTileEntity = (TileEntity) CompatForgeMultipart.methodMultipartHelper_createTileFromNBT.invoke(null, targetWorld, nbtToDeploy);
|
||||
|
||||
} else if (block == WarpDriveConfig.CC_Computer || block == WarpDriveConfig.CC_peripheral
|
||||
|| block == WarpDriveConfig.CCT_Turtle || block == WarpDriveConfig.CCT_Expanded || block == WarpDriveConfig.CCT_Advanced) {
|
||||
|
@ -327,8 +327,8 @@ public class JumpBlock {
|
|||
|
||||
targetWorld.setTileEntity(target.posX, target.posY, target.posZ, newTileEntity);
|
||||
if (isForgeMultipart) {
|
||||
WarpDriveConfig.forgeMultipart_tileMultipart_onChunkLoad.invoke(newTileEntity);
|
||||
WarpDriveConfig.forgeMultipart_helper_sendDescPacket.invoke(null, targetWorld, newTileEntity);
|
||||
CompatForgeMultipart.tileMultipart_onChunkLoad.invoke(newTileEntity);
|
||||
CompatForgeMultipart.methodMultipartHelper_sendDescPacket.invoke(null, targetWorld, newTileEntity);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue