Posted May 9, 20205 yr Alright, I am currently working on the fluid tanks that display how much fluid is the tile. The problem is I don't know how to display the fluid and render. Here are some Codes Tile Entity Code: Spoiler package com.mreyeballs29.itnc.tileentity; import com.mreyeballs29.itnc.inventory.TankContainer; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.fluid.Fluid; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.templates.FluidTank; import net.minecraftforge.registries.ForgeRegistries; public class TankTileEntity extends TileEntity implements INamedContainerProvider { private final FluidTank tank = new FluidTank(8000); private LazyOptional<FluidTank> optional = LazyOptional.of(() -> tank); public TankTileEntity() { super(INCTileEntityTypes.TANK); } public FluidTank getTank() { return tank; } private void deseralize(CompoundNBT nbt, FluidTank fluidtank) { Fluid fluid = null; int amount = 0; if (nbt.contains("fluid")) { String string = nbt.getString("fluid"); fluid = ForgeRegistries.FLUIDS.getValue(new ResourceLocation(string)); } if (nbt.contains("amount")) { amount = nbt.getInt("amount"); } if (fluid != null && amount > 0) { fluidtank.setFluid(new FluidStack(fluid, amount)); } else { fluidtank.setFluid(FluidStack.EMPTY); } } private CompoundNBT seralize(FluidTank fluidtank) { CompoundNBT nbt = new CompoundNBT(); FluidStack fluidstack = fluidtank.getFluid(); nbt.putString("fluid", fluidstack.getFluid().getRegistryName().toString()); nbt.putInt("amount", fluidstack.getAmount()); return nbt; } @Override public void read(CompoundNBT compound) { CompoundNBT nbtfluid = compound.getCompound("tank"); optional.ifPresent(h -> {deseralize(nbtfluid, h);}); super.read(compound); } @Override public CompoundNBT write(CompoundNBT compound) { optional.ifPresent(h -> {CompoundNBT nbt = seralize(h); compound.put("tank", nbt);}); return super.write(compound); } @Override public <T> LazyOptional<T> getCapability(Capability<T> cap) { return cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY ? optional.cast() : super.getCapability(cap); } @Override public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { return new TankContainer(p_createMenu_1_, world, pos, p_createMenu_2_, p_createMenu_3_); } @Override public ITextComponent getDisplayName() { return new TranslationTextComponent("container.tank"); } } Screen Code: Spoiler package com.mreyeballs29.itnc.client.gui.screen.inventory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.mojang.blaze3d.platform.GlStateManager; import com.mreyeballs29.itnc.inventory.TankContainer; import com.mreyeballs29.itnc.tileentity.TankTileEntity; import net.minecraft.block.Block; import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.PlayerContainer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraftforge.fluids.capability.templates.FluidTank; public class TankScreen extends ContainerScreen<TankContainer> { private static final ResourceLocation GUI = new ResourceLocation("itnc", "textures/gui/container/basic_tank.png"); public TankScreen(TankContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) { super(screenContainer, inv, titleIn); } @Override public void render(int mouseX, int mouseY, float partialTicks) { this.renderBackground(); super.render(mouseX, mouseY, partialTicks); this.renderHoveredToolTip(mouseX, mouseY); } private void addScreen() { Logger log = LogManager.getLogger(); log.info(this.container); log.info(this.container.getTileEntity().getTank().getFluid()); @SuppressWarnings("resource") TextureAtlasSprite sprite = getSprite(this.container.getTileEntity().getTank().getFluid().getFluid().getRegistryName()); blit(56, 56, 2, 2, 200, sprite); } @SuppressWarnings("deprecation") public TextureAtlasSprite getSprite(ResourceLocation resourceLocation) { return this.minecraft.getAtlasSpriteGetter(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(resourceLocation); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { this.font.drawString(this.title.getFormattedText(), 8.0F, 7.0F, 4210752); this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 5), 4210752); addScreen(); } @SuppressWarnings({ "deprecation", "resource" }) @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); this.minecraft.getTextureManager().bindTexture(GUI); int relX = (this.width - this.xSize) / 2; int relY = (this.height - this.ySize+3) / 2; this.blit(relX, relY, 0, 0, this.xSize, this.ySize+3); } } Container Code: Spoiler package com.mreyeballs29.itnc.inventory; import com.mreyeballs29.itnc.tileentity.TankTileEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Container; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; import net.minecraftforge.items.wrapper.InvWrapper; public class TankContainer extends Container { private TileEntity tileEntity; private PlayerEntity playerEntity; private InvWrapper playerInventory; public TankContainer(int id, World world, BlockPos pos, PlayerInventory inv, PlayerEntity playerEntity2) { super(INContainerTypes.TANK, id); tileEntity = world.getTileEntity(pos); playerEntity = playerEntity2; playerInventory = new InvWrapper(inv); layoutPlayerInventorySlots(8, 87); } public TankTileEntity getTileEntity() { return (TankTileEntity) tileEntity; } 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 boolean canInteractWith(PlayerEntity playerIn) { return !(playerEntity.getDistanceSq((double)tileEntity.getPos().getX() + 0.5D, (double)this.tileEntity.getPos().getY() + 0.5D, (double)this.tileEntity.getPos().getZ() + 0.5D) > 64.0D); } }
May 9, 20205 yr If you're talking about within the GUI, you just create another rectangle with the overlay texture that changes based on how much fluid is in the tank.
May 10, 20205 yr Author Yeah, but that texture needs to bind into the GUI which is the problem. I tried to use Minecraft#getAltasSprtiteGettter but I get a mess of textures.
May 10, 20205 yr Author 31 minutes ago, diesieben07 said: All block textures exist on one texture sheet. You can bind it using PlayerContainer.LOCATION_BLOCKS_TEXTURE. The TextureAtlasSprite then tells you the u v coordinates in that atlas texture. I tried using the method blit(int a, int b, int c, int d, int e, TextureAltasSprite f)but that did not work.
May 10, 20205 yr Author I used water as an example. The parameters were 16, 16, one, 16, 16, and water. Did I forget something? private void addScreen() { @SuppressWarnings("resource") TextureAtlasSprite sprite = getSprite(new ResourceLocation("minecraft", "water")); // This is the one I used blit(16, 16, 1, 16, 16, sprite); } public TextureAtlasSprite getSprite(ResourceLocation resourceLocation) { return this.minecraft.getAtlasSpriteGetter(PlayerContainer.LOCATION_BLOCKS_TEXTURE).apply(resourceLocation); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { this.font.drawString(this.title.getFormattedText(), 8.0F, 7.0F, 4210752); this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 5), 4210752); addScreen(); }
May 10, 20205 yr Author 2 minutes ago, diesieben07 said: What on earth are you doing... Nothing about what you are doing there makes any sense. I know it makes nonsense but I am trying to get the fluid texture into the tank screen. I used water as an example.
May 10, 20205 yr Author 30 minutes ago, Issac29 said: I know it makes nonsense but I am trying to get the fluid texture into the tank screen. I used water as an example. Anyway Here is the better code. @SuppressWarnings("resource") private void addScreen(int x, int y) { TextureAtlasSprite sprite = getSprite(new ResourceLocation("minecraft:water")); sprite.getAtlasTexture().bindTexture(); blit(100, 50, 0, 32, 32, sprite); } public TextureAtlasSprite getSprite(ResourceLocation resourceLocation) { return this.minecraft.getAtlasSpriteGetter(PlayerContainer.LOCATION_BLOCKS_TEXTURE).apply(resourceLocation); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { this.font.drawString(this.title.getFormattedText(), 8.0F, 7.0F, 4210752); this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 5), 4210752); addScreen(mouseX, mouseY); } Edit: For odd reason there still a invalid or missing texture. Edited May 10, 20205 yr by Issac29
May 10, 20205 yr Author 20 minutes ago, diesieben07 said: Why on earth is the method called "addScreen". That makes zero sense. Do not use getAtlasSpriteGetter. You need to get the model from the block and then get the textures from the model. There can be multiple or there could even potentially be none at all. OK I renamed the method "addScreen" to "drawFluidTexture". Which makes more sense. @SuppressWarnings("resource") private void drawFluidTexture(int x, int y) { TextureAtlasSprite texture = this.minecraft.getModelManager().getModel(new ResourceLocation("minecraft:water")).getParticleTexture(EmptyModelData.INSTANCE); texture.getAtlasTexture().bindTexture(); blit(84, 12, 0, 32, 32, texture); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { this.font.drawString(this.title.getFormattedText(), 8.0F, 7.0F, 4210752); this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 5), 4210752); drawFluidTexture(mouseX, mouseY); } But still has a missing texture. Maybe I needed to soft code it into something better.
May 10, 20205 yr Author 7 minutes ago, diesieben07 said: Have you verified that its actually returning a proper model and texture? The texture for weird reason returns "minecraft:missingno". This does not make any sense. As for the model it seems to have a number SimpleBakedModel@411933.
May 11, 20205 yr Author I figured out that to get the sprite texture, you needed the Fluid#getAttributes#getStillTexture to obtain that texture. No need for getting the model or the blockstate for just a simple four step code. AtlasTexture texture = minecraft.getModelManager().getAtlasTexture(PlayerContainer.LOCATION_BLOCKS_TEXTURE); TextureAtlasSprite sprite = texture.getSprite(Fluids.WATER.getAttributes().getStillTexture()); texture.bindTexture(); blit(70, 20, 0, 32, 32, sprite);
May 15, 20205 yr Author Alright most of the tank is synced but the only problem is the when I type this command /setblock x y z namespace:tankName{tankData: {FluidName: #fluidName, Amount: #amount}}, the server loads the data but the client does not load until reloading the world or chunk. That same applies to /data modify block x y z tankData set value {FluidName: #fluidName, Amount: #Amount}. I used every method to sync the client but some odd reason they don't sync when changing the tank value with commands. Before Reloading Chunks: After Reloading Chunks:
May 15, 20205 yr Author Just now, diesieben07 said: Show your code. 44 minutes ago, Issac29 said: Alright most of the tank is synced but the only problem is the when I type this command /setblock x y z namespace:tankName{tankData: {FluidName: #fluidName, Amount: #amount}}, the server loads the data but the client does not load until reloading the world or chunk. That same applies to /data modify block x y z tankData set value {FluidName: #fluidName, Amount: #Amount}. I used every method to sync the client but some odd reason they don't sync when changing the tank value with commands. Before Reloading Chunks: After Reloading Chunks: What the Images don't give enough information. Fine here is the code. public class TankTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity { ManualTank tank = new ManualTank(8000, this); private LazyOptional<FluidTank> optional = LazyOptional.of(() -> this.tank); public TankTileEntity() { super(INCTileEntityTypes.TANK); } @Override public void read(CompoundNBT compound) { super.read(compound); CompoundNBT nbtfluid = compound.getCompound("tank"); //$NON-NLS-1$ this.tank.readFromNBT(nbtfluid); } @Override public CompoundNBT write(CompoundNBT compound) { compound.put("tank", this.tank.writeToNBT(new CompoundNBT())); //$NON-NLS-1$ return super.write(compound); } @Override public CompoundNBT getUpdateTag() { CompoundNBT nbt = super.getUpdateTag(); return this.write(nbt); } @Override public boolean receiveClientEvent(int id, int type) { return true; } @Override public void handleUpdateTag(CompoundNBT tag) { read(tag); } @Override public <T> LazyOptional<T> getCapability(Capability<T> cap) { return cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY ? this.optional.cast() : super.getCapability(cap); } @Override public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) { return new TankContainer(p_createMenu_1_, this.world, this.pos, p_createMenu_2_); } @Override public ITextComponent getDisplayName() { return new TranslationTextComponent("container.tank"); //$NON-NLS-1$ } public FluidTank getTank() { return this.tank; } @Override public void tick() { return; } }
May 15, 20205 yr Author 5 minutes ago, diesieben07 said: unnecessarily puts load on the network. I guess that can cause server lag. 7 minutes ago, diesieben07 said: You should instead only sync when the Container is open, vanilla has some examples of this. How am I able to do that. Also I could not find anything that relates to that.
May 15, 20205 yr Author 19 minutes ago, diesieben07 said: Override detectAndSendChanges in your container class. I see no other container classes overriding detectAndSendChanges. Also why a custom packet.
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.