Inventory glitches when scrolling through pages
Wingnut601 opened this issue ยท 14 comments
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.
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 :)
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 ...
@modmuss50 have you looked at this
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.
@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?
@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);
}
}
Yeah that's looks like it should work, I will apply that in a bit when I'm back at my pc
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 :/