Jump to content

Call method when block is watched by player


BenignBanana

Recommended Posts

Hey everyone,

I hate to ask for yet more help after all my threads over the last few days, but this is a framework question so at least I'm not just an idiot and have a bug in my own code. I need to do an initial full sync for my TileEntities whenever a player starts watching it (or in the case of the client, as soon as the single player gets loaded in). How can I hook into this to trigger the sync? I tried to put it in onLoad() but that seems to be called before the client is loaded and it wouldn't work for multiplayer anyways.

Cheers in advance

Link to comment
Share on other sites

TileEntity#getUpdateTag is called when a Chunk is being sent to players and the returned compound tag is included in the SPacketChunkData.

 

ChunkWatchEvent.Watch is fired when a player starts watching a Chunk, directly after the SPacketChunkData has been sent.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Alright so I used getUpdateTag() which does actually fire (tried getUpdatePacket() yesterday, which doesn't seem to fire in SP). However it seems at the time getUpdateTag() is called, the world isn't properly loaded yet and all blocks return as air. Where do I need to hook in to get the first viable state where the player is watching and the client has already loaded the world from the server?

 

Edit: I use a custom sync system with all the networking handled in my library, I could use writeToNBT() but it would significantly increase the overhead for networking.

Edited by BenignBanana
Link to comment
Share on other sites

I don't access the world or blocks when making the tag, I wanted to use my "own" (really OpenModsLib's) sync system to send the syncable info over a custom network channel. That code needs to get the TileEntity at the relevant position so it can handle the incoming sync data. I solved this for now by just serializing the sync map into NBT and returning that in getUpdateTag(), but I'd really prefer to use a unified sync method. The readFromNBT()/writeToNBT() on the sync map are only supposed to be called when loading/saving the world, so I dislike calling it for synchronisation. So I need an event that triggers after a player has loaded the world from the server.

 

Edit: Here's my code that requires the world to be loaded:

                override fun findHandler(world: World, input: DataInput): ISyncMapProvider? {
                    val x = input.readInt()
                    val y = input.readInt()
                    val z = input.readInt()
                    val blockPos = BlockPos(x, y ,z)

                    if(!world.isAirBlock(blockPos)) {
                        val tile = world.getTileEntity(blockPos)
                        if(tile is ISyncMapProvider) return tile
                    }

                    Log.warn("Invalid handler info: can't find ISyncHandler TE @ ($x,$y,$z)", x, y, z)
                    return null
                }

 

Edited by BenignBanana
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.