mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-13 17:04:25 +00:00
Added multipart save/load based movement helper functions.
This commit is contained in:
1 parent
df62267614
commit
533e778648
2 files changed
+72
-5
No files matched your search
@@ -0,0 +1,60 @@
|
||||
package codechicken.multipart
|
||||
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
import codechicken.multipart.handler.MultipartSaveLoad
|
||||
import com.google.common.collect.LinkedListMultimap
|
||||
import scala.collection.JavaConversions._
|
||||
import codechicken.multipart.handler.MultipartSPH
|
||||
import net.minecraft.world.WorldServer
|
||||
import java.util.{List => JList}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import java.util.Arrays
|
||||
|
||||
/**
|
||||
* Static helper class for handling the unusual way that multipart tile entities load from nbt and send description packets
|
||||
* <br>
|
||||
* Multipart tile entities will all save themselves with the id "savedMultipart" which if normally loaded by minecraft,
|
||||
* will create a dummy tile entity which just holds the NBT it was read from. These dummies are then converted to actual container tiles on the ChunkLoad event.
|
||||
* The createTileFromNBT function should be used to construct a multipart tile from NBT without the ChunkLoad event.
|
||||
* <br>
|
||||
* Multipart tile entities do not send description packets via the conventional means of one packet per tile when PlayerInstance calls for it, to do so would be terribly inefficient.
|
||||
* Instead, the ChunkWatch event is used to batch all the describing data for a chunk into one packet which is compressed using relative positions.
|
||||
* The sendDescPacket(s) functions should be used to send the description packet of a tile or tiles without a ChunkWatch event.
|
||||
* <br>
|
||||
* An example of using this class to move blocks/tile entites around can be found at www.chickenbones.craftsaddle.org/Files/Other/ItemDevTool2.java
|
||||
*/
|
||||
object MultipartHelper
|
||||
{
|
||||
def createTileFromNBT(world:World, tag:NBTTagCompound):TileEntity = {
|
||||
if(!tag.getString("id").equals("savedMultipart"))
|
||||
return null
|
||||
|
||||
MultipartSaveLoad.loadingWorld = world
|
||||
return TileMultipart.createFromNBT(tag);
|
||||
}
|
||||
|
||||
def sendDescPacket(world:World, tile:TileEntity) {
|
||||
val c = world.getChunkFromBlockCoords(tile.xCoord, tile.zCoord)
|
||||
val pkt = MultipartSPH.getDescPacket(c, Arrays.asList(tile).iterator)
|
||||
if(pkt != null)
|
||||
pkt.sendToChunk(world, c.xPosition, c.zPosition)
|
||||
}
|
||||
|
||||
def sendDescPackets(world:World, tiles:Iterable[TileEntity]) {
|
||||
val map = LinkedListMultimap.create[Long, TileEntity]()
|
||||
tiles.foreach(t => map.put(t.xCoord.toLong<<32|t.zCoord, t))
|
||||
|
||||
val mgr = world.asInstanceOf[WorldServer].getPlayerManager
|
||||
map.asMap.entrySet.foreach{e =>
|
||||
val coord = e.getKey
|
||||
val c = world.getChunkFromBlockCoords((coord>>32).toInt, coord.toInt)
|
||||
lazy val pkt = MultipartSPH.getDescPacket(c, e.getValue.iterator)
|
||||
val inst = mgr.getOrCreateChunkWatcher(c.xPosition, c.zPosition, false)
|
||||
if(!inst.playersInChunk.isEmpty)
|
||||
inst.sendToAllPlayersWatchingChunk(pkt.toPacket)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.chunk.Chunk
|
||||
import java.util.Map
|
||||
import java.util.Iterator
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import codechicken.multipart.TileMultipart
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@@ -140,13 +141,19 @@ object MultipartSPH extends MultipartPH with IServerPacketHandler
|
||||
|
||||
def onChunkWatch(player:EntityPlayer, chunk:Chunk)
|
||||
{
|
||||
val iterator = chunk.chunkTileEntityMap.asInstanceOf[Map[_, TileEntity]].values.iterator
|
||||
val pkt = getDescPacket(chunk, chunk.chunkTileEntityMap.asInstanceOf[Map[_, TileEntity]].values.iterator)
|
||||
if(pkt != null)
|
||||
pkt.sendToPlayer(player)
|
||||
}
|
||||
|
||||
def getDescPacket(chunk:Chunk, it:Iterator[TileEntity]):PacketCustom =
|
||||
{
|
||||
val s = new MCByteStream(new ByteArrayOutputStream)
|
||||
|
||||
var num = 0
|
||||
while(iterator.hasNext)
|
||||
while(it.hasNext)
|
||||
{
|
||||
val tile = iterator.next
|
||||
val tile = it.next
|
||||
if(tile.isInstanceOf[TileMultipart])
|
||||
{
|
||||
s.writeShort(indexInChunk(new BlockCoord(tile)))
|
||||
@@ -156,11 +163,11 @@ object MultipartSPH extends MultipartPH with IServerPacketHandler
|
||||
}
|
||||
if(num != 0)
|
||||
{
|
||||
new PacketCustom(channel, 2).setChunkDataPacket().compressed()
|
||||
return new PacketCustom(channel, 2).setChunkDataPacket().compressed()
|
||||
.writeInt(chunk.xPosition).writeInt(chunk.zPosition)
|
||||
.writeShort(num)
|
||||
.writeByteArray(s.getBytes)
|
||||
.sendToPlayer(player)
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user