Package tconstruct.smeltery.logic

Source Code of tconstruct.smeltery.logic.AdaptiveSmelteryLogic$LiquidData

package tconstruct.smeltery.logic;

import java.util.*;
import mantle.blocks.abstracts.AdaptiveInventoryLogic;
import mantle.blocks.iface.*;
import mantle.world.CoordTuple;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.*;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.*;
import tconstruct.TConstruct;
import tconstruct.library.component.*;
import tconstruct.smeltery.TinkerSmeltery;
import tconstruct.smeltery.component.*;
import tconstruct.smeltery.inventory.AdaptiveSmelteryContainer;

public class AdaptiveSmelteryLogic extends AdaptiveInventoryLogic implements IActiveLogic, IMasterLogic, IComponentHolder, IFluidHandler
{
    byte direction;
    boolean updateFluids = false;
    boolean recheckStructure = false;
    boolean updateAir = false;
    SmelteryScan structure = new SmelteryScan(this, TinkerSmeltery.smeltery, TinkerSmeltery.lavaTank);
    MultiFluidTank multitank = new MultiFluidTank();
    SmelteryComponent smeltery = new SmelteryComponent(this, structure, multitank, 800);
    HashMap<CoordTuple, LiquidDataInstance> airUpdates = new HashMap<CoordTuple, LiquidDataInstance>();
    int tick = 0;

    public MultiFluidTank getMultiTank ()
    {
        return multitank;
    }

    public SmelteryComponent getSmeltery ()
    {
        return smeltery;
    }

    @Override
    public void updateEntity ()
    {
        tick++;
        if (tick % 4 == 0)
            smeltery.heatItems();

        if (!worldObj.isRemote)
        {
            if (tick % 20 == 0)
            {
                if (structure.isComplete())
                    smeltery.update();

                if (updateFluids)
                {
                    distributeFluids();
                    updateFluids = false;
                }

                if (updateAir)
                {
                    updateAir();
                    updateAir = false;
                }

                if (recheckStructure)
                {
                    structure.recheckStructure();
                    recheckStructure = false;
                }
            }

            if (tick >= 60)
            {
                if (!structure.isComplete())
                {
                    structure.checkValidStructure();
                    if (structure.isComplete())
                    {
                        validateSmeltery();
                    }
                }
                tick = 0;
            }

            if (airUpdates.size() > 0)
                updateFluidBlocks();
        }
    }

    public void setUpdateFluids ()
    {
        updateFluids = true;
    }

    @Override
    public List<LogicComponent> getComponents ()
    {
        ArrayList<LogicComponent> ret = new ArrayList<LogicComponent>(3);
        ret.add(structure);
        ret.add(multitank);
        ret.add(smeltery);
        return ret;
    }

    /* Structure */

    @Override
    public void setWorldObj (World world)
    {
        super.setWorldObj(world);
        structure.setWorld(world);
        smeltery.setWorld(world);
    }

    @Override
    public void notifyChange (IServantLogic servant, int x, int y, int z)
    {
        if (!worldObj.isRemote)
        {
            // System.out.println("Notifying of change from "+new CoordTuple(x,
            // y, z));
            recheckStructure = true;
        }
    }

    @Override
    public void placeBlock (EntityLivingBase entity, ItemStack itemstack)
    {
        structure.checkValidStructure();
        if (structure.isComplete())
        {
            validateSmeltery();
        }
    }

    void validateSmeltery ()
    {
        adjustInventory(structure.getAirSize(), true);
        smeltery.adjustSize(structure.getAirSize(), true);
        multitank.setCapacity(structure.getAirSize() * (TConstruct.ingotLiquidValue * 18));
        smeltery.setActiveLavaTank(structure.lavaTanks.get(0));
        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
    }

    @Override
    public void removeBlock ()
    {
        structure.cleanup();
    }

    /* Direction */

    @Override
    public byte getRenderDirection ()
    {
        return direction;
    }

    @Override
    public ForgeDirection getForgeDirection ()
    {
        return ForgeDirection.VALID_DIRECTIONS[direction];
    }

    @Override
    public void setDirection (int side)
    {

    }

    @Override
    public void setDirection (float yaw, float pitch, EntityLivingBase player)
    {
        int facing = MathHelper.floor_double((double) (yaw / 360) + 0.5D) & 3;
        switch (facing)
        {
        case 0:
            direction = 2;
            break;

        case 1:
            direction = 5;
            break;

        case 2:
            direction = 3;
            break;

        case 3:
            direction = 4;
            break;
        }
    }

    @Override
    public boolean getActive ()
    {
        return structure.isComplete();
    }

    @Override
    public void setActive (boolean flag)
    {

    }

    /* Inventory */

    @Override
    public int getInventoryStackLimit ()
    {
        return 1;
    }

    @Override
    public void setInventorySlotContents (int slot, ItemStack itemstack)
    {
        inventory[slot] = itemstack;
        if (itemstack != null && itemstack.stackSize > getInventoryStackLimit())
        {
            itemstack.stackSize = getInventoryStackLimit();
        }
        updateWorldBlock(slot, itemstack);
        updateAir = true;
    }

    @Override
    public ItemStack decrStackSize (int slot, int quantity)
    {
        if (inventory[slot] != null)
        {
            if (inventory[slot].stackSize <= quantity)
            {
                ItemStack stack = inventory[slot];
                inventory[slot] = null;
                updateWorldBlock(slot, inventory[slot]);
                return stack;
            }
            ItemStack split = inventory[slot].splitStack(quantity);
            if (inventory[slot].stackSize == 0)
            {
                inventory[slot] = null;
            }

            updateWorldBlock(slot, inventory[slot]);
            return split;
        }
        else
        {
            return null;
        }
    }

    @Override
    public void markDirty ()
    {
        smeltery.updateTemperatures();
        updateAir = true;
        super.markDirty();
    }

    void updateWorldBlock (int slot, ItemStack itemstack)
    {
        CoordTuple air = structure.getAirByIndex(slot);
        if (air != null)
        {
            TileEntity te = worldObj.getTileEntity(air.x, air.y, air.z);
            if (te != null && te instanceof TankAirLogic)
            {
                ((TankAirLogic) te).setInventorySlotContents(0, itemstack);
            }
        }
    }

    static final int pixelLayer = 162;

    // Do the Monster Mash~
    public void distributeFluids ()
    {
        // Calculate liquids in each block
        int size = structure.getAirLayerSize();
        // HashMap<CoordTuple, LiquidDataInstance> blocks = new
        // HashMap<CoordTuple, LiquidDataInstance>();

        for (FluidStack fluid : multitank.fluidlist)
        {
            // Base calculations per liquid
            LiquidData data = new LiquidData(fluid.amount, size);
            int baseY = structure.airCoords.get(0).y;
            int layerSize = structure.getAirLayerSize();

            // Calculate where to distribute liquids
            for (int i = 0; i < structure.airCoords.size(); i++)
            {
                LiquidDataInstance instance;
                CoordTuple coord = structure.airCoords.get(i);
                int height = 16 * (coord.y - baseY);
                int position = i % layerSize;

                if (!airUpdates.containsKey(coord))
                {
                    instance = new LiquidDataInstance();
                    airUpdates.put(coord, instance);
                }
                else
                {
                    instance = airUpdates.get(coord);
                }

                if (instance.openLayers() > 0) // This is capable of sending
                                               // negative liquid sizes to
                                               // blocks without the stopgap
                                               // check
                {
                    if (position > data.blocksWithExtra)
                    {
                        // Calculate open layers
                        int open = data.layers - height + 1;
                        if (open < 1) // Temporary stopgap check
                            continue;
                        if (open > instance.openLayers())
                            open = instance.openLayers();

                        // Copy fluid
                        FluidStack newFluid = fluid.copy();
                        newFluid.amount = pixelLayer * open;
                        instance.addFluid(open, newFluid);

                        // Subtract from total
                        data.totalAmount -= newFluid.amount;
                        if (data.totalAmount <= 0)
                            break;
                    }
                    else if (position == data.blocksWithExtra && data.leftovers > 0)
                    {
                        // Calculate open layers
                        int open = data.layers - height + 1;
                        if (open < 1) // Temporary stopgap check
                            continue;
                        boolean full = false;
                        if (open > instance.openLayers())
                        {
                            open = instance.openLayers();
                            full = true;
                        }

                        // Copy fluid
                        FluidStack newFluid = fluid.copy();
                        newFluid.amount = pixelLayer * open;
                        if (!full)
                            newFluid.amount += data.leftovers;
                        instance.addFluid(open, newFluid);

                        // Subtract from total
                        data.totalAmount -= newFluid.amount;
                        if (data.totalAmount <= 0)
                            break;
                    }
                    else
                    {
                        // Calculate open layers
                        int open = data.layers - height;
                        if (open < 1) // Temporary stopgap check
                            continue;
                        if (open > instance.openLayers())
                            open = instance.openLayers();

                        // Copy fluid
                        FluidStack newFluid = fluid.copy();
                        newFluid.amount = pixelLayer * open;
                        instance.addFluid(open, newFluid);

                        // Subtract from total
                        data.totalAmount -= newFluid.amount;
                        if (data.totalAmount <= 0)
                            break;
                    }
                }
            }
        }

        // Distribute liquids to each block
    }

    protected void updateFluidBlocks ()
    {
        Iterator iter = airUpdates.entrySet().iterator();
        byte count = 0;
        while (iter.hasNext() && count < 40)
        {
            Map.Entry pairs = (Map.Entry) iter.next();
            CoordTuple coord = (CoordTuple) pairs.getKey();
            TileEntity te = worldObj.getTileEntity(coord.x, coord.y, coord.z);
            if (te instanceof TankAirLogic)
            {
                ((TankAirLogic) te).overrideFluids(((LiquidDataInstance) pairs.getValue()).fluids);
            }
            iter.remove();
            count++;
        }
    }

    public void updateAir ()
    {
        for (CoordTuple loc : structure.airCoords)
            worldObj.markBlockForUpdate(loc.x, loc.y, loc.z);
    }

    class LiquidData
    {
        public int totalAmount;
        public int layers;
        public int leftovers;
        public int blocksWithExtra;

        LiquidData(int amount, int blocks)
        {
            totalAmount = amount;
            int layerAmount = pixelLayer * blocks;
            layers = amount / layerAmount;
            leftovers = amount % pixelLayer;
            blocksWithExtra = (amount % layerAmount) / pixelLayer;
        }
    }

    class LiquidDataInstance
    {
        public ArrayList<FluidStack> fluids = new ArrayList<FluidStack>();
        int layers = 0;

        public int openLayers ()
        {
            return 16 - layers;
        }

        public void addFluid (int l, FluidStack fluid)
        {
            layers += l;
            fluids.add(fluid);
        }
    }

    /* Gui */

    @Override
    public Container getGuiContainer (InventoryPlayer inventoryplayer, World world, int x, int y, int z)
    {
        return new AdaptiveSmelteryContainer(inventoryplayer, this);
    }

    public int getTempForSlot (int slot)
    {
        return smeltery.activeTemps[slot];
    }

    public int getMeltingPointForSlot (int slot)
    {
        return smeltery.meltingTemps[slot];
    }

    @Override
    public String getDefaultName ()
    {
        return "crafters.Smeltery";
    }

    /* Fluids */

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

    @Override
    public FluidStack drain (ForgeDirection from, FluidStack resource, boolean doDrain)
    {
        return multitank.drain(resource.amount, doDrain);
    }

    @Override
    public FluidStack drain (ForgeDirection from, int maxDrain, boolean doDrain)
    {
        return multitank.drain(maxDrain, doDrain);
    }

    @Override
    public boolean canFill (ForgeDirection from, Fluid fluid)
    {
        return false;
    }

    @Override
    public boolean canDrain (ForgeDirection from, Fluid fluid)
    {
        return false;
    }

    @Override
    public FluidTankInfo[] getTankInfo (ForgeDirection from)
    {
        return multitank.getMultiTankInfo();
    }

    public int getFillState ()
    {
        return 1;
    }

    /* NBT */

    @Override
    public void readFromNBT (NBTTagCompound tags)
    {
        super.readFromNBT(tags);
        readNetworkNBT(tags);

        structure.readFromNBT(tags);
        multitank.readFromNBT(tags);
        smeltery.readFromNBT(tags);
    }

    public void readNetworkNBT (NBTTagCompound tags)
    {
        direction = tags.getByte("Direction");
        adjustInventory(tags.getInteger("InvSize"), false);
        super.readInventoryFromNBT(tags);

        structure.readNetworkNBT(tags);
        multitank.readNetworkNBT(tags);
        smeltery.readNetworkNBT(tags);
    }

    @Override
    public void writeToNBT (NBTTagCompound tags)
    {
        super.writeToNBT(tags);
        writeNetworkNBT(tags);

        structure.writeToNBT(tags);
        multitank.writeToNBT(tags);
        smeltery.writeToNBT(tags);
    }

    public void writeNetworkNBT (NBTTagCompound tags)
    {
        tags.setByte("Direction", direction);
        tags.setInteger("InvSize", inventory.length);
        super.writeInventoryToNBT(tags);

        structure.writeNetworkNBT(tags);
        multitank.writeNetworkNBT(tags);
        smeltery.writeNetworkNBT(tags);
    }

    @Override
    public void onDataPacket (NetworkManager net, S35PacketUpdateTileEntity packet)
    {
        readNetworkNBT(packet.func_148857_g());
        worldObj.func_147479_m(xCoord, yCoord, zCoord);
    }

    @Override
    public Packet getDescriptionPacket ()
    {
        NBTTagCompound tag = new NBTTagCompound();
        writeNetworkNBT(tag);
        return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tag);
    }

    @Override
    public String getInventoryName ()
    {
        return getDefaultName();
    }

    @Override
    public boolean hasCustomInventoryName ()
    {
        return true;
    }

    @Override
    public void openInventory ()
    {
    }

    @Override
    public void closeInventory ()
    {
    }
}
TOP

Related Classes of tconstruct.smeltery.logic.AdaptiveSmelteryLogic$LiquidData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
-20639858-1', 'auto'); ga('send', 'pageview');