Reborn Storage

Reborn Storage

41M Downloads

Inventory glitches when scrolling through pages

Wingnut601 opened this issue ยท 14 comments

commented

SkyFactory 3 v3.0.5
RebornStorage-1.10.2-1.0.0.22
Multiplayer server

I made a unit 9W x 5H x 5D. CPUs run 3-high down the center (21 CPUs). Crafting Storage units line the sides of the CPUs (42 Crafting Storage).

When I scroll through pages of the multiblock my inventory is randomly hidden and will remain hidden after exiting the interface until I click on an inventory slot that contains an item. Scrolling through the hotbar or using 1,2,3, etc. does not bring back my inventory. I must open (E) and click on an occupied slot.

When I scroll though pages of the multiblock after a page where my inventory is hidden the next page will either un-hide my inventory or it will now show in the multiblock inventory slots. When my inventory displays in the machine inventory I close the interface and click on an occupied slot in my inventory and it is un-hidden again.

When I scroll though pages of the multiblock I will have successive pages that show my inventory contents in the storage of the multiblock as well as on my character.

Hopefully this makes sense and gives you a good visual of what I have experienced. Below are some screenshots of the issue.

screenshot_1
screenshot_2
screenshot_3
screenshot_4

commented

If the glitch appears, it is always the exact same way. You can break the frame or come back later, the order of glitching pages is the exact same then before. Breaking all storage block and replacing them did fix it for me, so i assume the glitch occurs on assigning the inventories to the blocks and its messing up the ids/inventories in some way.

Never modded client side so its too hard for me to track it down in the code :/

--- EDIT:
probably found it ... I'll post a potential fix soon ... give me some time :)

commented

Have you updated forge? The newer versions make problems.

commented

Ah ok, thats useful to know it might help me track it down.

commented

It's in RebornStorage/src/main/java/RebornStorage/multiblocks/MultiBlockCrafter.java
i changed some stuff and made lots of comments, please review it :) it SHOULD fix it but who knows...

	@Override
	protected void onMachineAssembled() {
//		invs.clear(); // obsolete due to updateInfo() does this again.
		updateInfo();
		rebuildPatterns();
	}


	public void updateInfo(){
		powerUsage = 0;
		speed = 0;
		pages = 0;
		invs.clear();
		for(IMultiblockPart part : connectedParts){
			if(part.getBlockState().getValue(BlockMultiCrafter.VARIANTS).equals("storage")){
				pages ++;
				powerUsage += 5;
		/*	'part' should always be 'instanceof TileMultiCrafter' because of the previous
		 *	'if(part.getBlockState().getValue(BlockMultiCrafter.VARIANTS).equals("storage"))'
		 *	so this check becomes obsolete, right?
		 */
//				if(part instanceof TileMultiCrafter){
					TileMultiCrafter tile = (TileMultiCrafter) part;
		/*	'pages' should be equal to the id so 'id' can be replaced by 'pages' everywhere
		 *	cuz after we found 1 storage, pages = 1, after we found the 2nd it's 2 and so on...
		 */
//					int id = 0;
		/*	The next part is causing the error:
		 *	if the block was registered before in a bigger crafter he might have a higher id
		 *	assigned and this is causing some ids are not existing.
		 *	for example you build a crafter with 4 storages. They get id 1, 2, 3 and 4.
		 *	now edit the crafter and break storage 2 and 3 and replace them with cpus.
		 *	The new multiblock is scanning the internals:
		 *	storage 1, was already registered ... it keeps id 1
		 *	storage 4, already registered too ... it keeps id 4
		 *	new storages will be registered with id 3 and up due to we have alread have 2 invs
		 *	and need to add 1 for numeration this leads to at least id 2 is missing and it is
		 *	messing up everything (I assume thats the case)
		 */
		/*	to fix the glitch we are overriting existing ids and generate a new id in any case,
		 *	so this whole next part becomes obsolete, sadly
		 */
//					boolean genId = false; 
//					if(tile.page.isPresent()){
//						if(!invs.containsKey(tile.page.get())){
//							id = tile.page.get();
//						} else {
//							genId = true;
//						}
//					} else {
//						genId = true;
//					}
//					if(genId){
//						id = invs.size() + 1;  //Does this need +1?
		/*	in this case +1 seems to be better because page 1 gets id 1, page 2 gets id 2 ...
		 *	but it is obsolete due to pages takes over this variable
		 */
						tile.page = Optional.of(pages);
		/*	assign a new page id ('pages') to the block and dont care about the previous,
		 *	so numbers are always consecutive.
		 *	please check if this overwriting might break something somewhere else...
		 *	it shouldn't, but you know your code best
		 */
//					}
					invs.put(pages, tile.inv);
		/*	put it in the map with the new id ... of course :)
		 */
//				}

			}
			if(part.getBlockState().getValue(BlockMultiCrafter.VARIANTS).equals("cpu")){
				powerUsage += 10;
				speed++;
			}
		}
	}

---EDIT: derp i messed up the Optional.of() part ... fixed now

and this will only fix newly created crafter ... existing ones will still keep the bug until OnMachineAssembled() is called the next time ...

commented

A few people have reported this, but I have no idea why it happens.

commented

@modmuss50 have you looked at this

commented

Not just yet, need to find some time to sit down and have a look.

commented

Ok, @InflamedSebi I added your changes, only issue with them is the pages are not in the same order after a world relog.

Unless I missed something.

commented

@modmuss50 it should iterate over all blocks in the multiblock the same way every reload (along the axes from top to bottom) ... so swapping pages shouldn't happen ... is this always the case or just sometimes?

commented

Seems random to me for some reason.

commented

@modmuss50
This issue is still odd ... nvm here is the fix :)
but review it please, notepad doen't check syntax and stuff ^^

	public void updateInfo(){
		powerUsage = 0;
		speed = 0;
		pages = 0;
		invs.clear();
		TreeMap<Integer, TileMultiCrafter> collector = new TreeMap<Integer, TileMultiCrafter>();
		int append = 2745;
	/*	we ned to collect all storages first and assign ids after every storage is known
	 *	also we need them to be sorted ... so a treemap. 'append' is explained later
	 */
		for(IMultiblockPart part : connectedParts){
			if(part.getBlockState().getValue(BlockMultiCrafter.VARIANTS).equals("storage")){
				pages ++;
				powerUsage += 5;
				TileMultiCrafter tile = (TileMultiCrafter) part;
	/*	just colect the block instead of assinging ids now
	 *	blocks without id get numerated by id 2745 and up
	 *	because max size of a crafter is 16*16*16, internals are 14*14*14
	 *	so the max id any storage can have is 2744
	 *	this makes new added storages get appended last
	 *	if you want new storages added before existing ones, set 'append' to '-2745' instead
	 */
//				tile.page = Optional.of(pages);
//				invs.put(pages, tile.inv);
				if(tile.page.isPresent()){
					collector.put(tile.page.get(), tile);
				} else {
					collector.put(append++, tile);
				}
			}
			if(part.getBlockState().getValue(BlockMultiCrafter.VARIANTS).equals("cpu")){
				powerUsage += 10;
				speed++;
			}
		}
	/*	now every storage is known and placed in an ordered map we just
	 *	need to iterate over it and assing new ids in that order, starting by 1
	 *	map.values() should preserve the order
	 */
		int newid = 0;
		for(TileMultiCrafter tile : collector.values()) {
			newid++;
			tile.page = Optional.of(newid);
			invs.put(newid, tile.inv);
		}
		
	}
commented

Yeah that's looks like it should work, I will apply that in a bit when I'm back at my pc

commented

Let me know if it works :)
didn't code since bukkit went down in 2014 ... I forgot how much fun it is xD
I should start something own again, but I probably don't have enough time to maintain it properly :/

commented

Seems to work great. Will get it on curse soon.