package mods.eln.sixnode.energymeter;
import mods.eln.Eln;
import mods.eln.i18n.I18N;
import mods.eln.misc.Direction;
import mods.eln.misc.LRDU;
import mods.eln.misc.Utils;
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.mna.component.ResistorSwitch;
import mods.eln.sim.nbt.NbtElectricalLoad;
import mods.eln.sim.process.destruct.VoltageStateWatchDog;
import mods.eln.sim.process.destruct.WorldExplosion;
import mods.eln.sixnode.electricalcable.ElectricalCableDescriptor;
import mods.eln.sound.SoundCommand;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class EnergyMeterElement extends SixNodeElement {
VoltageStateWatchDog voltageWatchDogA = new VoltageStateWatchDog();
VoltageStateWatchDog voltageWatchDogB = new VoltageStateWatchDog();
// ResistorCurrentWatchdog currentWatchDog = new ResistorCurrentWatchdog();
public SlowProcess slowProcess = new SlowProcess();
public EnergyMeterDescriptor descriptor;
public NbtElectricalLoad aLoad = new NbtElectricalLoad("aLoad");
public NbtElectricalLoad bLoad = new NbtElectricalLoad("bLoad");
public ResistorSwitch shunt = new ResistorSwitch("shunt", aLoad, bLoad);
SixNodeElementInventory inventory = new SixNodeElementInventory(1, 64, this);
public float voltageMax = (float) Eln.SVU, voltageMin = 0;
int energyUnit = 1, timeUnit = 0;
public ElectricalCableDescriptor cableDescriptor = null;
public static final byte clientEnergyStackId = 1;
public static final byte clientModId = 2;
public static final byte clientPasswordId = 3;
public static final byte clientToggleStateId = 4;
public static final byte clientTimeCounterId = 5;
public static final byte clientEnergyUnitId = 6;
public static final byte clientTimeUnitId = 7;
public static final byte serverPowerId = 1;
String password = "";
double energyStack = 0;
double timeCounter = 0;
enum Mod {ModCounter, ModPrepay}
Mod mod = Mod.ModCounter;
public EnergyMeterElement(SixNode sixNode, Direction side, SixNodeDescriptor descriptor) {
super(sixNode, side, descriptor);
shunt.mustUseUltraImpedance();
electricalLoadList.add(aLoad);
electricalLoadList.add(bLoad);
electricalComponentList.add(shunt);
electricalComponentList.add(new Resistor(bLoad, null).pullDown());
electricalComponentList.add(new Resistor(aLoad, null).pullDown());
slowProcessList.add(slowProcess);
WorldExplosion exp = new WorldExplosion(this).cableExplosion();
// slowProcessList.add(currentWatchDog);
slowProcessList.add(voltageWatchDogA);
slowProcessList.add(voltageWatchDogB);
// currentWatchDog.set(shunt).set(exp);
voltageWatchDogA.set(aLoad).set(exp);
voltageWatchDogB.set(bLoad).set(exp);
this.descriptor = (EnergyMeterDescriptor) descriptor;
}
public SixNodeElementInventory getInventory() {
return inventory;
}
@Override
public ElectricalLoad getElectricalLoad(LRDU lrdu) {
if (front == lrdu) return aLoad;
if (front.inverse() == lrdu) return bLoad;
return null;
}
@Override
public ThermalLoad getThermalLoad(LRDU lrdu) {
return null;
}
@Override
public int getConnectionMask(LRDU lrdu) {
if (inventory.getStackInSlot(EnergyMeterContainer.cableSlotId) == null) return 0;
if (front == lrdu) return NodeBase.maskElectricalAll;
if (front.inverse() == lrdu) return NodeBase.maskElectricalAll;
return 0;
}
@Override
public String multiMeterString() {
return Utils.plotVolt("Ua:", aLoad.getU()) + Utils.plotVolt("Ub:", bLoad.getU()) + Utils.plotVolt("I:", aLoad.getCurrent());
}
@Override
public Map<String, String> getWaila() {
Map<String, String> info = new HashMap<String, String>();
info.put(I18N.tr("Power"), Utils.plotPower("", aLoad.getU() * aLoad.getI()));
switch (mod) {
case ModCounter:
info.put(I18N.tr("Mode"), I18N.tr("Counter"));
info.put(I18N.tr("Energy"), Utils.plotEnergy("", energyStack));
break;
case ModPrepay:
info.put(I18N.tr("Mode"), I18N.tr("Prepay"));
info.put(I18N.tr("Energy left"), Utils.plotEnergy("", energyStack));
break;
}
return info;
}
@Override
public String thermoMeterString() {
return "";
}
@Override
public void networkSerialize(DataOutputStream stream) {
super.networkSerialize(stream);
try {
stream.writeBoolean(shunt.getState());
stream.writeUTF(password);
stream.writeUTF(mod.toString());
stream.writeDouble(timeCounter);
// stream.writeDouble(energyStack);
Utils.serialiseItemStack(stream, inventory.getStackInSlot(EnergyMeterContainer.cableSlotId));
stream.writeByte(energyUnit);
stream.writeByte(timeUnit);
} catch (IOException e) {
e.printStackTrace();
}
}
public void setSwitchState(boolean state) {
if (state == shunt.getState()) return;
// if (energyStack <= 0 && mod == Mod.ModPrepay) return;
shunt.setState(state);
play(new SoundCommand("random.click").mulVolume(0.3F, 0.6f).smallRange());
needPublish();
}
@Override
public void initialize() {
computeElectricalLoad();
}
@Override
protected void inventoryChanged() {
computeElectricalLoad();
reconnect();
}
public void computeElectricalLoad() {
ItemStack cable = inventory.getStackInSlot(EnergyMeterContainer.cableSlotId);
cableDescriptor = (ElectricalCableDescriptor) Eln.sixNodeItem.getDescriptor(cable);
if (cableDescriptor == null) {
aLoad.highImpedance();
bLoad.highImpedance();
voltageWatchDogA.disable();
voltageWatchDogB.disable();
// currentWatchDog.disable();
} else {
cableDescriptor.applyTo(aLoad);
cableDescriptor.applyTo(bLoad);
voltageWatchDogA.setUNominalMirror(cableDescriptor.electricalNominalVoltage);
voltageWatchDogB.setUNominalMirror(cableDescriptor.electricalNominalVoltage);
// currentWatchDog.setIAbsMax(cableDescriptor.electricalMaximalCurrent);
}
}
@Override
public void networkUnserialize(DataInputStream stream) {
super.networkUnserialize(stream);
try {
switch (stream.readByte()) {
case clientEnergyStackId:
energyStack = stream.readDouble();
slowProcess.publishTimeout = -1;
// needPublish();
break;
case clientTimeCounterId:
timeCounter = 0;
needPublish();
break;
case clientModId:
mod = Mod.valueOf(stream.readUTF());
needPublish();
break;
case clientPasswordId:
password = stream.readUTF();
needPublish();
break;
case clientToggleStateId:
setSwitchState(!shunt.getState());
break;
case clientEnergyUnitId:
energyUnit++;
if (energyUnit > 3) energyUnit = 0;
needPublish();
break;
case clientTimeUnitId:
timeUnit++;
if (timeUnit > 1) timeUnit = 0;
needPublish();
break;
}
} catch (IOException e) {
// e.printStackTrace();
}
}
@Override
public boolean hasGui() {
return true;
}
@Override
public Container newContainer(Direction side, EntityPlayer player) {
return new EnergyMeterContainer(player, inventory);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
try {
mod = Mod.valueOf(nbt.getString("mode"));
} catch (Exception e) {
mod = Mod.ModCounter;
}
energyStack = nbt.getDouble("energyStack");
timeCounter = nbt.getDouble("timeCounter");
password = nbt.getString("password");
slowProcess.oldEnergyPublish = energyStack;
energyUnit = nbt.getByte("energyUnit");
timeUnit = nbt.getByte("timeUnit");
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setString("mode", mod.toString());
nbt.setDouble("energyStack", energyStack);
nbt.setDouble("timeCounter", timeCounter);
nbt.setString("password", password);
nbt.setByte("energyUnit", (byte) energyUnit);
nbt.setByte("timeUnit", (byte) timeUnit);
}
class SlowProcess implements IProcess {
public static final double publishTimeoutReset = 1;
public double publishTimeout = Math.random() * publishTimeoutReset;
public double oldEnergyPublish;
@Override
public void process(double time) {
timeCounter += time * 72.0;
double p = aLoad.getCurrent() * aLoad.getU() * (aLoad.getU() > bLoad.getU() ? 1.0 : -1.0);
boolean highImp = false;
switch (mod) {
case ModCounter:
energyStack += p * time;
break;
case ModPrepay:
energyStack -= p * time;
if (energyStack < 0) {
// energyStack = 0;
// setSwitchState(false);
if (p > 0) {
highImp = true;
}
}
break;
}
if (highImp) shunt.ultraImpedance();
else Eln.applySmallRs(shunt);
publishTimeout -= time;
if (publishTimeout < 0) {
publishTimeout += publishTimeoutReset;
ByteArrayOutputStream bos = new ByteArrayOutputStream(64);
DataOutputStream packet = new DataOutputStream(bos);
preparePacketForClient(packet);
try {
packet.writeByte(serverPowerId);
packet.writeDouble(oldEnergyPublish);
packet.writeDouble((energyStack - oldEnergyPublish) / publishTimeoutReset);
sendPacketToAllClient(bos, 10);
} catch (IOException e) {
e.printStackTrace();
}
oldEnergyPublish = energyStack;
}
}
}
}