Package mods.railcraft.common.blocks.machine.alpha

Source Code of mods.railcraft.common.blocks.machine.alpha.TileSteamOven

/*
* Copyright (c) CovertJaguar, 2014 http://railcraft.info
*
* This code is the property of CovertJaguar
* and may only be used with explicit written
* permission unless otherwise specified on the
* license page at http://railcraft.info/wiki/info:license.
*/
package mods.railcraft.common.blocks.machine.alpha;

import buildcraft.api.statements.IActionExternal;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import mods.railcraft.common.blocks.RailcraftBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.IIcon;
import net.minecraftforge.common.util.ForgeDirection;
import mods.railcraft.common.blocks.machine.IEnumMachine;
import mods.railcraft.common.blocks.machine.MultiBlockPattern;
import mods.railcraft.common.blocks.machine.TileMultiBlock;
import mods.railcraft.common.blocks.machine.TileMultiBlockInventory;
import mods.railcraft.common.blocks.machine.beta.ISteamUser;
import mods.railcraft.common.gui.EnumGui;
import mods.railcraft.common.gui.GuiHandler;
import mods.railcraft.common.fluids.Fluids;
import mods.railcraft.common.util.inventory.InvTools;
import mods.railcraft.common.util.inventory.wrappers.InventoryMapper;
import mods.railcraft.common.fluids.FluidHelper;
import mods.railcraft.common.fluids.TankManager;
import mods.railcraft.common.fluids.tanks.StandardTank;
import mods.railcraft.common.fluids.tanks.FakeTank;
import mods.railcraft.common.fluids.tanks.FilteredTank;
import mods.railcraft.common.plugins.buildcraft.actions.Actions;
import mods.railcraft.common.plugins.buildcraft.triggers.IHasWork;
import mods.railcraft.common.util.effects.EffectManager;
import mods.railcraft.common.util.misc.Game;
import mods.railcraft.common.util.misc.MiscTools;
import mods.railcraft.common.util.sounds.SoundHelper;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;

import static net.minecraftforge.common.util.ForgeDirection.DOWN;
import static net.minecraftforge.common.util.ForgeDirection.UP;

public class TileSteamOven extends TileMultiBlockInventory implements IFluidHandler, ISidedInventory, ISteamUser, IHasWork {

    public static void placeSteamOven(World world, int x, int y, int z, List<ItemStack> input, List<ItemStack> output) {
        for (MultiBlockPattern pattern : TileSteamOven.patterns) {
            Map<Character, Integer> blockMapping = new HashMap<Character, Integer>();
            blockMapping.put('B', EnumMachineAlpha.STEAM_OVEN.ordinal());
            TileEntity tile = pattern.placeStructure(world, x, y, z, RailcraftBlocks.getBlockMachineAlpha(), blockMapping);
            if (tile instanceof TileSteamOven) {
                TileSteamOven master = (TileSteamOven) tile;
                for (int slot = 0; slot < 9; slot++) {
                    if (input != null && slot < input.size())
                        master.inv.setInventorySlotContents(TileSteamOven.SLOT_INPUT + slot, input.get(slot));
                    if (output != null && slot < output.size())
                        master.inv.setInventorySlotContents(TileSteamOven.SLOT_OUTPUT + slot, output.get(slot));
                }
            }
            return;
        }
    }

    enum Texture {

        DOOR_TL(6), DOOR_TR(7), DOOR_BL(8), DOOR_BR(9), SIDE(2), CAP(0);
        private final int index;

        private Texture(int index) {
            this.index = index;
        }

        public IIcon getIcon() {
            return EnumMachineAlpha.STEAM_OVEN.getTexture(index);
        }

    }

    private static final ForgeDirection[] UP_DOWN_AXES = new ForgeDirection[]{UP, DOWN};
    private static final int STEAM_PER_BATCH = 8000;
    private static final int TOTAL_COOK_TIME = 256;
    private static final int COOK_STEP = 16;
    private static final int ITEMS_SMELTED = 9;
    public static final int SLOT_INPUT = 0;
    public static final int SLOT_OUTPUT = 9;
    private static final int[] SLOTS = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
    private static final int TANK_CAPACITY = 8 * FluidHelper.BUCKET_VOLUME;
    private final static List<MultiBlockPattern> patterns = new ArrayList<MultiBlockPattern>();
    private ForgeDirection facing = ForgeDirection.NORTH;
    public int cookTime;
    public boolean finishedCycle = false;
    private boolean paused = false;
    private final TankManager tankManager = new TankManager();
    private final StandardTank tank;
    private final IInventory invInput = new InventoryMapper(this, SLOT_INPUT, 9);
    private final IInventory invOutput = new InventoryMapper(this, SLOT_OUTPUT, 9, false);
    private final Set<IActionExternal> actions = new HashSet<IActionExternal>();

    static {
        char[][][] map = {
            {
                {'*', 'O', 'O', '*'},
                {'O', 'O', 'O', 'O'},
                {'O', 'O', 'O', 'O'},
                {'*', 'O', 'O', '*'},},
            {
                {'*', 'O', 'O', '*'},
                {'O', 'B', 'B', 'O'},
                {'O', 'B', 'B', 'O'},
                {'*', 'O', 'O', '*'}
            },
            {
                {'*', 'O', 'O', '*'},
                {'O', 'B', 'B', 'O'},
                {'O', 'B', 'B', 'O'},
                {'*', 'O', 'O', '*'}
            },
            {
                {'*', 'O', 'O', '*'},
                {'O', 'O', 'O', 'O'},
                {'O', 'O', 'O', 'O'},
                {'*', 'O', 'O', '*'},},};
        patterns.add(new MultiBlockPattern(map));
    }

    public TileSteamOven() {
        super("railcraft.gui.steam.oven", 18, patterns);
        tank = new FilteredTank(TANK_CAPACITY, Fluids.STEAM.get(), this);
        tankManager.add(tank);
    }

    @Override
    public IEnumMachine getMachineType() {
        return EnumMachineAlpha.STEAM_OVEN;
    }

    public TankManager getTankManager() {
        TileSteamOven mBlock = (TileSteamOven) getMasterBlock();
        if (mBlock != null)
            return mBlock.tankManager;
        return null;
    }

    @Override
    public IIcon getIcon(int side) {
        if (isStructureValid() && side == getFacing().ordinal())
            switch (side) {
                case 2:
                    if (getPatternPositionY() == 2) {
                        if (getPatternPositionX() == 2)
                            return Texture.DOOR_TL.getIcon();
                        return Texture.DOOR_TR.getIcon();
                    }
                    if (getPatternPositionX() == 2)
                        return Texture.DOOR_BL.getIcon();
                    return Texture.DOOR_BR.getIcon();
                case 3:
                    if (getPatternPositionY() == 2) {
                        if (getPatternPositionX() == 1)
                            return Texture.DOOR_TL.getIcon();
                        return Texture.DOOR_TR.getIcon();
                    }
                    if (getPatternPositionX() == 1)
                        return Texture.DOOR_BL.getIcon();
                    return Texture.DOOR_BR.getIcon();
                case 4:
                    if (getPatternPositionY() == 2) {
                        if (getPatternPositionZ() == 1)
                            return Texture.DOOR_TL.getIcon();
                        return Texture.DOOR_TR.getIcon();
                    }
                    if (getPatternPositionZ() == 1)
                        return Texture.DOOR_BL.getIcon();
                    return Texture.DOOR_BR.getIcon();
                case 5:
                    if (getPatternPositionY() == 2) {
                        if (getPatternPositionZ() == 2)
                            return Texture.DOOR_TL.getIcon();
                        return Texture.DOOR_TR.getIcon();
                    }
                    if (getPatternPositionZ() == 2)
                        return Texture.DOOR_BL.getIcon();
                    return Texture.DOOR_BR.getIcon();
            }
        if (side > 1)
            return Texture.SIDE.getIcon();
        return Texture.CAP.getIcon();
    }

    public int getCookProgressScaled(int i) {
        int scale = (getCookTime() * i) / TOTAL_COOK_TIME;
        scale = Math.min(scale, i);
        scale = Math.max(scale, 0);
        return scale;
    }

    public int getCookTime() {
        TileSteamOven masterOven = (TileSteamOven) getMasterBlock();
        if (masterOven != null)
            return masterOven.cookTime;
        return -1;
    }

    public ForgeDirection getFacing() {
        TileSteamOven masterOven = (TileSteamOven) getMasterBlock();
        if (masterOven != null)
            return masterOven.facing;
        return facing;
    }

    public boolean hasFinishedCycle() {
        TileSteamOven mBlock = (TileSteamOven) getMasterBlock();
        return mBlock != null && mBlock.finishedCycle;
    }

    public void setHasFinishedCycle(boolean finished) {
        if (finishedCycle != finished) {
            finishedCycle = finished;
            sendUpdateToClient();
        }
    }

    @Override
    public void updateEntity() {
        super.updateEntity();

        if (Game.isNotHost(getWorld())) {
            if (hasFinishedCycle())
                EffectManager.instance.steamEffect(worldObj, this, +0.25);
            return;
        }

        if (isMaster()) {
            if (clock % 16 == 0)
                processActions();
            if (clock % COOK_STEP == 0) {
                setHasFinishedCycle(false);
                if (!paused)
                    if (hasRecipe()) {
                        if (cookTime <= 0 && drainSteam())
                            cookTime = 1;
                        else if (cookTime > 0) {
                            cookTime += COOK_STEP;
                            if (cookTime >= TOTAL_COOK_TIME)
                                if (smeltItems()) {
                                    cookTime = 0;
                                    setHasFinishedCycle(true);
                                    SoundHelper.playSound(worldObj, xCoord, yCoord, zCoord, SoundHelper.SOUND_STEAM_BURST, 1, (float) (1 + MiscTools.getRand().nextGaussian() * 0.1));
                                }
                        }
                    } else
                        cookTime = 0;
            }
        }
    }

    private boolean drainSteam() {
        FluidStack steam = tank.drain(STEAM_PER_BATCH, false);
        if (steam != null && steam.amount >= STEAM_PER_BATCH) {
            tank.drain(STEAM_PER_BATCH, true);
            return true;
        }
        return false;
    }

    private boolean hasRecipe() {
        for (int slot = 0; slot < 9; slot++) {
            ItemStack stack = invInput.getStackInSlot(slot);
            if (stack != null && FurnaceRecipes.smelting().getSmeltingResult(stack) != null)
                return true;
        }
        return false;
    }

    private boolean smeltItems() {
        int count = 0;
        boolean changed = true;
        boolean smelted = false;
        while (count < ITEMS_SMELTED && changed) {
            changed = false;
            for (int slot = 0; slot < 9 && count < ITEMS_SMELTED; slot++) {
                ItemStack stack = invInput.getStackInSlot(slot);
                if (stack != null) {
                    ItemStack output = FurnaceRecipes.smelting().getSmeltingResult(stack);
                    if (output != null && InvTools.isRoomForStack(output, invOutput)) {
                        ItemStack remainder = InvTools.moveItemStack(output.copy(), invOutput);
                        if (remainder == null) {
                            invInput.decrStackSize(slot, 1);
                            changed = true;
                            count++;
                        }
                    }
                }
            }
            smelted |= changed;
        }
        return smelted;
    }

    @Override
    public void onBlockPlacedBy(EntityLivingBase player) {
        super.onBlockPlacedBy(player);
        facing = MiscTools.getHorizontalSideClosestToPlayer(worldObj, xCoord, yCoord, zCoord, player);
    }

    @Override
    public boolean rotateBlock(ForgeDirection axis) {
        if (axis == UP || axis == DOWN)
            return false;
        TileSteamOven master = (TileSteamOven) getMasterBlock();
        if (master != null) {
            if (master.facing == axis)
                master.facing = axis.getOpposite();
            else
                master.facing = axis;
            master.scheduleMasterRetest();
            return true;
        }
        return false;
    }

    @Override
    public ForgeDirection[] getValidRotations() {
        return UP_DOWN_AXES;
    }

    @Override
    public boolean openGui(EntityPlayer player) {
        TileMultiBlock masterBlock = getMasterBlock();
        if (masterBlock != null) {
            GuiHandler.openGui(EnumGui.STEAN_OVEN, player, worldObj, masterBlock.xCoord, masterBlock.yCoord, masterBlock.zCoord);
            return true;
        }
        return false;
    }

    @Override
    public void writeToNBT(NBTTagCompound data) {
        super.writeToNBT(data);
        tankManager.writeTanksToNBT(data);
        data.setInteger("cookTime", cookTime);
        data.setByte("facing", (byte) facing.ordinal());
    }

    @Override
    public void readFromNBT(NBTTagCompound data) {
        super.readFromNBT(data);
        tankManager.readTanksFromNBT(data);
        cookTime = data.getInteger("cookTime");
        facing = ForgeDirection.getOrientation(data.getByte("facing"));
    }

    @Override
    public void writePacketData(DataOutputStream data) throws IOException {
        super.writePacketData(data);
        data.writeByte(facing.ordinal());
        data.writeBoolean(finishedCycle);
    }

    @Override
    public void readPacketData(DataInputStream data) throws IOException {
        super.readPacketData(data);
        byte f = data.readByte();
        finishedCycle = data.readBoolean();
        if (f != facing.ordinal()) {
            facing = ForgeDirection.getOrientation(f);
            markBlockForUpdate();
        }
    }

    @Override
    public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
        if (resource == null) return 0;
        TankManager tMan = getTankManager();
        if (tMan == null)
            return 0;
        return tMan.fill(0, resource, doFill);
    }

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

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

    @Override
    public boolean canFill(ForgeDirection from, Fluid fluid) {
        return fluid == null || Fluids.STEAM.is(fluid);
    }

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

    @Override
    public FluidTankInfo[] getTankInfo(ForgeDirection dir) {
        TankManager tMan = getTankManager();
        if (tMan != null)
            return tMan.getTankInfo();
        return FakeTank.INFO;
    }

    @Override
    public int[] getAccessibleSlotsFromSide(int side) {
        return SLOTS;
    }

    @Override
    public boolean canInsertItem(int slot, ItemStack stack, int side) {
        return isItemValidForSlot(slot, stack);
    }

    @Override
    public boolean canExtractItem(int slot, ItemStack itemstack, int side) {
        return slot >= SLOT_OUTPUT;
    }

    @Override
    public boolean isItemValidForSlot(int slot, ItemStack stack) {
        if (stack == null)
            return false;
        if (slot >= SLOT_OUTPUT)
            return false;
        return FurnaceRecipes.smelting().getSmeltingResult(stack) != null;
    }

    @Override
    public boolean hasWork() {
        TileSteamOven mBlock = (TileSteamOven) getMasterBlock();
        if (mBlock != null)
            return mBlock.cookTime > 0;
        return false;
    }

    private void processActions() {
        paused = false;
        for (IActionExternal action : actions) {
            if (action == Actions.PAUSE)
                paused = true;
        }
        actions.clear();
    }

    @Override
    public void actionActivated(IActionExternal action) {
        TileSteamOven mBlock = (TileSteamOven) getMasterBlock();
        if (mBlock != null)
            mBlock.actions.add(action);
    }

}
TOP

Related Classes of mods.railcraft.common.blocks.machine.alpha.TileSteamOven

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.