Jump to content

Problem with sync of screen and tile entity


Anubis

Recommended Posts

I created a tile entity, that can perform a crafting operation. Everything works as expected, but when I close the screen while working and open it after it has finished, the sceen shows the progress of when I closed the screen. Starting a new craftingoperation solves the problem, but this isn't right. I used the FunctionalIntReferenceHolder to keep track of the values of the tile entity, but I am not sure if this is the right way. Here is my code:

The screen:

	private void drawProgress() {
		RenderSystem.color4f(1F, 1F, 1F, 1F);
		minecraft.getTextureManager().bindTexture(BACKGROUND);
		int up = 0;
		int left = xSize;
		int down = ySizeProgress;
		int currentTime = this.container.currentWorktime.get();
		int maxTime = this.container.maxWorktime.get();
		int right = (int) Math.round(xSizeProgress * currentTime / maxTime);
		int gui_grafic_size = 256;
		blit(guiLeft + 52, guiTop + 56, left, up, right, down, gui_grafic_size, gui_grafic_size);
	}

The container:

	@Override
	public void init() {
		tileEntity.getInventory().ifPresent(handler -> {
			addSlot(new SlotItemHandler(handler, 0, 20, 76));
			addSlot(new SlotItemHandler(handler, 1, 139, 76));
		});
		addPlayerInventory(8, 113);
		
		this.trackInt(currentWorktime =
				new FunctionalIntReferenceHolder(() -> ((FlintFactoryTile_Entity) this.tileEntity).currentWorkTime,
						v -> this.tileEntity.currentWorkTime = v));
		this.trackInt(maxWorktime = new FunctionalIntReferenceHolder(
				() -> ((FlintFactoryTile_Entity) this.tileEntity).maxWorkTime, v -> this.tileEntity.maxWorkTime = v));
		currentWorktime.get();
		maxWorktime.get();
		
	}

And the tile entity ticking part:

 @Override
    public void tick() {
	boolean dirty = false;

	if (world != null && !this.world.isRemote) {
	    boolean work = false;
	    if (this.factoryinventory.isPresent()) {
		Inventory inventory = getinventoryasInventory();
		Inventory inputinv = new Inventory(inventory.getStackInSlot(0));
		Inventory outputinv = new Inventory(inventory.getStackInSlot(1));
		if (this.selectedRecipe != null) {

		    ItemStack output = this.selectedRecipe.getCraftingResult(inputinv);
		    boolean flag = inputinv.getStackInSlot(0).getCount() >= this.selectedRecipe.getIngredientCount();
		    if(!flag) {
			this.selectedRecipe=null;
			currentWorkTime=0;
		    }
		    work = outputinv.isEmpty() && flag;
		    if (!work) {
			ItemStack itemStack = outputinv.getStackInSlot(0);
			boolean equal = itemStack.isItemEqual(output);
			boolean fitting = itemStack.getMaxStackSize() >= output.getCount() + itemStack.getCount();
			work = equal && fitting && flag;
		    }

		    if (work) {
			dirty = true;
			if (this.currentWorkTime < this.maxWorkTime) {
			    this.currentWorkTime++;
			} else {
			    this.currentWorkTime = 0;
			    outputinv.addItem(output);
			    this.selectedRecipe = null;
			    this.factoryinventory.ifPresent(consumer -> {
				consumer.setStackInSlot(1, outputinv.getStackInSlot(0));
				consumer.getStackInSlot(0).shrink(2);
			    });
			    
			}
		    }

		}
	    }
	    this.world.setBlockState(this.getPos(), this.getBlockState().with(FlintFactoryBlock.WORKING, work));
	}
	if (dirty) {
	    this.markDirty();
	    this.world.notifyBlockUpdate(this.pos, this.getBlockState(), this.getBlockState(),
		    Constants.BlockFlags.BLOCK_UPDATE);
	}

 

Thanks for help

 

Link to comment
Share on other sites

3 minutes ago, diesieben07 said:

First of all, it seems that while working you call notifyBlockUpdate every tick.

So, only call it on start an end of the crafting progress?

3 minutes ago, diesieben07 said:

It seems like your TE does not reset maxWorkTime when it stops working.

Max work time is the end time and is include in the json of the recipe, the current work time is the time which is ticking and resets at the end. So while no recipe is executed, the current work time is 0 and the progress bar stays at 0%. And when recipe starts, the max work time is defined, so the scaling can be done with every recipe on its own.

 

Link to comment
Share on other sites

3 minutes ago, diesieben07 said:

Do you know what this method does? Why are you calling it at all?

Yes I know. My block has 2 states, weather it is working or not. See pictures below.

The working state:

image.thumb.png.5370746ab783c891005dce6203d10e4d.png

The default state:

image.thumb.png.fe04025da59c61a14041a66c885c3c1a.png

The gui:

image.thumb.png.9db82dddf9148b8982d51b8a4c96ceb7.png

The Gui in progress:

image.thumb.png.a8d3a8101c92ccf59c7b377f553c0b0d.png

4 minutes ago, diesieben07 said:

The logic you have here is hard to grasp just looking at the code. Please post a Git repo so I can use the debugger.

The recipes have there own working time, so when you click the recipe you want, the work time is read from the recipe. Here is on example recipe:

{
  "type": "crushing_project:lumbermilling",
  "ingredients": [
    {
      "item": "crushing_project:throable_flint",
      "count": 2
    }
  ],
  "result": "crushing_project:flint_and_flint",
  "count": 1,
  "crafttime": 50
}

 

 

I don't use github at the moment, so posting wont help me so much, especially because my problems are solved. Thanks for the help.

Link to comment
Share on other sites

8 minutes ago, diesieben07 said:

notifyBlockUpdate is not how you change block states though. You do that with setBlockState.

Ok, I thanks. I will use setBlockState. The code was a bit older, so I don't know why I used notifyBlockUpdate, but I checked setBlockState and it seems to call notifyBlockUpdate finally to. It calls markAndNotifyBlock which calls notifyBlockUpdate after much more other logic. I like to prevent other logics and the the process time comes down. I think this is why I used notifyBlockUpdate  in the first case. But when you say setBlockState is the better way, I will trust you. I work in 1.15, i don't know if there is a difference to other versions.

Link to comment
Share on other sites

If you are still interested, I uploaded the code to github:

https://github.com/AlmightyAnubis/Crushing_Project

Would be a great honor, if a expert like you will check for mistakes. Many things where I couldn't find a good answer in the internet and looked in the minecraft code to copy similar behavior, which resulted in botching in some cases I guess...

But I know, that you have better thinks to do, so now problem if you don't have time for that.

 

I deleted all the json files, because github forced me to 100 files upload limit. But many of them can be recovered with a run of runData

Edited by Anubis
missing JSON
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.