Posted August 14, 20169 yr Problem 1 is solved: In short, i needed to send Server information to the client while i had an Container open - A quick look into ContainerFurnace showed the solution, using detectAndSendChanges() I have a tileentity that uses fuel to plant plants. how much fuel it has in it is displayed in a gui, that is obviously a client thing. update() gets called on both client and server, but since it only uses fuel and plants if there is space, sometimes the client uses fuel(I would conclude when it is called first) and the server too and sometimes only the server uses fuel. this then makes the gui display the wrong, client-side information. After implementing this, a new problem occured. Go 2 posts down to look at it. Ok I now solved the issue by simply introducing a new value for the gui and only changing it if the values from the tileentity for lastfuel and fuel are different: int lastfuel; @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { if(te.getField(1)!=te.getField(0)) lastfuel=te.getField(1); ... } still wondering how the problem occured tho
August 14, 20169 yr make a container for the gui and then look at the furnace container how the furnace syncs the burn time and the current progress catch(Exception e) { } Yay, Pokémon exception handling, gotta catch 'em all (and then do nothing with 'em).
August 14, 20169 yr Author Ok well now I implemented this into my container: private int fuel; private int lastfuelvalue; public void detectAndSendChanges(){ super.detectAndSendChanges(); for (int i = 0; i<this.listeners.size(); ++i) { IContainerListener listener = (IContainerListener)this.listeners.get(i); if (this.fuel!=this.te.getField(0)){ listener.sendProgressBarUpdate(this, 0, this.te.getField(0)); } if (this.lastfuelvalue!=this.te.getField(1)){ listener.sendProgressBarUpdate(this, 1, this.te.getField(1)); } } this.fuel=this.te.getField(0); this.lastfuelvalue=this.te.getField(1); } @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data){ this.te.setField(id, data); } the really weird thing is, when the variable in field 0(fuel) changes and the gui is open, it kinda sets lastfuelvalue to fuel(what I dont want), but when i reopen the gui the packet is send again and it gets displayed correct. maybe i didnt explain it good but I just dont understand what mc is doing here... lemme show pictures: normal gui(fuel value in top left only for debug) after it used fuel while keeping the gui open after reopening the gui just want to remind: this ONLY happened after i added all this listening stuff!
August 14, 20169 yr What is in your get/set Field method ? catch(Exception e) { } Yay, Pokémon exception handling, gotta catch 'em all (and then do nothing with 'em).
August 14, 20169 yr You also need to add public void addListener(IContainerListener listener) { super.addListeners(listener); listener.sendAllWindowProperties(this, tileEntity); } to your containers class. 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.
August 15, 20169 yr Author get/setfield: @Override public int getField(int id) { switch (id){ case 0: return this.fuel; case 1: return this.lastfuel; } return 0; } @Override public void setField(int id, int value) { switch (id){ case 0: fuel=value; case 1: lastfuel=value; } } @Animefan I already had it but it changed nothing. Do you even know what i does?
August 15, 20169 yr get/setfield: @Animefan I already had it but it changed nothing. Do you even know what i does? I believe it sends all of the properties aka the fields from server to client. Did you return 2 on getFieldCount? 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.
August 15, 20169 yr Author it is actually this but i thought it is unnecessary: @Override public int getField(int id) { switch (id){ case 0: return this.fuel; case 1: return this.lastfuel; case 2: return this.yoffset; case 3: return this.actualslots; } return 0; } @Override public void setField(int id, int value) { switch (id){ case 0: fuel=value; case 1: lastfuel=value; case 2: yoffset=value; } } @Override public int getFieldCount() { return 4; }
August 15, 20169 yr Always post all of the code even if you think it unnecessary. Was that all of the code in your container? 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.
August 15, 20169 yr Author apart from the constructor, yes if you want it: private IInventory te; public FarmerContainer(IInventory playerInv, IInventory te) { this.te = te; //Farmer-Inventar this.addSlotToContainer(new CustomSlot(te, 0, 26, 45)); int xslots=te.getField(te.getFieldCount()-1); for (int y = 0; y < 2; ++y) { for (int x = 0; x < xslots; ++x) { this.addSlotToContainer(new CustomSlot(te, x + y * xslots + 1, 62 + x * 18, 45 - y * 21)); } } //Player-Inventar for (int y = 0; y < 3; ++y) { for (int x = 0; x < 9; ++x) { this.addSlotToContainer(new Slot(playerInv, x + y * 9 + 9, 8 + x * 18, 84 + y * 18)); } } for (int x = 0; x < 9; ++x) { this.addSlotToContainer(new Slot(playerInv, x, 8 + x * 18, 142)); } } nothing fancy
August 15, 20169 yr Author Maybe I could force the container from my tileentity to send an update shortly after I change the fuel value?
August 15, 20169 yr Well you definitely could, but using the in place system is easier. And I assume it would be more internet intensive. Give me a minute to look at the code... 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.
August 15, 20169 yr Could you post your entire TileEntity class it might not be functioning as intended. 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.
August 15, 20169 yr Author Here you go: public class FarmerTE extends TEInventory implements ITickable,ISidedInventory { int fuel; int lastfuel; int yoffset; private static int rowslots=5; public FarmerTE() { super("farmer",rowslots*2+1,new String[]{"fuel","lastfuel","yoffset"}); fuel=0; lastfuel=1; yoffset=-1; } private int delay=2; @Override public void update(){ if(worldObj.isRemote) return; if(delay>0){ delay--; return; } delay=5; BlockPos position=nextpos(); Block b=util.blockat(worldObj,position); if(b!=null){ // entferne hohes Gras if(util.blockat(worldObj, position.up()).equals(Blocks.TALLGRASS)) worldObj.setBlockState(position.up(),Blocks.AIR.getDefaultState()); // erde zu farmland if((b.equals(Blocks.DIRT)||b.equals(Blocks.GRASS))&&util.blockat(worldObj, position.up()).equals(Blocks.AIR)&&useFuel()){ worldObj.playSound(null, position, SoundEvents.ITEM_HOE_TILL, SoundCategory.BLOCKS, 1.0F, 1.0F); if(!worldObj.isRemote) worldObj.setBlockState(position, Blocks.FARMLAND.getDefaultState(), 11); } // pflanzen/ernten Block s=util.blockat(worldObj,position.up()); if(s.equals(Blocks.AIR)){ plant(position); } else if(s instanceof BlockCrops){ if(((BlockCrops)s).isMaxAge(worldObj.getBlockState(position.up()))&&useFuel()) harvest(position,s); } else if(s instanceof BlockNetherWart){ if(worldObj.getBlockState(position.up()).getValue(BlockNetherWart.AGE).intValue()>=3&&useFuel()) harvest(position,s); } } } private void plant(BlockPos position){ for(int slot=1;slot<rowslots+1;slot++){ ItemStack stack=this.getStackInSlot(slot); if(stack!=null&&isplantable(stack)){ IPlantable item=(IPlantable)stack.getItem(); if(util.blockat(worldObj,position).canSustainPlant(worldObj.getBlockState(position),worldObj,position,EnumFacing.UP,item)&&useFuel()){ worldObj.setBlockState(position.up(),item.getPlant(null, null)); decrStackSize(slot,1); return; } } } } private void harvest(BlockPos position,Block plant){ java.util.List<ItemStack> items=plant.getDrops(worldObj, position.up(), worldObj.getBlockState(position.up()), 0); for(ItemStack stack : items){ int start=rowslots+1; if(isplantable(stack)) start=1; for(int slot=start;slot<getSizeInventory();slot++){ ItemStack content=getStackInSlot(slot); if(content==null){ setInventorySlotContents(slot,stack); break; } else if(content.getItem().equals(stack.getItem())){ if(content.stackSize+stack.stackSize<=64){ content.stackSize+=stack.stackSize; setInventorySlotContents(slot,content); break; } else { stack.stackSize-=64-content.stackSize; content.stackSize=64; setInventorySlotContents(slot,content); } } } } worldObj.setBlockToAir(position.up()); plant(position); } private boolean isplantable(ItemStack stack){ return stack.getItem() instanceof IPlantable; } private boolean useFuel(){ int fuelPerOperation=50; if(fuel<fuelPerOperation){ if(getStackInSlot(0)!=null&&TileEntityFurnace.isItemFuel(getStackInSlot(0))){ lastfuel=TileEntityFurnace.getItemBurnTime(getStackInSlot(0)); fuel+=lastfuel; decrStackSize(0,1); } } if(fuel>=fuelPerOperation){ fuel-=fuelPerOperation; return true; } return false; } private int[][] get=new int[][]{{-1,-1,-1,0,1,1,1,0},{-1,0,1,1,1,0,-1,-1}}; private int currentblock=0; private BlockPos nextpos(){ if(currentblock==7) currentblock=0; else currentblock++; return pos.add(get[0][currentblock],0-yoffset,get[1][currentblock]); } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { if(index==0&&TileEntityFurnace.isItemFuel(stack)) return true; if(index>0&&index<rowslots+1&&isplantable(stack)) return true; return false; } @Override public boolean canInsertItem(int index, ItemStack stack, EnumFacing direction) { return isItemValidForSlot(index, stack); } @Override public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) { if(index>rowslots) return true; return false; } @Override public int[] getSlotsForFace(EnumFacing side) { return new int[]{0,1,2,3,4,5,6,7,8,9,10}; } @Override public int getField(int id) { switch (id){ case 0: return this.fuel; case 1: return this.lastfuel; case 2: return this.yoffset; case 3: return this.rowslots; } throw new RuntimeException("field "+id+" not found"); } @Override public void setField(int id, int value) { switch (id){ case 0: fuel=value; case 1: lastfuel=value; case 2: yoffset=value; } } @Override public int getFieldCount() { return 4; } }
August 15, 20169 yr I'm not sure if I understand the current problem, but is it that the current fuel can be greater than lastFuel? If so the problem is lastfuel=TileEntityFurnace.getItemBurnTime(getStackInSlot(0)); fuel+=lastfuel; If not please explain it to me. 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.
August 15, 20169 yr Author it can be, and that is intended, but it isnt and it cant be the problem since update() only performs on server side since I check for worldObj.isRemote
August 15, 20169 yr and it cant be the problem since update() only performs on server side since I check for worldObj.isRemote Well if it only updates server side then we send the data to the client...The client has the same data. Well could you explain the problem. 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.
August 15, 20169 yr Author you know what I am asking myself at the moment? Look at the screenshots and then what you said and see the nonsense
August 15, 20169 yr Are you sure it is fuel/last fuel and not the other way around? 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.
August 15, 20169 yr Author yes i am just for completeness my gui class: public class FarmerGui extends BaseGui { public FarmerGui(IInventory playerInv, TEInventory te) { super(new FarmerContainer(playerInv, te), playerInv, te); } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { drawBackgroundImage("farmer"); // fuel blueprint if(te.getStackInSlot(0)==null) this.drawRect(26, 45, 176, 0, 16, 16); // seeds blueprint for(int i=1;i-1<te.getField(te.getFieldCount()-1);i++) if(te.getStackInSlot(i)==null) this.drawRect(44+18*i, 45, 176, 16, 16, 16); // progress bar int progress=te.getField(0)>0?12-(te.getField(0)*12/te.getField(1)):14; this.drawRect(26, 28+progress, 176, 32+progress, 14, 14-progress); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { super.drawGuiContainerForegroundLayer(mouseX, mouseY); // temporary debug output drawString("Fuel: "+te.getField(0)+"/"+te.getField(1), 2, 2); } }
August 16, 20169 yr Author Read the whole post please. I already did this and a new problem popped up
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.