package mods.eln.sixnode.batterycharger; import mods.eln.Eln; import mods.eln.i18n.I18N; import mods.eln.item.MachineBoosterDescriptor; import mods.eln.item.electricalinterface.IItemEnergyBattery; import mods.eln.misc.Direction; import mods.eln.misc.LRDU; import mods.eln.misc.Utils; import mods.eln.node.AutoAcceptInventoryProxy; import mods.eln.node.NodeBase; import mods.eln.node.six.SixNode; import mods.eln.node.six.SixNodeDescriptor; import mods.eln.node.six.SixNodeElement; import mods.eln.node.six.SixNodeElementInventory; import mods.eln.sim.ElectricalLoad; import mods.eln.sim.IProcess; import mods.eln.sim.ThermalLoad; import mods.eln.sim.mna.component.Resistor; import mods.eln.sim.nbt.NbtElectricalLoad; import mods.eln.sim.process.destruct.ResistorPowerWatchdog; import mods.eln.sim.process.destruct.VoltageStateWatchDog; import mods.eln.sim.process.destruct.WorldExplosion; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class BatteryChargerElement extends SixNodeElement { public BatteryChargerDescriptor descriptor; public NbtElectricalLoad powerLoad = new NbtElectricalLoad("powerLoad"); public BatteryChargerSlowProcess slowProcess = new BatteryChargerSlowProcess(); Resistor powerResistor = new Resistor(powerLoad, null); AutoAcceptInventoryProxy inventory = (new AutoAcceptInventoryProxy(new SixNodeElementInventory(5, 64, this))) .acceptIfEmpty(0, IItemEnergyBattery.class) .acceptIfEmpty(1, IItemEnergyBattery.class) .acceptIfEmpty(2, IItemEnergyBattery.class) .acceptIfEmpty(3, IItemEnergyBattery.class) .acceptIfIncrement(4, 5, MachineBoosterDescriptor.class); VoltageStateWatchDog voltageWatchDog = new VoltageStateWatchDog(); ResistorPowerWatchdog powerWatchDog = new ResistorPowerWatchdog(); public String channel = "Default channel"; boolean invChanged = false; boolean powerOn = false; public static final byte toogleCharge = 1; byte charged, presence; @Override public IInventory getInventory() { if (inventory != null) return inventory.getInventory(); else return null; } @Override public Container newContainer(Direction side, EntityPlayer player) { return new BatteryChargerContainer(player, inventory.getInventory()); } public BatteryChargerElement(SixNode sixNode, Direction side, SixNodeDescriptor descriptor) { super(sixNode, side, descriptor); this.descriptor = (BatteryChargerDescriptor) descriptor; electricalLoadList.add(powerLoad); electricalComponentList.add(powerResistor); slowProcessList.add(slowProcess); WorldExplosion exp = new WorldExplosion(this).machineExplosion(); slowProcessList.add(voltageWatchDog.set(powerLoad).setUNominal(this.descriptor.nominalVoltage).set(exp)); //slowProcessList.add(powerWatchDog.set(powerResistor).setPmax(this.descriptor.nominalPower * 3).set(exp)); } @Override public ElectricalLoad getElectricalLoad(LRDU lrdu) { if (front == lrdu) return powerLoad; return null; } @Override public ThermalLoad getThermalLoad(LRDU lrdu) { return null; } @Override public int getConnectionMask(LRDU lrdu) { if (front == lrdu) return NodeBase.maskElectricalPower; return 0; } @Override public String multiMeterString() { return Utils.plotUIP(powerLoad.getU(), powerLoad.getCurrent()); } @Override public Map<String, String> getWaila() { Map<String, String> info = new HashMap<String, String>(); info.put(I18N.tr("Charge Current"), Utils.plotAmpere("", powerLoad.getCurrent())); if (Eln.wailaEasyMode) { info.put(I18N.tr("Voltage"), Utils.plotVolt("", powerLoad.getU())); info.put(I18N.tr("Power"), Utils.plotPower("", powerLoad.getI() * powerLoad.getU())); } return info; } @Override public String thermoMeterString() { return null; } @Override public void initialize() { descriptor.applyTo(powerLoad); } @Override protected void inventoryChanged() { super.inventoryChanged(); //needPublish(); invChanged = true; } @Override public boolean onBlockActivated(EntityPlayer entityPlayer, Direction side, float vx, float vy, float vz) { if (onBlockActivatedRotate(entityPlayer)) { return true; } else { return inventory.take(entityPlayer.getCurrentEquippedItem(), this, true, false); } } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setBoolean("powerOn", powerOn); nbt.setDouble("energyCounter", slowProcess.energyCounter); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); powerOn = nbt.getBoolean("powerOn"); slowProcess.energyCounter = nbt.getDouble("energyCounter"); } @Override public void networkUnserialize(DataInputStream stream) { super.networkUnserialize(stream); try { switch (stream.readByte()) { case toogleCharge: powerOn = !powerOn; needPublish(); break; } } catch (IOException e) { e.printStackTrace(); } } @Override public boolean hasGui() { return true; } @Override public void networkSerialize(DataOutputStream stream) { super.networkSerialize(stream); try { stream.writeBoolean(powerOn); stream.writeFloat((float) powerLoad.getU()); Utils.serialiseItemStack(stream, getInventory().getStackInSlot(0)); Utils.serialiseItemStack(stream, getInventory().getStackInSlot(1)); Utils.serialiseItemStack(stream, getInventory().getStackInSlot(2)); Utils.serialiseItemStack(stream, getInventory().getStackInSlot(3)); stream.writeByte(charged); stream.writeByte(presence); } catch (IOException e) { e.printStackTrace(); } } class BatteryChargerSlowProcess implements IProcess { double energyCounter = 0; double timeout = 0; @Override public void process(double time) { timeout -= time; if (timeout > 0) return; timeout = 1; time = 1; byte oldCharged = charged; charged = 0; presence = 0; if (!powerOn) { descriptor.setRp(powerResistor, false); } else { ItemStack booster = (getInventory().getStackInSlot(BatteryChargerContainer.boosterSlotId)); double boost = 1.0; double eff = 1.0; if (booster != null) { boost = Math.pow(1.25, booster.stackSize); eff = Math.pow(0.9, booster.stackSize); } energyCounter += powerResistor.getP() * time * eff; for (int idx = 0; idx < 4; idx++) { ItemStack stack = getInventory().getStackInSlot(idx); Object o = Utils.getItemObject(stack); if (o instanceof IItemEnergyBattery) { IItemEnergyBattery b = (IItemEnergyBattery) o; double e = Math.min(Math.min(energyCounter, b.getChargePower(stack) * time * boost), b.getEnergyMax(stack) - b.getEnergy(stack)); b.setEnergy(stack, b.getEnergy(stack) + e); energyCounter -= e; } } if (energyCounter < descriptor.nominalPower * time * 2 * boost) { //double target = descriptor.nominalPower * time * 2; double power = Math.min(descriptor.nominalPower * boost, (descriptor.nominalPower * time * 2 * boost - energyCounter) / time); powerResistor.setR(Math.max(powerLoad.getU() * powerLoad.getU() / power, descriptor.Rp / boost)); } else { descriptor.setRp(powerResistor, false); } } for (int idx = 0; idx < 4; idx++) { ItemStack stack = getInventory().getStackInSlot(idx); Object o = Utils.getItemObject(stack); if (o instanceof IItemEnergyBattery) { IItemEnergyBattery b = (IItemEnergyBattery) o; if (b.getEnergy(stack) == b.getEnergyMax(stack)) { charged += 1 << idx; } presence += 1 << idx; } } if (charged != oldCharged) needPublish(); if (invChanged) { invChanged = false; needPublish(); } } } }