From 6457c562a6b52f699477e200b26d50daba3f38f5 Mon Sep 17 00:00:00 2001 From: CannibalVox Date: Fri, 6 Mar 2015 20:57:05 -0600 Subject: [PATCH] Fix schematics & add TE sync --- .../mod_pocketDim/ConnectionHandler.java | 3 +- .../dungeon/DungeonSchematic.java | 8 +- .../mod_pocketDim/network/DimDoorsPacket.java | 1 + .../mod_pocketDim/schematic/Schematic.java | 101 ++++++++++++++---- .../tileentities/TileEntityDimDoor.java | 14 ++- .../tileentities/TileEntityRift.java | 35 +++--- .../mod_pocketDim/util/Point4D.java | 14 +++ .../mod_pocketDim/watcher/ClientLinkData.java | 31 ++++++ src/main/resources/META-INF/MANIFEST.MF | 4 + .../resources/META-INF/accessTransformer.cfg | 1 + 10 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 src/main/resources/META-INF/MANIFEST.MF create mode 100644 src/main/resources/META-INF/accessTransformer.cfg diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java b/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java index 4fc3d1f7..f7817cbf 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/ConnectionHandler.java @@ -23,8 +23,7 @@ public class ConnectionHandler { if(data.isPocketDimension()||data.id()==mod_pocketDim.properties.LimboDimensionID) { - DimDoorsNetwork.sendToPlayer( new ForgeMessage.DimensionRegisterMessage(data.id(), DimensionManager.getProviderType(data.id())), ) - Packet pkt = + DimDoorsNetwork.sendToPlayer( new ForgeMessage.DimensionRegisterMessage(data.id(), DimensionManager.getProviderType(data.id()))); event.manager.scheduleOutboundPacket(pkt[0]); } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java index 684f44a4..a59a5d27 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java @@ -166,7 +166,7 @@ public class DungeonSchematic extends Schematic { int index; int count; - int blockID; + Block block; int blockMeta; int dx, dy, dz; Point3D pocketPoint = new Point3D(0, 0, 0); @@ -182,12 +182,12 @@ public class DungeonSchematic extends Schematic { pocketPoint.setX(dx); pocketPoint.setY(dy); pocketPoint.setZ(dz); - blockID = blocks[index]; + block = blocks[index]; BlockRotator.transformPoint(pocketPoint, entranceDoorLocation, turnAngle, pocketCenter); - blockMeta = BlockRotator.transformMetadata(metadata[index], turnAngle, blockID); + blockMeta = BlockRotator.transformMetadata(metadata[index], turnAngle, block); //In the future, we might want to make this more efficient by building whole chunks at a time - blockSetter.setBlock(world, pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), blockID, blockMeta); + blockSetter.setBlock(world, pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), block, blockMeta); index++; } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/network/DimDoorsPacket.java b/src/main/java/StevenDimDoors/mod_pocketDim/network/DimDoorsPacket.java index a2f7d638..6a14437d 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/network/DimDoorsPacket.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/network/DimDoorsPacket.java @@ -6,6 +6,7 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.Packet; import net.minecraft.world.World; public abstract class DimDoorsPacket { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java index 76e815dd..2013b386 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/schematic/Schematic.java @@ -6,11 +6,14 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; import net.minecraft.block.Block; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -27,19 +30,30 @@ public class Schematic { protected short height; protected short length; - protected String[] blocks; + protected Block[] blocks; protected byte[] metadata; protected NBTTagList tileEntities; - protected Schematic(short width, short height, short length, String[] blocks, byte[] metadata, NBTTagList tileEntities) + protected Schematic(short width, short height, short length, String[] blockPalette, short[] blockIds, byte[] metadata, NBTTagList tileEntities) { this.width = width; this.height = height; this.length = length; - this.blocks = blocks; this.metadata = metadata; this.tileEntities = tileEntities; + + if (blockPalette != null) + loadBlockList(blockPalette, blockIds); } + + protected Schematic(short width, short height, short length, Block[] blocks, byte[] metadata, NBTTagList tileEntities) { + this.width = width; + this.height = height; + this.length = length; + this.blocks = blocks; + this.metadata = metadata; + this.tileEntities = tileEntities; + } protected Schematic(Schematic source) { @@ -53,6 +67,20 @@ public class Schematic { this.tileEntities = source.tileEntities; } + private void loadBlockList(String[] blockPalette, short[] blockIds) { + this.blocks = new Block[blockIds.length]; + + Block[] blockObjPalette = new Block[blockPalette.length]; + + for (int i = 0; i < blockPalette.length; i++) { + blockObjPalette[i++] = (Block)Block.blockRegistry.getObject(blockPalette[i]); + } + + for (int i = 0; i < blockIds.length; i++) { + this.blocks[i] = blockObjPalette[blockIds[i]]; + } + } + public int calculateIndex(int x, int y, int z) { if (x < 0 || x >= width) @@ -124,9 +152,7 @@ public class Schematic { public static Schematic readFromResource(String resourcePath) throws InvalidSchematicException { - //We need an instance of a class in the mod to retrieve a resource - Schematic empty = new Schematic((short) 0, (short) 0, (short) 0, null, null, null); - InputStream schematicStream = empty.getClass().getResourceAsStream(resourcePath); + InputStream schematicStream = Schematic.class.getResourceAsStream(resourcePath); return readFromStream(schematicStream); } @@ -141,7 +167,8 @@ public class Schematic { byte[] metadata = null; //block metadata byte[] lowBits = null; //first 8 bits of the block IDs byte[] highBits = null; //additional 4 bits of the block IDs - String[] blocks = null; //list of combined block IDs + short[] blockIds = null; //list of combined block IDs + String[] blockPalette = null; NBTTagList tileEntities = null; //storage for tile entities in NBT form NBTTagCompound schematicTag; //the NBT data extracted from the schematic file boolean hasExtendedBlockIDs; //indicates whether the schematic contains extended block IDs @@ -173,6 +200,19 @@ public class Schematic { if (length < 0) throw new InvalidSchematicException("The schematic cannot have a negative length."); + + NBTTagList nbtPalette = schematicTag.getTagList("Palette", 8); + + if (nbtPalette.tagCount() < 1) { + throw new InvalidSchematicException("The schematic must have a valid block palette."); + } + + blockPalette = new String[nbtPalette.tagCount()]; + + for (int i = 0; i < nbtPalette.tagCount(); i++) { + blockPalette[i] = nbtPalette.getStringTagAt(i); + } + //load block info lowBits = schematicTag.getByteArray("Blocks"); highBits = schematicTag.getByteArray("AddBlocks"); @@ -186,7 +226,7 @@ public class Schematic { if (volume > 2 * highBits.length && hasExtendedBlockIDs) throw new InvalidSchematicException("The schematic has extended block IDs for fewer blocks than its dimensions indicate."); - blocks = new String[volume]; + blockIds = new short[volume]; if (hasExtendedBlockIDs) { //Combine the split block IDs into a single value @@ -194,12 +234,12 @@ public class Schematic { int index; for (index = 0; index < pairs; index += 2) { - blocks[index] = (short) (((highBits[index >> 1] & 0x0F) << 8) + (lowBits[index] & 0xFF)); - blocks[index + 1] = (short) (((highBits[index >> 1] & 0xF0) << 4) + (lowBits[index + 1] & 0xFF)); + blockIds[index] = (short) (((highBits[index >> 1] & 0x0F) << 8) + (lowBits[index] & 0xFF)); + blockIds[index + 1] = (short) (((highBits[index >> 1] & 0xF0) << 4) + (lowBits[index + 1] & 0xFF)); } if (index < volume) { - blocks[index] = lowBits[index >> 1]; + blockIds[index] = lowBits[index >> 1]; } } else @@ -207,14 +247,21 @@ public class Schematic { //Copy the blockIDs for (int index = 0; index < volume; index++) { - blocks[index] = (short) (lowBits[index] & 0xFF); + blockIds[index] = (short) (lowBits[index] & 0xFF); } } + for (int i = 0; i < blockIds.length; i++) { + int paletteIndex = blockIds[i]; + if (paletteIndex < 0 || paletteIndex >= blockPalette.length) { + throw new InvalidSchematicException("Block entry referenced a non-existant palette entry."); + } + } + //Get the list of tile entities - tileEntities = schematicTag.getTagList("TileEntities"); + tileEntities = schematicTag.getTagList("TileEntities", 10); - Schematic result = new Schematic(width, height, length, blocks, metadata, tileEntities); + Schematic result = new Schematic(width, height, length, blockPalette, blockIds, metadata, tileEntities); return result; } catch (InvalidSchematicException ex) @@ -266,7 +313,7 @@ public class Schematic { //Short and sweet ^_^ WorldCopyOperation copier = new WorldCopyOperation(); copier.apply(world, x, y, z, width, height, length); - return new Schematic(width, height, length, copier.getBlockIDs(), copier.getMetadata(), copier.getTileEntities()); + return new Schematic(width, height, length, copier.getBlocks(), copier.getMetadata(), copier.getTileEntities()); } private static boolean encodeBlockIDs(short[] blocks, byte[] lowBits, byte[] highBits) @@ -291,6 +338,20 @@ public class Schematic { return hasHighBits; } + private static void reduceToPalette(Block[] blocks, List blockPalette, short[] blockIds) { + for (int i = 0; i < blocks.length; i++) { + String blockName = Block.blockRegistry.getNameForObject(blocks[i]); + int blockIndex = blockPalette.indexOf(blockName); + + if (blockIndex < 0) { + blockIndex = blockPalette.size(); + blockPalette.add(blockName); + } + + blockIds[i] = (short)blockIndex; + } + } + public NBTTagCompound writeToNBT() { return writeToNBT(true); @@ -301,13 +362,13 @@ public class Schematic { return writeToNBT(width, height, length, blocks, metadata, tileEntities, copyTileEntities); } - protected static NBTTagCompound writeToNBT(short width, short height, short length, short[] blocks, byte[] metadata, + protected static NBTTagCompound writeToNBT(short width, short height, short length, Block[] blocks, byte[] metadata, NBTTagList tileEntities, boolean copyTileEntities) { //This is the main storage function. Schematics are really compressed NBT tags, so if we can generate //the tags, most of the work is done. All the other storage functions will rely on this one. - NBTTagCompound schematicTag = new NBTTagCompound("Schematic"); + NBTTagCompound schematicTag = new NBTTagCompound(); schematicTag.setShort("Width", width); schematicTag.setShort("Length", length); @@ -316,9 +377,13 @@ public class Schematic { schematicTag.setTag("Entities", new NBTTagList()); schematicTag.setString("Materials", "Alpha"); + List blockPalette = new LinkedList(); + short[] blockIds = new short[blocks.length]; + reduceToPalette(blocks, blockPalette, blockIds); + byte[] lowBits = new byte[blocks.length]; byte[] highBits = new byte[(blocks.length >> 1) + (blocks.length & 1)]; - boolean hasExtendedIDs = encodeBlockIDs(blocks, lowBits, highBits); + boolean hasExtendedIDs = encodeBlockIDs(blockIds, lowBits, highBits); schematicTag.setByteArray("Blocks", lowBits); schematicTag.setByteArray("Data", metadata); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java index 07ba56b9..8390d43f 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityDimDoor.java @@ -2,6 +2,7 @@ package StevenDimDoors.mod_pocketDim.tileentities; import java.util.Random; +import StevenDimDoors.mod_pocketDim.network.CreateLinkPacket; import net.minecraft.nbt.NBTTagCompound; import StevenDimDoors.mod_pocketDim.ServerPacketHandler; import StevenDimDoors.mod_pocketDim.mod_pocketDim; @@ -9,7 +10,6 @@ import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.PocketManager; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; -import net.minecraft.network.Packet; public class TileEntityDimDoor extends DDTileEntityBase @@ -32,11 +32,21 @@ public class TileEntityDimDoor extends DDTileEntityBase { if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) { - return ServerPacketHandler.createLinkPacket(new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj))); + ClientLinkData linkData = new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)); + NBTTagCompound tag = new NBTTagCompound(); + linkData.writeToNBT(tag); + return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, tag); } return null; } + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound tag = pkt.func_148857_g(); + ClientLinkData linkData = ClientLinkData.readFromNBT(tag); + PocketManager.getLinkWatcher().onCreated(linkData); + } + @Override public void readFromNBT(NBTTagCompound nbt) { diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java index 8ef949fa..54eb418f 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/tileentities/TileEntityRift.java @@ -3,11 +3,14 @@ package StevenDimDoors.mod_pocketDim.tileentities; import java.util.ArrayList; import java.util.List; import java.util.Random; + +import StevenDimDoors.mod_pocketDim.network.CreateLinkPacket; import net.minecraft.entity.Entity; import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MathHelper; @@ -283,21 +286,25 @@ public class TileEntityRift extends DDTileEntityBase } - @Override - public Packet getDescriptionPacket() - { - if (PocketManager.getLink(xCoord, yCoord, zCoord, worldObj) != null) - { - return ServerPacketHandler.createLinkPacket(new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj))); - } - return null; - } + @Override + public Packet getDescriptionPacket() + { + if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null) + { + ClientLinkData linkData = new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)); + NBTTagCompound tag = new NBTTagCompound(); + linkData.writeToNBT(tag); + return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, tag); + } + return null; + } - @Override - public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) - { - readFromNBT(pkt.func_148857_g()); - } + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + NBTTagCompound tag = pkt.func_148857_g(); + ClientLinkData linkData = ClientLinkData.readFromNBT(tag); + PocketManager.getLinkWatcher().onCreated(linkData); + } @Override public float[] getRenderColor(Random rand) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/util/Point4D.java b/src/main/java/StevenDimDoors/mod_pocketDim/util/Point4D.java index 68243609..30bab3f8 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/util/Point4D.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/util/Point4D.java @@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.util; import java.io.*; import StevenDimDoors.mod_pocketDim.Point3D; +import net.minecraft.nbt.NBTTagCompound; public final class Point4D implements Comparable @@ -178,6 +179,15 @@ public final class Point4D implements Comparable return "(" + x + ", " + y + ", " + z + ", " + dimension + ")"; } + public static void writeToNBT(Point4D point, NBTTagCompound tag) { + if (point != null) { + tag.setInteger("X", point.x); + tag.setInteger("Y", point.y); + tag.setInteger("Z", point.z); + tag.setInteger("Dimension", point.dimension); + } + } + public static void write(Point4D point, DataOutput stream) throws IOException { stream.writeBoolean(point != null); @@ -201,4 +211,8 @@ public final class Point4D implements Comparable return null; } } + + public static Point4D readFromNBT(NBTTagCompound tag) { + return new Point4D(tag.getInteger("X"), tag.getInteger("Y"), tag.getInteger("Z"), tag.getInteger("Dimension")); + } } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java index 055cc843..c4e9bbde 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/watcher/ClientLinkData.java @@ -6,6 +6,7 @@ import StevenDimDoors.mod_pocketDim.core.DDLock; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.LinkType; import StevenDimDoors.mod_pocketDim.util.Point4D; +import net.minecraft.nbt.NBTTagCompound; public class ClientLinkData { @@ -49,6 +50,23 @@ public class ClientLinkData } } + public void writeToNBT(NBTTagCompound tag) { + tag.setInteger("Type", this.type.index); + + if (this.lock != null) { + NBTTagCompound lock = new NBTTagCompound(); + lock.setBoolean("State", this.lock.getLockState()); + lock.setInteger("Key", this.lock.getLockKey()); + tag.setTag("Lock", lock); + } + + if (this.point != null) { + NBTTagCompound point = new NBTTagCompound(); + Point4D.writeToNBT(this.point, point); + tag.setTag("Point", point); + } + } + public static ClientLinkData read(DataInput input) throws IOException { Point4D point = Point4D.read(input); @@ -60,4 +78,17 @@ public class ClientLinkData } return new ClientLinkData(point, type, lock); } + + public static ClientLinkData readFromNBT(NBTTagCompound tag) { + LinkType type = LinkType.getLinkTypeFromIndex(tag.getInteger("Type")); + Point4D point = null; + if (tag.hasKey("Point")) + point = Point4D.readFromNBT(tag.getCompoundTag("Point")); + DDLock lock = null; + if (tag.hasKey("Lock")) { + NBTTagCompound lockTag = tag.getCompoundTag("Lock"); + lock = new DDLock(lockTag.getBoolean("State"),lockTag.getInteger("Key")); + } + return new ClientLinkData(point, type, lock); + } } diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 00000000..e4056bc8 --- /dev/null +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 +Ant-Version: Apache Ant 1.8.3 +Created-By: 1.6.0_45-b06 (Sun Microsystems Inc.) +FMLAT: accessTransformer.cfg diff --git a/src/main/resources/META-INF/accessTransformer.cfg b/src/main/resources/META-INF/accessTransformer.cfg new file mode 100644 index 00000000..6a6d4832 --- /dev/null +++ b/src/main/resources/META-INF/accessTransformer.cfg @@ -0,0 +1 @@ +public net.minecraft.block.Block field_149781_w # Block resistance