Jump to content

[1.7.10] Force Interface(GUI) to update within tileentity


Recommended Posts

Posted

Hi, i was trying to make a machine, which(when click the button)write stackTagCompound of an itemstack in one slot and then output the result in the other slot. but the problem i met is when i use something like following code to do that, the "formatted" itemstack still "stay" at where it used to be, until i click it. and my question is, how to do that automaticly?

public class TileEntityMachin extends TileEntity implements IInventory{
      private ItemStack[] items;
     .....
     public void FormatItem(int input, int output)
     {
           ItemStack item = items[input].copy();
           items[input] = null; // because i have set the maxStackLimit to 1
           
          if (item != null && item.stackTagCompound != null)
         {
                   ....format that item....
         }

        items[output] = item;
     }
}

 

PS: i have also tried to use setInventorySlotContents, but its also not get fixed.

Posted

Guis are client side only. In order to make changes to slots and items, you need to do or on the server.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Guis are client side only. In order to make changes to slots and items, you need to do or on the server.

 

i have registered messagehandler for doing this, when the button is clicked, a message is sent to MessageHandler (on server side) and in the messagehandler the method "FormatItem" will be called. also the tileentity is  get through getServerHandler().playerEntity.openContainer like follow:


Container container = ctx.getServerHandler().playerEntity.openContainer;

if (container != null && container instanceof ContainerMachine)
{
        TileEntityMachine machine = ((ContainerMachine)container).getMachine();
       machine.FormatItem(input, output);
}

 

so i think i have done changes to slot and items at server side...but the problem is client-side Gui is not refreshed when i done these changes to slot and item :(

Posted

Process is:

- Server sends packet to all relevant clients (might be those who have the GUI open or more, depends on your needs) when the data changes.

 

- Client sends packet to request change of data (triggered from GUI).

 

- This change of data (which then happens on the server) triggers the packet from step 1, which updates the client.

 

Sry, im just kinda stupid maybe. But i still can't find out why my gui doesn't refresh. here is what i have done:

 

firstly a MessageHandler is registered on the server side:

msgWrapper.registerMessage(ButtonMessageHandler.class, ButtonMessage.class, MessageInfo.BTN_MESSAGE, Side.SERVER);

 

then in my Gui i have this one:

@Override
public void actionPerformed(GuiButton button)
{
	RedIntegrate.msgWrapper.sendToServer(new ButtonMessage((byte)button.id));
}

so in my opinion, i have sent the button click message to the server. and the server will process it like:

public class ButtonMessageHandler implements IMessageHandler<ButtonMessage, IMessage>{

@Override
public IMessage onMessage(ButtonMessage message, MessageContext ctx) {

	switch (message.btnID)
	{
	case GuiInfos.GUI_ProcessorHolder_BTN_FORMAT:
		Container container = ctx.getServerHandler().playerEntity.openContainer;

		if (container != null && container instanceof ContainerProcessorHolder)
		{
			TileEntityProcessorHolder holder = ((ContainerProcessorHolder)container).getProcessorHolder();
			holder.FormatChip();
		}

		break;
	}

	return null;
}

}

 

and in TE's FormatChip method, i wrote:

public void FormatChip()
{
	ItemStack item = items[1].copy();

	items[1] = null;
	if (item != null && items[2] == null && item.getItem().equals(IntegratedItems.itemFPGA))
	{
		if(item.stackTagCompound == null)
		{
			item.stackTagCompound = new NBTTagCompound();
		}

		item.stackTagCompound.setBoolean("formatted", true);
		item.stackTagCompound.setIntArray("outputs", outPorts);
		item.stackTagCompound.setIntArray("inputs", inPorts);

		items[2] = item;
	}
}

 

i have read some where that the Inventory will sync automaticly, so i think the content of this tileentity on client side will then sync automaticly with the one on server side. Am i wrong?

Posted

That should work.

 

but in fact it made the change in tileentity, but gui is not refreshed unless i click that slot(slot 1 in this case), and i'm confused about this for almost the whole week :(

Posted

Please show your Container.

 

my container is like this:

public class ContainerProcessorHolder extends Container{

private TileEntityProcessorHolder holder;

public ContainerProcessorHolder(InventoryPlayer invPlayer, TileEntityProcessorHolder TE_ProcessorHolder)
{
	this.holder = TE_ProcessorHolder;

	// linking hotbar into interface
	for (int x = 0; x < 9; ++x)
	{
		this.addSlotToContainer(new Slot(invPlayer, x, 8 + 18*x, 178));
	}

	// linking player inventory to interface
	for (int y = 0; y < 3; ++y)
		for (int x = 0; x < 9; ++x)
		{
			this.addSlotToContainer(new Slot(invPlayer, x + y * 9 + 9, 8 + 18 * x, 120 + y*18));
		}

	// linking 3 ProcessorHolderSlot to interface
	// gray one
	this.addSlotToContainer(new SlotProcessor(TE_ProcessorHolder, 0, 77, 39));
	// orange one
	this.addSlotToContainer(new SlotProcessor(TE_ProcessorHolder, 1, 53, 77));
	// green one
	this.addSlotToContainer(new SlotProcessor(TE_ProcessorHolder, 2, 105, 77));
}

@Override
public boolean canInteractWith(EntityPlayer player) {
	return holder.isUseableByPlayer(player);
}

@Override
public ItemStack transferStackInSlot(EntityPlayer player, int i)
{
	Slot slot = getSlot(i);

	if(slot != null && slot.getHasStack())
	{
		ItemStack stack = slot.getStack();
		ItemStack result = stack.copy();

		if (i >= 36)
		{
			// transfer item from the Machine's Inventory
			if (!mergeItemStack(stack, 0, 36, false))
			{
				return null;
			}
		}
		else
		{
			// transfer item from players inventory
			if (!stack.getItem().equals(IntegratedItems.itemFPGA) || !mergeItemStack(stack, 36, 36 + holder.getSizeInventory(), false))
			{
				return null;
			}
		}

		slot.putStack(null); // because FPGA's stack limit = 1

		slot.onPickupFromSlot(player, stack);

		return result;

	}

	return null;
}

@Override
public void onContainerClosed(EntityPlayer player)
{
	holder.closeInventory();
}

public TileEntityProcessorHolder getProcessorHolder()
{
	return holder;
}
}

 

do i need to implement method to make that work?

Posted

Looks all correct.

 

yep...it seems so..but there must be something wrong..or maybe my MC is wrong? cause i always get "faild to init device" when starting MC

Posted

That's unrelated. I am not sure what causes this to be honest.

Can you show how you open the GUI?

 

of course:

 

so firstly on the server side:

@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
{
	if (!world.isRemote)
	{
		TileEntity te = world.getTileEntity(x, y, z);
		if (te != null && te instanceof TileEntityProcessorHolder)
		{
			if(((TileEntityProcessorHolder)te).isUseableByPlayer(player))
				((TileEntityProcessorHolder)te).openInventory();
		}

		FMLNetworkHandler.openGui(player, RedIntegrate.instance, GuiInfos.GUI_ProcessorHolder, world, x, y, z);
	}
	return true;
}

 

PS: te.openInventory() is only to set a flag for keeping search for some special block when gui is opened

 

and here is the interface:

@SideOnly(Side.CLIENT)
public class GuiProcessorHolder extends GuiContainer {

private TileEntityProcessorHolder holder;

public GuiProcessorHolder(InventoryPlayer invPlayer, TileEntityProcessorHolder TE_ProcessorHolder) {
	super(new ContainerProcessorHolder(invPlayer, TE_ProcessorHolder));
	xSize = 176;
	ySize = 201;
	// TODO Auto-generated constructor stub
}

private static final ResourceLocation texture = new ResourceLocation(GuiInfos.RESOURCE_LOCATION, "textures/gui/GuiProcessorHolder.png");

@Override
protected void drawGuiContainerBackgroundLayer(float f, int x, int y) {
	// TODO Auto-generated method stub
	GL11.glColor4f(1, 1, 1, 1);

	this.mc.getMinecraft().renderEngine.bindTexture(texture);

	this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);

}

@Override
protected void drawGuiContainerForegroundLayer(int x, int y)
{
	this.fontRendererObj.drawString("Processor Holder", 8, 6, 0x404040);
}

@Override
public void initGui()
{
	super.initGui();

	buttonList.clear();

	buttonList.add(new GuiButton(GuiInfos.GUI_ProcessorHolder_BTN_FORMAT, guiLeft + xSize, guiTop, 60, 20, "Format"));
}

@Override
public void actionPerformed(GuiButton button)
{
	RedIntegrate.msgWrapper.sendToServer(new ButtonMessage((byte)button.id));
}
}

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.