Hbm-s-Nuclear-Tech-GIT/src/main/java/com/hbm/tileentity/machine/TileEntityMachineStrandCaster.java
abel1502 afa0418104
Make strand caster timeout refresh on pour
Previously, if a caster has been idle for a while, the first time something is poured into it, it would spew out a partial load almost immediately. The original intention behind the timeout was instead to make the strand caster perform incomplete operations if no new material has been poured for a while. This change makes the behaviour closer to intended. Most of the time, persistent use of the caster would consistently reach full fill, and incomplete fill will only be processed at the end.
2025-06-02 00:15:36 +03:00

353 lines
10 KiB
Java

package com.hbm.tileentity.machine;
import api.hbm.block.ICrucibleAcceptor;
import api.hbm.fluid.IFluidStandardTransceiver;
import com.hbm.blocks.BlockDummyable;
import com.hbm.inventory.container.ContainerMachineStrandCaster;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.fluid.tank.FluidTank;
import com.hbm.inventory.gui.GUIMachineStrandCaster;
import com.hbm.inventory.material.Mats;
import com.hbm.items.ModItems;
import com.hbm.items.machine.ItemMold;
import com.hbm.items.machine.ItemScraps;
import com.hbm.tileentity.IGUIProvider;
import com.hbm.util.fauxpointtwelve.DirPos;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
//god thank you bob for this base class
public class TileEntityMachineStrandCaster extends TileEntityFoundryCastingBase implements IGUIProvider, ICrucibleAcceptor, ISidedInventory, IFluidStandardTransceiver, IInventory {
public FluidTank water;
public FluidTank steam;
private long lastProgressTick = 0;
public String getName() {
return "container.machineStrandCaster";
}
@Override
public String getInventoryName() {
return getName();
}
public TileEntityMachineStrandCaster() {
super(7);
water = new FluidTank(Fluids.WATER, 64_000);
steam = new FluidTank(Fluids.SPENTSTEAM, 64_000);
}
@Override
public void updateEntity() {
if(!worldObj.isRemote) {
if(this.lastType != this.type || this.lastAmount != this.amount) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
this.lastType = this.type;
this.lastAmount = this.amount;
}
// In case of overfill problems, spit out the excess as scrap
if(amount > getCapacity()) {
ItemStack scrap = ItemScraps.create(new Mats.MaterialStack(type, Math.max(amount - getCapacity(), 0)));
EntityItem item = new EntityItem(worldObj, xCoord + 0.5, yCoord + 2, zCoord + 0.5, scrap);
worldObj.spawnEntityInWorld(item);
this.amount = this.getCapacity();
}
if(this.amount == 0) {
this.type = null;
}
this.updateConnections();
int moldsToCast = maxProcessable();
// Makes it flush the buffers after 10 seconds of inactivity, or when they're full
if (moldsToCast > 0 && (moldsToCast >= 9 || worldObj.getWorldTime() >= lastProgressTick + 200)) {
ItemMold.Mold mold = this.getInstalledMold();
this.amount -= moldsToCast * mold.getCost();
ItemStack out = mold.getOutput(type);
int remaining = out.stackSize * moldsToCast;
final int maxStackSize = out.getMaxStackSize();
for (int i = 1; i < 7; i++) {
if (remaining <= 0) {
break;
}
if (slots[i] == null) {
slots[i] = new ItemStack(out.getItem(), 0, out.getItemDamage());
}
if (slots[i].isItemEqual(out)) {
int toDeposit = Math.min(remaining, maxStackSize - slots[i].stackSize);
slots[i].stackSize += toDeposit;
remaining -= toDeposit;
}
}
markChanged();
water.setFill(water.getFill() - getWaterRequired() * moldsToCast);
steam.setFill(steam.getFill() + getWaterRequired() * moldsToCast);
lastProgressTick = worldObj.getWorldTime();
}
networkPackNT(150);
}
}
private int maxProcessable() {
ItemMold.Mold mold = this.getInstalledMold();
if (type == null || mold == null || mold.getOutput(type) == null) {
return 0;
}
int freeSlots = 0;
final int stackLimit = mold.getOutput(type).getMaxStackSize();
for (int i = 1; i < 7; i++) {
if (slots[i] == null) {
freeSlots += stackLimit;
} else if (slots[i].isItemEqual(mold.getOutput(type))) {
freeSlots += stackLimit - slots[i].stackSize;
}
}
int moldsToCast = amount / mold.getCost();
moldsToCast = Math.min(moldsToCast, freeSlots / mold.getOutput(type).stackSize);
moldsToCast = Math.min(moldsToCast, water.getFill() / getWaterRequired());
moldsToCast = Math.min(moldsToCast, (steam.getMaxFill() - steam.getFill()) / getWaterRequired());
return moldsToCast;
}
public DirPos[] getFluidConPos() {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
return new DirPos[] { new DirPos(xCoord + rot.offsetX * 2 - dir.offsetX, yCoord, zCoord + rot.offsetZ * 2 - dir.offsetZ, rot), new DirPos(xCoord - rot.offsetX - dir.offsetX, yCoord, zCoord - rot.offsetZ - dir.offsetZ, rot.getOpposite()), new DirPos(xCoord + rot.offsetX * 2 - dir.offsetX * 5, yCoord, zCoord + rot.offsetZ * 2 - dir.offsetZ * 5, rot), new DirPos(xCoord - rot.offsetX - dir.offsetX * 5, yCoord, zCoord - rot.offsetZ - dir.offsetZ * 5, rot.getOpposite()) };
}
public int[][] getMetalPourPos() {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
return new int[][] { new int[] { xCoord + rot.offsetX - dir.offsetX, yCoord + 2, zCoord + rot.offsetZ - dir.offsetZ }, new int[] { xCoord - dir.offsetX, yCoord + 2, zCoord - dir.offsetZ }, new int[] { xCoord + rot.offsetX, yCoord + 2, zCoord + rot.offsetZ }, new int[] { xCoord, yCoord + 2, zCoord } };
}
@Override
public ItemMold.Mold getInstalledMold() {
if(slots[0] == null)
return null;
if(slots[0].getItem() == ModItems.mold) {
return ((ItemMold) slots[0].getItem()).getMold(slots[0]);
}
return null;
}
@Override
public int getMoldSize() {
return getInstalledMold().size;
}
@Override
public boolean canAcceptPartialPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, Mats.MaterialStack stack) {
if(side != ForgeDirection.UP)
return false;
for(int[] pos : getMetalPourPos()) {
if(pos[0] == x && pos[1] == y && pos[2] == z) {
return this.standardCheck(world, x, y, z, side, stack);
}
}
return false;
}
@Override
public boolean standardCheck(World world, int x, int y, int z, ForgeDirection side, Mats.MaterialStack stack) {
if(this.type != null && this.type != stack.material)
return false;
int limit = this.getInstalledMold() != null ? this.getInstalledMold().getCost() * 9 : this.getCapacity();
return !(this.amount >= limit || getInstalledMold() == null);
}
@Override
public int getCapacity() {
ItemMold.Mold mold = this.getInstalledMold();
return mold == null ? 50000 : mold.getCost() * 10;
}
private int getWaterRequired() {
return getInstalledMold() != null ? 5 * getInstalledMold().getCost() : 50;
}
private void updateConnections() {
for(DirPos pos : getFluidConPos()) {
this.trySubscribe(water.getTankType(), worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
this.sendFluid(steam, worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
}
}
@Override
public Mats.MaterialStack standardAdd(World world, int x, int y, int z, ForgeDirection side, Mats.MaterialStack stack) {
this.type = stack.material;
int limit = this.getInstalledMold() != null ? this.getInstalledMold().getCost() * 9 : this.getCapacity();
if(stack.amount + this.amount <= limit) {
this.amount += stack.amount;
return null;
}
int required = limit - this.amount;
this.amount = limit;
stack.amount -= required;
lastProgressTick = world.getWorldTime();
return stack;
}
@Override
public FluidTank[] getSendingTanks() {
return new FluidTank[] { steam };
}
@Override
public FluidTank[] getReceivingTanks() {
return new FluidTank[] { water };
}
@Override
public FluidTank[] getAllTanks() {
return new FluidTank[] { water, steam };
}
@Override
public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) {
return new ContainerMachineStrandCaster(player.inventory, this);
}
@Override
@SideOnly(Side.CLIENT)
public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) {
return new GUIMachineStrandCaster(player.inventory, this);
}
@Override
public void serialize(ByteBuf buf) {
water.serialize(buf);
steam.serialize(buf);
}
@Override
public void deserialize(ByteBuf buf) {
water.deserialize(buf);
steam.deserialize(buf);
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
water.writeToNBT(nbt, "w");
steam.writeToNBT(nbt, "s");
nbt.setLong("t", lastProgressTick);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
water.readFromNBT(nbt, "w");
steam.readFromNBT(nbt, "s");
lastProgressTick = nbt.getLong("t");
}
@Override
public boolean isItemValidForSlot(int i, ItemStack stack) {
if(i == 0)
return stack.getItem() == ModItems.mold;
return false;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 65536.0D;
}
@Override
public int[] getAccessibleSlotsFromSide(int meta) {
return new int[] { 1, 2, 3, 4, 5, 6 };
}
public void markChanged() {
this.worldObj.markTileEntityChunkModified(this.xCoord, this.yCoord, this.zCoord, this);
}
@Override
public boolean isUseableByPlayer(EntityPlayer player) {
if(worldObj.getTileEntity(xCoord, yCoord, zCoord) != this) {
return false;
} else {
return player.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 128;
}
}
@Override
public boolean canInsertItem(int slot, ItemStack itemStack, int side) {
return this.isItemValidForSlot(slot, itemStack);
}
@Override
public boolean canExtractItem(int slot, ItemStack itemStack, int side) {
return !this.isItemValidForSlot(slot, itemStack);
}
AxisAlignedBB bb = null;
@Override
public AxisAlignedBB getRenderBoundingBox() {
if(bb == null) {
bb = AxisAlignedBB.getBoundingBox(xCoord - 7, yCoord, zCoord - 7, xCoord + 7, yCoord + 3, zCoord + 7);
}
return bb;
}
public boolean isLoaded = true;
@Override
public boolean isLoaded() {
return isLoaded;
}
@Override
public void onChunkUnload() {
super.onChunkUnload();
this.isLoaded = false;
}
}