Jump to content

[1.11.2] Modyfing tile entity data from client gui & TESR rendering


grand_gibus

Recommended Posts

Hello everyone, 
I'd like to make a client gui that updates a tile entitie data, on server and client side, and for every player. How would I go about doing that?
I looked at the command block gui, it sends a packet to somewhere but I don't know what happens next.

 

Also, totally unrealted:

I made a TESR that renders stuff in a large area. The thing is, that if you look away from the tile entity block, the render disepears where I'd like to still be able to see the render. How could I fix that? The StructureBlock TESR has a field 

	    @Override
	    public boolean isGlobalRenderer(TileEntityStructure te)
	    {
	        return true;
	    }

,but I tried to integrate it and it didn't change anything, so yeah.

 

Thanks in advance!

Link to comment
Share on other sites

To send data to the server you would have to create a custom packet (IMessage) along with a handler (IMessageHandler) and a NetworkWrapper for your mod using NetworkRegistry.INSTANCE.newSimpleChannel.

 

All it'd have to do is contain the relevant data (x,y,z) and on the handler get the tile entity at that location and update your data.

 

Hope this helps in some way

  • Like 1
Link to comment
Share on other sites

5 hours ago, grand_gibus said:

I made a TESR that renders stuff in a large area. The thing is, that if you look away from the tile entity block, the render disepears where I'd like to still be able to see the render. How could I fix that?

Override TileEntity::getRenderBoundingBox to return appropriate size of the rendered object.

2 hours ago, grand_gibus said:

But it the problem seemed that the server wasnt updating the client tile entities

If it's about rendering, you are not marking the TE as updated for rendering. I think you should call World#markAndNotifyBlock. (The flag parameter is explained on World#setBlockState)

  • Like 2

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

1 hour ago, grand_gibus said:

Thanks Abastro! It works for the TESR. 
For the TileEntity, where should I call the World#markAndNotifyBlock from? I've tried on both sides with no success.

It should work on either side, as it sends the update packet.

How and where did you call it?

Also how are you syncing the tileentity? Please post the relevant code.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

Here is my code:

(TileEntity, IMessage, IMessageHandler, Client GUI)



public class TileEntityWorkBench extends TileEntity{

	private String schematicName = "";
	
	public TileEntityWorkBench(){
	}
	
	public void updateSchematicName(String name){
		this.schematicName = name;
	}
	
	public String getSchematicName(){
		return this.schematicName;
	}
	
    public void readFromNBT(NBTTagCompound compound)
    {
    	this.schematicName = compound.getString("schematicName");
        super.readFromNBT(compound);

    }

    public NBTTagCompound writeToNBT(NBTTagCompound compound)
    {
        NBTTagCompound nbt = super.writeToNBT(compound);
    	nbt.setString("schematicName", schematicName);
    	return nbt;
    }
    
    
    @Override
    public AxisAlignedBB getRenderBoundingBox(){
    	return INFINITE_EXTENT_AABB;
    }
    
}


public class ServerMessage implements IMessage {

	  public ServerMessage(){}
	  
	  public int messageType;
	  public NBTTagCompound tag;
	  public ServerMessage(int messageType, NBTTagCompound tag) {
		  this.tag = tag;
		  this.messageType = messageType;
	  }

	  @Override
	  public void toBytes(ByteBuf buf) {
		  buf.writeInt(messageType);
		  ByteBufUtils.writeTag(buf, tag);
	  }

	  @Override
	  public void fromBytes(ByteBuf buf) {
		  this.messageType = buf.readInt();
		  this.tag = ByteBufUtils.readTag(buf);
	  }
	  
	  public static ServerMessage createUpdateWorkbenchMessage(int x, int y, int z, String schematicName){
		  NBTTagCompound nbt = new NBTTagCompound();
		  nbt.setString("schematicname", schematicName);
		  nbt.setInteger("x", x);
		  nbt.setInteger("y", y);
		  nbt.setInteger("z", z);
		  return new ServerMessage(ServerReciever.UPDATE_WORKBENCH_MESSAGE, nbt);
	  }
}



public class ServerReciever implements IMessageHandler<ServerMessage, IMessage> {
	
	public static final int UPDATE_WORKBENCH_MESSAGE = 0;
	
	@Override
	public IMessage onMessage(ServerMessage message, MessageContext ctx) {
		switch(message.messageType){
		
		case UPDATE_WORKBENCH_MESSAGE:
			updateWorkBenchInfo(message, ctx.getServerHandler().playerEntity.getServerWorld());
			break;
			
		default:
			break;
		}
		return null;
	}
	
	public static void updateWorkBenchInfo(ServerMessage message, WorldServer world){
		NBTTagCompound nbt = message.tag;
		TileEntityWorkBench workbench = (TileEntityWorkBench) world.getTileEntity(new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z")));
		workbench.updateSchematicName(nbt.getString("schematicname"));
		BlockPos pos = new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z"));
		world.markAndNotifyBlock(pos, null, world.getBlockState(pos), world.getBlockState(pos), 1);
		return;
	}
}


public class GuiWorkBench extends GuiScreen{
	
	public TileEntityWorkBench workbench;
	public BlockPos position;
	
	private GuiButton exportButton;
	private GuiTextField schematicName;
	
	public GuiWorkBench(TileEntityWorkBench workbench){
		this.workbench = workbench;
		this.position = workbench.getPos();
	}
	
	@Override
	public void initGui() {
		this.workbench = (TileEntityWorkBench) this.mc.world.getTileEntity(this.position);
		super.initGui();
	    this.buttonList.add(this.exportButton = new GuiButton(0, this.width / 2 - 100, this.height / 2 + 30, MillenaireLanguage.getGuiTraduction("workbench.export_button", new Object[0])));
	    this.schematicName = new GuiTextField(1, fontRendererObj, this.width / 2 - 90, this.height / 2, 180, 20);
	    this.schematicName.setText(this.workbench.getSchematicName());
	    
	    Keyboard.enableRepeatEvents(true);
	}
	
	@Override
	public void drawScreen(int mouseX, int mouseY, float partialTicks) {
		String welcomeText = MillenaireLanguage.getGuiTraduction("workbench.welcome", new Object[] {this.mc.player.getName()});
	    
		this.drawDefaultBackground();
		
	    super.drawScreen(mouseX, mouseY, partialTicks);

	    this.schematicName.drawTextBox();
	    this.schematicName.setFocused(true);
	    this.schematicName.updateCursorCounter();
	    
	    this.drawCenteredString(mc.fontRendererObj, welcomeText, this.width / 2 , this.height / 2 - 24, 0xFFFFFF);
	    
	    
	}
	
	@Override
	protected void actionPerformed(GuiButton button) throws IOException {
	    if (button == this.exportButton) {
	    	MillenaireNetwork.sendToServer(ServerMessage.createUpdateWorkbenchMessage(this.position.getX(), this.position.getY(), this.position.getZ(), schematicName.getText()));
	    	this.mc.displayGuiScreen(null);
	        if (this.mc.currentScreen == null){
	            this.mc.setIngameFocus();
	        }
	    }
	}
	
    /**
     * Returns true if this GUI should pause the game when it is displayed in single-player
     */
    public boolean doesGuiPauseGame()
    {
        return false;
    }
    
    /**
     * Fired when a key is typed (except F11 which toggles full screen). This is the equivalent of
     * KeyListener.keyTyped(KeyEvent e). Args : character (character on the key), keyCode (lwjgl Keyboard key code)
     */
    protected void keyTyped(char typedChar, int keyCode) throws IOException{
    	if(keyCode == 1){
	        this.mc.displayGuiScreen(null);
	        
	        
	        if (this.mc.currentScreen == null){
	            this.mc.setIngameFocus();
	        }
    	}else{
    		this.schematicName.textboxKeyTyped(typedChar, keyCode);
    	}
    }
    
    /**
     * Called when the screen is unloaded. Used to disable keyboard repeat events
     */
    public void onGuiClosed()
    {
        Keyboard.enableRepeatEvents(false);
    }
    
    
    
    public class MathGuiButton extends GuiButton{

		public MathGuiButton(int buttonId, int x, int y, String buttonText) {
			super(buttonId, x, y, buttonText);
			
			this.width = 20;
			this.height = 20;
		}
    	
    }
}

Sorry, didn't know what would be the most relevant code to show :P

Link to comment
Share on other sites

So it's client->server update from the gui.

You need to implement tileentity syncing.

I think this post will cover your case.

You can manually read the data from the update packet with TileEntity#onDataPacket. Use it if you don't want readFromNBT to do the work. (e.g. update packet has a different format)

  • Like 1

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

Thank you Abastro!
It didn't really work out in the first place but then I messed a bit around and it ended up working by adding an onDataPacket() override . Here is my code if anyone from the future has this problem:

	@Override
    public void readFromNBT(NBTTagCompound compound)
    {
    	this.schematicName = compound.getString("schematicName");
        super.readFromNBT(compound);

    }

	@Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound)
    {
        NBTTagCompound nbt = super.writeToNBT(compound);
    	nbt.setString("schematicName", schematicName);
    	return nbt;
    }    
@Override
    public NBTTagCompound getUpdateTag()
    {
        return this.writeToNBT(new NBTTagCompound());
    }
    
    @Nullable
    @Override
    public SPacketUpdateTileEntity getUpdatePacket()
    {
        return new SPacketUpdateTileEntity(this.getPos(), 1, this.getUpdateTag());
    }
    
    @Override
    public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt)
    {
    	this.readFromNBT(pkt.getNbtCompound());
    }

When the client the custom server packet handler recieve a message from the client gui, it executes this code:

	public static void updateWorkBenchInfo(ServerMessage message, WorldServer world){
		NBTTagCompound nbt = message.tag;
		TileEntityWorkBench workbench = (TileEntityWorkBench) world.getTileEntity(new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z")));
		workbench.updateSchematicName(nbt.getString("schematicname"));
		BlockPos pos = new BlockPos(nbt.getInteger("x"), nbt.getInteger("y"), nbt.getInteger("z"));
		world.markAndNotifyBlock(pos, null, world.getBlockState(pos), world.getBlockState(pos), 2);
		return;
	}

 

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.

Announcements



×
×
  • Create New...

Important Information

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