Non résolu bug donnée container et tile entity pas synchronisé
-
Bonjour,
Je développe actuellement un mods minecraft en 1.16.5 et je fais face à un problème. En gros, j’ai une tileEntity qui implémente un IFluidHandler avec une variable d’instance FluidTank ou l’ensemble des méthodes de mon interface agissent (drain(…), fill(…), getCapacity()…). Pour fonctionner mon TileEntity est accompagné de 3 autres classe : une classe Container, une classe screen et une classe block, lorsque je rempli un tank avec fill et que j’affiche le contenu depuis la classe tileEntity ça marche le fluid et la quantité dans le tanks sont bien détecté, pareil avec la classe Block , le fluid et le contenu sont bien détectés. Mais lorsque j’affiche le contenu du tank depuis la classe screen et la classe container le tank n’est pas reconnu, c’est à dire que lorsque j’affiche le contenu de mon tank, le fluid n’est pas reconnu et la quantité est à zero, ce qui est problématique dans le cas ou je veux faire une FluidBar sur mon GUI.pouvez-vous m’aider ?
Voici les différents code:
Block :
package net.A1exPrdgc.biotechmod.block.custom; import net.A1exPrdgc.biotechmod.container.SqueezerContainer; import net.A1exPrdgc.biotechmod.tileentity.ModTileEntities; import net.A1exPrdgc.biotechmod.tileentity.SqueezerTile; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.DirectionalBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.BlockItemUseContext; import net.minecraft.state.StateContainer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkHooks; import javax.annotation.Nullable; public class Squeezer extends DirectionalBlock { private SqueezerTile tileEntity; public Squeezer(Properties properties) { super(properties); this.setDefaultState(this.stateContainer.getBaseState().with(FACING, Direction.NORTH)); } @Override protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder){ builder.add(FACING); } @Nullable @Override public BlockState getStateForPlacement(BlockItemUseContext context){ return this.getDefaultState().with(FACING, context.getPlacementHorizontalFacing()); } @Override public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { //vérifie que le serveur répond if(!worldIn.isRemote()) { this.tileEntity = (SqueezerTile)worldIn.getTileEntity(pos); //vérifie que le joueur n'est pas en sneak if(!player.isCrouching()) { //agit si le joueur est en sneak if(tileEntity instanceof SqueezerTile) { INamedContainerProvider containerProvider = createContainerProvider(worldIn, pos); NetworkHooks.openGui(((ServerPlayerEntity) player), containerProvider, tileEntity.getPos()); ((SqueezerTile)tileEntity).liquid_root_creation(); System.out.println("azerty : " + ((SqueezerTile)tileEntity).getFluidInTank(1).getAmount()); } else { throw new IllegalStateException("container called is missing"); } } } return ActionResultType.SUCCESS; } private INamedContainerProvider createContainerProvider(World worldIn, BlockPos pos) { return new INamedContainerProvider() { @Override public ITextComponent getDisplayName() { return new TranslationTextComponent("Squeezer"); } @Nullable @Override public Container createMenu(int i, PlayerInventory playerInventory, PlayerEntity playerEntity) { return new SqueezerContainer(i, playerInventory, playerEntity, tileEntity); } }; } @Nullable @Override public TileEntity createTileEntity(BlockState state, IBlockReader world){ return ModTileEntities.SQUEEZER.get().create(); } @Override public boolean hasTileEntity(BlockState state){ return true; } }
TileEntity :
package net.A1exPrdgc.biotechmod.tileentity; import net.A1exPrdgc.biotechmod.fluid.ModFluids; import net.A1exPrdgc.biotechmod.item.ModItems; import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.templates.FluidTank; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; import javax.annotation.Nonnull; public class SqueezerTile extends TileEntity implements IFluidHandler { //-----------Obligatoire------------ private final ItemStackHandler itemHandler = createHandler(); private final LazyOptional<IItemHandler> handler = LazyOptional.of(() -> itemHandler); public final FluidTank tank = new FluidTank(200_000);; private int cookingTime; private int totalCookingTime; private static final String NBTFLUID= "liq"; private static final String NBTINV = "inv"; public SqueezerTile(TileEntityType<?> tileEntityTypeIn){ super(tileEntityTypeIn); } public SqueezerTile() { this(ModTileEntities.SQUEEZER.get()); } @Override public void read(BlockState state, CompoundNBT nbt) { itemHandler.deserializeNBT(nbt.getCompound(NBTINV)); tank.readFromNBT(nbt.getCompound(NBTFLUID)); super.read(state, nbt); } public FluidTank getTank(){ return tank; } @Override public CompoundNBT write(CompoundNBT compound){ compound.put(NBTINV, itemHandler.serializeNBT()); CompoundNBT fluid = new CompoundNBT(); tank.writeToNBT(fluid); compound.put(NBTFLUID, fluid); return super.write(compound); } private ItemStackHandler createHandler() { return new ItemStackHandler(7) { @Override protected void onContentsChanged(int slot){ markDirty(); } @Override public boolean isItemValid(int slot, @Nonnull ItemStack stack){ switch(slot) { case 2 : return stack.getItem() == Items.BUCKET; case 1 : return stack.getItem() == ModItems.ROOT.get(); default : return false; } } @Override public int getSlotLimit(int slot){ return 1; } @Nonnull @Override public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate){ if(!isItemValid(slot, stack)) { return stack; } return super.insertItem(slot, stack, simulate); } }; } @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap){ if(cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return handler.cast(); } return super.getCapability(cap); } @Override public int getTanks(){ return 1; } @Nonnull @Override public FluidStack getFluidInTank(int tank){ return this.tank.getFluidInTank(tank); } @Override public int getTankCapacity(int tank){ return this.tank.getTankCapacity(tank); } @Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack){ if(this.tank.getFluidInTank(tank) == stack) return true; return false; } @Override public int fill(FluidStack resource, FluidAction action){ return this.tank.fill(resource, action); } @Nonnull @Override public FluidStack drain(FluidStack resource, FluidAction action){ return this.tank.drain(resource, action); } @Nonnull @Override public FluidStack drain(int maxDrain, FluidAction action){ return this.tank.drain(maxDrain, action); } public void liquid_root_creation() { boolean hasRoot = this.itemHandler.getStackInSlot(1).getCount() > 0 && this.itemHandler.getStackInSlot(1).getItem() == ModItems.ROOT.get(); if(hasRoot) { //retire l'item this.itemHandler.getStackInSlot(1).shrink(1); //retire l'énergie /////////////////////////////////////////////////////////////////////////////////////////////////////// //ajoute le liquide this.tank.fill(new FluidStack(ModFluids.ROOT_FLUID.get(), 250), FluidAction.EXECUTE); System.out.println(this.getFluidInTank(1).getAmount()); } } @Override public String toString(){ return "tanks : " + this.getTanks() + "\n" + "quant : " + this.getFluidInTank(1).getAmount() + "\n" + "fluid : " + this.getFluidInTank(1).getFluid().getFluid() + "\n"; } //--------------------------------- }
Container :
package net.A1exPrdgc.biotechmod.container; import net.A1exPrdgc.biotechmod.block.ModBlocks; import net.A1exPrdgc.biotechmod.tileentity.SqueezerTile; import net.minecraft.command.arguments.SlotArgument; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.Slot; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IWorldPosCallable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; import net.minecraftforge.items.wrapper.InvWrapper; import javax.annotation.Nullable; public class SqueezerContainer extends Container { public final SqueezerTile tileEntity; private final PlayerEntity playerEntity; private final IItemHandler playerInventory; public SqueezerContainer(int windowId, PlayerInventory playerInventory, PlayerEntity player, SqueezerTile tile) { super(ModContainers.SQUEEZER_CONTAINER.get(), windowId); this.tileEntity = tile; this.playerEntity = player; this.playerInventory = new InvWrapper(playerInventory); layoutPlayerInventorySlots(8, 86); if(this.tileEntity != null) { tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(ih -> { addSlot(new SlotItemHandler(ih, 0, 80, 53)); addSlot(new SlotItemHandler(ih, 1, 39, 31)); addSlot(new SlotItemHandler(ih, 2, 123, 65)); addSlot(new SlotItemHandler(ih, 3, 152, 6)); addSlot(new SlotItemHandler(ih, 4, 152, 26)); addSlot(new SlotItemHandler(ih, 5, 152, 46)); addSlot(new SlotItemHandler(ih, 6, 152, 66)); }); } } @Override public boolean canInteractWith(PlayerEntity playerIn){ return isWithinUsableDistance(IWorldPosCallable.of( tileEntity.getWorld(), tileEntity.getPos()), playerIn, ModBlocks.SQUEEZER.get()); } //--------------------Gestion de l'inventaire---------------------- private int addSlotRange(IItemHandler handler, int index, int x, int y, int amount, int dx) { for (int i = 0; i < amount; i++) { addSlot(new SlotItemHandler(handler, index, x, y)); x += dx; index++; } return index; } private int addSlotBox(IItemHandler handler, int index, int x, int y, int horAmount, int dx, int verAmount, int dy) { for (int j = 0; j < verAmount; j++) { index = addSlotRange(handler, index, x, y, horAmount, dx); y += dy; } return index; } private void layoutPlayerInventorySlots(int leftCol, int topRow) { addSlotBox(playerInventory, 9, leftCol, topRow, 9, 18, 3, 18); topRow += 58; addSlotRange(playerInventory, 0, leftCol, topRow, 9, 18); } @Override public String toString(){ return "qa : " + this.tileEntity.getFluidInTank(1).getAmount() + "\n" + "fl : " + this.tileEntity.getFluidInTank(1).getFluid() + "\n"; } //---------------------------------------------------- // CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons // must assign a slot number to each of the slots used by the GUI. // For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar. // Each time we add a Slot to the container, it automatically increases the slotIndex, which means // 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8) // 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35) // 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8) private static final int HOTBAR_SLOT_COUNT = 9; private static final int PLAYER_INVENTORY_ROW_COUNT = 3; private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9; private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT; private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT; private static final int VANILLA_FIRST_SLOT_INDEX = 0; private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT; // THIS YOU HAVE TO DEFINE! private static final int TE_INVENTORY_SLOT_COUNT = 7; // must match TileEntityInventoryBasic.NUMBER_OF_SLOTS @Override public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { Slot sourceSlot = inventorySlots.get(index); if (sourceSlot == null || !sourceSlot.getHasStack()) return ItemStack.EMPTY; //EMPTY_ITEM ItemStack sourceStack = sourceSlot.getStack(); ItemStack copyOfSourceStack = sourceStack.copy(); // Check if the slot clicked is one of the vanilla container slots if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) { // This is a vanilla container slot so merge the stack into the tile inventory if (!mergeItemStack(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT, false)) { return ItemStack.EMPTY; // EMPTY_ITEM } } else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) { // This is a TE slot so merge the stack into the players inventory if (!mergeItemStack(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) { return ItemStack.EMPTY; } } else { System.out.println("Invalid slotIndex:" + index); return ItemStack.EMPTY; } // If stack size == 0 (the entire stack was moved) set slot contents to null if (sourceStack.getCount() == 0) { sourceSlot.putStack(ItemStack.EMPTY); } else { sourceSlot.onSlotChanged(); } sourceSlot.onTake(playerEntity, sourceStack); return copyOfSourceStack; } }
Screen :
package net.A1exPrdgc.biotechmod.screen; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import net.A1exPrdgc.biotechmod.BiotechMod; import net.A1exPrdgc.biotechmod.container.SqueezerContainer; import net.A1exPrdgc.biotechmod.tileentity.SqueezerTile; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluids; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.templates.FluidTank; import java.awt.*; public class SqueezerScreen extends ContainerScreen<SqueezerContainer> { private final ResourceLocation GUI = new ResourceLocation(BiotechMod.MOD_ID, "textures/gui/squeezer_gui.png"); protected Rectangle fluidbar = new Rectangle(122, 14, 18, 47); public SqueezerScreen(SqueezerContainer screenContainer, PlayerInventory inv, ITextComponent titleIn){ super(screenContainer, inv, titleIn); } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks){ this.renderBackground(matrixStack); super.render(matrixStack, mouseX, mouseY, partialTicks); this.renderHoveredTooltip(matrixStack, mouseX, mouseY); } @Override protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) { this.minecraft.getTextureManager().bindTexture(GUI); int i = this.guiLeft; int j = this.guiTop; final SqueezerTile squeezertile = container.tileEntity; System.out.println(container); if(squeezertile.getTank().getFluidInTank(1).getAmount() > 0) { System.out.println("phase 1"); Fluid fluid = squeezertile.tank.getFluid().getFluid(); TextureAtlasSprite fluidTexture1 = (TextureAtlasSprite)(minecraft.getAtlasSpriteGetter(fluid.getRegistryName())); this.minecraft.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); float fluidPercentage = (float) squeezertile.tank.getFluidAmount() / (float) squeezertile.tank.getCapacity(); int fluidHeight = (int) Math.ceil(fluidPercentage * (float) fluidbar.height); this.blit(matrixStack, fluidbar.x + i, fluidbar.y + j + (fluidbar.height - fluidbar.width),0, fluidbar.width, fluidHeight, fluidTexture1); System.out.println("blited"); } RenderSystem.color4f(1f, 1f, 1f, 1f); this.blit(matrixStack, i, j, 0, 0, this.xSize, this.ySize); //condition pour le lancement de la fabrication (animation flèche) } private int getFluidInTank(SqueezerTile squeezertile) { /* * First getFluid() -> returns the fluidStack * Second getFluid() -> returns the fluid */ if(squeezertile.getTank().getFluid().isEmpty()) return 0; return squeezertile.getTank().getFluidAmount()/squeezertile.getTank().getCapacity() * 74; } }
ModContainer :
package net.A1exPrdgc.biotechmod.container; import net.A1exPrdgc.biotechmod.BiotechMod; import net.A1exPrdgc.biotechmod.tileentity.SqueezerTile; import net.minecraft.inventory.container.ContainerType; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.extensions.IForgeContainerType; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class ModContainers { public static DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, BiotechMod.MOD_ID); public static final RegistryObject<ContainerType<SqueezerContainer>> SQUEEZER_CONTAINER = CONTAINERS.register("squeezer_container", () -> IForgeContainerType.create(((windowId, inv, data) -> { BlockPos pos = data.readBlockPos(); SqueezerTile tile = ((SqueezerTile)inv.player.world.getTileEntity(pos)); return new SqueezerContainer(windowId, inv, inv.player, tile); }))); public static void register(IEventBus eventbus) { CONTAINERS.register(eventbus); } }