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);
}
}