package mcjty.deepresonance.blocks.smelter; import elec332.core.world.WorldHelper; import mcjty.deepresonance.DeepResonance; import mcjty.deepresonance.blocks.ModBlocks; import mcjty.deepresonance.blocks.tank.ITankHook; import mcjty.deepresonance.blocks.tank.TileTank; import mcjty.deepresonance.config.ConfigMachines; import mcjty.deepresonance.fluid.DRFluidRegistry; import mcjty.deepresonance.fluid.LiquidCrystalFluidTagData; import mcjty.lib.container.DefaultSidedInventory; import mcjty.lib.container.InventoryHelper; import mcjty.lib.entity.GenericEnergyReceiverTileEntity; import mcjty.lib.network.Argument; import mcjty.lib.network.PacketRequestIntegerFromServer; import mcjty.lib.varia.CustomSidedInvWrapper; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import java.util.Map; /** * Created by Elec332 on 9-8-2015. */ public class SmelterTileEntity extends GenericEnergyReceiverTileEntity implements ITankHook, DefaultSidedInventory, ITickable { public static final String CMD_GETPROGRESS = "getProgress"; public static final String CLIENTCMD_GETPROGRESS = "getProgress"; private InventoryHelper inventoryHelper = new InventoryHelper(this, SmelterContainer.factory, 1); public SmelterTileEntity() { super(ConfigMachines.Smelter.rfMaximum, ConfigMachines.Smelter.rfPerTick); checkTanks = true; } private int totalProgress = 0; private int progress = 0; private TileTank lavaTank; private TileTank rclTank; private boolean checkTanks; private float finalQuality = 1.0f; // Calculated quality based on the amount of lava in the lava tank private float finalPurity = 0.1f; // Calculated quality based on the amount of lava in the lava tank private static int progressPercentage = 0; @Override public InventoryHelper getInventoryHelper() { return inventoryHelper; } @Override public void update() { if (!worldObj.isRemote){ checkStateServer(); } } protected void checkStateServer() { if (progress > 0) { if (canWork()) { progress--; storage.extractEnergy(ConfigMachines.Smelter.rfPerOre, false); if (progress == 0) { // Done! stopSmelting(); } } } else { IBlockState state = worldObj.getBlockState(getPos()); boolean oldworking = state.getValue(SmelterBlock.WORKING); boolean newworking; if (canWork() && validSlot()) { startSmelting(); newworking = true; } else { newworking = false; } if (newworking != oldworking) { state = state.withProperty(SmelterBlock.WORKING, newworking); worldObj.setBlockState(getPos(), state, 3); } } } public static int getProgressPercentage() { return progressPercentage; } private boolean canWork() { if (checkTanks) { if (checkTanks()) { checkTanks = false; } else { return false; } } return storage.getEnergyStored() >= ConfigMachines.Smelter.rfPerOre; } private boolean checkTanks(){ return lavaTank != null && rclTank != null && DRFluidRegistry.getFluidFromStack(lavaTank.getFluid()) == FluidRegistry.LAVA && lavaTank.getFluidAmount() > lavaTank.getCapacity()*0.25f && rclTank.fill(null, new FluidStack(DRFluidRegistry.liquidCrystal, ConfigMachines.Smelter.rclPerOre), false) == ConfigMachines.Smelter.rclPerOre; } private boolean validSlot(){ return inventoryHelper.getStackInSlot(SmelterContainer.SLOT_OREINPUT) != null && inventoryHelper.getStackInSlot(SmelterContainer.SLOT_OREINPUT).getItem() == Item.getItemFromBlock(ModBlocks.resonatingOreBlock); } private void startSmelting() { inventoryHelper.decrStackSize(SmelterContainer.SLOT_OREINPUT, 1); float percentage = (float)lavaTank.getFluidAmount() / lavaTank.getCapacity(); if (percentage < 0.40f) { // Slower smelting progress and slightly reduced quality finalQuality = 1.0f - (0.40f - percentage); finalPurity = 0.1f; } else if (percentage > 0.75f) { finalQuality = -1.0f; // Total waste! finalPurity = 0.0f; } else if (percentage > 0.60f) { // Reduced quality. finalQuality = 1.0f - (percentage - 0.60f) * 6.666f; finalPurity = 0.1f - (percentage - 0.60f) * 0.3f; } else { finalQuality = 1.0f; finalPurity = 0.1f; } lavaTank.drain(null, new FluidStack(FluidRegistry.LAVA, ConfigMachines.Smelter.lavaCost), true); progress = ConfigMachines.Smelter.processTime + (int) ((percentage - 0.5f) * ConfigMachines.Smelter.processTime); totalProgress = progress; } private void stopSmelting() { if (finalQuality > 0.0f) { FluidStack stack = LiquidCrystalFluidTagData.makeLiquidCrystalStack(ConfigMachines.Smelter.rclPerOre, finalQuality, finalPurity, 0.1f, 0.1f); rclTank.fill(null, stack, true); } } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); tagCompound.setInteger("totalProgress", totalProgress); tagCompound.setInteger("progress", progress); tagCompound.setFloat("finalQuality", finalQuality); tagCompound.setFloat("finalPurity", finalPurity); } @Override public void writeRestorableToNBT(NBTTagCompound tagCompound) { super.writeRestorableToNBT(tagCompound); writeBufferToNBT(tagCompound, inventoryHelper); } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); totalProgress = tagCompound.getInteger("totalProgress"); progress = tagCompound.getInteger("progress"); finalQuality = tagCompound.getFloat("finalQuality"); finalPurity = tagCompound.getFloat("finalPurity"); } @Override public void readRestorableFromNBT(NBTTagCompound tagCompound) { super.readRestorableFromNBT(tagCompound); readBufferFromNBT(tagCompound, inventoryHelper); } @Override public void hook(TileTank tank, EnumFacing direction) { if (direction == EnumFacing.DOWN){ this.lavaTank = tank; } else if (rclTank == null){ if (validRCLTank(tank)){ rclTank = tank; } } checkTanks = true; } @Override public void unHook(TileTank tank, EnumFacing direction) { if (tilesEqual(lavaTank, tank)){ lavaTank = null; } else if (tilesEqual(rclTank, tank)){ rclTank = null; notifyAndMarkDirty(); } checkTanks = true; } @Override public void onContentChanged(TileTank tank, EnumFacing direction) { if (tilesEqual(rclTank, tank)){ if (!validRCLTank(tank)) { rclTank = null; } } checkTanks = true; } private boolean validRCLTank(TileTank tank){ Fluid fluid = DRFluidRegistry.getFluidFromStack(tank.getFluid()); return fluid == null || fluid == DRFluidRegistry.liquidCrystal; } private boolean tilesEqual(TileTank first, TileTank second){ return first != null && second != null && first.getPos().equals(second.getPos()) && WorldHelper.getDimID(first.getWorld()) == WorldHelper.getDimID(second.getWorld()); } @Override public int[] getSlotsForFace(EnumFacing side) { return new int[] { SmelterContainer.SLOT_OREINPUT }; } @Override public boolean canInsertItem(int index, ItemStack item, EnumFacing side) { if (!isItemValidForSlot(index, item)) { return false; } return SmelterContainer.factory.isInputSlot(index) || SmelterContainer.factory.isSpecificItemSlot(index); } @Override public boolean canExtractItem(int index, ItemStack item, EnumFacing side) { return SmelterContainer.factory.isOutputSlot(index); } @Override public int getInventoryStackLimit() { return 64; } @Override public boolean isUseableByPlayer(EntityPlayer player) { return canPlayerAccess(player); } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return stack.getItem() == Item.getItemFromBlock(ModBlocks.resonatingOreBlock); } // Request the researching amount from the server. This has to be called on the client side. public void requestProgressFromServer() { DeepResonance.networkHandler.getNetworkWrapper().sendToServer(new PacketRequestIntegerFromServer(DeepResonance.MODID, pos, CMD_GETPROGRESS, CLIENTCMD_GETPROGRESS)); } @Override public Integer executeWithResultInteger(String command, Map<String, Argument> args) { Integer rc = super.executeWithResultInteger(command, args); if (rc != null) { return rc; } if (CMD_GETPROGRESS.equals(command)) { if (totalProgress == 0) { return 0; } else { return (totalProgress - progress) * 100 / totalProgress; } } return null; } @Override public boolean execute(String command, Integer result) { boolean rc = super.execute(command, result); if (rc) { return true; } if (CLIENTCMD_GETPROGRESS.equals(command)) { progressPercentage = result; return true; } return false; } IItemHandler invHandler = new CustomSidedInvWrapper(this); @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); } @Override @SuppressWarnings("unchecked") public <T> T getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, net.minecraft.util.EnumFacing facing) { if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { return (T) invHandler; } return super.getCapability(capability, facing); } protected void notifyAndMarkDirty(){ if (WorldHelper.chunkLoaded(worldObj, pos)){ this.markDirty(); this.worldObj.notifyNeighborsOfStateChange(pos, blockType); } } }