Jump to content

Recommended Posts

Posted

You're probably using a static variable somewhere. The TileEntities for each block should be all be different instances of your TileEntity class. I can't think of any reason why that might be so. But if one of the variables inside your TileEntity was declared as `static` then every TileEntity would share that same state. From the way you describe it, I'd guess that more than one of your variables is declared static.

  • Like 1
Posted

Post your code.

Some tips:

Spoiler

Modder Support:

Spoiler

1. Do not follow tutorials on YouTube, especially TechnoVision (previously called Loremaster) and HarryTalks, due to their promotion of bad practice and usage of outdated code.

2. Always post your code.

3. Never copy and paste code. You won't learn anything from doing that.

4. 

Quote

Programming via Eclipse's hotfixes will get you nowhere

5. Learn to use your IDE, especially the debugger.

6.

Quote

The "picture that's worth 1000 words" only works if there's an obvious problem or a freehand red circle around it.

Support & Bug Reports:

Spoiler

1. Read the EAQ before asking for help. Remember to provide the appropriate log(s).

2. Versions below 1.11 are no longer supported due to their age. Update to a modern version of Minecraft to receive support.

 

 

Posted
1 hour ago, jaminv said:

You're probably using a static variable somewhere. The TileEntities for each block should be all be different instances of your TileEntity class. I can't think of any reason why that might be so. But if one of the variables inside your TileEntity was declared as `static` then every TileEntity would share that same state. From the way you describe it, I'd guess that more than one of your variables is declared static.

Is it only apply on tileentity class or include block class as well?

Posted

One thing I noticed is that you shouldn't be calling BlockWorkbench.setState() from your TileEntity. Instead, you should add a method called getActualState() from your Block. In that method you can call world.getTileEntity(pos), get data from the TE, and return it in an IBlockState. Here's how I've done it in the past.

 

	@Override
	public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
        TileEntity tileentity = BlockHelper.getTileEntity(worldIn, pos);

        EnumFacing facing = EnumFacing.NORTH;
       	boolean active = false;

        if (tileentity instanceof TileEntityMachineBase) {
        	TileEntityMachineBase te = (TileEntityMachineBase)tileentity;
        	facing = te.getFacing();
        	active = te.isProcessing();
        }
        
        return state.withProperty(FACING, facing).withProperty(ACTIVE, active);
	}

 

I don't think this is causing your current problem, it's just the correct way to do things. I don't think you should really be calling World.setBlockState() the way that you are. It could cause you problems down the line.

 

Quote

Is it only apply on tileentity class or include block class as well?

The Block class uses a singleton pattern. Minecraft only creates one Block instance no matter how many blocks of that type there are in the world. So Block classes are basically already de facto static. You should never store anything in a Block class, but instead use block states and tile entities, which you are doing correctly. TileEntities are not singleton. Minecraft creates a separate TileEntity for every instance of a block in the [loaded] world. I don't see you doing anything wrong here. It's just important as a modder to understand what Minecraft is doing here.

 

private WorkstationEnergyStorage storage = new WorkstationEnergyStorage(6000);
...
private int cookTime, energy = storage.getEnergyStored();

 

You've got some weirdness with your energy handling. You probably shouldn't be storing the energy value in your TileEntity, but instead relying on WorkstationEnergyStorage storage to handle it for you. I'm not even sure how your machine actually works, because it doesn't look like `energy` should ever be more than 0. The above code is only called once, and it storage.getEnergyStored() will always be 0 when it's called. I don't see anything else syncing your `energy` value to the energy storage. Even if there is some code I'm not seeing somewhere, it's going to cause you problems down the line. There's no reason to store the energy value as an integer in your TileEntity. It's stored in your energy storage. Use that.

 

					ItemStack output = WorkbenchRecipes.getInstance().getWorkbenchResult(inputs[0], inputs[1]);
					
					if(!output.isEmpty())
					{
						output = WorkbenchRecipes.getInstance().getWorkbenchResult(inputs[0], inputs[1]);
						smelting = output;
						cookTime++;
						energy--;
						BlockWorkbench.setState(true, world, pos);
						if(cookTime == 200)
						{
							cookTime = 0;
							output = WorkbenchRecipes.getInstance().getWorkbenchResult(inputs[0], inputs[1]);
							smelting = output;
							inputs[0].shrink(1);
							inputs[1].shrink(1);
							handler.setStackInSlot(0, inputs[0]);
							handler.setStackInSlot(1, inputs[1]);
							if(handler.getStackInSlot(2).getCount() > 0)
							{
								handler.getStackInSlot(2).grow(1);
							}
							else
							{
								handler.insertItem(2, smelting, false);
							}
							smelting = null;
							output = null;
							cookTime = 0;
							System.out.println("finish");
							this.markDirty();
							return;
						}
					}

 

You've got some weird duplicate code in your update() method. You're initializing `output` 3 times to the exact same value. You're just wasting processor cycles. `smelting` is initialized twice but never used. `output` is set to null at the end of your code, but it's a local variable and this isn't necessary. Perhaps you were just trying different things out, but I would clean this up. It makes it easier to see what going on.

Although I've spotted a few potential issues that might cause you problems down the road, nothing really stands out as the actual problem. Are you sure you've pushed your most recent code to Github? With the energy issue, I'm not sure how you get to the point where this is actually outputing items. Perhaps I'm looking at an older version of the code?

Posted

In WorkbenchRecipes:

	private final Table<ItemStack, ItemStack, ItemStack> workingList = HashBasedTable.<ItemStack, ItemStack, ItemStack>create();

 

ItemStack doesn't have a hashcode() method, so it's just using the default. There's no real way to guarantee that it will arrive at the same hash value for similar stacks, especially when you factor in item counts, NBT, etc. I'm not really sure how this is working for you at all (unless you're only putting 1 of each item in at a time), but it will almost certainly cause you problems down the line.

 

What I've had to do is create a wrapper class that implements hashcode() in a consistent manner:

	@Override
	public int hashCode() {
		// Although it might cause hash collision, we don't hash meta or NBT data. Hash collision should be fairly minimal.
		// We don't hash meta because wildcard meta data wouldn't work.
		// We don't hash NBT because then items with simple NBT data (like renaming in an anvil) would be rejected by the recipe.
		return item.getRegistryName().hashCode();
	}

 

Posted (edited)

i know all the codes are messy because Ive been working on these for quite a long time, how I wrote these code is basically read other mod's source code, but different mod had different setups, which makes me really confused. In the update() function, I tried multiple times to get it to work, so it's really messy but works. For me, the primary target is to make everything to work and then the efficient of the code runs. Thank you for you patients and all replies. I will record a video and what the problems looks like.

 

And no, the code on the github is the latest

 

Edit:

Here is the video

 

As you can see, 2 aluminium bars can produce a aluminium plate. To test the bug, I put 4 aluminium bars into the left workbench, which produces 2 plates, and I put 2 bars into the right one, which should produce only 1 plate, but in the vd, they share the results.

 

Edited by poopoodice
Posted

That is strange. It's even more strange that it the count is 1 at first and then changes it to 2. Since the update() routine is never performed on the client, it's likely not a client/server desync at the tile entity. It seems like it's happening somewhere in the container, but I don't see it.


Unfortunately, I don't have time to debug through all of your code and I can't really run it yourself. You should trace through it and watch it happening step by step. I suggest subclassing ItemStackHandler and override the onContentsChanged. You can even narrow it down by creating an if (slot == 2) {} statement with a dummy operation in it, and add a breakpoint there. When you hit the breakpoint, you can look at the stack trace and see everything that it causing an update to the slot.

 

	@Override
	protected void onContentsChanged(int slot) {
		if (slot == 2) {
			int a = 0; // Breakpoint here
		}
	}

 

  • Thanks 1
Posted
10 hours ago, jaminv said:

output = WorkbenchRecipes.getInstance().getWorkbenchResult(inputs[0], inputs[1]);

Whenever you are interacting with ItemStacks in recipes you need to do ItemStack#copy to create a new instance otherwise you are using the same one for all of them.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
1 hour ago, jaminv said:

That is strange. It's even more strange that it the count is 1 at first and then changes it to 2. Since the update() routine is never performed on the client, it's likely not a client/server desync at the tile entity. It seems like it's happening somewhere in the container, but I don't see it.


Unfortunately, I don't have time to debug through all of your code and I can't really run it yourself. You should trace through it and watch it happening step by step. I suggest subclassing ItemStackHandler and override the onContentsChanged. You can even narrow it down by creating an if (slot == 2) {} statement with a dummy operation in it, and add a breakpoint there. When you hit the breakpoint, you can look at the stack trace and see everything that it causing an update to the slot.

 


	@Override
	protected void onContentsChanged(int slot) {
		if (slot == 2) {
			int a = 0; // Breakpoint here
		}
	}

 

Thank you, I will try it out

Posted
3 minutes ago, poopoodice said:

Is copyItemStack(ItemStack stack)  What Im looking for? 

Looks like that method is from 1.9.4 so no. Use ItemStack#copy

  • Thanks 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

AnimeFan8888 is right about returning ItemStacks. That would definitely cause an issue like this. You should have getWorkbenchResult() return like this:

return ((ItemStack)ent.getValue()).copy();

There's a pretty good chance that will solve your problem. It certainly can't hurt.

 

---

 

I don't know if it helps because it might be total information overload, but the recipe management system for my mod is here: https://github.com/jaminvanderberg/AdvancedMachines/tree/master/src/main/java/jaminv/advancedmachines/util/recipe. It includes a three-ingredient recipe manager that handles ingredients in any order, ore dictionary, etc. There's a lot there because recipe management can get quite complicated. But if it helps, great.

  • Thanks 1
Posted
9 minutes ago, Animefan8888 said:

ItemStack stack = ...;
newStack = stack.copy();

 

9 minutes ago, jaminv said:

AnimeFan8888 is right about returning ItemStacks. That would definitely cause an issue like this. You should have getWorkbenchResult() return like this:


return ((ItemStack)ent.getValue()).copy();

There's a pretty good chance that will solve your problem. It certainly can't hurt.

 

---

 

I don't know if it helps because it might be total information overload, but the recipe management system for my mod is here: https://github.com/jaminvanderberg/AdvancedMachines/tree/master/src/main/java/jaminv/advancedmachines/util/recipe. It includes a three-ingredient recipe manager that handles ingredients in any order, ore dictionary, etc. There's a lot there because recipe management can get quite complicated. But if it helps, great.

Wow, they works! Thank you guys so much, Animefan8888 Ive subscribe to ur channel hope you can upload some nice tutorials, and jaminv thanks for all ur suggestions! :))

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.