package mekanism.common; import ic2.api.ElectricItem; import ic2.api.IElectricItem; import java.util.ArrayList; import mekanism.api.EnumColor; import mekanism.api.EnumGas; import mekanism.api.IStorageTank; import mekanism.api.SideData; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import universalelectricity.core.item.ElectricItemHelper; import universalelectricity.core.item.IItemElectric; import com.google.common.io.ByteArrayDataInput; import dan200.computer.api.IComputerAccess; public abstract class TileEntityAdvancedElectricMachine extends TileEntityBasicMachine { /** How much secondary energy (fuel) this machine uses per tick. */ public int SECONDARY_ENERGY_PER_TICK; /** Maximum amount of secondary energy (fuel) this machine can hold. */ public int MAX_SECONDARY_ENERGY; /** How much secondary energy (fuel) is stored in this machine. */ public int secondaryEnergyStored = 0; /** * Advanced Electric Machine -- a machine like this has a total of 4 slots. Input slot (0), fuel slot (1), output slot (2), * energy slot (3), and the upgrade slot (4). The machine will not run if it does not have enough electricity, or if it doesn't have enough * fuel ticks. * * @param soundPath - location of the sound effect * @param name - full name of this machine * @param path - GUI texture path of this machine * @param perTick - how much energy this machine uses per tick. * @param secondaryPerTick - how much secondary energy (fuel) this machine uses per tick. * @param ticksRequired - how many ticks it takes to smelt an item. * @param maxEnergy - maximum amount of energy this machine can hold. * @param maxSecondaryEnergy - maximum amount of secondary energy (fuel) this machine can hold. */ public TileEntityAdvancedElectricMachine(String soundPath, String name, String path, int perTick, int secondaryPerTick, int ticksRequired, int maxEnergy, int maxSecondaryEnergy) { super(soundPath, name, path, perTick, ticksRequired, maxEnergy); sideOutputs.add(new SideData(EnumColor.GREY, 0, 0, new int[0])); sideOutputs.add(new SideData(EnumColor.DARK_RED, 0, 1, new int[] {0})); sideOutputs.add(new SideData(EnumColor.PURPLE, 1, 1, new int[] {1})); sideOutputs.add(new SideData(EnumColor.DARK_BLUE, 2, 1, new int[] {2})); sideOutputs.add(new SideData(EnumColor.DARK_GREEN, 3, 1, new int[] {3})); sideOutputs.add(new SideData(EnumColor.ORANGE, 4, 1, new int[] {4})); sideConfig = new byte[] {2, 1, 0, 4, 5, 3}; inventory = new ItemStack[5]; SECONDARY_ENERGY_PER_TICK = secondaryPerTick; MAX_SECONDARY_ENERGY = maxSecondaryEnergy; } /** * Gets the amount of ticks the declared itemstack can fuel this machine. * @param itemstack - itemstack to check with * @return fuel ticks */ public abstract int getFuelTicks(ItemStack itemstack); @Override public void onUpdate() { super.onUpdate(); if(!worldObj.isRemote) { ChargeUtils.discharge(3, this); if(inventory[4] != null) { if(inventory[4].isItemEqual(new ItemStack(Mekanism.EnergyUpgrade)) && energyMultiplier < 8) { if(upgradeTicks < UPGRADE_TICKS_REQUIRED) { upgradeTicks++; } else if(upgradeTicks == UPGRADE_TICKS_REQUIRED) { upgradeTicks = 0; energyMultiplier++; inventory[4].stackSize--; if(inventory[4].stackSize == 0) { inventory[4] = null; } } } else if(inventory[4].isItemEqual(new ItemStack(Mekanism.SpeedUpgrade)) && speedMultiplier < 8) { if(upgradeTicks < UPGRADE_TICKS_REQUIRED) { upgradeTicks++; } else if(upgradeTicks == UPGRADE_TICKS_REQUIRED) { upgradeTicks = 0; speedMultiplier++; inventory[4].stackSize--; if(inventory[4].stackSize == 0) { inventory[4] = null; } } } else { upgradeTicks = 0; } } else { upgradeTicks = 0; } handleSecondaryFuel(); if(electricityStored >= ENERGY_PER_TICK && secondaryEnergyStored >= SECONDARY_ENERGY_PER_TICK) { if(canOperate() && (operatingTicks+1) < MekanismUtils.getTicks(speedMultiplier, TICKS_REQUIRED) && secondaryEnergyStored >= SECONDARY_ENERGY_PER_TICK) { operatingTicks++; secondaryEnergyStored -= SECONDARY_ENERGY_PER_TICK; electricityStored -= ENERGY_PER_TICK; } else if((operatingTicks+1) >= MekanismUtils.getTicks(speedMultiplier, TICKS_REQUIRED)) { operate(); operatingTicks = 0; secondaryEnergyStored -= SECONDARY_ENERGY_PER_TICK; electricityStored -= ENERGY_PER_TICK; } } if(!canOperate()) { operatingTicks = 0; } if(canOperate() && electricityStored >= ENERGY_PER_TICK && secondaryEnergyStored >= SECONDARY_ENERGY_PER_TICK) { setActive(true); } else { setActive(false); } } } public void handleSecondaryFuel() { if(inventory[1] != null) { int fuelTicks = getFuelTicks(inventory[1]); int energyNeeded = MAX_SECONDARY_ENERGY - secondaryEnergyStored; if(fuelTicks > 0 && fuelTicks <= energyNeeded) { if(fuelTicks <= energyNeeded) { setSecondaryEnergy(secondaryEnergyStored + fuelTicks); } else if(fuelTicks > energyNeeded) { setSecondaryEnergy(secondaryEnergyStored + energyNeeded); } inventory[1].stackSize--; if(inventory[1].stackSize == 0) { inventory[1] = null; } } } } @Override public boolean isStackValidForSlot(int slotID, ItemStack itemstack) { if(slotID == 2) { return false; } else if(slotID == 4) { return itemstack.itemID == Mekanism.SpeedUpgrade.itemID || itemstack.itemID == Mekanism.EnergyUpgrade.itemID; } else if(slotID == 0) { return RecipeHandler.getOutput(itemstack, false, getRecipes()) != null; } else if(slotID == 3) { return (itemstack.getItem() instanceof IElectricItem && ((IElectricItem)itemstack.getItem()).canProvideEnergy(itemstack)) || (itemstack.getItem() instanceof IItemElectric && ((IItemElectric)itemstack.getItem()).getProvideRequest(itemstack).amperes != 0) || itemstack.itemID == Item.redstone.itemID; } else if(slotID == 1) { return getFuelTicks(itemstack) > 0 || (this instanceof TileEntityPurificationChamber && itemstack.getItem() instanceof IStorageTank && ((IStorageTank)itemstack.getItem()).getGasType(itemstack) == EnumGas.OXYGEN); } return true; } @Override public void operate() { ItemStack itemstack = RecipeHandler.getOutput(inventory[0], true, getRecipes()); if(inventory[0].stackSize <= 0) { inventory[0] = null; } if(inventory[2] == null) { inventory[2] = itemstack; } else { inventory[2].stackSize += itemstack.stackSize; } } @Override public boolean canOperate() { if(inventory[0] == null) { return false; } ItemStack itemstack = RecipeHandler.getOutput(inventory[0], false, getRecipes()); if(itemstack == null) { return false; } if(inventory[2] == null) { return true; } if(!inventory[2].isItemEqual(itemstack)) { return false; } else { return inventory[2].stackSize + itemstack.stackSize <= inventory[2].getMaxStackSize(); } } @Override public void handlePacketData(ByteArrayDataInput dataStream) { super.handlePacketData(dataStream); secondaryEnergyStored = dataStream.readInt(); } @Override public ArrayList getNetworkedData(ArrayList data) { super.getNetworkedData(data); data.add(secondaryEnergyStored); return data; } @Override public void readFromNBT(NBTTagCompound nbtTags) { super.readFromNBT(nbtTags); secondaryEnergyStored = nbtTags.getInteger("secondaryEnergyStored"); } @Override public void writeToNBT(NBTTagCompound nbtTags) { super.writeToNBT(nbtTags); nbtTags.setInteger("secondaryEnergyStored", secondaryEnergyStored); } /** * Sets the secondary energy to a new amount * @param energy - amount to store */ public void setSecondaryEnergy(int energy) { secondaryEnergyStored = Math.max(Math.min(energy, MAX_SECONDARY_ENERGY), 0); } /** * Gets the scaled secondary energy level for the GUI. * @param i - multiplier * @return scaled secondary energy */ public int getScaledSecondaryEnergyLevel(int i) { return secondaryEnergyStored*i / MAX_SECONDARY_ENERGY; } @Override public boolean func_102008_b(int slotID, ItemStack itemstack, int side) { if(slotID == 3) { return (itemstack.getItem() instanceof IItemElectric && ((IItemElectric)itemstack.getItem()).getProvideRequest(itemstack).getWatts() == 0) || (itemstack.getItem() instanceof IElectricItem && ((IElectricItem)itemstack.getItem()).canProvideEnergy(itemstack) && (!(itemstack.getItem() instanceof IItemElectric) || ((IItemElectric)itemstack.getItem()).getProvideRequest(itemstack).getWatts() == 0)); } else if(slotID == 2) { return true; } return false; } @Override public String[] getMethodNames() { return new String[] {"getStored", "getSecondaryStored", "getProgress", "isActive", "facing", "canOperate", "getMaxEnergy", "getEnergyNeeded"}; } @Override public Object[] callMethod(IComputerAccess computer, int method, Object[] arguments) throws Exception { switch(method) { case 0: return new Object[] {electricityStored}; case 1: return new Object[] {secondaryEnergyStored}; case 2: return new Object[] {operatingTicks}; case 3: return new Object[] {isActive}; case 4: return new Object[] {facing}; case 5: return new Object[] {canOperate()}; case 6: return new Object[] {MekanismUtils.getEnergy(energyMultiplier, MAX_ELECTRICITY)}; case 7: return new Object[] {(MekanismUtils.getEnergy(energyMultiplier, MAX_ELECTRICITY)-electricityStored)}; default: System.err.println("[Mekanism] Attempted to call unknown method with computer ID " + computer.getID()); return new Object[] {"Unknown command."}; } } }