Jump to content

Recommended Posts

Posted

Okay, so I would like to add a liquid tank to an inventory, and after doing some research, I have discovered the IFluidTank, IFluidHandler, and IFluidContainerItem. Now, I have no idea how to use them, I only know that they are used in inventory tanks, and couldnt find any tutorials on them, so, anyone here know how to use these interfaces? or can anyone direct me to a tutorial that explains the methods these add?

 

Thanks in advance.

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

Thanks.

 

But this only really explains what the methods do, which in most of them is pretty self explanatory, I need to know how to properly fill out all the methods. for example: with a gui that stores items, the decrStackSize is pretty self explanatory as to what it does, but not to how to fill it out. After watching tutorials on inventories and guis, I have learnt how to fill it out:

        public ItemStack decrStackSize(int i, int j) {

	if (this.slots[i] != null) {
		ItemStack itemStack;
		if (this.slots[i].stackSize <= j) {
			itemStack = this.slots[i];
			this.slots[i] = null;
			return itemStack;
		} else {
			itemStack = this.slots[i].splitStack(j);

			if (this.slots [i].stackSize == 0) {
				this.slots[i] = null;
			}
		}
		return itemStack;
	}
	return null;
}

 

Also, I am kind of new to java and modding... I know that I shouldnt, but I have jumped right to the advanced stuff, like multiblock structures (done successfully), custom wind turbine that can make power but only if there is an item inside the inventory, and the item takes damage over time, and more damage depending on how high the turbine is in the world. (done successfully) and custom machines that can run on the power the turbine makes (almoast done).

 

But these are things that I can find tutorials for, I cant find any tutorials on inventories that can store liquids, and even use liquids in a recipe.

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

The methods you need to implement by IFluidHandler are basicly wrapper methods for the IFluidTank class. You can just use the provided FluidTank class, which is already filled out, so you don't need to do that. As you can see in the TileFluidHandler class, most of the methods just call tank.aMethod(params), and more you don't need to know. If you really want to know how to fill these methods in, you need to study it yourself.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

You could, but that makes it so it only has a FluidTank which can store a bucket full of liquid. Your best bet is to copy it, rather then extending it, so you can make the tank bigger, and you can customize it further.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

You only need to implements those if you want to create your own version of FluidTank, but else you can just use the already made FluidTank.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

Okay, how do I add multiple tanks to my tileeinity? I am stuck on:

    @Override
    public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
    {
    	return tankInput.fill(resource, doFill);
    }

 

How can I make this do this for all 6 tanks in the inventory?

 

These are my 6 tanks:


        public FluidTank tankInput;
public FluidTank tankOutput1;
public FluidTank tankOutput2;
public FluidTank tankOutput3;
public FluidTank tankOutput4;
public FluidTank tankBiproduct;

        public TileEntityDistillationChamberFrame() {
                tankInput = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 48);
	tankOutput1 = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 12);
	tankOutput2 = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 12);
	tankOutput3 = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 12);
	tankOutput4 = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 12);
	tankBiproduct = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 16);
        }

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

So would I have

return tankInput.fill(...);
return tankOutput1.fill(...);
return tankOutput2.fill(...);
//etc

like that, with multiple return statements?

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

Also, how do I get it to draw the fluid in the tank in the gui class? Im sure that it isnt like the furnace for example where you have things you want to draw on the gui in the texture file, like the progress bar, or the burn tile bar. Would there be a way to get the liquids texture file and draw from that?

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

Drawing the fluids is the difficult part. Here's some code that you can use (don'tcopy/paste, you won't learn from it then):

 

In the drawGuiContainerBackgroundLayer method:

FluidStack fluid = tileentity.getTankInfo(null)[0].fluid;
        if (fluid != null)
        {
            TextureManager manager = Minecraft.getMinecraft().renderEngine;
            manager.bindTexture(manager.getResourceLocation(0));
            int fluidAmount = (int) (((float) fluid.amount / tileentity.tank.getCapacity()) * 60);
            drawFluid(guiLeft + xSize - 24, guiTop + 8 + 60 - fluidAmount, fluid.getFluid().getIcon(fluid), 16, fluidAmount);
        }

the drawFluid method:

private void drawFluid(int x, int y, IIcon icon, int width, int height)
    {
        int i = 0;
        int j = 0;
        
        int drawHeight = 0;
        int drawWidth = 0;
        
        for (i = 0; i < width; i += 16)
        {
            for (j = 0; j < height; j += 16)
            {
                drawWidth = Math.min(width - i, 16);
                drawHeight = Math.min(height - j, 16);
                drawScaledTexturedModelRectFromIcon(x + i, y + j, icon, drawWidth, drawHeight);
            }
        }
    }

and the drawScaledTexturedModelRectFromIcon method:

private void drawScaledTexturedModelRectFromIcon(int x, int y, IIcon icon, int width, int height)
    {
        if (icon == null)
        {
            return;
        }
        double minU = icon.getMinU();
        double maxU = icon.getMaxU();
        double minV = icon.getMinV();
        double maxV = icon.getMaxV();
        
        Tessellator tessellator = Tessellator.instance;
        tessellator.startDrawingQuads();
        tessellator.addVertexWithUV(x + 0, y + height, this.zLevel, minU, minV + (maxV - minV) * height / 16.0D);
        tessellator.addVertexWithUV(x + width, y + height, this.zLevel, minU + (maxU - minU) * width / 16.0D, minV + (maxV - minV) * height / 16.0D);
        tessellator.addVertexWithUV(x + width, y + 0, this.zLevel, minU + (maxU - minU) * width / 16.0D, minV);
        tessellator.addVertexWithUV(x + 0, y + 0, this.zLevel, minU, minV);
        tessellator.draw();
    }

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

Ad this will draw any fluid with a texture reguardless of what mod it is from?

 

Also...

You can't have multiple return statements. You need to take a tank based on the direction given.

 

I dont understand, how would I do this? what do you mean by direction? do you mean what side of the block the fluid comes from? if so, this is a multiblock structure storing the fluids.... how would this work?

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

Yes it will. And yes, by direction i mean the ForgeDirection passed, which is the side the block is that inputs the fluid into the tank. If it's a multiblock structure, you can just get the tank from the master, and call the methods in the master TileEntity.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

Also, I want one tank to be the input, and 5 tanks to be the output. How would I make a recipe with liquids so that if the right liquid is in the input tank, it will fill the 5 other tanks with a certain amount of a different liquid?

 

Also... (sorry for all the questions xD )

How do I make it so that when I mouse over a tank it displays the fluid name, and how much is stored out of how much can be stored. I know there is the onMouseOver method for slots, but the tanks aren't slots, so that method wont work for them.

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

Also... (again...)

I dont understand why this is happening....

 

 

94k4ss0.png

 

 

 

The gui is half the size it needs to be....

 

The gui texture file is 512x512 (twice the size if the default 256x256 gui) but I dont see why that would be a problem, because I am telling it to draw from the top left (X: 0, Y:0) to x: 276, Y: 183 the size of the actual gui texture. Am I not able to have gui's larger than 256x256?

 

Also... Sory but I need a response fast because I need to go very soon....

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

I havn't got any gl11 code in my gui class... Here it is:

 

 

package net.theepictekkit.generator.client.gui;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import net.theepictekkit.generator.Reference;
import net.theepictekkit.generator.common.container.ContainerDistillationChamber;
import net.theepictekkit.generator.common.tileentity.TileEntityDistillationChamberFrame;


public class GuiDistillationChamber extends GuiContainer {

private TileEntityDistillationChamberFrame tileEntityDistillationChamberFrame;

private final String modid = Reference.MODID;
private final ResourceLocation texture = new ResourceLocation (modid + ":" + "textures/gui/guiDistillationChamber.png");

public GuiDistillationChamber(InventoryPlayer invPlayer, TileEntityDistillationChamberFrame tileEntityDistillationChamberFrame) {
	super(new ContainerDistillationChamber(invPlayer, tileEntityDistillationChamberFrame));

	this.tileEntityDistillationChamberFrame = tileEntityDistillationChamberFrame;

	this.xSize = 276;
	this.ySize = 183;
}

@Override
protected void drawGuiContainerForegroundLayer(int x, int y) {

	fontRendererObj.drawString("Distillation Chamber", 8, 4, 0, false);
	fontRendererObj.drawString("Inventory", 8, 72, 0, false);

}

@Override
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) {
	Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
	drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
}
}

 

 

 

though come to think of it, would I be able to use gl11 to double the size if the gui?

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

The drawTexturedModalRect only accepts textures of which is the full size 256x256. You need to make your own method (copy the vanilla method) and change f and f1 to 1/imageSize (in your case 512), and call that method.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

Actually, I am trying halfing the x any y size in the code, this way, it will act like it is a 256x texture. The same way a texturepack can increase the resolution of blocks.

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Posted

Also... (sorry for all the questions xD )

How do I make it so that when I mouse over a tank it displays the fluid name, and how much is stored out of how much can be stored. I know there is the onMouseOver method for slots, but the tanks aren't slots, so that method wont work for them.

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • So me and a couple of friends are playing with a shitpost mod pack and one of the mods in the pack is corail tombstone and for some reason there is a problem with it, where on death to fire the player will get kicked out of the server and the tombstone will not spawn basically deleting an entire inventory, it doesn't matter what type of fire it is, whether it's from vanilla fire/lava, or from modded fire like ice&fire/lycanites and it's common enough to where everyone on the server has experienced at least once or twice and it doesn't give any crash log. a solution to this would be much appreciated thank you!
    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.